V6

Providers

A guide to Web3 Provider objects for ZKsync integration

A Web3 Provider object provides application-layer access to underlying blockchain networks.

The zksync-ethers library supports provider methods from the ethers.js library and supplies additional functionality.

Available providers

  • Provider: Extends ethers.JsonRpcProvider with ZKsync specific methods.
  • BrowserProvider: Extends the ZKsync Era Provider class for better compatibility with Web3 wallets.
Use BrowserProvider for browser integrations.

Provider

constructor

Creates a zksync Era Provider object.

Parameters:

ParameterTypeDescription
url?ethers.FetchRequestNetwork RPC URL (optional).
network?ethers.NetworkishNetwork name, chain ID, or object with network details.
options?anyAdditional provider options (optional).
constructor(url ? : ethers.FetchRequest | string, network ? : Networkish, options ? : any)

Example:

import { Provider } from "zksync-ethers";

const provider = new Provider("https://sepolia.era.zksync.dev");

The constructor for the Provider class creates an instance of the provider object, which connects your application to the zksync Era network. The url parameter specifies the network RPC URL, the network parameter allows you to define the network details, and options provides additional customization.

broadcastTransaction

Overrides the Ethers implementation.

Parameters:

ParameterTypeDescription
signedTxstringSigned transaction.
async broadcastTransaction(signedTx: string): Promise<TransactionResponse>

Example:

import { Provider, types, Wallet } from "zksync-ethers";

const PRIVATE_KEY = "<PRIVATE_KEY>";
const provider = Provider.getDefaultProvider(types.Network.Sepolia);
const wallet = new Wallet(PRIVATE_KEY, provider, ethProvider);

const signedTx = await wallet.signTransaction({
  to: "0xa61464658AfeAf65CccaaFD3a512b69A83B77618",
  value: ethers.parseEther("0.01"),
});
const tx = await provider.broadcastTransaction(signedTx);
console.log(tx.hash);

The broadcastTransaction method sends a signed transaction to the network. This is useful when you want to broadcast a transaction that has already been signed by a wallet. The method returns a transaction response, which includes the transaction hash.

estimateFee

Returns an estimated Fee for the requested transaction.

Parameters:

ParameterTypeDescription
transactionTransactionRequestTransaction request.
async estimateFee(transaction: TransactionRequest): Promise<Fee>

Example:

import { Provider, types } from "zksync-ethers";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);
const fee = await provider.estimateFee({
  from: "0x36615Cf349d7F6344891B1e7CA7C72883F5dc049",
  to: "0xa61464658AfeAf65CccaaFD3a512b69A83B77618",
  value: `0x${BigInt(7_000_000_000).toString(16)}`,
});
console.log(`Fee: ${toJSON(fee)}`);

The estimateFee method estimates the fee required for a transaction. This is important for users to know how much they need to pay in transaction fees before sending the transaction. The method returns a Fee object that contains the estimated fee details.

estimateGas

Returns an estimate of the gas required to submit a transaction.

Parameters:

ParameterTypeDescription
_txTransactionRequestTransaction request.
async estimateGas(_tx: TransactionRequest): Promise<bigint>

Example:

import { Provider, types, utils } from "zksync-ethers";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);
const gasTokenApprove = await provider.estimateGas({
  from: "0x36615Cf349d7F6344891B1e7CA7C72883F5dc049",
  to: "0x765F5AF819D818a8e8ee6ff63D8d0e8056DBE150",
  data: utils.IERC20.encodeFunctionData("approve", [RECEIVER, 1]),
});
console.log(`Gas for token approval tx: ${gasTokenApprove}`);

The estimateGas method estimates the amount of gas required for a transaction. This is essential for determining the cost of a transaction in terms of gas, ensuring you have enough funds to cover the transaction cost.

estimateGasL1

Returns an estimate of the gas required to submit a transaction from L1 to L2.

Parameters:

ParameterTypeDescription
transactionTransactionRequestTransaction request.
async estimateGasL1(transaction: TransactionRequest): Promise<bigint>

Example:

import { Provider, types } from "zksync-ethers";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);
const gasL1 = await provider.estimateGasL1({
  from: "0x36615Cf349d7F6344891B1e7CA7C72883F5dc049",
  to: await provider.getMainContractAddress(),
  value: 7_000_000_000,
  customData: {
    gasPerPubdata: 800,
  },
});
console.log(`L1 gas: ${BigInt(gasL1)}`);

The estimateGasL1 method estimates the gas required for a transaction from Layer 1 (L1) to Layer 2 (L2). This is crucial for cross-layer operations, ensuring you know the gas cost for moving transactions between layers.

estimateGasTransfer

Returns the gas estimation for a transfer transaction.

Parameters:

