BuildAndSendInvokeTxn
Builds, signs, estimates fees, and sends an invoke transaction to execute contract functions on Starknet. This method handles the complete transaction lifecycle including nonce management, fee estimation, and transaction signing automatically.
Method Signature
func (account *Account) BuildAndSendInvokeTxn(
ctx context.Context,
functionCalls []rpc.InvokeFunctionCall,
opts *TxnOptions,
) (rpc.AddInvokeTransactionResponse, error)Source: transaction.go
Parameters
ctx(context.Context): Context for request cancellation and timeoutfunctionCalls([]rpc.InvokeFunctionCall): Slice of function calls to execute on target contractsopts(*TxnOptions): Transaction options for fee estimation and execution. Passnilto use default values
Returns
rpc.AddInvokeTransactionResponse: Response containing the transaction hasherror: Error if transaction fails
AddInvokeTransactionResponse Structure
Source: types_transaction_response.go
The returned response contains:
type AddInvokeTransactionResponse struct {
Hash *felt.Felt `json:"transaction_hash"`
}Hash(*felt.Felt): Transaction hash of the invoke transaction
Usage Example
package main
import (
"context"
"fmt"
"log"
"math/big"
"os"
"time"
"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)
}
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)
}
strkContractAddress, err := utils.HexToFelt("0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d")
if err != nil {
log.Fatal("Failed to parse STRK contract address:", err)
}
recipient := accountAddressFelt
amount := new(felt.Felt).SetUint64(1000000000000000)
u256Amount, err := utils.HexToU256Felt(amount.String())
if err != nil {
log.Fatal("Failed to convert amount to U256:", err)
}
transferCall := rpc.InvokeFunctionCall{
ContractAddress: strkContractAddress,
FunctionName: "transfer",
CallData: append([]*felt.Felt{recipient}, u256Amount...),
}
opts := &account.TxnOptions{
FeeMultiplier: 1.5,
TipMultiplier: 1.0,
}
response, err := accnt.BuildAndSendInvokeTxn(
ctx,
[]rpc.InvokeFunctionCall{transferCall},
opts,
)
if err != nil {
log.Fatal("Failed to send invoke transaction:", err)
}
fmt.Printf("Invoke Transaction Successful:\n")
fmt.Printf("Transaction Hash: %s\n", response.Hash.String())
txReceipt, err := accnt.WaitForTransactionReceipt(
ctx,
response.Hash,
3*time.Second,
)
if err != nil {
log.Fatal("Failed to get transaction receipt:", err)
}
fmt.Printf("Block Number: %d\n", txReceipt.BlockNumber)
fmt.Printf("Execution Status: %s\n", txReceipt.ExecutionStatus)
fmt.Printf("Finality Status: %s\n", txReceipt.FinalityStatus)
}Error Handling
response, err := acc.BuildAndSendInvokeTxn(ctx, functionCalls, opts)
if err != nil {
switch {
case errors.Is(err, rpc.ErrInsufficientAccountBalance):
log.Println("Insufficient balance to pay transaction fees")
case errors.Is(err, rpc.ErrContractNotFound):
log.Println("Target contract not found")
case errors.Is(err, rpc.ErrInvalidCallData):
log.Println("Invalid function call data")
default:
log.Printf("Failed to send invoke transaction: %v", err)
}
return
}
fmt.Printf("Transaction sent successfully: %s\n", response.Hash.String())Common Use Cases
- Execute contract functions like token transfers, approvals, or swaps
- Interact with DeFi protocols (staking, lending, trading)
- Update contract state by calling state-changing functions
- Batch multiple function calls into a single transaction for atomic execution
- Automatically handles nonce management, fee estimation, and signing in one method call

