Skip to main content

The network

Networks and assets​

Seven public test networks are supported today. All are testnets — the assets on them have no value.

NetworkCodeLedger codeNative assetTokens
Ethereum SepoliasepSEPETHfrom the token registry — currently a Varnir-deployed test USDT
Tron NilenilesTRX-NILETRXfrom the token registry — currently a Varnir-deployed test USDT
BNB Smart Chain testnettbnbtBNBBNB (test)from the token registry
Base Sepoliabase-sepoliabase-sepoliaETHfrom the token registry — a Varnir test USDT (USDT), a Varnir test USDC (VUSDC) and Circle's testnet USDC (USDC), all 6 decimals
Arbitrum Sepoliaarb-sepoliaarb-sepoliaETHfrom the token registry — a Varnir test USDT (USDT), a Varnir test USDC (VUSDC) and Circle's testnet USDC (USDC), all 6 decimals
Polygon Amoypolygon-amoypolygon-amoyPOLfrom the token registry — a Varnir test USDT (USDT), a Varnir test USDC (VUSDC) and Circle's testnet USDC (USDC), all 6 decimals
Bitcoin Signetbtc-signetbtc-signetBTC (test)none — native BTC only

Bitcoin Testnet4 (btc-testnet4) is on hold since 2026-10-02: most of its blocks are mined by bots and carry no transactions, so payments can wait a long time to confirm. Varnir's apps no longer offer it for deposits or sends; Bitcoin Signet is the Bitcoin test network to use.

The code is what you pass to the SDK (VarnirChain.Sepolia, VarnirChain.TronNile, VarnirChain.BnbTestnet, VarnirChain.BaseSepolia, VarnirChain.ArbSepolia, VarnirChain.PolygonAmoy). The ledger code is how the network is spelled at rest on the ledger and inside signed transactions. @varnir/network-codes converts between the spellings, and also knows the mainnet and Solana codes a token registry can name (eth, trx, shasta, bnb, sol, soldev); those networks are not live.

The Phase C chains: one spelling​

The codes of Base Sepolia, Arbitrum Sepolia and Polygon Amoy are the same everywhere: in the SDK, on the ledger and in the API. They have no second spelling. Their tokens are a Varnir test USDT (USDT), a Varnir test USDC (VUSDC) and Circle's own testnet USDC (USDC), all with 6 decimals. BNB Smart Chain testnet's USDT has 18 decimals, like Binance-Peg USDT, so always read decimals from the token registry rather than assuming them from a ticker.

Which tokens a network credits is on-ledger state, not a fixed list. Ask the network rather than hardcoding it:

await client.listTokens();
// [{network: 'SEP', address: '4ea636f3…', symbol: 'USDT', decimals: 6,
// chargeable: true, enabled: true}, …]
Two spellings for Tron Nile

Deposit records carry the network as TRX-NILE, while wallet and pool records use niles. Both refer to the same network — they come from different code paths (the L1 deposit monitors versus the wallet pool). If you match on the network string anywhere, normalise both spellings, case-insensitively.

Wallet claiming is addressed by network code plus pool symbol — for Tron Nile that is niles / trx, for Ethereum Sepolia sep / eth, and for BNB Smart Chain testnet tbnb / eth, for Base Sepolia base-sepolia / eth, for Arbitrum Sepolia arb-sepolia / eth, and for Polygon Amoy polygon-amoy / eth (an EVM chain shares Ethereum's key type). The SDK's getWallet fills these in for you.

Send on the chain the address was issued for

An EVM deposit address is a 0x address, and the same string is valid on every EVM chain. Varnir credits a deposit only on the network the wallet was issued for: Base Sepolia ETH sent to a Sepolia address is not credited. It is not lost (Varnir holds that key on every chain), but recovering it is a manual support case.

Deposits confirm faster than withdrawals — on purpose​

A deposit is credited at a shallower block depth than a withdrawal is marked confirmed, even though both are watching the same L1 transaction. So for a Varnir→Varnir transfer routed over L1, the recipient sees the deposit credited before the sender sees the withdrawal confirmed. This is deliberate, not a bug — the two sides guard against different risks:

Deposit (credit the recipient)Withdrawal (confirm the sender's payment)
Ethereum Sepolia3 confirmations12 confirmations
BNB Smart Chain testnet612
Tron Nileshallow19
Base Sepoliathe safe blockthe safe block
Arbitrum Sepoliathe safe blockthe safe block
Polygon Amoy32 blocks below the finalized block32 blocks below the finalized block
Bitcoin Signet3 confirmations3 confirmations
  • Crediting a deposit favours speed and accepts a small reorg risk: a shallow credit that later reorged out would have over-credited an L2 balance, so the depth is kept low enough for a responsive experience.
  • Confirming a withdrawal is the higher-stakes call — it is Varnir declaring its own outbound payment irreversibly done (versus refunding or retrying it). Marking it confirmed too early and then having it reorg would mean Varnir believes it paid when it did not, so it waits deeper and re-checks on a slower cadence than the continuously-running deposit scanner.

Both depths are per-network and environment-tunable; the values above are the current testnet defaults. Nothing about this affects safety — balances are only ever moved once, checked fresh at commit (see the exchange's balance protection) — it only means the recipient hears the good news first.

How a token is identified​

A token is identified by its L1 contract address, not by its ticker.

An L2 balance is stored under that address, normalised to lowercase hex with no 0x or 41 prefix — so Sepolia's test USDT is 4ea636f3ba863577dcced852b749f618951f2cca. The chain's own native asset uses the literal key #native.

A ticker is not an identity. "USDT" named one contract on Sepolia and a different one on Nile, and two tokens on one network may legitimately share a symbol — so matching on one silently conflates assets. Match on the address; show the symbol.

const balances = await client.getBalances();
// [{chain: 'sep', token: '4ea636f3…', symbol: 'USDT',
// raw: '12500000', amount: '12.5', decimals: 6}]

token is the address (null for the native asset). symbol and decimals are resolved from the registry, and amount is raw scaled by them. If the registry does not describe a token, amount and decimals come back null rather than guessed — raw is always exact.

Older records use symbols

Deposits recorded before this change carry a symbol instead of an address, and Tron USDT appears as Tether rather than USDT. Varnir still reads those, but anything new is address-keyed.

Currencies on an invoice​

Invoices are still priced in one of exactly two currencies, native or USDT — they have not moved to address keys yet.

Ledger nodes​

The settlement layer is a four-node Activeledger testnet. Transactions are POSTed directly to a node — your signing code talks to the chain, not through a Varnir API:

https://node1-testnet.varnir.site
https://node2-testnet.varnir.site
https://node3-testnet.varnir.site
https://node4-testnet.varnir.site

Any node accepts any transaction. An integration should try them in turn and move on when one is unreachable, which is exactly what the SDK example does.

Scanner​

The public scanner is at scanner.varnir.site. It indexes ledger transactions, L1 deposits on all six networks, wallets and identities, and hosts the browser wallet at /wallet.

The same host serves the HTTP API described in the API reference.

Contract identities​

The on-ledger contracts an integration signs against, in the varnir namespace:

ContractId
Onboard79bfad7705d57b81e4e15cbce425686d97e240972e5d319058c675685bc4dc98
AssignOwnerfd9e832e1169d5fb1aa7a591cdbd8bb74dff7addde4e26176bf21f6569ef8e64

These are testnet ids and will change if the contracts are redeployed. Read them from configuration rather than hardcoding them in anything long-lived.