ParameterTypeDescription
tokenAddressToken address.
amountBigNumberishAmount of token.
from?AddressFrom address (optional).
to?AddressTo address (optional).
paymasterParams?PaymasterParamsPaymaster parameters (optional).
overrides?ethers.OverridesEthers overrides object (optional).
async estimateGasTransfer(transaction: {
  to: Address;
  amount: BigNumberish;
  from ? : Address;
  token ? : Address;
  paymasterParams ?: PaymasterParams;
  overrides ? : ethers.Overrides;
}): Promise<bigint>

Example:

import { Provider, types, utils } from "zksync-ethers";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);
const gasTransfer = await provider.estimateGasTransfer({
  token: utils.ETH_ADDRESS,
  amount: 7_000_000_000,
  to: "0xa61464658AfeAf65CccaaFD3a512b69A83B77618",
  from: "0x36615Cf349d7F6344891B1e7CA7C72883F5dc049",
});
console.log(`Gas for transfer tx: ${gasTransfer}`);

The estimateGasTransfer method estimates the gas required for a token transfer transaction. This helps users determine the cost of transferring tokens between addresses.

estimateGasWithdraw

Returns the gas estimation for a withdrawal transaction.

Parameters:

ParameterTypeDescription
tokenAddressToken address.
amountBigNumberishAmount of token.
from?AddressFrom address (optional).
to?AddressTo address (optional).
bridgeAddress?AddressBridge address (optional).
paymasterParams?PaymasterParamsPaymaster parameters (optional).
overrides?ethers.OverridesTransaction's overrides which may be used to pass l2 gasLimit, gasPrice, value, etc (optional).
async estimateGasWithdraw(transaction: {
  token: Address;
  amount: BigNumberish;
  from ? : Address;
  to ? : Address;
  bridgeAddress ? : Address;
  paymasterParams ?: PaymasterParams;
  overrides ? : ethers.Overrides;
}): Promise<bigint>

Example:

import { Provider, types, utils } from "zksync-ethers";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);
const gasWithdraw = await provider.estimateGasWithdraw({
  token: utils.ETH_ADDRESS,
  amount: 7_000_000_000,
  to: "0x36615Cf349d7F6344891B1e7CA7C72883F5dc049",
  from: "0x36615Cf349d7F6344891B1e7CA7C72883F5dc049",
});
console.log(`Gas for withdrawal tx: ${gasWithdraw}`);

estimateL1ToL2Execute

Returns gas estimation for an L1 to L2 execute operation.

Inputs

ParameterTypeDescription
contractAddressAddressAddress of contract.
calldatastringThe transaction call data.
caller?AddressCaller address (optional).
l2Value?BigNumberishCurrent L2 gas value (optional).
factoryDeps?BytesLike[]Byte array containing contract bytecode.
gasPerPubdataByte?BigNumberishConstant representing current amount of gas per byte (optional).
overrides?ethers.OverridesTransaction's overrides which may be used to pass l2 gasLimit, gasPrice, value, etc (optional).
async estimateL1ToL2Execute(transaction: {
  contractAddress: Address;
  calldata: string;
  caller ? : Address;
  l2Value ? : BigNumberish;
  factoryDeps ? : ethers.BytesLike[];
  gasPerPubdataByte ? : BigNumberish;
  overrides ? : ethers.Overrides;
}): Promise<bigint>

Example

import { Provider, types } from "zksync-ethers";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);
const gasL1ToL2 = await provider.estimateL1ToL2Execute({
  contractAddress: await provider.getMainContractAddress(),
  calldata: "0x",
  caller: "0x36615Cf349d7F6344891B1e7CA7C72883F5dc049",
  l2Value: 7_000_000_000,
});
console.log(`Gas L1 to L2: ${BigInt(gasL1ToL2)}`);

getAllAccountBalances

Returns all balances for confirmed tokens given by an account address.

Calls the zks_getAllAccountBalances JSON-RPC method.

Inputs

ParameterTypeDescription
addressAddressAccount address.
async getAllAccountBalances(address: Address): Promise<BalancesMap>

Example

Helper function: toJSON.

import { Provider, types } from "zksync-ethers";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);
const balances = await provider.getAllAccountBalances("0x36615Cf349d7F6344891B1e7CA7C72883F5dc049");
console.log(`All balances: ${toJSON(balances)}`);

getBalance

Returns the user's balance as a bigint object for an (optional) block tag and (optional) token.

When block and token are not supplied, committed and ETH are the default values.

Inputs

ParameterTypeDescription
addressAddressAccount address.
blockTag?BlockTagBlock tag for getting the balance on. Latest committed block is default (optional).
tokenAddress?AddressToken address. ETH is default (optional).
async getBalance(address: Address, blockTag?: BlockTag, tokenAddress?: Address)

Example

