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

btc-bridge-lib-temp

v0.3.1

Published

Bitcoin Bridge Library for handling multi-signature wallet operations, deposits, and withdrawals

Readme

ZenBridge Bitcoin Lib

License: MIT TypeScript Bitcoin PostgreSQL

A production-ready Bitcoin-to-Ethereum bridge system with enterprise-grade security, multi-signature wallet management, and cross-chain interoperability.

Bitcoin Lab implements a sophisticated bridge protocol using PSBT (Partially Signed Bitcoin Transactions), 3-of-5 multi-signature wallets, and CCIM (Cross-Chain Interoperability Message) for secure Bitcoin-Ethereum transfers.

Overview

Key Components

  • Observer Service: Central coordinator that monitors Bitcoin via Esplora and Zenchain via Subquery, indexes data to PostgreSQL, broadcasts transactions to Bitcoin network
  • Operator Nodes: Independent PSBT signers that connect directly to PostgreSQL, read unsigned PSBTs, write signatures, broadcast to Zenchain network via bridge operator nodes
  • PostgreSQL Database: Central state management where operators read unsigned PSBTs and write signatures, Observer reads/writes transaction state data
  • Multi-Signature Wallets: 3-of-5 threshold signatures using PSBT coordination
  • Subquery Indexer: Indexes Zenchain bridge contract events for withdrawal processing
  • Bridge Contracts: Zenchain smart contracts that emit events for cross-chain transfers
  • No Inter-Service Communication: Services only communicate through the shared PostgreSQL database

Quick Start

Prerequisites

Development Setup

  1. Clone the repository

    git clone https://github.com/your-org/bitcoin-lab.git
    cd bitcoin-lab
  2. Start the development environment

    # Start all services (PostgreSQL, Esplora, Observer, 5 Operators)
    docker-compose -f docker-compose.dev.yaml up -d
       
    # Check service health
    docker-compose -f docker-compose.dev.yaml ps
  3. Set up environment variables

    # Copy environment template
    cp .env.example .env
       
    # Edit with your configuration
    DATABASE_URL=postgresql://postgres:postgres@localhost:5432/postgres
    ESPLORA_URL=http://localhost/regtest/api
    NETWORK=regtest
  4. Verify setup

    # Check observer status
    docker logs btc_observer_dev
       
    # Check operator status
    docker logs btc_operator_1_dev

Build from Source

Prerequisites

  • Node.js 20+
  • npm or yarn package manager
  • PostgreSQL database
  • Docker (for development environment)

Installation

# Clone the repository
git clone https://github.com/zenchain-protocol/zenbridge-btc-lib.git
cd zenbridge-btc-lib

# Install dependencies
npm install

Build Process

# Build TypeScript to JavaScript
npm run build

# Run tests
npm test

# Run CLI
npm run cli

# Development mode (with hot reload)
npm run dev

Build Outputs

  • dist/ - Compiled JavaScript and type definitions
  • dist/cli/run.js - CLI executable
  • dist/index.js - Main library entry point

CLI Reference

The btc-bridge-cli provides comprehensive management capabilities for the Bitcoin bridge system:

Global Options

-V, --version                    # Show version number
-v, --verbose                    # Enable verbose logging (debug level)
-q, --quiet                      # Enable quiet logging (error level only)
--log-level <level>              # Set log level (trace, debug, info, warn, error, fatal)
--database-url <url>             # PostgreSQL connection string (overrides env vars)
-h, --help                       # Show command help

Database Management

# Migration commands
btc-bridge-cli migrate up            # Run pending migrations
btc-bridge-cli migrate down <version> # Rollback to specific migration version
btc-bridge-cli migrate version        # Show current migration version

# Configuration
btc-bridge-cli init [options]         # Initialize operator configurations
btc-bridge-cli populate <configPath>  # Populate database with public config

Migration Options

btc-bridge-cli migrate up              # Apply all pending migrations
btc-bridge-cli migrate down 003       # Rollback to migration version 003
btc-bridge-cli migrate version        # Check current database migration status

Initialization Options

