Accounts


Accounts

Overview

The zkSync Python SDK has a method that generates a signature and a method that verifies messages.

  • Wallet
  • sign_typed_data : used to sign EIP712-typed zkSync transactions.
  • verify_typed_data : used to verify the signed EIP712-typed zkSync transactions.

construction

For constructing the instance it needs only account and chain_id.

Example

from zksync2.signer.eth_signer import PrivateKeyEthSigner
from eth_account import Account
from zksync2.module.module_builder import ZkSyncBuilder


account = Account.from_key("PRIVATE_KEY")
zksync_web3 = ZkSyncBuilder.build("ZKSYNC_NETWORK_URL")

chain_id = zksync_web3.zksync.chain_id
signer = PrivateKeyEthSigner(account, chain_id)

sign_typed_data

The signer is used to generate the signature of the provided transaction based on your account(your private key).

Parameters

ParametersReturn valueDescription
EIP712 Structure, optional domainWeb3 py SignedMessageBuilds SignedMessage based on the encoded in EIP712 format Transaction.

verify_typed_data

It's used to verify the provided transaction, whose signature is added to the final EIP712 transaction for its validation.

Parameters

ParametersReturn valueDescription
signature, EIP712 structure, optional domainboolReturns True if the encoded transaction is signed with provided signature.

The signer class also has the following properties:

AttributeDescription
addressAccount address
domainDomain that is used to generate signature. It depends on chain_id of network.

Wallet

Creating wallet from a private key

The Wallet object can be created from 'BaseAccount'.

Inputs and outputs

NameDescription
zksync_web3A zkSync node provider. Needed for interaction with zkSync.
eth_web3An Ethereum node provider. Needed for interaction with L1.
l1_accountBase account used to associate with wallet.
returnsThe new Wallet object.

Example

from eth_account import Account
from eth_account.signers.local import LocalAccount
from web3 import Web3

from zksync2.account.wallet import Wallet
from zksync2.module.module_builder import ZkSyncBuilder

if __name__ == "__main__":
  ZKSYNC_PROVIDER = "https://sepolia.era.zksync.dev"
  ETH_PROVIDER = "https://rpc.ankr.com/eth_sepolia"
  zk_web3 = ZkSyncBuilder.build(ZKSYNC_PROVIDER)
  eth_web3 = Web3(Web3.HTTPProvider(ETH_PROVIDER))
  account: LocalAccount = Account.from_key(private_key)
  wallet = Wallet(zk_web3, eth_web3, account)

mainContract

Inputs and outputs

NameDescription
returnsContract of the zkSync smart contract.

Example

from eth_account import Account
from eth_account.signers.local import LocalAccount
from web3 import Web3

from zksync2.account.wallet import Wallet
from zksync2.module.module_builder import ZkSyncBuilder

if __name__ == "__main__":
  ZKSYNC_PROVIDER = "https://sepolia.era.zksync.dev"
  ETH_PROVIDER = "https://rpc.ankr.com/eth_sepolia"

  zk_web3 = ZkSyncBuilder.build(ZKSYNC_PROVIDER)
  eth_web3 = Web3(Web3.HTTPProvider(ETH_PROVIDER))

  account: LocalAccount = Account.from_key(private_key)
  wallet = Wallet(zk_web3, eth_web3, account)

  contract = wallet.main_contract
  print(contract.address);

get_l1_bridge_contracts

Returns Contract wrapper of the zkSync smart contract.

Inputs and outputs

NameDescription
returnsL1BridgeContracts object.

Example

from eth_account import Account
from eth_account.signers.local import LocalAccount
from web3 import Web3
from zksync2.account.wallet import Wallet
from zksync2.module.module_builder import ZkSyncBuilder

ZKSYNC_PROVIDER = "https://sepolia.era.zksync.dev"
ETH_PROVIDER = "https://rpc.ankr.com/eth_sepolia"

zk_web3 = ZkSyncBuilder.build(ZKSYNC_PROVIDER)
eth_web3 = Web3(Web3.HTTPProvider(ETH_PROVIDER))

account: LocalAccount = Account.from_key("PRIVATE_KEY")
wallet = Wallet(zk_web3, eth_web3, account)

l1_bridge_contracts = wallet.get_l1_bridge_contracts()

