feat: modular Bitcoin backend with adapter pattern#62
feat: modular Bitcoin backend with adapter pattern#62landabaso merged 35 commits intobitcoinerlab:mainfrom
Conversation
Introduce BitcoinLib interface that abstracts all Bitcoin operations (payments, script, crypto, PSBT, transactions) behind a pluggable adapter layer. This enables users to choose between bitcoinjs-lib and alternative backends (e.g. @scure/btc-signer) without changing application code. Key changes: - Add src/bitcoinLib.ts with BitcoinLib, PsbtLike, and Payment interfaces - Add src/adapters/bitcoinjs.ts wrapping bitcoinjs-lib as the default adapter - Refactor DescriptorsFactory to accept either TinySecp256k1Interface (backward compatible) or BitcoinLib (new modular path) - Thread operation dependencies (scriptOps, cryptoOps, taggedHash, etc.) through all leaf modules via parameter injection - Export PsbtLike, BitcoinLib, Network, and other types from index - Update all tests to use PsbtLike interface All 2274 existing tests pass.
Add a full adapter for @scure/btc-signer alongside the existing bitcoinjs-lib adapter, letting users choose their preferred Bitcoin library. Both are declared as optional peer dependencies so only the installed backend gets bundled. - src/adapters/scure.ts: ScurePsbtAdapter wrapping btc.Transaction, payment wrappers (p2pkh, p2wpkh, p2wsh, p2sh, p2tr), script utils, HD key adapter, taproot BIP32 signing, network definitions - src/scure.ts: separate entry point re-exporting createScureLib - package.json: bitcoinjs-lib moved to optional peerDependency, added @scure/btc-signer + @noble/* as optional peers, added ./scure subpath export, integrated test:scure script - src/index.ts: exported createBitcoinjsLib for symmetry - test/scureAdapter.cjs: 201-test standalone suite covering adapter basics, custom fixtures and Bitcoin Core fixtures - README.md: added "Choosing a Bitcoin Backend" section with install and usage instructions for both backends
|
Hey @Kukks , thanks for the PR!! It's quite large and I still do manual close checks for BitcoinerLab. Before I dig into it properly, let me know if you consider the PR finished on your side. I get the idea and agree with the general direction, though I might adjust a few things or even take a slightly different approach. Rather than dragging you through a long review cycle here, I think it's better if I take it from here once you're done. I might add more comments after I look into it further. |
|
I'm going to finish wiring up a test matrix and some accompanying fixes but yeah, feel free to take over then. The way I've done it is to include everything in one package, but allow libs to install which peer dependency they want and treeshaking does the rest as needed |
- Add extractTransaction() to PsbtLike interface + both adapters - Remove direct bitcoinjs-lib imports from tapTree.test.ts and vsize.test.ts - Use cross-env for cross-platform env var in test:unit:scure script - Add jest.config.scure.js and test/getLib.ts for adapter selection - test:matrix runs both backends: bitcoinjs (2274) + scure (2269) tests
It's all yours now |
|
yeah, i'm on it. btw, which repo is importing your fork so i can take a look? |
PR continuation notes
|
|
That said, I'm still not fully happy with the abstraction. The current scure flow still depends on wrapping the native scure transaction. I'd like to push that further so the scure/noble path feels more native/equivalent instead of just "bitcoinjs-shaped through wrappers". So I do not want to merge this yet. I'd rather continue from a follow-up PR and then merge the work from both PRs together. For now, though, this PR makes @scure/btc-signer usable and integrates it properly into the library. |
Summary
BitcoinLibinterface (src/bitcoinLib.ts) that abstracts all Bitcoin operations (payments, script, crypto, PSBT, transaction parsing) behind a pluggable adapter layerbitcoinjs-libadapter (src/adapters/bitcoinjs.ts) as the default backendDescriptorsFactoryaccepts eitherTinySecp256k1Interface(backward compatible) or a fullBitcoinLibadapter (new modular path)miniscript,tapMiniscript,ledger,signers, etc.) receive operations via parameter injection rather than importing frombitcoinjs-libdirectlyPsbtLike,BitcoinLib,Network,Payment, and other adapter types from the package indexThis is a non-breaking change: existing code that passes
ecctoDescriptorsFactory(ecc)continues to work identically (bitcoinjs-lib adapter is loaded lazily). New code can pass a fullBitcoinLibadapter to use an alternative backend.Test plan
DescriptorsFactory(ecc)works identically to beforeDescriptorsFactory(createBitcoinjsLib(ecc))produces same results