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.
It is compatible with web3py.Contract
for deploying contracts/accounts and for interacting with contracts/accounts
using provided ABI along with custom transaction signing logic.
__init__
Creates a SmartAccount
instance with provided signer
and provider
.
By default, uses sign_payload_with_ecdsa
and sign_payload_with_multiple_ecdsa
.
Inputs
Parameter | Type | Description |
---|---|---|
address | HexStr | Address of the smart account. |
secret | HexStr | Secrets to be used for signing transactions. |
provider | Web3 | The provider to connect to. |
transaction_builder | Method | Implementation of transaction builder (default is populate_transaction_ecdsa). |
payload_signer | Method | Implementation of signing (default is sign_payload_with_ecdsa). |
Example
from eth_account import Account
from eth_account.signers.local import LocalAccount
from web3 import Web3
from zksync2.account.smart_account import SmartAccount
from zksync2.module.module_builder import ZkSyncBuilder
if __name__ == "__main__":
ZKSYNC_PROVIDER = "https://sepolia.era.zksync.dev"
zksync = ZkSyncBuilder.build(ZKSYNC_PROVIDER)
account = SmartAccount(address_1, HexStr(private_key_1), zksync)
get_address
Returns the address of the account.
Example
from eth_account import Account
from eth_account.signers.local import LocalAccount
from web3 import Web3
from zksync2.account.smart_account import SmartAccount
from zksync2.module.module_builder import ZkSyncBuilder
if __name__ == "__main__":
ZKSYNC_PROVIDER = "https://sepolia.era.zksync.dev"
zksync = ZkSyncBuilder.build(ZKSYNC_PROVIDER)
account = SmartAccount(address_1, HexStr(private_key_1), zksync)
address = account.get_address()
get_balance
Returns the balance of the account.
Inputs
Name | Description |
---|---|
block_tag | The block the balance should be checked on. committed , i.e. the latest processed one is the default option. |
token_address | The address of the token. ETH by default. |
Example
from eth_account import Account
from eth_account.signers.local import LocalAccount
from web3 import Web3
from zksync2.account.smart_account import SmartAccount
from zksync2.module.module_builder import ZkSyncBuilder
if __name__ == "__main__":
ZKSYNC_PROVIDER = "https://sepolia.era.zksync.dev"
zksync = ZkSyncBuilder.build(ZKSYNC_PROVIDER)
account = SmartAccount(address_1, HexStr(private_key_1), zksync)
balance = account.get_balance()
get_all_balances
Returns all balances for confirmed tokens given by an account address.
Inputs and outputs
Name | Description |
---|---|
returns | ZksAccountBalances with all account balances. |
Example
from eth_account import Account
from eth_account.signers.local import LocalAccount
from web3 import Web3
from zksync2.account.smart_account import SmartAccount
from zksync2.module.module_builder import ZkSyncBuilder
if __name__ == "__main__":
ZKSYNC_PROVIDER = "https://sepolia.era.zksync.dev"
zksync = ZkSyncBuilder.build(ZKSYNC_PROVIDER)
account = SmartAccount(address_1, HexStr(private_key_1), zksync)
all_balances = account.get_all_balances()
get_deployment_nonce
Returns account's deployment nonce number.
Inputs and outputs
Name | Description |
---|---|
returns | The deployment nonce number. |
Example
from eth_account import Account
from eth_account.signers.local import LocalAccount
from web3 import Web3
from zksync2.account.smart_account import SmartAccount
from zksync2.module.module_builder import ZkSyncBuilder
if __name__ == "__main__":
ZKSYNC_PROVIDER = "https://sepolia.era.zksync.dev"
zksync = ZkSyncBuilder.build(ZKSYNC_PROVIDER)
account = SmartAccount(address_1, HexStr(private_key_1), zksync)
nonce = account.get_deployment_nonce()
populate_transaction
Populates the transaction tx
using the provided transaction_builder function.
If tx.from
is not set, it sets the value from the get_address
method which can
be utilized in the transaction builder function.
Inputs
Parameter | Type | Description |
---|---|---|
tx | Transaction712 | The transaction that needs to be populated. |
Example
from eth_account import Account
from eth_account.signers.local import LocalAccount
from web3 import Web3
from zksync2.account.smart_account import SmartAccount
from zksync2.module.module_builder import ZkSyncBuilder
if __name__ == "__main__":
ZKSYNC_PROVIDER = "https://sepolia.era.zksync.dev"
zksync = ZkSyncBuilder.build(ZKSYNC_PROVIDER)
account = SmartAccount(address_1, HexStr(private_key_1), zksync)
populated = account.populate_transaction(TxTransfer(
from_=address_1,
to=address_2,
value=7_000_000_000,
token=ADDRESS_DEFAULT
).tx712(0))
sign_transaction
Signs the transaction tx
using the provided payload_signer function,
returning the fully signed transaction. The populate_transaction
method
is called first to ensure that all necessary properties for the transaction to be valid
have been populated.
Inputs
Parameter | Type | Description |
---|---|---|
tx | Transaction712 | The transaction that needs to be signed. |
Example
from eth_account import Account
from eth_account.signers.local import LocalAccount
from web3 import Web3
from zksync2.account.smart_account import SmartAccount
from zksync2.module.module_builder import ZkSyncBuilder
if __name__ == "__main__":
ZKSYNC_PROVIDER = "https://sepolia.era.zksync.dev"
zksync = ZkSyncBuilder.build(ZKSYNC_PROVIDER)
account = SmartAccount(address_1, HexStr(private_key_1), zksync)
signed = account.sign_transaction(TxTransfer(
from_=address_1,
to=address_2,
value=7_000_000_000,
token=ADDRESS_DEFAULT
).tx712(0))
send_transaction
Sends tx
to the Network. The sign_transaction
is called first to ensure transaction is properly signed.
Inputs
Parameter | Type | Description |
---|---|---|
tx | Transaction712 | The transaction that needs to be sent. |
Example
from eth_account import Account
from eth_account.signers.local import LocalAccount
from web3 import Web3
from zksync2.account.smart_account import SmartAccount
from zksync2.module.module_builder import ZkSyncBuilder
if __name__ == "__main__":
ZKSYNC_PROVIDER = "https://sepolia.era.zksync.dev"
zksync = ZkSyncBuilder.build(ZKSYNC_PROVIDER)
account = SmartAccount(address_1, HexStr(private_key_1), zksync)
signed = account.send_transaction(TxTransfer(
from_=address_1,
to=address_2,
value=7_000_000_000,
token=ADDRESS_DEFAULT
).tx712(0))
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
Name | Description |
---|---|
transaction | WithdrawTransaction |
Example
from eth_account import Account
from eth_account.signers.local import LocalAccount
from web3 import Web3
from zksync2.account.smart_account import SmartAccount
from zksync2.module.module_builder import ZkSyncBuilder
from zksync2.core.types import WithdrawTransaction, ADDRESS_DEFAULT
ZKSYNC_PROVIDER = "https://sepolia.era.zksync.dev"
zk_web3 = ZkSyncBuilder.build(ZKSYNC_PROVIDER)
account = SmartAccount(address_1, HexStr(private_key_1), zksync)
withdraw_tx_hash = account.withdraw(
WithdrawTransaction(
token=ADDRESS_DEFAULT, amount=Web3.to_wei(1, "ether")
)
)
withdraw_receipt = zk_web3.zksync.wait_for_transaction_receipt(
withdraw_tx_hash, timeout=240, poll_latency=0.5
)
Withdraw ETH using paymaster to facilitate fee payment with an ERC20 token.
from eth_account import Account
from eth_account.signers.local import LocalAccount
from web3 import Web3
from zksync2.account.smart_account import SmartAccount
from zksync2.module.module_builder import ZkSyncBuilder
from zksync2.core.types import WithdrawTransaction, ADDRESS_DEFAULT
ZKSYNC_PROVIDER = "https://sepolia.era.zksync.dev"
zk_web3 = ZkSyncBuilder.build(ZKSYNC_PROVIDER)
account = SmartAccount(address_1, HexStr(private_key_1), zksync)
paymaster_address = zk_web3.to_checksum_address(HexStr("0x13D0D8550769f59aa241a41897D4859c87f7Dd46"))
token_address = zk_web3.to_checksum_address(HexStr("0x927488F48ffbc32112F1fF721759649A89721F8F"))
paymaster_params = PaymasterParams(
**{
"paymaster": paymaster_address,
"paymaster_input": eth_web3.to_bytes(
hexstr=PaymasterFlowEncoder(eth_web3).encode_approval_based(
token_address, 1, b""
)
),
}
)
withdraw_tx_hash = account.withdraw(
WithdrawTransaction(
token=ADDRESS_DEFAULT, amount=Web3.to_wei(1, "ether"), paymaster_params=paymaster_params
)
)
withdraw_receipt = zk_web3.zksync.wait_for_transaction_receipt(
withdraw_tx_hash, timeout=240, poll_latency=0.5
)
transfer
For convenience, the Wallet
class has transfer
method, which can transfer ETH
or any ERC20
token within the same interface.
Inputs and outputs
Name | Description |
---|---|
tx | TransferTransaction . |
returns | A HexStr of transaction. |
Example
Transfer ETH.
from eth_account import Account
from eth_account.signers.local import LocalAccount
from web3 import Web3
from zksync2.account.smart_account import SmartAccount
from zksync2.module.module_builder import ZkSyncBuilder
from zksync2.core.types import TransferTransaction, ADDRESS_DEFAULT
if __name__ == "__main__":
ZKSYNC_PROVIDER = "https://sepolia.era.zksync.dev"
zk_web3 = ZkSyncBuilder.build(ZKSYNC_PROVIDER)
account = SmartAccount(address_1, HexStr(private_key_1), zksync)
amount = 7_000_000_000
tx_hash = account.transfer(TransferTransaction(to=Web3.to_checksum_address("TO_ADDRESS"),
token_address=ADDRESS_DEFAULT,
amount=amount))
tx_receipt = zk_web3.zksync.wait_for_transaction_receipt(
tx_hash, timeout=240, poll_latency=0.5
)
Transfer ETH using paymaster to facilitate fee payment with an ERC20 token.
from eth_account import Account
from eth_account.signers.local import LocalAccount
from web3 import Web3
from zksync2.account.smart_account import SmartAccount
from zksync2.module.module_builder import ZkSyncBuilder
from zksync2.core.types import TransferTransaction, ADDRESS_DEFAULT, PaymasterParams
from zksync2.manage_contracts.paymaster_utils import PaymasterFlowEncoder
if __name__ == "__main__":
ZKSYNC_PROVIDER = "https://sepolia.era.zksync.dev"
zk_web3 = ZkSyncBuilder.build(ZKSYNC_PROVIDER)
account = SmartAccount(address_1, HexStr(private_key_1), zksync)
paymaster_address = zk_web3.to_checksum_address("0x13D0D8550769f59aa241a41897D4859c87f7Dd46")
token_address = zk_web3.to_checksum_address("0x927488F48ffbc32112F1fF721759649A89721F8F")
paymaster_params = PaymasterParams(
**{
"paymaster": paymaster_address,
"paymaster_input": eth_web3.to_bytes(
hexstr=PaymasterFlowEncoder(eth_web3).encode_approval_based(
token_address, 1, b""
)
),
}
)
amount = 7_000_000_000
tx_hash = account.transfer(
TransferTransaction(
to=Web3.to_checksum_address("TO_ADDRESS"),
amount=amount,
paymaster_params=paymaster_params,
)
)
tx_receipt = zk_web3.zksync.wait_for_transaction_receipt(
tx_hash, timeout=240, poll_latency=0.5
)