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

@babylonlabs-io/babylon-tbv-rust-wasm

v0.4.0

Published

BTC Vault WASM bindings for Babylon Trustless Bitcoin Vaults

Readme

@babylonlabs-io/babylon-tbv-rust-wasm

WASM bindings for Babylon Trustless Bitcoin Vaults (TBV), providing TypeScript/JavaScript interfaces for creating Bitcoin peg-in transactions.

Overview

This package provides WebAssembly bindings to the btc-vault Rust library, enabling browser and Node.js applications to construct Bitcoin transactions for TBV.

Installation

pnpm add @babylonlabs-io/babylon-tbv-rust-wasm

Usage

Creating a Peg-In Transaction

import {
  createPegInTransaction,
  type PegInParams,
} from '@babylonlabs-io/babylon-tbv-rust-wasm';

const params: PegInParams = {
  depositTxid: 'abc123...',
  depositVout: 0,
  depositValue: 100000n,
  depositScriptPubKey: '76a914...',
  depositorPubkey: '02abc...',
  claimerPubkey: '03def...',
  challengerPubkeys: ['04ghi...'],
  pegInAmount: 95000n,
  fee: 5000n,
  network: 'testnet',
};

const result = await createPegInTransaction(params);
console.log(result.txHex); // Transaction hex
console.log(result.txid); // Transaction ID

Creating a Payout Connector

The payout connector generates taproot scripts needed for signing payout transactions (both optimistic and regular payout paths).

import {
  createPayoutConnector,
  TAP_INTERNAL_KEY,
  type PayoutConnectorParams,
} from '@babylonlabs-io/babylon-tbv-rust-wasm';

const params: PayoutConnectorParams = {
  depositor: 'abc123...', // X-only pubkey (hex)
  vaultProvider: 'def456...', // X-only pubkey (hex)
  vaultKeepers: ['ghi789...'], // Array of vault keeper x-only pubkeys (hex)
  universalChallengers: ['jkl012...'], // Array of universal challenger x-only pubkeys (hex)
  timelockPegin: 50, // CSV timelock in blocks for PegIn output
};

const payoutInfo = await createPayoutConnector(params, 'testnet');

// Use taprootScriptHash for PSBT signing (this is the tapLeafHash)
console.log(payoutInfo.taprootScriptHash);

// Use tapInternalKey constant for PSBT signing
console.log(TAP_INTERNAL_KEY); // "50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0"

// Other available fields:
console.log(payoutInfo.payoutScript); // Full payout script (hex)
console.log(payoutInfo.scriptPubKey); // Taproot script pubkey (hex)
console.log(payoutInfo.address); // P2TR address

Assert Payout/NoPayout Connector

The Assert Payout/NoPayout connector generates taproot scripts for the depositor-as-claimer path. It produces payout scripts from Assert output 0 and per-challenger NoPayout scripts.

import {
  getAssertPayoutScriptInfo,
  getAssertNoPayoutScriptInfo,
  type AssertPayoutNoPayoutConnectorParams,
} from '@babylonlabs-io/babylon-tbv-rust-wasm';

const params: AssertPayoutNoPayoutConnectorParams = {
  claimer: 'abc123...',            // Depositor acting as claimer, x-only pubkey (hex)
  localChallengers: ['def456...'], // Local challenger x-only pubkeys (hex)
  universalChallengers: ['ghi789...'], // Universal challenger x-only pubkeys (hex)
  timelockAssert: 144,             // CSV timelock in blocks for Assert output
  councilMembers: ['jkl012...'],   // Security council member x-only pubkeys (hex)
  councilQuorum: 3,                // Council quorum (N-of-N)
};

// Payout script from Assert output 0
const payoutInfo = await getAssertPayoutScriptInfo(params);
console.log(payoutInfo.payoutScript);       // Payout script (hex)
console.log(payoutInfo.payoutControlBlock);  // Control block (hex)

