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.
Address
Returns the address of the associated account.
Address() common.Address
Example
fmt.Println("Address: ", account.Address())
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)
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 |
|---|---|---|
opts | CallOpts (optional) | Call options. |
token | common.Address | L2 token address. |
Balance(opts *CallOpts, token common.Address) (*big.Int, error)
Example
balance, err := account.Balance(nil, utils.EthAddress)
if err != nil {
log.Panic(err)
}
fmt.Println("Balance: ", balance)
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.Client) *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)
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)
}
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.Client | The client to connect to. Can be nil for offline usage. |
func NewSmartAccount(
address common.Address,
secret interface{},
signer *PayloadSigner,
builder *TransactionBuilder,
client *clients.Client) *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)
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)
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.Transaction | The transaction that needs to be populated. |
PopulateTransaction(ctx context.Context, tx *zkTypes.Transaction) error
Example
address := common.HexToAddress("<ACCOUNT ADDRESS>")
tx := &zkTypes.Transaction{
To: &address,
Value: big.NewInt(7_000_000_000),
}
err = account.PopulateTransaction(context.Background(), tx)
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.Transaction | The transaction that needs to be signed. |
SendTransaction(ctx context.Context, tx *zkTypes.Transaction) (common.Hash, error)
Example
address := common.HexToAddress("<ACCOUNT ADDRESS>")
txHash, err := account.SendTransaction(context.Background(), &zkTypes.Transaction{
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)
}
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.Transaction | The transaction that needs to be signed. |
SignTransaction(ctx context.Context, tx *zkTypes.Transaction) ([]byte, error)
Example
address := common.HexToAddress("<ACCOUNT ADDRESS>")
signedTx, err := account.SignTransaction(context.Background(), &zkTypes.Transaction{
To: &address,
Value: big.NewInt(1_000_000_000_000_000_000), // 1ETH
})
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)
}
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)
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,
})