Skip to main content

What is this?

The ZKsyncOS SDK provides lightweight adapters for ethers and viem to build L1 ↔ L2 flows—deposits and withdrawals—with a small, focused API. You’ll work with:
  • Adapter-level Clients (providers/wallets, resolved addresses, convenience contracts)
  • High-level SDKs (resources for deposits & withdrawals + helpers)
  • ZKsync-specific RPC helpers (client.zks.*)
  • A consistent, typed Error model (ZKsyncError, try* results)

Quick start

import { JsonRpcProvider, Wallet, parseEther } from 'ethers';
import { createEthersClient, createEthersSdk, ETH_ADDRESS } from '@dutterbutter/zksync-sdk/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);

// Low-level client + high-level SDK
const client = createEthersClient({ l1, l2, signer });
const sdk = createEthersSdk(client);

// Deposit 0.05 ETH L1 → L2 and wait for L2 execution
const handle = await sdk.deposits.create({
  token: ETH_ADDRESS,
  amount: parseEther('0.05'),
  to: await signer.getAddress(),
});

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

// ZKsync-specific RPC is available via client.zks
const bridgehub = await client.zks.getBridgehubAddress();

What’s documented here

Notes & conventions

  • Standard eth_* RPC should be performed through your chosen base library (ethers / viem).
    The SDK only adds ZKsync-specific RPC via client.zks.* (e.g., getBridgehubAddress, getL2ToL1LogProof, enhanced receipts).
  • Every resource method has a try* variant (e.g., tryCreate) that returns a result object instead of throwing.
    When errors occur, the SDK throws ZKsyncError with a stable envelope (see Error model).
  • Address resolution comes from on-chain lookups and well-known constants. You can override addresses in the client constructor for forks/tests.