SignDeclareTransaction
Signs a declare transaction by calculating the transaction hash and signing it with the account's private key. This method automatically sets the Signature field on the transaction with the resulting (r, s) signature components. Supports V1, V2, V3, and BroadcastDeclareTxnV3 declare transactions.
Method Signature
func (account *Account) SignDeclareTransaction(
ctx context.Context,
tx rpc.DeclareTxnType,
) errorSource: signature.go
Parameters
ctx(context.Context): Context for cancellation and timeouttx(rpc.DeclareTxnType): Declare transaction to sign (DeclareTxnV1, DeclareTxnV2, DeclareTxnV3, or BroadcastDeclareTxnV3)
Returns
error: Error if signing fails or transaction type is invalid
Usage Example
package main
import (
"context"
"encoding/json"
"fmt"
"log"
"math/big"
"os"
"github.com/NethermindEth/juno/core/felt"
"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")
}
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)
}
content, err := os.ReadFile("contracts/cairo0/hello_starknet_compiled.json")
if err != nil {
fmt.Printf("Note: Contract file not found, using mock data for demonstration\n\n")
nonce, err := accnt.Nonce(ctx)
if err != nil {
log.Fatal("Failed to get nonce:", err)
}
mockClassHash, _ := utils.HexToFelt("0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef")
mockCompiledClassHash, _ := utils.HexToFelt("0xabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcd")
declareTxn := &rpc.DeclareTxnV3{
Nonce: nonce,
Type: rpc.TransactionTypeDeclare,
Version: rpc.TransactionV3,
ResourceBounds: &rpc.ResourceBoundsMapping{
L1Gas: rpc.ResourceBounds{
MaxAmount: "0x0",
MaxPricePerUnit: "0x0",
},
L1DataGas: rpc.ResourceBounds{
MaxAmount: "0x0",
MaxPricePerUnit: "0x0",
},
L2Gas: rpc.ResourceBounds{
MaxAmount: "0x0",
MaxPricePerUnit: "0x0",
},
},
Tip: "0x0",
PayMasterData: []*felt.Felt{},
AccountDeploymentData: []*felt.Felt{},
NonceDataMode: rpc.DAModeL1,
FeeMode: rpc.DAModeL1,
SenderAddress: accountAddressFelt,
ClassHash: mockClassHash,
CompiledClassHash: mockCompiledClassHash,
Signature: []*felt.Felt{},
}
fmt.Printf("Sender: %s\n", declareTxn.SenderAddress.String())
fmt.Printf("Nonce: %d\n", declareTxn.Nonce.Uint64())
fmt.Printf("Class Hash: %s\n", declareTxn.ClassHash.String())
fmt.Printf("Compiled Class Hash: %s\n", declareTxn.CompiledClassHash.String())
fmt.Printf("Signature (before): %v\n\n", declareTxn.Signature)
err = accnt.SignDeclareTransaction(ctx, declareTxn)
if err != nil {
log.Fatal("Failed to sign declare transaction:", err)
}
fmt.Printf("Signature components:\n")
fmt.Printf(" r: %s\n", declareTxn.Signature[0].String())
fmt.Printf(" s: %s\n", declareTxn.Signature[1].String())
} else {
var class contracts.ContractClass
if err := json.Unmarshal(content, &class); err != nil {
log.Fatal("Failed to unmarshal contract class:", err)
}
fmt.Printf("Contract class loaded with %d entry points\n", len(class.EntryPointsByType.External))
}
}Error Handling
err := acc.SignDeclareTransaction(ctx, declareTx)
if err != nil {
switch {
case errors.Is(err, account.ErrInvalidTransactionType):
log.Println("Invalid declare transaction type")
case errors.Is(err, account.ErrHashCalculationFailed):
log.Println("Failed to calculate transaction hash")
case errors.Is(err, account.ErrSigningFailed):
log.Println("Failed to sign transaction")
default:
log.Printf("Failed to sign declare transaction: %v", err)
}
return
}Common Use Cases
- Sign manually constructed declare transactions before sending
- Low-level transaction signing for advanced workflows
- Usually handled automatically by BuildAndSendDeclareTxn
- Custom transaction flows requiring manual signing control
- Testing and debugging declare transaction signing

