zks_ RPC
Public ZKsync zks_* RPC methods exposed on the adapters via client.zks (Bridgehub address, Bytecode Supplier address, block metadata, L2→L1 log proofs, receipts with l2ToL1Logs).
Standard Ethereum RPC (eth_*)
Use your base library for all eth_* methods.
The client.zks surface only covers ZKsync-specific RPC (zks_*).
For standard Ethereum JSON-RPC (e.g., eth_call, eth_getLogs, eth_getBalance), call them through your chosen library (ethers or viem).
zks_ Interface
export interface ZksRpc {
// Fetches the Bridgehub contract address.
getBridgehubAddress(): Promise<Address>;
// Fetches the Bytecode Supplier contract address.
getBytecodeSupplierAddress(): Promise<Address>;
// Fetches a proof for an L2→L1 log emitted in the given transaction.
getL2ToL1LogProof(txHash: Hex, index: number): Promise<ProofNormalized>;
// Fetches the transaction receipt, including the `l2ToL1Logs` field.
getReceiptWithL2ToL1(txHash: Hex): Promise<ReceiptWithL2ToL1 | null>;
// Fetches block metadata for the given block number.
getBlockMetadataByNumber(blockNumber: number): Promise<BlockMetadata | null>;
// Fetches the genesis configuration returned by `zks_getGenesis`.
getGenesis(): Promise<GenesisInput>;
}
Methods
getBridgehubAddress() → Promise<Address>
Fetch the on-chain Bridgehub contract address.
const addr = await client.zks.getBridgehubAddress();
getBytecodeSupplierAddress() → Promise<Address>
Fetch the on-chain Bytecode Supplier contract address.
const addr = await client.zks.getBytecodeSupplierAddress();
getL2ToL1LogProof(txHash: Hex, index: number) → Promise<ProofNormalized>
Return a normalized proof for the L2→L1 log at index in txHash.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
txHash | Hex | yes | L2 transaction hash that emitted one or more L2→L1 logs. |
index | number | yes | Zero-based index of the target L2→L1 log within the tx. |
const proof = await client.zks.getL2ToL1LogProof(l2TxHash, 0);
/*
{
id: bigint,
batchNumber: bigint,
proof: Hex[]
}
*/
[!INFO] If a proof isn’t available yet, this method throws a typed
STATEerror. Poll according to your app’s cadence.
getReceiptWithL2ToL1(txHash: Hex) → Promise<ReceiptWithL2ToL1 | null>
Fetch the transaction receipt; the returned object always includes l2ToL1Logs (empty array if none).
const rcpt = await client.zks.getReceiptWithL2ToL1(l2TxHash);
console.log("L2 to L1 logs:", rcpt?.l2ToL1Logs); // always an array
getBlockMetadataByNumber(blockNumber: number)
What it does
Fetches per-block metadata used by the node (pubdata price, native price, execution version).
Returns null if the block metadata is unavailable.
Price fields are returned as bigint.
Example
const meta = await client.zks.getBlockMetadataByNumber(2);
if (meta) {
console.log(meta.pubdataPricePerByte, meta.nativePrice, meta.executionVersion);
}
Returns
type BlockMetadata = {
pubdataPricePerByte: bigint;
nativePrice: bigint;
executionVersion: number;
};
getGenesis()
What it does Retrieves the L2 genesis configuration exposed by the node, including initial contract deployments, storage patches, execution version, and the expected genesis root.
Example
const genesis = await client.zks.getGenesis();
for (const contract of genesis.initialContracts) {
console.log('Contract at', contract.address, 'with bytecode', contract.bytecode);
}
console.log('Execution version:', genesis.executionVersion);
console.log('Genesis root:', genesis.genesisRoot);
Returns
export type GenesisInput = {
initialContracts: GenesisContractDeployment[];
additionalStorage: GenesisStorageEntry[];
executionVersion: number;
genesisRoot: Hex;
};
Types (overview)
export interface ZksRpc {
// Fetches the Bridgehub contract address.
getBridgehubAddress(): Promise<Address>;
// Fetches the Bytecode Supplier contract address.
getBytecodeSupplierAddress(): Promise<Address>;
// Fetches a proof for an L2→L1 log emitted in the given transaction.
getL2ToL1LogProof(txHash: Hex, index: number): Promise<ProofNormalized>;
// Fetches the transaction receipt, including the `l2ToL1Logs` field.
getReceiptWithL2ToL1(txHash: Hex): Promise<ReceiptWithL2ToL1 | null>;
// Fetches block metadata for the given block number.
getBlockMetadataByNumber(blockNumber: number): Promise<BlockMetadata | null>;
// Fetches the genesis configuration returned by `zks_getGenesis`.
getGenesis(): Promise<GenesisInput>;
}
type ProofNormalized = {
id: bigint;
batchNumber: bigint;
proof: Hex[];
root: Hex;
};
type ReceiptWithL2ToL1 = {
transactionIndex: Hex;
transactionHash?: Hex;
status?: string | number;
blockNumber?: string | number;
logs?: Array<{
address: Address;
topics: Hex[];
data: Hex;
transactionHash: Hex;
}>;
// ZKsync-specific field
l2ToL1Logs?: L2ToL1Log[];
};
type BlockMetadata = {
pubdataPricePerByte: bigint;
nativePrice: bigint;
executionVersion: number;
};
export type GenesisInput = {
initialContracts: GenesisContractDeployment[];
additionalStorage: GenesisStorageEntry[];
executionVersion: number;
genesisRoot: Hex;
};
Usage
Ethers
import { JsonRpcProvider, Wallet } from 'ethers';
import { createEthersClient, createEthersSdk } from '@matterlabs/zksync-js/ethers';
const l1 = new JsonRpcProvider(process.env.L1_RPC!);
const l2 = new JsonRpcProvider(process.env.L2_RPC!);
const signer = new Wallet(process.env.PRIVATE_KEY!, l1);
const client = createEthersClient({ l1, l2, signer });
const sdk = createEthersSdk(client);
// Public RPC surface:
const addr = await client.zks.getBridgehubAddress();
Viem
import { createPublicClient, createWalletClient, http, parseEther } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
import { createViemClient, createViemSdk } from '@matterlabs/zksync-js/viem';
import { ETH_ADDRESS } from '@matterlabs/zksync-js/core';
const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`);
const l1 = createPublicClient({ transport: http(process.env.L1_RPC!) });
const l2 = createPublicClient({ transport: http(process.env.L2_RPC!) });
const l1Wallet = createWalletClient({ chain: l1Chain, account, transport: http(process.env.L1_RPC!) });
const l2Wallet = createWalletClient({ chain: l2Chain, account, transport: http(process.env.L2_RPC!) });
const client = createViemClient({ l1, l2, l1Wallet, l2Wallet });
const sdk = createViemSdk(client);
// Public RPC surface:
const addr = await client.zks.getBridgehubAddress();