@btc-vision/bitcoin 6.5.5 → 7.0.0-alpha.0
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/AUDIT/README.md +9 -0
- package/HOW_TO_WRITE_GOOD_CODE.md +2436 -0
- package/SECURITY.md +27 -0
- package/benchmark/psbt-2000-inputs.bench.ts +178 -0
- package/benchmark/signing.bench.ts +147 -0
- package/browser/address.d.ts +56 -9
- 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 +12482 -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 +57 -10
- package/build/address.d.ts.map +1 -0
- package/build/address.js +80 -24
- 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 +204 -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 +36 -9
- package/build/payments/bip341.d.ts.map +1 -0
- package/build/payments/bip341.js +35 -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 -152
- 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 +429 -104
- 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 +466 -144
- 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 +113 -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 +411 -412
- 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 +37 -13
- 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 +100 -36
- 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 +175 -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 +83 -25
- package/scripts/bundle-ecc.ts +111 -0
- package/src/address.ts +81 -44
- package/src/bech32utils.ts +3 -3
- package/src/bip66.ts +34 -24
- package/src/block.ts +196 -84
- package/src/branded.ts +18 -0
- package/src/crypto.ts +64 -26
- package/src/ecc/context.ts +277 -0
- package/src/ecc/index.ts +14 -0
- package/src/ecc/types.ts +154 -0
- package/src/ecpair.d.ts +99 -0
- package/src/errors.ts +163 -0
- package/src/index.ts +113 -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 +34 -33
- package/src/payments/embed.ts +244 -41
- package/src/payments/index.ts +12 -10
- package/src/payments/p2ms.ts +490 -118
- package/src/payments/p2op.ts +431 -133
- package/src/payments/p2pk.ts +370 -72
- package/src/payments/p2pkh.ts +524 -130
- package/src/payments/p2sh.ts +572 -172
- package/src/payments/p2tr.ts +686 -194
- package/src/payments/p2wpkh.ts +484 -107
- package/src/payments/p2wsh.ts +526 -164
- package/src/payments/types.ts +80 -66
- package/src/psbt/bip371.ts +68 -51
- package/src/psbt/psbtutils.ts +39 -40
- package/src/psbt/types.ts +331 -0
- package/src/psbt/utils.ts +188 -0
- package/src/psbt/validation.ts +192 -0
- package/src/psbt.ts +566 -809
- package/src/pubkey.ts +24 -25
- package/src/push_data.ts +18 -16
- package/src/script.ts +82 -64
- package/src/script_number.ts +6 -6
- package/src/script_signature.ts +33 -36
- package/src/transaction.ts +458 -238
- package/src/types.ts +231 -100
- package/src/workers/WorkerSigningPool.node.ts +887 -0
- package/src/workers/WorkerSigningPool.ts +670 -0
- package/src/workers/ecc-bundle.ts +26 -0
- package/src/workers/index.ts +165 -0
- package/src/workers/psbt-parallel.ts +332 -0
- package/src/workers/signing-worker.ts +353 -0
- package/src/workers/types.ts +413 -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/vite.config.browser.ts +3 -42
- package/vitest.config.integration.ts +11 -0
- package/browser/bufferutils.d.ts +0 -34
- package/browser/chunks/crypto-BhCpKpek.js +0 -2033
- package/browser/chunks/payments-yjA0Evsv.js +0 -1089
- package/browser/chunks/psbt-URK2hBFc.js +0 -4039
- 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/p2pkh.ts
CHANGED
|
@@ -1,108 +1,420 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pay-to-Public-Key-Hash (P2PKH) payment class.
|
|
3
|
+
*
|
|
4
|
+
* P2PKH is the most common legacy Bitcoin payment type. The output script
|
|
5
|
+
* contains the hash of a public key, and spending requires the full public key
|
|
6
|
+
* and a valid signature.
|
|
7
|
+
*
|
|
8
|
+
* @packageDocumentation
|
|
9
|
+
*/
|
|
10
|
+
|
|
1
11
|
import * as bs58check from 'bs58check';
|
|
2
12
|
import * as bcrypto from '../crypto.js';
|
|
3
|
-
import { bitcoin as BITCOIN_NETWORK } from '../networks.js';
|
|
13
|
+
import { bitcoin as BITCOIN_NETWORK, type Network } from '../networks.js';
|
|
4
14
|
import { decompressPublicKey } from '../pubkey.js';
|
|
5
15
|
import * as bscript from '../script.js';
|
|
6
|
-
import { isPoint,
|
|
7
|
-
import {
|
|
8
|
-
import
|
|
16
|
+
import { isPoint, type Bytes20, type PublicKey, type Script, type Signature } from '../types.js';
|
|
17
|
+
import { alloc, equals } from '../io/index.js';
|
|
18
|
+
import { PaymentType, type P2PKHPayment, type PaymentOpts } from './types.js';
|
|
9
19
|
|
|
10
20
|
const OPS = bscript.opcodes;
|
|
11
21
|
|
|
12
|
-
// input: {signature} {pubkey}
|
|
13
|
-
// output: OP_DUP OP_HASH160 {hash160(pubkey)} OP_EQUALVERIFY OP_CHECKSIG
|
|
14
22
|
/**
|
|
15
|
-
*
|
|
23
|
+
* Pay-to-Public-Key-Hash (P2PKH) payment class.
|
|
24
|
+
*
|
|
25
|
+
* Creates locking scripts of the form:
|
|
26
|
+
* `OP_DUP OP_HASH160 {hash160(pubkey)} OP_EQUALVERIFY OP_CHECKSIG`
|
|
27
|
+
*
|
|
28
|
+
* Spending requires providing: `{signature} {pubkey}`
|
|
16
29
|
*
|
|
17
|
-
* @
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```typescript
|
|
32
|
+
* import { P2PKH } from '@btc-vision/bitcoin';
|
|
33
|
+
*
|
|
34
|
+
* // Create from public key
|
|
35
|
+
* const payment = P2PKH.fromPubkey(pubkey);
|
|
36
|
+
* console.log(payment.address); // Bitcoin address
|
|
37
|
+
* console.log(payment.output); // scriptPubKey
|
|
38
|
+
*
|
|
39
|
+
* // Create from address
|
|
40
|
+
* const fromAddr = P2PKH.fromAddress('1BvBMSEYstWetqTFn5Au4m4GFg7xJaNVN2');
|
|
41
|
+
* console.log(fromAddr.hash); // 20-byte pubkey hash
|
|
42
|
+
*
|
|
43
|
+
* // Create from hash
|
|
44
|
+
* const fromHash = P2PKH.fromHash(hash160);
|
|
45
|
+
* console.log(fromHash.address);
|
|
46
|
+
* ```
|
|
21
47
|
*/
|
|
22
|
-
export
|
|
23
|
-
|
|
24
|
-
|
|
48
|
+
export class P2PKH {
|
|
49
|
+
// Static public fields
|
|
50
|
+
static readonly NAME = PaymentType.P2PKH;
|
|
51
|
+
|
|
52
|
+
// Private instance fields
|
|
53
|
+
readonly #network: Network;
|
|
54
|
+
readonly #opts: Required<PaymentOpts>;
|
|
55
|
+
|
|
56
|
+
// Input data (provided by user)
|
|
57
|
+
#inputAddress?: string | undefined;
|
|
58
|
+
#inputHash?: Uint8Array | undefined;
|
|
59
|
+
#inputPubkey?: Uint8Array | undefined;
|
|
60
|
+
#inputSignature?: Uint8Array | undefined;
|
|
61
|
+
#inputOutput?: Uint8Array | undefined;
|
|
62
|
+
#inputInput?: Uint8Array | undefined;
|
|
63
|
+
|
|
64
|
+
// Hybrid/uncompressed key flags
|
|
65
|
+
#useHybrid = false;
|
|
66
|
+
#useUncompressed = false;
|
|
67
|
+
|
|
68
|
+
// Cached computed values
|
|
69
|
+
#address?: string | undefined;
|
|
70
|
+
#hash?: Uint8Array | undefined;
|
|
71
|
+
#pubkey?: Uint8Array | undefined;
|
|
72
|
+
#signature?: Uint8Array | undefined;
|
|
73
|
+
#output?: Uint8Array | undefined;
|
|
74
|
+
#input?: Uint8Array | undefined;
|
|
75
|
+
#witness?: Uint8Array[] | undefined;
|
|
76
|
+
|
|
77
|
+
// Cache flags
|
|
78
|
+
#addressComputed = false;
|
|
79
|
+
#hashComputed = false;
|
|
80
|
+
#pubkeyComputed = false;
|
|
81
|
+
#signatureComputed = false;
|
|
82
|
+
#outputComputed = false;
|
|
83
|
+
#inputComputed = false;
|
|
84
|
+
#witnessComputed = false;
|
|
85
|
+
|
|
86
|
+
// Decoded address cache
|
|
87
|
+
#decodedAddress?: { version: number; hash: Uint8Array } | undefined;
|
|
88
|
+
#decodedAddressComputed = false;
|
|
89
|
+
|
|
90
|
+
// Decoded input chunks cache
|
|
91
|
+
#inputChunks?: (Uint8Array | number)[] | undefined;
|
|
92
|
+
#inputChunksComputed = false;
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Creates a new P2PKH payment instance.
|
|
96
|
+
*
|
|
97
|
+
* @param params - Payment parameters
|
|
98
|
+
* @param params.address - Base58Check encoded address
|
|
99
|
+
* @param params.hash - 20-byte pubkey hash (RIPEMD160(SHA256(pubkey)))
|
|
100
|
+
* @param params.pubkey - The public key (33 or 65 bytes)
|
|
101
|
+
* @param params.signature - DER-encoded signature
|
|
102
|
+
* @param params.output - The scriptPubKey
|
|
103
|
+
* @param params.input - The scriptSig
|
|
104
|
+
* @param params.network - Network parameters (defaults to mainnet)
|
|
105
|
+
* @param opts - Payment options
|
|
106
|
+
* @param opts.validate - Whether to validate inputs (default: true)
|
|
107
|
+
*
|
|
108
|
+
* @throws {TypeError} If validation is enabled and data is invalid
|
|
109
|
+
*/
|
|
110
|
+
constructor(
|
|
111
|
+
params: {
|
|
112
|
+
address?: string | undefined;
|
|
113
|
+
hash?: Uint8Array | undefined;
|
|
114
|
+
pubkey?: Uint8Array | undefined;
|
|
115
|
+
signature?: Uint8Array | undefined;
|
|
116
|
+
output?: Uint8Array | undefined;
|
|
117
|
+
input?: Uint8Array | undefined;
|
|
118
|
+
network?: Network | undefined;
|
|
119
|
+
useHybrid?: boolean | undefined;
|
|
120
|
+
useUncompressed?: boolean | undefined;
|
|
121
|
+
},
|
|
122
|
+
opts?: PaymentOpts,
|
|
123
|
+
) {
|
|
124
|
+
this.#network = params.network ?? BITCOIN_NETWORK;
|
|
125
|
+
this.#opts = {
|
|
126
|
+
validate: opts?.validate ?? true,
|
|
127
|
+
allowIncomplete: opts?.allowIncomplete ?? false,
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
// Store input data
|
|
131
|
+
this.#inputAddress = params.address;
|
|
132
|
+
this.#inputHash = params.hash;
|
|
133
|
+
this.#inputPubkey = params.pubkey;
|
|
134
|
+
this.#inputSignature = params.signature;
|
|
135
|
+
this.#inputOutput = params.output;
|
|
136
|
+
this.#inputInput = params.input;
|
|
137
|
+
this.#useHybrid = params.useHybrid ?? false;
|
|
138
|
+
this.#useUncompressed = params.useUncompressed ?? false;
|
|
139
|
+
|
|
140
|
+
// Validate if requested
|
|
141
|
+
if (this.#opts.validate) {
|
|
142
|
+
this.#validate();
|
|
143
|
+
}
|
|
25
144
|
}
|
|
26
145
|
|
|
27
|
-
|
|
146
|
+
// Public getters
|
|
28
147
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
148
|
+
/**
|
|
149
|
+
* Payment type discriminant.
|
|
150
|
+
*/
|
|
151
|
+
get name(): typeof PaymentType.P2PKH {
|
|
152
|
+
return PaymentType.P2PKH;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Network parameters.
|
|
157
|
+
*/
|
|
158
|
+
get network(): Network {
|
|
159
|
+
return this.#network;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Base58Check encoded Bitcoin address.
|
|
164
|
+
*/
|
|
165
|
+
get address(): string | undefined {
|
|
166
|
+
if (!this.#addressComputed) {
|
|
167
|
+
this.#address = this.#computeAddress();
|
|
168
|
+
this.#addressComputed = true;
|
|
169
|
+
}
|
|
170
|
+
return this.#address;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* 20-byte pubkey hash (RIPEMD160(SHA256(pubkey))).
|
|
175
|
+
*/
|
|
176
|
+
get hash(): Bytes20 | undefined {
|
|
177
|
+
if (!this.#hashComputed) {
|
|
178
|
+
this.#hash = this.#computeHash();
|
|
179
|
+
this.#hashComputed = true;
|
|
180
|
+
}
|
|
181
|
+
return this.#hash as Bytes20 | undefined;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* The public key (33 or 65 bytes).
|
|
186
|
+
*/
|
|
187
|
+
get pubkey(): PublicKey | undefined {
|
|
188
|
+
if (!this.#pubkeyComputed) {
|
|
189
|
+
this.#pubkey = this.#computePubkey();
|
|
190
|
+
this.#pubkeyComputed = true;
|
|
191
|
+
}
|
|
192
|
+
return this.#pubkey as PublicKey | undefined;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* The DER-encoded signature.
|
|
197
|
+
*/
|
|
198
|
+
get signature(): Signature | undefined {
|
|
199
|
+
if (!this.#signatureComputed) {
|
|
200
|
+
this.#signature = this.#computeSignature();
|
|
201
|
+
this.#signatureComputed = true;
|
|
202
|
+
}
|
|
203
|
+
return this.#signature as Signature | undefined;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* The scriptPubKey:
|
|
208
|
+
* `OP_DUP OP_HASH160 {hash} OP_EQUALVERIFY OP_CHECKSIG`
|
|
209
|
+
*/
|
|
210
|
+
get output(): Script | undefined {
|
|
211
|
+
if (!this.#outputComputed) {
|
|
212
|
+
this.#output = this.#computeOutput();
|
|
213
|
+
this.#outputComputed = true;
|
|
214
|
+
}
|
|
215
|
+
return this.#output as Script | undefined;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* The scriptSig: `{signature} {pubkey}`
|
|
220
|
+
*/
|
|
221
|
+
get input(): Script | undefined {
|
|
222
|
+
if (!this.#inputComputed) {
|
|
223
|
+
this.#input = this.#computeInput();
|
|
224
|
+
this.#inputComputed = true;
|
|
225
|
+
}
|
|
226
|
+
return this.#input as Script | undefined;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Witness stack (empty for P2PKH as it's not a SegWit type).
|
|
231
|
+
*/
|
|
232
|
+
get witness(): Uint8Array[] | undefined {
|
|
233
|
+
if (!this.#witnessComputed) {
|
|
234
|
+
this.#witness = this.#computeWitness();
|
|
235
|
+
this.#witnessComputed = true;
|
|
236
|
+
}
|
|
237
|
+
return this.#witness;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// Static factory methods
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Creates a P2PKH payment from a public key.
|
|
244
|
+
*
|
|
245
|
+
* @param pubkey - The public key (33 or 65 bytes)
|
|
246
|
+
* @param network - Network parameters (defaults to mainnet)
|
|
247
|
+
* @returns A new P2PKH payment instance
|
|
248
|
+
*
|
|
249
|
+
* @example
|
|
250
|
+
* ```typescript
|
|
251
|
+
* const payment = P2PKH.fromPubkey(pubkey);
|
|
252
|
+
* const address = payment.address;
|
|
253
|
+
* ```
|
|
254
|
+
*/
|
|
255
|
+
static fromPubkey(pubkey: PublicKey, network?: Network): P2PKH {
|
|
256
|
+
return new P2PKH({ pubkey, network });
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Creates a P2PKH payment from a Base58Check address.
|
|
261
|
+
*
|
|
262
|
+
* @param address - Base58Check encoded address
|
|
263
|
+
* @param network - Network parameters (defaults to mainnet)
|
|
264
|
+
* @returns A new P2PKH payment instance
|
|
265
|
+
*
|
|
266
|
+
* @example
|
|
267
|
+
* ```typescript
|
|
268
|
+
* const payment = P2PKH.fromAddress('1BvBMSEYstWetqTFn5Au4m4GFg7xJaNVN2');
|
|
269
|
+
* const hash = payment.hash;
|
|
270
|
+
* ```
|
|
271
|
+
*/
|
|
272
|
+
static fromAddress(address: string, network?: Network): P2PKH {
|
|
273
|
+
return new P2PKH({ address, network });
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Creates a P2PKH payment from a 20-byte pubkey hash.
|
|
278
|
+
*
|
|
279
|
+
* @param hash - 20-byte pubkey hash
|
|
280
|
+
* @param network - Network parameters (defaults to mainnet)
|
|
281
|
+
* @returns A new P2PKH payment instance
|
|
282
|
+
*
|
|
283
|
+
* @example
|
|
284
|
+
* ```typescript
|
|
285
|
+
* const payment = P2PKH.fromHash(hash160);
|
|
286
|
+
* const address = payment.address;
|
|
287
|
+
* ```
|
|
288
|
+
*/
|
|
289
|
+
static fromHash(hash: Bytes20, network?: Network): P2PKH {
|
|
290
|
+
return new P2PKH({ hash, network });
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Creates a P2PKH payment from a scriptPubKey.
|
|
295
|
+
*
|
|
296
|
+
* @param output - The scriptPubKey
|
|
297
|
+
* @param network - Network parameters (defaults to mainnet)
|
|
298
|
+
* @returns A new P2PKH payment instance
|
|
299
|
+
*/
|
|
300
|
+
static fromOutput(output: Uint8Array, network?: Network): P2PKH {
|
|
301
|
+
return new P2PKH({ output, network });
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// Private helper methods
|
|
305
|
+
|
|
306
|
+
#getDecodedAddress(): { version: number; hash: Uint8Array } | undefined {
|
|
307
|
+
if (!this.#decodedAddressComputed) {
|
|
308
|
+
if (this.#inputAddress) {
|
|
309
|
+
const payload = new Uint8Array(bs58check.default.decode(this.#inputAddress));
|
|
310
|
+
this.#decodedAddress = {
|
|
311
|
+
version: payload[0]!,
|
|
312
|
+
hash: payload.subarray(1),
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
this.#decodedAddressComputed = true;
|
|
316
|
+
}
|
|
317
|
+
return this.#decodedAddress;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
#getInputChunks(): (Uint8Array | number)[] | undefined {
|
|
321
|
+
if (!this.#inputChunksComputed) {
|
|
322
|
+
if (this.#inputInput) {
|
|
323
|
+
this.#inputChunks = bscript.decompile(this.#inputInput) ?? undefined;
|
|
324
|
+
}
|
|
325
|
+
this.#inputChunksComputed = true;
|
|
326
|
+
}
|
|
327
|
+
return this.#inputChunks;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// Private computation methods
|
|
331
|
+
|
|
332
|
+
#computeAddress(): string | undefined {
|
|
333
|
+
if (this.#inputAddress) {
|
|
334
|
+
return this.#inputAddress;
|
|
335
|
+
}
|
|
336
|
+
const h = this.hash;
|
|
337
|
+
if (!h) return undefined;
|
|
42
338
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
const hash = payload.subarray(1);
|
|
47
|
-
return { version, hash };
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
const _chunks = lazy.value(() => {
|
|
51
|
-
return bscript.decompile(a.input!);
|
|
52
|
-
}) as StackFunction;
|
|
53
|
-
|
|
54
|
-
const network = a.network || BITCOIN_NETWORK;
|
|
55
|
-
const o: P2PKHPayment = {
|
|
56
|
-
name: PaymentType.P2PKH,
|
|
57
|
-
network,
|
|
58
|
-
hash: undefined,
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
lazy.prop(o, 'address', () => {
|
|
62
|
-
if (!o.hash) return;
|
|
63
|
-
|
|
64
|
-
const payload = Buffer.allocUnsafe(21);
|
|
65
|
-
payload.writeUInt8(network.pubKeyHash, 0);
|
|
66
|
-
o.hash.copy(payload, 1);
|
|
339
|
+
const payload = alloc(21);
|
|
340
|
+
payload[0] = this.#network.pubKeyHash;
|
|
341
|
+
payload.set(h, 1);
|
|
67
342
|
return bs58check.default.encode(payload);
|
|
68
|
-
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
#computeHash(): Bytes20 | undefined {
|
|
346
|
+
if (this.#inputHash) {
|
|
347
|
+
return this.#inputHash as Bytes20;
|
|
348
|
+
}
|
|
349
|
+
if (this.#inputOutput) {
|
|
350
|
+
return this.#inputOutput.subarray(3, 23) as Bytes20;
|
|
351
|
+
}
|
|
352
|
+
if (this.#inputAddress) {
|
|
353
|
+
return this.#getDecodedAddress()?.hash as Bytes20 | undefined;
|
|
354
|
+
}
|
|
355
|
+
// Use the pubkey getter to derive pubkey from input if available
|
|
356
|
+
const pk = this.pubkey;
|
|
357
|
+
if (pk) {
|
|
358
|
+
return bcrypto.hash160(pk) as Bytes20;
|
|
359
|
+
}
|
|
360
|
+
return undefined;
|
|
361
|
+
}
|
|
69
362
|
|
|
70
|
-
|
|
71
|
-
if (
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
363
|
+
#computePubkey(): PublicKey | undefined {
|
|
364
|
+
if (this.#inputPubkey) {
|
|
365
|
+
return this.#inputPubkey as PublicKey;
|
|
366
|
+
}
|
|
367
|
+
if (this.#inputInput) {
|
|
368
|
+
const chunks = this.#getInputChunks();
|
|
369
|
+
if (chunks && chunks.length >= 2) {
|
|
370
|
+
return chunks[1] as PublicKey;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
return undefined;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
#computeSignature(): Signature | undefined {
|
|
377
|
+
if (this.#inputSignature) {
|
|
378
|
+
return this.#inputSignature as Signature;
|
|
379
|
+
}
|
|
380
|
+
if (this.#inputInput) {
|
|
381
|
+
const chunks = this.#getInputChunks();
|
|
382
|
+
if (chunks && chunks.length >= 1) {
|
|
383
|
+
return chunks[0] as Signature;
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
return undefined;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
#computeOutput(): Script | undefined {
|
|
390
|
+
if (this.#inputOutput) {
|
|
391
|
+
return this.#inputOutput as Script;
|
|
392
|
+
}
|
|
393
|
+
const h = this.hash;
|
|
394
|
+
if (!h) return undefined;
|
|
75
395
|
|
|
76
|
-
lazy.prop(o, 'output', () => {
|
|
77
|
-
if (!o.hash) return;
|
|
78
396
|
return bscript.compile([
|
|
79
397
|
OPS.OP_DUP,
|
|
80
398
|
OPS.OP_HASH160,
|
|
81
|
-
|
|
399
|
+
h,
|
|
82
400
|
OPS.OP_EQUALVERIFY,
|
|
83
401
|
OPS.OP_CHECKSIG,
|
|
84
|
-
]);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
if (
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
if (!a.pubkey) return;
|
|
99
|
-
if (!a.signature) return;
|
|
100
|
-
|
|
101
|
-
let pubKey: Buffer = a.pubkey;
|
|
102
|
-
if (a.useHybrid || a.useUncompressed) {
|
|
103
|
-
const decompressed = decompressPublicKey(a.pubkey);
|
|
402
|
+
]) as Script;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
#computeInput(): Script | undefined {
|
|
406
|
+
if (this.#inputInput) {
|
|
407
|
+
return this.#inputInput as Script;
|
|
408
|
+
}
|
|
409
|
+
if (!this.#inputPubkey || !this.#inputSignature) {
|
|
410
|
+
return undefined;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
let pubKey: Uint8Array = this.#inputPubkey;
|
|
414
|
+
if (this.#useHybrid || this.#useUncompressed) {
|
|
415
|
+
const decompressed = decompressPublicKey(this.#inputPubkey as PublicKey);
|
|
104
416
|
if (decompressed) {
|
|
105
|
-
if (
|
|
417
|
+
if (this.#useUncompressed) {
|
|
106
418
|
pubKey = decompressed.uncompressed;
|
|
107
419
|
} else {
|
|
108
420
|
pubKey = decompressed.hybrid;
|
|
@@ -110,77 +422,87 @@ export function p2pkh(a: Omit<P2PKHPayment, 'name'>, opts?: PaymentOpts): P2PKHP
|
|
|
110
422
|
}
|
|
111
423
|
}
|
|
112
424
|
|
|
113
|
-
return bscript.compile([
|
|
114
|
-
}
|
|
425
|
+
return bscript.compile([this.#inputSignature, pubKey]) as Script;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
#computeWitness(): Uint8Array[] | undefined {
|
|
429
|
+
if (this.input) {
|
|
430
|
+
return [];
|
|
431
|
+
}
|
|
432
|
+
return undefined;
|
|
433
|
+
}
|
|
115
434
|
|
|
116
|
-
|
|
117
|
-
if (!o.input) return;
|
|
118
|
-
return [];
|
|
119
|
-
});
|
|
435
|
+
// Validation
|
|
120
436
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
if (
|
|
125
|
-
|
|
437
|
+
#validate(): void {
|
|
438
|
+
let hash: Uint8Array = new Uint8Array(0);
|
|
439
|
+
|
|
440
|
+
if (this.#inputAddress) {
|
|
441
|
+
const addr = this.#getDecodedAddress();
|
|
442
|
+
if (!addr) {
|
|
443
|
+
throw new TypeError('Invalid address');
|
|
444
|
+
}
|
|
445
|
+
if (addr.version !== this.#network.pubKeyHash) {
|
|
126
446
|
throw new TypeError('Invalid version or Network mismatch');
|
|
127
447
|
}
|
|
128
|
-
|
|
129
|
-
if (_address().hash.length !== 20) {
|
|
448
|
+
if (addr.hash.length !== 20) {
|
|
130
449
|
throw new TypeError('Invalid address');
|
|
131
450
|
}
|
|
132
|
-
|
|
133
|
-
hash = _address().hash;
|
|
451
|
+
hash = addr.hash;
|
|
134
452
|
}
|
|
135
453
|
|
|
136
|
-
if (
|
|
137
|
-
if (hash.length > 0 && !
|
|
454
|
+
if (this.#inputHash) {
|
|
455
|
+
if (hash.length > 0 && !equals(hash, this.#inputHash)) {
|
|
138
456
|
throw new TypeError('Hash mismatch');
|
|
139
457
|
} else {
|
|
140
|
-
hash =
|
|
458
|
+
hash = this.#inputHash;
|
|
141
459
|
}
|
|
142
460
|
}
|
|
143
461
|
|
|
144
|
-
if (
|
|
462
|
+
if (this.#inputOutput) {
|
|
145
463
|
if (
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
464
|
+
this.#inputOutput.length !== 25 ||
|
|
465
|
+
this.#inputOutput[0] !== OPS.OP_DUP ||
|
|
466
|
+
this.#inputOutput[1] !== OPS.OP_HASH160 ||
|
|
467
|
+
this.#inputOutput[2] !== 0x14 ||
|
|
468
|
+
this.#inputOutput[23] !== OPS.OP_EQUALVERIFY ||
|
|
469
|
+
this.#inputOutput[24] !== OPS.OP_CHECKSIG
|
|
152
470
|
) {
|
|
153
471
|
throw new TypeError('Output is invalid');
|
|
154
472
|
}
|
|
155
473
|
|
|
156
|
-
const hash2 =
|
|
157
|
-
if (hash.length > 0 && !
|
|
158
|
-
|
|
474
|
+
const hash2 = this.#inputOutput.subarray(3, 23);
|
|
475
|
+
if (hash.length > 0 && !equals(hash, hash2)) {
|
|
476
|
+
throw new TypeError('Hash mismatch');
|
|
477
|
+
} else {
|
|
478
|
+
hash = hash2;
|
|
479
|
+
}
|
|
159
480
|
}
|
|
160
481
|
|
|
161
|
-
if (
|
|
162
|
-
const pkh = bcrypto.hash160(
|
|
482
|
+
if (this.#inputPubkey) {
|
|
483
|
+
const pkh = bcrypto.hash160(this.#inputPubkey);
|
|
163
484
|
|
|
164
|
-
let badHash = hash.length > 0 && !
|
|
485
|
+
let badHash = hash.length > 0 && !equals(hash, pkh);
|
|
165
486
|
if (badHash) {
|
|
166
487
|
if (
|
|
167
|
-
(
|
|
168
|
-
|
|
488
|
+
(this.#inputPubkey.length === 33 &&
|
|
489
|
+
(this.#inputPubkey[0] === 0x02 || this.#inputPubkey[0] === 0x03)) ||
|
|
490
|
+
(this.#inputPubkey.length === 65 && this.#inputPubkey[0] === 0x04)
|
|
169
491
|
) {
|
|
170
|
-
const uncompressed = decompressPublicKey(
|
|
492
|
+
const uncompressed = decompressPublicKey(this.#inputPubkey as PublicKey);
|
|
171
493
|
if (uncompressed) {
|
|
172
494
|
const pkh2 = bcrypto.hash160(uncompressed.uncompressed);
|
|
173
495
|
|
|
174
|
-
if (!
|
|
496
|
+
if (!equals(hash, pkh2)) {
|
|
175
497
|
const pkh3 = bcrypto.hash160(uncompressed.hybrid);
|
|
176
|
-
badHash = !
|
|
498
|
+
badHash = !equals(hash, pkh3);
|
|
177
499
|
|
|
178
500
|
if (!badHash) {
|
|
179
|
-
|
|
501
|
+
this.#useHybrid = true;
|
|
180
502
|
}
|
|
181
503
|
} else {
|
|
182
504
|
badHash = false;
|
|
183
|
-
|
|
505
|
+
this.#useUncompressed = true;
|
|
184
506
|
}
|
|
185
507
|
}
|
|
186
508
|
}
|
|
@@ -193,22 +515,94 @@ export function p2pkh(a: Omit<P2PKHPayment, 'name'>, opts?: PaymentOpts): P2PKHP
|
|
|
193
515
|
}
|
|
194
516
|
}
|
|
195
517
|
|
|
196
|
-
if (
|
|
197
|
-
const chunks =
|
|
198
|
-
if (chunks.length !== 2)
|
|
199
|
-
|
|
518
|
+
if (this.#inputInput) {
|
|
519
|
+
const chunks = this.#getInputChunks();
|
|
520
|
+
if (!chunks || chunks.length !== 2) {
|
|
521
|
+
throw new TypeError('Input is invalid');
|
|
522
|
+
}
|
|
523
|
+
if (!bscript.isCanonicalScriptSignature(chunks[0] as Uint8Array)) {
|
|
200
524
|
throw new TypeError('Input has invalid signature');
|
|
201
|
-
|
|
525
|
+
}
|
|
526
|
+
if (!isPoint(chunks[1])) {
|
|
527
|
+
throw new TypeError('Input has invalid pubkey');
|
|
528
|
+
}
|
|
202
529
|
|
|
203
|
-
if (
|
|
530
|
+
if (this.#inputSignature && !equals(this.#inputSignature, chunks[0] as Uint8Array)) {
|
|
204
531
|
throw new TypeError('Signature mismatch');
|
|
205
|
-
|
|
532
|
+
}
|
|
533
|
+
if (this.#inputPubkey && !equals(this.#inputPubkey, chunks[1] as Uint8Array)) {
|
|
206
534
|
throw new TypeError('Pubkey mismatch');
|
|
535
|
+
}
|
|
207
536
|
|
|
208
|
-
const pkh = bcrypto.hash160(chunks[1] as
|
|
209
|
-
if (hash.length > 0 && !
|
|
537
|
+
const pkh = bcrypto.hash160(chunks[1] as Uint8Array);
|
|
538
|
+
if (hash.length > 0 && !equals(hash, pkh)) {
|
|
539
|
+
throw new TypeError('Hash mismatch (input)');
|
|
540
|
+
}
|
|
210
541
|
}
|
|
211
542
|
}
|
|
212
543
|
|
|
213
|
-
|
|
544
|
+
/**
|
|
545
|
+
* Converts to a plain P2PKHPayment object for backwards compatibility.
|
|
546
|
+
*
|
|
547
|
+
* @returns A P2PKHPayment object
|
|
548
|
+
*/
|
|
549
|
+
toPayment(): P2PKHPayment {
|
|
550
|
+
return {
|
|
551
|
+
name: this.name,
|
|
552
|
+
network: this.network,
|
|
553
|
+
address: this.address,
|
|
554
|
+
hash: this.hash,
|
|
555
|
+
pubkey: this.pubkey,
|
|
556
|
+
signature: this.signature,
|
|
557
|
+
output: this.output,
|
|
558
|
+
input: this.input,
|
|
559
|
+
witness: this.witness,
|
|
560
|
+
};
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
/**
|
|
565
|
+
* Creates a Pay-to-Public-Key-Hash (P2PKH) payment object.
|
|
566
|
+
*
|
|
567
|
+
* This is the legacy factory function for backwards compatibility.
|
|
568
|
+
* For new code, prefer using the P2PKH class directly.
|
|
569
|
+
*
|
|
570
|
+
* @param a - The payment object containing the necessary data
|
|
571
|
+
* @param opts - Optional payment options
|
|
572
|
+
* @returns The P2PKH payment object
|
|
573
|
+
* @throws {TypeError} If the required data is not provided or if the data is invalid
|
|
574
|
+
*
|
|
575
|
+
* @example
|
|
576
|
+
* ```typescript
|
|
577
|
+
* import { p2pkh } from '@btc-vision/bitcoin';
|
|
578
|
+
*
|
|
579
|
+
* // Create from public key
|
|
580
|
+
* const payment = p2pkh({ pubkey });
|
|
581
|
+
*
|
|
582
|
+
* // Create from address
|
|
583
|
+
* const fromAddr = p2pkh({ address: '1BvBMSEYstWetqTFn5Au4m4GFg7xJaNVN2' });
|
|
584
|
+
* ```
|
|
585
|
+
*/
|
|
586
|
+
export function p2pkh(a: Omit<P2PKHPayment, 'name'>, opts?: PaymentOpts): P2PKHPayment {
|
|
587
|
+
if (!a.address && !a.hash && !a.output && !a.pubkey && !a.input) {
|
|
588
|
+
throw new TypeError('Not enough data');
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
const instance = new P2PKH(
|
|
592
|
+
{
|
|
593
|
+
address: a.address,
|
|
594
|
+
hash: a.hash,
|
|
595
|
+
pubkey: a.pubkey,
|
|
596
|
+
signature: a.signature,
|
|
597
|
+
output: a.output,
|
|
598
|
+
input: a.input,
|
|
599
|
+
network: a.network,
|
|
600
|
+
useHybrid: a.useHybrid,
|
|
601
|
+
useUncompressed: a.useUncompressed,
|
|
602
|
+
},
|
|
603
|
+
opts,
|
|
604
|
+
);
|
|
605
|
+
|
|
606
|
+
// Return a merged object for backwards compatibility
|
|
607
|
+
return Object.assign(instance.toPayment(), a);
|
|
214
608
|
}
|