Skip to main content

Signer Interface

software.sava.core.accounts.Signer Provides Ed25519 key pair management and signing capabilities.

Constants

int KEY_LENGTH = 32;
KEY_LENGTH
int
Length of Ed25519 private key in bytes (32)

Key Generation

Generate Private Key

static byte[] generatePrivateKeyBytes()
return
byte[]
32-byte randomly generated private key

Generate Key Pair

static byte[] generatePrivateKeyPairBytes()
return
byte[]
64-byte array containing private key (bytes 0-31) and public key (bytes 32-63)

Create From Private Key

static byte[] createKeyPairBytesFromPrivateKey(byte[] privateKey)
privateKey
byte[]
required
32-byte private key
return
byte[]
64-byte key pair array

Factory Methods

From Private Key

static Signer createFromPrivateKey(byte[] privateKey)
privateKey
byte[]
required
32-byte private key (will be copied)
return
Signer
KeyPairSigner instance with generated public key

From Key Pair

static Signer createFromKeyPair(byte[] keyPair)
keyPair
byte[]
required
64-byte array containing private key (0-31) and public key (32-63)
return
Signer
KeyPairSigner instance
static Signer createFromKeyPair(
    byte[] publicKey,
    byte[] privateKey
)
publicKey
byte[]
required
32-byte public key
privateKey
byte[]
required
32-byte private key
static Signer createFromKeyPair(
    PublicKey publicKey,
    PrivateKey privateKey
)
publicKey
PublicKey
required
Sava PublicKey instance
privateKey
PrivateKey
required
Java security PrivateKey instance

Key Validation

static void validateKeyPair(
    byte[] privateKey,
    byte[] expectedPublicKey
)
privateKey
byte[]
required
Private key to validate
expectedPublicKey
byte[]
required
Expected public key derived from private key
Throws IllegalStateException if keys don’t match or public key is invalid.
static void validateKeyPair(byte[] keyPair)
keyPair
byte[]
required
64-byte key pair to validate

Instance Methods

Access Keys

PublicKey publicKey()
return
PublicKey
Public key of this signer
PrivateKey privateKey()
return
PrivateKey
Java security PrivateKey instance

Create Dedicated Signer

Signer createDedicatedSigner()
return
Signer
New signer instance with independent state for multi-threaded signing

Sign Messages

int sign(
    byte[] message,
    int msgOffset,
    int msgLen,
    int outPos
)
message
byte[]
required
Message bytes to sign
msgOffset
int
required
Offset in message array
msgLen
int
required
Length of message
outPos
int
required
Position in message array to write signature
return
int
New position after signature (outPos + 64)
byte[] sign(byte[] message, int msgOffset, int msgLen)
return
byte[]
64-byte Ed25519 signature
byte[] sign(byte[] message)
return
byte[]
64-byte signature of entire message

Example Usage

import software.sava.core.accounts.Signer;
import software.sava.core.accounts.PublicKey;

// Generate new keypair
var keyPair = Signer.generatePrivateKeyPairBytes();
var signer = Signer.createFromKeyPair(keyPair);

// Access public key
PublicKey pubKey = signer.publicKey();
System.out.println("Address: " + pubKey.toBase58());

// Sign a message
byte[] message = "Hello Solana".getBytes();
byte[] signature = signer.sign(message);

// Verify signature
boolean valid = pubKey.verifySignature(message, signature);

// Create from existing private key
var existingSigner = Signer.createFromPrivateKey(privateKeyBytes);

// Multi-threaded signing
var dedicatedSigner = signer.createDedicatedSigner();
// Use dedicatedSigner in another thread

KeyPairSigner Implementation

software.sava.core.accounts.KeyPairSigner Default implementation of the Signer interface.

Features

  • Ed25519 signature generation using BouncyCastle
  • Thread-safe signing operations
  • Secure key storage
  • Automatic public key derivation from private key

Signing Process

  1. Creates Ed25519 signer with private key
  2. Updates signer with message bytes
  3. Generates 64-byte signature
  4. Returns signature or writes to output array

Security Notes

  • Private keys are validated on creation
  • Key pairs are validated to match
  • Secure random number generation for key creation
  • Keys are copied to prevent external modification

Example: Transaction Signing

import software.sava.core.accounts.Signer;
import software.sava.core.tx.Transaction;

// Create signer
var signer = Signer.createFromKeyPair(keyPairBytes);

// Create transaction
var tx = Transaction.createTx(
    signer.publicKey(),
    instructions
);

// Sign transaction
String blockHash = getRecentBlockhash();
tx.sign(blockHash, signer);

// Get base64-encoded signed transaction
String signedTx = tx.base64EncodeToString();

// Or sign and encode in one step
String encoded = tx.signAndBase64Encode(blockHash, signer);

Example: Multiple Signers

import software.sava.core.accounts.Signer;
import java.util.List;

// Create multiple signers
var signer1 = Signer.createFromKeyPair(keyPair1);
var signer2 = Signer.createFromKeyPair(keyPair2);
var signer3 = Signer.createFromKeyPair(keyPair3);

// Sign transaction with multiple signers
var signers = List.of(signer1, signer2, signer3);
tx.sign(blockHash, signers);

Build docs developers (and LLMs) love