Skip to content

SDK Examples

Worked examples against @tokenbot-org/sdk. Every method used here exists on the shipped SDK — see the reference.

All examples assume this setup:

import { SignedHttpClient, unlockIdentity } from '@tokenbot-org/cli-core';
import { TokenbotSdk } from '@tokenbot-org/sdk';
const privateKey = unlockIdentity(encryptedKey, salt, passphrase);
const sdk = new TokenbotSdk({
http: new SignedHttpClient({ apiUrl: 'https://api.tokenbot.com', publicKey, privateKey }),
graphqlUrl: 'https://gql-api.tokenbot.com/graphql',
wsUrl: 'wss://gql-api.tokenbot.com/graphql',
});

const me = await sdk.identity.whoami();
console.log(me);

Fails with SdkAuthError if the key isn’t registered — the cheapest way to check wiring before anything else.


The trap here is the default window:

// ❌ Silently returns only the last month
const partial = await sdk.trades.list();
// ✅ Full history
const all = await sdk.trades.list({ filter: { dateRange: 'ALL', limit: 500 } });

graphql-api defaults dateRange to MONTH when it isn’t supplied, so omitting it looks like “all trades” and isn’t.


const trades = await sdk.trades.list({ filter: { dateRange: 'ALL', limit: 500 } });
const pnl = trades.reduce((sum, t) => sum + Number(t.profitLoss ?? 0), 0);
console.log(`realised pnl: ${pnl.toFixed(2)}`);

Page with limit + page if you have more than one page of history.


4. Filter by symbol — and why it needs a big limit

Section titled “4. Filter by symbol — and why it needs a big limit”
const btc = await sdk.trades.list({
filter: { symbol: 'BTC/USDT', dateRange: 'ALL', limit: 500 },
});

symbol is applied client-side, because graphql-api has no symbol filter. It narrows the page the server already returned. With a small limit you can get an empty result even when matching trades exist further back.


// 1. Register the exchange account the copier trades on.
// This uploads credentials to the SERVER so the platform can act for you.
const account = await sdk.exchanges.createAccount({
exchangeName: 'binance',
accountName: 'main',
tradingType: 'spot',
apiKey: process.env.BINANCE_KEY!,
apiSecret: process.env.BINANCE_SECRET!,
});
// 2. Pick a strategy to follow
const strategies = await sdk.strategies.list();
const leader = strategies[0];
// 3. Create the copier
const copier = await sdk.copiers.create({
strategyId: leader.id,
exchangeAccountId: account.id,
name: 'btc follow',
allocationPercentage: 25,
});
// 4. Bind them — note POSITIONAL args, unlike the CLI's flags
await sdk.copiers.link(leader.id, copier.id);

To detach:

await sdk.copiers.unlink(leader.id, copier.id);

await sdk.copiers.update(copierId, { allocationPercentage: 10 });

update is a partial — send only what changes.


const hook = await sdk.webhooks.create({
url: 'https://example.com/hooks/tokenbot',
events: ['trade.filled'],
});
await sdk.webhooks.test(hook.id);

test sends a real test event, so you can confirm the endpoint before depending on it.


for await (const snap of sdk.mm.orderBookWatch({ exchangeId: 'mexc', symbol: 'TBOT/USDT' })) {
console.log('best bid', snap.bids[0], 'best ask', snap.asks[0]);
break; // tears the socket down cleanly
}

Requires wsUrl on the constructor. Without it this throws SdkError immediately rather than failing later at the socket.


import {
SdkAuthError,
SdkNotFoundError,
SdkPermissionError,
SdkValidationError,
SdkNetworkError,
} from '@tokenbot-org/sdk';
async function safeGetStrategy(id: string) {
try {
return await sdk.strategies.get(id);
} catch (err) {
if (err instanceof SdkNotFoundError) return null;
if (err instanceof SdkPermissionError) throw new Error('not your strategy');
if (err instanceof SdkAuthError) throw new Error('identity rejected — re-run tokenbot init');
if (err instanceof SdkValidationError) throw new Error('unexpected API shape — SDK may be stale');
if (err instanceof SdkNetworkError) throw new Error('could not reach TokenBot');
throw err;
}
}

SdkValidationError is the interesting one: responses are schema-validated, so a server-side shape change surfaces at the boundary instead of as an undefined field deep in your code.


const [me, strategies, copiers] = await Promise.all([
sdk.identity.whoami(),
sdk.strategies.list(),
sdk.copiers.list(),
]);
console.log(`account: ${me.id}`);
console.log(`strategies: ${strategies.length}`);
console.log(`copiers: ${copiers.length} (${copiers.filter((c) => c.isActive).length} active)`);