Guide

Metadata

Every field on a chain class. Which ones may be missing and why. Where each decimals value, magic and proof-of-work hash was checked.

The fields

FieldTypeDescription
keyChainKeyCanonical class key
namestringDisplay name
symbolstringNative token symbol
decimalsnumber?Native currency decimal places
typeChainTypeBlockchain family
bip44number?BIP-44 / SLIP-0044 coin type
chainIdstring?EVM chain ID in hexadecimal
caip2string?CAIP-2 identifier
magicstring?P2P magic bytes, wire order
powPowAlgorithm?Proof-of-work algorithm
explorerstringBlock explorer base URL
rpcDefaultstring?Default public RPC endpoint

key is read off the class, chain.key and Bitcoin.key are the same string. type is the family the class belongs to: evm, utxo, solana, stellar, xrpl, move, ton, tron, octra, arweave or monero. EVM and Move set it for their subclasses, every other chain declares it itself.

Optional fields stay empty when the chain has no registered value. Octra has no BIP-44 coin type and no CAIP-2 namespace, so both are undefined rather than invented. eCash and Decred have a coin type but no CAIP-2 identifier. Only EVM chains carry a chainId, and only some chains ship a public RPC worth defaulting to. The tools print an absent coin type or CAIP-2 as none, because a value that simply vanishes reads as "not shown" and invites the caller to supply one from memory.

chainId and the reference in caip2 encode the same number twice, so a test checks them against each other. Linea shipped a testnet id against a mainnet CAIP-2 until that test existed.

Decimals

decimals is the exponent in 1 whole native unit = 10^decimals base units. It belongs to the currency, not the address family. eCash is the useful counterexample: XEC has two decimal places despite sharing Bitcoin's UTXO ancestry, and assuming eight for every UTXO chain would get XEC amounts badly wrong. Avalanche here means AVAX on the C-Chain; this metadata doesn't describe its X and P chains.

ts
create("bitcoin").decimals; // 8
getChain("xec").decimals; // 2

This isn't a token's precision or a UI rounding preference, and an RPC may already return amounts in whole units. Every built-in chain declares decimals. Custom classes may leave it undefined, which means unknown, never a default of 18. 0 is a valid value for an indivisible currency. chains info and chains_lookup print unknown when the field is absent, --json omits it.

These references were checked on 2026-09-05, Arc on 2026-09-18, Dogecoin on 2026-09-23, Bitcoin Cash, Bitcoin SV, Bitcoin Gold, Dash and Zcash on 2026-09-24. Tests pin the values independently of the classes, and no network request is needed at runtime or during tests.

ChainDecimalsReference
Ethereum, Base, Arbitrum, Optimism, Polygon, BNB Chain, Avalanche C-Chain, Fantom, Gnosis, Linea, zkSync, Scroll, Berachain, Arc18ethereum-lists/chains, nativeCurrency.decimals in eip155-{1,8453,42161,10,137,56,43114,250,100,59144,324,534352,80094,5042}.json; on Arc that is native USDC, the ERC-20 view of the same balance has 6
Bitcoin8Bitcoin Core COIN, 100,000,000 satoshis
Litecoin8Litecoin COIN, 100,000,000
Pepecoin8Pepecoin COIN, 100,000,000; native PEP, not an ERC-20 token
eCash2eCash build documentation, 100 satoshis per XEC
Cardano6Cardano denominations, 1,000,000 lovelace per ADA
Solana9Solana account structure, 1,000,000,000 lamports per SOL
Stellar7Stellar asset precision, 10,000,000 stroops per XLM
XRP Ledger6XRP currency format, 1,000,000 drops per XRP
Aptos8AptosCoin initialization, decimals = 8
Sui9SUI module, 1,000,000,000 mist per SUI
TON9TON Core conversion, 1,000,000,000 nano units per TON
TRON6TRX denominations, 1,000,000 sun per TRX
Octra6Octranomics, 1,000,000 operational units per OCT
Arweave12Arweave debugging guide, 1,000,000,000,000 Winston per AR
Monero12Monero configuration, CRYPTONOTE_DISPLAY_DECIMAL_POINT = 12
Decred8Decred AtomsPerCoin, 100,000,000 atoms
Dogecoin8Dogecoin COIN, 100,000,000
Bitcoin Cash8Bitcoin Cash Node COIN, 100,000,000 satoshis
Bitcoin SV8SV Node COIN, 100,000,000 satoshis
Bitcoin Gold8Bitcoin Gold COIN, 100,000,000 satoshis
Dash8Dash Core COIN, 100,000,000 duffs
Zcash8zcashd COIN, 100,000,000 zatoshis

Coin types

bip44 is the SLIP-0044 coin type, the number that goes into m/44'/coin'/…. All fourteen EVM chains repeat 60, Ethereum's, which is what wallets actually derive with. Decred is 42, not its legacy 20. Octra has none registered and the field says so instead of borrowing one. Deriving keys from it belongs in @agntn/keys, not here.

