FAR
GitHub

Free Asset Resolver

An open resolver between CoinGecko IDs and CAIP-19 chain-agnostic identifiers. Every lookup is a static file: no key, no rate limit, no server that can be down differently from any other file.

…loading

Look up an asset

Type a name, ticker, CoinGecko id or contract address. You get back every chain the asset is deployed on, as CAIP-19.

loading the registry…

Routes

The lookup above needs none of these. It loads the whole registry once and searches locally. These are for a program that wants one file.

RouteKeyReturns
/name/{slug}.jsonlowercased, punctuation→-every asset with that name, a group, because names are not unique
/symbol/{slug}.jsonsame slug ruleevery asset with that ticker. usdc returns 60+
/cg/{id}.jsonCoinGecko IDone asset with all its chain deployments
/caip/{ns}/{ref}/{ans}/{aref}.jsonCAIP-19 as a paththe asset at that exact identifier

Bulk and metadata

/far.json.gzthe entire registry, ~1.8 MB, often simpler than making requests
/index.jsoncounts, source hashes, route list
/manifest.jsonsha256 of every file plus a Merkle root
/_namespace-gaps.jsonidentifiers we had to invent because no CASA spec defines one

Verifying what you fetched

curl -s https://0xcounting.github.io/FAR/cg/tether.json | shasum -a 256
# compare against the entry for cg/tether.json in /manifest.json

The manifest also carries a Merkle root over every (path, hash) pair, so a single file can be proven to belong to a published release without downloading the rest. An inclusion proof is about 17 hashes. Builds are deterministic: same inputs, same root.

Using it in code

const BASE = 'https://0xcounting.github.io/FAR';

// by name — returns a GROUP, because names are not unique
const r = await fetch(`${BASE}/name/${slug}.json`);
if (r.status === 404) return null;            // no asset by that name
const { assets } = await r.json();

// by CAIP-19 — ":" and "/" become path separators, "%" becomes "~"
const path = caip19.replace(/:/g, '/').replace(/%/g, '~');
const one = await fetch(`${BASE}/caip/${path}.json`);