Accounts
Overview
The accounts
package provides abstractions that wrap operations that interact with an account. An account typically
contains a private key, allowing it to sign various types of payloads. There are the following interfaces that provide
account operations for different purposes:
Signer
provides support for signing EIP-712 transactions as well as other types of transactions supported bytypes.Signer
.AdapterL1
is associated with an account and provides common operations on the L1 network for the associated account.AdapterL2
is associated with an account and provides common operations on the L2 network for the associated account.Deployer
is associated with an account and provides deployment of smart contracts and smart accounts on the L2 network for the associated account.Adapter
consists ofAdapterL1
,AdapterL2
, andDeployer
interfaces.
There are the following objects that provide account operations:
BaseSigner
implements theSigner
interface.WalletL1
implements theAdapterL1
interface.WalletL2
implements theAdapterL2
interface.BaseDeployer
implements theDeployer
interface.Wallet
implements theAdapter
interface.SmartAccount
which provides better support for account abstraction. There are following factory methods:NewECDSASmartAccount
: uses a single ECDSA key for signing payload.NewMultisigECDSASmartAccount
: uses multiple ECDSA keys for signing payloads.
In most cases, Wallet
should be used because it provides all the necessary operations. Other objects and interfaces
are separated to make the SDK more flexible and extensible.
BaseSigner
Init
Creates a new instance of BaseSigner
based on the provided mnemonic phrase.
func NewBaseSignerFromMnemonic(mnemonic string, chainId int64) (*BaseSigner, error)
Creates a new instance of BaseSigner
based on the provided mnemonic phrase and account ID.
func NewBaseSignerFromMnemonicAndAccountId(mnemonic string, accountId uint32, chainId int64) (*BaseSigner, error)
Creates a new instance of BaseSigner based on the provided raw private key.
func NewBaseSignerFromRawPrivateKey(rawPk []byte, chainId int64) (*BaseSigner, error)
Creates an instance of Signer with a randomly generated private key.
func NewRandomBaseSigner(chainId int64) (*BaseSigner, error)
Address
Returns the address associated with the signer.
Address() common.Address
Domain
Returns the EIP-712 domain used for signing.
Domain() *eip712.Domain
PrivateKey
Returns the private key associated with the signer.
PrivateKey() *ecdsa.PrivateKey
Signs the given hash using the signer's private key and returns the signature. The hash should be the 32-byte hash of the data to be signed.
SignHash
SignHash(msg []byte) ([]byte, error)
SignTypeData
Signs the given EIP-712 typed data using the signer's private key and returns the signature. The domain parameter is the EIP-712 domain separator, and the data parameter is the EIP-712 typed data.
SignTypedData(d *eip712.Domain, data eip712.TypedData) ([]byte, error)
WalletL1
Init
Creates an instance of WalletL1 associated with the account provided by the raw private key.
func NewWalletL1(rawPrivateKey []byte, clientL1 *ethclient.Client, clientL2 *clients.Client) (*WalletL1, error
Creates an instance of WalletL1 associated with the account provided by the signer.
NewWalletL1FromSigner(signer *Signer, clientL1 *ethclient.Client, clientL2 *clients.Client) (*WalletL1, error)
Example
PrivateKey := os.Getenv("PRIVATE_KEY")
ZkSyncEraProvider := "https://sepolia.era.zksync.dev"
EthereumProvider := "https://rpc.ankr.com/eth_sepolia"
client, err := clients.Dial(ZkSyncEraProvider)
if err != nil {
log.Panic(err)
}
defer client.Close()
ethClient, err := ethclient.Dial(EthereumProvider)
if err != nil {
log.Panic(err)
}
defer ethClient.Close()
wallet, err := accounts.NewWalletL1(common.Hex2Bytes(PrivateKey), &client, ethClient)
if err != nil {
log.Panic(err)
}
MainContract
Returns the ZKsync L1 smart contract.
Inputs
Parameter | Type | Description |
---|---|---|
ctx | context.Context | Context. |
MainContract(ctx context.Context) (*zksync.IZkSync, error)
Example
mainContract, err := wallet.MainContract(context.Background())
if err != nil {
log.Panic(err)
}
BridgehubContract
Returns the Bridgehub L1 smart contract.
Inputs
Parameter | Type | Description |
---|---|---|
ctx | context.Context | Context. |
BridgehubContract(_ context.Context) (*bridgehub.IBridgehub, error)
Example
bridgehub, err := wallet.BridgehubContract(context.Background())
if err != nil {
log.Panic(err)
}
L1BridgeContracts
Returns L1 bridge contracts.
Inputs
Parameter | Type | Description |
---|---|---|
ctx | context.Context | Context. |
L1BridgeContracts(ctx context.Context) (*zkTypes.L1BridgeContracts, error)
Example
contracts, err := wallet.L1BridgeContracts(context.Background())
if err != nil {
log.Panic(err)
}
BaseToken
Returns the address of the base token on L1.
Inputs
Parameter | Type | Description |
---|---|---|
opts | CallOpts (optional) | Call options. |
BaseToken(opts *CallOpts) (common.Address, error)
Example
baseToken, err := wallet.BaseToken(nil)
if err != nil {
log.Panic(err)
}
fmt.Println("Base token: ", baseToken)
IsEthBasedChain
Returns whether the chain is ETH-based.
Inputs
Parameter | Type | Description |
---|---|---|
ctx | context.Context | Context. |
IsEthBasedChain(ctx context.Context) (bool, error)
Example
isEthBased, err := wallet.IsEthBasedChain(context.Background())
if err != nil {
log.Panic(err)
}
fmt.Println("Is ETH-based chain: ", isEthBased)
BalanceL1
Returns the balance of the specified token on L1 that can be either ETH or any ERC20 token.
Inputs
Parameter | Type | Description |
---|---|---|
opts | CallOpts (optional) | Call options. |
token | common.Address | Token address. |
BalanceL1(opts *CallOpts, token common.Address) (*big.Int, error)
Example
balance, err := wallet.BalanceL1(nil, utils.EthAddress)
if err != nil {
log.Panic(err)
}
fmt.Println("Balance: ", balance)
AllowanceL1
Returns the amount of approved tokens for a specific L1 bridge.
Inputs
Parameter | Type | Description |
---|---|---|
opts | CallOpts (optional) | Call options. |
token | common.Address | Token address. |
bridgeAddress | common.Address | Bridge address. |
AllowanceL1(opts *CallOpts, token common.Address, bridgeAddress common.Address) (*big.Int, error)
Example
// The Crown token on testnet
TokenAddress := common.HexToAddress("0x927488F48ffbc32112F1fF721759649A89721F8F")
contracts, err := client.BridgeContracts(context.Background())
if err != nil {
log.Panic(err)
}
bridgeAllowance, err := wallet.AllowanceL1(nil, TokenAddress, contracts.L1Erc20DefaultBridge)
if err != nil {
log.Panic(err)
}
fmt.Println("Bridge allowance: ", bridgeAllowance)
L2TokenAddress
Returns the corresponding address on the L2 network for the token on the L1 network.
Inputs
Parameter | Type | Description |
---|---|---|
ctx | context.Context | Context. |
token | common.Address | L1 token address. |
L2TokenAddress(ctx context.Context, token common.Address) (common.Address, error)
Example
l1DAI := common.HexToAddress("0x5C221E77624690fff6dd741493D735a17716c26B")
l2DAI, err := wallet.L2TokenAddress(context.Background(), l1DAI)
if err != nil {
log.Panic(err)
}
fmt.Println("L2 DAI address: ", l2DAI)
ApproveERC20
Approves the specified amount of tokens for the specified L1 bridge.
Inputs
Parameter | Type | Description |
---|---|---|
ctx | context.Context | Context. |
token | common.Address | L1 token address. |
amount | *big.Int | Approval amount. |
ApproveERC20(auth *TransactOpts, token common.Address, amount *big.Int, bridgeAddress common.Address) (*types.Transaction, error)
Example
// The Crown token on testnet
TokenAddress := common.HexToAddress("0x927488F48ffbc32112F1fF721759649A89721F8F")
contracts, err := client.BridgeContracts(context.Background())
if err != nil {
log.Panic(err)
}
tx, err := wallet.ApproveERC20(nil, TokenAddress, contracts.L1Erc20DefaultBridge)
if err != nil {
log.Panic(err)
}
fmt.Println("Tx: ", tx.Hash())
BaseCost
Returns base cost for L2 transaction.
Inputs
Parameter | Type | Description |
---|---|---|
opts | CallOpts (optional) | Call options. |
gasLimit | *big.Int | The gasLimit for the the L2 contract call. |
gasPerPubdataByte | *big.Int | The L2 gas price for each published L1 calldata byte. |
gasPrice | *big.Int (optional) | The L1 gas price of the L1 transaction that will send the request for an execute call. |
BaseCost(opts *CallOpts, gasLimit, gasPerPubdataByte, gasPrice *big.Int) (*big.Int, error)
Example
gasPrice, err := client.SuggestGasPrice(context.Background())
if err != nil {
log.Panic(err)
}
baseCost, err := wallet.BaseCost(nil, big.NewInt(9000), utils.RequiredL1ToL2GasPerPubdataLimit, gasPrice)
if err != nil {
log.Panic(err)
}
fmt.Println("Base cost: ", baseCost)
DepositAllowanceParams
Returns the parameters for the approval token transaction based on the deposit token and amount. Some deposit transactions require multiple approvals. Existing allowance for the bridge is not checked; allowance is calculated solely based on the specified amount.
Inputs
Parameter | Type | Description |
---|---|---|
opts | CallOpts (optional) | Call options. |
msg | DepositCallMsg | Deposit call parameters. |
DepositAllowanceParams(opts *CallOpts, msg DepositCallMsg) ([]struct {
Token common.Address
Allowance *big.Int
}, error)
Example
Get allowance parameters for depositing token on ETH-based chain.
msg := accounts.DepositCallMsg{
Token: common.HexToAddress("<L1 token address>"),
To: Receiver,
Amount: big.NewInt(5),
}
allowanceParams, err := wallet.DepositAllowanceParams(nil, msg)
if err != nil {
log.Panic(err)
}
bridgeContracts, err := client.BridgeContracts(context.Background())
if err != nil {
log.Panic(err)
}
approveTx, err := wallet.ApproveERC20(nil, allowanceParams[0].Token, allowanceParams[0].Allowance, bridgeContracts.L1SharedBridge)
if err != nil {
log.Panic(err)
}
_, err = bind.WaitMined(context.Background(), ethClient, approveTx)
if err != nil {
log.Panic(err)
}
Get allowance parameters for depositing ETH on non-ETH-based chain.
msg := accounts.DepositCallMsg{
Token: utils.LegacyEthAddress,
To: Receiver,
Amount: big.NewInt(7_000_000_000),
}
allowanceParams, err := wallet.DepositAllowanceParams(nil, msg)
if err != nil {
log.Panic(err)
}
bridgeContracts, err := client.BridgeContracts(context.Background())
if err != nil {
log.Panic(err)
}
approveTx, err := wallet.ApproveERC20(nil, allowanceParams[0].Token, allowanceParams[0].Allowance, bridgeContracts.L1SharedBridge)
if err != nil {
log.Panic(err)
}
_, err = bind.WaitMined(context.Background(), ethClient, approveTx)
if err != nil {
log.Panic(err)
}
Get allowance parameters for depositing base token on non-ETH-based chain.
token, err := wallet.BaseToken(nil)
if err != nil {
log.Panic(err)
}
msg := accounts.DepositCallMsg{
Token: token,
To: Receiver,
Amount: big.NewInt(7_000_000_000),
}
allowanceParams, err := wallet.DepositAllowanceParams(nil, msg)
if err != nil {
log.Panic(err)
}
bridgeContracts, err := client.BridgeContracts(context.Background())
if err != nil {
log.Panic(err)
}
approveTx, err := wallet.ApproveERC20(nil, allowanceParams[0].Token, allowanceParams[0].Allowance, bridgeContracts.L1SharedBridge)
if err != nil {
log.Panic(err)
}
_, err = bind.WaitMined(context.Background(), ethClient, approveTx)
if err != nil {
log.Panic(err)
}
Get allowance parameters for depositing non-base token on non-ETH-based chain.
msg := accounts.DepositCallMsg{
Token: common.HexToAddress("<L1 token address>"),
To: Receiver,
Amount: big.NewInt(5),
}
allowanceParams, err := wallet.DepositAllowanceParams(nil, msg)
if err != nil {
log.Panic(err)
}
bridgeContracts, err := client.BridgeContracts(context.Background())
if err != nil {
log.Panic(err)
}
approveTx, err := wallet.ApproveERC20(nil, allowanceParams[0].Token, allowanceParams[0].Allowance, bridgeContracts.L1SharedBridge)
if err != nil {
log.Panic(err)
}
_, err = bind.WaitMined(context.Background(), ethClient, approveTx)
if err != nil {
log.Panic(err)
}
approveTx, err = wallet.ApproveERC20(nil, allowanceParams[1].Token, allowanceParams[1].Allowance, bridgeContracts.L1SharedBridge)
if err != nil {
log.Panic(err)
}
_, err = bind.WaitMined(context.Background(), ethClient, approveTx)
if err != nil {
log.Panic(err)
}
ZkSyncEraProvider := "https://testnet.era.zksync.dev"
client, err := clients.Dial(ZkSyncEraProvider)
if err != nil {
log.Panic(err)
}
defer client.Close()
gasPrice, err := client.SuggestGasPrice(context.Background())
if err != nil {
log.Panic(err)
}
baseCost, err := wallet.BaseCost(nil, big.NewInt(9000), utils.RequiredL1ToL2GasPerPubdataLimit, gasPrice)
if err != nil {
log.Panic(err)
}
fmt.Println("Base cost: ", baseCost)
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 BridgeAddress
). In this case, depending on is the chain
ETH-based or not ApproveERC20
or ApproveBaseERC20
can be enabled to perform token approval.
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 AllowanceL1
method.
Inputs
Parameter | Type | Description |
---|---|---|
auth | *TransactOpts (optional) | Transaction options. |
tx | DepositTransaction | Deposit transaction parameters. |
Deposit(auth *TransactOpts, tx DepositTransaction) (*types.Transaction, error)
Example
Deposit ETH on ETH-based chain.
tx, err := wallet.Deposit(nil, accounts.DepositTransaction{
To: wallet.Address(),
Token: utils.LegacyEthAddress,
Amount: amount,
RefundRecipient: wallet.Address(),
})
if err != nil {
log.Panic(err)
}
l1Receipt, err := bind.WaitMined(context.Background(), ethClient, tx)
if err != nil {
log.Panic(err)
}
l2Tx, err := client.L2TransactionFromPriorityOp(context.Background(), l1Receipt)
if err != nil {
log.Panic(err)
}
l2Receipt, err := client.WaitMined(context.Background(), l2Tx.Hash)
if err != nil {
log.Panic(err)
}
Deposit token on ETH-based chain.
tx, err := wallet.Deposit(nil, accounts.DepositTransaction{
To: wallet.Address(),
Token: L1Dai,
Amount: amount,
ApproveERC20: true,
RefundRecipient: wallet.Address(),
})
if err != nil {
log.Panic(err)
}
l1Receipt, err := bind.WaitMined(context.Background(), ethClient, tx)
if err != nil {
log.Panic(err)
}
l2Tx, err := client.L2TransactionFromPriorityOp(context.Background(), l1Receipt)
if err != nil {
log.Panic(err)
}
l2Receipt, err := client.WaitMined(context.Background(), l2Tx.Hash)
if err != nil {
log.Panic(err)
}
Deposit ETH on non-ETH-based chain.
tx, err := wallet.Deposit(nil, accounts.DepositTransaction{
To: wallet.Address(),
Token: utils.LegacyEthAddress,
Amount: amount,
ApproveBaseERC20: true,
RefundRecipient: wallet.Address(),
})
if err != nil {
log.Panic(err)
}
l1Receipt, err := bind.WaitMined(context.Background(), ethClient, tx)
if err != nil {
log.Panic(err)
}
l2Tx, err := client.L2TransactionFromPriorityOp(context.Background(), l1Receipt)
if err != nil {
log.Panic(err)
}
l2Receipt, err := client.WaitMined(context.Background(), l2Tx.Hash)
if err != nil {
log.Panic(err)
}
Deposit base token on non-ETH-based chain.
baseToken, err := wallet.BaseToken(nil)
if err != nil {
log.Panic(err)
}
tx, err := wallet.Deposit(nil, accounts.DepositTransaction{
To: wallet.Address(),
Token: baseToken,
Amount: amount,
ApproveBaseERC20: true,
RefundRecipient: wallet.Address(),
})
if err != nil {
log.Panic(err)
}
l1Receipt, err := bind.WaitMined(context.Background(), ethClient, tx)
if err != nil {
log.Panic(err)
}
l2Tx, err := client.L2TransactionFromPriorityOp(context.Background(), l1Receipt)
if err != nil {
log.Panic(err)
}
l2Receipt, err := client.WaitMined(context.Background(), l2Tx.Hash)
if err != nil {
log.Panic(err)
}
Deposit non-base token on non-ETH-based chain.
tx, err := wallet.Deposit(nil, accounts.DepositTransaction{
To: wallet.Address(),
Token: L1Dai,
Amount: amount,
ApproveERC20: true,
ApproveBaseERC20: true,
RefundRecipient: wallet.Address(),
})
if err != nil {
log.Panic(err)
}
l1Receipt, err := bind.WaitMined(context.Background(), ethClient, tx)
if err != nil {
log.Panic(err)
}
l2Tx, err := client.L2TransactionFromPriorityOp(context.Background(), l1Receipt)
if err != nil {
log.Panic(err)
}
l2Receipt, err := client.WaitMined(context.Background(), l2Tx.Hash)
if err != nil {
log.Panic(err)
}
EstimateGasDeposit
Estimates the amount of gas required for a deposit transaction on L1 network. Gas of approving ERC20 token is not included in the estimation.
Inputs
Parameter | Type | Description |
---|---|---|
ctx | context.Context | Context. |
msg | DepositCallMsg | Deposit call parameters. |
EstimateGasDeposit(ctx context.Context, msg DepositCallMsg) (uint64, error)
Example
depositGas, err := wallet.EstimateGasDeposit(context.Background(), accounts.DepositCallMsg{
To: wallet.Address(),
Token: utils.EthAddress,
Amount: big.NewInt(7_000_000_000),
})
if err != nil {
log.Panic(err)
}
fmt.Println("Deposit gas: ", depositGas)
FullRequiredDepositFee
Retrieves the full needed ETH fee for the deposit on both L1 and L2 networks.
Inputs
Parameter | Type | Description |
---|---|---|
ctx | context.Context | Context. |
msg | DepositCallMsg | Deposit call parameters. |
FullRequiredDepositFee(ctx context.Context, msg DepositCallMsg) (*FullDepositFee, error)
Example
fee, err := wallet.FullRequiredDepositFee(context.Background(), accounts.DepositCallMsg{
To: wallet.Address(),
Token: utils.EthAddress,
Amount: big.NewInt(7_000_000_000),
})
if err != nil {
log.Panic(err)
}
fmt.Printf("Fee: %+v\n", fee)
FinalizeWithdraw
Proves the inclusion of the L2 -> L1 withdrawal message.
Inputs
Parameter | Type | Description |
---|---|---|
auth | *TransactOpts (optional) | Transaction options. |
withdrawalHash | common.Hash | Hash of the L2 transaction where the withdrawal was initiated. |
index | int | In case there were multiple withdrawals in one transaction, you may pass an index of the withdrawal you want to finalize. |
FinalizeWithdraw(auth *TransactOpts, withdrawalHash common.Hash, index int) (*types.Transaction, error)
Example
withdrawalHash := common.HexToHash("<tx hash>")
finalizeWithdrawTx, err := wallet.FinalizeWithdraw(nil, withdrawalHash, 0)
if err != nil {
log.Panic(err)
}
fmt.Println("Finalize withdraw transaction: ", finalizeWithdrawTx.Hash())
IsWithdrawFinalized
Checks if the withdrawal finalized on L1 network.
Inputs
Parameter | Type | Description |
---|---|---|
opts | CallOpts (optional) | Call options. |
withdrawalHash | common.Hash | Hash of the L2 transaction where the withdrawal was initiated. |
index | int | In case there where multiple withdrawals in one transaction, you may pass an index of the withdrawal you want to finalize. |
IsWithdrawFinalized(opts *CallOpts, withdrawalHash common.Hash, index int) (bool, error)
Example
withdrawalHash := common.HexToHash("<tx hash>")
isFinalized, err := wallet.IsWithdrawFinalized(nil, withdrawalHash, 0)
if err != nil {
log.Panic(err)
}
fmt.Println("Is withdrawal finalized: ", isFinalized)
ClaimFailedDeposit
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
Parameter | Type | Description |
---|---|---|
auth | *TransactOpts (optional) | Transaction options. |
depositHash | common.Hash | The L2 transaction hash of the failed deposit. |
ClaimFailedDeposit(auth *TransactOpts, depositHash common.Hash) (*types.Transaction, error)
Example
failedDepositL2Hash := common.HexToHash("<deposit L2 hash>")
cfdTx, err := wallet.ClaimFailedDeposit(nil, failedDepositL2Hash)
if err != nil {
log.Panic(err)
}
fmt.Println("ClaimFailedDeposit hash: ", cfdTx.Hash)
RequestExecute
Request execution of L2 transaction from L1.
Inputs
Parameter | Type | Description |
---|---|---|
auth | *TransactOpts (optional) | Transaction options. |
tx | RequestExecuteTransaction | Request execute transaction parameters. |
RequestExecute(auth *TransactOpts, tx RequestExecuteTransaction) (*types.Transaction, error)
Example
contractAddress := common.HexToAddress("<Contract address>")
requestExecuteTx, err := wallet.RequestExecute(nil, accounts.RequestExecuteTransaction{
ContractAddress: contractAddress,
L2Value: big.NewInt(7_000_000_000),
L2GasLimit: big.NewInt(90_000),
GasPerPubdataByte: utils.RequiredL1ToL2GasPerPubdataLimit,
RefundRecipient: to,
})
if err != nil {
log.Panic(err)
}
fmt.Println("Request execute tx: ", requestExecuteTx.Hash())
EstimateGasRequestExecute
Estimates the amount of gas required for a request execute transaction.
Inputs
Parameter | Type | Description |
---|---|---|
ctx | context.Context | Context. |
msg | RequestExecuteCallMsg | Request execute call parameters. |
EstimateGasRequestExecute(ctx context.Context, msg RequestExecuteCallMsg) (uint64, error)
Example
contractAddress := common.HexToAddress("<Contract address>")
gas, err := wallet.EstimateGasRequestExecute(context.Background(), accounts.RequestExecuteCallMsg{
ContractAddress: contractAddress,
L2Value: big.NewInt(7_000_000_000),
L2GasLimit: big.NewInt(90_000),
GasPerPubdataByte: utils.RequiredL1ToL2GasPerPubdataLimit,
RefundRecipient: to,
})
if err != nil {
log.Panic(err)
}
fmt.Println("Gas: ", gas)
RequestExecuteAllowanceParams
Returns the parameters for the approval token transaction based on the request execute transaction. Existing allowance for the bridge is not checked; allowance is calculated solely based on the specified transaction.
Inputs
Parameter | Type | Description |
---|---|---|
opts | CallOpts (optional) | Call options. |
msg | RequestExecuteCallMsg | Request execute call parameters. |
RequestExecuteAllowanceParams(opts *CallOpts, msg RequestExecuteCallMsg) (AllowanceParams, error)
Example
msg := accounts.RequestExecuteCallMsg{
ContractAddress: wallet.Address(),
L2Value: big.NewInt(7_000_000_000),
Value: big.NewInt(0),
}
allowanceParams, err := wallet.RequestExecuteAllowanceParams(nil, msg)
if err != nil {
log.Panic(err)
}
bridgeContracts, err := client.BridgeContracts(context.Background())
if err != nil {
log.Panic(err)
}
approveTx, err := wallet.ApproveERC20(nil, allowanceParams.Token, allowanceParams.Allowance, bridgeContracts.L1SharedBridge)
if err != nil {
log.Panic(err)
}
_, err = bind.WaitMined(context.Background(), ethClient, approveTx)
if err != nil {
log.Panic(err)
}
EstimateCustomBridgeDepositL2Gas
Used by EstimateDefaultBridgeDepositL2Gas
to estimate L2 gas
required for token bridging via a custom ERC20 bridge.
Inputs
Parameter | Type | Description |
---|---|---|
ctx | context.Context | Context. |
l1BridgeAddress | common.Address | L1 bridge address. |
l2BridgeAddress | common.Address | L2 bridge address. |
token | common.Address | Token address. |
amount | *big.Int | Deposit amount. |
to | common.Address | Recipient address. |
bridgeData | []byte | Bridge data. |
from | common.Address (optional) | Sender address. |
gasPerPubdataByte | *big.Int (optional) | Current gas per byte of pubdata. |
EstimateCustomBridgeDepositL2Gas(ctx context.Context, l1BridgeAddress, l2BridgeAddress, token common.Address,
amount *big.Int, to common.Address, bridgeData []byte, from common.Address, gasPerPubdataByte *big.Int) (uint64, error)
Example
L1BridgeAddress := common.HexToAddress("<Bridge address>")
Token := common.HexToAddress("<Token address>")
From := common.HexToAddress("<Sender address>")
To := common.HexToAddress("<Receipt address>")
bridge, err := l1bridge.NewIL1Bridge(L1BridgeAddress, ethClient)
if err != nil {
log.Panic(err)
}
l2BridgeAddress, err := bridge.L2Bridge(nil)
if err != nil {
log.Panic(err)
}
customBridgeData, err := utils.Erc20DefaultBridgeData(Token, ethClient)
if err != nil {
log.Panic(err)
}
gas, err := wallet1.EstimateCustomBridgeDepositL2Gas(context.Background(), L1BridgeAddress, l2BridgeAddress, Token,
big.NewInt(7), To, customBridgeData, From, utils.RequiredL1ToL2GasPerPubdataLimit)
if err != nil {
log.Panic(err)
}
fmt.Println("L2 gas: ", gas)
EstimateDefaultBridgeDepositL2Gas
Returns an estimation of L2 gas required for token bridging via the default ERC20 bridge.
Inputs
Parameter | Type | Description |
---|---|---|
ctx | context.Context | Context. |
token | common.Address | Token address. |
amount | *big.Int | Deposit amount. |
to | common.Address | Recipient address. |
from | common.Address (optional) | Sender address. |
gasPerPubdataByte | *big.Int (optional) | Current gas per byte of pubdata. |
EstimateDefaultBridgeDepositL2Gas(ctx context.Context, token common.Address, amount *big.Int,
to, from common.Address, gasPerPubdataByte *big.Int) (uint64, error)
Example
Token := common.HexToAddress("<Token address>")
From := common.HexToAddress("<Sender address>")
To := common.HexToAddress("<Receipt address>")
gas, err := wallet1.EstimateDefaultBridgeDepositL2Gas(
context.Background(), Token, big.NewInt(7), To, From, utils.RequiredL1ToL2GasPerPubdataLimit,
)
if err != nil {
log.Panic(err)
}
fmt.Println("L2 gas: ", gas)
WalletL2
Init
Creates an instance of WalletL2
associated with the account provided by the raw private key.
func NewWalletL2(rawPrivateKey []byte, client *clients.Client) (*WalletL2, error)
Creates an instance of WalletL2
. The client
can be optional; if it is not provided, only
SignTransaction
, Address
, Signer
can be performed, as the rest of the functionalities
require communication to the network.
func NewWalletL2FromSigner(signer *Signer, client *clients.Client) (*WalletL2, error)
Example
PrivateKey := os.Getenv("PRIVATE_KEY")
ZkSyncEraProvider := "https://testnet.era.zksync.dev"
client, err := clients.Dial(ZkSyncEraProvider)
if err != nil {
log.Panic(err)
}
defer client.Close()
wallet, err := accounts.NewWallet(common.Hex2Bytes(PrivateKey), &client)
if err != nil {
log.Panic(err)
}
Address
Returns the address of the associated account.
Address() common.Address
Example
fmt.Println("Address: ", wallet.Address())
Signer
Returns the signer of the associated account.
Signer() Signer
Example
fmt.Printf("Signer %+v\n", wallet.Signer())
Balance
Returns the balance of the specified token that can be either ETH or any ERC20 token. The block number can be nil
,
in which case the balance is taken from the latest known block.
Inputs
Parameter | Type | Description |
---|---|---|
ctx | context.Context | Context. |
token | common.Address | L2 token address. |
at | *big.Int | Block number. |
Balance(ctx context.Context, token common.Address, at *big.Int) (*big.Int, error)
Example
balance, err := wallet.Balance(context.Background(), utils.EthAddress, nil)
if err != nil {
log.Panic(err)
}
fmt.Println("Balance: ", balance)
AllBalances
Returns all balances for confirmed tokens given by an associated account.
Inputs
Parameter | Type | Description |
---|---|---|
ctx | context.Context | Context. |
AllBalances(ctx context.Context) (map[common.Address]*big.Int, error)
Example
balances, err := wallet.AllBalances(context.Background())
if err != nil {
log.Panic(err)
}
fmt.Printf("Balances: %+v\n", balances)
L2BridgeContracts
Returns L2 bridge contracts.
Inputs
Parameter | Type | Description |
---|---|---|
ctx | context.Context | Context. |
L2BridgeContracts(ctx context.Context) (*zkTypes.L2BridgeContracts, error)
Example
contracts, err := wallet.L2BridgeContracts(context.Background())
if err != nil {
log.Panic(err)
}
DeploymentNonce
Returns the deployment nonce of the account.
Inputs
Parameter | Type | Description |
---|---|---|
opts | CallOpts (optional) | Call options. |
func (a *WalletL2) DeploymentNonce(opts *CallOpts) (*big.Int, error)
Example
deploymentNonce, err := wallet.DeploymentNonce(nil)
if err != nil {
log.Panic(err)
}
IsBaseToken
Returns whether the token is the base token.
Inputs
Parameter | Type | Description |
---|---|---|
ctx | context.Context | Context. |
token | common.Address | Token address. |
IsBaseToken(ctx context.Context, token common.Address) (bool, error)
Example
isBaseToken, err := wallet.IsBaseToken(
context.Background(),
common.HexToAddress("0x5C221E77624690fff6dd741493D735a17716c26B")
)
if err != nil {
log.Panic(err)
}
fmt.Println("Is base token: ", isBaseToken)
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
Parameter | Type | Description |
---|---|---|
auth | *TransactOpts (optional) | Transaction options. |
tx | WithdrawalTransaction | Withdrawal transaction parameters. |
Withdraw(auth *TransactOpts, tx WithdrawalTransaction) (*types.Transaction, error)
Example
tx, err := wallet.Withdraw(nil, accounts.WithdrawalTransaction{
To: wallet.Address(),
Amount: big.NewInt(1_000_000_000_000_000_000),
Token: utils.EthAddress,
})
if err != nil {
panic(err)
}
fmt.Println("Withdraw transaction: ", tx.Hash())
EstimateGasWithdraw
Estimates the amount of gas required for a withdrawal transaction.
Inputs
Parameter | Type | Description |
---|---|---|
ctx | context.Context | Context. |
msg | WithdrawalCallMsg | Withdrawal call parameters. |
EstimateGasWithdraw(ctx context.Context, msg WithdrawalCallMsg) (uint64, error)
Example
gas, err := wallet.EstimateGasWithdraw(context.Background(), accounts.WithdrawalCallMsg{
To: wallet.Address(),
Amount: big.NewInt(7_000_000),
Token: utils.EthAddress,
})
if err != nil {
log.Panic(err)
}
fmt.Println("Gas: ", gas)
Transfer
Moves the ETH or any ERC20 token from the associated account to the target account.
Inputs
Parameter | Type | Description |
---|---|---|
auth | *TransactOpts (optional) | Transaction options. |
tx | TransferTransaction | Transfer transaction parameters. |
Transfer(auth *TransactOpts, tx TransferTransaction) (*types.Transaction, error)
Example
tx, err := wallet.Transfer(nil, accounts.TransferTransaction{
To: common.HexToAddress("<Receipt address>"),
Amount: big.NewInt(7_000_000_000),
Token: utils.EthAddress,
})
if err != nil {
log.Panic(err)
}
fmt.Println("Transaction: ", tx.Hash())
EstimateGasTransfer
Estimates the amount of gas required for a transfer transaction.
Inputs
Parameter | Type | Description |
---|---|---|
ctx | context.Context | Context. |
msg | TransferCallMsg | Transfer call parameters. |
EstimateGasTransfer(ctx context.Context, msg TransferCallMsg) (uint64, error)
Example
gas, err := wallet.EstimateGasTransfer(context.Background(), accounts.TransferCallMsg{
To: common.HexToAddress("<Receipt address>"),
Amount: big.NewInt(7_000_000_000),
Token: utils.EthAddress,
})
if err != nil {
log.Panic(err)
}
fmt.Println("Gas: ", gas)
CallContract
Executes a message call for EIP-712 transaction, which is directly executed in the VM of the node, but never mined into the blockchain.
Inputs
Parameter | Type | Description |
---|---|---|
ctx | context.Context | Context. |
msg | CallMsg | Contains parameters for contract call using EIP-712 transaction. |
blockNumber | *big.Int (optional) | Selects the block height at which the call runs. It can be nil , in which case the code is taken from the latest known block. Note that state from very old blocks might not be available. |
CallContract(ctx context.Context, msg CallMsg, blockNumber *big.Int) ([]byte, error)
Example
// The Crown token on testnet
TokenAddress := common.HexToAddress("0x927488F48ffbc32112F1fF721759649A89721F8F")
tokenAbi, err := erc20.IERC20MetaData.GetAbi()
if err != nil {
log.Panic(err)
}
symbolCalldata, err := tokenAbi.Pack("symbol")
if err != nil {
log.Panic(err)
}
result, err := wallet.CallContract(context.Background(), types.CallMsg{
CallMsg: ethereum.CallMsg{
To: &TokenAddress,
Data: symbolCalldata,
},
}, nil)
if err != nil {
log.Panic(err)
}
unpack, err := tokenAbi.Unpack("symbol", result)
if err != nil {
log.Panic(err)
}
symbol := *abi.ConvertType(unpack[0], new(string)).(*string)
fmt.Println("Symbol: ", symbol)
PopulateTransaction
Designed for users who prefer a simplified approach by providing only the necessary data to create a valid
EIP-712 transaction. The only required fields are Transaction.To
and either
Transaction.Data
or Transaction.Value
(or both, if the method is payable).
Any other fields that are not set will be prepared by this method.
Inputs
Parameter | Type | Description |
---|---|---|
ctx | context.Context | Context. |
tx | Transaction | Transaction parameters. |
PopulateTransaction(ctx context.Context, tx Transaction) (*zkTypes.Transaction712, error)
Example
// The Crown token on testnet
TokenAddress := common.HexToAddress("0x927488F48ffbc32112F1fF721759649A89721F8F")
// Paymaster for Crown token on testnet
PaymasterAddress := common.HexToAddress("0x13D0D8550769f59aa241a41897D4859c87f7Dd46")
ReceiptAddress := common.HexToAddress("0xa61464658AfeAf65CccaaFD3a512b69A83B77618")
abi, err := erc20.IERC20MetaData.GetAbi()
if err != nil {
log.Panic(err)
}
// Encode transfer function from token contract
calldata, err := abi.Pack("transfer", ReceiptAddress, big.NewInt(7))
if err != nil {
log.Panic(err)
}
preparedTx, err := wallet.PopulateTransaction(context.Background(), &accounts.Transaction{
To: &TokenAddress,
Data: calldata,
})
fmt.Printf("Prepared tx: %+v\n", preparedTx)
SignTransaction
Returns a signed transaction that is ready to be broadcast to the network. The input transaction must be a valid
transaction with all fields having appropriate values. To obtain a valid transaction, you can use the
PopulateTransaction
method.
Inputs
Parameter | Type | Description |
---|---|---|
tx | zkTypes.Transaction712 | EIP-712 transaction parameters. |
SignTransaction(tx *zkTypes.Transaction712) ([]byte, error)
Example
// The Crown token on testnet
TokenAddress := common.HexToAddress("0x927488F48ffbc32112F1fF721759649A89721F8F")
// Paymaster for Crown token on testnet
PaymasterAddress := common.HexToAddress("0x13D0D8550769f59aa241a41897D4859c87f7Dd46")
ReceiptAddress := common.HexToAddress("0xa61464658AfeAf65CccaaFD3a512b69A83B77618")
abi, err := erc20.IERC20MetaData.GetAbi()
if err != nil {
log.Panic(err)
}
// Encode transfer function from token contract
calldata, err := abi.Pack("transfer", ReceiptAddress, big.NewInt(7))
if err != nil {
log.Panic(err)
}
preparedTx, err := wallet.PopulateTransaction(context.Background(), &accounts.Transaction{
To: &TokenAddress,
Data: calldata,
})
signedTx, err := wallet.SignTransaction(preparedTx)
if err != nil {
log.Panic(err)
}
fmt.Printf("Signed tx: %+v\n", signedTx)
SendTransaction
Injects a transaction into the pending pool for execution. Any unset transaction fields are prepared using the
PopulateTransaction
method.
Inputs
Parameter | Type | Description |
---|---|---|
ctx | context.Context | Context. |
tx | Transaction | Transaction parameters. |
SendTransaction(ctx context.Context, tx *Transaction) (common.Hash, error)
Example
// The Crown token on testnet
TokenAddress := common.HexToAddress("0x927488F48ffbc32112F1fF721759649A89721F8F")
// Paymaster for Crown token on testnet
PaymasterAddress := common.HexToAddress("0x13D0D8550769f59aa241a41897D4859c87f7Dd46")
ReceiptAddress := common.HexToAddress("0xa61464658AfeAf65CccaaFD3a512b69A83B77618")
abi, err := erc20.IERC20MetaData.GetAbi()
if err != nil {
log.Panic(err)
}
// Encode transfer function from token contract
calldata, err := abi.Pack("transfer", ReceiptAddress, big.NewInt(7))
if err != nil {
log.Panic(err)
}
// Create paymaster parameters with encoded paymaster input
paymasterParams, err := utils.GetPaymasterParams(
PaymasterAddress,
&zkTypes.ApprovalBasedPaymasterInput{
Token: TokenAddress,
MinimalAllowance: big.NewInt(1),
InnerInput: []byte{},
})
if err != nil {
log.Panic(err)
}
hash, err := wallet.SendTransaction(context.Background(), &accounts.Transaction{
To: &TokenAddress,
Data: calldata,
Meta: &types.Eip712Meta{
PaymasterParams: paymasterParams,
},
})
if err != nil {
log.Panic(err)
}
_, err = client.WaitMined(context.Background(), hash)
if err != nil {
log.Panic(err)
}
fmt.Println("Tx: ", hash)
BaseDeployer
Init
Creates an instance of BaseDeployer
based on provided AdapterL2
.
func NewBaseDeployer(adapter *AdapterL2) *BaseDeployer
Deploy
Deploys smart contract using CREATE2 method.
Inputs
Parameter | Type | Description |
---|---|---|
auth | *TransactOpts (optional) | Transaction options. |
tx | Create2Transaction | CREATE2 transaction parameters. |
Deploy(auth *TransactOpts, tx Create2Transaction) (common.Hash, error)
Example
bytecode, err := os.ReadFile("Storage.zbin")
if err != nil {
log.Panic(err)
}
//Deploy smart contract
hash, err := wallet.Deploy(nil, accounts.Create2Transaction{Bytecode: bytecode})
if err != nil {
panic(err)
}
fmt.Println("Transaction: ", hash)
DeployWithCreate
Deploys smart contract using CREATE method.
Inputs
Parameter | Type | Description |
---|---|---|
auth | *TransactOpts (optional) | Transaction options. |
tx | CreateTransaction | CREATE transaction parameters. |
DeployWithCreate(auth *TransactOpts, tx CreateTransaction) (common.Hash, error)
Example
bytecode, err := os.ReadFile("Storage.zbin")
if err != nil {
log.Panic(err)
}
//Deploy smart contract
hash, err := wallet.DeployWithCreate(nil, accounts.CreateTransaction{Bytecode: bytecode})
if err != nil {
panic(err)
}
fmt.Println("Transaction: ", hash)
DeployAccount
Deploys smart account using CREATE2 method.
Inputs
Parameter | Type | Description |
---|---|---|
auth | *TransactOpts (optional) | Transaction options. |
tx | Create2Transaction | CREATE2 transaction parameters. |
DeployAccount(auth *TransactOpts, tx Create2Transaction) (common.Hash, error)
Example
# Crown token on testnet
TokenAddress := common.HexToAddress("0x927488F48ffbc32112F1fF721759649A89721F8F")
_, paymasterAbi, bytecode, err := utils.ReadStandardJson("Paymaster.json")
if err != nil {
log.Panic(err)
}
// Encode paymaster constructor
constructor, err := paymasterAbi.Pack("", common.HexToAddress(TokenAddress))
if err != nil {
log.Panic(err)
}
// Deploy paymaster contract
hash, err := wallet.DeployAccount(nil, accounts.Create2Transaction{Bytecode: bytecode, Calldata: constructor})
if err != nil {
log.Panic(err)
}
if err != nil {
log.Panic(err)
}
fmt.Println("Transaction: ", hash)
DeployAccountWithCreate
Deploys smart account using CREATE method.
Inputs
Parameter | Type | Description |
---|---|---|
auth | *TransactOpts (optional) | Transaction options. |
tx | CreateTransaction | CREATE transaction parameters. |
DeployAccountWithCreate(auth *TransactOpts, tx CreateTransaction) (common.Hash, error)
Example
# Crown token on testnet
TokenAddress := common.HexToAddress("0x927488F48ffbc32112F1fF721759649A89721F8F")
_, paymasterAbi, bytecode, err := utils.ReadStandardJson("Paymaster.json")
if err != nil {
log.Panic(err)
}
constructor, err := paymasterAbi.Pack("", common.HexToAddress(TokenAddress))
if err != nil {
log.Panic(err)
}
// Deploy paymaster contract
hash, err := wallet.DeployAccountWithCreate(nil, accounts.CreateTransaction{
Bytecode: bytecode,
Calldata: constructor,
})
if err != nil {
log.Panic(err)
}
fmt.Println("Transaction: ", hash)
Wallet
It contains the same functions as WalletL1
, WalletL2
, and BaseDeployer
since it implements the Adapter interface, and the usage of those methods is the same.
Init
Creates an instance of Wallet
associated with the account provided by the rawPrivateKey
. The clientL1
parameters is optional; if not provided, only methods from AdapterL2
and Deployer
interfaces can be used,
as the rest of the functionalities require communication with the L1 network. A Wallet
can be configured to
communicate with L1 networks by using and ConnectL1
method.
func NewWallet(rawPrivateKey []byte, clientL2 *clients.Client, clientL1 *ethclient.Client) (*Wallet, error)
Creates an instance of Wallet associated with the account provided by the signer. The clientL2
and clientL1
parameters are optional; if not provided, only SignTransaction
, Address
and Signer
methods can be used,
as the rest of the functionalities require communication with the network. A wallet that contains only a
signer can be configured to communicate with L2 and L1 networks by using Connect
and
ConnectL1
, respectively.
func NewWalletFromSigner(signer Signer, clientL2 *clients.Client, clientL1 *ethclient.Client) (*Wallet, error)
Creates a new instance of Wallet
based on the provided mnemonic phrase. The clientL2
and clientL1
parameters are optional, and can be configured with Connect
and ConnectL1
, respectively.
func NewWalletFromMnemonic(mnemonic string, chainId int64, clientL2 *clients.Client, clientL1 *ethclient.Client) (*Wallet, error)
Creates a new instance of Wallet
based on the provided private key of the account and chain ID.
The clientL2
and clientL1
parameters are optional, and can be configured with Connect
and ConnectL1
, respectively.
func NewWalletFromRawPrivateKey(rawPk []byte, chainId int64, clientL2 *clients.Client, clientL1 *ethclient.Client) (*Wallet, error)
Creates an instance of Wallet
with a randomly generated account. The clientL2
and clientL1
parameters are
optional, and can be configured with Connect
and ConnectL1
, respectively.
func NewRandomWallet(chainId int64, clientL2 *clients.Client, clientL1 *ethclient.Client) (*Wallet, error)
Example
PrivateKey := os.Getenv("PRIVATE_KEY")
ZkSyncEraProvider := "https://sepolia.era.zksync.dev"
EthereumProvider := "https://rpc.ankr.com/eth_sepolia"
client, err := clients.Dial(ZkSyncEraProvider)
if err != nil {
log.Panic(err)
}
defer client.Close()
ethClient, err := ethclient.Dial(EthereumProvider)
if err != nil {
log.Panic(err)
}
defer ethClient.Close()
wallet, err := accounts.NewWallet(common.Hex2Bytes(PrivateKey), &client, ethClient)
if err != nil {
log.Panic(err)
}
chainID, err := client.ChainID(context.Background())
if err != nil {
log.Panic(err)
}
wallet, err = accounts.NewRandomWallet(chainID.Int64(),nil,nil)
if err != nil {
log.Panic(err)
}
Connect
Returns a new instance of Wallet
with the provided client for the L2 network.
Inputs
Parameter | Type | Description |
---|---|---|
client | *clients.Client | L2 client. |
Connect(client *clients.Client) (*Wallet, error)
Example
PrivateKey := os.Getenv("PRIVATE_KEY")
ZkSyncEraProvider := "https://testnet.era.zksync.dev"
client, err := clients.Dial(ZkSyncEraProvider)
if err != nil {
log.Panic(err)
}
defer client.Close()
chainID, err := client.ChainID(context.Background())
if err != nil {
log.Panic(err)
}
wallet, err := accounts.NewRandomWallet(chainID, nil, nil)
if err != nil {
log.Panic(err)
}
// create new wallet with connection to L2
wallet, err = wallet.Connect(&client)
if err != nil {
log.Panic(err)
}
ConnectL1
Returns a new instance of Wallet
with the provided client for the L1 network.
Inputs
Parameter | Type | Description |
---|---|---|
client | *ethclient.Client | L1 client. |
ConnectL1(client *ethclient.Client) (*Wallet, error)
Example
chainID, err := client.ChainID(context.Background())
if err != nil {
log.Panic(err)
}
wallet, err = accounts.NewRandomWallet(chainID, nil, nil)
if err != nil {
log.Panic(err)
}
// create new wallet with connection to L1
wallet, err = wallet.Connect(ðClient)
if err != nil {
log.Panic(err)
}
Nonce
Returns the account nonce of the associated account. The block number can be nil
, in which case the nonce is taken
from the latest known block.
Inputs
Parameter | Type | Description |
---|---|---|
ctx | context.Context | Context. |
blockNumber | *big.Int (optional) | Block number. |
Nonce(ctx context.Context, blockNumber *big.Int) (uint64, error)
Example
nonce, err := wallet.Nonce(context.Background(), big.NewInt(9000))
if err != nil {
log.Panic(err)
}
fmt.Println("Nonce: ", nonce)
PendingNonce
Returns the account nonce of the associated account in the pending state. This is the nonce that should be used for the next transaction.
Inputs
Parameter | Type | Description |
---|---|---|
ctx | context.Context | Context. |
PendingNonce(ctx context.Context) (uint64, error)
Example
nonce, err := wallet.PendingNonce(context.Background())
if err != nil {
log.Panic(err)
}
fmt.Println("Nonce: ", nonce)
SmartAccount
A SmartAccount
is a signer which can be configured to sign various payloads using a provided secret.
The secret can be in any form, allowing for flexibility when working with different account implementations.
The SmartAccount
is bound to a specific address and provides the ability to define custom method for populating transactions
and custom signing method used for signing messages, typed data, and transactions.
Init
Creates a new SmartAccount
instance. By default, it uses SignPayloadWithECDSA
as a signer and PopulateTransactionECDSA
as a builder and
requires private key in hex format to be provided.
Inputs
Parameter | Type | Description |
---|---|---|
address | common.Address | Account address. |
secret | interface{} | Secret used for signing. |
signer | *PayloadSigner | Function used for signing payload. |
builder | *TransactionBuilder | Function used for populating transaction. |
client | *clients.BaseClient | The client to connect to. Can be nil for offline usage. |
func NewSmartAccount(
address common.Address,
secret interface{},
signer *PayloadSigner,
builder *TransactionBuilder,
client *clients.BaseClient) *SmartAccount
Examples
privateKey := os.Getenv("PRIVATE_KEY")
address := common.HexToAddress("<ACCOUNT ADDRESS>")
ZkSyncEraProvider := "https://sepolia.era.zksync.dev"
client, err := clients.DialBase(ZkSyncEraProvider)
if err != nil {
log.Panic(err)
}
defer client.Close()
account := accounts.NewSmartAccount(
address,
privateKey,
&accounts.SignPayloadWithECDSA,
&accounts.PopulateTransactionECDSA,
nil)
NewECDSASmartAccount
Creates a SmartAccount
instance that uses single ECDSA key for signing payload.
Parameter | Type | Description |
---|---|---|
address | common.Address | Account address. |
privateKey | string | The ECDSA private key. |
client | *clients.BaseClient | The client to connect to. Can be nil for offline usage. |
func NewECDSASmartAccount(address common.Address, privateKey string, client *clients.BaseClient) *SmartAccount
Example
privateKey := os.Getenv("PRIVATE_KEY")
address := common.HexToAddress("<ACCOUNT ADDRESS>")
ZkSyncEraProvider := "https://sepolia.era.zksync.dev"
client, err := clients.DialBase(ZkSyncEraProvider)
if err != nil {
log.Panic(err)
}
defer client.Close()
account := accounts.NewECDSASmartAccount(address, privateKey, client)
NewMultisigECDSASmartAccount
Creates a SmartAccount
instance that uses multiple ECDSA keys for signing payloads.
The signature is generated by concatenating signatures created by signing with each key individually.
Parameter | Type | Description |
---|---|---|
address | common.Address | Account address. |
privateKeys | []string | The list of the ECDSA private keys. |
client | *clients.BaseClient | The client to connect to. Can be nil for offline usage. |
NewMultisigECDSASmartAccount(address common.Address, privateKeys []string, client *clients.BaseClient) *SmartAccount
Example
privateKey1 := os.Getenv("PRIVATE_KEY1")
privateKey2 := os.Getenv("PRIVATE_KEY2")
address := common.HexToAddress("<ACCOUNT ADDRESS>")
ZkSyncEraProvider := "https://sepolia.era.zksync.dev"
client, err := clients.DialBase(ZkSyncEraProvider)
if err != nil {
log.Panic(err)
}
defer client.Close()
account := accounts.NewMultisigECDSASmartAccount(address, []string{privateKey1, privateKey2}, client)
Connect
Creates a new instance of SmartAccount connected to a client or
detached from any provider if nil
is provided.
Inputs
Parameter | Type | Description |
---|---|---|
client | *clients.DialBase | The client to connect the SmartAccount to. If nil , the SmartAccount will be detached from any provider. |
Connect(client *clients.BaseClient) *SmartAccount
Example
privateKey := os.Getenv("PRIVATE_KEY")
ZkSyncEraProvider := "https://testnet.era.zksync.dev"
client, err := clients.Dial(ZkSyncEraProvider)
if err != nil {
log.Panic(err)
}
defer client.Close()
account := accounts.NewECDSASmartAccount(Address1, PrivateKey1, nil)
account = account.Connect(client)
Address
Returns the address of the associated account.
Address() common.Address
Example
fmt.Println("Address: ", account.Address())
Balance
Returns the balance of the specified token that can be either ETH or any ERC20 token. The block number can be nil
,
in which case the balance is taken from the latest known block.
Inputs
Parameter | Type | Description |
---|---|---|
ctx | context.Context | Context. |
token | common.Address | L2 token address. |
at | *big.Int | Block number. |
Balance(ctx context.Context, token common.Address, at *big.Int) (*big.Int, error)
Example
balance, err := account.Balance(context.Background(), utils.EthAddress, nil)
if err != nil {
log.Panic(err)
}
fmt.Println("Balance: ", balance)
AllBalances
Returns all balances for confirmed tokens given by an associated account.
Inputs
Parameter | Type | Description |
---|---|---|
ctx | context.Context | Context. |
AllBalances(ctx context.Context) (map[common.Address]*big.Int, error)
Example
balances, err := account.AllBalances(context.Background())
if err != nil {
log.Panic(err)
}
fmt.Printf("Balances: %+v\n", balances)
Nonce
Returns the account nonce of the associated account. The block number can be nil
, in which case the nonce is taken
from the latest known block.
Inputs
Parameter | Type | Description |
---|---|---|
ctx | context.Context | Context. |
blockNumber | *big.Int (optional) | Block number. |
Nonce(ctx context.Context, blockNumber *big.Int) (uint64, error)
Example
nonce, err := account.Nonce(context.Background(), big.NewInt(9000))
if err != nil {
log.Panic(err)
}
fmt.Println("Nonce: ", nonce)
DeploymentNonce
Returns the deployment nonce of the account.
Inputs
Parameter | Type | Description |
---|---|---|
opts | CallOpts (optional) | Call options. |
DeploymentNonce(opts *CallOpts) (*big.Int, error)
Example
deploymentNonce, err := account.DeploymentNonce(nil)
if err != nil {
log.Panic(err)
}
PopulateTransaction
Populates the transaction tx
using the provided TransactionBuilder
function.
If tx.From
is not set, it sets the value from the Address()
method which can
be utilized in the TransactionBuilder
function.
Inputs
Parameter | Type | Description |
---|---|---|
ctx | context.Context | Context. |
tx | *zkTypes.Transaction712 | The transaction that needs to be populated. |
PopulateTransaction(ctx context.Context, tx *zkTypes.Transaction712) error
Example
address := common.HexToAddress("<ACCOUNT ADDRESS>")
tx := &zkTypes.Transaction712{
To: &address,
Value: big.NewInt(7_000_000_000),
}
err = account.PopulateTransaction(context.Background(), tx)
if err != nil {
log.Panic(err)
}
SignTransaction
Returns a signed transaction that is ready to be broadcast to
the network. The PopulateTransaction
method is called first to ensure that all
necessary properties for the transaction to be valid have been populated.
Inputs
Parameter | Type | Description |
---|---|---|
ctx | context.Context | Context. |
tx | *zkTypes.Transaction712 | The transaction that needs to be signed. |
SignTransaction(ctx context.Context, tx *zkTypes.Transaction712) ([]byte, error)
Example
address := common.HexToAddress("<ACCOUNT ADDRESS>")
signedTx, err := account.SignTransaction(context.Background(), &zkTypes.Transaction712{
To: &address,
Value: big.NewInt(1_000_000_000_000_000_000), // 1ETH
})
if err != nil {
log.Panic(err)
}
SendTransaction
Injects a transaction into the pending pool for execution.
The SignTransaction
is called first to ensure transaction is properly signed.
Inputs
Parameter | Type | Description |
---|---|---|
ctx | context.Context | Context. |
tx | *zkTypes.Transaction712 | The transaction that needs to be signed. |
SendTransaction(ctx context.Context, tx *zkTypes.Transaction712) (common.Hash, error)
Example
address := common.HexToAddress("<ACCOUNT ADDRESS>")
txHash, err := account.SendTransaction(context.Background(), &zkTypes.Transaction712{
To: &address,
Value: big.NewInt(1_000_000_000_000_000_000), // 1ETH
})
if err != nil {
log.Panic(err)
}
SignMessage
Signs a message using the provided PayloadSigner
function.
Inputs
Parameter | Type | Description |
---|---|---|
ctx | context.Context | Context. |
message | []byte | The message that needs to be signed. |
SignMessage(ctx context.Context, message []byte) ([]byte, error)
Example
signature, err := account.SignMessage(context.Background(), []byte("Hello World!"))
if err != nil {
log.Panic(err)
}
SignTypedData
signs a typed data using the provided PayloadSigner
function.
Inputs
Parameter | Type | Description |
---|---|---|
ctx | context.Context | Context. |
typedData | apitypes.TypedData | The typed data that needs to be signed. |
SignTypedData(ctx context.Context, typedData apitypes.TypedData) ([]byte, error)
Example
signature, err := account.SignTypedData(context.Background(), apitypes.TypedData{
Domain: apitypes.TypedDataDomain{
Name: "Example",
Version: "1",
ChainId: math.NewHexOrDecimal256(270),
},
Types: apitypes.Types{
"Person": []apitypes.Type{
{Name: "name", Type: "string"},
{Name: "age", Type: "uint8"},
},
"EIP712Domain": []apitypes.Type{
{Name: "name", Type: "string"},
{Name: "version", Type: "string"},
{Name: "chainId", Type: "uint256"},
},
},
PrimaryType: "Person",
Message: apitypes.TypedDataMessage{
"name": "John",
"age": hexutil.EncodeUint64(30),
},
})
if err != nil {
log.Panic(err)
}
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
Parameter | Type | Description |
---|---|---|
auth | *TransactOpts (optional) | Transaction options. |
tx | WithdrawalTransaction | Withdrawal transaction parameters. |
Withdraw(auth *TransactOpts, tx WithdrawalTransaction) (common.Hash, error)
Examples
Withdraw ETH.
txHash, err := account.Withdraw(nil, accounts.WithdrawalTransaction{
To: account.Address(),
Amount: big.NewInt(1_000_000_000_000_000_000),
Token: utils.LegacyEthAddress,
})
if err != nil {
log.Panic(err)
}
fmt.Println("Withdraw transaction: ", txHash)
Withdraw ETH using paymaster to facilitate fee payment with an ERC20 token.
token := common.HexToAddress("0x927488F48ffbc32112F1fF721759649A89721F8F"); // Crown token which can be minted for free
paymaster := common.HexToAddress("0x13D0D8550769f59aa241a41897D4859c87f7Dd46"); // Paymaster for Crown token
paymasterParams, err := utils.GetPaymasterParams(
paymaster,
&zkTypes.ApprovalBasedPaymasterInput{
Token: token,
MinimalAllowance: big.NewInt(1),
InnerInput: []byte{},
})
if err != nil {
log.Panic(err)
}
txHash, err := account.Withdraw(nil, accounts.WithdrawalTransaction{
To: account.Address(),
Amount: big.NewInt(1_000_000_000_000_000_000),
Token: utils.LegacyEthAddress,
PaymasterParams: paymasterParams,
})
Transfer
Moves the ETH or any ERC20 token from the associated account to the target account.
Inputs
Parameter | Type | Description |
---|---|---|
auth | *TransactOpts (optional) | Transaction options. |
tx | TransferTransaction | Transfer transaction parameters. |
Transfer(auth *TransactOpts, tx TransferTransaction) (common.Hash, error)
Examples
Transfer ETH.
txHash, err := account.Transfer(nil, accounts.TransferTransaction{
To: Address2,
Amount: amount,
Token: utils.LegacyEthAddress,
})
if err != nil {
log.Panic(err)
}
fmt.Println("Transaction: ", txHash)
Transfer ETH using paymaster to facilitate fee payment with an ERC20 token.
token := common.HexToAddress("0x927488F48ffbc32112F1fF721759649A89721F8F"); // Crown token which can be minted for free
paymaster := common.HexToAddress("0x13D0D8550769f59aa241a41897D4859c87f7Dd46"); // Paymaster for Crown token
paymasterParams, err := utils.GetPaymasterParams(
paymaster,
&zkTypes.ApprovalBasedPaymasterInput{
Token: token,
MinimalAllowance: big.NewInt(1),
InnerInput: []byte{},
})
if err != nil {
log.Panic(err)
}
txHash, err := account.Transfer(nil, accounts.TransferTransaction{
To: Address2,
Amount: amount,
Token: utils.LegacyEthAddress,
PaymasterParams: paymasterParams,
})
if err != nil {
log.Panic(err)
}
fmt.Println("Transaction: ", txHash)