BuildAndEstimateDeployAccountTxn
Builds and estimates a deploy account transaction without sending it to the network. This method precomputes the account address, builds the deploy transaction, signs it, estimates fees, updates the transaction with the estimated fees, and signs again. The returned transaction is ready to be sent, but you must fund the precomputed address with tokens before broadcasting the transaction.
Method Signature
func (account *Account) BuildAndEstimateDeployAccountTxn(
ctx context.Context,
salt *felt.Felt,
classHash *felt.Felt,
constructorCalldata []*felt.Felt,
opts *TxnOptions,
) (*rpc.BroadcastDeployAccountTxnV3, *felt.Felt, error)Source: transaction.go
Parameters
ctx(context.Context): Context for request cancellation and timeoutsalt(*felt.Felt): Random value used for deterministic address generationclassHash(*felt.Felt): Class hash of the account contract to deployconstructorCalldata([]*felt.Felt): Parameters passed to the account contract constructoropts(*TxnOptions): Transaction options for fee estimation and execution. Passnilto use default values
Returns
*rpc.BroadcastDeployAccountTxnV3: Signed deploy account transaction ready to broadcast*felt.Felt: Precomputed account address (must be funded before sending transaction)error: Error if building or estimation fails
BroadcastDeployAccountTxnV3 Structure
Source: types_transaction.go
The returned transaction contains:
type DeployAccountTxnV3 struct {
Type TransactionType `json:"type"`
Version TransactionVersion `json:"version"`
Signature []*felt.Felt `json:"signature"`
Nonce *felt.Felt `json:"nonce"`
ContractAddressSalt *felt.Felt `json:"contract_address_salt"`
ConstructorCalldata []*felt.Felt `json:"constructor_calldata"`
ClassHash *felt.Felt `json:"class_hash"`
ResourceBounds *ResourceBoundsMapping `json:"resource_bounds"`
Tip U64 `json:"tip"`
PayMasterData []*felt.Felt `json:"paymaster_data"`
NonceDataMode DataAvailabilityMode `json:"nonce_data_availability_mode"`
FeeMode DataAvailabilityMode `json:"fee_data_availability_mode"`
}Usage Example
package main
import (
"context"
"fmt"
"log"
"os"
"github.com/NethermindEth/juno/core/felt"
"github.com/NethermindEth/starknet.go/account"
"github.com/NethermindEth/starknet.go/rpc"
"github.com/NethermindEth/starknet.go/utils"
"github.com/joho/godotenv"
)
func main() {
ctx := context.Background()
if err := godotenv.Load(); err != nil {
log.Fatal("Failed to load .env file:", err)
}
rpcURL := os.Getenv("STARKNET_RPC_URL")
if rpcURL == "" {
log.Fatal("STARKNET_RPC_URL not set in .env file")
}
provider, err := rpc.NewProvider(ctx, rpcURL)
if err != nil {
log.Fatal("Failed to create provider:", err)
}
ks, publicKey, privateKey := account.GetRandomKeys()
fmt.Printf("Generated keys:\n")
fmt.Printf(" Public Key: %s\n", publicKey.String())
fmt.Printf(" Private Key: %s\n\n", privateKey)
accnt, err := account.NewAccount(
provider,
publicKey,
publicKey.String(),
ks,
account.CairoV2,
)
if err != nil {
log.Fatal("Failed to create account:", err)
}
classHash, err := utils.HexToFelt("0x061dac032f228abef9c6626f995015233097ae253a7f72d68552db02f2971b8f")
if err != nil {
log.Fatal("Failed to parse class hash:", err)
}
constructorCalldata := []*felt.Felt{publicKey}
salt := publicKey
opts := &account.TxnOptions{
FeeMultiplier: 1.5,
TipMultiplier: 1.0,
}
deployTxn, precomputedAddress, err := accnt.BuildAndEstimateDeployAccountTxn(
ctx,
salt,
classHash,
constructorCalldata,
opts,
)
if err != nil {
log.Fatal("Failed to build and estimate deploy account transaction:", err)
}
fmt.Printf("\nDeploy Account Transaction:\n")
fmt.Printf("Type: %s\n", deployTxn.Type)
fmt.Printf("Version: %s\n", deployTxn.Version)
fmt.Printf("Precomputed Address: %s\n", precomputedAddress.String())
fmt.Printf("Class Hash: %s\n", deployTxn.ClassHash.String())
fmt.Printf("Salt: %s\n", deployTxn.ContractAddressSalt.String())
fmt.Printf("Nonce: %s\n", deployTxn.Nonce.String())
fmt.Printf("Signature Length: %d\n", len(deployTxn.Signature))
fmt.Printf("\nResource Bounds:\n")
fmt.Printf("L1 Gas:\n")
fmt.Printf(" Max Amount: %s\n", deployTxn.ResourceBounds.L1Gas.MaxAmount)
fmt.Printf(" Max Price Per Unit: %s\n", deployTxn.ResourceBounds.L1Gas.MaxPricePerUnit)
fmt.Printf("L2 Gas:\n")
fmt.Printf(" Max Amount: %s\n", deployTxn.ResourceBounds.L2Gas.MaxAmount)
fmt.Printf(" Max Price Per Unit: %s\n", deployTxn.ResourceBounds.L2Gas.MaxPricePerUnit)
fmt.Printf("Tip: %s\n\n", deployTxn.Tip)
overallFee, err := utils.ResBoundsMapToOverallFee(
deployTxn.ResourceBounds,
1,
deployTxn.Tip,
)
if err != nil {
log.Fatal("Failed to calculate overall fee:", err)
}
fmt.Printf("Estimated Fee: %s STRK\n\n", overallFee.String())
fmt.Printf("Fund the precomputed address with STRK tokens:\n")
fmt.Printf(" Address: %s\n", precomputedAddress.String())
fmt.Printf(" Amount: At least %s STRK\n\n", overallFee.String())
}Error Handling
tx, addr, err := acc.BuildAndEstimateDeployAccountTxn(ctx, salt, classHash, calldata, opts)
if err != nil {
switch {
case errors.Is(err, account.ErrInvalidClassHash):
log.Println("Invalid class hash provided")
case errors.Is(err, rpc.ErrContractNotFound):
log.Println("Class hash not found on network")
default:
log.Printf("Failed to build transaction: %v", err)
}
return
}
// Verify address before funding
fmt.Printf("Fund this address: %s\n", addr.String())Common Use Cases
- Calculate the account address before deployment and fund it with tokens
- Estimate deployment fees before committing to deploy an account
- Prepare a deploy account transaction that can be sent later after funding
- Deploy new account contracts using standard account classes (OpenZeppelin, Argent, Braavos)
- Essential first step in the account deployment workflow before calling SendTransaction