Note

there is no separate Ether bridge contract, Main contract is used instead.

get_l2_bridge_contracts

Returns L2 bridge contracts.

Example

from eth_account import Account
from eth_account.signers.local import LocalAccount
from web3 import Web3
from zksync2.account.wallet import Wallet
from zksync2.module.module_builder import ZkSyncBuilder

ZKSYNC_PROVIDER = "https://sepolia.era.zksync.dev"
ETH_PROVIDER = "https://rpc.ankr.com/eth_sepolia"

zk_web3 = ZkSyncBuilder.build(ZKSYNC_PROVIDER)
eth_web3 = Web3(Web3.HTTPProvider(ETH_PROVIDER))

account: LocalAccount = Account.from_key("PRIVATE_KEY")
wallet = Wallet(zk_web3, eth_web3, account)

l2_bridge_contracts = await wallet.get_l2_bridge_contracts()

get_balance

Returns the amount of the token the Wallet has.

Inputs and outputs

NameDescription
block_tagThe block the balance should be checked on. committed, i.e. the latest processed one is the default option.
token_addressThe address of the token. ETH by default.
returnsThe amount of the token the Wallet has.

Example

from eth_account import Account
from eth_account.signers.local import LocalAccount
from web3 import Web3

from zksync2.account.wallet import Wallet
from zksync2.module.module_builder import ZkSyncBuilder

if __name__ == "__main__":
  ZKSYNC_PROVIDER = "https://sepolia.era.zksync.dev"
  ETH_PROVIDER = "https://rpc.ankr.com/eth_sepolia"

  zk_web3 = ZkSyncBuilder.build(ZKSYNC_PROVIDER)
  eth_web3 = Web3(Web3.HTTPProvider(ETH_PROVIDER))

  account: LocalAccount = Account.from_key("PRIVATE_KEY")
  wallet = Wallet(zk_web3, eth_web3, account)


  balance = wallet.get_balance()
  print(balance)

get_l1_balance

Returns the amount of the token the Wallet has on Ethereum.

Inputs and outputs

NameDescription
tokenThe address of the token. ETH by default.
blockThe block the balance should be checked on. The latest processed one is the default option.
returnsThe amount of the token the Wallet has on Ethereum.

Example

from eth_account import Account
from eth_account.signers.local import LocalAccount
from web3 import Web3

from zksync2.account.wallet import Wallet
from zksync2.module.module_builder import ZkSyncBuilder

if __name__ == "__main__":
  ZKSYNC_PROVIDER = "https://sepolia.era.zksync.dev"
  ETH_PROVIDER = "https://rpc.ankr.com/eth_sepolia"

  zk_web3 = ZkSyncBuilder.build(ZKSYNC_PROVIDER)
  eth_web3 = Web3(Web3.HTTPProvider(ETH_PROVIDER))

  account: LocalAccount = Account.from_key("PRIVATE_KEY")
  wallet = Wallet(zk_web3, eth_web3, account)


  balance = wallet.get_l1_balance()
  print(balance)

get_all_balances

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

Inputs and outputs

NameDescription
returnsZksAccountBalances with all account balances.

Example

from eth_account import Account
from eth_account.signers.local import LocalAccount
from web3 import Web3

from zksync2.account.wallet import Wallet
from zksync2.module.module_builder import ZkSyncBuilder

if __name__ == "__main__":
  ZKSYNC_PROVIDER = "https://sepolia.era.zksync.dev"
  ETH_PROVIDER = "https://rpc.ankr.com/eth_sepolia"

  zk_web3 = ZkSyncBuilder.build(ZKSYNC_PROVIDER)
  eth_web3 = Web3(Web3.HTTPProvider(ETH_PROVIDER))

  account: LocalAccount = Account.from_key("PRIVATE_KEY")
  wallet = Wallet(zk_web3, eth_web3, account)


  balance = wallet.get_l1_balance()
  print(balance)

get_deployment_nonce

Returns account's deployment nonce number.

Inputs and outputs

NameDescription
returnsThe deployment nonce number.

Example

from eth_account import Account
from eth_account.signers.local import LocalAccount
from web3 import Web3

from zksync2.account.wallet import Wallet
from zksync2.module.module_builder import ZkSyncBuilder