import { Provider, types } from "zksync-ethers";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);
const account = "0x36615Cf349d7F6344891B1e7CA7C72883F5dc049";
const tokenAddress = "0x927488F48ffbc32112F1fF721759649A89721F8F"; // Crown token which can be minted for free
console.log(`ETH balance: ${await provider.getBalance(account)}`);
console.log(`Token balance: ${await provider.getBalance(account, "latest", tokenAddres)}`);

getBaseTokenContractAddress

Returns the L1 base token address.

Calls the zks_getBaseTokenL1Address JSON-RPC method.

async getBaseTokenContractAddress(): Promise<Address>

Example

import { Provider, types } from "zksync-ethers";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);
console.log(`Base token: ${await provider.getBaseTokenContractAddress()}`);

getBlock

Returns block from the network, or false if there is no block.

Inputs

ParameterTypeDescription
blockHashOrBlockTagBlockTagBlock tag for getting the balance on.
includeTxs?booleanWhether to fetch transactions that are in block (optional).
async getBlock(blockHashOrBlockTag: BlockTag, includeTxs?: boolean): Promise<Block>

Example

Helper function: toJSON.

import { Provider, types } from "zksync-ethers";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);
console.log(`Block: ${toJSON(await provider.getBlock("latest", true))}`);

getBlockDetails

Returns additional ZKsync-specific information about the L2 block.

Calls the zks_getBlockDetails JSON-RPC method.

Inputs

ParameterTypeDescription
numbernumberBlock number.
async getBlockDetails(number:number): Promise<BlockDetails>

Example

Helper function: toJSON.

import { Provider, types } from "zksync-ethers";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);
console.log(`Block details: ${toJSON(await provider.getBlockDetails(90_000))}`);

getBridgehubContractAddress

Returns the Bridgehub smart contract address.

Calls the zks_getBridgehubContract JSON-RPC method.

async getBridgehubContractAddress(): Promise<Address>

Example

import { Provider, types } from "zksync-ethers";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);
console.log(`Bridgehub: ${await provider.getBridgehubContractAddress()}`);

getBytecodeByHash

Returns bytecode of a contract given by its hash.

Calls the zks_getBytecodeByHash JSON-RPC method.

Inputs

ParameterTypeDescription
bytecodeHashBytesLikeBytecode hash.
async getBytecodeByHash(bytecodeHash: BytesLike): Promise<Uint8Array>

Example

import { Provider, types } from "zksync-ethers";

// Bytecode hash can be computed by following these steps:
// const testnetPaymasterBytecode = await provider.getCode(await provider.getTestnetPaymasterAddress());
// const testnetPaymasterBytecodeHash = ethers.hexlify(utils.hashBytecode(testnetPaymasterBytecode));

const testnetPaymasterBytecodeHash = "0x010000f16d2b10ddeb1c32f2c9d222eb1aea0f638ec94a81d4e916c627720e30";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);
console.log(`Bytecode: ${await provider.getBytecodeByHash(testnetPaymasterBytecodeHash)}`);

getConfirmedTokens

Returns confirmed tokens. Confirmed token is any token bridged to ZKsync Era via the official bridge.

Calls the zks_getConfirmedTokens JSON-RPC method.

Inputs

ParameterTypeDescription
startAddressThe token id from which to start. Default 0.
limitAddressThe maximum number of tokens to list. Default 255.
async getConfirmedTokens(start: number = 0, limit: number = 255): Promise<Token[]>

Example

Helper function: toJSON.

import { Provider, types, utils } from "zksync-ethers";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);
const tokens = await provider.getConfirmedTokens();
console.log(`Confirmed tokens: ${utils.toJSON(tokens)}`);

getContractAccountInfo

Returns the version of the supported account abstraction and nonce ordering from a given contract address.

Inputs

ParameterTypeDescription
addressAddressContract address.
async getContractAccountInfo(address:Address): Promise<ContractAccountInfo>

Example

Helper function: toJSON.

import { Provider, types } from "zksync-ethers";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);
const tokenAddress = "0x927488F48ffbc32112F1fF721759649A89721F8F"; // Crown token which can be minted for free
console.log(`Contract account info: ${toJSON(await provider.getContractAccountInfo(tokenAddress))}`);

getDefaultBridgeAddresses

Returns the addresses of the default ZKsync Era bridge contracts on both L1 and L2.

getDefaultBridgeAddresses(): Promise<{
  erc20L1: string;
  erc20L2: string;
  wethL1: string;
  wethL2: string;
  sharedL1: string;
  sharedL2: string;
}>

Example

Helper function: toJSON.

import { Provider, types } from "zksync-ethers";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);
console.log(`Default bridges: ${toJSON(await provider.getDefaultBridgeAddresses())}`);

connectL2Bridge

Returns contract wrapper. If given address is shared bridge address it returns Il2SharedBridge and if its legacy it returns Il2Bridge.

Inputs

