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

j-bitcoin

v2.0.1

Published

Comprehensive JavaScript/TypeScript Bitcoin (BTC) wallet library with custodial and non-custodial support, hierarchical deterministic keys, threshold signatures, and advanced cryptographic features

Readme


Why J-Bitcoin?

| | J-Bitcoin | Others | |---|:---:|:---:| | HD Wallets (BIP32/39/44/49/84/86) | ✅ | ✅ | | Threshold Signatures (TSS) | ✅ | ❌ | | Taproot (P2TR) | ✅ | Some | | Schnorr Signatures (BIP340) | ✅ | Some | | BIP322 Message Signing | ✅ | ❌ | | TypeScript Support | ✅ | ✅ | | Zero Native Dependencies* | ✅ | ❌ | | Testnet Verified | ✅ | ? |

*Only uses @noble/curves for cryptographic primitives


⚡ Quick Start

npm install j-bitcoin

Create HD Wallet in 3 Lines

import { CustodialWallet } from 'j-bitcoin';

const { wallet, mnemonic } = CustodialWallet.createNew('main', 128);
const address = wallet.getReceivingAddress(0, 0, 'segwit');

console.log('Backup:', mnemonic);
console.log('Address:', address.address); // bc1q...

Threshold Signatures (2-of-3 TSS)

import { NonCustodialWallet } from 'j-bitcoin';

// No single point of failure - requires 3 parties to sign
const { wallet, shares } = NonCustodialWallet.createNew('main', 3, 1);
const signature = wallet.sign(messageHash); // Distributed signing

🚀 Features

| Category | Features | |----------|----------| | Wallets | Custodial HD wallets, Non-custodial threshold wallets (TSS) | | Standards | BIP32, BIP39, BIP44, BIP49, BIP84, BIP86, BIP173, BIP322, BIP340, BIP350 | | Addresses | Legacy P2PKH (1...), P2SH-P2WPKH (3...), Native SegWit (bc1q...), Taproot (bc1p...) | | Signatures | ECDSA, Schnorr (BIP340), Threshold signatures (TSS), BIP322 message signing | | Networks | Bitcoin Mainnet, Testnet |


📖 Examples

import { CustodialWallet } from 'j-bitcoin';

// Generate new wallet (12-word mnemonic by default, 256 for 24-word)
const { wallet, mnemonic } = CustodialWallet.createNew('main', 128);
console.log('Backup mnemonic:', mnemonic);

// Derive addresses (account, index, type)
const legacy = wallet.getReceivingAddress(0, 0, 'legacy');         // 1...
const wrapped = wallet.getReceivingAddress(0, 0, 'wrapped-segwit'); // 3...
const segwit = wallet.getReceivingAddress(0, 0, 'segwit');         // bc1q...
const taproot = wallet.getReceivingAddress(0, 0, 'taproot');       // bc1p...

console.log('Legacy:', legacy.address);
console.log('SegWit:', segwit.address);
console.log('Taproot:', taproot.address);

// Get change address
const change = wallet.getChangeAddress(0, 0, 'segwit');

// Batch generate addresses
const addresses = wallet.getAddresses(0, 'segwit', 20);

// Restore from mnemonic
const restored = CustodialWallet.fromMnemonic('main', mnemonic);

// Export/import WIF
const wif = wallet.exportWIF(0, 0, 0, 'segwit');
const wifWallet = CustodialWallet.fromWIF(wif);
import { NonCustodialWallet } from 'j-bitcoin';

// Create TSS-only wallet (3 participants, threshold degree t=1)
// Signing requires 2t+1 = 3 participants
const { wallet, shares, config } = NonCustodialWallet.createNew('main', 3, 1);
console.log('TSS config:', config);

// Create HD + TSS wallet (combined mode)
const { wallet: hdWallet, mnemonic, shares: hdShares } = 
  NonCustodialWallet.createNewHD('main', 3, 1);

// Get TSS aggregate public key address
const tssAddress = wallet.getAddress('segwit');

// Get HD-derived addresses (same API as CustodialWallet)
const segwitAddr = hdWallet.getReceivingAddress(0, 0, 'segwit');

// Sign message hash with TSS
const messageHash = Buffer.alloc(32, 'test');
const signature = wallet.sign(messageHash);
const isValid = wallet.verify(messageHash, signature);

// Sign with HD-derived key
const hdSig = hdWallet.signMessageHD('Hello Bitcoin!', 0, 0, 'segwit');
import { BIP39 } from 'j-bitcoin';

// Generate 12-word mnemonic (128-bit)
const { mnemonic } = BIP39.generateMnemonic(128);

// Generate 24-word mnemonic (256-bit)
const { mnemonic: mnemonic24 } = BIP39.generateMnemonic(256);

// Validate mnemonic
const isValid = BIP39.validateChecksum(mnemonic);

// Derive seed (with optional passphrase)
const seed = BIP39.deriveSeed(mnemonic, 'optional-passphrase');
import { Schnorr, ECDSA } from 'j-bitcoin';

const privateKey = Buffer.alloc(32, 'key');
const messageHash = Buffer.alloc(32, 'msg');