if __name__ == "__main__":
  ZKSYNC_PROVIDER = "https://sepolia.era.zksync.dev"
  ETH_PROVIDER = "https://rpc.ankr.com/eth_sepolia"

  zk_web3 = ZkSyncBuilder.build(ZKSYNC_PROVIDER)
  eth_web3 = Web3(Web3.HTTPProvider(ETH_PROVIDER))

  account: LocalAccount = Account.from_key("PRIVATE_KEY")
  wallet = Wallet(zk_web3, eth_web3, account)


  nonce = wallet.get_deployment_nonce()

l2_token_address

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

Note

Only works for tokens bridged on default zkSync Era bridges.

Inputs

ParameterTypeDescription
addressAddressThe address of the token on L2.

Example

from eth_account import Account
from eth_account.signers.local import LocalAccount
from web3 import Web3

from zksync2.account.wallet import Wallet
from zksync2.module.module_builder import ZkSyncBuilder

if __name__ == "__main__":
  ZKSYNC_PROVIDER = "https://sepolia.era.zksync.dev"
  ETH_PROVIDER = "https://rpc.ankr.com/eth_sepolia"

  zk_web3 = ZkSyncBuilder.build(ZKSYNC_PROVIDER)
  eth_web3 = Web3(Web3.HTTPProvider(ETH_PROVIDER))

  account: LocalAccount = Account.from_key("PRIVATE_KEY")
  wallet = Wallet(zk_web3, eth_web3, account)


  l2_address = wallet.l2_token_address("L1_ADDRESS")

transfer

For convenience, the Wallet class has transfer method, which can transfer ETH or any ERC20 token within the same interface.

Inputs and outputs

NameDescription
txTransferTransaction.
returnsA HexStr of transaction.

Example

from eth_account import Account
from eth_account.signers.local import LocalAccount
from web3 import Web3

from zksync2.account.wallet import Wallet
from zksync2.module.module_builder import ZkSyncBuilder
from zksync2.core.types import TransferTransaction, ADDRESS_DEFAULT

if __name__ == "__main__":
  ZKSYNC_PROVIDER = "https://sepolia.era.zksync.dev"
  ETH_PROVIDER = "https://rpc.ankr.com/eth_sepolia"

  zk_web3 = ZkSyncBuilder.build(ZKSYNC_PROVIDER)
  eth_web3 = Web3(Web3.HTTPProvider(ETH_PROVIDER))

  account: LocalAccount = Account.from_key("PRIVATE_KEY")
  wallet = Wallet(zk_web3, eth_web3, account)

  amount = 7_000_000_000
  tx_hash = wallet.transfer(TransferTransaction(to=Web3.to_checksum_address("TO_ADDRESS"),
  token_address=ADDRESS_DEFAULT,
  amount=amount))

  tx_receipt = zk_web3.zksync.wait_for_transaction_receipt(
    tx_hash, timeout=240, poll_latency=0.5
  )

Transfer ETH using paymaster to facilitate fee payment with an ERC20 token.

from eth_account import Account
from eth_account.signers.local import LocalAccount
from web3 import Web3

from zksync2.account.wallet import Wallet
from zksync2.module.module_builder import ZkSyncBuilder
from zksync2.core.types import TransferTransaction, ADDRESS_DEFAULT, PaymasterParams
from zksync2.manage_contracts.paymaster_utils import PaymasterFlowEncoder


if __name__ == "__main__":
  ZKSYNC_PROVIDER = "https://sepolia.era.zksync.dev"
  ETH_PROVIDER = "https://rpc.ankr.com/eth_sepolia"

  zk_web3 = ZkSyncBuilder.build(ZKSYNC_PROVIDER)
  eth_web3 = Web3(Web3.HTTPProvider(ETH_PROVIDER))

  account: LocalAccount = Account.from_key("PRIVATE_KEY")
  wallet = Wallet(zk_web3, eth_web3, account)

  paymaster_address = zk_web3.to_checksum_address("0x13D0D8550769f59aa241a41897D4859c87f7Dd46")
  token_address = zk_web3.to_checksum_address("0x927488F48ffbc32112F1fF721759649A89721F8F")


  paymaster_params = PaymasterParams(
            **{
                "paymaster": paymaster_address,
                "paymaster_input": eth_web3.to_bytes(
                    hexstr=PaymasterFlowEncoder(eth_web3).encode_approval_based(
                        token_address, 1, b""
                    )
                ),
            }
        )

  amount = 7_000_000_000
  tx_hash = wallet.transfer(
              TransferTransaction(
                  to=Web3.to_checksum_address("TO_ADDRESS"),
                  amount=amount,
                  paymaster_params=paymaster_params,
              )
          )

  tx_receipt = zk_web3.zksync.wait_for_transaction_receipt(
    tx_hash, timeout=240, poll_latency=0.5
  )

