Account Package
The Account package provides comprehensive functionality for managing Starknet accounts, building and signing transactions, and executing contract interactions. This package is the primary interface for performing on-chain operations in Starknet applications.
Overview
Accounts in Starknet are smart contracts that manage authentication and authorization for transaction execution. Unlike Ethereum's Externally Owned Accounts (EOAs), Starknet uses Account Abstraction where every account is a contract with customizable validation logic.
The account package lets you create and manage accounts, build and sign different types of transactions (invoke, declare, deploy), estimate fees using resource bounds for V3 transactions, and manage keys through a secure keystore interface. It works with both Cairo 0 and Cairo 2 contracts, giving you flexibility across different contract versions.
Key Components
Functions
- FmtCallDataCairo0 - Format calldata arrays for Cairo 0 contracts
- FmtCallDataCairo2 - Format calldata arrays for Cairo 2 contracts
- PrecomputeAccountAddress - Calculate account address before deployment
Methods
- NewAccount - Create a new account instance
- BuildAndEstimateDeployAccountTxn - Build and estimate deploy account transaction
- BuildAndSendDeclareTxn - Declare a contract class
- BuildAndSendInvokeTxn - Execute contract function calls
- DeployContractWithUDC - Deploy contracts using Universal Deployer Contract
- FmtCalldata - Format calldata based on account Cairo version
- Nonce - Get current account nonce
- SendTransaction - Send a signed transaction
- Sign - Sign a message hash
- SignDeclareTransaction - Sign declare transactions
- SignDeployAccountTransaction - Sign deploy account transactions
- SignInvokeTransaction - Sign invoke transactions
- TransactionHashDeclare - Calculate declare transaction hash
- TransactionHashDeployAccount - Calculate deploy account transaction hash
- TransactionHashInvoke - Calculate invoke transaction hash
- Verify - Verify ECDSA signature
- WaitForTransactionReceipt - Wait for transaction confirmation
Keystore
- GetRandomKeys - Generate random key pairs for testing
- NewMemKeystore - Create empty in-memory keystore
- Get - Retrieve private key from keystore
- Put - Store private key in keystore
- Sign - Sign message hash with stored key
- SetNewMemKeystore - Create keystore with initial key pair
Getting Started
To use the Account package, import it in your Go code:
import "github.com/NethermindEth/starknet.go/account"Quick Example
package main
import (
"context"
"fmt"
"log"
"github.com/NethermindEth/juno/core/felt"
"github.com/NethermindEth/starknet.go/account"
"github.com/NethermindEth/starknet.go/rpc"
)
func main() {
provider, err := rpc.NewProvider("https://starknet-sepolia.public.blastapi.io/rpc/v0_8")
if err != nil {
log.Fatal(err)
}
ks, pubKey, _ := account.GetRandomKeys()
accountAddress, _ := felt.SetString("0x1234...")
acc, err := account.NewAccount(provider, accountAddress, pubKey.String(), ks, account.CairoV2)
if err != nil {
log.Fatal(err)
}
nonce, err := acc.Nonce(context.Background())
if err != nil {
log.Fatal(err)
}
fmt.Printf("Account nonce: %s\n", nonce.String())
}For more examples, see the Examples page.
How Accounts Work in Starknet
Account Abstraction
Starknet implements native Account Abstraction, meaning every account is a smart contract. Each account can define its own signature validation logic, allowing for different authentication methods like ECDSA, Schnorr signatures, or even multisig setups. Accounts can also implement session keys for temporary authorization of specific operations, and since they're contracts, they can be upgraded to add new features over time.
The account package handles these complexities for you while still giving you full control over how transactions are signed and executed.
Transaction Lifecycle
Every transaction in Starknet goes through five steps. First, you build the transaction with its calldata, nonce, and resource bounds. Then you calculate the transaction hash that needs to be signed. Next, you generate an ECDSA signature over that hash. After that, you broadcast the signed transaction to the network. Finally, you poll for the transaction receipt to confirm it was processed.
The account package gives you methods for each individual step if you need fine control, or convenience methods like BuildAndSendInvokeTxn that handle multiple steps automatically.
Transaction Types
Starknet supports three main transaction types. Invoke transactions execute one or more contract function calls in a single transaction. Declare transactions register new contract classes on-chain so they can be deployed later. Deploy Account transactions create new account contracts at a precomputed address.
Each transaction type has different versions (V0, V1, V2, V3) with their own fee mechanisms and data structures. Newer versions generally provide better fee estimation and more granular control over gas costs.
Resource Bounds (V3 Transactions)
Transaction V3 introduces resource bounds that let you set precise limits on fees. You can specify the maximum amount of resources (L1 Gas, L2 Gas, L1 Data Gas) your transaction can consume and the maximum price per unit you're willing to pay. This prevents unexpected fee spikes and gives you much better control over transaction costs.
resourceBounds := &rpc.ResourceBoundsMapping{
L1Gas: rpc.ResourceBounds{
MaxAmount: "0x100000",
MaxPricePerUnit: "0x2540be400",
},
L2Gas: rpc.ResourceBounds{
MaxAmount: "0x0",
MaxPricePerUnit: "0x0",
},
}Choosing the Right Approach
High-Level vs Low-Level Methods
The account package provides both convenience methods and granular control. Use the BuildAndSend methods when you want automatic nonce management and fee estimation with standard transaction settings. These methods handle everything in one call and work well for most applications.
Use manual construction when you need precise control over resource bounds and fees, want to inspect or modify transactions before sending them, or need to implement custom transaction batching logic. Manual construction also helps when you need to separate the building, signing, and sending steps for your specific workflow.
Keystore Implementations
Use MemKeystore when you're developing and testing locally, building CLI tools, or prototyping where keys are generated per-session and don't need to persist. It's simple and works great for development.
Implement a custom keystore when building production applications that need secure key storage, integrating with hardware wallets or HSMs, implementing multi-signature schemes, or when keys need to persist across sessions with proper encryption.
Common Workflows
Deploy a New Account
First generate keys and precompute the address where your account will live. Then fund that precomputed address using a faucet or by transferring tokens to it. Once funded, build and send the deploy account transaction. Finally, wait for confirmation that the account was deployed successfully.
See the Deploy Account example for complete implementation.
Execute Contract Function
Build an invoke function call with the contract address and your calldata. Send the transaction using BuildAndSendInvokeTxn which handles nonce management and signing automatically. Wait for the transaction receipt to confirm execution.
See the Invoke example for detailed walkthrough.
Declare Contract Class
Load your compiled contract files (both the .casm.json and .sierra.json). Build and send the declare transaction which registers the contract class on-chain. The response includes the class hash you'll use to deploy instances of this contract later.
See the Declare example for step-by-step guide.
Use Cases
You can use the account package to build web3 applications that interact with Starknet contracts, create and manage user accounts with custom validation logic, or build bots and automation tools for contract interactions. It handles contract deployment and management, lets you execute multiple contract calls in a single transaction, and supports paymaster patterns for gasless transactions. It's also essential for creating test accounts and executing transactions in development environments.
Understanding Nonces and Replay Protection
Every account maintains a nonce (number used once) that increments with each transaction. This prevents replay attacks where an attacker could re-broadcast a signed transaction. Nonces must be sequential starting from 0, and each transaction consumes exactly one nonce. If you try to send a transaction with the wrong nonce, the network will reject it. The Nonce method retrieves the current nonce from on-chain state.
The BuildAndSend methods automatically fetch and use the correct nonce for you. When using manual construction, you need to track and manage nonces yourself.

