A wallet can show different returns in USD and SOL because the denomination changes with exchange rates. PnL V2 supports currency selection on wallet summary, history, and performance. Keep the denomination visible and avoid treating converted daily values as a fresh cost-basis calculation.
Run the Node.js example
Use Node.js 24 LTS and keep the API credentials on your server. Create an empty directory, then install:
npm init -y
npm install @solana-tracker/[email protected]
npm install --save-dev tsx typescript @types/node
Save the TypeScript block as index.mts. Put ST_API_KEY in an uncommitted .env file. Streaming examples also need ST_DATASTREAM_URL, the full private WebSocket URL from your Data API dashboard. REST and streaming access depend on your plan.
node --env-file=.env --import tsx index.mts
Set WALLET_ADDRESS to the public wallet under analysis.
import { Client } from '@solana-tracker/data-api';
const apiKey = process.env.ST_API_KEY;
if (!apiKey) throw new Error('Set ST_API_KEY');
const client = new Client({ apiKey });
const mint = process.env.TOKEN_MINT ?? 'So11111111111111111111111111111111111111112';
const wallet = process.env.WALLET_ADDRESS;
if (!wallet) throw new Error('Set WALLET_ADDRESS');
const history = await client.getPnlV2WalletHistory(wallet, {
period: '30d', currency: 'sol',
});
if ('queued' in history && history.queued) {
console.log('History indexing pending');
} else {
console.log('History:', history);
}
const performance = await client.getPnlV2WalletPerformance(wallet, {
period: '30d', currency: 'sol',
});
console.log('Performance:', performance);
Choose the endpoint by the panel
Use wallet summary for the current overview, history for daily observations, and performance for period analysis. Keep wallet and period in the query key. A late response for a previous wallet should never populate the current wallet's chart.
Wallet queries can return queued: true. Render a pending state and retry with bounded delays. Do not access analytics fields before narrowing the result, and do not turn a queue response into a zero-profit datapoint.
Respect the conversion semantics
USD is the default. Historical SOL and EUR values use daily reference rates; the wallet summary uses current spot conversion. Counts, percentages, timestamps, and ROI are not converted.
Some field names remain USD-oriented even in a converted response. Use the response's top-level currency when available and the documented default, not a field-name substring, to choose the symbol and axis label.
Daily historical conversions are approximate and cumulative converted values do not necessarily chain perfectly across dates. Converting an entire USD history using today's SOL price produces a different series from the API's historical conversion.
Keep daily activity separate from cumulative totals
The July correction makes performance trade counts represent daily buys plus sells within the window. Do not sum cumulative lifetime counts over daily snapshots; that repeatedly counts earlier trades.
Likewise, determine whether each PnL field is a daily change or a cumulative value before summing it. Persist the original response alongside derived chart points so the calculation can be reviewed.
Make comparisons reproducible
Store endpoint, wallet, period or explicit dates, denomination, response time, and any supported PnL mode with the cached analysis. Apply pnlMode only to endpoints that document it; it is not a universal query parameter for every history call.
For a leaderboard, compare the same metric and window across wallets. For portfolio value, use the wallet holdings endpoint, which answers a different question from trading profit.
FAQ
Does currency=sol calculate native SOL trading PnL?
No. It denominates supported monetary analytics in SOL; it does not expand PnL asset coverage.
Why does a current summary differ from converted history?
The summary and historical endpoints use different time references for conversion.
Are trade counts converted with currency?
No. Counts, percentages, ROI, and timestamps retain their original meaning.