getAllowanceL1

Returns the amount of approved tokens for a specific L1 bridge.

Inputs

ParameterTypeDescription
tokenAddressThe Ethereum address of the token.
bridge_addressAddressThe address of the bridge contract to be used. Defaults to the default zkSync bridge, either L1EthBridge or L1Erc20Bridge (optional).

Example

from eth_account import Account
from eth_account.signers.local import LocalAccount
from eth_typing import HexStr
from web3 import Web3

from zksync2.account.wallet import Wallet
from zksync2.module.module_builder import ZkSyncBuilder

if __name__ == "__main__":
  ZKSYNC_PROVIDER = "https://sepolia.era.zksync.dev"
  ETH_PROVIDER = "https://rpc.ankr.com/eth_sepolia"

  zk_web3 = ZkSyncBuilder.build(ZKSYNC_PROVIDER)
  eth_web3 = Web3(Web3.HTTPProvider(ETH_PROVIDER))

  account: LocalAccount = Account.from_key("PRIVATE_KEY")
  wallet = Wallet(zk_web3, eth_web3, account)
  l1_address = HexStr("0x5C221E77624690fff6dd741493D735a17716c26B")

  result = wallet.get_allowance_l1(HexStr(l1_address))

approve_erc20

Bridging ERC20 tokens from Ethereum requires approving the tokens to the zkSync Ethereum smart contract.

Inputs

ParameterTypeDescription
tokenAddressThe Ethereum address of the token.
amountintThe amount of the token to be approved.
bridge_addressAddressThe address of the bridge contract to be used. Defaults to the default zkSync bridge, either L1EthBridge or L1Erc20Bridge (optional).
gas_limitint

Example

from eth_account import Account
from eth_account.signers.local import LocalAccount
from eth_typing import HexStr
from web3 import Web3

from zksync2.account.wallet import Wallet
from zksync2.module.module_builder import ZkSyncBuilder

if __name__ == "__main__":
  ZKSYNC_PROVIDER = "https://sepolia.era.zksync.dev"
  ETH_PROVIDER = "https://rpc.ankr.com/eth_sepolia"

  zk_web3 = ZkSyncBuilder.build(ZKSYNC_PROVIDER)
  eth_web3 = Web3(Web3.HTTPProvider(ETH_PROVIDER))

  account: LocalAccount = Account.from_key("PRIVATE_KEY")
  wallet = Wallet(zk_web3, eth_web3, account)
  l1_address = HexStr("0x56E69Fa1BB0d1402c89E3A4E3417882DeA6B14Be")

  result = wallet.approve_erc20(HexStr(l1_address), 10000000)

getBaseCost

Returns base cost for L2 transaction.

Inputs

NameTypeDescription
l2_gas_limitintThe l2_gas_limit for the L2 contract call.
gas_per_pubdata_byteintThe L2 gas price for each published L1 calldata byte (optional).
gas_priceintThe L1 gas price of the L1 transaction that will send the request for an execute call (optional).

Example

from eth_account import Account
from eth_account.signers.local import LocalAccount
from web3 import Web3

from zksync2.account.wallet import Wallet
from zksync2.module.module_builder import ZkSyncBuilder

if __name__ == "__main__":
  ZKSYNC_PROVIDER = "https://sepolia.era.zksync.dev"
  ETH_PROVIDER = "https://rpc.ankr.com/eth_sepolia"

  zk_web3 = ZkSyncBuilder.build(ZKSYNC_PROVIDER)
  eth_web3 = Web3(Web3.HTTPProvider(ETH_PROVIDER))

  account: LocalAccount = Account.from_key("PRIVATE_KEY")
  wallet = Wallet(zk_web3, eth_web3, account)

  result = wallet.get_base_cost(l2_gas_limit=100_000)

