Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Supported Chains

Two chains ship as built-in: Ethereum mainnet (chainId 1) and Base mainnet (chainId 8453). Every other chainId throws UnsupportedChainError at createApyxClient time — the SDK fails fast rather than constructing a half-broken client.

Address book

The same table lives in code at src/addresses.ts — that file is the source of truth and the registry the SDK reads at runtime. If a chain ever goes missing here but exists in the source, file an issue.

Address checksumming and immutability

createApyxClient runs every address — built-in and overridden alike — through getAddress from viem. That serves two purposes:

  1. Validation. A malformed address (non-hex, wrong length, bad case-checksum) raises InvalidAddressError at construction. Failure is loud and immediate, not at first call.
  2. Normalization. The returned apyx.addresses object always holds EIP-55 checksummed strings, regardless of the case you pass in.

The result is also Object.freezed — apyx.addresses cannot be mutated in place after construction, even by accident.

apyUSDRateView is optional per chain

The on-chain rate view contract is deployed on Ethereum but not on Base. The SDK reflects that in the type system: apyx.apyUSDRateView is typed as RateViewModule | undefined. Always guard with ?.:

const apy = await apyx.apyUSDRateView?.apy();
//                                    ^^^^^^^^
// undefined on chains where the rate view isn't deployed

Calling without the optional chain on Base would be a compile-time error.

If you need to compute the same value off-chain (e.g. to compare), combine apyUSD.exchangeRate() with a historical reference rate; see the APY recipe.

Overriding addresses (forks, testnets, custom deployments)

The built-in registry covers the live mainnet deployments. To target a fork or a custom redeploy, pass addresses at construction:

const apyx = createApyxClient({
  chain: mainnet,
  transport: http('http://127.0.0.1:8545'),
  addresses: {
    apyUSD: '0xYourFork...',
    // apxUSD + apyUSDRateView fall back to the built-in mainnet values
  },
});

A partial override is merged onto the built-in registry — you only need to specify the fields you’re moving. Each override goes through the same getAddress validation and freezes into apyx.addresses like any other entry.

This is the path used by every e2e test that runs against an anvil mainnet fork (see E2E testing).

Adding a new chain

The matrix above is short on purpose: more deployments lands as the protocol expands. Track the add list in src/addresses.ts — a new chainId entry there ripples through to the SDK and CLI without code changes elsewhere.

If you’re consuming the SDK on a chain we haven’t listed and the contract is already deployed there, override addresses and tell us — we’d rather generalise the registry than have every consumer hand-roll the same mapping.