Skip to main content
Verify message signatures without creating a wallet instance. This is useful for readonly verification scenarios where you only have access to a Spark address.

Use Case

When building applications that need to verify signatures but don’t have access to wallet credentials:
  • Readonly wallet views
  • Signature verification services
  • Cross-chain verification (verifying Spark signatures from other chains)
  • Server-side verification without sensitive key material

How It Works

Spark addresses encode the wallet’s identity public key. You can extract this key using decodeSparkAddress and verify signatures directly with secp256k1.

Implementation

import { decodeSparkAddress } from "@buildonspark/spark-sdk";
import * as secp256k1 from "@noble/secp256k1";

// Extract identity public key from Spark address
const { identityPublicKey } = decodeSparkAddress(address, network);

// Verify the signature
const isValid = secp256k1.verify(signature, message, identityPublicKey);

Parameters

address
string
required
The Spark address to extract the identity public key from
network
NetworkType
required
The network type (MAINNET, TESTNET, or REGTEST)
signature
Uint8Array | string
required
The signature to verify
message
Uint8Array | string
required
The original message that was signed

Full Example

import { decodeSparkAddress, NetworkType } from "@buildonspark/spark-sdk";
import * as secp256k1 from "@noble/secp256k1";
import { sha256 } from "@noble/hashes/sha256";

async function verifySparkSignature(
  address: string,
  message: string,
  signature: string,
  network: NetworkType = NetworkType.MAINNET
): Promise<boolean> {
  // Decode address to get identity public key
  const { identityPublicKey } = decodeSparkAddress(address, network);

  // Hash the message (signatures are typically over message hashes)
  const messageHash = sha256(new TextEncoder().encode(message));

  // Convert signature from hex if needed
  const sigBytes = typeof signature === "string"
    ? Uint8Array.from(Buffer.from(signature, "hex"))
    : signature;

  // Verify using secp256k1
  return secp256k1.verify(sigBytes, messageHash, identityPublicKey);
}

// Usage
const isValid = await verifySparkSignature(
  "sp1qw508d6qejxtdg4y5r3zarvary0c5xw7k...",
  "Hello, Spark!",
  "304402..."
);
console.log("Signature valid:", isValid);

Key Points

No Wallet Required

decodeSparkAddress is exported directly from the SDK and doesn’t require wallet initialization

Lightweight

Only needs the SDK and a secp256k1 library—no sensitive data or network calls