deposit

Transfers the specified token from the associated account on the L1 network to the target account on the L2 network. The token can be either ETH or any ERC20 token. For ERC20 tokens, enough approved tokens must be associated with the specified L1 bridge (default one or the one defined in transaction.bridge_address). In this case, transaction.approve_erc20 can be enabled to perform token approval. If there are already enough approved tokens for the L1 bridge, token approval will be skipped. To check the amount of approved tokens for a specific bridge, use the get_allowance_l1 method.

Inputs

NameDescription
transactionDeposittransaction
returnsHash of the transaction.

Example

from eth_account import Account
from eth_account.signers.local import LocalAccount
from web3 import Web3
from zksync2.account.wallet import Wallet
from zksync2.module.module_builder import ZkSyncBuilder
from zksync2.core.types import TransactionOptions, DepositTransaction, ADDRESS_DEFAULT


ZKSYNC_PROVIDER = "https://sepolia.era.zksync.dev"
ETH_PROVIDER = "https://rpc.ankr.com/eth_sepolia"

zk_web3 = ZkSyncBuilder.build(ZKSYNC_PROVIDER)
eth_web3 = Web3(Web3.HTTPProvider(ETH_PROVIDER))

account: LocalAccount = Account.from_key("PRIVATE_KEY")
wallet = Wallet(zk_web3, eth_web3, account)

l1_address = HexStr("0x56E69Fa1BB0d1402c89E3A4E3417882DeA6B14Be")
l1_hash_erc20 = wallet.deposit(DepositTransaction(Web3.to_checksum_address(l1_address),
                                            10000000,
                                            account.address,
                                            approve_erc20=True))

l1_tx_receipt_erc20 = eth_web3.eth.wait_for_transaction_receipt(l1_hash_erc20)

l1_hash_eth = wallet.deposit(DepositTransaction(token=ADDRESS_DEFAULT,
                                        amount=10000000,
                                        to=wallet.address))

l1_tx_receipt_eth = eth_web3.eth.wait_for_transaction_receipt(l1_hash_eth)

prepare_deposit_tx

Returns populated deposit transaction.

Inputs

NameDescription
transactionDeposittransaction

Example

from eth_account import Account
from eth_account.signers.local import LocalAccount
from web3 import Web3
from zksync2.account.wallet import Wallet
from zksync2.module.module_builder import ZkSyncBuilder
from zksync2.core.types import TransactionOptions, DepositTransaction, ADDRESS_DEFAULT


ZKSYNC_PROVIDER = "https://sepolia.era.zksync.dev"
ETH_PROVIDER = "https://rpc.ankr.com/eth_sepolia"

zk_web3 = ZkSyncBuilder.build(ZKSYNC_PROVIDER)
eth_web3 = Web3(Web3.HTTPProvider(ETH_PROVIDER))

account: LocalAccount = Account.from_key("PRIVATE_KEY")
wallet = Wallet(zk_web3, eth_web3, account)

l1_address = HexStr("0x56E69Fa1BB0d1402c89E3A4E3417882DeA6B14Be")
deposit_erc20 = wallet.prepare_deposit_tx(DepositTransaction(Web3.to_checksum_address(l1_address),
                                            10000000,
                                            account.address,
                                            approve_erc20=True))

deposit_eth = wallet.prepare_deposit_tx(DepositTransaction(token=ADDRESS_DEFAULT,
                                        amount=10000000,
                                        to=wallet.address))

estimate_gas_deposit

Estimates the amount of gas required for a deposit transaction on L1 network. Gas of approving ERC20 token is not included in estimation.

Inputs

NameDescription
transactionDeposittransaction

Example

from eth_account import Account
from eth_account.signers.local import LocalAccount
from web3 import Web3
from zksync2.account.wallet import Wallet
from zksync2.module.module_builder import ZkSyncBuilder
from zksync2.core.types import TransactionOptions, DepositTransaction, ADDRESS_DEFAULT


ZKSYNC_PROVIDER = "https://sepolia.era.zksync.dev"
ETH_PROVIDER = "https://rpc.ankr.com/eth_sepolia"

