EthersSdk

High-level SDK built on top of the Ethers adapter — provides deposits, withdrawals, and token/contract resources.


At a Glance

  • Factory: createEthersSdk(client) → EthersSdk
  • Composed resources: sdk.deposits, sdk.withdrawals, sdk.tokens, sdk.contracts
  • Client vs SDK: The client wires RPC/signing, while the SDK adds high-level flows (quote → prepare → create → wait) plus token and contract resources.

Import

import { createEthersClient, createEthersSdk } from '@matterlabs/zksync-js/ethers';

Quick Start

import { JsonRpcProvider, Wallet, parseEther } from 'ethers';
import { createEthersClient, createEthersSdk } from '@matterlabs/zksync-js/ethers';

const l1 = new JsonRpcProvider(process.env.ETH_RPC!);
const l2 = new JsonRpcProvider(process.env.ZKSYNC_RPC!);
const signer = new Wallet(process.env.PRIVATE_KEY!, l1);

const client = createEthersClient({ l1, l2, signer });
const sdk = createEthersSdk(client);

// Example: deposit 0.05 ETH L1 → L2 and wait for L2 execution
const handle = await sdk.deposits.create({
  token: ETH_ADDRESS, // 0x…00 sentinel for ETH supported
  amount: parseEther('0.05'),
  to: await signer.getAddress(),
});

await sdk.deposits.wait(handle, { for: 'l2' });

// Example: resolve core contracts
const { l1NativeTokenVault } = await sdk.contracts.instances();

// Example: map a token L1 → L2
const token = await sdk.tokens.resolve('0xYourToken');
console.log(token.l2);

[!TIP] The SDK composes the client with resources: deposits, withdrawals, tokens, and contracts.

createEthersSdk(client) → EthersSdk

Parameters

NameTypeRequiredDescription
clientEthersClientInstance returned by createEthersClient({ l1, l2, signer }).

Returns: EthersSdk

EthersSdk Interface

deposits: DepositsResource

L1 → L2 flows. See Deposits.

withdrawals: WithdrawalsResource

L2 → L1 flows. See Withdrawals.

tokens: TokensResource

Token identity, L1⇄L2 mapping, bridge asset IDs, chain token facts. See Tokens.

contracts: ContractsResource

Resolved addresses and connected contract instances. See Contracts.

contracts

Utilities for resolved addresses and connected contracts. Token mapping lives in sdk.tokens.

addresses() → Promise<ResolvedAddresses>

Resolve core addresses (Bridgehub, routers, vaults, base-token system).

const a = await sdk.contracts.addresses();

instances() → Promise<{ ...contracts }>

Return connected ethers.Contract instances for all core contracts.

const c = await sdk.contracts.instances();

One-off Contract Getters

MethodReturnsDescription
bridgehub()Promise<Contract>Connected Bridgehub contract.
l1AssetRouter()Promise<Contract>Connected L1 Asset Router contract.
l1NativeTokenVault()Promise<Contract>Connected L1 Native Token Vault.
l1Nullifier()Promise<Contract>Connected L1 Nullifier contract.
l2AssetRouter()Promise<Contract>Connected L2 Asset Router contract.
l2NativeTokenVault()Promise<Contract>Connected L2 Native Token Vault.
l2BaseTokenSystem()Promise<Contract>Connected L2 Base Token System.
const nullifier = await sdk.contracts.l1Nullifier();

Notes & Pitfalls

  • Client first: Always construct the client with { l1, l2, signer } before creating the SDK.

  • Chain-derived behavior: Contracts and token methods pull from on-chain data — results vary by network.

  • Error model: All resource methods throw typed errors. Prefer try* variants (e.g., tryCreate) for structured results.