Data Service API#

For historical or aggregated queries — asset search, DEX exchange history, paginated transaction lists — a data service is faster than replaying a node’s transaction history yourself. @decentralchain/data-service-client-js is the official TypeScript client for it.

Note

Verified against @decentralchain/data-service-client-js 4.2.0 on npm (installed and imported on Node.js 24 by the docs CI). The monorepo is renaming the package to data-service-client; that name is not published yet.

Public endpoints#

The package has no built-in URL: pass rootUrl for the network you use. For DEX queries, pass the address of that network’s matcher.

Testnet

Mainnet

Data service rootUrl

https://testnet-data-service.decentralchain.io/v0

https://data-service.decentralchain.io/v0

Matcher API

https://testnet-matcher.decentralchain.io/matcher

no public Mainnet matcher yet

Matcher public key

BEtB5b2kX8Yge4sb5RRbTUqd5Va8Ah8PhphowcW31z6Y

—

Matcher address

31VMNVAvVh67dPZ41nMnYZvhoZFW7wwPrmq

—

You can confirm the Testnet matcher’s key at any time: curl -s https://testnet-matcher.decentralchain.io/matcher returns it as a JSON string.

Installing#

npm install @decentralchain/data-service-client-js@4.2.0

Requires Node.js >= 24 and an ESM environment ("type": "module"). Note the default export — this package doesn’t use a named { DataServiceClient } import.

Connecting#

import DataServiceClient from '@decentralchain/data-service-client-js';

const client = new DataServiceClient({
  rootUrl: 'https://testnet-data-service.decentralchain.io/v0',
});

Option

Required

Purpose

rootUrl

Yes

Base URL of the data service API

fetch

No

Custom fetch implementation

parse

No

Custom JSON parser

transform

No

Custom response transformer

Methods#

Method

Purpose

getAssets(...ids)

Fetch one or more assets by ID

getAssetsByTicker(ticker)

Fetch assets by ticker symbol ('*' for all)

getCandles(amountAsset, priceAsset, opts)

OHLCV candles for a trading pair

getPairs(matcherAddress)

Returns a function to fetch pair data for a given matcher

getExchangeTxs(opts?)

Exchange (DEX trade) transactions, by ID or filtered/paginated

getTransferTxs(opts?)

Transfer transactions

getMassTransferTxs(opts?)

Mass transfer transactions

aliases.getById(id) / getByIdList(ids) / getByAddress(address, opts?)

Alias lookups

All methods return Promise<{ data: T; fetchMore?: (count: number) => Promise }> — call fetchMore to page through a result set without re-specifying filters.

Example: exchange history for a pair#

import DataServiceClient from '@decentralchain/data-service-client-js';

const rootUrl = 'https://testnet-data-service.decentralchain.io/v0';
const client = new DataServiceClient({ rootUrl });

// A pair traded on the Testnet matcher: DCCCANARY, priced in DCC
const amountAsset = 'Hs5y6vFumpwVp6my7rVEmJEQQD3wiQ29qJhnixNqPit5';
const priceAsset = 'DCC';
const matcher = '31VMNVAvVh67dPZ41nMnYZvhoZFW7wwPrmq'; // Testnet matcher

// The pair's last 10 trades, newest first, then the 10 before them
const trades = await client.getExchangeTxs({ amountAsset, priceAsset, matcher, limit: 10, sort: 'desc' });
console.log('Trades:', trades.data.length);
if (trades.fetchMore) {
  const older = await trades.fetchMore(10);
  console.log('Older trades:', older.data.length);
}

// Daily candles for the last 7 days. In data-service-client-js 4.2.0, getCandles() throws
// "Invalid maxHeight: null" when a day in the range has no trades, so read the candles
// endpoint directly and drop the empty days (their prices and volumes are null).
const timeEnd = Date.now();
const query = new URLSearchParams({
  timeStart: String(timeEnd - 7 * 24 * 60 * 60 * 1000),
  timeEnd: String(timeEnd),
  interval: '1d',
  matcher,
});
const response = await fetch(`${rootUrl}/candles/${amountAsset}/${priceAsset}?${query}`);
const body = (await response.json()) as { data: { data: { time: string; close: number | null; volume: number | null } }[] };
const candles = body.data.map((c) => c.data).filter((c) => c.close !== null);
for (const c of candles) console.log(`${c.time.slice(0, 10)} close ${c.close} DCC, volume ${c.volume}`);

Warning

getCandles() in data-service-client-js 4.2.0, the published release, throws Invalid maxHeight: null when any interval in the range has no trades: the data service returns those intervals with null prices and volumes, and the client rejects them. The example reads the candles endpoint (GET /candles/{amountAsset}/{priceAsset}) directly instead. The fix, which returns empty intervals as null, is in the monorepo but not yet published to npm.

Matcher address#

Several methods (getPairs, getCandles) take a matcher address as a parameter rather than assuming a single network-wide matcher. Use the Testnet matcher address 31VMNVAvVh67dPZ41nMnYZvhoZFW7wwPrmq from Public endpoints.