At a glance
- Factory:
createViemClient({ l1, l2, l1Wallet, l2Wallet?, overrides? }) → ViemClient - What it provides: cached core addresses, typed contracts, convenience wallet access (L2 wallet derivation), and ZKsync RPC bound to
l2. - When to use: create this first; then pass into
createViemSdk(client).
Import
Quick start
createViemClient(args) → ViemClient
Returns: ViemClient
ViemClient interface
Adapter discriminator.
Public L1 client.
Public L2 (ZKsync) client.
Wallet bound to L1 (carries default
account).Optional pre-supplied L2 wallet.
Default account (from
l1Wallet).ZKsync-specific RPC bound to
l2.Methods
ensureAddresses() → Promise<ResolvedAddresses>
Resolve and cache core contract addresses from chain state (merges any overrides).
contracts() → Promise<{ ...contracts }>
Return typed viem contracts (getContract) connected to the current clients.
refresh(): void
Clear cached addresses/contracts. Subsequent calls re-resolve.
baseToken(chainId: bigint) → Promise<Address>
Return the L1 base-token address for a given L2 chain via Bridgehub.baseToken(chainId).
getL2Wallet() → viem.WalletClient
Return the L2 wallet. If not provided at construction, lazily creates one from the same account as l1Wallet over the L2 transport.
Types
ResolvedAddresses
Notes & pitfalls
- Wallet placement: Deposits sign on L1; withdrawals sign on L2; finalization signs on L1 (via SDK).
- Caching:
ensureAddresses()andcontracts()are cached. Userefresh()after network/override changes. - Overrides: For forks or custom deployments, pass
overridesat construction; they’ll be merged with on-chain lookups. - Error surface: Methods may throw typed errors; use the SDK’s
try*variants (on resources) if you prefer result objects.