Deposit Ether to ZKsync

Learn how to create a script to deposit Ether to ZKsync.

This how-to guide explains how to create a script that deposits Ether to ZKsync.

What you'll learn:

  • How L2 deposits work
  • How to deposit Ether to ZKsync


  • - zksync-ethers
Last Updated: May 09, 2024

Depositing assets from L1 to L2 is a fundamental step to interact with ZKsync. This guide demonstrates how to deposit ETH using the Javascript SDK, ensuring a smooth transition of assets to L2. In ZKsync, assets deposited from L1 are locked in a smart contract and corresponding representations of these assets are minted on L2, enabling fast and cheap transactions.


  • Node.js: Ensure you have Node.js installed. If not, download it from here.
  • Private Key: Have access to a private key for the account you'll be using.
  • L1 RPC Endpoint: A URL to an Ethereum node to interact with. You can find RPC endpoints for Sepolia and Ethereum mainnet on Chainlist or use a node provider like Alchemy.

Understand L1 - L2 Deposits

Depositing assets from L1 to L2 involves calling the deposit method on the L1 bridge contract. Here's a simplified breakdown of the process:

  1. Locking L1 Tokens: Initially, the specified tokens on L1 are sent to the L1 bridge, where they are locked.
  2. Initiating L1 to L2 Transaction: The L1 bridge then initiates a transaction to the L2 bridge, marking the start of the deposit process.
  3. Minting L2 Tokens: Tokens corresponding to the deposit are minted on L2 and sent to the designated L2 address.
    • If the token contract isn’t already present on ZKsync Era, a new contract is deployed with a new L2 token address, which is derived from the original L1 address, name, and symbol.
  4. Confirmation Logging: Each executed L1 to L2 transaction is confirmed with a log message sent from L2 back to L1.
  5. Finalizing Deposit: Finally, the finalizeDeposit method is called on the L2 bridge to complete the deposit process, ensuring the funds are minted on L2.

This structured flow ensures a secure and orderly transfer of assets from L1 to L2, paving the way for further interactions on the Layer 2 network.

Setup Environment

Setup the node script:

mkdir deposit-scripts && cd deposit-scripts
npm init -y
npm i typescript ts-node ethers@^5.7.2 zksync-ethers@5 dotenv

Create a .env file in the project root containing your private key and the L1 RPC endpoint.


Create the Deposit Script

Create a new file deposit.ts and insert the below code:

import { Wallet, Provider, utils } from "zksync-ethers";
import * as ethers from "ethers";

// load env file
import dotenv from "dotenv";

// HTTP RPC endpoints
const L1_RPC_ENDPOINT = process.env.L1_RPC_ENDPOINT || ""; // or an RPC endpoint from Infura/Chainstack/QuickNode/etc.
const L2_RPC_ENDPOINT = process.env.L2_RPC_ENDPOINT || ""; // or the ZKsync Era mainnet

// Amount in ETH
const AMOUNT = "0.00001";

const WALLET_PRIV_KEY = process.env.WALLET_PRIV_KEY || "";

  throw new Error("Wallet private key is not configured in env file");

  throw new Error("Missing L1 RPC endpoint. Check or an RPC node provider");

async function main() {
  console.log(`Running script to deposit ETH in L2`);

  // Initialize the wallet.
  const l1provider = new Provider(L1_RPC_ENDPOINT);
  const l2provider = new Provider(L2_RPC_ENDPOINT);
  const wallet = new Wallet(WALLET_PRIV_KEY, l2provider, l1provider);

  console.log(`L1 Balance is ${await wallet.getBalanceL1()}`);
  console.log(`L2 Balance is ${await wallet.getBalance()}`);

  // Deposit ETH to L2
  const depositHandle = await wallet.deposit({
    to: wallet.address,
    token: utils.ETH_ADDRESS,
    amount: ethers.utils.parseEther(AMOUNT),
  console.log(`Deposit transaction sent ${depositHandle.hash}`);
  console.log(`Please wait a few minutes for the deposit to be processed in L2`);

  .catch((error) => {
    process.exitCode = 1;

Run the Script

Execute the script using the following command:

npx ts-node deposit.ts

Verify the Deposit

Upon running the script, you should see output similar to below, indicating the deposit transaction has been sent and is being processed on L2:

Running script to deposit ETH in L2
L1 Balance is 6539874840163375070
L2 Balance is 5712612651486983637
Deposit transaction sent 0xffb8e302430b0584e2e0104dd6295a03688c98ba7b6e9279b01dba65188cc444
Please wait a few minutes for the deposit to be processed in L2


By following this guide, you have successfully deposited ETH from L1 to L2 using the ZKsync Javascript SDK. This is a fundamental step towards interacting with the ZKsync Era.

Made with ❤️ by the ZKsync Community