@btc-vision/bitcoin 6.5.6 → 7.0.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/HOW_TO_WRITE_GOOD_CODE.md +2436 -0
- package/benchmark/psbt-2000-inputs.bench.ts +178 -0
- package/benchmark/signing.bench.ts +147 -0
- package/browser/address.d.ts +57 -10
- package/browser/address.d.ts.map +1 -0
- package/browser/bech32utils.d.ts +9 -1
- package/browser/bech32utils.d.ts.map +1 -0
- package/browser/bip66.d.ts +11 -6
- package/browser/bip66.d.ts.map +1 -0
- package/browser/block.d.ts +117 -11
- package/browser/block.d.ts.map +1 -0
- package/browser/branded.d.ts +20 -0
- package/browser/branded.d.ts.map +1 -0
- package/browser/crypto/crypto.d.ts +1 -0
- package/browser/crypto/crypto.d.ts.map +1 -0
- package/browser/crypto.d.ts +46 -7
- package/browser/crypto.d.ts.map +1 -0
- package/browser/ecc/context.d.ts +129 -0
- package/browser/ecc/context.d.ts.map +1 -0
- package/browser/ecc/index.d.ts +11 -0
- package/browser/ecc/index.d.ts.map +1 -0
- package/browser/ecc/types.d.ts +128 -0
- package/browser/ecc/types.d.ts.map +1 -0
- package/browser/ecpair.d.ts +99 -0
- package/browser/errors.d.ts +124 -0
- package/browser/errors.d.ts.map +1 -0
- package/browser/index.d.ts +32 -5
- package/browser/index.d.ts.map +1 -0
- package/browser/index.js +12477 -101
- package/browser/io/BinaryReader.d.ts +276 -0
- package/browser/io/BinaryReader.d.ts.map +1 -0
- package/browser/io/BinaryWriter.d.ts +391 -0
- package/browser/io/BinaryWriter.d.ts.map +1 -0
- package/browser/io/MemoryPool.d.ts +220 -0
- package/browser/io/MemoryPool.d.ts.map +1 -0
- package/browser/io/base64.d.ts +13 -0
- package/browser/io/base64.d.ts.map +1 -0
- package/browser/io/hex.d.ts +67 -0
- package/browser/io/hex.d.ts.map +1 -0
- package/browser/io/index.d.ts +17 -0
- package/browser/io/index.d.ts.map +1 -0
- package/browser/io/utils.d.ts +199 -0
- package/browser/io/utils.d.ts.map +1 -0
- package/browser/merkle.d.ts +10 -1
- package/browser/merkle.d.ts.map +1 -0
- package/browser/networks.d.ts +70 -9
- package/browser/networks.d.ts.map +1 -0
- package/browser/opcodes.d.ts +1 -0
- package/browser/opcodes.d.ts.map +1 -0
- package/browser/payments/bip341.d.ts +35 -9
- package/browser/payments/bip341.d.ts.map +1 -0
- package/browser/payments/embed.d.ts +112 -1
- package/browser/payments/embed.d.ts.map +1 -0
- package/browser/payments/index.d.ts +17 -10
- package/browser/payments/index.d.ts.map +1 -0
- package/browser/payments/p2ms.d.ts +150 -0
- package/browser/payments/p2ms.d.ts.map +1 -0
- package/browser/payments/p2op.d.ts +150 -24
- package/browser/payments/p2op.d.ts.map +1 -0
- package/browser/payments/p2pk.d.ts +154 -1
- package/browser/payments/p2pk.d.ts.map +1 -0
- package/browser/payments/p2pkh.d.ts +176 -1
- package/browser/payments/p2pkh.d.ts.map +1 -0
- package/browser/payments/p2sh.d.ts +150 -1
- package/browser/payments/p2sh.d.ts.map +1 -0
- package/browser/payments/p2tr.d.ts +185 -1
- package/browser/payments/p2tr.d.ts.map +1 -0
- package/browser/payments/p2wpkh.d.ts +161 -1
- package/browser/payments/p2wpkh.d.ts.map +1 -0
- package/browser/payments/p2wsh.d.ts +146 -1
- package/browser/payments/p2wsh.d.ts.map +1 -0
- package/browser/payments/types.d.ts +94 -64
- package/browser/payments/types.d.ts.map +1 -0
- package/browser/psbt/bip371.d.ts +34 -8
- package/browser/psbt/bip371.d.ts.map +1 -0
- package/browser/psbt/psbtutils.d.ts +56 -16
- package/browser/psbt/psbtutils.d.ts.map +1 -0
- package/browser/psbt/types.d.ts +245 -0
- package/browser/psbt/types.d.ts.map +1 -0
- package/browser/psbt/utils.d.ts +64 -0
- package/browser/psbt/utils.d.ts.map +1 -0
- package/browser/psbt/validation.d.ts +84 -0
- package/browser/psbt/validation.d.ts.map +1 -0
- package/browser/psbt.d.ts +82 -118
- package/browser/psbt.d.ts.map +1 -0
- package/browser/pubkey.d.ts +27 -6
- package/browser/pubkey.d.ts.map +1 -0
- package/browser/push_data.d.ts +24 -2
- package/browser/push_data.d.ts.map +1 -0
- package/browser/script.d.ts +33 -8
- package/browser/script.d.ts.map +1 -0
- package/browser/script_number.d.ts +17 -0
- package/browser/script_number.d.ts.map +1 -0
- package/browser/script_signature.d.ts +23 -5
- package/browser/script_signature.d.ts.map +1 -0
- package/browser/transaction.d.ts +160 -18
- package/browser/transaction.d.ts.map +1 -0
- package/browser/types.d.ts +36 -38
- package/browser/types.d.ts.map +1 -0
- package/browser/workers/WorkerSigningPool.d.ts +143 -0
- package/browser/workers/WorkerSigningPool.d.ts.map +1 -0
- package/browser/workers/WorkerSigningPool.node.d.ts +116 -0
- package/browser/workers/WorkerSigningPool.node.d.ts.map +1 -0
- package/browser/workers/ecc-bundle.d.ts +25 -0
- package/browser/workers/ecc-bundle.d.ts.map +1 -0
- package/browser/workers/index.d.ts +91 -0
- package/browser/workers/index.d.ts.map +1 -0
- package/browser/workers/psbt-parallel.d.ts +88 -0
- package/browser/workers/psbt-parallel.d.ts.map +1 -0
- package/browser/workers/signing-worker.d.ts +37 -0
- package/browser/workers/signing-worker.d.ts.map +1 -0
- package/browser/workers/types.d.ts +365 -0
- package/browser/workers/types.d.ts.map +1 -0
- package/build/address.d.ts +58 -11
- package/build/address.d.ts.map +1 -0
- package/build/address.js +82 -25
- package/build/address.js.map +1 -0
- package/build/bech32utils.d.ts +9 -1
- package/build/bech32utils.d.ts.map +1 -0
- package/build/bech32utils.js +10 -2
- package/build/bech32utils.js.map +1 -0
- package/build/bip66.d.ts +11 -6
- package/build/bip66.d.ts.map +1 -0
- package/build/bip66.js +32 -3
- package/build/bip66.js.map +1 -0
- package/build/block.d.ts +117 -11
- package/build/block.d.ts.map +1 -0
- package/build/block.js +202 -72
- package/build/block.js.map +1 -0
- package/build/branded.d.ts +20 -0
- package/build/branded.d.ts.map +1 -0
- package/build/branded.js +7 -0
- package/build/branded.js.map +1 -0
- package/build/crypto/crypto.d.ts +1 -0
- package/build/crypto/crypto.d.ts.map +1 -0
- package/build/crypto/crypto.js +1 -0
- package/build/crypto/crypto.js.map +1 -0
- package/build/crypto.d.ts +46 -7
- package/build/crypto.d.ts.map +1 -0
- package/build/crypto.js +65 -20
- package/build/crypto.js.map +1 -0
- package/build/ecc/context.d.ts +135 -0
- package/build/ecc/context.d.ts.map +1 -0
- package/build/ecc/context.js +232 -0
- package/build/ecc/context.js.map +1 -0
- package/build/ecc/index.d.ts +11 -0
- package/build/ecc/index.d.ts.map +1 -0
- package/build/ecc/index.js +11 -0
- package/build/ecc/index.js.map +1 -0
- package/build/ecc/types.d.ts +134 -0
- package/build/ecc/types.d.ts.map +1 -0
- package/build/ecc/types.js +8 -0
- package/build/ecc/types.js.map +1 -0
- package/build/errors.d.ts +124 -0
- package/build/errors.d.ts.map +1 -0
- package/build/errors.js +155 -0
- package/build/errors.js.map +1 -0
- package/build/index.d.ts +32 -5
- package/build/index.d.ts.map +1 -0
- package/build/index.js +26 -3
- package/build/index.js.map +1 -0
- package/build/io/BinaryReader.d.ts +276 -0
- package/build/io/BinaryReader.d.ts.map +1 -0
- package/build/io/BinaryReader.js +425 -0
- package/build/io/BinaryReader.js.map +1 -0
- package/build/io/BinaryWriter.d.ts +391 -0
- package/build/io/BinaryWriter.d.ts.map +1 -0
- package/build/io/BinaryWriter.js +611 -0
- package/build/io/BinaryWriter.js.map +1 -0
- package/build/io/MemoryPool.d.ts +220 -0
- package/build/io/MemoryPool.d.ts.map +1 -0
- package/build/io/MemoryPool.js +309 -0
- package/build/io/MemoryPool.js.map +1 -0
- package/build/io/base64.d.ts +13 -0
- package/build/io/base64.d.ts.map +1 -0
- package/build/io/base64.js +20 -0
- package/build/io/base64.js.map +1 -0
- package/build/io/hex.d.ts +67 -0
- package/build/io/hex.d.ts.map +1 -0
- package/build/io/hex.js +138 -0
- package/build/io/hex.js.map +1 -0
- package/build/io/index.d.ts +17 -0
- package/build/io/index.d.ts.map +1 -0
- package/build/io/index.js +23 -0
- package/build/io/index.js.map +1 -0
- package/build/io/utils.d.ts +199 -0
- package/build/io/utils.d.ts.map +1 -0
- package/build/io/utils.js +271 -0
- package/build/io/utils.js.map +1 -0
- package/build/merkle.d.ts +10 -1
- package/build/merkle.d.ts.map +1 -0
- package/build/merkle.js +12 -1
- package/build/merkle.js.map +1 -0
- package/build/networks.d.ts +70 -9
- package/build/networks.d.ts.map +1 -0
- package/build/networks.js +90 -4
- package/build/networks.js.map +1 -0
- package/build/opcodes.d.ts +1 -0
- package/build/opcodes.d.ts.map +1 -0
- package/build/opcodes.js +1 -0
- package/build/opcodes.js.map +1 -0
- package/build/payments/bip341.d.ts +35 -9
- package/build/payments/bip341.d.ts.map +1 -0
- package/build/payments/bip341.js +34 -15
- package/build/payments/bip341.js.map +1 -0
- package/build/payments/embed.d.ts +120 -1
- package/build/payments/embed.d.ts.map +1 -0
- package/build/payments/embed.js +215 -34
- package/build/payments/embed.js.map +1 -0
- package/build/payments/index.d.ts +17 -10
- package/build/payments/index.d.ts.map +1 -0
- package/build/payments/index.js +20 -10
- package/build/payments/index.js.map +1 -0
- package/build/payments/p2ms.d.ts +159 -1
- package/build/payments/p2ms.d.ts.map +1 -0
- package/build/payments/p2ms.js +427 -108
- package/build/payments/p2ms.js.map +1 -0
- package/build/payments/p2op.d.ts +158 -24
- package/build/payments/p2op.d.ts.map +1 -0
- package/build/payments/p2op.js +379 -93
- package/build/payments/p2op.js.map +1 -0
- package/build/payments/p2pk.d.ts +162 -1
- package/build/payments/p2pk.d.ts.map +1 -0
- package/build/payments/p2pk.js +327 -58
- package/build/payments/p2pk.js.map +1 -0
- package/build/payments/p2pkh.d.ts +185 -1
- package/build/payments/p2pkh.d.ts.map +1 -0
- package/build/payments/p2pkh.js +467 -114
- package/build/payments/p2pkh.js.map +1 -0
- package/build/payments/p2sh.d.ts +159 -1
- package/build/payments/p2sh.d.ts.map +1 -0
- package/build/payments/p2sh.js +500 -150
- package/build/payments/p2sh.js.map +1 -0
- package/build/payments/p2tr.d.ts +193 -1
- package/build/payments/p2tr.d.ts.map +1 -0
- package/build/payments/p2tr.js +592 -174
- package/build/payments/p2tr.js.map +1 -0
- package/build/payments/p2wpkh.d.ts +170 -1
- package/build/payments/p2wpkh.d.ts.map +1 -0
- package/build/payments/p2wpkh.js +428 -103
- package/build/payments/p2wpkh.js.map +1 -0
- package/build/payments/p2wsh.d.ts +155 -1
- package/build/payments/p2wsh.d.ts.map +1 -0
- package/build/payments/p2wsh.js +465 -143
- package/build/payments/p2wsh.js.map +1 -0
- package/build/payments/types.d.ts +98 -64
- package/build/payments/types.d.ts.map +1 -0
- package/build/payments/types.js +17 -13
- package/build/payments/types.js.map +1 -0
- package/build/psbt/bip371.d.ts +35 -9
- package/build/psbt/bip371.d.ts.map +1 -0
- package/build/psbt/bip371.js +117 -28
- package/build/psbt/bip371.js.map +1 -0
- package/build/psbt/psbtutils.d.ts +56 -16
- package/build/psbt/psbtutils.d.ts.map +1 -0
- package/build/psbt/psbtutils.js +71 -16
- package/build/psbt/psbtutils.js.map +1 -0
- package/build/psbt/types.d.ts +249 -0
- package/build/psbt/types.d.ts.map +1 -0
- package/build/psbt/types.js +6 -0
- package/build/psbt/types.js.map +1 -0
- package/build/psbt/utils.d.ts +68 -0
- package/build/psbt/utils.d.ts.map +1 -0
- package/build/psbt/utils.js +171 -0
- package/build/psbt/utils.js.map +1 -0
- package/build/psbt/validation.d.ts +88 -0
- package/build/psbt/validation.d.ts.map +1 -0
- package/build/psbt/validation.js +149 -0
- package/build/psbt/validation.js.map +1 -0
- package/build/psbt.d.ts +84 -120
- package/build/psbt.d.ts.map +1 -0
- package/build/psbt.js +406 -413
- package/build/psbt.js.map +1 -0
- package/build/pubkey.d.ts +27 -6
- package/build/pubkey.d.ts.map +1 -0
- package/build/pubkey.js +36 -12
- package/build/pubkey.js.map +1 -0
- package/build/push_data.d.ts +24 -2
- package/build/push_data.d.ts.map +1 -0
- package/build/push_data.js +44 -12
- package/build/push_data.js.map +1 -0
- package/build/script.d.ts +33 -8
- package/build/script.d.ts.map +1 -0
- package/build/script.js +101 -37
- package/build/script.js.map +1 -0
- package/build/script_number.d.ts +17 -0
- package/build/script_number.d.ts.map +1 -0
- package/build/script_number.js +19 -0
- package/build/script_number.js.map +1 -0
- package/build/script_signature.d.ts +23 -5
- package/build/script_signature.d.ts.map +1 -0
- package/build/script_signature.js +48 -15
- package/build/script_signature.js.map +1 -0
- package/build/transaction.d.ts +160 -18
- package/build/transaction.d.ts.map +1 -0
- package/build/transaction.js +443 -176
- package/build/transaction.js.map +1 -0
- package/build/tsconfig.build.tsbuildinfo +1 -0
- package/build/types.d.ts +36 -38
- package/build/types.d.ts.map +1 -0
- package/build/types.js +169 -57
- package/build/types.js.map +1 -0
- package/build/workers/WorkerSigningPool.d.ts +174 -0
- package/build/workers/WorkerSigningPool.d.ts.map +1 -0
- package/build/workers/WorkerSigningPool.js +553 -0
- package/build/workers/WorkerSigningPool.js.map +1 -0
- package/build/workers/WorkerSigningPool.node.d.ts +124 -0
- package/build/workers/WorkerSigningPool.node.d.ts.map +1 -0
- package/build/workers/WorkerSigningPool.node.js +753 -0
- package/build/workers/WorkerSigningPool.node.js.map +1 -0
- package/build/workers/ecc-bundle.d.ts +25 -0
- package/build/workers/ecc-bundle.d.ts.map +1 -0
- package/build/workers/ecc-bundle.js +25 -0
- package/build/workers/ecc-bundle.js.map +1 -0
- package/build/workers/index.d.ts +91 -0
- package/build/workers/index.d.ts.map +1 -0
- package/build/workers/index.js +114 -0
- package/build/workers/index.js.map +1 -0
- package/build/workers/psbt-parallel.d.ts +117 -0
- package/build/workers/psbt-parallel.d.ts.map +1 -0
- package/build/workers/psbt-parallel.js +233 -0
- package/build/workers/psbt-parallel.js.map +1 -0
- package/build/workers/signing-worker.d.ts +37 -0
- package/build/workers/signing-worker.d.ts.map +1 -0
- package/build/workers/signing-worker.js +350 -0
- package/build/workers/signing-worker.js.map +1 -0
- package/build/workers/types.d.ts +365 -0
- package/build/workers/types.d.ts.map +1 -0
- package/build/workers/types.js +60 -0
- package/build/workers/types.js.map +1 -0
- package/package.json +68 -9
- package/scripts/bundle-ecc.ts +111 -0
- package/src/address.ts +91 -45
- package/src/bech32utils.ts +3 -3
- package/src/bip66.ts +34 -24
- package/src/block.ts +205 -86
- package/src/branded.ts +18 -0
- package/src/crypto.ts +64 -26
- package/src/ecc/context.ts +280 -0
- package/src/ecc/index.ts +14 -0
- package/src/ecc/types.ts +147 -0
- package/src/ecpair.d.ts +99 -0
- package/src/errors.ts +163 -0
- package/src/index.ts +112 -9
- package/src/io/BinaryReader.ts +461 -0
- package/src/io/BinaryWriter.ts +696 -0
- package/src/io/MemoryPool.ts +343 -0
- package/src/io/base64.ts +20 -0
- package/src/io/hex.ts +155 -0
- package/src/io/index.ts +41 -0
- package/src/io/utils.ts +283 -0
- package/src/merkle.ts +14 -9
- package/src/networks.ts +9 -9
- package/src/payments/bip341.ts +32 -33
- package/src/payments/embed.ts +244 -41
- package/src/payments/index.ts +12 -10
- package/src/payments/p2ms.ts +497 -118
- package/src/payments/p2op.ts +432 -134
- package/src/payments/p2pk.ts +370 -72
- package/src/payments/p2pkh.ts +524 -130
- package/src/payments/p2sh.ts +572 -169
- package/src/payments/p2tr.ts +686 -194
- package/src/payments/p2wpkh.ts +482 -105
- package/src/payments/p2wsh.ts +524 -162
- package/src/payments/types.ts +80 -66
- package/src/psbt/bip371.ts +72 -51
- package/src/psbt/psbtutils.ts +39 -40
- package/src/psbt/types.ts +324 -0
- package/src/psbt/utils.ts +188 -0
- package/src/psbt/validation.ts +185 -0
- package/src/psbt.ts +608 -827
- package/src/pubkey.ts +22 -23
- package/src/push_data.ts +18 -16
- package/src/script.ts +81 -66
- package/src/script_number.ts +6 -6
- package/src/script_signature.ts +33 -36
- package/src/transaction.ts +462 -239
- package/src/types.ts +229 -100
- package/src/workers/WorkerSigningPool.node.ts +887 -0
- package/src/workers/WorkerSigningPool.ts +666 -0
- package/src/workers/ecc-bundle.ts +26 -0
- package/src/workers/index.ts +165 -0
- package/src/workers/psbt-parallel.ts +327 -0
- package/src/workers/signing-worker.ts +353 -0
- package/src/workers/types.ts +417 -0
- package/test/address.spec.ts +9 -6
- package/test/bitcoin.core.spec.ts +16 -17
- package/test/block.spec.ts +8 -7
- package/test/bufferutils.spec.ts +228 -214
- package/test/crypto.spec.ts +19 -11
- package/test/fixtures/p2pk.json +0 -8
- package/test/fixtures/p2pkh.json +1 -1
- package/test/fixtures/p2sh.json +1 -1
- package/test/fixtures/script.json +1 -1
- package/test/fixtures/transaction.json +2 -2
- package/test/integration/_regtest.ts +25 -0
- package/test/integration/addresses.spec.ts +4 -3
- package/test/integration/bip32.spec.ts +2 -1
- package/test/integration/blocks.spec.ts +1 -1
- package/test/integration/cltv.spec.ts +18 -16
- package/test/integration/csv.spec.ts +37 -64
- package/test/integration/payments.spec.ts +5 -3
- package/test/integration/taproot.spec.ts +76 -83
- package/test/integration/transactions.spec.ts +38 -35
- package/test/payments.spec.ts +35 -13
- package/test/payments.utils.ts +17 -16
- package/test/psbt.spec.ts +111 -100
- package/test/script.spec.ts +11 -10
- package/test/script_signature.spec.ts +9 -11
- package/test/taproot-cache.spec.ts +694 -0
- package/test/transaction.spec.ts +32 -40
- package/test/types.spec.ts +74 -29
- package/test/workers-pool.spec.ts +963 -0
- package/test/workers-signing.spec.ts +635 -0
- package/test/workers.spec.ts +1390 -0
- package/tsconfig.base.json +34 -18
- package/tsconfig.browser.json +15 -0
- package/tsconfig.build.json +5 -0
- package/tsconfig.json +5 -14
- package/typedoc.json +29 -0
- package/vite.config.browser.ts +3 -42
- package/vitest.config.integration.ts +2 -0
- package/browser/bufferutils.d.ts +0 -34
- package/browser/chunks/crypto-BhCpKpek.js +0 -2033
- package/browser/chunks/payments-B1wlSccx.js +0 -1089
- package/browser/chunks/psbt-BCNk7JUx.js +0 -4055
- package/browser/chunks/script-DyPItFEl.js +0 -318
- package/browser/chunks/transaction-C_UbhMGn.js +0 -432
- package/browser/chunks/utils-DNZi-T5W.js +0 -761
- package/browser/ecc_lib.d.ts +0 -3
- package/browser/hooks/AdvancedSignatureManager.d.ts +0 -16
- package/browser/hooks/HookedSigner.d.ts +0 -4
- package/browser/hooks/SignatureManager.d.ts +0 -13
- package/browser/payments/lazy.d.ts +0 -2
- package/browser/typeforce.d.ts +0 -38
- package/build/bufferutils.d.ts +0 -34
- package/build/bufferutils.js +0 -141
- package/build/ecc_lib.d.ts +0 -3
- package/build/ecc_lib.js +0 -61
- package/build/hooks/AdvancedSignatureManager.d.ts +0 -16
- package/build/hooks/AdvancedSignatureManager.js +0 -52
- package/build/hooks/HookedSigner.d.ts +0 -4
- package/build/hooks/HookedSigner.js +0 -64
- package/build/hooks/SignatureManager.d.ts +0 -13
- package/build/hooks/SignatureManager.js +0 -45
- package/build/payments/lazy.d.ts +0 -2
- package/build/payments/lazy.js +0 -28
- package/build/tsconfig.tsbuildinfo +0 -1
- package/src/bufferutils.ts +0 -188
- package/src/ecc_lib.ts +0 -94
- package/src/hooks/AdvancedSignatureManager.ts +0 -104
- package/src/hooks/HookedSigner.ts +0 -108
- package/src/hooks/SignatureManager.ts +0 -84
- package/src/payments/lazy.ts +0 -28
- package/src/typeforce.d.ts +0 -38
- package/tsconfig.webpack.json +0 -18
package/src/payments/p2ms.ts
CHANGED
|
@@ -1,156 +1,535 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Pay-to-Multisig (P2MS) payment class.
|
|
3
|
+
*
|
|
4
|
+
* P2MS is a bare multisig script where M-of-N signatures are required
|
|
5
|
+
* to spend the output. The public keys are embedded directly in the script.
|
|
6
|
+
*
|
|
7
|
+
* @packageDocumentation
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { bitcoin as BITCOIN_NETWORK, type Network } from '../networks.js';
|
|
2
11
|
import * as bscript from '../script.js';
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
12
|
+
import {
|
|
13
|
+
isPoint,
|
|
14
|
+
type PublicKey,
|
|
15
|
+
type Script,
|
|
16
|
+
type Signature,
|
|
17
|
+
type Stack,
|
|
18
|
+
stacksEqual,
|
|
19
|
+
} from '../types.js';
|
|
20
|
+
import { type P2MSPayment, type PaymentOpts, PaymentType } from './types.js';
|
|
6
21
|
|
|
7
22
|
const OPS = bscript.opcodes;
|
|
8
|
-
|
|
9
23
|
const OP_INT_BASE = OPS.OP_RESERVED; // OP_1 - 1
|
|
10
24
|
|
|
11
|
-
// input: OP_0 [signatures ...]
|
|
12
|
-
// output: m [pubKeys ...] n OP_CHECKMULTISIG
|
|
13
25
|
/**
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
26
|
+
* Pay-to-Multisig (P2MS) payment class.
|
|
27
|
+
*
|
|
28
|
+
* Creates locking scripts of the form:
|
|
29
|
+
* `m {pubKey1} {pubKey2} ... {pubKeyN} n OP_CHECKMULTISIG`
|
|
30
|
+
*
|
|
31
|
+
* Spending requires: `OP_0 {sig1} {sig2} ... {sigM}`
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```typescript
|
|
35
|
+
* import { P2MS } from '@btc-vision/bitcoin';
|
|
36
|
+
*
|
|
37
|
+
* // Create a 2-of-3 multisig
|
|
38
|
+
* const payment = P2MS.fromPubkeys(2, [pubkey1, pubkey2, pubkey3]);
|
|
39
|
+
* console.log(payment.output); // scriptPubKey
|
|
40
|
+
* console.log(payment.m); // 2
|
|
41
|
+
* console.log(payment.n); // 3
|
|
42
|
+
*
|
|
43
|
+
* // Decode an existing output
|
|
44
|
+
* const decoded = P2MS.fromOutput(scriptPubKey);
|
|
45
|
+
* console.log(decoded.pubkeys); // array of public keys
|
|
46
|
+
* ```
|
|
19
47
|
*/
|
|
20
|
-
export
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
opts = Object.assign({ validate: true }, opts || {});
|
|
48
|
+
export class P2MS {
|
|
49
|
+
// Static public fields
|
|
50
|
+
static readonly NAME = PaymentType.P2MS;
|
|
24
51
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
(opts!.allowIncomplete && (x as number) === OPS.OP_0) !== undefined
|
|
29
|
-
);
|
|
30
|
-
}
|
|
52
|
+
// Private instance fields
|
|
53
|
+
readonly #network: Network;
|
|
54
|
+
readonly #opts: Required<PaymentOpts>;
|
|
31
55
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
56
|
+
// Input data (provided by user)
|
|
57
|
+
#inputM?: number | undefined;
|
|
58
|
+
#inputN?: number | undefined;
|
|
59
|
+
#inputPubkeys?: Uint8Array[] | undefined;
|
|
60
|
+
#inputSignatures?: Uint8Array[] | undefined;
|
|
61
|
+
#inputOutput?: Uint8Array | undefined;
|
|
62
|
+
#inputInput?: Uint8Array | undefined;
|
|
63
|
+
|
|
64
|
+
// Cached computed values
|
|
65
|
+
#m?: number | undefined;
|
|
66
|
+
#n?: number | undefined;
|
|
67
|
+
#pubkeys?: Uint8Array[] | undefined;
|
|
68
|
+
#signatures?: Uint8Array[] | undefined;
|
|
69
|
+
#output?: Uint8Array | undefined;
|
|
70
|
+
#input?: Uint8Array | undefined;
|
|
71
|
+
#witness?: Uint8Array[] | undefined;
|
|
72
|
+
|
|
73
|
+
// Cache flags
|
|
74
|
+
#mComputed = false;
|
|
75
|
+
#nComputed = false;
|
|
76
|
+
#pubkeysComputed = false;
|
|
77
|
+
#signaturesComputed = false;
|
|
78
|
+
#outputComputed = false;
|
|
79
|
+
#inputComputed = false;
|
|
80
|
+
#witnessComputed = false;
|
|
81
|
+
|
|
82
|
+
// Decoded chunks cache
|
|
83
|
+
#decodedChunks?: Stack | undefined;
|
|
84
|
+
#decoded = false;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Creates a new P2MS payment instance.
|
|
88
|
+
*
|
|
89
|
+
* @param params - Payment parameters
|
|
90
|
+
* @param params.m - Required number of signatures
|
|
91
|
+
* @param params.n - Total number of public keys (optional, derived from pubkeys)
|
|
92
|
+
* @param params.pubkeys - Array of public keys
|
|
93
|
+
* @param params.signatures - Array of signatures
|
|
94
|
+
* @param params.output - The scriptPubKey
|
|
95
|
+
* @param params.input - The scriptSig
|
|
96
|
+
* @param params.network - Network parameters (defaults to mainnet)
|
|
97
|
+
* @param opts - Payment options
|
|
98
|
+
* @param opts.validate - Whether to validate inputs (default: true)
|
|
99
|
+
* @param opts.allowIncomplete - Allow incomplete signatures (default: false)
|
|
100
|
+
*
|
|
101
|
+
* @throws {TypeError} If validation is enabled and data is invalid
|
|
102
|
+
*/
|
|
103
|
+
constructor(
|
|
104
|
+
params: {
|
|
105
|
+
m?: number | undefined;
|
|
106
|
+
n?: number | undefined;
|
|
107
|
+
pubkeys?: Uint8Array[] | undefined;
|
|
108
|
+
signatures?: Uint8Array[] | undefined;
|
|
109
|
+
output?: Uint8Array | undefined;
|
|
110
|
+
input?: Uint8Array | undefined;
|
|
111
|
+
network?: Network | undefined;
|
|
42
112
|
},
|
|
43
|
-
|
|
44
|
-
)
|
|
113
|
+
opts?: PaymentOpts,
|
|
114
|
+
) {
|
|
115
|
+
this.#network = params.network ?? BITCOIN_NETWORK;
|
|
116
|
+
this.#opts = {
|
|
117
|
+
validate: opts?.validate ?? true,
|
|
118
|
+
allowIncomplete: opts?.allowIncomplete ?? false,
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
// Store input data
|
|
122
|
+
this.#inputM = params.m;
|
|
123
|
+
this.#inputN = params.n;
|
|
124
|
+
this.#inputPubkeys = params.pubkeys;
|
|
125
|
+
this.#inputSignatures = params.signatures;
|
|
126
|
+
this.#inputOutput = params.output;
|
|
127
|
+
this.#inputInput = params.input;
|
|
45
128
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
129
|
+
// Validate if requested
|
|
130
|
+
if (this.#opts.validate) {
|
|
131
|
+
this.#validate();
|
|
132
|
+
}
|
|
133
|
+
}
|
|
51
134
|
|
|
52
|
-
|
|
53
|
-
|
|
135
|
+
// Public getters
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Payment type discriminant.
|
|
139
|
+
*/
|
|
140
|
+
get name(): string {
|
|
141
|
+
const m = this.m;
|
|
142
|
+
const n = this.n;
|
|
143
|
+
if (m !== undefined && n !== undefined) {
|
|
144
|
+
return `p2ms(${m} of ${n})`;
|
|
145
|
+
}
|
|
146
|
+
return PaymentType.P2MS;
|
|
147
|
+
}
|
|
54
148
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
149
|
+
/**
|
|
150
|
+
* Network parameters.
|
|
151
|
+
*/
|
|
152
|
+
get network(): Network {
|
|
153
|
+
return this.#network;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Required number of signatures (M in M-of-N).
|
|
158
|
+
*/
|
|
159
|
+
get m(): number | undefined {
|
|
160
|
+
if (!this.#mComputed) {
|
|
161
|
+
this.#m = this.#computeM();
|
|
162
|
+
this.#mComputed = true;
|
|
163
|
+
}
|
|
164
|
+
return this.#m;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Total number of public keys (N in M-of-N).
|
|
169
|
+
*/
|
|
170
|
+
get n(): number | undefined {
|
|
171
|
+
if (!this.#nComputed) {
|
|
172
|
+
this.#n = this.#computeN();
|
|
173
|
+
this.#nComputed = true;
|
|
174
|
+
}
|
|
175
|
+
return this.#n;
|
|
62
176
|
}
|
|
63
177
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
178
|
+
/**
|
|
179
|
+
* Array of public keys.
|
|
180
|
+
*/
|
|
181
|
+
get pubkeys(): PublicKey[] | undefined {
|
|
182
|
+
if (!this.#pubkeysComputed) {
|
|
183
|
+
this.#pubkeys = this.#computePubkeys();
|
|
184
|
+
this.#pubkeysComputed = true;
|
|
185
|
+
}
|
|
186
|
+
return this.#pubkeys as PublicKey[] | undefined;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Array of signatures.
|
|
191
|
+
*/
|
|
192
|
+
get signatures(): Signature[] | undefined {
|
|
193
|
+
if (!this.#signaturesComputed) {
|
|
194
|
+
this.#signatures = this.#computeSignatures();
|
|
195
|
+
this.#signaturesComputed = true;
|
|
196
|
+
}
|
|
197
|
+
return this.#signatures as Signature[] | undefined;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* The scriptPubKey: `m {pubkeys} n OP_CHECKMULTISIG`
|
|
202
|
+
*/
|
|
203
|
+
get output(): Script | undefined {
|
|
204
|
+
if (!this.#outputComputed) {
|
|
205
|
+
this.#output = this.#computeOutput();
|
|
206
|
+
this.#outputComputed = true;
|
|
207
|
+
}
|
|
208
|
+
return this.#output as Script | undefined;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* The scriptSig: `OP_0 {signatures}`
|
|
213
|
+
*/
|
|
214
|
+
get input(): Script | undefined {
|
|
215
|
+
if (!this.#inputComputed) {
|
|
216
|
+
this.#input = this.#computeInput();
|
|
217
|
+
this.#inputComputed = true;
|
|
218
|
+
}
|
|
219
|
+
return this.#input as Script | undefined;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Witness stack (empty for P2MS as it's not a SegWit type).
|
|
224
|
+
*/
|
|
225
|
+
get witness(): Uint8Array[] | undefined {
|
|
226
|
+
if (!this.#witnessComputed) {
|
|
227
|
+
this.#witness = this.#computeWitness();
|
|
228
|
+
this.#witnessComputed = true;
|
|
229
|
+
}
|
|
230
|
+
return this.#witness;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// Static factory methods
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Creates a P2MS payment from public keys.
|
|
237
|
+
*
|
|
238
|
+
* @param m - Required number of signatures
|
|
239
|
+
* @param pubkeys - Array of public keys
|
|
240
|
+
* @param network - Network parameters (defaults to mainnet)
|
|
241
|
+
* @returns A new P2MS payment instance
|
|
242
|
+
*
|
|
243
|
+
* @example
|
|
244
|
+
* ```typescript
|
|
245
|
+
* // Create a 2-of-3 multisig
|
|
246
|
+
* const payment = P2MS.fromPubkeys(2, [pubkey1, pubkey2, pubkey3]);
|
|
247
|
+
* ```
|
|
248
|
+
*/
|
|
249
|
+
static fromPubkeys(m: number, pubkeys: PublicKey[], network?: Network): P2MS {
|
|
250
|
+
return new P2MS({ m, pubkeys, network });
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Creates a P2MS payment from a scriptPubKey.
|
|
255
|
+
*
|
|
256
|
+
* @param output - The scriptPubKey
|
|
257
|
+
* @param network - Network parameters (defaults to mainnet)
|
|
258
|
+
* @returns A new P2MS payment instance
|
|
259
|
+
*/
|
|
260
|
+
static fromOutput(output: Uint8Array, network?: Network): P2MS {
|
|
261
|
+
return new P2MS({ output, network });
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Creates a P2MS payment from signatures (for spending).
|
|
266
|
+
*
|
|
267
|
+
* @param signatures - Array of signatures
|
|
268
|
+
* @param m - Required number of signatures (optional)
|
|
269
|
+
* @param pubkeys - Array of public keys (optional, for validation)
|
|
270
|
+
* @param network - Network parameters (defaults to mainnet)
|
|
271
|
+
* @returns A new P2MS payment instance
|
|
272
|
+
*/
|
|
273
|
+
static fromSignatures(
|
|
274
|
+
signatures: Signature[],
|
|
275
|
+
m?: number,
|
|
276
|
+
pubkeys?: PublicKey[],
|
|
277
|
+
network?: Network,
|
|
278
|
+
): P2MS {
|
|
279
|
+
return new P2MS({ signatures, m, pubkeys, network });
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// Private helper methods
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Converts to a plain P2MSPayment object for backwards compatibility.
|
|
286
|
+
*
|
|
287
|
+
* @returns A P2MSPayment object
|
|
288
|
+
*/
|
|
289
|
+
toPayment(): P2MSPayment {
|
|
290
|
+
return {
|
|
291
|
+
name: this.name,
|
|
292
|
+
network: this.network,
|
|
293
|
+
m: this.m,
|
|
294
|
+
n: this.n,
|
|
295
|
+
pubkeys: this.pubkeys,
|
|
296
|
+
signatures: this.signatures,
|
|
297
|
+
output: this.output,
|
|
298
|
+
input: this.input,
|
|
299
|
+
witness: this.witness,
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// Private computation methods
|
|
304
|
+
|
|
305
|
+
#decode(output: Uint8Array | Stack): void {
|
|
306
|
+
if (this.#decoded) return;
|
|
307
|
+
this.#decoded = true;
|
|
308
|
+
this.#decodedChunks = (bscript.decompile(output) ?? []) as Stack;
|
|
309
|
+
this.#m = (this.#decodedChunks[0] as number) - OP_INT_BASE;
|
|
310
|
+
this.#n = (this.#decodedChunks[this.#decodedChunks.length - 2] as number) - OP_INT_BASE;
|
|
311
|
+
this.#pubkeys = this.#decodedChunks.slice(1, -2) as Uint8Array[];
|
|
312
|
+
this.#mComputed = true;
|
|
313
|
+
this.#nComputed = true;
|
|
314
|
+
this.#pubkeysComputed = true;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
#computeM(): number | undefined {
|
|
318
|
+
if (this.#inputM !== undefined) {
|
|
319
|
+
return this.#inputM;
|
|
320
|
+
}
|
|
321
|
+
const output = this.#inputOutput ?? this.output;
|
|
322
|
+
if (output) {
|
|
323
|
+
this.#decode(output);
|
|
324
|
+
return this.#m;
|
|
325
|
+
}
|
|
326
|
+
return undefined;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
#computeN(): number | undefined {
|
|
330
|
+
if (this.#inputN !== undefined) {
|
|
331
|
+
return this.#inputN;
|
|
332
|
+
}
|
|
333
|
+
if (this.#inputPubkeys) {
|
|
334
|
+
return this.#inputPubkeys.length;
|
|
335
|
+
}
|
|
336
|
+
if (this.#inputOutput) {
|
|
337
|
+
this.#decode(this.#inputOutput);
|
|
338
|
+
return this.#n;
|
|
339
|
+
}
|
|
340
|
+
return undefined;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
#computePubkeys(): PublicKey[] | undefined {
|
|
344
|
+
if (this.#inputPubkeys) {
|
|
345
|
+
return this.#inputPubkeys as PublicKey[];
|
|
346
|
+
}
|
|
347
|
+
if (this.#inputOutput) {
|
|
348
|
+
this.#decode(this.#inputOutput);
|
|
349
|
+
return this.#pubkeys as PublicKey[] | undefined;
|
|
350
|
+
}
|
|
351
|
+
return undefined;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
#computeSignatures(): Signature[] | undefined {
|
|
355
|
+
if (this.#inputSignatures) {
|
|
356
|
+
return this.#inputSignatures as Signature[];
|
|
357
|
+
}
|
|
358
|
+
if (this.#inputInput) {
|
|
359
|
+
const decompiled = bscript.decompile(this.#inputInput);
|
|
360
|
+
if (decompiled === null || decompiled === undefined) {
|
|
361
|
+
return undefined;
|
|
362
|
+
}
|
|
363
|
+
return decompiled.slice(1) as Signature[];
|
|
364
|
+
}
|
|
365
|
+
return undefined;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
#computeOutput(): Script | undefined {
|
|
369
|
+
if (this.#inputOutput) {
|
|
370
|
+
return this.#inputOutput as Script;
|
|
371
|
+
}
|
|
372
|
+
const m = this.#inputM;
|
|
373
|
+
const n = this.n;
|
|
374
|
+
const pubkeys = this.#inputPubkeys;
|
|
375
|
+
if (m === undefined || n === undefined || !pubkeys) {
|
|
376
|
+
return undefined;
|
|
377
|
+
}
|
|
68
378
|
return bscript.compile(
|
|
69
|
-
([] as Stack).concat(
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
379
|
+
([] as Stack).concat(OP_INT_BASE + m, pubkeys, OP_INT_BASE + n, OPS.OP_CHECKMULTISIG),
|
|
380
|
+
) as Script;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
#computeInput(): Script | undefined {
|
|
384
|
+
if (this.#inputInput) {
|
|
385
|
+
return this.#inputInput as Script;
|
|
386
|
+
}
|
|
387
|
+
if (!this.#inputSignatures) {
|
|
388
|
+
return undefined;
|
|
389
|
+
}
|
|
390
|
+
return bscript.compile(([OPS.OP_0] as Stack).concat(this.#inputSignatures)) as Script;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
// Validation
|
|
394
|
+
|
|
395
|
+
#computeWitness(): Uint8Array[] | undefined {
|
|
396
|
+
if (this.input) {
|
|
397
|
+
return [];
|
|
398
|
+
}
|
|
399
|
+
return undefined;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
#isAcceptableSignature(x: Uint8Array | number): boolean {
|
|
403
|
+
return (
|
|
404
|
+
bscript.isCanonicalScriptSignature(x as Uint8Array) ||
|
|
405
|
+
(this.#opts.allowIncomplete && (x as number) === OPS.OP_0)
|
|
75
406
|
);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
return bscript.compile(([OPS.OP_0] as Stack).concat(a.signatures));
|
|
101
|
-
});
|
|
102
|
-
lazy.prop(o, 'witness', () => {
|
|
103
|
-
if (!o.input) return;
|
|
104
|
-
return [];
|
|
105
|
-
});
|
|
106
|
-
lazy.prop(o, 'name', () => {
|
|
107
|
-
if (!o.m || !o.n) return;
|
|
108
|
-
return `p2ms(${o.m} of ${o.n})`;
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
// extended validation
|
|
112
|
-
if (opts.validate) {
|
|
113
|
-
if (a.output) {
|
|
114
|
-
decode(a.output);
|
|
115
|
-
if (!typef.Number(chunks[0])) throw new TypeError('Output is invalid');
|
|
116
|
-
if (!typef.Number(chunks[chunks.length - 2])) throw new TypeError('Output is invalid');
|
|
117
|
-
if (chunks[chunks.length - 1] !== OPS.OP_CHECKMULTISIG)
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
#validate(): void {
|
|
410
|
+
if (this.#inputOutput) {
|
|
411
|
+
this.#decode(this.#inputOutput);
|
|
412
|
+
const chunks = this.#decodedChunks;
|
|
413
|
+
if (!chunks) {
|
|
414
|
+
throw new TypeError('Output is invalid');
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
if (typeof chunks[0] !== 'number') {
|
|
418
|
+
throw new TypeError('Output is invalid');
|
|
419
|
+
}
|
|
420
|
+
if (typeof chunks[chunks.length - 2] !== 'number') {
|
|
421
|
+
throw new TypeError('Output is invalid');
|
|
422
|
+
}
|
|
423
|
+
if (chunks[chunks.length - 1] !== OPS.OP_CHECKMULTISIG) {
|
|
424
|
+
throw new TypeError('Output is invalid');
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
const m = this.#m;
|
|
428
|
+
const n = this.#n;
|
|
429
|
+
const pubkeys = this.#pubkeys;
|
|
430
|
+
if (m === undefined || n === undefined || !pubkeys) {
|
|
118
431
|
throw new TypeError('Output is invalid');
|
|
432
|
+
}
|
|
119
433
|
|
|
120
|
-
if (
|
|
434
|
+
if (m <= 0 || n > 16 || m > n || n !== chunks.length - 3) {
|
|
435
|
+
throw new TypeError('Output is invalid');
|
|
436
|
+
}
|
|
437
|
+
if (!pubkeys.every((x) => isPoint(x))) {
|
|
121
438
|
throw new TypeError('Output is invalid');
|
|
122
|
-
|
|
439
|
+
}
|
|
123
440
|
|
|
124
|
-
if (
|
|
125
|
-
|
|
126
|
-
|
|
441
|
+
if (this.#inputM !== undefined && this.#inputM !== m) {
|
|
442
|
+
throw new TypeError('m mismatch');
|
|
443
|
+
}
|
|
444
|
+
if (this.#inputN !== undefined && this.#inputN !== n) {
|
|
445
|
+
throw new TypeError('n mismatch');
|
|
446
|
+
}
|
|
447
|
+
if (this.#inputPubkeys && !stacksEqual(this.#inputPubkeys, pubkeys)) {
|
|
127
448
|
throw new TypeError('Pubkeys mismatch');
|
|
449
|
+
}
|
|
128
450
|
}
|
|
129
451
|
|
|
130
|
-
if (
|
|
131
|
-
if (
|
|
452
|
+
if (this.#inputPubkeys) {
|
|
453
|
+
if (this.#inputN !== undefined && this.#inputN !== this.#inputPubkeys.length) {
|
|
132
454
|
throw new TypeError('Pubkey count mismatch');
|
|
133
|
-
|
|
455
|
+
}
|
|
456
|
+
this.#n = this.#inputPubkeys.length;
|
|
457
|
+
this.#nComputed = true;
|
|
134
458
|
|
|
135
|
-
if (
|
|
459
|
+
if (this.#m !== undefined && this.#n < this.#m) {
|
|
460
|
+
throw new TypeError('Pubkey count cannot be less than m');
|
|
461
|
+
}
|
|
136
462
|
}
|
|
137
463
|
|
|
138
|
-
if (
|
|
139
|
-
if (
|
|
140
|
-
|
|
464
|
+
if (this.#inputSignatures) {
|
|
465
|
+
if (this.#m !== undefined && this.#inputSignatures.length < this.#m) {
|
|
466
|
+
throw new TypeError('Not enough signatures provided');
|
|
467
|
+
}
|
|
468
|
+
if (this.#m !== undefined && this.#inputSignatures.length > this.#m) {
|
|
469
|
+
throw new TypeError('Too many signatures provided');
|
|
470
|
+
}
|
|
141
471
|
}
|
|
142
472
|
|
|
143
|
-
if (
|
|
144
|
-
if (
|
|
145
|
-
|
|
473
|
+
if (this.#inputInput) {
|
|
474
|
+
if (this.#inputInput[0] !== OPS.OP_0) {
|
|
475
|
+
throw new TypeError('Input is invalid');
|
|
476
|
+
}
|
|
477
|
+
const sigs = this.signatures;
|
|
478
|
+
if (!sigs || sigs.length === 0 || !sigs.every((s) => this.#isAcceptableSignature(s))) {
|
|
146
479
|
throw new TypeError('Input has invalid signature(s)');
|
|
480
|
+
}
|
|
147
481
|
|
|
148
|
-
if (
|
|
482
|
+
if (this.#inputSignatures && !stacksEqual(this.#inputSignatures, sigs)) {
|
|
149
483
|
throw new TypeError('Signature mismatch');
|
|
150
|
-
|
|
484
|
+
}
|
|
485
|
+
if (
|
|
486
|
+
this.#inputM !== undefined &&
|
|
487
|
+
this.#inputSignatures &&
|
|
488
|
+
this.#inputM !== this.#inputSignatures.length
|
|
489
|
+
) {
|
|
151
490
|
throw new TypeError('Signature count mismatch');
|
|
491
|
+
}
|
|
152
492
|
}
|
|
153
493
|
}
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
/**
|
|
497
|
+
* Creates a Pay-to-Multisig (P2MS) payment object.
|
|
498
|
+
*
|
|
499
|
+
* This is the legacy factory function for backwards compatibility.
|
|
500
|
+
* For new code, prefer using the P2MS class directly.
|
|
501
|
+
*
|
|
502
|
+
* @param a - The payment object containing the necessary data
|
|
503
|
+
* @param opts - Optional payment options
|
|
504
|
+
* @returns The P2MS payment object
|
|
505
|
+
* @throws {TypeError} If the required data is not provided or if the data is invalid
|
|
506
|
+
*
|
|
507
|
+
* @example
|
|
508
|
+
* ```typescript
|
|
509
|
+
* import { p2ms } from '@btc-vision/bitcoin';
|
|
510
|
+
*
|
|
511
|
+
* // Create a 2-of-3 multisig
|
|
512
|
+
* const payment = p2ms({ m: 2, pubkeys: [pubkey1, pubkey2, pubkey3] });
|
|
513
|
+
* ```
|
|
514
|
+
*/
|
|
515
|
+
export function p2ms(a: Omit<P2MSPayment, 'name'>, opts?: PaymentOpts): P2MSPayment {
|
|
516
|
+
if (!a.input && !a.output && !(a.pubkeys && a.m !== undefined) && !a.signatures) {
|
|
517
|
+
throw new TypeError('Not enough data');
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
const instance = new P2MS(
|
|
521
|
+
{
|
|
522
|
+
m: a.m,
|
|
523
|
+
n: a.n,
|
|
524
|
+
pubkeys: a.pubkeys,
|
|
525
|
+
signatures: a.signatures,
|
|
526
|
+
output: a.output,
|
|
527
|
+
input: a.input,
|
|
528
|
+
network: a.network,
|
|
529
|
+
},
|
|
530
|
+
opts,
|
|
531
|
+
);
|
|
154
532
|
|
|
155
|
-
|
|
533
|
+
// Return a merged object for backwards compatibility
|
|
534
|
+
return Object.assign(instance.toPayment(), a);
|
|
156
535
|
}
|