@range-security/asset-resolver
v1.0.11
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.
EVM Contract ABIs
Fetch a verified contract ABI from EVM_REDIS_URL. ABIs are populated by evm-tx-indexer's fill-abi from Sourcify, keyed by Range network id.
import { getContractAbi, disconnectAll } from '@range-security/asset-resolver';
const c = await getContractAbi('eth', '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48');
// { contract, network, version, abi, metadata, isProxy, proxyContract, proxyAbi } | null
await disconnectAll(); // closes the shared EVM redis clientFor a proxy, proxyAbi holds the implementation ABI (the effective decoder); isProxy and proxyContract describe the proxy. Returns null on a cache miss.
