constNODE_URL=process.env.NODE_URL||'https://reference.symboltest.net:3001';console.log(`Using node ${NODE_URL}`);constSUPPLY_PATH='/network/currency/supply';// Convert the returned decimal string (whole XYM) to atomic units.// A float conversion would lose precision when the value has more// than 15 significant digits.consttoAtomic=s=>{const[whole,frac='']=s.trim().split('.');return(BigInt(whole)*1_000_000n)+BigInt(frac.padEnd(6,'0'));};// Format an atomic amount back as whole XYM with 6 decimals.constfmt=v=>`${(v/1_000_000n).toLocaleString('en-US')}.`+`${(v%1_000_000n).toString().padStart(6,'0')}`;try{constmaximumResponse=awaitfetch(`${NODE_URL}${SUPPLY_PATH}/max`);constmaximumSupply=toAtomic(awaitmaximumResponse.text());console.log(`Maximum supply: ${fmt(maximumSupply)} XYM`);consttotalResponse=awaitfetch(`${NODE_URL}${SUPPLY_PATH}/total`);consttotalSupply=toAtomic(awaittotalResponse.text());console.log(`Total supply: ${fmt(totalSupply)} XYM`);constcirculatingResponse=awaitfetch(`${NODE_URL}${SUPPLY_PATH}/circulating`);constcirculatingSupply=toAtomic(awaitcirculatingResponse.text());console.log(`Circulating supply: ${fmt(circulatingSupply)} XYM`);constnonCirculatingSupply=totalSupply-circulatingSupply;console.log(`Non-circulating supply: ${fmt(nonCirculatingSupply)} XYM`);constunmintedSupply=maximumSupply-totalSupply;console.log(`Unminted supply: ${fmt(unmintedSupply)} XYM`);}catch(error){console.log(error);}
The snippet uses the NODE_URL environment variable to set the Symbol API node.
If no value is provided, a default testnet node is used.
Default node is testnet
The default node points to testnet.
For production supply data, set NODE_URL to a mainnet node.
For a list of available mainnet nodes, see symbol.fyi/nodes.
All three endpoints return a plain-text number (not JSON), already expressed in whole units with decimal places
(e.g. 8999999999.000000), not in atomic units.
A supply value like 8323505878.695894 has 16 digits, but a floating-point number can only store about 15 digits
accurately.
Parsing these values as floats can silently change the last digit, so the code parses and subtracts them using exact
numeric types instead (Decimal in Python, the toAtomic helper with BigInt in JavaScript, and BigDecimal in
Java).
Circulating supply is node-dependent
The list of non-circulating accounts is configured by each node operator (in the node's rest.json file),
so different nodes could report different circulating supply values.
If you are integrating supply data, ensure you query a trusted node with the
default configuration.