ParameterTypeDescription
address'Address'The bridge address.
async connectL2Bridge(address: Address): Promise<Il2SharedBridge | Il2Bridge>

Example

import { Provider, types } from "zksync-ethers";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);
const l2Bridge = await provider.connectL2Bridge("<L2_BRIDGE_ADDRESS>");

isL2BridgeLegacy

Returns true if passed bridge address is legacy and false if its shared bridge.

Inputs

ParameterTypeDescription
address'Address'The bridge address.
async isL2BridgeLegacy(address: Address): Promise<boolean>

Example

import { Provider, types } from "zksync-ethers";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);
const isBridgeLegacy = await provider.isL2BridgeLegacy("<L2_BRIDGE_ADDRESS>");
console.log(isBridgeLegacy);

getDefaultProvider

Static method which returns a Provider object from the RPC URL or localhost.

Inputs

ParameterTypeDescription
zksyncNetworkZkSyncNetworkType of ZKsync network. Localhost by default.
static getDefaultProvider(zksyncNetwork: ZkSyncNetwork = ZkSyncNetwork.Localhost)

Example

import { Provider, types } from "zksync-ethers";

const providerMainnet = Provider.getDefaultProvider(types.Network.Mainnet);
const providerTestnet = Provider.getDefaultProvider(types.Network.Sepolia);
const providerLocalnet = Provider.getDefaultProvider(types.Network.Localhost);

getFeeParams

Returns the current fee parameters.

Calls the zks_getFeeParams JSON-RPC method.

async getFeeParams(): Promise<FeeParams>

Example

Helper function: toJSON.

import { Provider, types, utils } from "zksync-ethers";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);
const feeParams = await provider.getFeeParams();
console.log(`Fee: ${utils.toJSON(feeParams)}`);

getFilterChanges

Returns an array of logs by calling Ethereum method eth_getFilterChanges.

Inputs

ParameterTypeDescription
idxbigintFilter index.
async getFilterChanges(idx: bigint): Promise<Array<Log | string>>

Example

import { Provider, types, utils } from "zksync-ethers";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);
const filter = await provider.newFilter({
  address: utils.L2_ETH_TOKEN_ADDRESS,
  topics: [ethers.id("Transfer(address,address,uint256)")],
});
const result = await provider.getFilterChanges(filter);

getGasPrice

Returns an estimate (best guess) of the gas price to use in a transaction.

async getGasPrice(): Promise<bigint>

Example

import { Provider, types } from "zksync-ethers";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);
console.log(`Gas price: ${await provider.getGasPrice()}`);

getL1BatchBlockRange

Returns the range of blocks contained within a batch given by batch number.

Calls the zks_getL1BatchBlockRange JSON-RPC method.

Inputs

ParameterTypeDescription
l1BatchNumbernumberL1 batch number.
async getL1BatchBlockRange(l1BatchNumber: number): Promise<[number, number] | null>

Example

Helper function: toJSON.

import { Provider, types } from "zksync-ethers";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);
const l1BatchNumber = await provider.getL1BatchNumber();
console.log(`L1 batch block range: ${toJSON(await provider.getL1BatchBlockRange(l1BatchNumber))}`);

getL1BatchDetails

Returns data pertaining to a given batch.

Calls the zks_getL1BatchDetails JSON-RPC method.

Inputs

ParameterTypeDescription
numbernumberL1 batch number.
async getL1BatchDetails(number: number): Promise<BatchDetails>

Example

Helper function: toJSON.

import { Provider, types } from "zksync-ethers";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);
const l1BatchNumber = await provider.getL1BatchNumber();
console.log(`L1 batch details: ${toJSON(await provider.getL1BatchDetails(l1BatchNumber))}`);

getL1BatchNumber

Returns the latest L1 batch number.

Calls the zks_getL1BatchNumber JSON-RPC method.

async getL1BatchNumber(): Promise<number>

Example

import { Provider, types } from "zksync-ethers";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);
console.log(`L1 batch number: ${await provider.getL1BatchNumber()}`);

getL2TransactionFromPriorityOp

Returns a L2 transaction from L1 transaction response.

Inputs

ParameterTypeDescription
l1TxResponseTransactionResponseL1 transaction response.
async getL2TransactionFromPriorityOp(l1TxResponse: ethers.TransactionResponse): Promise<TransactionResponse>

Example

Helper function: toJSON.

import { Provider, types } from "zksync-ethers";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);
const ethProvider = ethers.getDefaultProvider("sepolia");
const l1Tx = "0xcca5411f3e514052f4a4ae1c2020badec6e0998adb52c09959c5f5ff15fba3a8";
const l1TxResponse = await ethProvider.getTransaction(l1Tx);
if (l1TxResponse) {
  console.log(`Tx: ${toJSON(await provider.getL2TransactionFromPriorityOp(l1TxResponse))}`);
}

getLogProof