btc-bridge-cli init \
  --network <network>                  # Bitcoin network (mainnet, testnet, regtest)
  --operators <count>                  # Number of operators (default: 5)
  --threshold <threshold>              # Signature threshold (default: 3)
  --refund-lock-time <seconds>         # Refund locktime in seconds (default: 172800)
  --block-confirmations <blocks>       # Confirmation requirement (default: 6)
  --output-dir <dir>                   # Config output directory (default: ./configs)

Service Operations

# Observer Service (monitors both networks)
btc-bridge-cli observe [subcommand]     # Run observer services
btc-bridge-cli observe all              # Run all observer services
btc-bridge-cli observe wallet           # Wallet monitoring only
btc-bridge-cli observe psbt             # PSBT processing only  
btc-bridge-cli observe ccim             # CCIM message processing only

# Operator Service (PSBT signers)
btc-bridge-cli operate <operatorId>     # Run operator service (ID 1-5)

Observer Options

btc-bridge-cli observe all \
  --delay <ms>                         # Cycle delay in milliseconds (default: 5000)
  --esplora <url>                      # Esplora API URL override
  --network <network>                  # Bitcoin network (default: regtest)
  --cycles <number>                    # Limited cycle count (default: infinite)
  --subquery-url <url>                 # SubQuery GraphQL endpoint URL

Operator Options

btc-bridge-cli operate 1 \
  --delay <ms>                         # Cycle delay in milliseconds (default: 3000)
  --network <network>                  # Bitcoin network (default: regtest)
  --mnemonic <phrase>                  # BIP39 seed phrase (or OPERATOR_MNEMONIC env var)
  --cycles <number>                    # Limited cycle count (default: infinite)

Wallet Management

# Create wallets
btc-bridge-cli create deposit <count>    # Create deposit wallets
btc-bridge-cli create hodl <count>       # Create HODL wallets

Withdrawal Processing

# Mock withdrawal for testing
btc-bridge-cli withdraw <ethAddress> <btcAddress> <amountBTC> \
  --esplora <url>                      # Esplora API URL
  --network <network>                  # Bitcoin network  
  --config <path>                      # Public config file path
  --fee <btc>                          # Transaction fee in BTC (default: 0.0001)

Complete Setup Examples

# 1. Database setup and configuration
btc-bridge-cli migrate up
btc-bridge-cli init --network regtest --operators 5 --threshold 3
btc-bridge-cli populate ./configs/public-config.json

# 2. Create wallet infrastructure  
btc-bridge-cli create deposit 10
btc-bridge-cli create hodl 5

# 3. Start observer service (single process)
btc-bridge-cli observe all --verbose --delay 5000 &

# 4. Start multiple operators (separate processes)
btc-bridge-cli operate 1 --verbose &
btc-bridge-cli operate 2 --verbose &  
btc-bridge-cli operate 3 --verbose &

# 5. Test withdrawal
btc-bridge-cli withdraw \
  0x742d35Cc6610C7532C8B77D566D77Bd0e5BfD726 \
  tb1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh \
  0.001

# 6. Check system status with custom database
btc-bridge-cli --database-url postgresql://user:pass@host:5432/btc_bridge \
  migrate version

Development Workflow

# Start with clean database
btc-bridge-cli --database-url $DEV_DATABASE_URL migrate up

# Generate development configuration  
btc-bridge-cli init \
  --network regtest \
  --output-dir ./dev-configs \
  --refund-lock-time 3600

# Set up development environment
btc-bridge-cli populate ./dev-configs/public-config.json
btc-bridge-cli create deposit 20
btc-bridge-cli create hodl 10

# Run services in development mode
btc-bridge-cli observe all --cycles 100 --delay 1000 &
for i in {1..3}; do
  btc-bridge-cli operate $i --cycles 100 --delay 1000 &
done

API References

The Bitcoin Bridge Library exposes several service classes for programmatic integration. Each service follows consistent initialization patterns and provides specific functionality for bridge operations.

BridgeService

Purpose: Main user-facing API for deposit/withdrawal operations and status queries.

Initialization:

import { BridgeService } from 'btc-bridge-lib';
import { Pool } from 'pg';

// Using factory method (recommended)
const pool = new Pool({ connectionString: process.env.DATABASE_URL });
const configManager = new ConfigManager('./configs/public-config.json');
const logger = pino({ level: 'info' });