zk_web3 = ZkSyncBuilder.build(ZKSYNC_PROVIDER)
eth_web3 = Web3(Web3.HTTPProvider(ETH_PROVIDER))

account: LocalAccount = Account.from_key("PRIVATE_KEY")
wallet = Wallet(zk_web3, eth_web3, account)

l1_address = HexStr("0x56E69Fa1BB0d1402c89E3A4E3417882DeA6B14Be")
estimated_gas_erc20 = wallet.estimate_gas_deposit(DepositTransaction(Web3.to_checksum_address(l1_address),
                                            10000000,
                                            account.address,
                                            approve_erc20=True))

estimated_gas_eth = wallet.estimate_gas_deposit(DepositTransaction(token=ADDRESS_DEFAULT,
                                        amount=10000000,
                                        to=wallet.address))

getFullRequiredDepositFee

Retrieves the full needed ETH fee for the deposit. Returns the L1 fee and the L2 fee FullDepositFee.

Inputs

NameDescription
transactionDeposittransaction

Example

from eth_account import Account
from eth_account.signers.local import LocalAccount
from web3 import Web3
from zksync2.account.wallet import Wallet
from zksync2.module.module_builder import ZkSyncBuilder
from zksync2.core.types import TransactionOptions, DepositTransaction, ADDRESS_DEFAULT


ZKSYNC_PROVIDER = "https://sepolia.era.zksync.dev"
ETH_PROVIDER = "https://rpc.ankr.com/eth_sepolia"

zk_web3 = ZkSyncBuilder.build(ZKSYNC_PROVIDER)
eth_web3 = Web3(Web3.HTTPProvider(ETH_PROVIDER))

account: LocalAccount = Account.from_key("PRIVATE_KEY")
wallet = Wallet(zk_web3, eth_web3, account)

full_deposit_fee_eth = wallet.get_full_required_deposit_fee(DepositTransaction(token=ADDRESS_DEFAULT, to=wallet.address))

claimFailedDeposit

The claim_failed_deposit method withdraws funds from the initiated deposit, which failed when finalizing on L2.
If the deposit L2 transaction has failed, it sends an L1 transaction calling claimFailedDeposit method of the L1 bridge, which results in returning L1 tokens back to the depositor, otherwise throws the error.

Inputs

ParameterTypeDescription
depositHashHexStrThe L2 transaction hash of the failed deposit.

Example

from eth_account import Account
from eth_account.signers.local import LocalAccount
from web3 import Web3
from zksync2.account.wallet import Wallet
from zksync2.module.module_builder import ZkSyncBuilder


ZKSYNC_PROVIDER = "https://sepolia.era.zksync.dev"
ETH_PROVIDER = "https://rpc.ankr.com/eth_sepolia"

zk_web3 = ZkSyncBuilder.build(ZKSYNC_PROVIDER)
eth_web3 = Web3(Web3.HTTPProvider(ETH_PROVIDER))

account: LocalAccount = Account.from_key("PRIVATE_KEY")
wallet = Wallet(zk_web3, eth_web3, account)

claim_failed_deposit_handle = wallet.get_full_required_deposit_fee(HexStr("<FAILED_DEPOSIT_TX_HASH>"))

withdraw

Initiates the withdrawal process which withdraws ETH or any ERC20 token from the associated account on L2 network to the target account on L1 network.

Inputs

NameDescription
transactionWithdrawTransaction

Example

from eth_account import Account
from eth_account.signers.local import LocalAccount
from web3 import Web3
from zksync2.account.wallet import Wallet
from zksync2.module.module_builder import ZkSyncBuilder
from zksync2.core.types import WithdrawTransaction, ADDRESS_DEFAULT


ZKSYNC_PROVIDER = "https://sepolia.era.zksync.dev"
ETH_PROVIDER = "https://rpc.ankr.com/eth_sepolia"

zk_web3 = ZkSyncBuilder.build(ZKSYNC_PROVIDER)
eth_web3 = Web3(Web3.HTTPProvider(ETH_PROVIDER))

account: LocalAccount = Account.from_key("PRIVATE_KEY")
wallet = Wallet(zk_web3, eth_web3, account)

withdraw_tx_hash = wallet.withdraw(
    WithdrawTransaction(
        token=ADDRESS_DEFAULT, amount=Web3.to_wei(1, "ether")
    )
)

