BitcoinJS Lib
bitcoinjs-lib is a foundational JavaScript library for interacting with the Bitcoin protocol in both Node.js and browser environments. Written in TypeScript, it provides essential functionalities for creating and manipulating Bitcoin transactions, managing addresses, and working with various script types. The current stable version is 7.0.1. The project follows a release cadence where only tagged releases are considered stable, with the `master` branch serving as the unstable development branch. Key differentiators include its strong emphasis on security through auditability and extensive testing (over 95% test coverage), its modular design (e.g., separating key management into `ecpair` and `bip32` packages to reduce bundle size), and its commitment to open standards and a helpful community. It does not handle key derivation itself, offloading this to specialized, smaller libraries.
Common errors
-
Cannot read properties of undefined (reading 'ECPairFactory')
cause Attempting to use `ECPairFactory` (or `BIP32Factory`) without correct import and initialization, typically because the `ecpair` or `bip32` packages are not installed or an ECC library is not provided.fixEnsure `ecpair` (and/or `bip32`) is installed. Import `ECPairFactory` from `ecpair` (e.g., `import * as ECPairFactory from 'ecpair';`) and initialize it with an ECC library (e.g., `const ECPair = ECPairFactory.ECPairFactory(ecc);`). -
TypeError: Psbt.data.globalMap.unsignedTx.getHash is not a function
cause Accessing methods of the `Transaction` object directly from `Psbt.data.globalMap.unsignedTx` in `bitcoinjs-lib` v7. The type has changed to `TransactionFromBuffer` for performance.fixUse the methods provided by `TransactionFromBuffer` (e.g., `getId()` or `getHash()`) directly on `psbt.data.globalMap.unsignedTx`. -
Error: No inputs to sign.
cause The PSBT was created without proper input information, specifically `witnessUtxo` or `nonWitnessUtxo` being missing for the respective script type (e.g., P2WPKH needs `witnessUtxo`, P2PKH needs `nonWitnessUtxo`).fixEnsure that each input added to the PSBT has the necessary UTXO information (`witnessUtxo` or `nonWitnessUtxo`) corresponding to the script type you are attempting to sign. -
Error: Key pair for input #X not provided.
cause The `keyPair` provided to `psbt.signInput(X, keyPair)` does not match the public key associated with the UTXO in input X, or the input data is insufficient for signing.fixVerify that the `keyPair` used for signing corresponds to the private key of the address funding the specific input (index X) you are trying to sign. Also ensure the input details in the PSBT are accurate and complete.
Warnings
- breaking The `ECPair` and `bip32` key management classes were externalized into separate packages (`ecpair` and `bip32`) starting from `bitcoinjs-lib` v6. These must now be installed and imported independently and initialized with an ECC curve library (e.g., `@noble/secp256k1` or `tiny-secp256k1`).
- gotcha The `master` branch is unstable and serves as the development branch. It is explicitly not recommended for production use. Only officially tagged releases are considered stable and suitable for applications.
- breaking In `bitcoinjs-lib` v7, the `Psbt.data.globalMap.unsignedTx` property's type changed from a `Transaction` object to a `TransactionFromBuffer` object. This impacts direct access to transaction details from this field, which is now optimized for `txid/wtxid` calculation without full transaction parsing.
- breaking In `bitcoinjs-lib` v7, `Psbt.signInput` now returns `this` (the Psbt instance) instead of `void`. While this allows for method chaining, it's a change in return type that might affect existing code if the return value was explicitly assumed to be `void`.
- gotcha Given the critical nature of Bitcoin libraries, thorough auditing of `bitcoinjs-lib` and all its dependencies is strongly recommended before production deployment. The project advocates a 'Don't trust. Verify.' philosophy.
Install
-
npm install bitcoinjs-lib -
yarn add bitcoinjs-lib -
pnpm add bitcoinjs-lib
Imports
- bitcoin
const bitcoin = require('bitcoinjs-lib');import * as bitcoin from 'bitcoinjs-lib';
- Transaction, networks, Psbt
import bitcoinjsLib from 'bitcoinjs-lib';
import { Transaction, networks, Psbt } from 'bitcoinjs-lib'; - ECPair, BIP32
import { ECPair } from 'bitcoinjs-lib';import * as ecc from '@noble/secp256k1'; import * as ECPairFactory from 'ecpair'; const ECPair = ECPairFactory.ECPairFactory(ecc); // Similarly for bip32: import * as bip32Factory from 'bip32'; const bip32 = bip32Factory.BIP32Factory(ecc);
Quickstart
import * as ecc from '@noble/secp256k1'; // Or 'tiny-secp256k1'
import * as ECPairFactory from 'ecpair';
import { Psbt, payments, networks } from 'bitcoinjs-lib';
// 1. Initialize ECPair with an ECC library (required since v6)
const ECPair = ECPairFactory.ECPairFactory(ecc);
// 2. Generate a key pair for a new P2WPKH (SegWit) address
const keyPair = ECPair.makeRandom({ network: networks.testnet });
const { address } = payments.p2wpkh({ pubkey: keyPair.publicKey, network: networks.testnet });
console.log('New SegWit Testnet Address:', address);
console.log('WIF (WARNING: DO NOT SHARE OR USE IN PRODUCTION):', keyPair.toWIF());
// 3. Create a Partially Signed Bitcoin Transaction (PSBT)
// This is a simplified example; real PSBTs require fetching actual UTXO details.
const psbt = new Psbt({ network: networks.testnet })
.addInput({
hash: '8f72289c02d75a8a113333333333333333333333333333333333333333333333', // Dummy TX ID
index: 0,
// For P2WPKH, witnessUtxo is required
witnessUtxo: { script: payments.p2wpkh({ pubkey: keyPair.publicKey }).output!, value: 20000 },
})
.addOutput({
address: 'tb1qgs400u6kqvq977gskv0d5x0r0sfgz7454w077e', // Another dummy testnet address
value: 10000,
});
// 4. Sign the input
psbt.signInput(0, keyPair);
// 5. Finalize the input (adds witness data)
psbt.finalizeAllInputs();
// 6. Extract the signed transaction (hex format) and log it
const transaction = psbt.extractTransaction().toHex();
console.log('Signed Transaction (Hex):', transaction);