@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/p2pkh.ts
CHANGED
|
@@ -1,108 +1,439 @@
|
|
|
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 { type Bytes20, isPoint, type PublicKey, type Script, type Signature } from '../types.js';
|
|
17
|
+
import { alloc, equals } from '../io/index.js';
|
|
18
|
+
import { type P2PKHPayment, type PaymentOpts, PaymentType } 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
|
+
/**
|
|
307
|
+
* Converts to a plain P2PKHPayment object for backwards compatibility.
|
|
308
|
+
*
|
|
309
|
+
* @returns A P2PKHPayment object
|
|
310
|
+
*/
|
|
311
|
+
toPayment(): P2PKHPayment {
|
|
312
|
+
return {
|
|
313
|
+
name: this.name,
|
|
314
|
+
network: this.network,
|
|
315
|
+
address: this.address,
|
|
316
|
+
hash: this.hash,
|
|
317
|
+
pubkey: this.pubkey,
|
|
318
|
+
signature: this.signature,
|
|
319
|
+
output: this.output,
|
|
320
|
+
input: this.input,
|
|
321
|
+
witness: this.witness,
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
#getDecodedAddress(): { version: number; hash: Uint8Array } | undefined {
|
|
326
|
+
if (!this.#decodedAddressComputed) {
|
|
327
|
+
if (this.#inputAddress) {
|
|
328
|
+
const payload = new Uint8Array(bs58check.default.decode(this.#inputAddress));
|
|
329
|
+
this.#decodedAddress = {
|
|
330
|
+
version: payload[0]!,
|
|
331
|
+
hash: payload.subarray(1),
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
this.#decodedAddressComputed = true;
|
|
335
|
+
}
|
|
336
|
+
return this.#decodedAddress;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
// Private computation methods
|
|
340
|
+
|
|
341
|
+
#getInputChunks(): (Uint8Array | number)[] | undefined {
|
|
342
|
+
if (!this.#inputChunksComputed) {
|
|
343
|
+
if (this.#inputInput) {
|
|
344
|
+
this.#inputChunks = bscript.decompile(this.#inputInput) ?? undefined;
|
|
345
|
+
}
|
|
346
|
+
this.#inputChunksComputed = true;
|
|
347
|
+
}
|
|
348
|
+
return this.#inputChunks;
|
|
349
|
+
}
|
|
42
350
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
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);
|
|
351
|
+
#computeAddress(): string | undefined {
|
|
352
|
+
if (this.#inputAddress) {
|
|
353
|
+
return this.#inputAddress;
|
|
354
|
+
}
|
|
355
|
+
const h = this.hash;
|
|
356
|
+
if (!h) return undefined;
|
|
357
|
+
|
|
358
|
+
const payload = alloc(21);
|
|
359
|
+
payload[0] = this.#network.pubKeyHash;
|
|
360
|
+
payload.set(h, 1);
|
|
67
361
|
return bs58check.default.encode(payload);
|
|
68
|
-
}
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
#computeHash(): Bytes20 | undefined {
|
|
365
|
+
if (this.#inputHash) {
|
|
366
|
+
return this.#inputHash as Bytes20;
|
|
367
|
+
}
|
|
368
|
+
if (this.#inputOutput) {
|
|
369
|
+
return this.#inputOutput.subarray(3, 23) as Bytes20;
|
|
370
|
+
}
|
|
371
|
+
if (this.#inputAddress) {
|
|
372
|
+
return this.#getDecodedAddress()?.hash as Bytes20 | undefined;
|
|
373
|
+
}
|
|
374
|
+
// Use the pubkey getter to derive pubkey from input if available
|
|
375
|
+
const pk = this.pubkey;
|
|
376
|
+
if (pk) {
|
|
377
|
+
return bcrypto.hash160(pk) as Bytes20;
|
|
378
|
+
}
|
|
379
|
+
return undefined;
|
|
380
|
+
}
|
|
69
381
|
|
|
70
|
-
|
|
71
|
-
if (
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
382
|
+
#computePubkey(): PublicKey | undefined {
|
|
383
|
+
if (this.#inputPubkey) {
|
|
384
|
+
return this.#inputPubkey as PublicKey;
|
|
385
|
+
}
|
|
386
|
+
if (this.#inputInput) {
|
|
387
|
+
const chunks = this.#getInputChunks();
|
|
388
|
+
if (chunks && chunks.length >= 2) {
|
|
389
|
+
return chunks[1] as PublicKey;
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
return undefined;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
#computeSignature(): Signature | undefined {
|
|
396
|
+
if (this.#inputSignature) {
|
|
397
|
+
return this.#inputSignature as Signature;
|
|
398
|
+
}
|
|
399
|
+
if (this.#inputInput) {
|
|
400
|
+
const chunks = this.#getInputChunks();
|
|
401
|
+
if (chunks && chunks.length >= 1) {
|
|
402
|
+
return chunks[0] as Signature;
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
return undefined;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
#computeOutput(): Script | undefined {
|
|
409
|
+
if (this.#inputOutput) {
|
|
410
|
+
return this.#inputOutput as Script;
|
|
411
|
+
}
|
|
412
|
+
const h = this.hash;
|
|
413
|
+
if (!h) return undefined;
|
|
75
414
|
|
|
76
|
-
lazy.prop(o, 'output', () => {
|
|
77
|
-
if (!o.hash) return;
|
|
78
415
|
return bscript.compile([
|
|
79
416
|
OPS.OP_DUP,
|
|
80
417
|
OPS.OP_HASH160,
|
|
81
|
-
|
|
418
|
+
h,
|
|
82
419
|
OPS.OP_EQUALVERIFY,
|
|
83
420
|
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);
|
|
421
|
+
]) as Script;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
#computeInput(): Script | undefined {
|
|
425
|
+
if (this.#inputInput) {
|
|
426
|
+
return this.#inputInput as Script;
|
|
427
|
+
}
|
|
428
|
+
if (!this.#inputPubkey || !this.#inputSignature) {
|
|
429
|
+
return undefined;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
let pubKey: Uint8Array = this.#inputPubkey;
|
|
433
|
+
if (this.#useHybrid || this.#useUncompressed) {
|
|
434
|
+
const decompressed = decompressPublicKey(this.#inputPubkey as PublicKey);
|
|
104
435
|
if (decompressed) {
|
|
105
|
-
if (
|
|
436
|
+
if (this.#useUncompressed) {
|
|
106
437
|
pubKey = decompressed.uncompressed;
|
|
107
438
|
} else {
|
|
108
439
|
pubKey = decompressed.hybrid;
|
|
@@ -110,77 +441,87 @@ export function p2pkh(a: Omit<P2PKHPayment, 'name'>, opts?: PaymentOpts): P2PKHP
|
|
|
110
441
|
}
|
|
111
442
|
}
|
|
112
443
|
|
|
113
|
-
return bscript.compile([
|
|
114
|
-
}
|
|
444
|
+
return bscript.compile([this.#inputSignature, pubKey]) as Script;
|
|
445
|
+
}
|
|
115
446
|
|
|
116
|
-
|
|
117
|
-
if (!o.input) return;
|
|
118
|
-
return [];
|
|
119
|
-
});
|
|
447
|
+
// Validation
|
|
120
448
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
449
|
+
#computeWitness(): Uint8Array[] | undefined {
|
|
450
|
+
if (this.input) {
|
|
451
|
+
return [];
|
|
452
|
+
}
|
|
453
|
+
return undefined;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
#validate(): void {
|
|
457
|
+
let hash: Uint8Array = new Uint8Array(0);
|
|
458
|
+
|
|
459
|
+
if (this.#inputAddress) {
|
|
460
|
+
const addr = this.#getDecodedAddress();
|
|
461
|
+
if (!addr) {
|
|
462
|
+
throw new TypeError('Invalid address');
|
|
463
|
+
}
|
|
464
|
+
if (addr.version !== this.#network.pubKeyHash) {
|
|
126
465
|
throw new TypeError('Invalid version or Network mismatch');
|
|
127
466
|
}
|
|
128
|
-
|
|
129
|
-
if (_address().hash.length !== 20) {
|
|
467
|
+
if (addr.hash.length !== 20) {
|
|
130
468
|
throw new TypeError('Invalid address');
|
|
131
469
|
}
|
|
132
|
-
|
|
133
|
-
hash = _address().hash;
|
|
470
|
+
hash = addr.hash;
|
|
134
471
|
}
|
|
135
472
|
|
|
136
|
-
if (
|
|
137
|
-
if (hash.length > 0 && !
|
|
473
|
+
if (this.#inputHash) {
|
|
474
|
+
if (hash.length > 0 && !equals(hash, this.#inputHash)) {
|
|
138
475
|
throw new TypeError('Hash mismatch');
|
|
139
476
|
} else {
|
|
140
|
-
hash =
|
|
477
|
+
hash = this.#inputHash;
|
|
141
478
|
}
|
|
142
479
|
}
|
|
143
480
|
|
|
144
|
-
if (
|
|
481
|
+
if (this.#inputOutput) {
|
|
145
482
|
if (
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
483
|
+
this.#inputOutput.length !== 25 ||
|
|
484
|
+
this.#inputOutput[0] !== OPS.OP_DUP ||
|
|
485
|
+
this.#inputOutput[1] !== OPS.OP_HASH160 ||
|
|
486
|
+
this.#inputOutput[2] !== 0x14 ||
|
|
487
|
+
this.#inputOutput[23] !== OPS.OP_EQUALVERIFY ||
|
|
488
|
+
this.#inputOutput[24] !== OPS.OP_CHECKSIG
|
|
152
489
|
) {
|
|
153
490
|
throw new TypeError('Output is invalid');
|
|
154
491
|
}
|
|
155
492
|
|
|
156
|
-
const hash2 =
|
|
157
|
-
if (hash.length > 0 && !
|
|
158
|
-
|
|
493
|
+
const hash2 = this.#inputOutput.subarray(3, 23);
|
|
494
|
+
if (hash.length > 0 && !equals(hash, hash2)) {
|
|
495
|
+
throw new TypeError('Hash mismatch');
|
|
496
|
+
} else {
|
|
497
|
+
hash = hash2;
|
|
498
|
+
}
|
|
159
499
|
}
|
|
160
500
|
|
|
161
|
-
if (
|
|
162
|
-
const pkh = bcrypto.hash160(
|
|
501
|
+
if (this.#inputPubkey) {
|
|
502
|
+
const pkh = bcrypto.hash160(this.#inputPubkey);
|
|
163
503
|
|
|
164
|
-
let badHash = hash.length > 0 && !
|
|
504
|
+
let badHash = hash.length > 0 && !equals(hash, pkh);
|
|
165
505
|
if (badHash) {
|
|
166
506
|
if (
|
|
167
|
-
(
|
|
168
|
-
|
|
507
|
+
(this.#inputPubkey.length === 33 &&
|
|
508
|
+
(this.#inputPubkey[0] === 0x02 || this.#inputPubkey[0] === 0x03)) ||
|
|
509
|
+
(this.#inputPubkey.length === 65 && this.#inputPubkey[0] === 0x04)
|
|
169
510
|
) {
|
|
170
|
-
const uncompressed = decompressPublicKey(
|
|
511
|
+
const uncompressed = decompressPublicKey(this.#inputPubkey as PublicKey);
|
|
171
512
|
if (uncompressed) {
|
|
172
513
|
const pkh2 = bcrypto.hash160(uncompressed.uncompressed);
|
|
173
514
|
|
|
174
|
-
if (!
|
|
515
|
+
if (!equals(hash, pkh2)) {
|
|
175
516
|
const pkh3 = bcrypto.hash160(uncompressed.hybrid);
|
|
176
|
-
badHash = !
|
|
517
|
+
badHash = !equals(hash, pkh3);
|
|
177
518
|
|
|
178
519
|
if (!badHash) {
|
|
179
|
-
|
|
520
|
+
this.#useHybrid = true;
|
|
180
521
|
}
|
|
181
522
|
} else {
|
|
182
523
|
badHash = false;
|
|
183
|
-
|
|
524
|
+
this.#useUncompressed = true;
|
|
184
525
|
}
|
|
185
526
|
}
|
|
186
527
|
}
|
|
@@ -193,22 +534,75 @@ export function p2pkh(a: Omit<P2PKHPayment, 'name'>, opts?: PaymentOpts): P2PKHP
|
|
|
193
534
|
}
|
|
194
535
|
}
|
|
195
536
|
|
|
196
|
-
if (
|
|
197
|
-
const chunks =
|
|
198
|
-
if (chunks.length !== 2)
|
|
199
|
-
|
|
537
|
+
if (this.#inputInput) {
|
|
538
|
+
const chunks = this.#getInputChunks();
|
|
539
|
+
if (!chunks || chunks.length !== 2) {
|
|
540
|
+
throw new TypeError('Input is invalid');
|
|
541
|
+
}
|
|
542
|
+
if (!bscript.isCanonicalScriptSignature(chunks[0] as Uint8Array)) {
|
|
200
543
|
throw new TypeError('Input has invalid signature');
|
|
201
|
-
|
|
544
|
+
}
|
|
545
|
+
if (!isPoint(chunks[1])) {
|
|
546
|
+
throw new TypeError('Input has invalid pubkey');
|
|
547
|
+
}
|
|
202
548
|
|
|
203
|
-
if (
|
|
549
|
+
if (this.#inputSignature && !equals(this.#inputSignature, chunks[0] as Uint8Array)) {
|
|
204
550
|
throw new TypeError('Signature mismatch');
|
|
205
|
-
|
|
551
|
+
}
|
|
552
|
+
if (this.#inputPubkey && !equals(this.#inputPubkey, chunks[1] as Uint8Array)) {
|
|
206
553
|
throw new TypeError('Pubkey mismatch');
|
|
554
|
+
}
|
|
207
555
|
|
|
208
|
-
const pkh = bcrypto.hash160(chunks[1] as
|
|
209
|
-
if (hash.length > 0 && !
|
|
556
|
+
const pkh = bcrypto.hash160(chunks[1] as Uint8Array);
|
|
557
|
+
if (hash.length > 0 && !equals(hash, pkh)) {
|
|
558
|
+
throw new TypeError('Hash mismatch (input)');
|
|
559
|
+
}
|
|
210
560
|
}
|
|
211
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
|
+
);
|
|
212
605
|
|
|
213
|
-
|
|
606
|
+
// Return a merged object for backwards compatibility
|
|
607
|
+
return Object.assign(instance.toPayment(), a);
|
|
214
608
|
}
|