Overview

The Spark SDK provides the SparkSigner interface to enable flexible implementation of signing operations. This abstraction allows you to customize how cryptographic operations are performed and enables support for different signing strategies including multisig configurations, hardware wallets, and other specialized key management systems.
The SDK includes a default implementation (DefaultSparkSigner) that handles standard single-signature operations. This can serve as a reference for implementing custom signers that support multisig, hardware wallets, or other advanced signing schemes.
getIdentityPublicKey(): Promise<Uint8Array>;
getDepositSigningKey(): Promise<Uint8Array>;
generateStaticDepositKey(idx: number): Promise<Uint8Array>;
getStaticDepositSigningKey(idx: number): Promise<Uint8Array>;
getStaticDepositSecretKey(idx: number): Promise<Uint8Array>;

generateMnemonic(): Promise<string>;
mnemonicToSeed(mnemonic: string): Promise<Uint8Array>;

createSparkWalletFromSeed(
  seed: Uint8Array | string,
  accountNumber?: number,
): Promise<string>;

restoreSigningKeysFromLeafs(leafs: TreeNode[]): Promise<void>;
getTrackedPublicKeys(): Promise<Uint8Array[]>;
// Generates a new private key, and returns the public key
generatePublicKey(hash?: Uint8Array): Promise<Uint8Array>;
// Called when a public key is no longer needed
removePublicKey(publicKey: Uint8Array): Promise<void>;
getSchnorrPublicKey(publicKey: Uint8Array): Promise<Uint8Array>;

signSchnorr(message: Uint8Array, publicKey: Uint8Array): Promise<Uint8Array>;
signSchnorrWithIdentityKey(message: Uint8Array): Promise<Uint8Array>;

subtractPrivateKeysGivenPublicKeys(
  first: Uint8Array,
  second: Uint8Array,
): Promise<Uint8Array>;
splitSecretWithProofs(
  params: SplitSecretWithProofsParams,
): Promise<VerifiableSecretShare[]>;

signFrost(params: SignFrostParams): Promise<Uint8Array>;
aggregateFrost(params: AggregateFrostParams): Promise<Uint8Array>;

signMessageWithPublicKey(
  message: Uint8Array,
  publicKey: Uint8Array,
  compact?: boolean,
): Promise<Uint8Array>;
// If compact is true, the signature should be in ecdsa compact format else it should be in DER format
signMessageWithIdentityKey(
  message: Uint8Array,
  compact?: boolean,
): Promise<Uint8Array>;
validateMessageWithIdentityKey(
  message: Uint8Array,
  signature: Uint8Array,
): Promise<boolean>;

encryptLeafPrivateKeyEcies(
  receiverPublicKey: Uint8Array,
  publicKey: Uint8Array,
): Promise<Uint8Array>;
decryptEcies(ciphertext: Uint8Array): Promise<Uint8Array>;

getRandomSigningCommitment(): Promise<SigningCommitment>;

hashRandomPrivateKey(): Promise<Uint8Array>;
generateAdaptorFromSignature(signature: Uint8Array): Promise<{
  adaptorSignature: Uint8Array;
  adaptorPublicKey: Uint8Array;
}>;

getDepositSigningKey(): Promise<Uint8Array>;
getMasterPublicKey(): Promise<Uint8Array>;

Core Concepts

Key Types

  • Identity Key: Primary wallet identifier used for authentication
  • Signing Keys: Derived keys for specific transaction outputs
  • Deposit Keys: Keys for receiving L1 Bitcoin deposits
  • Static Deposit Keys: Reusable keys for deposit operations

Security Model

All private keys are derived from a master seed using BIP32 hierarchical deterministic key derivation. The signer maintains an internal mapping between public keys and their corresponding private keys, ensuring secure access control.

Interface Methods

Wallet Initialization

generateMnemonic()

Generates a new BIP39 mnemonic phrase for wallet creation.
async generateMnemonic(): Promise<string>
Returns:
  • Promise<string>: A 12-word BIP39 mnemonic phrase
Example:
const mnemonic = await signer.generateMnemonic();
console.log(mnemonic); // "abandon ability able about above absent..."

mnemonicToSeed(mnemonic: string)

Converts a BIP39 mnemonic phrase to a cryptographic seed.
async mnemonicToSeed(mnemonic: string): Promise<Uint8Array>
Parameters:
  • mnemonic: Valid BIP39 mnemonic phrase
Returns:
  • Promise<Uint8Array>: 64-byte seed derived from the mnemonic

