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 |
---|---|---|
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)
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)
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.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)
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.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)
}
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)
}
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)
}
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,
})