// NoPayout script for a specific challenger
const noPayoutInfo = await getAssertNoPayoutScriptInfo(params, 'def456...');
console.log(noPayoutInfo.noPayoutScript);       // NoPayout script (hex)
console.log(noPayoutInfo.noPayoutControlBlock);  // Control block (hex)

ChallengeAssert Connector

The ChallengeAssert connector generates scripts for ChallengeAssert transactions in the depositor-as-claimer path. It uses Lamport hashes and GC input label hashes provided by the vault provider.

import {
  getChallengeAssertScriptInfo,
  type ChallengeAssertConnectorParams,
} from '@babylonlabs-io/babylon-tbv-rust-wasm';

const params: ChallengeAssertConnectorParams = {
  claimer: 'abc123...',              // Depositor acting as claimer, x-only pubkey (hex)
  challenger: 'def456...',           // Challenger x-only pubkey (hex)
  lamportHashesJson: '[[...]]',      // JSON string of Lamport hashes from VP
  gcInputLabelHashesJson: '[[...]]', // JSON string of GC input label hashes from VP
};

const scriptInfo = await getChallengeAssertScriptInfo(params);
console.log(scriptInfo.script);       // ChallengeAssert script (hex)
console.log(scriptInfo.controlBlock); // Control block (hex)

Constants

The package exports the taproot internal key constant used for vault transactions:

import { TAP_INTERNAL_KEY, tapInternalPubkey } from '@babylonlabs-io/babylon-tbv-rust-wasm';

// As hex string
console.log(TAP_INTERNAL_KEY);
// "50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0"

// As Buffer
console.log(tapInternalPubkey);
// Buffer containing the x-only pubkey

Development

Prerequisites

For normal development (building TypeScript):

  • Node.js >= 24
  • pnpm >= 10

For updating WASM bindings (rare):

  • Rust 1.92.0 (via rustup) - Required for reproducible builds
  • wasm-pack >= 0.13.1
  • LLVM (for secp256k1 compilation)

On macOS with Homebrew:

# Install Rust via rustup (not Homebrew)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# Install wasm32 target
rustup target add wasm32-unknown-unknown

# Install wasm-pack
cargo install wasm-pack

# Install LLVM
brew install llvm

# The rust-toolchain.toml file in this directory will automatically
# install and use Rust 1.92.0 when you enter this directory.
# Just cd into the directory and rustup will handle it:
cd packages/babylon-tbv-rust-wasm/
rustc --version  # Will automatically be 1.92.0

How version pinning works:

This package includes a rust-toolchain.toml file that pins Rust to version 1.92.0:

[toolchain]
channel = "1.92.0"

When you cd into this directory, rustup automatically:

  1. Downloads Rust 1.92.0 if not already installed
  2. Switches to use 1.92.0 for all commands in this directory
  3. Ensures everyone on the team uses the exact same version

The build script also enforces this version with a runtime check, failing early if wrong version is detected.

Building

Regular Build (TypeScript only) - Fast ⚡

pnpm run build

Build time: very fast

This compiles the TypeScript wrapper (src/index.tsdist/index.js). The WASM files are already pre-built and checked into git at dist/generated/.

Use this for:

  • Normal development
  • Making changes to TypeScript code
  • CI/CD pipelines
  • Publishing the package

Rebuilding WASM (only when updating btc-vault) - Slow 🐌

pnpm run build-wasm

Build time: slower

This script:

  1. Clones the btc-vault repository
  2. Checks out a specific commit on a branch
  3. Builds the Rust code to WebAssembly using wasm-pack
  4. Outputs generated files to dist/generated/

You only need to run build-wasm when:

  • Updating to a new btc-vault commit/tag/release
  • The WASM bindings API changes in btc-vault

Project Structure