createSparkWalletFromSeed(seed, accountNumber?)

Initializes the signer with a master seed and derives all necessary keys.
async createSparkWalletFromSeed(
  seed: Uint8Array | string,
  accountNumber?: number,
): Promise<string>
Parameters:
  • seed: Master seed as bytes or hex string
  • accountNumber: (Optional, default: 0) Account index for key derivation
Returns:
  • Promise<string>: Hex-encoded identity public key
Example:
const seed = await signer.mnemonicToSeed(mnemonic);
const identityPubKey = await signer.createSparkWalletFromSeed(seed, 0);

Key Management

getIdentityPublicKey()

Retrieves the wallet’s identity public key.
async getIdentityPublicKey(): Promise<Uint8Array>
Returns:
  • Promise<Uint8Array>: The identity public key

getMasterPublicKey()

Retrieves the master public key.
async getMasterPublicKey(): Promise<Uint8Array>
Returns:
  • Promise<Uint8Array>: The master public key

generatePublicKey(hash?)

Generates a new signing key pair and returns the public key.
async generatePublicKey(hash?: Uint8Array): Promise<Uint8Array>
Parameters:
  • hash: (Optional) Deterministic hash for key derivation
Returns:
  • Promise<Uint8Array>: The generated public key

removePublicKey(publicKey)

Removes a public key from the signer’s tracked keys.
async removePublicKey(publicKey: Uint8Array): Promise<void>
Parameters:
  • publicKey: Public key to remove

getTrackedPublicKeys()

Returns all currently tracked public keys.
async getTrackedPublicKeys(): Promise<Uint8Array[]>
Returns:
  • Promise<Uint8Array[]>: Array of tracked public keys

Deposit Address Management

getDepositSigningKey()

Retrieves the deposit signing public key.
async getDepositSigningKey(): Promise<Uint8Array>
Returns:
  • Promise<Uint8Array>: The deposit signing public key

generateStaticDepositKey(idx)

Generates or retrieves a static deposit key by index.
async generateStaticDepositKey(idx: number): Promise<Uint8Array>
Parameters:
  • idx: Index for the static deposit key
Returns:
  • Promise<Uint8Array>: The static deposit public key

getStaticDepositSigningKey(idx)

Retrieves a static deposit signing key by index.
async getStaticDepositSigningKey(idx: number): Promise<Uint8Array>
Parameters:
  • idx: Index for the static deposit key
Returns:
  • Promise<Uint8Array>: The static deposit signing public key

getStaticDepositSecretKey(idx)

Retrieves a static deposit private key by index.
async getStaticDepositSecretKey(idx: number): Promise<Uint8Array>
Parameters:
  • idx: Index for the static deposit key
Returns:
  • Promise<Uint8Array>: The static deposit private key

Digital Signatures

signMessageWithIdentityKey(message, compact?)

Signs a message using the wallet’s identity key.
async signMessageWithIdentityKey(
  message: Uint8Array,
  compact?: boolean,
): Promise<Uint8Array>
Parameters:
  • message: Message to sign
  • compact: (Optional, default: false) Use compact signature format
Returns:
  • Promise<Uint8Array>: ECDSA signature (DER or compact format)

signMessageWithPublicKey(message, publicKey, compact?)

Signs a message using a specific public key.
async signMessageWithPublicKey(
  message: Uint8Array,
  publicKey: Uint8Array,
  compact?: boolean,
): Promise<Uint8Array>
Parameters:
  • message: Message to sign
  • publicKey: Public key to use for signing
  • compact: (Optional, default: false) Use compact signature format
Returns:
  • Promise<Uint8Array>: ECDSA signature (DER or compact format)

validateMessageWithIdentityKey(message, signature)

Validates a signature against the identity key.
async validateMessageWithIdentityKey(
  message: Uint8Array,
  signature: Uint8Array,
): Promise<boolean>
Parameters:
  • message: Original message
  • signature: Signature to validate
Returns:
  • Promise<boolean>: True if signature is valid

Schnorr Signatures

getSchnorrPublicKey(publicKey)

Converts a secp256k1 public key to Schnorr format.
async getSchnorrPublicKey(publicKey: Uint8Array): Promise<Uint8Array>
Parameters:
  • publicKey: secp256k1 public key
Returns:
  • Promise<Uint8Array>: Schnorr public key

signSchnorr(message, publicKey)

Creates a Schnorr signature for a message.
async signSchnorr(message: Uint8Array, publicKey: Uint8Array): Promise<Uint8Array>
Parameters:
  • message: Message to sign
  • publicKey: Public key to use for signing
