04 / Networks & tokens

Chains, tokens
and the CA.

The vault is chain-agnostic Solidity; the front end ships with a list of networks it knows how to switch to and a short list of tokens it can preview. This page covers both, and how the app decides which vault address to talk to.

Supported chains

#

The network table lives in app/lib/vellumNetworks.ts. Each entry has a viem Chain, a label and the environment variable that supplies its vault address.

NetworkChain idKindVault env var
Robinhood Chain4663Production (default)NEXT_PUBLIC_VELLUM_ROBINHOOD_VAULT_ADDRESS
Ethereum1ProductionNEXT_PUBLIC_VELLUM_ETHEREUM_VAULT_ADDRESS
Base8453ProductionNEXT_PUBLIC_VELLUM_BASE_VAULT_ADDRESS
Arbitrum42161ProductionNEXT_PUBLIC_VELLUM_ARBITRUM_VAULT_ADDRESS
Optimism10ProductionNEXT_PUBLIC_VELLUM_OPTIMISM_VAULT_ADDRESS
Robinhood Chain Testnet46630TestnetNEXT_PUBLIC_VELLUM_ROBINHOOD_TESTNET_VAULT_ADDRESS
Ethereum Sepolia11155111TestnetNEXT_PUBLIC_VELLUM_SEPOLIA_VAULT_ADDRESS
Base Sepolia84532TestnetNEXT_PUBLIC_VELLUM_BASE_SEPOLIA_VAULT_ADDRESS (falls back to NEXT_PUBLIC_VELLUM_TEST_VAULT_ADDRESS)
Arbitrum Sepolia421614TestnetNEXT_PUBLIC_VELLUM_ARBITRUM_SEPOLIA_VAULT_ADDRESS
Optimism Sepolia11155420TestnetNEXT_PUBLIC_VELLUM_OPTIMISM_SEPOLIA_VAULT_ADDRESS

Robinhood Chain and its testnet are defined inline (RPC rpc.mainnet.chain.robinhood.com / rpc.testnet.chain.robinhood.com, Blockscout explorers). The rest come from viem/chains.

Default network

#

DEFAULT_NETWORK_ID is Robinhood Chain (4663). When you press Approve and wrap or Claim note, the app:

  1. Reads the wallet's current eth_chainId.
  2. If it differs, sends wallet_switchEthereumChain.
  3. If the wallet reports error 4902 (chain unknown), sends wallet_addEthereumChain with the chain's name, RPC, native currency and explorer, then retries.

The wallet's native balance shown in the header is read from whichever chain the wallet is on, in that chain's native symbol.

Single active network

The current app UI always targets the default network. The other entries in the table exist so the network list, explorer links and env-var mapping are ready; a network switcher is not exposed in the interface yet.

Listed tokens

#

Token pills in the wrap form are presets. Selecting one fills the token address (when known), the symbol, the card colours and the display-only entry mark.

SymbolNameAddress (Robinhood Chain)Role
$WETHWrapped Ether0x0Bd7D308f8E1639FAb988df18A8011f41EAcAD73Live preset
$USDGGlobal Dollar0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168Live preset
$CASHCATCash Cat0x020bfC650A365f8BB26819deAAbF3E21291018b4Live preset
$PONSPons0x39dBED3a2bd333467115dE45665cC57F813C4571Live preset
$IFWhat IF0x232CDFc415D10b673845D83Dc02ba2eaBe7e30d1Live preset

Networks other than Robinhood Chain ship with $CASHCAT / $PONS / $IF as address-less showcase presets: picking one previews the card, but you must paste a real ERC-20 address to wrap.

Price feed

The entry mark on the preview card comes from GET /api/price?chain=<id>&token=<address>, a small route handler that queries DexScreener, keeps only pairs on the requested chain, picks the one with the most USD liquidity and returns its USD price (handling the token being on either side of the pair). Responses are cached for 30 s. Supported chains: Robinhood Chain, Ethereum, Base, Arbitrum, Optimism; testnets return null.

Any ERC-20

#

The vault does not maintain an allow-list. Any address whose transferFrom moves exactly the requested amount into the vault can be wrapped. In the app, paste an address into the Token address field; on blur the app reads name(), symbol() and decimals() from the default network's public RPC and updates the preview. The amount you type is parsed with those decimals.

Tokens that will not work: fee-on-transfer tokens, rebasing tokens, tokens that revert on transferFrom without allowance, and anything that is not an ERC-20. See token assumptions.

Vault address resolution

#

The front end needs one address: the deployed VellumVault (the "CA"). It is resolved by useVellumVaultAddress() in app/lib/vellumVaultAddress.ts in this order:

  1. localStorage["vellum-vault-address"] — set from the admin panel. Browser-local; wins when present.
  2. NEXT_PUBLIC_VELLUM_ROBINHOOD_VAULT_ADDRESS
  3. NEXT_PUBLIC_VELLUM_CONTRACT_ADDRESS
  4. NEXT_PUBLIC_VELLUM_TEST_VAULT_ADDRESS

If all four are empty, the wrap button reads Vault required, claiming is disabled and no transaction can be sent; the admin panel shows CA / COMING SOON as the current address. The home page hero label "CA COMING SOON" is static copy and is not wired to this value.

bash# .env.local — minimal production configuration
NEXT_PUBLIC_VELLUM_ROBINHOOD_VAULT_ADDRESS=0xYourDeployedVault