npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@starkware-bitcoin/spv-verify

v0.1.8

Published

Raito SPV verification SDK (WASM + TypeScript)

Downloads

26

Readme

Raito SPV Verify SDK

A comprehensive TypeScript SDK for fetching and verifying compressed SPV (Simplified Payment Verification) proofs. Built on WebAssembly for high performance in both web browsers and Node.js environments.

Usage

Quick Start

Using the Singleton Pattern (Recommended)

import { getRaitoSpvSdk } from '@starkware-bitcoin/spv-verify';

async function main() {
  const sdk = getRaitoSpvSdk(); // Gets singleton instance
  await sdk.init();

  const recentHeight = await sdk.fetchRecentProvenHeight();
  console.log('Most recent proven block height:', recentHeight);

  const chainStateResult = await sdk.verifyRecentChainState();
  console.log('MMR root:', chainStateResult.mmrRoot);
  console.log('Chain state height:', chainStateResult.chainState.block_height);

  const blockHeader = await sdk.verifyBlockHeader(
    chainStateResult.chainState.block_height
  );
  console.log('Verified block header prev hash:', blockHeader.prev_blockhash);

  const txid = '4f1b987645e596329b985064b1ce33046e4e293a08fd961193c8ddbb1ca219cc';
  const transaction = await sdk.verifyTransaction(txid);
  console.log('First output value (sats):', transaction.output[0]?.value);
}

main().catch(console.error);

Using Direct Instantiation

import { createRaitoSpvSdk } from '@starkware-bitcoin/spv-verify';

async function main() {
  const sdk = createRaitoSpvSdk(); // Creates new instance
  await sdk.init();

  const recentHeight = await sdk.fetchRecentProvenHeight();
  console.log('Most recent proven block height:', recentHeight);

  const chainStateResult = await sdk.verifyRecentChainState();
  console.log('MMR root:', chainStateResult.mmrRoot);
  console.log('Chain state height:', chainStateResult.chainState.block_height);

  const blockHeader = await sdk.verifyBlockHeader(
    chainStateResult.chainState.block_height
  );
  console.log('Verified block header prev hash:', blockHeader.prev_blockhash);

  const txid = '4f1b987645e596329b985064b1ce33046e4e293a08fd961193c8ddbb1ca219cc';
  const transaction = await sdk.verifyTransaction(txid);
  console.log('First output value (sats):', transaction.output[0]?.value);
}

main().catch(console.error);

Custom RPC URL and Verifier Configuration

You can direct the SDK to another bridge endpoint or tweak the verifier configuration that is passed to the WASM backend:

Using Singleton with Custom Configuration

// Configuration is only used when creating the singleton instance
const sdk = getRaitoSpvSdk({
  raitoRpcUrl: 'https://api.raito.wtf',
  verifierConfig: {
    min_work: '1813388729421943762059264',
    bootloader_hash:
      '0x0001837d8b77b6368e0129ce3f65b5d63863cfab93c47865ee5cbe62922ab8f3',
    task_program_hash:
      '0x00f0876bb47895e8c4a6e7043829d7886e3b135e3ef30544fb688ef4e25663ca',
    task_output_size: 8,
  }
});

Using Direct Instantiation with Custom Configuration

const sdk = createRaitoSpvSdk({
  raitoRpcUrl: 'https://api.raito.wtf',
  verifierConfig: {
    min_work: '1813388729421943762059264',
    bootloader_hash:
      '0x0001837d8b77b6368e0129ce3f65b5d63863cfab93c47865ee5cbe62922ab8f3',
    task_program_hash:
      '0x00f0876bb47895e8c4a6e7043829d7886e3b135e3ef30544fb688ef4e25663ca',
    task_output_size: 8,
  }
});

All fields in the configuration object are optional; omitted values fall back to the defaults shown above.

Singleton Pattern Benefits

The singleton pattern is recommended for most use cases because it:

  • Prevents multiple WASM initializations: Avoids the overhead of loading the WASM module multiple times
  • Maintains state consistency: Ensures all parts of your application use the same SDK instance with shared cache
  • Reduces memory usage: Only one instance exists throughout your application lifecycle
  • Simplifies configuration: Set up the SDK once and use it everywhere

Use resetRaitoSpvSdk() if you need to reinitialize with different parameters or for testing purposes.

Verifying Recent Chain State

  • verifyRecentChainState() downloads the latest recursive proof from the Raito bridge RPC, verifies it with WASM, and caches the result.
  • The returned object contains both the verified mmrRoot and the parsed chainState snapshot (including the most recent proven block_height).
  • Subsequent calls reuse the cached result until a new instance of the SDK is created.