packages/babylon-tbv-rust-wasm/
├── src/
│   ├── index.ts              # Main entry point
│   ├── types.ts              # TypeScript type definitions
│   ├── constants.ts          # Taproot constants
│   ├── payoutConnector.ts    # Payout connector wrapper
│   ├── assertPayoutNoPayoutConnector.ts  # Assert Payout/NoPayout connector
│   └── challengeAssertConnector.ts       # ChallengeAssert connector
├── dist/
│   ├── generated/            # WASM files (pre-built)
│   │   ├── btc_vault.js
│   │   ├── btc_vault.d.ts
│   │   ├── btc_vault_bg.wasm
│   │   └── btc_vault_bg.wasm.d.ts
│   ├── *.js                  # Compiled TypeScript
│   ├── *.d.ts                # Type declarations
│   └── *.map                 # Source maps
├── scripts/
│   └── build-wasm.js         # Rebuild WASM from btc-vault
└── package.json

Key points:

  • src/ contains TypeScript source code
  • dist/generated/ contains pre-built WASM bindings

Updating btc-vault Version

When btc-vault releases a new version or you want to update the WASM bindings:

  1. Ensure you have Rust 1.92.0:

    rustc --version
    # Should output: rustc 1.92.0 (ded5c06cf 2025-12-08)
    
    # If not, update:
    rustup update stable
  2. Edit configuration in scripts/build-wasm.js:

    const BTC_VAULT_BRANCH = 'main'; // or "feat/branch-name"
    const BTC_VAULT_COMMIT = '<new-commit-sha>';
    const REQUIRED_RUSTC_VERSION = '1.92.0'; // Update if needed
  3. Rebuild WASM:

    pnpm run build-wasm

    The build script will:

    • Verify your Rust version matches REQUIRED_RUSTC_VERSION
    • Clone btc-vault at the specified commit
    • Build WASM bindings
    • Copy generated files to dist/generated/
  4. Test the build:

    pnpm run build
  5. Commit the updated WASM files to git:

    git add scripts/build-wasm.js dist/generated/
    git commit -m "chore: update btc-vault WASM to <commit-sha>"

Reproducible Builds

Why WASM binaries may differ between developers:

The WASM binary includes debug information with file paths, which contain usernames:

  • Developer A: /Users/alice/.cargo/... (21 chars)
  • Developer B: /Users/bob/.cargo/... (18 chars)
  • 29 embedded paths × 3 byte difference = ~87 byte size difference

This causes ~64-100 byte size differences due to different path lengths. This is expected and normal - the binaries are functionally equivalent and work identically.

Why we can't remove paths (yet):

  • Rust's trim-paths feature (RFC 3127) would solve this
  • ❌ Still nightly-only, not available in stable Rust 1.92.0
  • ✅ Will be monitored and adopted when stabilized
  • Alternative (Docker) adds complexity without sufficient benefit

To minimize differences:

  • ✅ All developers use Rust 1.92.0 (enforced by rust-toolchain.toml + build script)
  • ✅ Same wasm-pack version
  • ✅ Same build flags and optimization levels
  • ⏰ When trim-paths stabilizes: Add to Cargo.toml profile

Bottom line: Small size differences are cosmetic only. Functionality is identical.

API Reference

Functions

createPegInTransaction(params: PegInParams): Promise<PegInResult>

Creates a Bitcoin peg-in transaction for the vault system.

Parameters:

  • params.depositTxid - Transaction ID of the deposit
  • params.depositVout - Output index of the deposit
  • params.depositValue - Value in satoshis
  • params.depositScriptPubKey - Script pubkey (hex)
  • params.depositorPubkey - Depositor's x-only pubkey (hex)
  • params.claimerPubkey - Claimer's x-only pubkey (hex)
  • params.challengerPubkeys - Array of challenger x-only pubkeys (hex)
  • params.pegInAmount - Amount to peg-in in satoshis
  • params.fee - Transaction fee in satoshis
  • params.network - Bitcoin network ("bitcoin", "testnet", "regtest", or "signet")

Returns:

  • txHex - Transaction hex string
  • txid - Transaction ID
  • vaultScriptPubKey - Vault script pubkey (hex)
  • vaultValue - Vault output value in satoshis
  • changeValue - Change output value in satoshis (0 if no change)

createPayoutConnector(params: PayoutConnectorParams, network: Network): Promise<PayoutConnectorInfo>

Creates a payout connector for signing payout transactions.