withdraw_receipt = zk_web3.zksync.wait_for_transaction_receipt(
    withdraw_tx_hash, timeout=240, poll_latency=0.5
)

Withdraw ETH using paymaster to facilitate fee payment with an ERC20 token.

from eth_account import Account
from eth_account.signers.local import LocalAccount
from web3 import Web3
from zksync2.account.wallet import Wallet
from zksync2.module.module_builder import ZkSyncBuilder
from zksync2.core.types import WithdrawTransaction, ADDRESS_DEFAULT


ZKSYNC_PROVIDER = "https://sepolia.era.zksync.dev"
ETH_PROVIDER = "https://rpc.ankr.com/eth_sepolia"

zk_web3 = ZkSyncBuilder.build(ZKSYNC_PROVIDER)
eth_web3 = Web3(Web3.HTTPProvider(ETH_PROVIDER))

account: LocalAccount = Account.from_key("PRIVATE_KEY")
wallet = Wallet(zk_web3, eth_web3, account)

paymaster_address = zk_web3.to_checksum_address(HexStr("0x13D0D8550769f59aa241a41897D4859c87f7Dd46"))
token_address = zk_web3.to_checksum_address(HexStr("0x927488F48ffbc32112F1fF721759649A89721F8F"))

paymaster_params = PaymasterParams(
    **{
        "paymaster": paymaster_address,
        "paymaster_input": eth_web3.to_bytes(
            hexstr=PaymasterFlowEncoder(eth_web3).encode_approval_based(
                token_address, 1, b""
            )
        ),
    }
)

withdraw_tx_hash = wallet.withdraw(
    WithdrawTransaction(
        token=ADDRESS_DEFAULT, amount=Web3.to_wei(1, "ether"), paymaster_params=paymaster_params
    )
)

withdraw_receipt = zk_web3.zksync.wait_for_transaction_receipt(
    withdraw_tx_hash, timeout=240, poll_latency=0.5
)

finalizeWithdrawal

Proves the inclusion of the L2 -> L1 withdrawal message.

Inputs

NameTypeDescription
withdraw_hashHexStrHash of the L2 transaction where the withdrawal was initiated.
index?numberIn case there were multiple withdrawals in one transaction, you may pass an index of the withdrawal you want to finalize. Defaults to 0 (optional).

Example

from eth_account import Account
from eth_account.signers.local import LocalAccount
from web3 import Web3
from zksync2.account.wallet import Wallet
from zksync2.module.module_builder import ZkSyncBuilder


ZKSYNC_PROVIDER = "https://sepolia.era.zksync.dev"
ETH_PROVIDER = "https://rpc.ankr.com/eth_sepolia"

zk_web3 = ZkSyncBuilder.build(ZKSYNC_PROVIDER)
eth_web3 = Web3(Web3.HTTPProvider(ETH_PROVIDER))

account: LocalAccount = Account.from_key("PRIVATE_KEY")
wallet = Wallet(zk_web3, eth_web3, account)

withdraw_tx_hash = wallet.finalize_withdrawal("<WITHDRAWAL_TX_HASH>")

is_withdrawal_finalized

Returns whether the withdrawal transaction is finalized on the L1 network.

Inputs

NameTypeDescription
withdraw_hashHexStrHash of the L2 transaction where the withdrawal was initiated.
indexnumberIn case there were multiple withdrawals in one transaction, you may pass an index of the withdrawal you want to finalize. Defaults to 0 (optional).

Example

from eth_account import Account
from eth_account.signers.local import LocalAccount
from web3 import Web3
from zksync2.account.wallet import Wallet
from zksync2.module.module_builder import ZkSyncBuilder


ZKSYNC_PROVIDER = "https://sepolia.era.zksync.dev"
ETH_PROVIDER = "https://rpc.ankr.com/eth_sepolia"

zk_web3 = ZkSyncBuilder.build(ZKSYNC_PROVIDER)
eth_web3 = Web3(Web3.HTTPProvider(ETH_PROVIDER))

account: LocalAccount = Account.from_key("PRIVATE_KEY")
wallet = Wallet(zk_web3, eth_web3, account)