Magic bytes

magic is the four bytes every P2P message opens with, written as lowercase hex in the order they cross the wire. Every message a Bitcoin node sends you starts with f9beb4d9. Send one under other bytes and the node disconnects. learn me a bitcoin has the long version.

Only chains that kept Bitcoin's wire protocol have one. That's eleven of them. Cardano, Monero and the account chains frame their messages differently, so the field stays undefined there. Cardano's "network magic" is a different thing too, a number checked during the handshake, not a prefix on every message.

The value is mainnet's. A chain class here describes mainnet, and testnet and regtest move the bytes anyway.

ts
create("bitcoin").magic; // "f9beb4d9"
getChain("doge").magic; // "c0c0c0c0"
create("ethereum").magic; // undefined

Two traps. Bitcoin Cash picked e3e1f3e8 in 2017, and eCash and Bitcoin SV kept it when they split off. So the bytes alone won't tell you which of the three you're talking to. The same nodes still write Bitcoin's f9beb4d9 at the start of every block in blk*.dat. That's diskMagic, the field here is netMagic. Decred declares 0xd9b400f9 as a number and writes it little-endian, so the wire reads f900b4d9, and that's what the field holds.

Each value was read on 2026-09-24 from the mainnet params in the node's own source. Tests pin all eleven.

ChainMagicReference
Bitcoinf9beb4d9Bitcoin Core chainparams.cpp, pchMessageStart
Litecoinfbc0b6dbLitecoin chainparams.cpp, pchMessageStart
Pepecoinc0a0f0e0Pepecoin chainparams.cpp, pchMessageStart
Dogecoinc0c0c0c0Dogecoin chainparams.cpp, pchMessageStart
Bitcoin Cashe3e1f3e8Bitcoin Cash Node chainparams.cpp, netMagic
eCashe3e1f3e8Bitcoin ABC chainparams.cpp, netMagic
Bitcoin SVe3e1f3e8SV Node chainparams.cpp, netMagic
Bitcoin Golde1476d44Bitcoin Gold chainparams.cpp, pchMessageStart
Dashbf0c6bbdDash Core chainparams.cpp, pchMessageStart
Zcash24e92764zcashd chainparams.cpp, pchMessageStart; Zebra agrees
Decredf900b4d9dcrd wire/protocol.go, MainNet CurrencyNet = 0xd9b400f9, read little-endian by wire/common.go

Proof of work

pow names what a miner grinds. Mostly that's a hash of the block header, and the block counts once it lands under the target. Equihash is a puzzle instead: the header carries a solution, and only then does its SHA-256d face the target. Either way it's the one algorithm the whole chain agrees on. Pool software and mining hardware are sorted by it: an ASIC built for sha256d can't mine Litecoin.

ts
create("zcash").pow; // "equihash-200-9"
getChain("xmr").pow; // "randomx"
create("ethereum").pow; // undefined

Twelve chains here mine. Ethereum left proof of work in 2022, and Cardano and most account chains never had it. Two are harder. Arweave does mine, but each round is one RandomX hash and then SHA-256 over chunks the miner actually stores. Octra's proof of useful work is encrypted computation, not a hash to grind. Neither fits in one string, so both stay undefined.

Equihash has one more catch. It's a family, not a function, and (n, k) decide how much memory a solution costs. Zcash runs 200,9. Bitcoin Gold started there and moved to 144,5 in 2018 to shake off the Zcash ASICs. A bare "equihash" would put both under one name, so the parameters are part of the value.

The value is today's mainnet algorithm. Decred switched from BLAKE-256 to BLAKE3 with DCP-0011, Monero went from CryptoNight to RandomX in 2019. Old blocks still verify under the old hash, the field only says what the next one needs.

Each value was read on 2026-09-24 from the node's own header check. Tests pin all twelve.

ChainpowReference
Bitcoinsha256dBitcoin Core primitives/block.cpp, GetHash
Bitcoin Cashsha256dBitcoin Cash Node primitives/block.cpp, GetHash
eCashsha256dBitcoin ABC primitives/block.cpp, GetHash
Bitcoin SVsha256dSV Node primitives/block.cpp, GetHash
LitecoinscryptLitecoin primitives/block.cpp, GetPoWHash
DogecoinscryptDogecoin primitives/pureheader.cpp, GetPoWHash
PepecoinscryptPepecoin primitives/pureheader.cpp, GetPoWHash
Dashx11Dash Core primitives/block.cpp, HashX11
Zcashequihash-200-9zcashd chainparams.cpp, nEquihashN, nEquihashK
Bitcoin Goldequihash-144-5Bitcoin Gold chainparams.cpp, nEquihashNnew, nEquihashKnew
Decredblake3dcrd wire/blockheader.go, PowHashV2
MonerorandomxMonero cryptonote_tx_utils.cpp, rx_slow_hash