Account creation#

An account is needed to start interacting with Starknet. If you don’t have one there are a few ways of creating one programmatically:

  • using DeployAccount transaction

  • deploy through Cairo syscall (another account is needed)

  • using Universal Deployer Contract (another account is needed)

The first approach is recommended since it doesn’t rely on third-party contracts. The concept behind the DeployAccount transaction is based on prefunding a generated address with tokens and then creating the transaction which will charge the fee from the address.

Deploying an account with DeployAccount transaction requires the following:

  • class_hash of the account contract

  • generating a private key and deployment salt

  • computing an address based on the account’s secrets

  • prefunding an address with the fee tokens (e.g. using the token bridge)

  • creating and signing a DeployAccount transaction with generated secrets

  • sending the transaction to Starknet

Here is step by step example:

from starknet_py.hash.address import compute_address
from starknet_py.net.account.account import Account
from starknet_py.net.full_node_client import FullNodeClient
from starknet_py.net.models import StarknetChainId
from starknet_py.net.signer.stark_curve_signer import KeyPair

# First, make sure to generate private key and salt

key_pair = KeyPair.from_private_key(private_key)

# Compute an address
address = compute_address(
    salt=salt,
    class_hash=class_hash,  # class_hash of the Account declared on the Starknet
    constructor_calldata=[key_pair.public_key],
    deployer_address=0,
)

# Prefund the address (using the token bridge or by sending fee tokens to the computed address)
# Make sure the tx has been accepted on L2 before proceeding

# Define the client to be used to interact with Starknet
client = FullNodeClient(node_url="your.node.url")
chain = StarknetChainId.GOERLI

# Use `Account.deploy_account_v1` or `Account.deploy_account_v3` static methods to deploy an account
account_deployment_result = await Account.deploy_account_v1(
    address=address,
    class_hash=class_hash,
    salt=salt,
    key_pair=key_pair,
    client=client,
    chain=chain,
    constructor_calldata=[key_pair.public_key],
    max_fee=int(1e15),
)
# Wait for deployment transaction to be accepted
await account_deployment_result.wait_for_acceptance()

# From now on, account can be used as usual
account = account_deployment_result.account

Hint

If you are experiencing transaction failures with FEE_TRANSFER_FAILURE make sure that the address you are trying to deploy is prefunded with enough tokens, and verify that max_fee argument in sign_deploy_account_v1() or l1_resource_bounds argument in sign_deploy_account_v3() is set to a high enough value.