Returns the proof for a transaction's L2 to L1 log sent via the L1Messenger system contract.

Calls the zks_getL2ToL1LogProof JSON-RPC method.

Inputs

ParameterTypeDescription
txHashBytesLikeHash of the L2 transaction the L2 to L1 log was produced within.
index?numberThe index of the L2 to L1 log in the transaction (optional).
async getLogProof(txHash: BytesLike, index ? : number): Promise<MessageProof | null>

Example

Helper function: toJSON.

import { Provider, types } from "zksync-ethers";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);
// Any L2 -> L1 transaction can be used.
// In this case, withdrawal transaction is used.
const tx = "0x2a1c6c74b184965c0cb015aae9ea134fd96215d2e4f4979cfec12563295f610e";
console.log(`Log ${toJSON(await provider.getLogProof(tx, 0))}`);

getLogs

Returns an array of all logs that match a filter with a given id by calling Ethereum method eth_getLogs.

Inputs

ParameterTypeDescription
filterFilter or FilterByBlockHashFilter query.
async getLogs(filter: Filter | FilterByBlockHash): Promise<Log[]>

Example

Helper function: toJSON.

import { Provider, types, utils } from "zksync-ethers";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);
console.log(`Logs: ${toJSON(await provider.getLogs({ fromBlock: 0, toBlock: 5, address: utils.L2_ETH_TOKEN_ADDRESS }))}`);

getMainContractAddress

Returns the main ZKsync Era smart contract address.

Calls the zks_getMainContract JSON-RPC method.

async getMainContractAddress(): Promise<Address>

Example

import { Provider, types } from "zksync-ethers";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);
console.log(`Main contract: ${await provider.getMainContractAddress()}`);

getPriorityOpConfirmation

Returns the transaction confirmation data that is part of L2->L1 message.

Inputs

NameTypeDescription
txHashBytesLikeHash of the L2 transaction where the withdrawal was initiated.
index?numberIn case there were multiple transactions in one message, you may pass an index of the transaction which confirmation data should be fetched. Defaults to 0 (optional).
async getPriorityOpConfirmation(txHash: string, index: number = 0): Promise<{
  l1BatchNumber: number;
  l2MessageIndex: number;
  l2TxNumberInBlock: number;
  proof: string[]
}>

Example

Helper function: toJSON.

import { Provider, types, utils } from "zksync-ethers";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);
// Any L2 -> L1 transaction can be used.
// In this case, withdrawal transaction is used.
const tx = "0x2a1c6c74b184965c0cb015aae9ea134fd96215d2e4f4979cfec12563295f610e";
console.log(`Confirmation data: ${utils.toJSON(await provider.getPriorityOpConfirmation(tx, 0))}`);

getPriorityOpResponse

Returns a TransactionResponse as a PriorityOpResponse object.

Inputs

ParameterTypeDescription
l1TxResponseTransactionResponseL1 transaction response.
async getPriorityOpResponse(l1TxResponse: ethers.TransactionResponse): Promise<PriorityOpResponse>

Example

Helper function: toJSON.

import { Provider, types } from "zksync-ethers";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);
const ethProvider = ethers.getDefaultProvider("sepolia");
const l1Tx = "0xcca5411f3e514052f4a4ae1c2020badec6e0998adb52c09959c5f5ff15fba3a8";
const l1TxResponse = await ethProvider.getTransaction(l1Tx);
if (l1TxResponse) {
  console.log(`Tx: ${toJSON(await provider.getPriorityOpResponse(l1TxResponse))}`);
}

getProof

Returns Merkle proofs for one or more storage values at the specified account along with a Merkle proof of their authenticity.

Calls the zks_getProof JSON-RPC method.

Inputs

ParameterTypeDescription
addressAddressThe account to fetch storage values and proofs for.
keysstring[]Vector of storage keys in the account.
l1BatchNumbernumberNumber of the L1 batch specifying the point in time at which the requested values are returned.
async getProof(address: Address, keys: string[], l1BatchNumber: number): Promise<StorageProof>

Example

Helper function: toJSON.

import { Provider, types, utils } from "zksync-ethers";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);
const address = "0x082b1BB53fE43810f646dDd71AA2AB201b4C6b04";

// Fetching the storage proof for rawNonces storage slot in NonceHolder system contract.
// mapping(uint256 => uint256) internal rawNonces;

// Ensure the address is a 256-bit number by padding it
// because rawNonces slot uses uint256 for mapping addresses and their nonces.
const addressPadded = ethers.zeroPadValue(address, 32);

// Convert the slot number to a hex string and pad it to 32 bytes.
const slotPadded = ethers.zeroPadValue(ethers.toBeHex(0), 32);

// Concatenate the padded address and slot number.
const concatenated = addressPadded + slotPadded.slice(2); // slice to remove '0x' from the slotPadded

