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 |
|
|
Matcher API |
|
no public Mainnet matcher yet |
Matcher public key |
|
— |
Matcher address |
|
— |
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 |
|---|---|---|
|
Yes |
Base URL of the data service API |
|
No |
Custom |
|
No |
Custom JSON parser |
|
No |
Custom response transformer |
Methods#
Method |
Purpose |
|---|---|
|
Fetch one or more assets by ID |
|
Fetch assets by ticker symbol ( |
|
OHLCV candles for a trading pair |
|
Returns a function to fetch pair data for a given matcher |
|
Exchange (DEX trade) transactions, by ID or filtered/paginated |
|
Transfer transactions |
|
Mass transfer transactions |
|
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.