Returns:
  • Promise<Uint8Array>: Schnorr signature

signSchnorrWithIdentityKey(message)

Creates a Schnorr signature using the identity key.
async signSchnorrWithIdentityKey(message: Uint8Array): Promise<Uint8Array>
Parameters:
  • message: Message to sign
Returns:
  • Promise<Uint8Array>: Schnorr signature

Advanced Cryptographic Operations

restoreSigningKeysFromLeafs(leafs)

Restores signing keys from a set of tree leaf nodes.
async restoreSigningKeysFromLeafs(leafs: TreeNode[]): Promise<void>
Parameters:
  • leafs: Array of tree leaf nodes

subtractPrivateKeysGivenPublicKeys(first, second)

Performs private key subtraction and returns the resulting public key.
async subtractPrivateKeysGivenPublicKeys(
  first: Uint8Array,
  second: Uint8Array,
): Promise<Uint8Array>
Parameters:
  • first: First public key
  • second: Second public key
Returns:
  • Promise<Uint8Array>: Resulting public key after subtraction

splitSecretWithProofs(params)

Implements Shamir’s Secret Sharing with verifiable proofs.
interface SplitSecretWithProofsParams {
  secret: Uint8Array;
  curveOrder: bigint;
  threshold: number;
  numShares: number;
  isSecretPubkey?: boolean;
}

async splitSecretWithProofs(
  params: SplitSecretWithProofsParams,
): Promise<VerifiableSecretShare[]>
Parameters:
  • params: Secret sharing parameters
Returns:
  • Promise<VerifiableSecretShare[]>: Array of verifiable secret shares

FROST Protocol (Threshold Signatures)

getRandomSigningCommitment()

Generates a random signing commitment for FROST protocol.
async getRandomSigningCommitment(): Promise<SigningCommitment>
Returns:
  • Promise<SigningCommitment>: Random signing commitment

signFrost(params)

Performs FROST signing operation.
interface SignFrostParams {
  message: Uint8Array;
  privateAsPubKey: Uint8Array;
  publicKey: Uint8Array;
  verifyingKey: Uint8Array;
  selfCommitment: ISigningCommitment;
  statechainCommitments?: { [key: string]: ISigningCommitment };
  adaptorPubKey?: Uint8Array;
}

async signFrost(params: SignFrostParams): Promise<Uint8Array>
Parameters:
  • params: FROST signing parameters
Returns:
  • Promise<Uint8Array>: FROST signature share

aggregateFrost(params)

Aggregates FROST signature shares into a final signature.
interface AggregateFrostParams extends Omit<SignFrostParams, "privateAsPubKey"> {
  selfSignature: Uint8Array;
  statechainSignatures?: { [key: string]: Uint8Array };
  statechainPublicKeys?: { [key: string]: Uint8Array };
}

async aggregateFrost(params: AggregateFrostParams): Promise<Uint8Array>
Parameters:
  • params: FROST aggregation parameters
Returns:
  • Promise<Uint8Array>: Final aggregated signature

Encryption

encryptLeafPrivateKeyEcies(receiverPublicKey, publicKey)

Encrypts a leaf private key using ECIES.
async encryptLeafPrivateKeyEcies(
  receiverPublicKey: Uint8Array,
  publicKey: Uint8Array,
): Promise<Uint8Array>
Parameters:
  • receiverPublicKey: Recipient’s public key
  • publicKey: Public key whose private key to encrypt
Returns:
  • Promise<Uint8Array>: Encrypted private key

decryptEcies(ciphertext)

Decrypts ECIES-encrypted data using the identity key.
async decryptEcies(ciphertext: Uint8Array): Promise<Uint8Array>
Parameters:
  • ciphertext: Encrypted data
Returns:
  • Promise<Uint8Array>: Decrypted public key

Utility Functions

hashRandomPrivateKey()

Generates a hash of a random private key.
async hashRandomPrivateKey(): Promise<Uint8Array>
Returns:
  • Promise<Uint8Array>: SHA256 hash of a random private key

generateAdaptorFromSignature(signature)

Generates an adaptor signature from a regular signature.
async generateAdaptorFromSignature(signature: Uint8Array): Promise<{
  adaptorSignature: Uint8Array;
  adaptorPublicKey: Uint8Array;
}>
Parameters:
  • signature: Original signature
Returns:
  • Promise containing:
    • adaptorSignature: The adaptor signature
    • adaptorPublicKey: The adaptor public key