Sign
Signs a felt message using the account's private key from the keystore. The signature is compatible with Starknet's signature verification scheme and returns two felt components (r, s).
Method Signature
func (account *Account) Sign(ctx context.Context, msg *felt.Felt) ([]*felt.Felt, error)Source: signature.go
Parameters
ctx- Context for cancellation and timeoutmsg- Message to sign as felt
Returns
[]*felt.Felt- Signature as array [r, s]error- Error if signing fails
Usage Example
package main
import (
"context"
"fmt"
"log"
"math/big"
"os"
"github.com/NethermindEth/juno/core/felt"
"github.com/NethermindEth/starknet.go/account"
"github.com/NethermindEth/starknet.go/curve"
"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)
}
message := new(felt.Felt).SetUint64(12345)
fmt.Printf("Message to sign: %s\n", message.String())
fmt.Printf("Message (decimal): %d\n", message.Uint64())
signature, err := accnt.Sign(ctx, message)
if err != nil {
log.Fatal("Failed to sign message:", err)
}
fmt.Printf("Signature components:\n")
fmt.Printf(" r: %s\n", signature[0].String())
fmt.Printf(" s: %s\n", signature[1].String())
pubKeyFelt, _ := utils.HexToFelt(publicKey)
isValid, err := curve.Verify(message.BigInt(new(big.Int)), signature[0].BigInt(new(big.Int)), signature[1].BigInt(new(big.Int)), pubKeyFelt.BigInt(new(big.Int)))
if err != nil {
log.Fatal("Failed to verify signature:", err)
}
fmt.Printf("Signature verification: %v\n", isValid)
messageStr := "Hello Starknet!"
fmt.Printf("Original message: \"%s\"\n", messageStr)
messageFelt := new(felt.Felt).SetBigInt(utils.UTF8StrToBig(messageStr))
fmt.Printf("Message as felt: %s\n", messageFelt.String())
signature2, err := accnt.Sign(ctx, messageFelt)
if err != nil {
log.Fatal("Failed to sign message:", err)
}
fmt.Printf("Signature:\n")
fmt.Printf(" r: %s\n", signature2[0].String())
fmt.Printf(" s: %s\n", signature2[1].String())
isValid2, err := curve.Verify(messageFelt.BigInt(new(big.Int)), signature2[0].BigInt(new(big.Int)), signature2[1].BigInt(new(big.Int)), pubKeyFelt.BigInt(new(big.Int)))
if err != nil {
log.Fatal("Failed to verify signature:", err)
}
fmt.Printf("Signature valid: %v\n", isValid2)
txHash, _ := utils.HexToFelt("0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef")
fmt.Printf("Transaction hash: %s\n", txHash.String())
signature3, err := accnt.Sign(ctx, txHash)
if err != nil {
log.Fatal("Failed to sign transaction hash:", err)
}
fmt.Printf("Transaction signature:\n")
fmt.Printf(" r: %s\n", signature3[0].String())
fmt.Printf(" s: %s\n", signature3[1].String())
isValid3, err := curve.Verify(txHash.BigInt(new(big.Int)), signature3[0].BigInt(new(big.Int)), signature3[1].BigInt(new(big.Int)), pubKeyFelt.BigInt(new(big.Int)))
if err != nil {
log.Fatal("Failed to verify signature:", err)
}
fmt.Printf("Signature valid: %v\n", isValid3)
}Error Handling
signature, err := acc.Sign(ctx, message)
if err != nil {
// Handle errors like:
// - Key not found in keystore
// - Signing failure
return err
}Common Use Cases
- Sign arbitrary messages for off-chain verification
- Create signatures for custom authentication schemes
- Sign data for cross-chain message passing
- Generate proofs of ownership or authorization
- Low-level signing operations (most users should use transaction-specific signing methods)

