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