const bridgeService = await BridgeService.init(pool, configManager, logger);

// Direct constructor
const bridgeService = new BridgeService(
  pool,
  operatorPublicKeyManagers,
  configManager, 
  logger
);

Core Methods:

// Create new deposit address
const deposit = await bridgeService.createDeposit(
  '0x742d35Cc6610C7532C8B77D566D77Bd0e5BfD726',  // Ethereum receiver
  'tb1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh'   // Bitcoin refund address
);

// Query deposit status
const status = await bridgeService.getDepositStatus('deposit-123');

// Query withdrawal status  
const withdrawal = await bridgeService.getWithdrawalStatus('0xabc...');

// Get user transaction history
const deposits = await bridgeService.getDepositHistory(
  '0x742d35Cc6610C7532C8B77D566D77Bd0e5BfD726',
  10,  // limit
  0    // offset
);

// Rate limiting checks
const canProceed = await bridgeService.canProceed(ethereumAddress);
const rateLimit = await bridgeService.checkRateLimit(ethereumAddress);

Constants:

BridgeService.SCHEME  // 'p2sh' - default wallet scheme

ObserverService

Purpose: Central monitoring service that coordinates bridge operations and handles automated workflows.

Initialization:

import { ObserverService } from 'btc-bridge-lib';

const observerService = new ObserverService(
  pool,                          // PostgreSQL connection
  esploraClient,                 // Bitcoin API client
  operatorPublicKeyManagers,     // Array of operator key managers
  zenchainService,               // Zenchain blockchain service
  subqueryService,               // Cross-chain message service
  configManager,                 // Network configuration
  logger,                        // Structured logger
  { batchSize: 10 }             // Optional batch processing config
);

Workflow Methods:

// Wallet lifecycle management
await observerService.handleDepositWalletsToCreate();    // Generate new deposit addresses
await observerService.handleHodlWalletsToGenerate();     // Create HODL storage wallets
await observerService.handleWalletsToCredit();           // Credit wallets with UTXOs
await observerService.handleWalletsToSweep();            // Sweep deposits to HODL

// Transaction processing
await observerService.handlePsbtSessionsToFinalise();    // Finalize signed PSBTs
await observerService.handlePsbtSessionsToBroadcast();   // Broadcast to Bitcoin network
await observerService.handlePsbtSessionsToConfirm();     // Confirm transaction inclusion

// Cross-chain operations
await observerService.handleCCIMMessagesForWithdrawals(); // Process withdrawal requests

Return Type: All methods return Promise<ObserverProcessResult>:

interface ObserverProcessResult {
  success: boolean;
  processed: number;
  errors: string[];
}

OperatorService

Purpose: Individual operator node for PSBT signing in the multi-signature scheme.

Initialization:

import { OperatorService } from 'btc-bridge-lib';

const operatorService = new OperatorService(
  pool,                    // PostgreSQL connection
  operatorKeyManager,      // Single operator's private keys
  logger,                  // Structured logger
  { batchSize: 5 }        // Optional batch processing config
);

Core Methods:

// Main signing workflow
const result = await operatorService.handleSessionsToSign();

// Query operations
const deposits = await operatorService.getConfirmedDeposits(
  sweepId,  // Specific sweep ID
  20,       // limit
  0         // offset
);

// Operator identification
const id = operatorService.operatorId;  // Returns number (1-5)

Return Type: Promise<OperatorProcessResult>:

interface OperatorProcessResult {
  success: boolean;
  signedSessions: number;
  skippedSessions: number;
  errors: string[];
}

ZenchainService

Purpose: Zenchain blockchain integration for cross-chain messaging and contract interactions.

Initialization:

import { ZenchainService, NetworkType } from 'btc-bridge-lib';

// Auto-configuration based on network
const zenchainService = new ZenchainService(
  NetworkType.REGTEST,                    // Network type
  'http://localhost:8545'                 // Optional RPC URL override
);

Blockchain Methods:

// Contract information
const operatorVersion = await zenchainService.getCurrentOperatorVersion();
const networkConfig = zenchainService.getNetworkConfig();
const publicClient = zenchainService.getPublicClient();