// Hash the concatenated string using Keccak-256.
const storageKey = ethers.keccak256(concatenated);

const l1BatchNumber = await provider.getL1BatchNumber();
const storageProof = await provider.getProof(utils.NONCE_HOLDER_ADDRESS, [storageKey], l1BatchNumber);
console.log(`Storage proof: ${toJSON(storageProof)}`);

getProtocolVersion

Return the protocol version.

Calls the zks_getProtocolVersion JSON-RPC method.

Inputs

ParameterTypeDescription
idnumberSpecific version ID (optional).
async getProtocolVersion(id?: number): Promise<ProtocolVersion>

Example

import { Provider, types } from "zksync-ethers";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);
console.log(`Protocol version: ${await provider.getProtocolVersion()}`);

getRawBlockTransactions

Returns data of transactions in a block.

Calls the zks_getRawBlockTransactions JSON-RPC method.

Inputs

ParameterTypeDescription
numbernumberBlock number.
async getRawBlockTransactions(number: number): Promise<RawBlockTransaction[]>

Example

Helper function: toJSON.

import { Provider, types } from "zksync-ethers";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);
console.log(`Raw block transactions: ${toJSON(await provider.getRawBlockTransactions(90_000))}`);

getTestnetPaymasterAddress

Returns the testnet paymaster address if available, or null.

async getTestnetPaymasterAddress(): Promise<Address | null>

Example

import { Provider, types } from "zksync-ethers";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);
console.log(`Testnet paymaster: ${await provider.getTestnetPaymasterAddress()}`);

getTransaction

Returns a specified L2 transaction response object by overriding the Ethers implementation.

Inputs

ParameterTypeDescription
txHashstringTransaction hash.
async getTransaction(txHash: string): Promise<TransactionResponse>

Example

import { Provider, types } from "zksync-ethers";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);

const TX_HASH = "<YOUR_TX_HASH_ADDRESS>";
const txHandle = await provider.getTransaction(TX_HASH);

// Wait until the transaction is processed by the server.
await txHandle.wait();
// Wait until the transaction is finalized.
await txHandle.waitFinalize();

getTransactionDetails

Returns data from a specific transaction given by the transaction hash.

Calls the zks_getTransactionDetails JSON-RPC method.

Inputs

ParameterTypeDescription
txHashBytesLikeTransaction hash.
async getTransactionDetails(txHash: BytesLike): Promise<TransactionDetails>

Example

Helper function: toJSON.

import { Provider, types } from "zksync-ethers";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);

const TX_HASH = "<YOUR_TX_HASH_ADDRESS>";
console.log(`Transaction details: ${toJSON(await provider.getTransactionDetails(TX_HASH))}`);

getTransactionReceipt

Returns the transaction receipt from a given hash number.

Ethers implementation.

Inputs

ParameterTypeDescription
txHashstringTransaction hash.
async getTransactionReceipt(txHash: string): Promise<TransactionReceipt>

Example

Helper function: toJSON.

import { Provider, types } from "zksync-ethers";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);
const TX_HASH = "<YOUR_TX_HASH_ADDRESS>";
console.log(`Transaction receipt: ${toJSON(await provider.getTransactionReceipt(TX_HASH))}`);

getTransactionStatus

Returns the status of a specified transaction.

Inputs

ParameterTypeDescription
txHashstringTransaction hash.
async getTransactionStatus(txHash: string): Promise<TransactionStatus>

Example

Helper function: toJSON.

import { Provider, types } from "zksync-ethers";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);

const TX_HASH = "<YOUR_TX_HASH_ADDRESS>";
console.log(`Transaction status: ${toJSON(await provider.getTransactionStatus(TX_HASH))}`);

getTransferTx

Returns the populated transfer transaction.

Inputs

ParameterTypeDescription
tokenAddressToken address.
amountBigNumberishAmount of token.
from?AddressFrom address (optional).
to?AddressTo address (optional).
paymasterParams?PaymasterParamsPaymaster parameters (optional).
overrides?ethers.OverridesTransaction's overrides which may be used to pass l2 gasLimit, gasPrice, value, etc (optional).
async getTransferTx(transaction: {
  to: Address;
  amount: BigNumberish;
  from ? : Address;
  token ? : Address;
  paymasterParams?: PaymasterParams;
  overrides ? : ethers.Overrides;
}): Promise<EthersTransactionRequest>

Examples

Retrieve populated ETH transfer transaction.

import { Provider, types, utils } from "zksync-ethers";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);

const tx = await provider.getTransferTx({
  token: utils.ETH_ADDRESS,
  amount: 7_000_000_000,
  to: "0xa61464658AfeAf65CccaaFD3a512b69A83B77618",
  from: "0x36615Cf349d7F6344891B1e7CA7C72883F5dc049",
});
console.log(`Transfer tx: ${tx}`);