withdraw_tx_hash = wallet.is_withdrawal_finalized("<WITHDRAWAL_TX_HASH>")

requestExecute

Request execution of L2 transaction from L1. Return hash of the transaction

Inputs

NameDescription
transactionRequestExecuteCallMsg object

Example

from eth_account import Account
from eth_account.signers.local import LocalAccount
from web3 import Web3
from eth_typing import HexStr
from zksync2.account.wallet import Wallet
from zksync2.module.module_builder import ZkSyncBuilder
from zksync2.core.types import TransactionOptions, DepositTransaction, ADDRESS_DEFAULT, RequestExecuteCallMsg


ZKSYNC_PROVIDER = "https://sepolia.era.zksync.dev"
ETH_PROVIDER = "https://rpc.ankr.com/eth_sepolia"

zk_web3 = ZkSyncBuilder.build(ZKSYNC_PROVIDER)
eth_web3 = Web3(Web3.HTTPProvider(ETH_PROVIDER))

account: LocalAccount = Account.from_key("PRIVATE_KEY")
wallet = Wallet(zk_web3, eth_web3, account)

amount = 7_000_000_000

l1_tx_receipt = wallet.request_execute(RequestExecuteCallMsg(contract_address=Web3.to_checksum_address(zk_web3.zksync.main_contract_address),call_data=HexStr("0x"),l2_value=amount,
                                                             l2_gas_limit=900_000))

l2_hash = zk_web3.zksync.get_l2_hash_from_priority_op(l1_tx_receipt, wallet.main_contract)
zk_web3.zksync.wait_for_transaction_receipt(l2_hash)

get_request_execute_transaction

Returns populated request execute transaction.

Inputs

NameDescription
transactionRequestExecuteCallMsg object

Example

from eth_account import Account
from eth_account.signers.local import LocalAccount
from web3 import Web3
from eth_typing import HexStr
from zksync2.account.wallet import Wallet
from zksync2.module.module_builder import ZkSyncBuilder
from zksync2.core.types import TransactionOptions, DepositTransaction, ADDRESS_DEFAULT, RequestExecuteCallMsg


ZKSYNC_PROVIDER = "https://sepolia.era.zksync.dev"
ETH_PROVIDER = "https://rpc.ankr.com/eth_sepolia"

zk_web3 = ZkSyncBuilder.build(ZKSYNC_PROVIDER)
eth_web3 = Web3(Web3.HTTPProvider(ETH_PROVIDER))

account: LocalAccount = Account.from_key("PRIVATE_KEY")
wallet = Wallet(zk_web3, eth_web3, account)

amount = 7_000_000_000
l2_balance_before = wallet.get_balance()

request_execute_transaction = wallet.get_request_execute_transaction(RequestExecuteCallMsg(contract_address=Web3.to_checksum_address(zk_web3.zksync.main_contract_address),
                                                                                     call_data=HexStr("0x"),l2_value=amount,l2_gas_limit=900_000))

estimateGasRequestExecute

Estimates the amount of gas required for a request execute transaction.

Inputs

NameDescription
transactionRequestExecuteCallMsg object

Example

from eth_account import Account
from eth_account.signers.local import LocalAccount
from web3 import Web3
from eth_typing import HexStr
from zksync2.account.wallet import Wallet
from zksync2.module.module_builder import ZkSyncBuilder
from zksync2.core.types import TransactionOptions, DepositTransaction, ADDRESS_DEFAULT, RequestExecuteCallMsg


ZKSYNC_PROVIDER = "https://sepolia.era.zksync.dev"
ETH_PROVIDER = "https://rpc.ankr.com/eth_sepolia"

zk_web3 = ZkSyncBuilder.build(ZKSYNC_PROVIDER)
eth_web3 = Web3(Web3.HTTPProvider(ETH_PROVIDER))

account: LocalAccount = Account.from_key("PRIVATE_KEY")
wallet = Wallet(zk_web3, eth_web3, account)

amount = 7_000_000_000
l2_balance_before = wallet.get_balance()

estimated_gas = wallet.estimate_gas_request_execute(RequestExecuteCallMsg(contract_address=Web3.to_checksum_address(zk_web3.zksync.main_contract_address),
                                                                                     call_data=HexStr("0x"),l2_value=amount,l2_gas_limit=900_000))