Parameters:

  • params.depositor - Depositor's x-only pubkey (hex)
  • params.vaultProvider - Vault provider's x-only pubkey (hex)
  • params.vaultKeepers - Array of vault keeper x-only pubkeys (hex)
  • params.universalChallengers - Array of universal challenger x-only pubkeys (hex)
  • params.timelockPegin - CSV timelock in blocks for PegIn output
  • network - Bitcoin network

Returns:

  • payoutScript - Full payout script (hex)
  • taprootScriptHash - Taproot script hash / tapLeafHash for PSBT signing
  • scriptPubKey - Taproot script pubkey (hex)
  • address - P2TR address

getPeginPayoutScript(params: PayoutConnectorParams): Promise<string>

Returns the payout script hex from the PeginPayoutConnector without requiring a network parameter. Useful for building depositor Payout PSBTs where you only need the script (not the address).

Parameters:

  • params.depositor - Depositor's x-only pubkey (hex)
  • params.vaultProvider - Vault provider's x-only pubkey (hex)
  • params.vaultKeepers - Array of vault keeper x-only pubkeys (hex)
  • params.universalChallengers - Array of universal challenger x-only pubkeys (hex)
  • params.timelockPegin - CSV timelock in blocks for PegIn output

Returns:

  • Payout script hex string

getAssertPayoutScriptInfo(params: AssertPayoutNoPayoutConnectorParams): Promise<AssertPayoutScriptInfo>

Generates the Payout script and control block from Assert output 0 for the depositor-as-claimer path.

Parameters:

  • params.claimer - Claimer (depositor) x-only pubkey (hex)
  • params.localChallengers - Array of local challenger x-only pubkeys (hex)
  • params.universalChallengers - Array of universal challenger x-only pubkeys (hex)
  • params.timelockAssert - CSV timelock in blocks for Assert output
  • params.councilMembers - Array of security council member x-only pubkeys (hex)
  • params.councilQuorum - Council quorum (N-of-N)

Returns:

  • payoutScript - Payout script (hex)
  • payoutControlBlock - Control block for the payout script (hex)

getAssertNoPayoutScriptInfo(params: AssertPayoutNoPayoutConnectorParams, challengerPubkey: string): Promise<AssertNoPayoutScriptInfo>

Generates the NoPayout script and control block for a specific challenger. Each challenger has a distinct NoPayout script.

Parameters:

  • params - Same as getAssertPayoutScriptInfo
  • challengerPubkey - The challenger's x-only pubkey (hex)

Returns:

  • noPayoutScript - NoPayout script (hex)
  • noPayoutControlBlock - Control block for the NoPayout script (hex)

getChallengeAssertScriptInfo(params: ChallengeAssertConnectorParams): Promise<ChallengeAssertScriptInfo>

Generates the ChallengeAssert script and control block for a specific challenger. Uses Lamport hashes and GC input label hashes from the vault provider.

Parameters:

  • params.claimer - Claimer (depositor) x-only pubkey (hex)
  • params.challenger - Challenger x-only pubkey (hex)
  • params.lamportHashesJson - JSON string of Lamport hash values from VP
  • params.gcInputLabelHashesJson - JSON string of GC input label hashes from VP

Returns:

  • script - ChallengeAssert script (hex)
  • controlBlock - Control block for the ChallengeAssert script (hex)

Constants

TAP_INTERNAL_KEY: string

The unspendable taproot internal key used in vault transactions (BIP-341 nothing-up-my-sleeve number).

Value: "50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0"

tapInternalPubkey: Buffer

The same as TAP_INTERNAL_KEY but as a Buffer for convenience.

Raw WASM Types

The package also exports raw WASM classes for advanced usage:

  • WasmPeginTx - Low-level peg-in transaction class
  • WasmPeginPayoutConnector - Low-level payout connector class
  • WasmAssertPayoutNoPayoutConnector - Low-level Assert Payout/NoPayout connector class
  • WasmAssertChallengeAssertConnector - Low-level ChallengeAssert connector class