@range-security/asset-resolver
v1.0.5
Published
Cross-chain token resolver.
Keywords
Readme
@range-security/asset-resolver
Cross-chain token resolver.
Install
yarn add @range-security/asset-resolverEnvironment
| Variable | Required |
|---|---|
| ASSET_REDIS_URL | Yes |
| EVM_REDIS_URL | Yes |
| IDL_REDIS_URL | For getProgramIdl |
| HISTORIC_PRICES_URL | For historical prices |
Production Environments
Resolve a denom/address to symbol, decimals and live USD price, or convert a raw on-chain amount to a human-readable form.
import {
resolveToken,
resolveAmount,
disconnectAll,
} from '@range-security/asset-resolver';
const token = await resolveToken('uatom', 'cosmoshub');
// { symbol: 'ATOM', decimals: 6, usd: 4.21, cg: 'cosmos', ... }
const amount = await resolveAmount('1500000', 'uatom', 'cosmoshub');
// { amount: '1.5', symbol: 'ATOM', usd: 6.31, tokenUsdString: '1.5 ATOM($6.31)', ... }
await disconnectAll(); // close redis on shutdownRouting:
network === 'solana'→ Solana resolvernetwork === 'stellar'→ Stellar resolver- everything else → cosmos/EVM cascade (priced assets → cosmos registry → IBC fallback → EVM registry)
Test Environment
Override resolutions in tests without hitting Redis. All setup helpers throw unless NODE_ENV=test.
import {
setupToken,
setupNetwork,
setupNetworkMapping,
resetTestOverrides,
resolveToken,
} from '@range-security/asset-resolver';
beforeEach(() => resetTestOverrides());
setupToken('uatom', 'cosmoshub', {
symbol: 'ATOM',
decimals: 6,
usd: 10,
cg: 'cosmos',
});
setupNetwork({ id: 'cosmoshub', /* ... */ });
setupNetworkMapping({ from: 'cosmoshub', bridge: 'ibc', to: 'cosmos-hub' });
const token = await resolveToken('uatom', 'cosmoshub'); // returns the overrideHistorical Prices
Switch the resolver into historical mode — resolveToken / resolveAmount return USD as of the given day for any token with a cg (CoinGecko id). Snapshots are cached on disk under <cwd>/.asset-resolver-cache/<YYYY-MM-DD>.json.
import {
setHistoricalPrices,
clearHistoricalPrices,
resolveAmount,
} from '@range-security/asset-resolver';
await setHistoricalPrices('2024-01-15'); // ISO string
// or: await setHistoricalPrices(Date.now() - 86_400_000);
// or: await setHistoricalPrices(dayjs().subtract(7, 'day'));
const amount = await resolveAmount('1500000', 'uatom', 'cosmoshub');
// amount.usd uses the 2024-01-15 price; amount.priceHistorical === true
clearHistoricalPrices(); // back to live pricesTokens without a cg id, or missing from that day's snapshot, pass through with their live price and priceHistorical: false. State is module-level — concurrent callers in the same process share one date.
