@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/pubkey.ts
CHANGED
|
@@ -2,33 +2,34 @@
|
|
|
2
2
|
* Public key utilities for Bitcoin
|
|
3
3
|
* @packageDocumentation
|
|
4
4
|
*/
|
|
5
|
-
import {
|
|
5
|
+
import { Point } from '@noble/secp256k1';
|
|
6
|
+
import { alloc, concat, equals, fromHex, toHex } from './io/index.js';
|
|
7
|
+
import type { PublicKey, XOnlyPublicKey } from './types.js';
|
|
6
8
|
|
|
7
9
|
/**
|
|
8
10
|
* Converts a public key to x-only format (32 bytes).
|
|
9
11
|
* @param pubKey - The public key buffer (33 or 65 bytes)
|
|
10
12
|
* @returns The x-only public key (32 bytes)
|
|
11
13
|
*/
|
|
12
|
-
export const toXOnly = (pubKey:
|
|
13
|
-
|
|
14
|
-
return Buffer.isBuffer(buffer) ? buffer : Buffer.from(buffer);
|
|
14
|
+
export const toXOnly = (pubKey: PublicKey | XOnlyPublicKey): XOnlyPublicKey => {
|
|
15
|
+
return (pubKey.length === 32 ? pubKey : pubKey.subarray(1, 33)) as XOnlyPublicKey;
|
|
15
16
|
};
|
|
16
17
|
|
|
17
18
|
export interface UncompressedPublicKey {
|
|
18
|
-
hybrid:
|
|
19
|
-
uncompressed:
|
|
19
|
+
hybrid: Uint8Array;
|
|
20
|
+
uncompressed: Uint8Array;
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
/**
|
|
23
|
-
* Converts bigint to 32-byte
|
|
24
|
+
* Converts bigint to 32-byte Uint8Array.
|
|
24
25
|
*/
|
|
25
|
-
export function bigIntTo32Bytes(num: bigint):
|
|
26
|
+
export function bigIntTo32Bytes(num: bigint): Uint8Array {
|
|
26
27
|
let hex = num.toString(16);
|
|
27
28
|
hex = hex.padStart(64, '0');
|
|
28
29
|
if (hex.length > 64) {
|
|
29
30
|
hex = hex.slice(-64);
|
|
30
31
|
}
|
|
31
|
-
return
|
|
32
|
+
return fromHex(hex);
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
/**
|
|
@@ -36,11 +37,9 @@ export function bigIntTo32Bytes(num: bigint): Buffer {
|
|
|
36
37
|
* to its "hybrid" form (prefix 0x06/0x07), then derives a P2PKH address from it.
|
|
37
38
|
*
|
|
38
39
|
* @param realPubKey - 33-byte compressed (0x02/0x03) or 65-byte uncompressed (0x04) pubkey
|
|
39
|
-
* @returns
|
|
40
|
+
* @returns UncompressedPublicKey | undefined
|
|
40
41
|
*/
|
|
41
|
-
export function decompressPublicKey(
|
|
42
|
-
realPubKey: Uint8Array | Buffer,
|
|
43
|
-
): UncompressedPublicKey | undefined {
|
|
42
|
+
export function decompressPublicKey(realPubKey: PublicKey): UncompressedPublicKey | undefined {
|
|
44
43
|
if (realPubKey.length === 32) {
|
|
45
44
|
return;
|
|
46
45
|
}
|
|
@@ -52,9 +51,9 @@ export function decompressPublicKey(
|
|
|
52
51
|
return;
|
|
53
52
|
}
|
|
54
53
|
|
|
55
|
-
let point:
|
|
54
|
+
let point: Point;
|
|
56
55
|
try {
|
|
57
|
-
point =
|
|
56
|
+
point = Point.fromHex(toHex(realPubKey));
|
|
58
57
|
} catch (err) {
|
|
59
58
|
throw new Error('Invalid secp256k1 public key bytes. Cannot parse.');
|
|
60
59
|
}
|
|
@@ -65,12 +64,12 @@ export function decompressPublicKey(
|
|
|
65
64
|
const isEven = point.y % 2n === 0n;
|
|
66
65
|
const prefix = isEven ? 0x06 : 0x07;
|
|
67
66
|
|
|
68
|
-
const hybridPubKey =
|
|
67
|
+
const hybridPubKey = alloc(65);
|
|
69
68
|
hybridPubKey[0] = prefix;
|
|
70
|
-
|
|
71
|
-
|
|
69
|
+
hybridPubKey.set(xBuf, 1);
|
|
70
|
+
hybridPubKey.set(yBuf, 33);
|
|
72
71
|
|
|
73
|
-
const uncompressedPubKey =
|
|
72
|
+
const uncompressedPubKey = concat([new Uint8Array([0x04]), xBuf, yBuf]);
|
|
74
73
|
|
|
75
74
|
return {
|
|
76
75
|
hybrid: hybridPubKey,
|
|
@@ -79,20 +78,20 @@ export function decompressPublicKey(
|
|
|
79
78
|
}
|
|
80
79
|
|
|
81
80
|
/**
|
|
82
|
-
* Compare two potential pubkey
|
|
81
|
+
* Compare two potential pubkey Uint8Arrays, treating hybrid keys (0x06/0x07)
|
|
83
82
|
* as equivalent to uncompressed (0x04).
|
|
84
83
|
*/
|
|
85
|
-
export function pubkeysMatch(a:
|
|
86
|
-
if (
|
|
84
|
+
export function pubkeysMatch(a: Uint8Array, b: Uint8Array): boolean {
|
|
85
|
+
if (equals(a, b)) return true;
|
|
87
86
|
|
|
88
87
|
if (a.length === 65 && b.length === 65) {
|
|
89
|
-
const aCopy =
|
|
90
|
-
const bCopy =
|
|
88
|
+
const aCopy = new Uint8Array(a);
|
|
89
|
+
const bCopy = new Uint8Array(b);
|
|
91
90
|
|
|
92
91
|
if (aCopy[0] === 0x06 || aCopy[0] === 0x07) aCopy[0] = 0x04;
|
|
93
92
|
if (bCopy[0] === 0x06 || bCopy[0] === 0x07) bCopy[0] = 0x04;
|
|
94
93
|
|
|
95
|
-
return
|
|
94
|
+
return equals(aCopy, bCopy);
|
|
96
95
|
}
|
|
97
96
|
|
|
98
97
|
return false;
|
package/src/push_data.ts
CHANGED
|
@@ -19,27 +19,28 @@ export function encodingLength(i: number): number {
|
|
|
19
19
|
* @param offset - The offset at which to start writing the encoded buffer.
|
|
20
20
|
* @returns The size of the encoded buffer.
|
|
21
21
|
*/
|
|
22
|
-
export function encode(buffer:
|
|
22
|
+
export function encode(buffer: Uint8Array, num: number, offset: number): number {
|
|
23
23
|
const size = encodingLength(num);
|
|
24
|
+
const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
|
|
24
25
|
|
|
25
26
|
// ~6 bit
|
|
26
27
|
if (size === 1) {
|
|
27
|
-
buffer
|
|
28
|
+
buffer[offset] = num;
|
|
28
29
|
|
|
29
30
|
// 8 bit
|
|
30
31
|
} else if (size === 2) {
|
|
31
|
-
buffer
|
|
32
|
-
buffer
|
|
32
|
+
buffer[offset] = opcodes.OP_PUSHDATA1;
|
|
33
|
+
buffer[offset + 1] = num;
|
|
33
34
|
|
|
34
35
|
// 16 bit
|
|
35
36
|
} else if (size === 3) {
|
|
36
|
-
buffer
|
|
37
|
-
|
|
37
|
+
buffer[offset] = opcodes.OP_PUSHDATA2;
|
|
38
|
+
view.setUint16(offset + 1, num, true);
|
|
38
39
|
|
|
39
40
|
// 32 bit
|
|
40
41
|
} else {
|
|
41
|
-
buffer
|
|
42
|
-
|
|
42
|
+
buffer[offset] = opcodes.OP_PUSHDATA4;
|
|
43
|
+
view.setUint32(offset + 1, num, true);
|
|
43
44
|
}
|
|
44
45
|
|
|
45
46
|
return size;
|
|
@@ -52,32 +53,33 @@ export function encode(buffer: Buffer, num: number, offset: number): number {
|
|
|
52
53
|
* @returns An object containing the opcode, number, and size, or null if decoding fails.
|
|
53
54
|
*/
|
|
54
55
|
export function decode(
|
|
55
|
-
buffer:
|
|
56
|
+
buffer: Uint8Array,
|
|
56
57
|
offset: number,
|
|
57
58
|
): {
|
|
58
59
|
opcode: number;
|
|
59
60
|
number: number;
|
|
60
61
|
size: number;
|
|
61
62
|
} | null {
|
|
62
|
-
const
|
|
63
|
+
const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
|
|
64
|
+
const opcode = buffer[offset];
|
|
63
65
|
let num: number;
|
|
64
66
|
let size: number;
|
|
65
67
|
|
|
66
68
|
// ~6 bit
|
|
67
|
-
if (opcode < opcodes.OP_PUSHDATA1) {
|
|
68
|
-
num = opcode
|
|
69
|
+
if (opcode! < opcodes.OP_PUSHDATA1) {
|
|
70
|
+
num = opcode!;
|
|
69
71
|
size = 1;
|
|
70
72
|
|
|
71
73
|
// 8 bit
|
|
72
74
|
} else if (opcode === opcodes.OP_PUSHDATA1) {
|
|
73
75
|
if (offset + 2 > buffer.length) return null;
|
|
74
|
-
num = buffer
|
|
76
|
+
num = buffer[offset + 1]!;
|
|
75
77
|
size = 2;
|
|
76
78
|
|
|
77
79
|
// 16 bit
|
|
78
80
|
} else if (opcode === opcodes.OP_PUSHDATA2) {
|
|
79
81
|
if (offset + 3 > buffer.length) return null;
|
|
80
|
-
num =
|
|
82
|
+
num = view.getUint16(offset + 1, true);
|
|
81
83
|
size = 3;
|
|
82
84
|
|
|
83
85
|
// 32 bit
|
|
@@ -85,12 +87,12 @@ export function decode(
|
|
|
85
87
|
if (offset + 5 > buffer.length) return null;
|
|
86
88
|
if (opcode !== opcodes.OP_PUSHDATA4) throw new Error('Unexpected opcode');
|
|
87
89
|
|
|
88
|
-
num =
|
|
90
|
+
num = view.getUint32(offset + 1, true);
|
|
89
91
|
size = 5;
|
|
90
92
|
}
|
|
91
93
|
|
|
92
94
|
return {
|
|
93
|
-
opcode
|
|
95
|
+
opcode: opcode!,
|
|
94
96
|
number: num,
|
|
95
97
|
size,
|
|
96
98
|
};
|
package/src/script.ts
CHANGED
|
@@ -3,74 +3,78 @@
|
|
|
3
3
|
* @packageDocumentation
|
|
4
4
|
*/
|
|
5
5
|
import * as bip66 from './bip66.js';
|
|
6
|
-
import {
|
|
6
|
+
import { toHex, fromHex, alloc } from './io/index.js';
|
|
7
|
+
import type { Opcodes } from './opcodes.js';
|
|
8
|
+
import { opcodes, REVERSE_OPS } from './opcodes.js';
|
|
7
9
|
import * as pushdata from './push_data.js';
|
|
8
10
|
import * as scriptNumber from './script_number.js';
|
|
9
11
|
import * as scriptSignature from './script_signature.js';
|
|
10
12
|
import * as types from './types.js';
|
|
11
|
-
import type { Stack } from './types.js';
|
|
12
|
-
|
|
13
|
-
const { typeforce } = types;
|
|
13
|
+
import type { Script, Stack } from './types.js';
|
|
14
14
|
|
|
15
15
|
const OP_INT_BASE = opcodes.OP_RESERVED; // OP_1 - 1
|
|
16
16
|
export { opcodes };
|
|
17
17
|
|
|
18
18
|
function isOPInt(value: number): boolean {
|
|
19
19
|
return (
|
|
20
|
-
types.
|
|
20
|
+
types.isNumber(value) &&
|
|
21
21
|
(value === opcodes.OP_0 ||
|
|
22
22
|
(value >= opcodes.OP_1 && value <= opcodes.OP_16) ||
|
|
23
23
|
value === opcodes.OP_1NEGATE)
|
|
24
24
|
);
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
function isPushOnlyChunk(value: number |
|
|
28
|
-
|
|
27
|
+
function isPushOnlyChunk(value: number | Uint8Array): boolean {
|
|
28
|
+
if (value instanceof Uint8Array) return true;
|
|
29
|
+
return isOPInt(value);
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
export function isPushOnly(value: Stack): boolean {
|
|
32
|
-
return types.
|
|
33
|
+
return types.isArray(value) && value.every(isPushOnlyChunk);
|
|
33
34
|
}
|
|
34
35
|
|
|
35
36
|
export function countNonPushOnlyOPs(value: Stack): number {
|
|
36
37
|
return value.length - value.filter(isPushOnlyChunk).length;
|
|
37
38
|
}
|
|
38
39
|
|
|
39
|
-
function asMinimalOP(buffer:
|
|
40
|
+
function asMinimalOP(buffer: Uint8Array): number | undefined {
|
|
40
41
|
if (buffer.length === 0) return opcodes.OP_0;
|
|
41
|
-
if (buffer.length !== 1) return;
|
|
42
|
-
if (buffer[0] >= 1 && buffer[0] <= 16) return OP_INT_BASE + buffer[0]
|
|
42
|
+
if (buffer.length !== 1) return undefined;
|
|
43
|
+
if (buffer[0]! >= 1 && buffer[0]! <= 16) return OP_INT_BASE + buffer[0]!;
|
|
43
44
|
if (buffer[0] === 0x81) return opcodes.OP_1NEGATE;
|
|
45
|
+
return undefined;
|
|
44
46
|
}
|
|
45
47
|
|
|
46
|
-
function
|
|
47
|
-
return
|
|
48
|
+
function chunksIsUint8Array(buf: Uint8Array | Stack): buf is Uint8Array {
|
|
49
|
+
return buf instanceof Uint8Array;
|
|
48
50
|
}
|
|
49
51
|
|
|
50
|
-
function chunksIsArray(buf:
|
|
51
|
-
return types.
|
|
52
|
+
function chunksIsArray(buf: Uint8Array | Stack): buf is Stack {
|
|
53
|
+
return types.isArray(buf);
|
|
52
54
|
}
|
|
53
55
|
|
|
54
|
-
function
|
|
55
|
-
return
|
|
56
|
+
function singleChunkIsUint8Array(buf: number | Uint8Array): buf is Uint8Array {
|
|
57
|
+
return buf instanceof Uint8Array;
|
|
56
58
|
}
|
|
57
59
|
|
|
58
60
|
/**
|
|
59
|
-
* Compiles an array of chunks into a
|
|
61
|
+
* Compiles an array of chunks into a Uint8Array.
|
|
60
62
|
*
|
|
61
63
|
* @param chunks - The array of chunks to compile.
|
|
62
|
-
* @returns The compiled
|
|
64
|
+
* @returns The compiled Uint8Array.
|
|
63
65
|
* @throws Error if the compilation fails.
|
|
64
66
|
*/
|
|
65
|
-
export function compile(chunks:
|
|
66
|
-
//
|
|
67
|
-
if (
|
|
67
|
+
export function compile(chunks: Uint8Array | Stack): Script {
|
|
68
|
+
// Already compiled - return as-is
|
|
69
|
+
if (chunksIsUint8Array(chunks)) return chunks as Script;
|
|
68
70
|
|
|
69
|
-
|
|
71
|
+
if (!types.isArray(chunks)) {
|
|
72
|
+
throw new TypeError('Expected an array');
|
|
73
|
+
}
|
|
70
74
|
|
|
71
75
|
const bufferSize = chunks.reduce((accum: number, chunk) => {
|
|
72
76
|
// data chunk
|
|
73
|
-
if (
|
|
77
|
+
if (singleChunkIsUint8Array(chunk)) {
|
|
74
78
|
// adhere to BIP62.3, minimal push policy
|
|
75
79
|
if (chunk.length === 1 && asMinimalOP(chunk) !== undefined) {
|
|
76
80
|
return accum + 1;
|
|
@@ -83,46 +87,50 @@ export function compile(chunks: Buffer | Stack): Buffer {
|
|
|
83
87
|
return accum + 1;
|
|
84
88
|
}, 0.0);
|
|
85
89
|
|
|
86
|
-
const buffer =
|
|
90
|
+
const buffer = new Uint8Array(bufferSize);
|
|
87
91
|
let offset = 0;
|
|
88
92
|
|
|
89
93
|
chunks.forEach((chunk) => {
|
|
90
94
|
// data chunk
|
|
91
|
-
if (
|
|
95
|
+
if (singleChunkIsUint8Array(chunk)) {
|
|
92
96
|
// adhere to BIP62.3, minimal push policy
|
|
93
97
|
const opcode = asMinimalOP(chunk);
|
|
94
98
|
if (opcode !== undefined) {
|
|
95
|
-
buffer
|
|
99
|
+
buffer[offset] = opcode;
|
|
96
100
|
offset += 1;
|
|
97
101
|
return;
|
|
98
102
|
}
|
|
99
103
|
|
|
100
104
|
offset += pushdata.encode(buffer, chunk.length, offset);
|
|
101
|
-
|
|
105
|
+
buffer.set(chunk, offset);
|
|
102
106
|
offset += chunk.length;
|
|
103
107
|
|
|
104
108
|
// opcode
|
|
105
109
|
} else {
|
|
106
|
-
buffer
|
|
110
|
+
buffer[offset] = chunk;
|
|
107
111
|
offset += 1;
|
|
108
112
|
}
|
|
109
113
|
});
|
|
110
114
|
|
|
111
115
|
if (offset !== buffer.length) throw new Error('Could not decode chunks');
|
|
112
|
-
return buffer;
|
|
116
|
+
return buffer as Script;
|
|
113
117
|
}
|
|
114
118
|
|
|
115
|
-
export function decompile(
|
|
116
|
-
|
|
117
|
-
|
|
119
|
+
export function decompile(
|
|
120
|
+
buffer: Uint8Array | Stack,
|
|
121
|
+
): Array<number | Uint8Array> | null {
|
|
122
|
+
// Already decompiled - return as-is
|
|
123
|
+
if (chunksIsArray(buffer)) return buffer as Array<number | Uint8Array>;
|
|
118
124
|
|
|
119
|
-
|
|
125
|
+
if (!(buffer instanceof Uint8Array)) {
|
|
126
|
+
throw new TypeError('Expected a Uint8Array');
|
|
127
|
+
}
|
|
120
128
|
|
|
121
|
-
const chunks: Array<number |
|
|
129
|
+
const chunks: Array<number | Uint8Array> = [];
|
|
122
130
|
let i = 0;
|
|
123
131
|
|
|
124
132
|
while (i < buffer.length) {
|
|
125
|
-
const opcode = buffer[i]
|
|
133
|
+
const opcode = buffer[i]!;
|
|
126
134
|
|
|
127
135
|
// data chunk
|
|
128
136
|
if (opcode > opcodes.OP_0 && opcode <= opcodes.OP_PUSHDATA4) {
|
|
@@ -159,23 +167,27 @@ export function decompile(buffer: Buffer | Array<number | Buffer>): Array<number
|
|
|
159
167
|
|
|
160
168
|
/**
|
|
161
169
|
* Converts the given chunks into an ASM (Assembly) string representation.
|
|
162
|
-
* If the chunks parameter is a
|
|
170
|
+
* If the chunks parameter is a Uint8Array, it will be decompiled into a Stack before conversion.
|
|
163
171
|
* @param chunks - The chunks to convert into ASM.
|
|
164
172
|
* @returns The ASM string representation of the chunks.
|
|
165
173
|
*/
|
|
166
|
-
export function toASM(chunks:
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
174
|
+
export function toASM(chunks: Uint8Array | Stack): string {
|
|
175
|
+
let resolved: Stack;
|
|
176
|
+
if (chunksIsUint8Array(chunks)) {
|
|
177
|
+
const decompiled = decompile(chunks);
|
|
178
|
+
if (!decompiled) {
|
|
179
|
+
throw new Error('Could not convert invalid chunks to ASM');
|
|
180
|
+
}
|
|
181
|
+
resolved = decompiled;
|
|
182
|
+
} else {
|
|
183
|
+
resolved = chunks;
|
|
172
184
|
}
|
|
173
|
-
return
|
|
185
|
+
return resolved
|
|
174
186
|
.map((chunk) => {
|
|
175
187
|
// data?
|
|
176
|
-
if (
|
|
188
|
+
if (singleChunkIsUint8Array(chunk)) {
|
|
177
189
|
const op = asMinimalOP(chunk);
|
|
178
|
-
if (op === undefined) return chunk
|
|
190
|
+
if (op === undefined) return toHex(chunk);
|
|
179
191
|
chunk = op;
|
|
180
192
|
}
|
|
181
193
|
|
|
@@ -186,12 +198,14 @@ export function toASM(chunks: Buffer | Array<number | Buffer>): string {
|
|
|
186
198
|
}
|
|
187
199
|
|
|
188
200
|
/**
|
|
189
|
-
* Converts an ASM string to a
|
|
201
|
+
* Converts an ASM string to a Uint8Array.
|
|
190
202
|
* @param asm The ASM string to convert.
|
|
191
|
-
* @returns The converted
|
|
203
|
+
* @returns The converted Uint8Array.
|
|
192
204
|
*/
|
|
193
|
-
export function fromASM(asm: string):
|
|
194
|
-
|
|
205
|
+
export function fromASM(asm: string): Script {
|
|
206
|
+
if (typeof asm !== 'string') {
|
|
207
|
+
throw new TypeError('Expected a string');
|
|
208
|
+
}
|
|
195
209
|
|
|
196
210
|
return compile(
|
|
197
211
|
asm.split(' ').map((chunkStr) => {
|
|
@@ -199,41 +213,45 @@ export function fromASM(asm: string): Buffer {
|
|
|
199
213
|
if (opcodes[chunkStr as keyof Opcodes] !== undefined) {
|
|
200
214
|
return opcodes[chunkStr as keyof Opcodes];
|
|
201
215
|
}
|
|
202
|
-
|
|
216
|
+
if (!types.isHex(chunkStr)) {
|
|
217
|
+
throw new TypeError('Expected hex string');
|
|
218
|
+
}
|
|
203
219
|
|
|
204
220
|
// data!
|
|
205
|
-
return
|
|
221
|
+
return fromHex(chunkStr);
|
|
206
222
|
}),
|
|
207
223
|
);
|
|
208
224
|
}
|
|
209
225
|
|
|
210
226
|
/**
|
|
211
|
-
* Converts the given chunks into a stack of
|
|
227
|
+
* Converts the given chunks into a stack of Uint8Arrays.
|
|
212
228
|
*
|
|
213
229
|
* @param chunks - The chunks to convert.
|
|
214
|
-
* @returns The stack of
|
|
230
|
+
* @returns The stack of Uint8Arrays.
|
|
215
231
|
*/
|
|
216
|
-
export function toStack(chunks:
|
|
217
|
-
|
|
218
|
-
|
|
232
|
+
export function toStack(chunks: Uint8Array | Stack): Uint8Array[] {
|
|
233
|
+
const resolved = chunksIsUint8Array(chunks) ? decompile(chunks) : chunks;
|
|
234
|
+
if (!resolved || !isPushOnly(resolved)) {
|
|
235
|
+
throw new TypeError('Expected push-only script');
|
|
236
|
+
}
|
|
219
237
|
|
|
220
|
-
return
|
|
221
|
-
if (
|
|
222
|
-
if (op === opcodes.OP_0) return
|
|
238
|
+
return resolved.map((op) => {
|
|
239
|
+
if (singleChunkIsUint8Array(op)) return op;
|
|
240
|
+
if (op === opcodes.OP_0) return alloc(0);
|
|
223
241
|
|
|
224
242
|
return scriptNumber.encode(op - OP_INT_BASE);
|
|
225
243
|
});
|
|
226
244
|
}
|
|
227
245
|
|
|
228
|
-
export function isCanonicalPubKey(buffer:
|
|
246
|
+
export function isCanonicalPubKey(buffer: Uint8Array): boolean {
|
|
229
247
|
return types.isPoint(buffer);
|
|
230
248
|
}
|
|
231
249
|
|
|
232
250
|
import { isDefinedHashType } from './script_signature.js';
|
|
233
251
|
|
|
234
|
-
export function isCanonicalScriptSignature(buffer:
|
|
235
|
-
if (!
|
|
236
|
-
if (!isDefinedHashType(buffer[buffer.length - 1])) return false;
|
|
252
|
+
export function isCanonicalScriptSignature(buffer: Uint8Array): boolean {
|
|
253
|
+
if (!(buffer instanceof Uint8Array)) return false;
|
|
254
|
+
if (!isDefinedHashType(buffer[buffer.length - 1]!)) return false;
|
|
237
255
|
|
|
238
256
|
return bip66.check(buffer.subarray(0, -1));
|
|
239
257
|
}
|
package/src/script_number.ts
CHANGED
|
@@ -16,8 +16,8 @@ export function decode(buffer: Buffer, maxLength?: number, minimal?: boolean): n
|
|
|
16
16
|
if (length === 0) return 0;
|
|
17
17
|
if (length > maxLength) throw new TypeError('Script number overflow');
|
|
18
18
|
if (minimal) {
|
|
19
|
-
if ((buffer[length - 1] & 0x7f) === 0) {
|
|
20
|
-
if (length <= 1 || (buffer[length - 2] & 0x80) === 0)
|
|
19
|
+
if ((buffer[length - 1]! & 0x7f) === 0) {
|
|
20
|
+
if (length <= 1 || (buffer[length - 2]! & 0x80) === 0)
|
|
21
21
|
throw new Error('Non-minimally encoded script number');
|
|
22
22
|
}
|
|
23
23
|
}
|
|
@@ -34,10 +34,10 @@ export function decode(buffer: Buffer, maxLength?: number, minimal?: boolean): n
|
|
|
34
34
|
// 32-bit / 24-bit / 16-bit / 8-bit
|
|
35
35
|
let result = 0;
|
|
36
36
|
for (let i = 0; i < length; ++i) {
|
|
37
|
-
result |= buffer[i] << (8 * i);
|
|
37
|
+
result |= buffer[i]! << (8 * i);
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
if (buffer[length - 1] & 0x80) return -(result & ~(0x80 << (8 * (length - 1))));
|
|
40
|
+
if (buffer[length - 1]! & 0x80) return -(result & ~(0x80 << (8 * (length - 1))));
|
|
41
41
|
return result;
|
|
42
42
|
}
|
|
43
43
|
|
|
@@ -62,10 +62,10 @@ export function encode(_number: number): Buffer {
|
|
|
62
62
|
value >>= 8;
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
if (buffer[size - 1] & 0x80) {
|
|
65
|
+
if (buffer[size - 1]! & 0x80) {
|
|
66
66
|
buffer.writeUInt8(negative ? 0x80 : 0x00, size - 1);
|
|
67
67
|
} else if (negative) {
|
|
68
|
-
buffer[size - 1] |= 0x80;
|
|
68
|
+
buffer[size - 1]! |= 0x80;
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
return buffer;
|
package/src/script_signature.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import * as bip66 from './bip66.js';
|
|
2
|
-
import
|
|
2
|
+
import { alloc, concat } from './io/index.js';
|
|
3
|
+
import { isUInt8, isUint8ArrayN } from './types.js';
|
|
3
4
|
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
const ZERO = Buffer.alloc(1, 0);
|
|
5
|
+
const ZERO = new Uint8Array([0]);
|
|
7
6
|
|
|
8
7
|
/**
|
|
9
8
|
* Checks if a hash type is defined (valid for Bitcoin signatures).
|
|
@@ -16,48 +15,48 @@ export function isDefinedHashType(hashType: number): boolean {
|
|
|
16
15
|
}
|
|
17
16
|
|
|
18
17
|
/**
|
|
19
|
-
* Converts a
|
|
20
|
-
* @param x - The
|
|
21
|
-
* @returns The DER-encoded
|
|
18
|
+
* Converts a Uint8Array to a DER-encoded Uint8Array.
|
|
19
|
+
* @param x - The Uint8Array to be converted.
|
|
20
|
+
* @returns The DER-encoded Uint8Array.
|
|
22
21
|
*/
|
|
23
|
-
function toDER(x:
|
|
22
|
+
function toDER(x: Uint8Array): Uint8Array {
|
|
24
23
|
let i = 0;
|
|
25
24
|
while (x[i] === 0) ++i;
|
|
26
25
|
if (i === x.length) return ZERO;
|
|
27
26
|
x = x.subarray(i);
|
|
28
|
-
if (x[0] & 0x80) return
|
|
27
|
+
if (x[0]! & 0x80) return concat([ZERO, x]);
|
|
29
28
|
return x;
|
|
30
29
|
}
|
|
31
30
|
|
|
32
31
|
/**
|
|
33
|
-
* Converts a DER-encoded signature to a
|
|
34
|
-
* If the first byte of the input
|
|
35
|
-
* The resulting
|
|
32
|
+
* Converts a DER-encoded signature to a Uint8Array.
|
|
33
|
+
* If the first byte of the input is 0x00, it is skipped.
|
|
34
|
+
* The resulting Uint8Array is 32 bytes long, filled with zeros if necessary.
|
|
36
35
|
* @param x - The DER-encoded signature.
|
|
37
|
-
* @returns The converted
|
|
36
|
+
* @returns The converted Uint8Array.
|
|
38
37
|
*/
|
|
39
|
-
function fromDER(x:
|
|
38
|
+
function fromDER(x: Uint8Array): Uint8Array {
|
|
40
39
|
if (x[0] === 0x00) x = x.subarray(1);
|
|
41
|
-
const buffer =
|
|
40
|
+
const buffer = alloc(32);
|
|
42
41
|
const bstart = Math.max(0, 32 - x.length);
|
|
43
|
-
|
|
42
|
+
buffer.set(x, bstart);
|
|
44
43
|
return buffer;
|
|
45
44
|
}
|
|
46
45
|
|
|
47
|
-
interface ScriptSignature {
|
|
48
|
-
signature:
|
|
46
|
+
export interface ScriptSignature {
|
|
47
|
+
signature: Uint8Array;
|
|
49
48
|
hashType: number;
|
|
50
49
|
}
|
|
51
50
|
|
|
52
51
|
// BIP62: 1 byte hashType flag (only 0x01, 0x02, 0x03, 0x81, 0x82 and 0x83 are allowed)
|
|
53
52
|
/**
|
|
54
|
-
* Decodes a
|
|
55
|
-
* @param buffer - The
|
|
53
|
+
* Decodes a Uint8Array into a ScriptSignature object.
|
|
54
|
+
* @param buffer - The Uint8Array to decode.
|
|
56
55
|
* @returns The decoded ScriptSignature object.
|
|
57
56
|
* @throws Error if the hashType is invalid.
|
|
58
57
|
*/
|
|
59
|
-
export function decode(buffer:
|
|
60
|
-
const hashType = buffer
|
|
58
|
+
export function decode(buffer: Uint8Array): ScriptSignature {
|
|
59
|
+
const hashType = buffer[buffer.length - 1]!;
|
|
61
60
|
if (!isDefinedHashType(hashType)) {
|
|
62
61
|
throw new Error(`Invalid hashType ${hashType}`);
|
|
63
62
|
}
|
|
@@ -65,36 +64,34 @@ export function decode(buffer: Buffer): ScriptSignature {
|
|
|
65
64
|
const decoded = bip66.decode(buffer.subarray(0, -1));
|
|
66
65
|
const r = fromDER(decoded.r);
|
|
67
66
|
const s = fromDER(decoded.s);
|
|
68
|
-
const signature =
|
|
67
|
+
const signature = concat([r, s]);
|
|
69
68
|
|
|
70
69
|
return { signature, hashType };
|
|
71
70
|
}
|
|
72
71
|
|
|
73
72
|
/**
|
|
74
|
-
* Encodes a signature and hash type into a
|
|
73
|
+
* Encodes a signature and hash type into a Uint8Array.
|
|
75
74
|
* @param signature - The signature to encode.
|
|
76
75
|
* @param hashType - The hash type to encode.
|
|
77
|
-
* @returns The encoded
|
|
76
|
+
* @returns The encoded Uint8Array.
|
|
78
77
|
* @throws Error if the hashType is invalid.
|
|
79
78
|
*/
|
|
80
|
-
export function encode(signature:
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
);
|
|
79
|
+
export function encode(signature: Uint8Array, hashType: number): Uint8Array {
|
|
80
|
+
if (!isUint8ArrayN(signature, 64)) {
|
|
81
|
+
throw new TypeError('Expected signature to be a 64-byte Uint8Array');
|
|
82
|
+
}
|
|
83
|
+
if (!isUInt8(hashType)) {
|
|
84
|
+
throw new TypeError('Expected hashType to be a UInt8');
|
|
85
|
+
}
|
|
88
86
|
|
|
89
87
|
if (!isDefinedHashType(hashType)) {
|
|
90
88
|
throw new Error(`Invalid hashType ${hashType}`);
|
|
91
89
|
}
|
|
92
90
|
|
|
93
|
-
const hashTypeBuffer =
|
|
94
|
-
hashTypeBuffer.writeUInt8(hashType, 0);
|
|
91
|
+
const hashTypeBuffer = new Uint8Array([hashType]);
|
|
95
92
|
|
|
96
93
|
const r = toDER(signature.subarray(0, 32));
|
|
97
94
|
const s = toDER(signature.subarray(32, 64));
|
|
98
95
|
|
|
99
|
-
return
|
|
96
|
+
return concat([bip66.encode(r, s), hashTypeBuffer]);
|
|
100
97
|
}
|