Retrieve populated ETH transfer transaction using paymaster to facilitate fee payment with an ERC20 token.

import { Provider, types, utils } from "zksync-ethers";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);
const token = "0x927488F48ffbc32112F1fF721759649A89721F8F"; // Crown token which can be minted for free
const paymaster = "0x13D0D8550769f59aa241a41897D4859c87f7Dd46"; // Paymaster for Crown token

const tx = await provider.getTransferTx({
  token: utils.ETH_ADDRESS,
  amount: 7_000_000_000,
  to: "0xa61464658AfeAf65CccaaFD3a512b69A83B77618",
  from: "0x36615Cf349d7F6344891B1e7CA7C72883F5dc049",
  paymasterParams: utils.getPaymasterParams(paymaster, {
    type: "ApprovalBased",
    token: token,
    minimalAllowance: 1,
    innerInput: new Uint8Array(),
  }),
});
console.log(`Transfer tx: ${tx}`);

getWithdrawTx

Returns the populated withdrawal transaction.

Inputs

ParameterTypeDescription
tokenAddressToken address.
amountBigNumberishAmount of token.
from?AddressFrom address (optional).
to?AddressTo address (optional).
bridgeAddress?AddressBridge address (optional).
paymasterParams?PaymasterParamsPaymaster parameters (optional).
overrides?ethers.OverridesTransaction's overrides which may be used to pass l2 gasLimit, gasPrice, value, etc (optional).
async getWithdrawTx(transaction: {
  token: Address;
  amount: BigNumberish;
  from ? : Address;
  to ? : Address;
  bridgeAddress ? : Address;
  paymasterParams?: PaymasterParams;
  overrides ? : ethers.Overrides;
}): Promise<EthersTransactionRequest>

Examples

Retrieve populated ETH withdrawal transactions.

import { Provider, types, utils } from "zksync-ethers";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);

const tx = await provider.getWithdrawTx({
  token: utils.ETH_ADDRESS,
  amount: 7_000_000_000,
  to: "0x36615Cf349d7F6344891B1e7CA7C72883F5dc049",
  from: "0x36615Cf349d7F6344891B1e7CA7C72883F5dc049",
});
console.log(`Withdrawal tx: ${tx}`);

Retrieve populated ETH withdrawal transaction using paymaster to facilitate fee payment with an ERC20 token.

import { Provider, types, utils } from "zksync-ethers";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);
const token = "0x927488F48ffbc32112F1fF721759649A89721F8F"; // Crown token which can be minted for free
const paymaster = "0x13D0D8550769f59aa241a41897D4859c87f7Dd46"; // Paymaster for Crown token

const tx = await provider.getWithdrawTx({
  token: utils.ETH_ADDRESS,
  amount: 7_000_000_000,
  to: "0x36615Cf349d7F6344891B1e7CA7C72883F5dc049",
  from: "0x36615Cf349d7F6344891B1e7CA7C72883F5dc049",
  paymasterParams: utils.getPaymasterParams(paymaster, {
    type: "ApprovalBased",
    token: token,
    minimalAllowance: 1,
    innerInput: new Uint8Array(),
  }),
});
console.log(`Withdrawal tx: ${tx}`);

isBaseToken

Returns whether the token is the base token.

Inputs

ParameterTypeDescription
tokenAddressThe address of the token.
async isBaseToken(token: Address): Promise<string>

Example

import { Provider, types } from "zksync-ethers";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);
console.log(`Is base token: ${await provider.isBaseToken("0x5C221E77624690fff6dd741493D735a17716c26B")}`);

isEthBasedChain

Returns whether the chain is ETH-based.

async isEthBasedChain(): Promise<boolean>

Example

import { Provider, types } from "zksync-ethers";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);
console.log(`Is ETH based chain: ${await provider.isEthBasedChain()}`);

l1ChainId

Returns the chain id of the underlying L1.

Calls the zks_L1ChainId JSON-RPC method.

async l1ChainId(): Promise<number>

Example

import { Provider, types } from "zksync-ethers";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);
console.log(`L1 chain ID: ${await provider.l1ChainId()}`);

l1TokenAddress

Returns the L1 token address equivalent for a L2 token address as they are not equal. ETH's address is set to zero address.

Only works for tokens bridged on default ZKsync Era bridges.

Inputs

ParameterTypeDescription
tokenAddressThe address of the token on L2.
async l1TokenAddress(token: Address): Promise<string>

Example

import { Provider, types } from "zksync-ethers";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);
console.log(`L1 token address: ${await provider.l1TokenAddress("0x3e7676937A7E96CFB7616f255b9AD9FF47363D4b")}`);

l2TokenAddress

Returns the L2 token address equivalent for a L1 token address as they are not equal. ETH's address is set to zero address.

Only works for tokens bridged on default ZKsync Era bridges.

