@avalabs/signals-sdk
v0.4.1
Published
TypeScript SDK for Core Signals market data, sentiment, social posts, and news feeds.
Downloads
4,654
Keywords
Readme
@avalabs/signals-sdk
SDK for Core Signals. It exposes API path constants, URL helpers, an injectable fetch transport, module clients, and a unified SignalsClient.
import { SignalsClient } from '@avalabs/signals-sdk';
const client = new SignalsClient({ baseUrl: 'https://proxy-api.avax.network' });
// assets are CoinGecko IDs
const ticker = await client.ticker.get({ assets: ['bitcoin', 'avalanche-2'] });
const sentiment = await client.sentiment.get();
const posts = await client.social.getPosts({ limit: 10 });
const news = await client.social.getNews({ page: 1 });
const feed = await client.feed();Ticker module
TickerModule.get() fetches live prices from the CoinGecko proxy and returns ModuleResult<TickerData>.
TickerData contains:
prices: PriceTick[]— per-asset price, market cap, 24h volume and changemarket?: MarketCapTick— total market cap and 24h change (omitted if the global endpoint is unavailable)
The result is a discriminated union:
const result = await client.ticker.get({ assets: ['bitcoin', 'avalanche-2'] });
if (result.status === 'ok') {
console.log(result.data.prices); // PriceTick[]
console.log(result.data.market); // MarketCapTick | undefined
console.log(result.stale); // true if data is older than freshThresholdMs
} else if (result.status === 'unavailable') {
// data is older than staleThresholdMs — treat as no data
} else {
// result.status === 'error'
console.error(result.error);
}Staleness
Staleness is evaluated against CoinGecko's last_updated timestamp in the response:
| Condition | Result |
| ------------------------------------------------------- | ------------------------------ |
| now - last_updated ≤ freshThresholdMs (default 60 s) | status: 'ok', stale: false |
| now - last_updated > freshThresholdMs | status: 'ok', stale: true |
| now - last_updated > staleThresholdMs (default 180 s) | status: 'unavailable' |
Use the stale flag to show a "prices may be delayed" indicator without blocking rendering:
if (result.status === 'ok' && result.stale) {
showDelayedPricesBanner();
}Polling with TanStack Query
The SDK is a one-shot fetch — polling is the consumer's responsibility. TanStack Query is the recommended approach because it pauses in the background, resumes on focus, and deduplicates concurrent callers automatically.
import { useQuery } from '@tanstack/react-query';
const ASSETS = ['bitcoin', 'ethereum', 'avalanche-2'];
function useTickerQuery() {
return useQuery({
queryKey: ['signals', 'ticker', ASSETS],
queryFn: ({ signal }) => client.ticker.get({ assets: ASSETS, signal }),
refetchInterval: 60_000, // re-fetch every 60 s
refetchIntervalInBackground: false, // pause when tab/app is hidden
staleTime: 60_000, // don't treat cached data as stale for 60 s
});
}The AbortSignal from queryFn is forwarded directly to the transport, so in-flight requests are cancelled when the component unmounts or the query key changes.
For the full feed:
function useSignalsFeedQuery() {
return useQuery({
queryKey: ['signals', 'feed'],
queryFn: ({ signal }) => client.feed({ signal }),
refetchInterval: 60_000,
refetchIntervalInBackground: false,
staleTime: 60_000,
});
}Custom thresholds and asset list
Configure thresholds and a default asset list by constructing TickerModule directly:
import { TickerModule, createTransport } from '@avalabs/signals-sdk';
const transport = createTransport({ baseUrl: 'https://proxy-api.avax.network' });
const ticker = new TickerModule({
transport,
assets: ['bitcoin', 'ethereum', 'avalanche-2'],
freshThresholdMs: 30_000,
staleThresholdMs: 120_000,
});API paths
The package exports SIGNALS_API_PATHS for proxy/backend alignment:
import { SIGNALS_API_PATHS } from '@avalabs/signals-sdk';
SIGNALS_API_PATHS.ticker; // /proxy/coingecko/coins/markets
SIGNALS_API_PATHS.tickerGlobal; // /proxy/coingecko/global
SIGNALS_API_PATHS.sentiment;
SIGNALS_API_PATHS.socialPosts;
SIGNALS_API_PATHS.socialNews;
SIGNALS_API_PATHS.feed;Override paths at construction time:
const client = new SignalsClient({
baseUrl: 'https://proxy-api.avax.network',
apiPaths: {
ticker: '/v2/proxy/coingecko/coins/markets',
},
});Development
pnpm --filter @avalabs/signals-sdk build
pnpm --filter @avalabs/signals-sdk test
pnpm --filter @avalabs/signals-sdk typecheck
pnpm --filter @avalabs/signals-sdk lintThis package starts at 0.0.0. Use pnpm changeset for the first release changeset, then pnpm version-packages and the root release flow.