// Contract addresses
const zbtcAddress = zenchainService.getZBTCAddress();
const bridgeAddress = zenchainService.getBridgeAddress(); 
const directoryAddress = zenchainService.getBridgeDirectoryAddress();

// Network information
const chainId = zenchainService.getChainId();
const networkType = zenchainService.getNetworkType();
const bitcoinNetwork = zenchainService.getBitcoinNetwork();

// Fee information
const feePerbill = await zenchainService.getBridgeFeePerbill();

// CCIM message creation
const ccimMessage = await zenchainService.getCCIMMessageFromDeposit(
  depositAddress,
  amount,
  ethereumReceiver
);

CAIP Utilities:

// Static helper methods for Cross-Chain Asset Identification Protocol
const chainId = ZenchainService.createBitcoinChainId('mainnet');
const accountId = ZenchainService.createBitcoinAccountId('bc1qxy...', 'mainnet');
const assetId = ZenchainService.createBitcoinAssetId('mainnet');

Constants:

ZenchainService.PERBILL  // BigInt("1000000000") - fee calculation base

SubqueryService

Purpose: GraphQL client for querying indexed blockchain data and CCIM messages.

Initialization:

import { SubqueryService } from 'btc-bridge-lib';

const subqueryService = new SubqueryService(
  'https://api.subquery.network/sq/project/ccim-messages',  // GraphQL endpoint
  logger,                                                   // Structured logger
  30000                                                     // Request timeout (ms)
);

Query Methods:

// Fetch new CCIM transfer messages
const result = await subqueryService.fetchNewCCIMMessages({
  first: 10,                    // Pagination limit
  offset: 0,                    // Pagination offset  
  orderBy: 'BLOCK_HEIGHT_DESC', // Sort order
  filter: {                     // Optional filters
    blockHeight: { greaterThan: 1000000 },
    messageType: { equalTo: 'TRANSFER' }
  }
});

// Get configured endpoint
const url = subqueryService.getQueryUrl();

Return Type: Promise<FetchCCIMMessagesResult>:

interface FetchCCIMMessagesResult {
  messages: CCIMMessage[];
  totalCount: number;
  hasNextPage: boolean;
}

Service Integration Example

Complete Bridge Setup:

import { 
  BridgeService, 
  ObserverService, 
  OperatorService,
  ZenchainService,
  SubqueryService,
  ConfigManager
} from 'btc-bridge-lib';
import { Pool } from 'pg';
import pino from 'pino';

// Database connection
const pool = new Pool({ connectionString: process.env.DATABASE_URL });
const logger = pino({ level: 'info' });

// Configuration
const configManager = new ConfigManager('./configs/public-config.json');

// External services
const zenchainService = new ZenchainService(NetworkType.REGTEST);
const subqueryService = new SubqueryService(process.env.SUBQUERY_URL!, logger);

// Bridge service for user API
const bridgeService = await BridgeService.init(pool, configManager, logger);

// Observer service for automated workflows
const observerService = new ObserverService(
  pool,
  esploraClient,
  operatorPublicKeyManagers,
  zenchainService,
  subqueryService,
  configManager,
  logger.child({ service: 'observer' })
);

// Operator services (one per operator)
const operatorServices = await Promise.all(
  Array.from({ length: 5 }, async (_, i) => {
    const operatorId = i + 1;
    const keyManager = await OperatorKeyManager.load(operatorId, mnemonic);
    return new OperatorService(
      pool,
      keyManager,
      logger.child({ service: 'operator', operatorId })
    );
  })
);

// Service lifecycle
await observerService.handleDepositWalletsToCreate();
await Promise.all(operatorServices.map(service => service.handleSessionsToSign()));

Error Handling Pattern:

try {
  const result = await observerService.handleWalletsToSweep();
  if (!result.success) {
    logger.error({ errors: result.errors }, 'Observer processing failed');
  }
} catch (error) {
  logger.error({ error }, 'Observer service error');
}

Contributing

We welcome contributions to the Bitcoin Bridge Library! Please see CONTRIBUTING.md for detailed development workflow, coding standards, and guidelines for:

  • Setting up the development environment
  • Code style and linting requirements
  • Testing procedures
  • Pull request guidelines
  • Release process

Acknowledgments