Scoping bitcoinjs-lib

Why bitcoinjs-lib is in the first Red Team cut: a JavaScript Bitcoin library whose bugs multiply across wallets.

bitcoinjs-lib is the second project in the initial cut. Scope only. No findings.

What it is

bitcoinjs-lib is a JavaScript Bitcoin library for Node.js and browsers. It is written in TypeScript, ships the compiled JavaScript, and is MIT-licensed under the bitcoinjs org. Tagged releases are the stable artifacts; master is development. The README’s first operational warning is not to use master in production.

The library is the transaction, address, script, and PSBT layer. Key management was split out: ecpair for single keys, bip32 for HD derivation, tiny-secp256k1 (or a substitute) for the curve. Complementary packages in the same org cover BIP39, bech32, coin selection, and related encodings. A wallet that “just uses bitcoinjs” is usually a graph of these packages plus an ECC backend.

It is not a node. It does not validate the chain. It builds and signs the objects wallets then broadcast. That is a different blast radius from Bitcoin Core, and a different one from SeedSigner.

Why it is in the first cut

Library defects multiply. A signing-device bug hurts the people who bought that device. A widely imported PSBT or address helper hurts every wallet that did not reimplement the BIP.

JavaScript is a hostile place to do this. The project says so in public: the RNG is only as good as window.crypto or crypto.randomBytes; Buffer bugs can lose funds; Math.random is forbidden; xpubs are a liability; users must see a human-readable transaction before broadcast. That is already a test plan. I am not going to invent a cleverer one.

AI is a reasonable instrument on TypeScript with a large existing suite (the project claims coverage above 95%). The job is not “generate a wallet.” It is “where does the type system, the test suite, or the documented invariant stop, and a caller-shaped input keep going.”

It also sits in the middle of the cut. SeedSigner is a product with a physical air-gap. bitcoinjs-lib is code other products embed, including in browsers where the build pipeline (browserify, bundlers, WASM vs ASM.js ECC) is part of the threat model.

Surfaces I will treat as in-scope

Public source and the published test suite. Not third-party blockchain APIs the integration tests talk to, except as documented fixtures. Not scraping npm users.

PSBT and transaction serialization. Round-trip stability, unknown fields, taproot vs legacy paths, finalization, witness vs scriptSig. A library can produce a transaction that is valid and not the one the caller described.

Addresses and scripts. P2PKH, nested and native segwit, taproot, multisig shapes, bech32/bech32m, network prefixes. Silent network confusion (mainnet encoder, testnet key) is a classic funds bug.

The split-package boundary. bitcoinjs-lib without bip32 / ecpair is a smaller bundle and a larger chance that a caller glues versions together that do not agree on ECC or derivation. Version skew is in scope as a review question, not as supply-chain theater.

ECC backends. tiny-secp256k1 WASM, the ASM.js build, @bitcoinerlab/secp256k1. Taproot paths that require an extra ECC library. I care about whether the documented backend is actually the one doing the signing.

RNG and buffers. I will not re-derive RFC6979. I will look at whether the library’s own warnings are enforceable in code or only in README prose — especially around randombytes, Buffer, and environments the docs already flag (iOS, bad RNGs).

npm versus git. The README warns they do not currently provide tooling to verify that the npm release matches GitHub. That gap is part of the trust story for every app that npm installs this. I will treat it as a process finding if it still holds, not as a license to skip reviewing the source.

psbt      # build, combine, finalize, taproot
addr      # scripts, bech32m, network magic
glue      # bip32, ecpair, ecc library versions
rng       # what actually seeds keys in browser vs node
release   # git tag vs npm tarball

Out of scope for this pass: rewriting altcoin support, and auditing every wallet that depends on the library.

How I will use AI here

Property-style questions against the test suite: encode/decode pairs, network prefixes, PSBT identities. Compare taproot helpers to the BIPs the comments cite. Ask what is untested, then read that code myself.

The project already runs CI. A model that cannot point at a missing case is not helping. A model that invents a “critical overflow” in well-fuzzed encode paths is the default, and it gets discarded.

Disclosure

bitcoinjs-lib asks for public GitHub issues and pull requests in the open unless the content cannot be public. For anything that would actually move funds, I will follow their request to negotiate a private channel from a public issue, not dump details on this site.

Next: Zeus. Previous: SeedSigner.