BuildAndSendDeclareTxn
Builds, signs, estimates fees, and sends a declare transaction to register a new contract class on Starknet. This method handles the entire declaration process including nonce management, fee estimation, and transaction signing automatically. The returned class hash can be used to deploy contract instances.
Method Signature
func (account *Account) BuildAndSendDeclareTxn(
ctx context.Context,
casmClass *contracts.CasmClass,
contractClass *contracts.ContractClass,
opts *TxnOptions,
) (rpc.AddDeclareTransactionResponse, error)Source: transaction.go
Parameters
ctx(context.Context): Context for request cancellation and timeoutcasmClass(*contracts.CasmClass): Compiled CASM (Cairo Assembly) class generated from Sierra compilationcontractClass(*contracts.ContractClass): Sierra contract class containing the high-level contract definitionopts(*TxnOptions): Transaction options for fee estimation and execution. Passnilto use default values
Returns
rpc.AddDeclareTransactionResponse: Response containing transaction hash and declared class hasherror: Error if declaration fails
AddDeclareTransactionResponse Structure
Source: types_transaction_response.go
The returned response contains:
type AddDeclareTransactionResponse struct {
Hash *felt.Felt `json:"transaction_hash"`
ClassHash *felt.Felt `json:"class_hash"`
}Hash(*felt.Felt): Transaction hash of the declare transactionClassHash(*felt.Felt): Class hash of the declared contract (used for deployment)
Usage Example
package main
import (
"context"
"encoding/json"
"fmt"
"log"
"math/big"
"os"
"github.com/NethermindEth/starknet.go/account"
"github.com/NethermindEth/starknet.go/contracts"
"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)
}
accountAddress := os.Getenv("ACCOUNT_ADDRESS")
publicKey := os.Getenv("ACCOUNT_PUBLIC_KEY")
privateKey := os.Getenv("ACCOUNT_PRIVATE_KEY")
if accountAddress == "" || publicKey == "" || privateKey == "" {
log.Fatal("ACCOUNT_ADDRESS, ACCOUNT_PUBLIC_KEY, or ACCOUNT_PRIVATE_KEY not set in .env")
}
ks := account.NewMemKeystore()
privKeyBI, ok := new(big.Int).SetString(privateKey, 0)
if !ok {
log.Fatal("Failed to parse private key")
}
ks.Put(publicKey, privKeyBI)
accountAddressFelt, err := utils.HexToFelt(accountAddress)
if err != nil {
log.Fatal("Failed to parse account address:", err)
}
accnt, err := account.NewAccount(
provider,
accountAddressFelt,
publicKey,
ks,
account.CairoV2,
)
if err != nil {
log.Fatal("Failed to create account:", err)
}
sierraFile, err := os.ReadFile("contract.sierra.json")
if err != nil {
log.Fatal("Failed to read sierra file:", err)
}
var contractClass contracts.ContractClass
if err := json.Unmarshal(sierraFile, &contractClass); err != nil {
log.Fatal("Failed to unmarshal contract class:", err)
}
casmClass, err := contracts.UnmarshalCasmClass("contract.casm.json")
if err != nil {
log.Fatal("Failed to unmarshal casm class:", err)
}
opts := &account.TxnOptions{
FeeMultiplier: 1.5,
TipMultiplier: 1.0,
}
response, err := accnt.BuildAndSendDeclareTxn(
ctx,
casmClass,
&contractClass,
opts,
)
if err != nil {
log.Fatal("Failed to declare contract:", err)
}
fmt.Printf("Declare Transaction Successful:\n")
fmt.Printf("Transaction Hash: %s\n", response.Hash.String())
fmt.Printf("Class Hash: %s\n", response.ClassHash.String())
fmt.Printf("\nUse this class hash to deploy contract instances\n")
}Error Handling
response, err := acc.BuildAndSendDeclareTxn(ctx, casmClass, contractClass, opts)
if err != nil {
switch {
case errors.Is(err, rpc.ErrClassAlreadyDeclared):
log.Println("Contract class already declared on network")
case errors.Is(err, rpc.ErrInvalidContractClass):
log.Println("Invalid contract class format")
case errors.Is(err, rpc.ErrInsufficientAccountBalance):
log.Println("Insufficient balance to pay transaction fees")
default:
log.Printf("Failed to declare contract: %v", err)
}
return
}
fmt.Printf("Declared successfully with class hash: %s\n", response.ClassHash.String())Common Use Cases
- Register a new contract class on Starknet before deploying instances
- Declare upgraded versions of existing contracts with new class hashes
- Deploy libraries or base contracts that will be used by other contracts
- Essential first step before using DeployContractWithUDC to create contract instances
- Automatically handles nonce management, fee estimation, and signing in one method call

