WalletL1
The WalletL1
class provides functionalities for managing and interacting with accounts on
the Layer 1 (L1) network. It includes methods for creating wallets, querying contracts, checking balances, and
performing transactions on the Ethereum network.
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)
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())
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)
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)
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)
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)
}
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)
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)
}
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)
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)
/;
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)
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)
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())
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)
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)
}
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)
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)
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)
}
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)
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)
}
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())
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)
}