Verifying Block Headers

  • Call verifyBlockHeader(blockHeight) to fetch the inclusion proof and block header for that height. The SDK matches the MMR root with the previously verified chain state before returning the header.
  • You can supply a blockHeader object as the second argument if you already have the header; the SDK will skip the fetch and only verify the proof.

Verifying Transactions

  • verifyTransaction(txid) retrieves the merkle proof from the bridge, verifies it with WASM, and ensures the enclosing block header is part of the verified MMR tree.
  • The method returns the decoded transaction object, which is cached so repeated checks of the same txid are free.

API Reference

getRaitoSpvSdk(config?)

Gets the singleton instance of RaitoSpvSdk. If no instance exists, creates one with the provided parameters.

  • config (optional): Partial<RaitoSpvSdkConfig> configuration object. Contains:
    • raitoRpcUrl (optional): custom bridge RPC endpoint. Defaults to https://api.raito.wtf.
    • verifierConfig (optional): partial verifier configuration. Missing fields fall back to the default verifier settings bundled with the SDK.
  • Returns: the singleton RaitoSpvSdk instance.

createRaitoSpvSdk(config?)

Creates a new instance of RaitoSpvSdk.

  • config (optional): Partial<RaitoSpvSdkConfig> configuration object. Contains:
    • raitoRpcUrl (optional): custom bridge RPC endpoint. Defaults to https://api.raito.wtf.
    • verifierConfig (optional): partial verifier configuration. Missing fields fall back to the default verifier settings bundled with the SDK.
  • Returns: a new RaitoSpvSdk instance.

resetRaitoSpvSdk()

Resets the singleton instance. Useful for testing or reinitialization with different parameters.

  • Returns: void

RaitoSpvSdk

init(): Promise<void>

Loads and initialises the WASM module. Call once before using the other methods.

fetchRecentProvenHeight(): Promise<number>

Fetches the most recent proven Bitcoin block height available from the bridge API.

verifyRecentChainState(): Promise<ChainStateProofVerificationResult>

Downloads and verifies the latest recursive proof. Returns an object with the verified MMR root and the parsed chainState snapshot. Results are cached per SDK instance.

verifyBlockHeader(blockHeight: number, blockHeader?: BlockHeader): Promise<BlockHeader>

Verifies that the block header at blockHeight is included in the proven MMR. Optionally accepts a pre-fetched header to avoid an extra RPC round trip.

verifyTransaction(txid: string): Promise<Transaction>

Verifies the merkle proof for txid, ensures the enclosing block header is in the MMR, and returns the parsed transaction data.

Types

RaitoSpvSdkConfig

interface RaitoSpvSdkConfig {
  raitoRpcUrl: string;
  verifierConfig: Partial<VerifierConfig>;
}

Configuration object for initializing the RaitoSpvSdk. Both fields are required when using the full config object, but when passed to getRaitoSpvSdk() or createRaitoSpvSdk(), you can use Partial<RaitoSpvSdkConfig> to make all fields optional.

  • raitoRpcUrl: The RPC endpoint URL for the Raito bridge API
  • verifierConfig: Partial verifier configuration that will be merged with defaults

VerifierConfig

interface VerifierConfig {
  min_work: string;
  bootloader_hash: string;
  task_program_hash: string;
  task_output_size: number;
}

Verifier configuration passed to the WASM backend for proof verification.

ChainStateProofVerificationResult

interface ChainStateProofVerificationResult {
  mmrRoot: string;
  chainState: ChainState;
}

ChainState

interface ChainState {
  block_height: number;
  total_work: string;
  best_block_hash: string;
  current_target: string;
  epoch_start_time: number;
  prev_timestamps: number[];
}

BlockHeader

interface BlockHeader {
  version: number;
  prev_blockhash: string;
  merkle_root: string;
  time: number;
  bits: number;
  nonce: number;
}

Transaction

interface Transaction {
  version: number;
  lock_time: number;
  input: Array<{
    previous_output: { txid: string; vout: number };
    script_sig: string;
    sequence: number;
    witness: string[];
  }>;
  output: Array<{
    value: bigint;
    script_pubkey: string;
  }>;
}

Building from Source

Prerequisites

  • Rust toolchain (latest stable)
  • wasm-pack for building WASM
  • Node.js 18+ and npm

Build Steps

# Install wasm-pack if you haven't already
cargo install wasm-pack

# Build the complete SDK (includes WASM compilation and TypeScript bundling)
npm run build

Examples

The SDK includes complete examples demonstrating different usage patterns:

Node.js Example

# Run the Node.js example
node examples/node-example.js

Block Proof Example

# Run the block proof example
node examples/block-proof-example.js

Web Browser Example

# Start the web example development server
cd examples/web-example
npm install
npm run dev