Inputs

ParameterTypeDescription
tokenAddressThe address of the token on L1.
bridgeAddress?AddressThe address of the custom bridge on L2(optional).
async l2TokenAddress(token: Address): Promise<string>

Example

import { Provider, types } from "zksync-ethers";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);
console.log(`L2 token address: ${await provider.l2TokenAddress("0x5C221E77624690fff6dd741493D735a17716c26B")}`);

newBlockFilter

Returns a new block filter by calling Ethereum method eth_newBlockFilter.

async newBlockFilter(): Promise<bigint>

Example

import { Provider, types } from "zksync-ethers";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);
console.log(`New block filter: ${await provider.newBlockFilter()}`);

newFilter

Returns a new filter by calling Ethereum method eth_newFilter and passing a filter object.

Inputs

ParameterTypeDescription
filterFilterByBlockHash or FilterFilter query.
async newFilter(filter: FilterByBlockHash | Filter): Promise<bigint>

Example

import { Provider, types, utils } from "zksync-ethers";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);
console.log(
  `New filter: ${await provider.newFilter({
    fromBlock: 0,
    toBlock: 5,
    address: utils.L2_ETH_TOKEN_ADDRESS,
  })}`
);

newPendingTransactionFilter

Returns a new pending transaction filter by calling Ethereum method eth_newPendingTransactionFilter and passing a filter object.

async newPendingTransactionsFilter(): Promise<bigint>

Example

import { Provider, types } from "zksync-ethers";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);
console.log(`New pending transaction filter: ${await provider.newPendingTransactionsFilter()}`);

sendRawTransactionWithDetailedOutput

Executes a transaction and returns its hash, storage logs, and events that would have been generated if the transaction had already been included in the block. The API has a similar behaviour to eth_sendRawTransaction but with some extra data returned from it.

With this API Consumer apps can apply "optimistic" events in their applications instantly without having to wait for ZKsync block confirmation time.

It’s expected that the optimistic logs of two uncommitted transactions that modify the same state will not have causal relationships between each other.

Calls the zks_sendRawTransactionWithDetailedOutput JSON-RPC method.

Inputs

ParameterTypeDescription
signedTxstringThe signed transaction that needs to be broadcasted.
async sendRawTransactionWithDetailedOutput(signedTx: string): Promise<TransactionWithDetailedOutput>

Example

Helper function: toJSON.

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

const PRIVATE_KEY = "<PRIVATE_KEY>";
const provider = Provider.getDefaultProvider(types.Network.Sepolia);
const wallet = new Wallet(PRIVATE_KEY, provider);

const txWithOutputs = await provider.sendRawTransactionWithDetailedOutput(
  await wallet.signTransaction({
    to: Wallet.createRandom().address,
    value: ethers.parseEther("0.01"),
  })
);

console.log(`Transaction with detailed output: ${utils.toJSON(txWithOutputs)}`);

BrowserProvider

Use this provider for Web3 browser wallet integrations for easy compatibility with Metamask, WalletConnect, and other popular browser wallets.

constructor

Returns a provider object by extending the constructor of the Provider class and accepting an Eip1193Provider instead of a node URL.

Inputs

ParameterTypeDescription
ethereumEip1193ProviderThe Eip1193Provider class instance. For instance, Metamask is window.ethereum.
network?NetworkishNetwork name (optional).
constructor(ethereum: Eip1193Provider, network?: Networkish)

Example

import { BrowserProvider } from "zksync-ethers";

const provider = new BrowserProvider(window.ethereum);

estimateGas

Returns gas estimate by overriding the ZKsync Era estimateGas method.

Inputs

ParameterTypeDescription
transactionTransactionRequestTransaction request.
async estimateGas(transaction: TransactionRequest): Promise<bigint>

Example

import { BrowserProvider } from "zksync-ethers";

const provider = new BrowserProvider(window.ethereum);
const gas = await provider.estimateGas({
  to: "<RECEIVER>",
  amount: ethers.parseEther("0.01"),
});
console.log(`Gas: ${gas}`);

getSigner

Override of Ethers implementation.

Inputs

ParameterTypeDescription
address?number or stringAccount address or index (optional).
async getSigner(address ? : number | string): Promise<Signer>

Example

import { BrowserProvider } from "zksync-ethers";

const provider = new BrowserProvider(window.ethereum);
const signer = await provider.getSigner();

send

Returns a provider request object by overriding the Ethers implementation.

Inputs

ParameterTypeDescription
methodAddressRequest method name as string.
params?Array<any>Parameters of any type (optional).
async send(method: string, params?: Array<any>): Promise <any>

Appendix

toJSON

function toJSON(object: any): string {
  return JSON.stringify(object, (key, value) => {
    if (typeof value === "bigint") {
      return value.toString(); // Convert BigInt to string
    }
    return value;
  });
}