// Schnorr (BIP340)
const schnorr = new Schnorr();
const schnorrSig = await schnorr.sign(privateKey, messageHash);
const schnorrPubKey = schnorr.getPublicKey(privateKey);
const isValidSchnorr = await schnorr.verify(schnorrSig.signature, messageHash, schnorrPubKey);

// ECDSA
const ecdsaSig = ECDSA.sign(privateKey, messageHash);
const ecdsaPubKey = ECDSA.getPublicKey(privateKey);
const isValidEcdsa = ECDSA.verify(ecdsaSig, messageHash, ecdsaPubKey);
import { CustodialWallet } from 'j-bitcoin';

const wallet = CustodialWallet.fromMnemonic('main', mnemonic);

// Create transaction builder
const builder = wallet.createTransaction();

// Add inputs and outputs
builder.addInput(txid, vout, sequence);
builder.addOutput(address, amount);
builder.setFeeRate(10); // sat/vB

// Sign with wallet keys
await wallet.signTransaction(builder, [
  { account: 0, change: 0, index: 0, type: 'segwit' }
]);

// Get raw transaction hex
const rawTx = builder.build().toHex();
import { BECH32 } from 'j-bitcoin';

// Encode public key to SegWit address
const address = BECH32.to_P2WPKH(publicKeyHex, 'main');

// Encode to Taproot address  
const taprootAddr = BECH32.to_P2TR(xOnlyPubKeyHex, 'main');

// Decode address
const { program, version, type } = BECH32.decode(address);

📚 API Reference

Wallet Classes

| Class | Description | |-------|-------------| | CustodialWallet | Full HD wallet with BIP32/39/44/49/84/86 support | | NonCustodialWallet | Threshold (TSS) + HD hybrid wallet |

Wallet Methods

| Method | Description | |--------|-------------| | createNew(network, strength) | Create new wallet with mnemonic | | fromMnemonic(network, mnemonic) | Restore from BIP39 phrase | | fromWIF(wif) | Import from WIF private key | | fromExtendedKey(network, xprv/xpub) | Import from extended key | | getReceivingAddress(account, index, type) | Get external address | | getChangeAddress(account, index, type) | Get internal address | | getAddresses(account, type, count) | Batch generate addresses | | signMessage(message, account, index, type) | Sign message | | createTransaction() | Create transaction builder | | signTransaction(builder, inputInfo) | Sign transaction | | exportWIF(account, change, index, type) | Export key as WIF |

Cryptographic Modules

| Module | Description | |--------|-------------| | BIP39 | Mnemonic generation (12-24 words), validation, seed derivation | | ECDSA | Standard Bitcoin signatures with recovery | | Schnorr | BIP340 Schnorr signatures | | BECH32 | Bech32/Bech32m address encoding (BIP173/BIP350) | | BIP322 | Generic message signing for all address types | | b58encode / b58decode | Base58Check encoding |


🧪 Testnet Verified

All address types and signing algorithms have been tested on Bitcoin Testnet4 with real transactions:

| Address Type | Custodial | Non-Custodial (TSS) | |--------------|:---------:|:-------------------:| | Legacy (P2PKH) | ✅ | ✅ | | Wrapped SegWit (P2SH-P2WPKH) | ✅ | ✅ | | Native SegWit (P2WPKH) | ✅ | ✅ | | Taproot (P2TR) | ✅ | ✅ |


📁 Project Structure

src/
├── wallet/                    # Wallet implementations
│   ├── custodial.js          # HD wallet (BIP32/39/44/49/84/86)
│   └── non-custodial.js      # Threshold signature + HD wallet
├── bip/                       # BIP standards
│   ├── BIP173-BIP350.js      # Bech32/Bech32m encoding
│   ├── bip32/                # HD key derivation
│   ├── bip39/                # Mnemonic generation
│   └── bip49.js              # P2SH-P2WPKH support
├── core/
│   ├── constants.js          # Network/crypto constants
│   ├── crypto/
│   │   ├── hash/             # RIPEMD160, HASH160
│   │   └── signatures/       # ECDSA, Schnorr, Threshold
│   └── taproot/              # Taproot support
├── encoding/
│   ├── base58.js             # Base58Check
│   ├── base32.js             # Bech32/Bech32m
│   └── address/              # Address encode/decode
├── transaction/
│   ├── builder.js            # Transaction construction
│   ├── psbt.js               # PSBT support
│   ├── message-signing.js    # BIP322 message signing
│   └── script-builder.js     # Script creation
└── utils/
    ├── validation.js         # Input validation
    └── address-helpers.js    # Address utilities

🔒 Security

⚠️ Important: This library handles private keys and cryptographic material.

  • Never share private keys, mnemonics, or threshold shares
  • Test on testnet before mainnet deployment
  • Store securely - use encrypted offline storage for mnemonics
  • Validate inputs - always validate addresses and signatures
  • Clear sensitive data - call wallet.destroy() when done

🛠️ Development

# Install dependencies
npm install

# Run tests
npm test
npm run test:coverage

# Run wallet compliance tests
node test/custodial-test.js
node test/non-custodial-test.js

# Run comprehensive feature tests (43 tests)
node test/test-all-features.js

# Run testnet testing (requires funding)
node test/testnet-test.js

# Lint and format
npm run lint
npm run format

📦 Dependencies


📄 License

ISC License - see LICENSE


🔗 Links