@bsv/sdk 1.3.12 → 1.3.14
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/dist/cjs/package.json +15 -3
- package/dist/cjs/src/auth/Peer.js +83 -57
- package/dist/cjs/src/auth/Peer.js.map +1 -1
- package/dist/cjs/src/auth/SessionManager.js +14 -9
- package/dist/cjs/src/auth/SessionManager.js.map +1 -1
- package/dist/cjs/src/auth/certificates/Certificate.js +16 -10
- package/dist/cjs/src/auth/certificates/Certificate.js.map +1 -1
- package/dist/cjs/src/auth/certificates/MasterCertificate.js +25 -23
- package/dist/cjs/src/auth/certificates/MasterCertificate.js.map +1 -1
- package/dist/cjs/src/auth/certificates/VerifiableCertificate.js +2 -2
- package/dist/cjs/src/auth/certificates/VerifiableCertificate.js.map +1 -1
- package/dist/cjs/src/auth/certificates/__tests/CompletedProtoWallet.js +62 -46
- package/dist/cjs/src/auth/certificates/__tests/CompletedProtoWallet.js.map +1 -1
- package/dist/cjs/src/auth/clients/AuthFetch.js +1 -0
- package/dist/cjs/src/auth/clients/AuthFetch.js.map +1 -1
- package/dist/cjs/src/auth/transports/SimplifiedFetchTransport.js +70 -43
- package/dist/cjs/src/auth/transports/SimplifiedFetchTransport.js.map +1 -1
- package/dist/cjs/src/auth/utils/createNonce.js +2 -1
- package/dist/cjs/src/auth/utils/createNonce.js.map +1 -1
- package/dist/cjs/src/auth/utils/getVerifiableCertificates.js.map +1 -1
- package/dist/cjs/src/auth/utils/validateCertificates.js +5 -2
- package/dist/cjs/src/auth/utils/validateCertificates.js.map +1 -1
- package/dist/cjs/src/auth/utils/verifyNonce.js +2 -1
- package/dist/cjs/src/auth/utils/verifyNonce.js.map +1 -1
- package/dist/cjs/src/compat/BSM.js +7 -17
- package/dist/cjs/src/compat/BSM.js.map +1 -1
- package/dist/cjs/src/compat/ECIES.js +172 -133
- package/dist/cjs/src/compat/ECIES.js.map +1 -1
- package/dist/cjs/src/compat/HD.js +63 -73
- package/dist/cjs/src/compat/HD.js.map +1 -1
- package/dist/cjs/src/compat/Mnemonic.js +102 -106
- package/dist/cjs/src/compat/Mnemonic.js.map +1 -1
- package/dist/cjs/src/compat/Utxo.js +2 -2
- package/dist/cjs/src/compat/Utxo.js.map +1 -1
- package/dist/cjs/src/compat/index.js +7 -17
- package/dist/cjs/src/compat/index.js.map +1 -1
- package/dist/cjs/src/messages/EncryptedMessage.js +3 -1
- package/dist/cjs/src/messages/EncryptedMessage.js.map +1 -1
- package/dist/cjs/src/messages/SignedMessage.js +1 -0
- package/dist/cjs/src/messages/SignedMessage.js.map +1 -1
- package/dist/cjs/src/messages/index.js +7 -17
- package/dist/cjs/src/messages/index.js.map +1 -1
- package/dist/cjs/src/overlay-tools/LookupResolver.js +54 -35
- package/dist/cjs/src/overlay-tools/LookupResolver.js.map +1 -1
- package/dist/cjs/src/overlay-tools/OverlayAdminTokenTemplate.js +32 -20
- package/dist/cjs/src/overlay-tools/OverlayAdminTokenTemplate.js.map +1 -1
- package/dist/cjs/src/overlay-tools/SHIPBroadcaster.js +40 -28
- package/dist/cjs/src/overlay-tools/SHIPBroadcaster.js.map +1 -1
- package/dist/cjs/src/primitives/AESGCM.js +6 -5
- package/dist/cjs/src/primitives/AESGCM.js.map +1 -1
- package/dist/cjs/src/primitives/BasePoint.js +1 -1
- package/dist/cjs/src/primitives/BasePoint.js.map +1 -1
- package/dist/cjs/src/primitives/BigNumber.js +50 -62
- package/dist/cjs/src/primitives/BigNumber.js.map +1 -1
- package/dist/cjs/src/primitives/Curve.js +46 -22
- package/dist/cjs/src/primitives/Curve.js.map +1 -1
- package/dist/cjs/src/primitives/DRBG.js +2 -8
- package/dist/cjs/src/primitives/DRBG.js.map +1 -1
- package/dist/cjs/src/primitives/ECDSA.js +51 -35
- package/dist/cjs/src/primitives/ECDSA.js.map +1 -1
- package/dist/cjs/src/primitives/Hash.js +191 -216
- package/dist/cjs/src/primitives/Hash.js.map +1 -1
- package/dist/cjs/src/primitives/JacobianPoint.js +19 -5
- package/dist/cjs/src/primitives/JacobianPoint.js.map +1 -1
- package/dist/cjs/src/primitives/K256.js.map +1 -1
- package/dist/cjs/src/primitives/Mersenne.js.map +1 -1
- package/dist/cjs/src/primitives/MontgomoryMethod.js.map +1 -1
- package/dist/cjs/src/primitives/Point.js +117 -88
- package/dist/cjs/src/primitives/Point.js.map +1 -1
- package/dist/cjs/src/primitives/Polynomial.js +4 -2
- package/dist/cjs/src/primitives/Polynomial.js.map +1 -1
- package/dist/cjs/src/primitives/PrivateKey.js +32 -33
- package/dist/cjs/src/primitives/PrivateKey.js.map +1 -1
- package/dist/cjs/src/primitives/PublicKey.js.map +1 -1
- package/dist/cjs/src/primitives/Random.js +6 -5
- package/dist/cjs/src/primitives/Random.js.map +1 -1
- package/dist/cjs/src/primitives/ReductionContext.js +1 -1
- package/dist/cjs/src/primitives/ReductionContext.js.map +1 -1
- package/dist/cjs/src/primitives/Schnorr.js +21 -15
- package/dist/cjs/src/primitives/Schnorr.js.map +1 -1
- package/dist/cjs/src/primitives/Signature.js +8 -7
- package/dist/cjs/src/primitives/Signature.js.map +1 -1
- package/dist/cjs/src/primitives/SymmetricKey.js +13 -13
- package/dist/cjs/src/primitives/SymmetricKey.js.map +1 -1
- package/dist/cjs/src/primitives/TransactionSignature.js +31 -29
- package/dist/cjs/src/primitives/TransactionSignature.js.map +1 -1
- package/dist/cjs/src/primitives/index.js +7 -17
- package/dist/cjs/src/primitives/index.js.map +1 -1
- package/dist/cjs/src/primitives/utils.js +79 -68
- package/dist/cjs/src/primitives/utils.js.map +1 -1
- package/dist/cjs/src/script/OP.js +3 -3
- package/dist/cjs/src/script/OP.js.map +1 -1
- package/dist/cjs/src/script/Script.js +12 -10
- package/dist/cjs/src/script/Script.js.map +1 -1
- package/dist/cjs/src/script/Spend.js +47 -49
- package/dist/cjs/src/script/Spend.js.map +1 -1
- package/dist/cjs/src/script/templates/P2PKH.js +24 -12
- package/dist/cjs/src/script/templates/P2PKH.js.map +1 -1
- package/dist/cjs/src/script/templates/PushDrop.js +28 -23
- package/dist/cjs/src/script/templates/PushDrop.js.map +1 -1
- package/dist/cjs/src/script/templates/RPuzzle.js +10 -6
- package/dist/cjs/src/script/templates/RPuzzle.js.map +1 -1
- package/dist/cjs/src/totp/totp.js +2 -1
- package/dist/cjs/src/totp/totp.js.map +1 -1
- package/dist/cjs/src/transaction/Beef.js +177 -154
- package/dist/cjs/src/transaction/Beef.js.map +1 -1
- package/dist/cjs/src/transaction/BeefParty.js +24 -24
- package/dist/cjs/src/transaction/BeefParty.js.map +1 -1
- package/dist/cjs/src/transaction/BeefTx.js +26 -18
- package/dist/cjs/src/transaction/BeefTx.js.map +1 -1
- package/dist/cjs/src/transaction/Broadcaster.js +3 -2
- package/dist/cjs/src/transaction/Broadcaster.js.map +1 -1
- package/dist/cjs/src/transaction/MerklePath.js +64 -37
- package/dist/cjs/src/transaction/MerklePath.js.map +1 -1
- package/dist/cjs/src/transaction/Transaction.js +111 -137
- package/dist/cjs/src/transaction/Transaction.js.map +1 -1
- package/dist/cjs/src/transaction/broadcasters/ARC.js +25 -16
- package/dist/cjs/src/transaction/broadcasters/ARC.js.map +1 -1
- package/dist/cjs/src/transaction/broadcasters/DefaultBroadcaster.js +2 -1
- package/dist/cjs/src/transaction/broadcasters/DefaultBroadcaster.js.map +1 -1
- package/dist/cjs/src/transaction/broadcasters/WhatsOnChainBroadcaster.js.map +1 -1
- package/dist/cjs/src/transaction/chaintrackers/DefaultChainTracker.js +2 -1
- package/dist/cjs/src/transaction/chaintrackers/DefaultChainTracker.js.map +1 -1
- package/dist/cjs/src/transaction/chaintrackers/WhatsOnChain.js +3 -3
- package/dist/cjs/src/transaction/chaintrackers/WhatsOnChain.js.map +1 -1
- package/dist/cjs/src/transaction/fee-models/SatoshisPerKilobyte.js.map +1 -1
- package/dist/cjs/src/transaction/http/DefaultHttpClient.js +5 -3
- package/dist/cjs/src/transaction/http/DefaultHttpClient.js.map +1 -1
- package/dist/cjs/src/transaction/http/FetchHttpClient.js +5 -2
- package/dist/cjs/src/transaction/http/FetchHttpClient.js.map +1 -1
- package/dist/cjs/src/transaction/http/NodejsHttpClient.js +5 -3
- package/dist/cjs/src/transaction/http/NodejsHttpClient.js.map +1 -1
- package/dist/cjs/src/transaction/http/index.js.map +1 -1
- package/dist/cjs/src/transaction/index.js.map +1 -1
- package/dist/cjs/src/wallet/CachedKeyDeriver.js +91 -66
- package/dist/cjs/src/wallet/CachedKeyDeriver.js.map +1 -1
- package/dist/cjs/src/wallet/KeyDeriver.js +61 -52
- package/dist/cjs/src/wallet/KeyDeriver.js.map +1 -1
- package/dist/cjs/src/wallet/ProtoWallet.js +79 -29
- package/dist/cjs/src/wallet/ProtoWallet.js.map +1 -1
- package/dist/cjs/src/wallet/WalletClient.js +7 -2
- package/dist/cjs/src/wallet/WalletClient.js.map +1 -1
- package/dist/cjs/src/wallet/WalletError.js +2 -2
- package/dist/cjs/src/wallet/WalletError.js.map +1 -1
- package/dist/cjs/src/wallet/substrates/HTTPWalletJSON.js +4 -3
- package/dist/cjs/src/wallet/substrates/HTTPWalletJSON.js.map +1 -1
- package/dist/cjs/src/wallet/substrates/HTTPWalletWire.js +2 -2
- package/dist/cjs/src/wallet/substrates/HTTPWalletWire.js.map +1 -1
- package/dist/cjs/src/wallet/substrates/WalletWireProcessor.js +1239 -1261
- package/dist/cjs/src/wallet/substrates/WalletWireProcessor.js.map +1 -1
- package/dist/cjs/src/wallet/substrates/WalletWireTransceiver.js +102 -43
- package/dist/cjs/src/wallet/substrates/WalletWireTransceiver.js.map +1 -1
- package/dist/cjs/src/wallet/substrates/XDM.js +8 -3
- package/dist/cjs/src/wallet/substrates/XDM.js.map +1 -1
- package/dist/cjs/src/wallet/substrates/window.CWI.js +28 -28
- package/dist/cjs/src/wallet/substrates/window.CWI.js.map +1 -1
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/esm/mod.js +15 -15
- package/dist/esm/src/auth/Peer.js +75 -54
- package/dist/esm/src/auth/Peer.js.map +1 -1
- package/dist/esm/src/auth/SessionManager.js +14 -9
- package/dist/esm/src/auth/SessionManager.js.map +1 -1
- package/dist/esm/src/auth/certificates/Certificate.js +15 -11
- package/dist/esm/src/auth/certificates/Certificate.js.map +1 -1
- package/dist/esm/src/auth/certificates/MasterCertificate.js +25 -23
- package/dist/esm/src/auth/certificates/MasterCertificate.js.map +1 -1
- package/dist/esm/src/auth/certificates/VerifiableCertificate.js +2 -2
- package/dist/esm/src/auth/certificates/VerifiableCertificate.js.map +1 -1
- package/dist/esm/src/auth/certificates/__tests/CompletedProtoWallet.js +64 -47
- package/dist/esm/src/auth/certificates/__tests/CompletedProtoWallet.js.map +1 -1
- package/dist/esm/src/auth/clients/AuthFetch.js +1 -0
- package/dist/esm/src/auth/clients/AuthFetch.js.map +1 -1
- package/dist/esm/src/auth/transports/SimplifiedFetchTransport.js +69 -43
- package/dist/esm/src/auth/transports/SimplifiedFetchTransport.js.map +1 -1
- package/dist/esm/src/auth/utils/createNonce.js.map +1 -1
- package/dist/esm/src/auth/utils/getVerifiableCertificates.js +1 -1
- package/dist/esm/src/auth/utils/getVerifiableCertificates.js.map +1 -1
- package/dist/esm/src/auth/utils/validateCertificates.js +6 -3
- package/dist/esm/src/auth/utils/validateCertificates.js.map +1 -1
- package/dist/esm/src/auth/utils/verifyNonce.js.map +1 -1
- package/dist/esm/src/compat/BSM.js.map +1 -1
- package/dist/esm/src/compat/ECIES.js +165 -116
- package/dist/esm/src/compat/ECIES.js.map +1 -1
- package/dist/esm/src/compat/HD.js +56 -56
- package/dist/esm/src/compat/HD.js.map +1 -1
- package/dist/esm/src/compat/Mnemonic.js +95 -89
- package/dist/esm/src/compat/Mnemonic.js.map +1 -1
- package/dist/esm/src/compat/Utxo.js +1 -1
- package/dist/esm/src/compat/Utxo.js.map +1 -1
- package/dist/esm/src/messages/EncryptedMessage.js +3 -1
- package/dist/esm/src/messages/EncryptedMessage.js.map +1 -1
- package/dist/esm/src/messages/SignedMessage.js +1 -0
- package/dist/esm/src/messages/SignedMessage.js.map +1 -1
- package/dist/esm/src/overlay-tools/LookupResolver.js +53 -35
- package/dist/esm/src/overlay-tools/LookupResolver.js.map +1 -1
- package/dist/esm/src/overlay-tools/OverlayAdminTokenTemplate.js +32 -20
- package/dist/esm/src/overlay-tools/OverlayAdminTokenTemplate.js.map +1 -1
- package/dist/esm/src/overlay-tools/SHIPBroadcaster.js +40 -28
- package/dist/esm/src/overlay-tools/SHIPBroadcaster.js.map +1 -1
- package/dist/esm/src/primitives/AESGCM.js +1 -0
- package/dist/esm/src/primitives/AESGCM.js.map +1 -1
- package/dist/esm/src/primitives/BasePoint.js +1 -1
- package/dist/esm/src/primitives/BasePoint.js.map +1 -1
- package/dist/esm/src/primitives/BigNumber.js +50 -62
- package/dist/esm/src/primitives/BigNumber.js.map +1 -1
- package/dist/esm/src/primitives/Curve.js +45 -22
- package/dist/esm/src/primitives/Curve.js.map +1 -1
- package/dist/esm/src/primitives/DRBG.js +2 -8
- package/dist/esm/src/primitives/DRBG.js.map +1 -1
- package/dist/esm/src/primitives/ECDSA.js +50 -35
- package/dist/esm/src/primitives/ECDSA.js.map +1 -1
- package/dist/esm/src/primitives/Hash.js +188 -213
- package/dist/esm/src/primitives/Hash.js.map +1 -1
- package/dist/esm/src/primitives/JacobianPoint.js +18 -5
- package/dist/esm/src/primitives/JacobianPoint.js.map +1 -1
- package/dist/esm/src/primitives/K256.js.map +1 -1
- package/dist/esm/src/primitives/Mersenne.js.map +1 -1
- package/dist/esm/src/primitives/MontgomoryMethod.js.map +1 -1
- package/dist/esm/src/primitives/Point.js +107 -88
- package/dist/esm/src/primitives/Point.js.map +1 -1
- package/dist/esm/src/primitives/Polynomial.js +4 -2
- package/dist/esm/src/primitives/Polynomial.js.map +1 -1
- package/dist/esm/src/primitives/PrivateKey.js +25 -16
- package/dist/esm/src/primitives/PrivateKey.js.map +1 -1
- package/dist/esm/src/primitives/PublicKey.js.map +1 -1
- package/dist/esm/src/primitives/Random.js +7 -6
- package/dist/esm/src/primitives/Random.js.map +1 -1
- package/dist/esm/src/primitives/ReductionContext.js +1 -1
- package/dist/esm/src/primitives/ReductionContext.js.map +1 -1
- package/dist/esm/src/primitives/Schnorr.js +21 -15
- package/dist/esm/src/primitives/Schnorr.js.map +1 -1
- package/dist/esm/src/primitives/Signature.js +8 -7
- package/dist/esm/src/primitives/Signature.js.map +1 -1
- package/dist/esm/src/primitives/SymmetricKey.js +13 -13
- package/dist/esm/src/primitives/SymmetricKey.js.map +1 -1
- package/dist/esm/src/primitives/TransactionSignature.js +22 -12
- package/dist/esm/src/primitives/TransactionSignature.js.map +1 -1
- package/dist/esm/src/primitives/utils.js +76 -66
- package/dist/esm/src/primitives/utils.js.map +1 -1
- package/dist/esm/src/script/OP.js +3 -3
- package/dist/esm/src/script/OP.js.map +1 -1
- package/dist/esm/src/script/Script.js +12 -10
- package/dist/esm/src/script/Script.js.map +1 -1
- package/dist/esm/src/script/Spend.js +39 -32
- package/dist/esm/src/script/Spend.js.map +1 -1
- package/dist/esm/src/script/templates/P2PKH.js +26 -11
- package/dist/esm/src/script/templates/P2PKH.js.map +1 -1
- package/dist/esm/src/script/templates/PushDrop.js +29 -22
- package/dist/esm/src/script/templates/PushDrop.js.map +1 -1
- package/dist/esm/src/script/templates/RPuzzle.js +11 -6
- package/dist/esm/src/script/templates/RPuzzle.js.map +1 -1
- package/dist/esm/src/totp/totp.js +2 -1
- package/dist/esm/src/totp/totp.js.map +1 -1
- package/dist/esm/src/transaction/Beef.js +176 -154
- package/dist/esm/src/transaction/Beef.js.map +1 -1
- package/dist/esm/src/transaction/BeefParty.js +24 -24
- package/dist/esm/src/transaction/BeefParty.js.map +1 -1
- package/dist/esm/src/transaction/BeefTx.js +26 -18
- package/dist/esm/src/transaction/BeefTx.js.map +1 -1
- package/dist/esm/src/transaction/Broadcaster.js.map +1 -1
- package/dist/esm/src/transaction/MerklePath.js +61 -36
- package/dist/esm/src/transaction/MerklePath.js.map +1 -1
- package/dist/esm/src/transaction/Transaction.js +105 -138
- package/dist/esm/src/transaction/Transaction.js.map +1 -1
- package/dist/esm/src/transaction/broadcasters/ARC.js +25 -16
- package/dist/esm/src/transaction/broadcasters/ARC.js.map +1 -1
- package/dist/esm/src/transaction/broadcasters/DefaultBroadcaster.js.map +1 -1
- package/dist/esm/src/transaction/broadcasters/WhatsOnChainBroadcaster.js.map +1 -1
- package/dist/esm/src/transaction/chaintrackers/WhatsOnChain.js +3 -3
- package/dist/esm/src/transaction/chaintrackers/WhatsOnChain.js.map +1 -1
- package/dist/esm/src/transaction/fee-models/SatoshisPerKilobyte.js.map +1 -1
- package/dist/esm/src/transaction/http/DefaultHttpClient.js +3 -2
- package/dist/esm/src/transaction/http/DefaultHttpClient.js.map +1 -1
- package/dist/esm/src/transaction/http/FetchHttpClient.js +4 -2
- package/dist/esm/src/transaction/http/FetchHttpClient.js.map +1 -1
- package/dist/esm/src/transaction/http/NodejsHttpClient.js +5 -3
- package/dist/esm/src/transaction/http/NodejsHttpClient.js.map +1 -1
- package/dist/esm/src/transaction/http/index.js.map +1 -1
- package/dist/esm/src/transaction/index.js.map +1 -1
- package/dist/esm/src/wallet/CachedKeyDeriver.js +91 -66
- package/dist/esm/src/wallet/CachedKeyDeriver.js.map +1 -1
- package/dist/esm/src/wallet/KeyDeriver.js +60 -52
- package/dist/esm/src/wallet/KeyDeriver.js.map +1 -1
- package/dist/esm/src/wallet/ProtoWallet.js +75 -29
- package/dist/esm/src/wallet/ProtoWallet.js.map +1 -1
- package/dist/esm/src/wallet/WalletClient.js +7 -2
- package/dist/esm/src/wallet/WalletClient.js.map +1 -1
- package/dist/esm/src/wallet/WalletError.js +2 -2
- package/dist/esm/src/wallet/WalletError.js.map +1 -1
- package/dist/esm/src/wallet/substrates/HTTPWalletJSON.js +4 -4
- package/dist/esm/src/wallet/substrates/HTTPWalletJSON.js.map +1 -1
- package/dist/esm/src/wallet/substrates/HTTPWalletWire.js +2 -2
- package/dist/esm/src/wallet/substrates/HTTPWalletWire.js.map +1 -1
- package/dist/esm/src/wallet/substrates/WalletWireProcessor.js +1239 -1261
- package/dist/esm/src/wallet/substrates/WalletWireProcessor.js.map +1 -1
- package/dist/esm/src/wallet/substrates/WalletWireTransceiver.js +95 -43
- package/dist/esm/src/wallet/substrates/WalletWireTransceiver.js.map +1 -1
- package/dist/esm/src/wallet/substrates/XDM.js +8 -3
- package/dist/esm/src/wallet/substrates/XDM.js.map +1 -1
- package/dist/esm/src/wallet/substrates/window.CWI.js +28 -28
- package/dist/esm/src/wallet/substrates/window.CWI.js.map +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/types/mod.d.ts +15 -15
- package/dist/types/src/auth/Peer.d.ts +10 -10
- package/dist/types/src/auth/Peer.d.ts.map +1 -1
- package/dist/types/src/auth/SessionManager.d.ts +4 -4
- package/dist/types/src/auth/SessionManager.d.ts.map +1 -1
- package/dist/types/src/auth/certificates/Certificate.d.ts +6 -6
- package/dist/types/src/auth/certificates/Certificate.d.ts.map +1 -1
- package/dist/types/src/auth/certificates/MasterCertificate.d.ts +5 -5
- package/dist/types/src/auth/certificates/MasterCertificate.d.ts.map +1 -1
- package/dist/types/src/auth/certificates/VerifiableCertificate.d.ts.map +1 -1
- package/dist/types/src/auth/certificates/__tests/CompletedProtoWallet.d.ts +23 -22
- package/dist/types/src/auth/certificates/__tests/CompletedProtoWallet.d.ts.map +1 -1
- package/dist/types/src/auth/clients/AuthFetch.d.ts.map +1 -1
- package/dist/types/src/auth/transports/SimplifiedFetchTransport.d.ts +1 -1
- package/dist/types/src/auth/transports/SimplifiedFetchTransport.d.ts.map +1 -1
- package/dist/types/src/auth/utils/createNonce.d.ts.map +1 -1
- package/dist/types/src/auth/utils/getVerifiableCertificates.d.ts +3 -3
- package/dist/types/src/auth/utils/getVerifiableCertificates.d.ts.map +1 -1
- package/dist/types/src/auth/utils/validateCertificates.d.ts +2 -2
- package/dist/types/src/auth/utils/validateCertificates.d.ts.map +1 -1
- package/dist/types/src/auth/utils/verifyNonce.d.ts +1 -1
- package/dist/types/src/auth/utils/verifyNonce.d.ts.map +1 -1
- package/dist/types/src/compat/BSM.d.ts +1 -1
- package/dist/types/src/compat/BSM.d.ts.map +1 -1
- package/dist/types/src/compat/ECIES.d.ts +36 -36
- package/dist/types/src/compat/ECIES.d.ts.map +1 -1
- package/dist/types/src/compat/HD.d.ts +51 -51
- package/dist/types/src/compat/HD.d.ts.map +1 -1
- package/dist/types/src/compat/Mnemonic.d.ts +79 -79
- package/dist/types/src/compat/Mnemonic.d.ts.map +1 -1
- package/dist/types/src/compat/Utxo.d.ts.map +1 -1
- package/dist/types/src/messages/EncryptedMessage.d.ts.map +1 -1
- package/dist/types/src/messages/SignedMessage.d.ts.map +1 -1
- package/dist/types/src/overlay-tools/LookupResolver.d.ts +9 -9
- package/dist/types/src/overlay-tools/LookupResolver.d.ts.map +1 -1
- package/dist/types/src/overlay-tools/OverlayAdminTokenTemplate.d.ts +17 -17
- package/dist/types/src/overlay-tools/OverlayAdminTokenTemplate.d.ts.map +1 -1
- package/dist/types/src/overlay-tools/SHIPBroadcaster.d.ts +14 -14
- package/dist/types/src/overlay-tools/SHIPBroadcaster.d.ts.map +1 -1
- package/dist/types/src/primitives/AESGCM.d.ts.map +1 -1
- package/dist/types/src/primitives/BasePoint.d.ts +8 -8
- package/dist/types/src/primitives/BasePoint.d.ts.map +1 -1
- package/dist/types/src/primitives/BigNumber.d.ts.map +1 -1
- package/dist/types/src/primitives/Curve.d.ts +14 -7
- package/dist/types/src/primitives/Curve.d.ts.map +1 -1
- package/dist/types/src/primitives/DRBG.d.ts.map +1 -1
- package/dist/types/src/primitives/ECDSA.d.ts +1 -1
- package/dist/types/src/primitives/ECDSA.d.ts.map +1 -1
- package/dist/types/src/primitives/Hash.d.ts +11 -11
- package/dist/types/src/primitives/Hash.d.ts.map +1 -1
- package/dist/types/src/primitives/JacobianPoint.d.ts.map +1 -1
- package/dist/types/src/primitives/Point.d.ts +14 -10
- package/dist/types/src/primitives/Point.d.ts.map +1 -1
- package/dist/types/src/primitives/Polynomial.d.ts.map +1 -1
- package/dist/types/src/primitives/PrivateKey.d.ts +2 -2
- package/dist/types/src/primitives/PrivateKey.d.ts.map +1 -1
- package/dist/types/src/primitives/PublicKey.d.ts.map +1 -1
- package/dist/types/src/primitives/Random.d.ts.map +1 -1
- package/dist/types/src/primitives/Schnorr.d.ts +14 -14
- package/dist/types/src/primitives/Schnorr.d.ts.map +1 -1
- package/dist/types/src/primitives/Signature.d.ts +1 -1
- package/dist/types/src/primitives/Signature.d.ts.map +1 -1
- package/dist/types/src/primitives/SymmetricKey.d.ts +13 -13
- package/dist/types/src/primitives/SymmetricKey.d.ts.map +1 -1
- package/dist/types/src/primitives/TransactionSignature.d.ts +4 -4
- package/dist/types/src/primitives/TransactionSignature.d.ts.map +1 -1
- package/dist/types/src/primitives/utils.d.ts +3 -6
- package/dist/types/src/primitives/utils.d.ts.map +1 -1
- package/dist/types/src/script/Script.d.ts +3 -3
- package/dist/types/src/script/Script.d.ts.map +1 -1
- package/dist/types/src/script/ScriptTemplate.d.ts +2 -2
- package/dist/types/src/script/ScriptTemplate.d.ts.map +1 -1
- package/dist/types/src/script/Spend.d.ts.map +1 -1
- package/dist/types/src/script/templates/P2PKH.d.ts.map +1 -1
- package/dist/types/src/script/templates/PushDrop.d.ts +1 -2
- package/dist/types/src/script/templates/PushDrop.d.ts.map +1 -1
- package/dist/types/src/script/templates/RPuzzle.d.ts.map +1 -1
- package/dist/types/src/totp/totp.d.ts.map +1 -1
- package/dist/types/src/transaction/Beef.d.ts +96 -96
- package/dist/types/src/transaction/Beef.d.ts.map +1 -1
- package/dist/types/src/transaction/BeefParty.d.ts +22 -22
- package/dist/types/src/transaction/BeefParty.d.ts.map +1 -1
- package/dist/types/src/transaction/BeefTx.d.ts +5 -5
- package/dist/types/src/transaction/BeefTx.d.ts.map +1 -1
- package/dist/types/src/transaction/Broadcaster.d.ts.map +1 -1
- package/dist/types/src/transaction/ChainTracker.d.ts +2 -2
- package/dist/types/src/transaction/FeeModel.d.ts.map +1 -1
- package/dist/types/src/transaction/MerklePath.d.ts.map +1 -1
- package/dist/types/src/transaction/Transaction.d.ts +4 -12
- package/dist/types/src/transaction/Transaction.d.ts.map +1 -1
- package/dist/types/src/transaction/TransactionOutput.d.ts.map +1 -1
- package/dist/types/src/transaction/broadcasters/ARC.d.ts +1 -1
- package/dist/types/src/transaction/broadcasters/ARC.d.ts.map +1 -1
- package/dist/types/src/transaction/broadcasters/DefaultBroadcaster.d.ts.map +1 -1
- package/dist/types/src/transaction/broadcasters/WhatsOnChainBroadcaster.d.ts.map +1 -1
- package/dist/types/src/transaction/chaintrackers/DefaultChainTracker.d.ts.map +1 -1
- package/dist/types/src/transaction/chaintrackers/WhatsOnChain.d.ts.map +1 -1
- package/dist/types/src/transaction/fee-models/SatoshisPerKilobyte.d.ts.map +1 -1
- package/dist/types/src/transaction/http/DefaultHttpClient.d.ts +1 -1
- package/dist/types/src/transaction/http/DefaultHttpClient.d.ts.map +1 -1
- package/dist/types/src/transaction/http/FetchHttpClient.d.ts +5 -5
- package/dist/types/src/transaction/http/FetchHttpClient.d.ts.map +1 -1
- package/dist/types/src/transaction/http/HttpClient.d.ts +4 -4
- package/dist/types/src/transaction/http/HttpClient.d.ts.map +1 -1
- package/dist/types/src/transaction/http/NodejsHttpClient.d.ts +3 -3
- package/dist/types/src/transaction/http/NodejsHttpClient.d.ts.map +1 -1
- package/dist/types/src/transaction/http/index.d.ts.map +1 -1
- package/dist/types/src/transaction/index.d.ts.map +1 -1
- package/dist/types/src/wallet/CachedKeyDeriver.d.ts +58 -58
- package/dist/types/src/wallet/CachedKeyDeriver.d.ts.map +1 -1
- package/dist/types/src/wallet/KeyDeriver.d.ts +78 -78
- package/dist/types/src/wallet/KeyDeriver.d.ts.map +1 -1
- package/dist/types/src/wallet/ProtoWallet.d.ts +10 -10
- package/dist/types/src/wallet/ProtoWallet.d.ts.map +1 -1
- package/dist/types/src/wallet/Wallet.interfaces.d.ts +151 -152
- package/dist/types/src/wallet/Wallet.interfaces.d.ts.map +1 -1
- package/dist/types/src/wallet/WalletClient.d.ts +5 -5
- package/dist/types/src/wallet/WalletClient.d.ts.map +1 -1
- package/dist/types/src/wallet/substrates/HTTPWalletJSON.d.ts +6 -6
- package/dist/types/src/wallet/substrates/HTTPWalletJSON.d.ts.map +1 -1
- package/dist/types/src/wallet/substrates/HTTPWalletWire.d.ts.map +1 -1
- package/dist/types/src/wallet/substrates/WalletWireProcessor.d.ts.map +1 -1
- package/dist/types/src/wallet/substrates/WalletWireTransceiver.d.ts.map +1 -1
- package/dist/types/src/wallet/substrates/XDM.d.ts +1 -1
- package/dist/types/src/wallet/substrates/XDM.d.ts.map +1 -1
- package/dist/types/src/wallet/substrates/window.CWI.d.ts +6 -6
- package/dist/types/src/wallet/substrates/window.CWI.d.ts.map +1 -1
- package/dist/types/tsconfig.types.tsbuildinfo +1 -1
- package/dist/umd/bundle.js +1 -1
- package/docs/auth.md +92 -82
- package/docs/compat.md +24 -24
- package/docs/messages.md +7 -5
- package/docs/overlay-tools.md +21 -21
- package/docs/primitives.md +336 -315
- package/docs/script.md +35 -35
- package/docs/swagger/dist/swagger-initializer.js +7 -7
- package/docs/swagger/dist/swagger-ui-bundle.js +1 -1
- package/docs/swagger/dist/swagger-ui-es-bundle-core.js +2 -2
- package/docs/swagger/dist/swagger-ui-es-bundle.js +1 -1
- package/docs/swagger/dist/swagger-ui-standalone-preset.js +1 -1
- package/docs/swagger/dist/swagger-ui.js +2 -2
- package/docs/totp.md +5 -5
- package/docs/transaction.md +103 -105
- package/docs/wallet-substrates.md +17 -17
- package/docs/wallet.md +202 -204
- package/mod.ts +15 -15
- package/package.json +15 -3
- package/src/auth/Peer.ts +271 -121
- package/src/auth/SessionManager.ts +17 -10
- package/src/auth/__tests/Peer.test.ts +361 -179
- package/src/auth/__tests/SessionManager.test.ts +67 -19
- package/src/auth/__tests/build.test.ts +11 -0
- package/src/auth/certificates/Certificate.ts +27 -14
- package/src/auth/certificates/MasterCertificate.ts +106 -62
- package/src/auth/certificates/VerifiableCertificate.ts +30 -8
- package/src/auth/certificates/__tests/Certificate.test.ts +32 -17
- package/src/auth/certificates/__tests/CompletedProtoWallet.ts +171 -68
- package/src/auth/certificates/__tests/MasterCertificate.test.ts +63 -47
- package/src/auth/certificates/__tests/VerifiableCertificate.test.ts +42 -31
- package/src/auth/certificates/index.ts +1 -1
- package/src/auth/clients/AuthFetch.ts +1 -0
- package/src/auth/clients/index.ts +1 -1
- package/src/auth/transports/SimplifiedFetchTransport.ts +145 -72
- package/src/auth/transports/index.ts +1 -1
- package/src/auth/utils/__tests/cryptononce.test.ts +52 -23
- package/src/auth/utils/__tests/getVerifiableCertificates.test.ts +56 -30
- package/src/auth/utils/__tests/validateCertificates.test.ts +53 -31
- package/src/auth/utils/createNonce.ts +11 -3
- package/src/auth/utils/getVerifiableCertificates.ts +12 -7
- package/src/auth/utils/validateCertificates.ts +57 -39
- package/src/auth/utils/verifyNonce.ts +6 -2
- package/src/compat/BSM.ts +10 -2
- package/src/compat/ECIES.ts +265 -141
- package/src/compat/HD.ts +81 -63
- package/src/compat/Mnemonic.ts +104 -91
- package/src/compat/Utxo.ts +8 -5
- package/src/compat/__tests/BSM.test.ts +42 -16
- package/src/compat/__tests/ECIES.test.ts +117 -52
- package/src/compat/__tests/HD.test.ts +55 -42
- package/src/compat/__tests/Mnemonic.test.ts +11 -12
- package/src/compat/__tests/Mnemonic.vectors.ts +110 -55
- package/src/messages/EncryptedMessage.ts +6 -2
- package/src/messages/SignedMessage.ts +14 -8
- package/src/messages/__tests/EncryptedMessage.test.ts +23 -24
- package/src/messages/__tests/SignedMessage.test.ts +17 -11
- package/src/overlay-tools/LookupResolver.ts +108 -56
- package/src/overlay-tools/OverlayAdminTokenTemplate.ts +52 -23
- package/src/overlay-tools/SHIPBroadcaster.ts +135 -59
- package/src/overlay-tools/__tests/LookupResolver.test.ts +723 -323
- package/src/overlay-tools/__tests/OverlayAdminTokenTemplate.test.ts +50 -22
- package/src/overlay-tools/__tests/SHIPBroadcaster.test.ts +607 -290
- package/src/primitives/AESGCM.ts +2 -0
- package/src/primitives/BasePoint.ts +4 -4
- package/src/primitives/BigNumber.ts +99 -90
- package/src/primitives/Curve.ts +117 -46
- package/src/primitives/DRBG.ts +9 -11
- package/src/primitives/ECDSA.ts +109 -63
- package/src/primitives/Hash.ts +492 -321
- package/src/primitives/JacobianPoint.ts +67 -19
- package/src/primitives/Point.ts +254 -152
- package/src/primitives/Polynomial.ts +8 -3
- package/src/primitives/PrivateKey.ts +41 -17
- package/src/primitives/PublicKey.ts +13 -3
- package/src/primitives/Random.ts +14 -8
- package/src/primitives/ReductionContext.ts +1 -1
- package/src/primitives/Schnorr.ts +40 -18
- package/src/primitives/Signature.ts +26 -16
- package/src/primitives/SymmetricKey.ts +14 -14
- package/src/primitives/TransactionSignature.ts +41 -17
- package/src/primitives/__tests/AESGCM.test.ts +457 -151
- package/src/primitives/__tests/BRC42.private.vectors.ts +30 -15
- package/src/primitives/__tests/BRC42.public.vectors.ts +30 -15
- package/src/primitives/__tests/BigNumber.arithmatic.test.ts +344 -125
- package/src/primitives/__tests/BigNumber.binary.test.ts +148 -67
- package/src/primitives/__tests/BigNumber.constructor.test.ts +65 -25
- package/src/primitives/__tests/BigNumber.dhGroup.test.ts +15 -11
- package/src/primitives/__tests/BigNumber.fixtures.ts +16 -8
- package/src/primitives/__tests/BigNumber.serializers.test.ts +41 -15
- package/src/primitives/__tests/BigNumber.utils.test.ts +132 -42
- package/src/primitives/__tests/Curve.unit.test.ts +75 -53
- package/src/primitives/__tests/DRBG.test.ts +1 -1
- package/src/primitives/__tests/DRBG.vectors.ts +45 -75
- package/src/primitives/__tests/ECDH.test.ts +15 -8
- package/src/primitives/__tests/ECDSA.test.ts +12 -6
- package/src/primitives/__tests/HMAC.test.ts +24 -18
- package/src/primitives/__tests/Hash.test.ts +57 -46
- package/src/primitives/__tests/PBKDF2.vectors.ts +130 -117
- package/src/primitives/__tests/PrivateKey.split.test.ts +33 -11
- package/src/primitives/__tests/PrivateKey.test.ts +11 -10
- package/src/primitives/__tests/PublicKey.test.ts +64 -53
- package/src/primitives/__tests/Random.test.ts +1 -1
- package/src/primitives/__tests/Reader.test.ts +240 -219
- package/src/primitives/__tests/ReductionContext.test.ts +98 -61
- package/src/primitives/__tests/Schnorr.test.ts +249 -237
- package/src/primitives/__tests/SymmetricKey.test.ts +18 -15
- package/src/primitives/__tests/SymmetricKey.vectors.ts +16 -8
- package/src/primitives/__tests/Writer.test.ts +23 -13
- package/src/primitives/__tests/bug-31.test.ts +6 -10
- package/src/primitives/__tests/utils.test.ts +70 -19
- package/src/primitives/utils.ts +103 -79
- package/src/script/Script.ts +18 -12
- package/src/script/ScriptTemplate.ts +3 -5
- package/src/script/Spend.ts +306 -108
- package/src/script/__tests/Script.test.ts +73 -55
- package/src/script/__tests/Spend.test.ts +208 -83
- package/src/script/__tests/SpendComplex.test.ts +19 -13
- package/src/script/__tests/script.invalid.vectors.ts +428 -1796
- package/src/script/__tests/script.valid.vectors.ts +728 -2764
- package/src/script/templates/P2PKH.ts +34 -12
- package/src/script/templates/PushDrop.ts +65 -31
- package/src/script/templates/RPuzzle.ts +29 -8
- package/src/script/templates/__tests/PushDrop.test.ts +146 -41
- package/src/totp/__tests/totp.test.ts +45 -44
- package/src/totp/totp.ts +3 -2
- package/src/transaction/Beef.ts +269 -174
- package/src/transaction/BeefParty.ts +41 -31
- package/src/transaction/BeefTx.ts +36 -26
- package/src/transaction/Broadcaster.ts +10 -6
- package/src/transaction/ChainTracker.ts +2 -2
- package/src/transaction/FeeModel.ts +0 -1
- package/src/transaction/MerklePath.ts +124 -59
- package/src/transaction/Transaction.ts +188 -187
- package/src/transaction/TransactionOutput.ts +0 -1
- package/src/transaction/__tests/Beef.test.ts +390 -287
- package/src/transaction/__tests/MerklePath.test.ts +59 -26
- package/src/transaction/__tests/Transaction.benchmarks.test.ts +231 -201
- package/src/transaction/__tests/Transaction.test.ts +758 -482
- package/src/transaction/__tests/bigtx.vectors.ts +2 -1
- package/src/transaction/__tests/bump.invalid.vectors.ts +24 -6
- package/src/transaction/__tests/bump.valid.vectors.ts +6 -2
- package/src/transaction/__tests/tx.invalid.vectors.ts +881 -185
- package/src/transaction/__tests/tx.valid.vectors.ts +1210 -257
- package/src/transaction/broadcasters/ARC.ts +69 -38
- package/src/transaction/broadcasters/DefaultBroadcaster.ts +9 -3
- package/src/transaction/broadcasters/WhatsOnChainBroadcaster.ts +20 -7
- package/src/transaction/broadcasters/__tests/ARC.test.ts +127 -59
- package/src/transaction/broadcasters/__tests/WhatsOnChainBroadcaster.test.ts +27 -18
- package/src/transaction/chaintrackers/DefaultChainTracker.ts +1 -1
- package/src/transaction/chaintrackers/WhatsOnChain.ts +27 -11
- package/src/transaction/chaintrackers/__tests/WhatsOnChainChainTracker.test.ts +59 -23
- package/src/transaction/fee-models/SatoshisPerKilobyte.ts +9 -5
- package/src/transaction/http/DefaultHttpClient.ts +5 -4
- package/src/transaction/http/FetchHttpClient.ts +18 -9
- package/src/transaction/http/HttpClient.ts +27 -22
- package/src/transaction/http/NodejsHttpClient.ts +23 -9
- package/src/transaction/http/index.ts +5 -1
- package/src/transaction/index.ts +5 -1
- package/src/wallet/CachedKeyDeriver.ts +151 -82
- package/src/wallet/KeyDeriver.ts +186 -105
- package/src/wallet/ProtoWallet.ts +121 -52
- package/src/wallet/Wallet.interfaces.ts +167 -156
- package/src/wallet/WalletClient.ts +314 -59
- package/src/wallet/WalletError.ts +2 -2
- package/src/wallet/__tests/CachedKeyDeriver.test.ts +86 -27
- package/src/wallet/__tests/KeyDeriver.test.ts +136 -33
- package/src/wallet/__tests/ProtoWallet.test.ts +190 -102
- package/src/wallet/substrates/HTTPWalletJSON.ts +250 -67
- package/src/wallet/substrates/HTTPWalletWire.ts +7 -3
- package/src/wallet/substrates/WalletWireCalls.ts +2 -2
- package/src/wallet/substrates/WalletWireProcessor.ts +1412 -1277
- package/src/wallet/substrates/WalletWireTransceiver.ts +713 -138
- package/src/wallet/substrates/XDM.ts +425 -36
- package/src/wallet/substrates/__tests/WalletWire.integration.test.ts +488 -225
- package/src/wallet/substrates/__tests/XDM.test.ts +232 -234
- package/src/wallet/substrates/window.CWI.ts +520 -61
|
@@ -1,43 +1,37 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import
|
|
10
|
-
import
|
|
11
|
-
import
|
|
12
|
-
import
|
|
13
|
-
import
|
|
14
|
-
import
|
|
1
|
+
|
|
2
|
+
import BigNumber from '../../primitives/BigNumber'
|
|
3
|
+
import TransactionSignature from '../../primitives/TransactionSignature'
|
|
4
|
+
import { toHex, toArray, Writer } from '../../primitives/utils'
|
|
5
|
+
import Script from '../../script/Script'
|
|
6
|
+
import UnlockingScript from '../../script/UnlockingScript'
|
|
7
|
+
import LockingScript from '../../script/LockingScript'
|
|
8
|
+
import Transaction from '../../transaction/Transaction'
|
|
9
|
+
import { hash256, hash160 } from '../../primitives/Hash'
|
|
10
|
+
import PrivateKey from '../../primitives/PrivateKey'
|
|
11
|
+
import Curve from '../../primitives/Curve'
|
|
12
|
+
import P2PKH from '../../script/templates/P2PKH'
|
|
13
|
+
import fromUtxo from '../../compat/Utxo'
|
|
14
|
+
import MerklePath from '../../transaction/MerklePath'
|
|
15
|
+
import { BEEF_V1 } from '../../transaction/Beef'
|
|
15
16
|
|
|
16
17
|
import sighashVectors from '../../primitives/__tests/sighash.vectors'
|
|
17
18
|
import invalidTransactions from './tx.invalid.vectors'
|
|
18
19
|
import validTransactions from './tx.valid.vectors'
|
|
19
20
|
import bigTX from './bigtx.vectors'
|
|
21
|
+
import { BroadcastResponse } from '../../transaction/Broadcaster'
|
|
20
22
|
|
|
21
|
-
const BRC62Hex =
|
|
22
|
-
|
|
23
|
+
const BRC62Hex =
|
|
24
|
+
'0100beef01fe636d0c0007021400fe507c0c7aa754cef1f7889d5fd395cf1f785dd7de98eed895dbedfe4e5bc70d1502ac4e164f5bc16746bb0868404292ac8318bbac3800e4aad13a014da427adce3e010b00bc4ff395efd11719b277694cface5aa50d085a0bb81f613f70313acd28cf4557010400574b2d9142b8d28b61d88e3b2c3f44d858411356b49a28a4643b6d1a6a092a5201030051a05fc84d531b5d250c23f4f886f6812f9fe3f402d61607f977b4ecd2701c19010000fd781529d58fc2523cf396a7f25440b409857e7e221766c57214b1d38c7b481f01010062f542f45ea3660f86c013ced80534cb5fd4c19d66c56e7e8c5d4bf2d40acc5e010100b121e91836fd7cd5102b654e9f72f3cf6fdbfd0b161c53a9c54b12c841126331020100000001cd4e4cac3c7b56920d1e7655e7e260d31f29d9a388d04910f1bbd72304a79029010000006b483045022100e75279a205a547c445719420aa3138bf14743e3f42618e5f86a19bde14bb95f7022064777d34776b05d816daf1699493fcdf2ef5a5ab1ad710d9c97bfb5b8f7cef3641210263e2dee22b1ddc5e11f6fab8bcd2378bdd19580d640501ea956ec0e786f93e76ffffffff013e660000000000001976a9146bfd5c7fbe21529d45803dbcf0c87dd3c71efbc288ac0000000001000100000001ac4e164f5bc16746bb0868404292ac8318bbac3800e4aad13a014da427adce3e000000006a47304402203a61a2e931612b4bda08d541cfb980885173b8dcf64a3471238ae7abcd368d6402204cbf24f04b9aa2256d8901f0ed97866603d2be8324c2bfb7a37bf8fc90edd5b441210263e2dee22b1ddc5e11f6fab8bcd2378bdd19580d640501ea956ec0e786f93e76ffffffff013c660000000000001976a9146bfd5c7fbe21529d45803dbcf0c87dd3c71efbc288ac0000000000'
|
|
25
|
+
const MerkleRootFromBEEF =
|
|
26
|
+
'bb6f640cc4ee56bf38eb5a1969ac0c16caa2d3d202b22bf3735d10eec0ca6e00'
|
|
23
27
|
|
|
24
28
|
describe('Transaction', () => {
|
|
25
|
-
const txIn = {
|
|
26
|
-
sourceTXID: '0000000000000000000000000000000000000000000000000000000000000000',
|
|
27
|
-
sourceOutputIndex: 0,
|
|
28
|
-
unlockingScript: UnlockingScript.fromHex('ae'),
|
|
29
|
-
sequence: 0
|
|
30
|
-
}
|
|
31
|
-
const txOut = {
|
|
32
|
-
satoshis: BigNumber.fromHex('0500000000000000', 'be'),
|
|
33
|
-
lockingScript: LockingScript.fromHex('ae')
|
|
34
|
-
}
|
|
35
|
-
const tx = new Transaction(0, [txIn], [txOut], 0)
|
|
36
29
|
const txhex =
|
|
37
30
|
'000000000100000000000000000000000000000000000000000000000000000000000000000000000001ae0000000001050000000000000001ae00000000'
|
|
38
31
|
const txbuf = toArray(txhex, 'hex')
|
|
39
32
|
|
|
40
|
-
const tx2idhex =
|
|
33
|
+
const tx2idhex =
|
|
34
|
+
'8c9aa966d35bfeaf031409e0001b90ccdafd8d859799eb945a3c515b8260bcf2'
|
|
41
35
|
const tx2hex =
|
|
42
36
|
'01000000029e8d016a7b0dc49a325922d05da1f916d1e4d4f0cb840c9727f3d22ce8d1363f000000008c493046022100e9318720bee5425378b4763b0427158b1051eec8b08442ce3fbfbf7b30202a44022100d4172239ebd701dae2fbaaccd9f038e7ca166707333427e3fb2a2865b19a7f27014104510c67f46d2cbb29476d1f0b794be4cb549ea59ab9cc1e731969a7bf5be95f7ad5e7f904e5ccf50a9dc1714df00fbeb794aa27aaff33260c1032d931a75c56f2ffffffffa3195e7a1ab665473ff717814f6881485dc8759bebe97e31c301ffe7933a656f020000008b48304502201c282f35f3e02a1f32d2089265ad4b561f07ea3c288169dedcf2f785e6065efa022100e8db18aadacb382eed13ee04708f00ba0a9c40e3b21cf91da8859d0f7d99e0c50141042b409e1ebbb43875be5edde9c452c82c01e3903d38fa4fd89f3887a52cb8aea9dc8aec7e2c9d5b3609c03eb16259a2537135a1bf0f9c5fbbcbdbaf83ba402442ffffffff02206b1000000000001976a91420bb5c3bfaef0231dc05190e7f1c8e22e098991e88acf0ca0100000000001976a9149e3e2d23973a04ec1b02be97c30ab9f2f27c3b2c88ac00000000'
|
|
43
37
|
const tx2buf = toArray(tx2hex, 'hex')
|
|
@@ -90,7 +84,7 @@ describe('Transaction', () => {
|
|
|
90
84
|
describe('#parseScriptOffsets', () => {
|
|
91
85
|
it('should match sliced scripts to parsed scripts', async () => {
|
|
92
86
|
const tx = Transaction.fromBinary(tx2buf)
|
|
93
|
-
expect(tx.id(
|
|
87
|
+
expect(tx.id('hex')).toBe(tx2idhex)
|
|
94
88
|
const r = Transaction.parseScriptOffsets(tx2buf)
|
|
95
89
|
expect(r.inputs.length).toBe(2)
|
|
96
90
|
expect(r.outputs.length).toBe(2)
|
|
@@ -122,7 +116,11 @@ describe('Transaction', () => {
|
|
|
122
116
|
describe('#hash', () => {
|
|
123
117
|
it('should correctly calculate the hash of this known transaction', () => {
|
|
124
118
|
const tx = Transaction.fromBinary(tx2buf)
|
|
125
|
-
|
|
119
|
+
const hash = tx.hash()
|
|
120
|
+
const reversedHash = Array.isArray(hash)
|
|
121
|
+
? hash.reverse()
|
|
122
|
+
: toArray(hash, 'hex').reverse()
|
|
123
|
+
expect(toHex(reversedHash)).toEqual(tx2idhex)
|
|
126
124
|
})
|
|
127
125
|
})
|
|
128
126
|
|
|
@@ -136,7 +134,8 @@ describe('Transaction', () => {
|
|
|
136
134
|
describe('#addInput', () => {
|
|
137
135
|
it('should add an input', () => {
|
|
138
136
|
const txIn = {
|
|
139
|
-
sourceTXID:
|
|
137
|
+
sourceTXID:
|
|
138
|
+
'0000000000000000000000000000000000000000000000000000000000000000',
|
|
140
139
|
sourceOutputIndex: 0,
|
|
141
140
|
unlockingScript: new UnlockingScript(),
|
|
142
141
|
sequence: 0xffffffff
|
|
@@ -165,35 +164,52 @@ describe('Transaction', () => {
|
|
|
165
164
|
it('Signs unlocking script templates, hydrating the scripts', async () => {
|
|
166
165
|
const privateKey = new PrivateKey(1)
|
|
167
166
|
const publicKey = new Curve().g.mul(privateKey)
|
|
168
|
-
const publicKeyHash = hash160(publicKey.encode(true))
|
|
167
|
+
const publicKeyHash = hash160(publicKey.encode(true))
|
|
169
168
|
const p2pkh = new P2PKH()
|
|
170
|
-
const sourceTx = new Transaction(
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
169
|
+
const sourceTx = new Transaction(
|
|
170
|
+
1,
|
|
171
|
+
[],
|
|
172
|
+
[
|
|
173
|
+
{
|
|
174
|
+
lockingScript: p2pkh.lock(publicKeyHash),
|
|
175
|
+
satoshis: 4000
|
|
176
|
+
}
|
|
177
|
+
],
|
|
178
|
+
0
|
|
179
|
+
)
|
|
180
|
+
const spendTx = new Transaction(
|
|
181
|
+
1,
|
|
182
|
+
[
|
|
183
|
+
{
|
|
184
|
+
sourceTransaction: sourceTx,
|
|
185
|
+
sourceOutputIndex: 0,
|
|
186
|
+
unlockingScriptTemplate: p2pkh.unlock(privateKey),
|
|
187
|
+
sequence: 0xffffffff
|
|
188
|
+
}
|
|
189
|
+
],
|
|
190
|
+
[
|
|
191
|
+
{
|
|
192
|
+
satoshis: 1000,
|
|
193
|
+
lockingScript: p2pkh.lock(publicKeyHash)
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
lockingScript: p2pkh.lock(publicKeyHash),
|
|
197
|
+
change: true
|
|
198
|
+
}
|
|
199
|
+
],
|
|
200
|
+
0
|
|
201
|
+
)
|
|
186
202
|
expect(spendTx.inputs[0].unlockingScript).not.toBeDefined()
|
|
187
203
|
await spendTx.fee()
|
|
188
204
|
await spendTx.sign()
|
|
189
205
|
expect(spendTx.inputs[0].unlockingScript).toBeDefined()
|
|
190
206
|
// P2PKH unlocking scripts have two chunks (the signature and public key)
|
|
191
|
-
expect(spendTx.inputs[0].unlockingScript
|
|
207
|
+
expect(spendTx.inputs[0].unlockingScript?.chunks.length).toBe(2)
|
|
192
208
|
})
|
|
193
209
|
it('Signs a large number of unlocking script templates in a timely manner', async () => {
|
|
194
210
|
const privateKey = new PrivateKey(134)
|
|
195
211
|
const publicKey = new Curve().g.mul(privateKey)
|
|
196
|
-
const publicKeyHash = hash160(publicKey.encode(true))
|
|
212
|
+
const publicKeyHash = hash160(publicKey.encode(true))
|
|
197
213
|
const p2pkh = new P2PKH()
|
|
198
214
|
const spendCount = 30
|
|
199
215
|
const output = {
|
|
@@ -223,41 +239,69 @@ describe('Transaction', () => {
|
|
|
223
239
|
sequence: 0xffffffff
|
|
224
240
|
}
|
|
225
241
|
}
|
|
226
|
-
const spendTx = new Transaction(
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
242
|
+
const spendTx = new Transaction(
|
|
243
|
+
1,
|
|
244
|
+
manyInputs,
|
|
245
|
+
[
|
|
246
|
+
{
|
|
247
|
+
satoshis: 1000,
|
|
248
|
+
lockingScript: p2pkh.lock(publicKeyHash)
|
|
249
|
+
},
|
|
250
|
+
{
|
|
251
|
+
lockingScript: p2pkh.lock(publicKeyHash),
|
|
252
|
+
change: true
|
|
253
|
+
}
|
|
254
|
+
],
|
|
255
|
+
0
|
|
256
|
+
)
|
|
233
257
|
expect(spendTx.inputs[0].unlockingScript).not.toBeDefined()
|
|
234
258
|
await spendTx.fee()
|
|
235
259
|
await spendTx.sign()
|
|
236
260
|
expect(spendTx.inputs[0].unlockingScript).toBeDefined()
|
|
237
261
|
// P2PKH unlocking scripts have two chunks (the signature and public key)
|
|
238
|
-
expect(spendTx.inputs[0].unlockingScript
|
|
262
|
+
expect(spendTx.inputs[0].unlockingScript?.chunks.length).toBe(2)
|
|
239
263
|
})
|
|
240
264
|
it('Throws an Error if signing before the fee is computed', async () => {
|
|
241
265
|
const privateKey = new PrivateKey(1)
|
|
242
266
|
const publicKey = new Curve().g.mul(privateKey)
|
|
243
|
-
const publicKeyHash = hash160(
|
|
267
|
+
const publicKeyHash = hash160(
|
|
268
|
+
publicKey.encode(true),
|
|
269
|
+
'hex'
|
|
270
|
+
) as unknown as number[]
|
|
244
271
|
const p2pkh = new P2PKH()
|
|
245
|
-
const sourceTx = new Transaction(
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
272
|
+
const sourceTx = new Transaction(
|
|
273
|
+
1,
|
|
274
|
+
[],
|
|
275
|
+
[
|
|
276
|
+
{
|
|
277
|
+
lockingScript: p2pkh.lock(publicKeyHash),
|
|
278
|
+
satoshis: 4000
|
|
279
|
+
}
|
|
280
|
+
],
|
|
281
|
+
0
|
|
282
|
+
)
|
|
283
|
+
const spendTx = new Transaction(
|
|
284
|
+
1,
|
|
285
|
+
[
|
|
286
|
+
{
|
|
287
|
+
sourceTransaction: sourceTx,
|
|
288
|
+
sourceOutputIndex: 0,
|
|
289
|
+
unlockingScriptTemplate: p2pkh.unlock(privateKey),
|
|
290
|
+
sequence: 0xffffffff
|
|
291
|
+
}
|
|
292
|
+
],
|
|
293
|
+
[
|
|
294
|
+
{
|
|
295
|
+
satoshis: 1000,
|
|
296
|
+
lockingScript: p2pkh.lock(publicKeyHash)
|
|
297
|
+
},
|
|
298
|
+
{
|
|
299
|
+
lockingScript: p2pkh.lock(publicKeyHash),
|
|
300
|
+
change: true
|
|
301
|
+
}
|
|
302
|
+
],
|
|
303
|
+
0
|
|
304
|
+
)
|
|
261
305
|
await expect(spendTx.sign()).rejects.toThrow()
|
|
262
306
|
})
|
|
263
307
|
})
|
|
@@ -266,24 +310,41 @@ describe('Transaction', () => {
|
|
|
266
310
|
it('Computes fees with the default fee model', async () => {
|
|
267
311
|
const privateKey = new PrivateKey(1)
|
|
268
312
|
const publicKey = new Curve().g.mul(privateKey)
|
|
269
|
-
const publicKeyHash = hash160(publicKey.encode(true))
|
|
313
|
+
const publicKeyHash = hash160(publicKey.encode(true))
|
|
270
314
|
const p2pkh = new P2PKH()
|
|
271
|
-
const sourceTx = new Transaction(
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
315
|
+
const sourceTx = new Transaction(
|
|
316
|
+
1,
|
|
317
|
+
[],
|
|
318
|
+
[
|
|
319
|
+
{
|
|
320
|
+
lockingScript: p2pkh.lock(publicKeyHash),
|
|
321
|
+
satoshis: 4000
|
|
322
|
+
}
|
|
323
|
+
],
|
|
324
|
+
0
|
|
325
|
+
)
|
|
326
|
+
const spendTx = new Transaction(
|
|
327
|
+
1,
|
|
328
|
+
[
|
|
329
|
+
{
|
|
330
|
+
sourceTransaction: sourceTx,
|
|
331
|
+
sourceOutputIndex: 0,
|
|
332
|
+
unlockingScriptTemplate: p2pkh.unlock(privateKey),
|
|
333
|
+
sequence: 0xffffffff
|
|
334
|
+
}
|
|
335
|
+
],
|
|
336
|
+
[
|
|
337
|
+
{
|
|
338
|
+
satoshis: 1000,
|
|
339
|
+
lockingScript: p2pkh.lock(publicKeyHash)
|
|
340
|
+
},
|
|
341
|
+
{
|
|
342
|
+
lockingScript: p2pkh.lock(publicKeyHash),
|
|
343
|
+
change: true
|
|
344
|
+
}
|
|
345
|
+
],
|
|
346
|
+
0
|
|
347
|
+
)
|
|
287
348
|
expect(spendTx.outputs[1].satoshis).not.toBeDefined()
|
|
288
349
|
await spendTx.fee()
|
|
289
350
|
// Transaction size is 225 bytes for one-input two-output P2PKH.
|
|
@@ -294,24 +355,41 @@ describe('Transaction', () => {
|
|
|
294
355
|
it('Computes fees with a custom fee model', async () => {
|
|
295
356
|
const privateKey = new PrivateKey(1)
|
|
296
357
|
const publicKey = new Curve().g.mul(privateKey)
|
|
297
|
-
const publicKeyHash = hash160(publicKey.encode(true))
|
|
358
|
+
const publicKeyHash = hash160(publicKey.encode(true))
|
|
298
359
|
const p2pkh = new P2PKH()
|
|
299
|
-
const sourceTx = new Transaction(
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
360
|
+
const sourceTx = new Transaction(
|
|
361
|
+
1,
|
|
362
|
+
[],
|
|
363
|
+
[
|
|
364
|
+
{
|
|
365
|
+
lockingScript: p2pkh.lock(publicKeyHash),
|
|
366
|
+
satoshis: 4000
|
|
367
|
+
}
|
|
368
|
+
],
|
|
369
|
+
0
|
|
370
|
+
)
|
|
371
|
+
const spendTx = new Transaction(
|
|
372
|
+
1,
|
|
373
|
+
[
|
|
374
|
+
{
|
|
375
|
+
sourceTransaction: sourceTx,
|
|
376
|
+
sourceOutputIndex: 0,
|
|
377
|
+
unlockingScriptTemplate: p2pkh.unlock(privateKey),
|
|
378
|
+
sequence: 0xffffffff
|
|
379
|
+
}
|
|
380
|
+
],
|
|
381
|
+
[
|
|
382
|
+
{
|
|
383
|
+
satoshis: 1000,
|
|
384
|
+
lockingScript: p2pkh.lock(publicKeyHash)
|
|
385
|
+
},
|
|
386
|
+
{
|
|
387
|
+
lockingScript: p2pkh.lock(publicKeyHash),
|
|
388
|
+
change: true
|
|
389
|
+
}
|
|
390
|
+
],
|
|
391
|
+
0
|
|
392
|
+
)
|
|
315
393
|
expect(spendTx.outputs[1].satoshis).not.toBeDefined()
|
|
316
394
|
await spendTx.fee({
|
|
317
395
|
// Our custom fee model will always charge 1033 sats for a tx.
|
|
@@ -323,24 +401,41 @@ describe('Transaction', () => {
|
|
|
323
401
|
it('Computes fee using FixedFee model', async () => {
|
|
324
402
|
const privateKey = new PrivateKey(1)
|
|
325
403
|
const publicKey = new Curve().g.mul(privateKey)
|
|
326
|
-
const publicKeyHash = hash160(publicKey.encode(true))
|
|
404
|
+
const publicKeyHash = hash160(publicKey.encode(true))
|
|
327
405
|
const p2pkh = new P2PKH()
|
|
328
|
-
const sourceTx = new Transaction(
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
406
|
+
const sourceTx = new Transaction(
|
|
407
|
+
1,
|
|
408
|
+
[],
|
|
409
|
+
[
|
|
410
|
+
{
|
|
411
|
+
lockingScript: p2pkh.lock(publicKeyHash),
|
|
412
|
+
satoshis: 4000
|
|
413
|
+
}
|
|
414
|
+
],
|
|
415
|
+
0
|
|
416
|
+
)
|
|
417
|
+
const spendTx = new Transaction(
|
|
418
|
+
1,
|
|
419
|
+
[
|
|
420
|
+
{
|
|
421
|
+
sourceTransaction: sourceTx,
|
|
422
|
+
sourceOutputIndex: 0,
|
|
423
|
+
unlockingScriptTemplate: p2pkh.unlock(privateKey),
|
|
424
|
+
sequence: 0xffffffff
|
|
425
|
+
}
|
|
426
|
+
],
|
|
427
|
+
[
|
|
428
|
+
{
|
|
429
|
+
satoshis: 1000,
|
|
430
|
+
lockingScript: p2pkh.lock(publicKeyHash)
|
|
431
|
+
},
|
|
432
|
+
{
|
|
433
|
+
lockingScript: p2pkh.lock(publicKeyHash),
|
|
434
|
+
change: true
|
|
435
|
+
}
|
|
436
|
+
],
|
|
437
|
+
0
|
|
438
|
+
)
|
|
344
439
|
expect(spendTx.outputs[1].satoshis).not.toBeDefined()
|
|
345
440
|
await spendTx.fee(1033)
|
|
346
441
|
// 4000 sats in - 1000 sats out - 1033 sats fee = expected 1967 sats change
|
|
@@ -349,33 +444,53 @@ describe('Transaction', () => {
|
|
|
349
444
|
it('Distributes change equally among multiple change outputs', async () => {
|
|
350
445
|
const privateKey = new PrivateKey(1)
|
|
351
446
|
const publicKey = new Curve().g.mul(privateKey)
|
|
352
|
-
const publicKeyHash = hash160(publicKey.encode(true))
|
|
447
|
+
const publicKeyHash = hash160(publicKey.encode(true))
|
|
353
448
|
const p2pkh = new P2PKH()
|
|
354
|
-
const sourceTx = new Transaction(
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
449
|
+
const sourceTx = new Transaction(
|
|
450
|
+
1,
|
|
451
|
+
[],
|
|
452
|
+
[
|
|
453
|
+
{
|
|
454
|
+
lockingScript: p2pkh.lock(publicKeyHash),
|
|
455
|
+
satoshis: 4000
|
|
456
|
+
}
|
|
457
|
+
],
|
|
458
|
+
0
|
|
459
|
+
)
|
|
460
|
+
const spendTx = new Transaction(
|
|
461
|
+
1,
|
|
462
|
+
[
|
|
463
|
+
{
|
|
464
|
+
sourceTransaction: sourceTx,
|
|
465
|
+
sourceOutputIndex: 0,
|
|
466
|
+
unlockingScriptTemplate: p2pkh.unlock(privateKey),
|
|
467
|
+
sequence: 0xffffffff
|
|
468
|
+
}
|
|
469
|
+
],
|
|
470
|
+
[
|
|
471
|
+
{
|
|
472
|
+
satoshis: 1000,
|
|
473
|
+
lockingScript: p2pkh.lock(publicKeyHash)
|
|
474
|
+
},
|
|
475
|
+
{
|
|
476
|
+
lockingScript: p2pkh.lock(publicKeyHash),
|
|
477
|
+
change: true
|
|
478
|
+
},
|
|
479
|
+
{
|
|
480
|
+
lockingScript: p2pkh.lock(publicKeyHash),
|
|
481
|
+
change: true
|
|
482
|
+
},
|
|
483
|
+
{
|
|
484
|
+
lockingScript: p2pkh.lock(publicKeyHash),
|
|
485
|
+
change: true
|
|
486
|
+
},
|
|
487
|
+
{
|
|
488
|
+
lockingScript: p2pkh.lock(publicKeyHash),
|
|
489
|
+
change: true
|
|
490
|
+
}
|
|
491
|
+
],
|
|
492
|
+
0
|
|
493
|
+
)
|
|
379
494
|
expect(spendTx.outputs[1].satoshis).not.toBeDefined()
|
|
380
495
|
expect(spendTx.outputs[2].satoshis).not.toBeDefined()
|
|
381
496
|
expect(spendTx.outputs[3].satoshis).not.toBeDefined()
|
|
@@ -395,133 +510,205 @@ describe('Transaction', () => {
|
|
|
395
510
|
it('Distributes change randomly among multiple change outputs', async () => {
|
|
396
511
|
const privateKey = new PrivateKey(1)
|
|
397
512
|
const publicKey = new Curve().g.mul(privateKey)
|
|
398
|
-
const publicKeyHash = hash160(publicKey.encode(true))
|
|
513
|
+
const publicKeyHash = hash160(publicKey.encode(true))
|
|
399
514
|
const p2pkh = new P2PKH()
|
|
400
|
-
const sourceTx = new Transaction(
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
515
|
+
const sourceTx = new Transaction(
|
|
516
|
+
1,
|
|
517
|
+
[],
|
|
518
|
+
[
|
|
519
|
+
{
|
|
520
|
+
lockingScript: p2pkh.lock(publicKeyHash),
|
|
521
|
+
satoshis: 900
|
|
522
|
+
}
|
|
523
|
+
],
|
|
524
|
+
0
|
|
525
|
+
)
|
|
526
|
+
const spendTx = new Transaction(
|
|
527
|
+
1,
|
|
528
|
+
[
|
|
529
|
+
{
|
|
530
|
+
sourceTransaction: sourceTx,
|
|
531
|
+
sourceOutputIndex: 0,
|
|
532
|
+
unlockingScriptTemplate: p2pkh.unlock(privateKey),
|
|
533
|
+
sequence: 0xffffffff
|
|
534
|
+
}
|
|
535
|
+
],
|
|
536
|
+
[
|
|
537
|
+
{
|
|
538
|
+
satoshis: 1,
|
|
539
|
+
lockingScript: p2pkh.lock(publicKeyHash)
|
|
540
|
+
},
|
|
541
|
+
{
|
|
542
|
+
lockingScript: p2pkh.lock(publicKeyHash),
|
|
543
|
+
change: true
|
|
544
|
+
},
|
|
545
|
+
{
|
|
546
|
+
lockingScript: p2pkh.lock(publicKeyHash),
|
|
547
|
+
change: true
|
|
548
|
+
},
|
|
549
|
+
{
|
|
550
|
+
lockingScript: p2pkh.lock(publicKeyHash),
|
|
551
|
+
change: true
|
|
552
|
+
},
|
|
553
|
+
{
|
|
554
|
+
lockingScript: p2pkh.lock(publicKeyHash),
|
|
555
|
+
change: true
|
|
556
|
+
},
|
|
557
|
+
{
|
|
558
|
+
lockingScript: p2pkh.lock(publicKeyHash),
|
|
559
|
+
change: true
|
|
560
|
+
},
|
|
561
|
+
{
|
|
562
|
+
lockingScript: p2pkh.lock(publicKeyHash),
|
|
563
|
+
change: true
|
|
564
|
+
}
|
|
565
|
+
],
|
|
566
|
+
0
|
|
567
|
+
)
|
|
431
568
|
expect(spendTx.outputs[1].satoshis).not.toBeDefined()
|
|
432
569
|
expect(spendTx.outputs[2].satoshis).not.toBeDefined()
|
|
433
570
|
expect(spendTx.outputs[3].satoshis).not.toBeDefined()
|
|
434
571
|
expect(spendTx.outputs[4].satoshis).not.toBeDefined()
|
|
435
572
|
expect(spendTx.outputs[5].satoshis).not.toBeDefined()
|
|
436
573
|
expect(spendTx.outputs[6].satoshis).not.toBeDefined()
|
|
437
|
-
await spendTx.fee(
|
|
438
|
-
|
|
439
|
-
|
|
574
|
+
await spendTx.fee(
|
|
575
|
+
{
|
|
576
|
+
computeFee: async () => 3
|
|
577
|
+
},
|
|
578
|
+
'random'
|
|
579
|
+
)
|
|
440
580
|
expect(spendTx.outputs[0].satoshis).toEqual(1)
|
|
441
|
-
expect(spendTx.outputs.reduce((a, b) => a + b.satoshis, 0)).toEqual(897)
|
|
581
|
+
expect(spendTx.outputs.reduce((a, b) => a + (b.satoshis ?? 0), 0)).toEqual(897)
|
|
442
582
|
})
|
|
443
583
|
it('Distributes change randomly among multiple change outputs, with one set output', async () => {
|
|
444
584
|
const privateKey = new PrivateKey(1)
|
|
445
585
|
const publicKey = new Curve().g.mul(privateKey)
|
|
446
|
-
const publicKeyHash = hash160(publicKey.encode(true))
|
|
586
|
+
const publicKeyHash = hash160(publicKey.encode(true))
|
|
447
587
|
const p2pkh = new P2PKH()
|
|
448
|
-
const sourceTx = new Transaction(
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
588
|
+
const sourceTx = new Transaction(
|
|
589
|
+
1,
|
|
590
|
+
[],
|
|
591
|
+
[
|
|
592
|
+
{
|
|
593
|
+
lockingScript: p2pkh.lock(publicKeyHash),
|
|
594
|
+
satoshis: 9
|
|
595
|
+
}
|
|
596
|
+
],
|
|
597
|
+
0
|
|
598
|
+
)
|
|
599
|
+
const spendTx = new Transaction(
|
|
600
|
+
1,
|
|
601
|
+
[
|
|
602
|
+
{
|
|
603
|
+
sourceTransaction: sourceTx,
|
|
604
|
+
sourceOutputIndex: 0,
|
|
605
|
+
unlockingScriptTemplate: p2pkh.unlock(privateKey),
|
|
606
|
+
sequence: 0xffffffff
|
|
607
|
+
}
|
|
608
|
+
],
|
|
609
|
+
[
|
|
610
|
+
{
|
|
611
|
+
satoshis: 1,
|
|
612
|
+
lockingScript: p2pkh.lock(publicKeyHash)
|
|
613
|
+
},
|
|
614
|
+
{
|
|
615
|
+
lockingScript: p2pkh.lock(publicKeyHash),
|
|
616
|
+
change: true
|
|
617
|
+
},
|
|
618
|
+
{
|
|
619
|
+
lockingScript: p2pkh.lock(publicKeyHash),
|
|
620
|
+
change: true
|
|
621
|
+
},
|
|
622
|
+
{
|
|
623
|
+
lockingScript: p2pkh.lock(publicKeyHash),
|
|
624
|
+
change: true
|
|
625
|
+
},
|
|
626
|
+
{
|
|
627
|
+
lockingScript: p2pkh.lock(publicKeyHash),
|
|
628
|
+
change: true
|
|
629
|
+
},
|
|
630
|
+
{
|
|
631
|
+
lockingScript: p2pkh.lock(publicKeyHash),
|
|
632
|
+
change: true
|
|
633
|
+
},
|
|
634
|
+
{
|
|
635
|
+
lockingScript: p2pkh.lock(publicKeyHash),
|
|
636
|
+
change: true
|
|
637
|
+
}
|
|
638
|
+
],
|
|
639
|
+
0
|
|
640
|
+
)
|
|
479
641
|
expect(spendTx.outputs[1].satoshis).not.toBeDefined()
|
|
480
642
|
expect(spendTx.outputs[2].satoshis).not.toBeDefined()
|
|
481
643
|
expect(spendTx.outputs[3].satoshis).not.toBeDefined()
|
|
482
644
|
expect(spendTx.outputs[4].satoshis).not.toBeDefined()
|
|
483
645
|
expect(spendTx.outputs[5].satoshis).not.toBeDefined()
|
|
484
646
|
expect(spendTx.outputs[6].satoshis).not.toBeDefined()
|
|
485
|
-
await spendTx.fee(
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
647
|
+
await spendTx.fee(
|
|
648
|
+
{
|
|
649
|
+
computeFee: async () => 1
|
|
650
|
+
},
|
|
651
|
+
'random'
|
|
652
|
+
)
|
|
653
|
+
expect(spendTx.outputs.reduce((a, b) => a + (b.satoshis ?? 0), 0)).toEqual(8)
|
|
489
654
|
})
|
|
490
655
|
it('Distributes change randomly among multiple change outputs, thinnly spread', async () => {
|
|
491
656
|
const privateKey = new PrivateKey(1)
|
|
492
657
|
const publicKey = new Curve().g.mul(privateKey)
|
|
493
|
-
const publicKeyHash = hash160(publicKey.encode(true))
|
|
658
|
+
const publicKeyHash = hash160(publicKey.encode(true))
|
|
494
659
|
const p2pkh = new P2PKH()
|
|
495
|
-
const sourceTx = new Transaction(
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
660
|
+
const sourceTx = new Transaction(
|
|
661
|
+
1,
|
|
662
|
+
[],
|
|
663
|
+
[
|
|
664
|
+
{
|
|
665
|
+
lockingScript: p2pkh.lock(publicKeyHash),
|
|
666
|
+
satoshis: 46
|
|
667
|
+
}
|
|
668
|
+
],
|
|
669
|
+
0
|
|
670
|
+
)
|
|
671
|
+
const spendTx = new Transaction(
|
|
672
|
+
1,
|
|
673
|
+
[
|
|
674
|
+
{
|
|
675
|
+
sourceTransaction: sourceTx,
|
|
676
|
+
sourceOutputIndex: 0,
|
|
677
|
+
unlockingScriptTemplate: p2pkh.unlock(privateKey),
|
|
678
|
+
sequence: 0xffffffff
|
|
679
|
+
}
|
|
680
|
+
],
|
|
681
|
+
Array(21)
|
|
682
|
+
.fill(null)
|
|
683
|
+
.map(() => ({
|
|
684
|
+
lockingScript: p2pkh.lock(publicKeyHash),
|
|
685
|
+
change: true
|
|
686
|
+
})),
|
|
687
|
+
0
|
|
688
|
+
)
|
|
689
|
+
await spendTx.fee(
|
|
690
|
+
{
|
|
691
|
+
computeFee: async () => 1
|
|
692
|
+
},
|
|
693
|
+
'random'
|
|
694
|
+
)
|
|
695
|
+
expect(spendTx.outputs.reduce((a, b) => a + (b.satoshis ?? 0), 0)).toEqual(45)
|
|
512
696
|
})
|
|
513
697
|
it('Calculates fee for utxo based transaction', async () => {
|
|
514
|
-
const utxos = [
|
|
698
|
+
const utxos = [
|
|
699
|
+
// WoC format utxos
|
|
515
700
|
{
|
|
516
701
|
height: 1600000,
|
|
517
702
|
tx_pos: 0,
|
|
518
|
-
tx_hash:
|
|
703
|
+
tx_hash:
|
|
704
|
+
'672dd6a93fa5d7ba6794e0bdf8b479440b95a55ec10ad3d9e03585ecb5628d8d',
|
|
519
705
|
value: 10000
|
|
520
706
|
},
|
|
521
707
|
{
|
|
522
708
|
height: 1600000,
|
|
523
709
|
tx_pos: 0,
|
|
524
|
-
tx_hash:
|
|
710
|
+
tx_hash:
|
|
711
|
+
'f33505acf37a7726cc37d391bc6f889b8684ac2a2d581c4be2a4b1c8b46609bc',
|
|
525
712
|
value: 10000
|
|
526
713
|
}
|
|
527
714
|
]
|
|
@@ -564,9 +751,9 @@ describe('Transaction', () => {
|
|
|
564
751
|
txStatus: 'success',
|
|
565
752
|
extraInfo: 'received'
|
|
566
753
|
})
|
|
567
|
-
})
|
|
754
|
+
})
|
|
568
755
|
|
|
569
|
-
|
|
756
|
+
; (global as any).window = { fetch: mockedFetch } as any
|
|
570
757
|
|
|
571
758
|
const tx = new Transaction()
|
|
572
759
|
const rv = await tx.broadcast()
|
|
@@ -582,48 +769,70 @@ describe('Transaction', () => {
|
|
|
582
769
|
})
|
|
583
770
|
|
|
584
771
|
it('Broadcasts with the provided Broadcaster instance', async () => {
|
|
585
|
-
const mockBroadcast = jest.fn(() =>
|
|
772
|
+
const mockBroadcast = jest.fn(async (): Promise<BroadcastResponse> => {
|
|
773
|
+
return {
|
|
774
|
+
status: 'success', // Explicitly matches the literal type "success"
|
|
775
|
+
txid: 'mock_txid',
|
|
776
|
+
message: 'Transaction successfully broadcasted.'
|
|
777
|
+
}
|
|
778
|
+
})
|
|
779
|
+
|
|
586
780
|
const tx = new Transaction()
|
|
587
781
|
const rv = await tx.broadcast({
|
|
588
782
|
broadcast: mockBroadcast
|
|
589
783
|
})
|
|
784
|
+
|
|
785
|
+
// Ensure the mock function was called with the correct argument
|
|
590
786
|
expect(mockBroadcast).toHaveBeenCalledWith(tx)
|
|
591
|
-
expect(rv).toEqual('MOCK_RV')
|
|
592
|
-
})
|
|
593
|
-
})
|
|
594
787
|
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
788
|
+
// Verify the return value matches the mocked response
|
|
789
|
+
expect(rv).toEqual({
|
|
790
|
+
status: 'success',
|
|
791
|
+
txid: 'mock_txid',
|
|
792
|
+
message: 'Transaction successfully broadcasted.'
|
|
793
|
+
})
|
|
601
794
|
})
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
795
|
+
|
|
796
|
+
describe('BEEF', () => {
|
|
797
|
+
it('Serialization and deserialization', async () => {
|
|
798
|
+
const tx = Transaction.fromBEEF(toArray(BRC62Hex, 'hex'))
|
|
799
|
+
expect(tx.inputs[0].sourceTransaction?.merklePath?.blockHeight).toEqual(
|
|
800
|
+
814435
|
|
801
|
+
)
|
|
802
|
+
const beef = toHex(tx.toBEEF())
|
|
803
|
+
expect(beef).toEqual(BRC62Hex)
|
|
804
|
+
})
|
|
805
|
+
it('Does not double-encode transactions', () => {
|
|
806
|
+
// Source: https://github.com/bitcoin-sv/ts-sdk/issues/77
|
|
807
|
+
const incorrect =
|
|
808
|
+
'0100beef01fe76eb0c000e02c402deff5437203e0b5cb22646cbada24a60349bf45c8b280ffb755868f2955c3111c500f4076b7f48031fc467f87d5e99d9c3c0b59e4dca5e3049f58b735c59b413a8b6016300bad9c2d948e8a2ca647fdb50f2fd36641c4adf937b41134405a3e7f734b8beb201300053604a579558b5f7030e618d5c726a19229e0ff677f6edf109f41c5cfdafc93e0119005f8465c2a8d1558afbfa80c2395f3f8866a2fa5015e54fab778b0149da58376c010d00cd452b4e74f57d199cdb81b8a0e4a62dcdaf89504d6c63a5a65d5b866912b8c0010700d2ae7e2ce76da560509172066f1a1cf81faf81d73f9c0f6fd5af0904973dcfb10102006e5e077bcaa35c0240d61c1f3bba8d789223711ec035ef88b0911fc569d2b95a010000c961038959b9d404297a180c066816562dd2a34986c0960121a87ba91a51262f010100a50e381b4e8812479ea561e5bab7dcaa80078652b1b39ee5410966c515a3442b010100383ce8891ca7bf1ddefa5e0d8a1ba9ab01cb4e18046e9d7d0d438b5aaecc38b2010100c694be322b4e74acca8a5ef7703afedb708281321fd674f1221eebc743b0e01c0101000f3cc61f2b3d762cfecdd977ba768a5cbb0a4b402ad4f0d1bd3a98a582794c35010100094ad56eeea3b47edb2b298775f2efabe48172612cb3419962632251d8cdb78e010100de84bf9dd8873f37decbda1b5188e24ead978b147a63c809691702d19c47e8cb050200000001b67f1b6a6c3e70742a39b82ba45d51c983f598963ebf237101cc372da1144b83020000006b483045022100d14c3eb0c1438747c124f099bc664bf945cd27cbd96915027057e508bbc9e03302203c73f79d4e00f8018783e1008ce0fbb8e8c58bff6bd8042ab7e3966a66c8788c41210356762156ee9347c3e2ceca17d13713028d5446f453e9cbcb0ea170b4ca7fab52ffffffff037c660000000000001976a91417c85798ff61f7ec8af257f672d973b6ec6d88fd88ac75330100000000001976a914eb645f9ea7e4e232e54b9651474c100026698c3088acf2458005000000001976a914802737e30c85b6fe86e26fb28e03140058aca65e88ac0000000001000100000001deff5437203e0b5cb22646cbada24a60349bf45c8b280ffb755868f2955c3111000000006a473044022076da9f61380c208f43652587c219b4452a7b803a0407c2c7c0f3bc27612c4e88022021a9eb02da5529873a5986933f9c35965aa78537b9e2aef9382de33cfb1ab4bb41210314793e1758db3caa7d2bce97b347ae3ced2f8a402b797ed986be63473d4644a0ffffffff023c330000000000001976a91417c85798ff61f7ec8af257f672d973b6ec6d88fd88ac3c330000000000001976a91417c85798ff61f7ec8af257f672d973b6ec6d88fd88ac00000000000200000001b67f1b6a6c3e70742a39b82ba45d51c983f598963ebf237101cc372da1144b83020000006b483045022100d14c3eb0c1438747c124f099bc664bf945cd27cbd96915027057e508bbc9e03302203c73f79d4e00f8018783e1008ce0fbb8e8c58bff6bd8042ab7e3966a66c8788c41210356762156ee9347c3e2ceca17d13713028d5446f453e9cbcb0ea170b4ca7fab52ffffffff037c660000000000001976a91417c85798ff61f7ec8af257f672d973b6ec6d88fd88ac75330100000000001976a914eb645f9ea7e4e232e54b9651474c100026698c3088acf2458005000000001976a914802737e30c85b6fe86e26fb28e03140058aca65e88ac0000000001000100000001deff5437203e0b5cb22646cbada24a60349bf45c8b280ffb755868f2955c3111000000006a473044022076da9f61380c208f43652587c219b4452a7b803a0407c2c7c0f3bc27612c4e88022021a9eb02da5529873a5986933f9c35965aa78537b9e2aef9382de33cfb1ab4bb41210314793e1758db3caa7d2bce97b347ae3ced2f8a402b797ed986be63473d4644a0ffffffff023c330000000000001976a91417c85798ff61f7ec8af257f672d973b6ec6d88fd88ac3c330000000000001976a91417c85798ff61f7ec8af257f672d973b6ec6d88fd88ac000000000001000000022e7f69f3e1e17e22cfb8818577b3c83a4fbbbc1bab55c70ffcdd994ae30ea48b000000006b483045022100d9a2d1efea4896b36b2eb5af42cf52009982c7c31b446213fe37f26835d9d72202203e4dee0ceb068a4936e79b0bf69f72203906a00a4256cb1a7b30a40764616e8441210314793e1758db3caa7d2bce97b347ae3ced2f8a402b797ed986be63473d4644a0ffffffff2e7f69f3e1e17e22cfb8818577b3c83a4fbbbc1bab55c70ffcdd994ae30ea48b010000006b483045022100b57a09145c57b7b5efb4b546f1b0bfb7adbc5e64d35d9d6989345d4c60c483940220280998a210a49a6efaacda6fb73670001bb7269d069be80eb14ea2227a73e82241210314793e1758db3caa7d2bce97b347ae3ced2f8a402b797ed986be63473d4644a0ffffffff0174660000000000001976a91417c85798ff61f7ec8af257f672d973b6ec6d88fd88ac0000000000'
|
|
809
|
+
const correct =
|
|
810
|
+
'0100beef01fe76eb0c000e02c402deff5437203e0b5cb22646cbada24a60349bf45c8b280ffb755868f2955c3111c500f4076b7f48031fc467f87d5e99d9c3c0b59e4dca5e3049f58b735c59b413a8b6016300bad9c2d948e8a2ca647fdb50f2fd36641c4adf937b41134405a3e7f734b8beb201300053604a579558b5f7030e618d5c726a19229e0ff677f6edf109f41c5cfdafc93e0119005f8465c2a8d1558afbfa80c2395f3f8866a2fa5015e54fab778b0149da58376c010d00cd452b4e74f57d199cdb81b8a0e4a62dcdaf89504d6c63a5a65d5b866912b8c0010700d2ae7e2ce76da560509172066f1a1cf81faf81d73f9c0f6fd5af0904973dcfb10102006e5e077bcaa35c0240d61c1f3bba8d789223711ec035ef88b0911fc569d2b95a010000c961038959b9d404297a180c066816562dd2a34986c0960121a87ba91a51262f010100a50e381b4e8812479ea561e5bab7dcaa80078652b1b39ee5410966c515a3442b010100383ce8891ca7bf1ddefa5e0d8a1ba9ab01cb4e18046e9d7d0d438b5aaecc38b2010100c694be322b4e74acca8a5ef7703afedb708281321fd674f1221eebc743b0e01c0101000f3cc61f2b3d762cfecdd977ba768a5cbb0a4b402ad4f0d1bd3a98a582794c35010100094ad56eeea3b47edb2b298775f2efabe48172612cb3419962632251d8cdb78e010100de84bf9dd8873f37decbda1b5188e24ead978b147a63c809691702d19c47e8cb030200000001b67f1b6a6c3e70742a39b82ba45d51c983f598963ebf237101cc372da1144b83020000006b483045022100d14c3eb0c1438747c124f099bc664bf945cd27cbd96915027057e508bbc9e03302203c73f79d4e00f8018783e1008ce0fbb8e8c58bff6bd8042ab7e3966a66c8788c41210356762156ee9347c3e2ceca17d13713028d5446f453e9cbcb0ea170b4ca7fab52ffffffff037c660000000000001976a91417c85798ff61f7ec8af257f672d973b6ec6d88fd88ac75330100000000001976a914eb645f9ea7e4e232e54b9651474c100026698c3088acf2458005000000001976a914802737e30c85b6fe86e26fb28e03140058aca65e88ac0000000001000100000001deff5437203e0b5cb22646cbada24a60349bf45c8b280ffb755868f2955c3111000000006a473044022076da9f61380c208f43652587c219b4452a7b803a0407c2c7c0f3bc27612c4e88022021a9eb02da5529873a5986933f9c35965aa78537b9e2aef9382de33cfb1ab4bb41210314793e1758db3caa7d2bce97b347ae3ced2f8a402b797ed986be63473d4644a0ffffffff023c330000000000001976a91417c85798ff61f7ec8af257f672d973b6ec6d88fd88ac3c330000000000001976a91417c85798ff61f7ec8af257f672d973b6ec6d88fd88ac000000000001000000022e7f69f3e1e17e22cfb8818577b3c83a4fbbbc1bab55c70ffcdd994ae30ea48b000000006b483045022100d9a2d1efea4896b36b2eb5af42cf52009982c7c31b446213fe37f26835d9d72202203e4dee0ceb068a4936e79b0bf69f72203906a00a4256cb1a7b30a40764616e8441210314793e1758db3caa7d2bce97b347ae3ced2f8a402b797ed986be63473d4644a0ffffffff2e7f69f3e1e17e22cfb8818577b3c83a4fbbbc1bab55c70ffcdd994ae30ea48b010000006b483045022100b57a09145c57b7b5efb4b546f1b0bfb7adbc5e64d35d9d6989345d4c60c483940220280998a210a49a6efaacda6fb73670001bb7269d069be80eb14ea2227a73e82241210314793e1758db3caa7d2bce97b347ae3ced2f8a402b797ed986be63473d4644a0ffffffff0174660000000000001976a91417c85798ff61f7ec8af257f672d973b6ec6d88fd88ac0000000000'
|
|
811
|
+
const tx1 = Transaction.fromHexBEEF(incorrect)
|
|
812
|
+
expect(tx1.toHexBEEF()).toEqual(correct)
|
|
813
|
+
})
|
|
608
814
|
})
|
|
609
|
-
})
|
|
610
815
|
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
816
|
+
describe('EF', () => {
|
|
817
|
+
it('Serialization and deserialization', async () => {
|
|
818
|
+
const tx = Transaction.fromBEEF(toArray(BRC62Hex, 'hex'))
|
|
819
|
+
const ef = toHex(tx.toEF())
|
|
820
|
+
expect(ef).toEqual(
|
|
821
|
+
'010000000000000000ef01ac4e164f5bc16746bb0868404292ac8318bbac3800e4aad13a014da427adce3e000000006a47304402203a61a2e931612b4bda08d541cfb980885173b8dcf64a3471238ae7abcd368d6402204cbf24f04b9aa2256d8901f0ed97866603d2be8324c2bfb7a37bf8fc90edd5b441210263e2dee22b1ddc5e11f6fab8bcd2378bdd19580d640501ea956ec0e786f93e76ffffffff3e660000000000001976a9146bfd5c7fbe21529d45803dbcf0c87dd3c71efbc288ac013c660000000000001976a9146bfd5c7fbe21529d45803dbcf0c87dd3c71efbc288ac00000000'
|
|
822
|
+
)
|
|
823
|
+
})
|
|
616
824
|
})
|
|
617
|
-
})
|
|
618
825
|
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
826
|
+
describe('Verification', () => {
|
|
827
|
+
it('Verifies the transaction from the BEEF spec', async () => {
|
|
828
|
+
const tx = Transaction.fromHexBEEF(BRC62Hex)
|
|
829
|
+
const alwaysYesChainTracker = {
|
|
830
|
+
currentHeight: async () => 1631619, // Mocked current height
|
|
831
|
+
isValidRootForHeight: async () => true // Always returns true
|
|
832
|
+
}
|
|
833
|
+
const verified = await tx.verify(alwaysYesChainTracker)
|
|
834
|
+
expect(verified).toBe(true)
|
|
835
|
+
})
|
|
627
836
|
})
|
|
628
837
|
|
|
629
838
|
it('Verifies the transaction from the BEEF spec with a default chain tracker', async () => {
|
|
@@ -641,9 +850,8 @@ describe('Transaction', () => {
|
|
|
641
850
|
json: async () => ({
|
|
642
851
|
merkleroot: MerkleRootFromBEEF
|
|
643
852
|
})
|
|
644
|
-
})
|
|
645
|
-
|
|
646
|
-
|
|
853
|
+
})
|
|
854
|
+
; (global as any).window = { fetch: mockFetch }
|
|
647
855
|
|
|
648
856
|
const tx = Transaction.fromHexBEEF(BRC62Hex)
|
|
649
857
|
|
|
@@ -654,105 +862,295 @@ describe('Transaction', () => {
|
|
|
654
862
|
})
|
|
655
863
|
|
|
656
864
|
it('Verifies the transaction from the BEEF spec with a scripts only', async () => {
|
|
657
|
-
const BEEF =
|
|
658
|
-
|
|
865
|
+
const BEEF =
|
|
866
|
+
'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'
|
|
867
|
+
const tx = Transaction.fromBEEF(toArray(BEEF, 'base64'))
|
|
659
868
|
|
|
660
869
|
// Verifies transaction with scripts only
|
|
661
|
-
const verified = await tx.verify(
|
|
870
|
+
const verified = await tx.verify('scripts only')
|
|
662
871
|
expect(verified).toBe(true)
|
|
663
872
|
})
|
|
664
873
|
|
|
665
874
|
it('Verifies tx scripts only when our input has no MerklePath.', async () => {
|
|
666
|
-
const sourceTransaction = Transaction.fromHex(
|
|
667
|
-
|
|
668
|
-
|
|
875
|
+
const sourceTransaction = Transaction.fromHex(
|
|
876
|
+
'01000000013834506e4af751dc3a0d73e9bdd067709ade5248860967fb3eb72854be6011dc020000006b4830450221008abf2ce1afbcc3c4895265b0966ac69e2275fb35a738f9873b5416cd3bb68cc102202c906f9771d2d6868f81a34d6a3af4cd7de070969286db7097c5e0f3a009b638412102f6a81c442dcd903c7808a75abde9217268bb70417ad538c18fb597b4c553c354ffffffff0301000000000000007c21039bf52152665699e24c1018bf5b48e575de316f844962a79db32b93b7e328bf71ac1062656e63686d61726b546f6b656e5f36463044022034ca3cc49163e4d5bc24f41c5ea4631efd4ae7c243f904c90e1db6e6a55e8f0e02206bb031baca2fc6d64da5ad722ce2e07137718e5e58092e5ecf54e52fcdd664ab6dc8000000000000001976a91470763a553d615a8144fa0889a0e1f93d1d8da8b088acaf430000000000001976a9145aa12f9be0121eee54e7331d8f995fe4dded72f588ac00000000'
|
|
877
|
+
)
|
|
878
|
+
const tx = Transaction.fromHex(
|
|
879
|
+
'01000000015c22e8d34a95a761a0685b8b5a99a0845e9f03d87d5716a7351d08939db5cd92020000006a47304402205101f2bdc40098cbde1a270071a5bfdd5a6fbefc8a38a8b4a1adaca0a6ff55e702200ec5c0a57cb65dfc6aa22e6856bb4c62b8987a7b9fa32cb601c94b579ba67d83412103c8be6b217fc55939851e28239fbbf731f997e026ad344aa9d4b739181fe96743ffffffff0301000000000000007c21039bf52152665699e24c1018bf5b48e575de316f844962a79db32b93b7e328bf71ac1062656e63686d61726b546f6b656e5f374630440220026808e9453f75ca1fc3c7bb0f7be1efaca5cea6b1eda96ab7db56c519b6793202207d1fa5e7d54254d2142256947f93a061781280a6ed2464052470633a7c888d1f6dc8000000000000001976a91428bb6f207ac8f4b7f6c1c5914e143a6165586b2488ace5420000000000001976a914197cbde77abbcb985ca60a85c2988b2ac32c541a88ac00000000'
|
|
880
|
+
)
|
|
881
|
+
|
|
882
|
+
// Create a mock MerklePath
|
|
883
|
+
const mockMerklePath = new MerklePath(0, [
|
|
884
|
+
[{ offset: 0, hash: 'dummyHash' }]
|
|
885
|
+
])
|
|
886
|
+
sourceTransaction.merklePath = mockMerklePath
|
|
887
|
+
|
|
669
888
|
tx.inputs[0].sourceTransaction = sourceTransaction
|
|
670
889
|
const verified = await tx.verify('scripts only', undefined)
|
|
671
890
|
expect(verified).toBe(true)
|
|
672
891
|
})
|
|
673
|
-
})
|
|
674
892
|
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
893
|
+
describe('vectors: a 1mb transaction', () => {
|
|
894
|
+
it('should find the correct id of this (valid, on the blockchain) 1 mb transaction', () => {
|
|
895
|
+
const txidhex = bigTX.txidhex
|
|
896
|
+
const txhex = bigTX.txhex
|
|
897
|
+
const tx = Transaction.fromHex(txhex)
|
|
898
|
+
const txid = tx.id('hex')
|
|
899
|
+
expect(txid).toEqual(txidhex)
|
|
900
|
+
})
|
|
682
901
|
})
|
|
683
|
-
})
|
|
684
902
|
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
903
|
+
describe('vectors: sighash and serialization', () => {
|
|
904
|
+
sighashVectors.forEach((vector, i) => {
|
|
905
|
+
if (i === 0) {
|
|
906
|
+
return
|
|
907
|
+
}
|
|
908
|
+
it(`should pass bitcoin-abc sighash test vector ${i}`, () => {
|
|
909
|
+
const txbuf = toArray(vector[0], 'hex')
|
|
910
|
+
const scriptbuf = toArray(vector[1], 'hex')
|
|
911
|
+
const subScript = Script.fromBinary(scriptbuf)
|
|
912
|
+
const nIn = vector[2] as number
|
|
913
|
+
const nHashType = vector[3] as number
|
|
914
|
+
const sighashBuf = toArray(vector[4], 'hex')
|
|
915
|
+
const tx = Transaction.fromBinary(txbuf)
|
|
916
|
+
|
|
917
|
+
// make sure transacion to/from buffer is isomorphic
|
|
918
|
+
expect(toHex(tx.toBinary())).toEqual(toHex(txbuf))
|
|
919
|
+
|
|
920
|
+
// sighash ought to be correct
|
|
921
|
+
const valueBn = new BigNumber(0).toNumber()
|
|
922
|
+
const otherInputs = [...tx.inputs]
|
|
923
|
+
const [input] = otherInputs.splice(nIn, 1)
|
|
924
|
+
const preimage = TransactionSignature.format({
|
|
925
|
+
sourceTXID: input.sourceTXID ?? '',
|
|
926
|
+
sourceOutputIndex: input.sourceOutputIndex,
|
|
927
|
+
sourceSatoshis: valueBn,
|
|
928
|
+
transactionVersion: tx.version,
|
|
929
|
+
otherInputs,
|
|
930
|
+
outputs: tx.outputs,
|
|
931
|
+
inputIndex: nIn,
|
|
932
|
+
subscript: subScript,
|
|
933
|
+
inputSequence: input.sequence ?? 0xffffffff,
|
|
934
|
+
lockTime: tx.lockTime,
|
|
935
|
+
scope: nHashType
|
|
936
|
+
})
|
|
937
|
+
const hash = hash256(preimage)
|
|
938
|
+
hash.reverse()
|
|
939
|
+
expect(toHex(hash)).toEqual(toHex(sighashBuf))
|
|
718
940
|
})
|
|
719
|
-
const hash = hash256(preimage) as number[]
|
|
720
|
-
hash.reverse()
|
|
721
|
-
expect(toHex(hash)).toEqual(toHex(sighashBuf))
|
|
722
941
|
})
|
|
723
|
-
})
|
|
724
942
|
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
943
|
+
validTransactions.forEach((vector, i) => {
|
|
944
|
+
if (vector.length === 1) {
|
|
945
|
+
return
|
|
946
|
+
}
|
|
947
|
+
it(`should correctly serialized/deserialize tx_valid test vector ${i}`, () => {
|
|
948
|
+
const expectedHex = vector[1]
|
|
949
|
+
const expectedBin = toArray(vector[1], 'hex')
|
|
950
|
+
const actualTX = Transaction.fromBinary(expectedBin)
|
|
951
|
+
const actualBin = actualTX.toBinary()
|
|
952
|
+
const actualHex = toHex(actualBin)
|
|
953
|
+
expect(actualHex).toEqual(expectedHex)
|
|
954
|
+
})
|
|
955
|
+
})
|
|
956
|
+
|
|
957
|
+
invalidTransactions.forEach((vector, i) => {
|
|
958
|
+
if (vector.length === 1) {
|
|
959
|
+
return
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
// 151, 142 and 25 have invalid Satoshi amounts that exceed 53 bits in length, causing exceptions that make serialization and deserialization impossible.
|
|
963
|
+
if (i === 151 || i === 142 || i === 25) {
|
|
964
|
+
return
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
it(`should correctly serialized/deserialize tx_invalid test vector ${i}`, () => {
|
|
968
|
+
const expectedHex = vector[1]
|
|
969
|
+
const expectedBin = toArray(vector[1], 'hex')
|
|
970
|
+
const actualTX = Transaction.fromBinary(expectedBin)
|
|
971
|
+
const actualBin = actualTX.toBinary()
|
|
972
|
+
const actualHex = toHex(actualBin)
|
|
973
|
+
expect(actualHex).toEqual(expectedHex)
|
|
974
|
+
})
|
|
736
975
|
})
|
|
737
976
|
})
|
|
738
977
|
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
978
|
+
describe('Atomic BEEF', () => {
|
|
979
|
+
it('should serialize a transaction to Atomic BEEF format correctly', async () => {
|
|
980
|
+
const privateKey = new PrivateKey(1)
|
|
981
|
+
const publicKey = new Curve().g.mul(privateKey)
|
|
982
|
+
const publicKeyHash = hash160(publicKey.encode(true))
|
|
983
|
+
const p2pkh = new P2PKH()
|
|
984
|
+
|
|
985
|
+
// Create a simple transaction
|
|
986
|
+
const sourceTx = new Transaction(
|
|
987
|
+
1,
|
|
988
|
+
[],
|
|
989
|
+
[
|
|
990
|
+
{
|
|
991
|
+
lockingScript: p2pkh.lock(publicKeyHash),
|
|
992
|
+
satoshis: 10000
|
|
993
|
+
}
|
|
994
|
+
],
|
|
995
|
+
0
|
|
996
|
+
)
|
|
997
|
+
|
|
998
|
+
const spendTx = new Transaction(
|
|
999
|
+
1,
|
|
1000
|
+
[
|
|
1001
|
+
{
|
|
1002
|
+
sourceTransaction: sourceTx,
|
|
1003
|
+
sourceOutputIndex: 0,
|
|
1004
|
+
unlockingScriptTemplate: p2pkh.unlock(privateKey),
|
|
1005
|
+
sequence: 0xffffffff
|
|
1006
|
+
}
|
|
1007
|
+
],
|
|
1008
|
+
[
|
|
1009
|
+
{
|
|
1010
|
+
satoshis: 9000,
|
|
1011
|
+
lockingScript: p2pkh.lock(publicKeyHash)
|
|
1012
|
+
}
|
|
1013
|
+
],
|
|
1014
|
+
0
|
|
1015
|
+
)
|
|
1016
|
+
|
|
1017
|
+
// Sign the transaction
|
|
1018
|
+
await spendTx.fee()
|
|
1019
|
+
await spendTx.sign()
|
|
1020
|
+
|
|
1021
|
+
// Assign a MerklePath to the source transaction to simulate mined transaction
|
|
1022
|
+
const sourceTxID = sourceTx.id('hex')
|
|
1023
|
+
const merklePath = new MerklePath(1000, [
|
|
1024
|
+
[
|
|
1025
|
+
{ offset: 0, hash: sourceTxID, txid: true },
|
|
1026
|
+
{ offset: 1, duplicate: true }
|
|
1027
|
+
]
|
|
1028
|
+
])
|
|
1029
|
+
sourceTx.merklePath = merklePath
|
|
1030
|
+
|
|
1031
|
+
// Serialize to Atomic BEEF
|
|
1032
|
+
const atomicBEEF = spendTx.toAtomicBEEF()
|
|
1033
|
+
expect(atomicBEEF).toBeDefined()
|
|
1034
|
+
// Verify that the Atomic BEEF starts with the correct prefix and TXID
|
|
1035
|
+
const expectedPrefix = [0x01, 0x01, 0x01, 0x01]
|
|
1036
|
+
expect(atomicBEEF.slice(0, 4)).toEqual(expectedPrefix)
|
|
1037
|
+
const txid = spendTx.id()
|
|
1038
|
+
expect(atomicBEEF.slice(4, 36)).toEqual(txid)
|
|
1039
|
+
|
|
1040
|
+
// Deserialize from Atomic BEEF
|
|
1041
|
+
const deserializedTx = Transaction.fromAtomicBEEF(atomicBEEF)
|
|
1042
|
+
expect(deserializedTx.toHex()).toEqual(spendTx.toHex())
|
|
1043
|
+
})
|
|
743
1044
|
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
1045
|
+
it('should throw an error when deserializing Atomic BEEF if subject transaction is missing', () => {
|
|
1046
|
+
// Create Atomic BEEF data with missing subject transaction
|
|
1047
|
+
const writer = new Writer()
|
|
1048
|
+
// Write Atomic BEEF prefix
|
|
1049
|
+
writer.writeUInt32LE(0x01010101)
|
|
1050
|
+
// Write subject TXID
|
|
1051
|
+
const fakeTXID = toArray('00'.repeat(32), 'hex')
|
|
1052
|
+
writer.write(fakeTXID)
|
|
1053
|
+
// Write empty BEEF data
|
|
1054
|
+
writer.writeUInt32LE(BEEF_V1) // BEEF version
|
|
1055
|
+
writer.writeVarIntNum(0) // No BUMPs
|
|
1056
|
+
writer.writeVarIntNum(0) // No transactions
|
|
1057
|
+
|
|
1058
|
+
const atomicBEEFData = writer.toArray()
|
|
1059
|
+
|
|
1060
|
+
expect(() => {
|
|
1061
|
+
Transaction.fromAtomicBEEF(atomicBEEFData)
|
|
1062
|
+
}).toThrow('beef must include at least one transaction.')
|
|
1063
|
+
})
|
|
1064
|
+
|
|
1065
|
+
it('should allow selecting a specific TXID from BEEF data', async () => {
|
|
1066
|
+
// Create two transactions, one depending on the other
|
|
1067
|
+
const privateKey = new PrivateKey(1)
|
|
1068
|
+
const publicKey = new Curve().g.mul(privateKey)
|
|
1069
|
+
const publicKeyHash = hash160(publicKey.encode(true)) as number[]
|
|
1070
|
+
const p2pkh = new P2PKH()
|
|
1071
|
+
|
|
1072
|
+
const sourceTx = new Transaction(
|
|
1073
|
+
1,
|
|
1074
|
+
[],
|
|
1075
|
+
[
|
|
1076
|
+
{
|
|
1077
|
+
lockingScript: p2pkh.lock(publicKeyHash),
|
|
1078
|
+
satoshis: 10000
|
|
1079
|
+
}
|
|
1080
|
+
],
|
|
1081
|
+
0
|
|
1082
|
+
)
|
|
1083
|
+
|
|
1084
|
+
const spendTx = new Transaction(
|
|
1085
|
+
1,
|
|
1086
|
+
[
|
|
1087
|
+
{
|
|
1088
|
+
sourceTransaction: sourceTx,
|
|
1089
|
+
sourceOutputIndex: 0,
|
|
1090
|
+
unlockingScriptTemplate: p2pkh.unlock(privateKey),
|
|
1091
|
+
sequence: 0xffffffff
|
|
1092
|
+
}
|
|
1093
|
+
],
|
|
1094
|
+
[
|
|
1095
|
+
{
|
|
1096
|
+
satoshis: 9000,
|
|
1097
|
+
lockingScript: p2pkh.lock(publicKeyHash)
|
|
1098
|
+
}
|
|
1099
|
+
],
|
|
1100
|
+
0
|
|
1101
|
+
)
|
|
1102
|
+
|
|
1103
|
+
// Sign transactions
|
|
1104
|
+
await spendTx.fee()
|
|
1105
|
+
await spendTx.sign()
|
|
1106
|
+
|
|
1107
|
+
// Assign merkle path to source transaction
|
|
1108
|
+
const sourceTxID = sourceTx.id('hex')
|
|
1109
|
+
sourceTx.merklePath = new MerklePath(1000, [
|
|
1110
|
+
[
|
|
1111
|
+
{ offset: 0, hash: sourceTxID, txid: true },
|
|
1112
|
+
{ offset: 1, duplicate: true }
|
|
1113
|
+
]
|
|
1114
|
+
])
|
|
1115
|
+
|
|
1116
|
+
// Serialize to BEEF
|
|
1117
|
+
const beefData = spendTx.toBEEF()
|
|
1118
|
+
// Get TXIDs
|
|
1119
|
+
const spendTxID = spendTx.id('hex')
|
|
1120
|
+
|
|
1121
|
+
// Deserialize the source transaction from BEEF data
|
|
1122
|
+
const deserializedSourceTx = Transaction.fromBEEF(beefData, sourceTxID)
|
|
1123
|
+
expect(deserializedSourceTx.id('hex')).toEqual(sourceTxID)
|
|
1124
|
+
|
|
1125
|
+
// Deserialize the spend transaction from BEEF data
|
|
1126
|
+
const deserializedSpendTx = Transaction.fromBEEF(beefData, spendTxID)
|
|
1127
|
+
expect(deserializedSpendTx.id('hex')).toEqual(spendTxID)
|
|
1128
|
+
|
|
1129
|
+
// Attempt to deserialize a non-existent transaction
|
|
1130
|
+
expect(() => {
|
|
1131
|
+
Transaction.fromBEEF(beefData, '00'.repeat(32))
|
|
1132
|
+
}).toThrowError(
|
|
1133
|
+
'Transaction with TXID 0000000000000000000000000000000000000000000000000000000000000000 not found in BEEF data.'
|
|
1134
|
+
)
|
|
1135
|
+
})
|
|
1136
|
+
})
|
|
748
1137
|
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
const
|
|
752
|
-
const
|
|
753
|
-
const
|
|
754
|
-
|
|
755
|
-
|
|
1138
|
+
describe('addP2PKHOutput', () => {
|
|
1139
|
+
it('should create an output on the current transaction using an address hash or string', async () => {
|
|
1140
|
+
const privateKey = PrivateKey.fromRandom()
|
|
1141
|
+
const lockingScript = new P2PKH().lock(privateKey.toAddress())
|
|
1142
|
+
const tx = new Transaction()
|
|
1143
|
+
tx.addInput({
|
|
1144
|
+
sourceTXID: '00'.repeat(32),
|
|
1145
|
+
sourceOutputIndex: 0,
|
|
1146
|
+
unlockingScriptTemplate: new P2PKH().unlock(privateKey)
|
|
1147
|
+
})
|
|
1148
|
+
tx.addP2PKHOutput(privateKey.toAddress(), 10000)
|
|
1149
|
+
expect(tx.outputs.length).toEqual(1)
|
|
1150
|
+
expect(tx.outputs[0].satoshis).toEqual(10000)
|
|
1151
|
+
expect(
|
|
1152
|
+
tx.outputs[0].lockingScript.toHex() === lockingScript.toHex()
|
|
1153
|
+
).toBeTruthy()
|
|
756
1154
|
})
|
|
757
1155
|
})
|
|
758
1156
|
})
|
|
@@ -825,98 +1223,7 @@ describe('Transaction', () => {
|
|
|
825
1223
|
|
|
826
1224
|
expect(() => {
|
|
827
1225
|
Transaction.fromAtomicBEEF(atomicBEEFData)
|
|
828
|
-
}).toThrowError('
|
|
829
|
-
})
|
|
830
|
-
|
|
831
|
-
it('should throw an error when deserializing Atomic BEEF if there are unrelated transactions', async () => {
|
|
832
|
-
// Create two unrelated transactions
|
|
833
|
-
const privateKey1 = new PrivateKey(1)
|
|
834
|
-
const publicKey1 = new Curve().g.mul(privateKey1)
|
|
835
|
-
const publicKeyHash1 = hash160(publicKey1.encode(true)) as number[]
|
|
836
|
-
const p2pkh = new P2PKH()
|
|
837
|
-
|
|
838
|
-
const sourceTx1 = new Transaction(1, [], [{
|
|
839
|
-
lockingScript: p2pkh.lock(publicKeyHash1),
|
|
840
|
-
satoshis: 10000
|
|
841
|
-
}], 0)
|
|
842
|
-
|
|
843
|
-
const spendTx1 = new Transaction(1, [{
|
|
844
|
-
sourceTransaction: sourceTx1,
|
|
845
|
-
sourceOutputIndex: 0,
|
|
846
|
-
unlockingScriptTemplate: p2pkh.unlock(privateKey1),
|
|
847
|
-
sequence: 0xffffffff
|
|
848
|
-
}], [{
|
|
849
|
-
satoshis: 9000,
|
|
850
|
-
lockingScript: p2pkh.lock(publicKeyHash1)
|
|
851
|
-
}], 0)
|
|
852
|
-
|
|
853
|
-
// Another unrelated transaction
|
|
854
|
-
const privateKey2 = new PrivateKey(2)
|
|
855
|
-
const publicKey2 = new Curve().g.mul(privateKey2)
|
|
856
|
-
const publicKeyHash2 = hash160(publicKey2.encode(true)) as number[]
|
|
857
|
-
|
|
858
|
-
const sourceTx2 = new Transaction(1, [], [{
|
|
859
|
-
lockingScript: p2pkh.lock(publicKeyHash2),
|
|
860
|
-
satoshis: 10000
|
|
861
|
-
}], 0)
|
|
862
|
-
|
|
863
|
-
// Assign merkle paths to source transactions to simulate mined transactions
|
|
864
|
-
const sourceTx1ID = sourceTx1.id('hex')
|
|
865
|
-
const sourceTx2ID = sourceTx2.id('hex')
|
|
866
|
-
sourceTx1.merklePath = new MerklePath(1000, [
|
|
867
|
-
[
|
|
868
|
-
{ offset: 0, hash: sourceTx1ID, txid: true },
|
|
869
|
-
{ offset: 1, duplicate: true }
|
|
870
|
-
]
|
|
871
|
-
])
|
|
872
|
-
sourceTx2.merklePath = new MerklePath(1001, [
|
|
873
|
-
[
|
|
874
|
-
{ offset: 0, hash: sourceTx2ID, txid: true },
|
|
875
|
-
{ offset: 1, duplicate: true }
|
|
876
|
-
]
|
|
877
|
-
])
|
|
878
|
-
|
|
879
|
-
// Sign the transaction
|
|
880
|
-
await spendTx1.fee()
|
|
881
|
-
await spendTx1.sign()
|
|
882
|
-
|
|
883
|
-
// Construct the Atomic BEEF data manually, including the unrelated transaction
|
|
884
|
-
const writer = new Writer()
|
|
885
|
-
// Write Atomic BEEF prefix
|
|
886
|
-
writer.writeUInt32LE(0x01010101)
|
|
887
|
-
// Write subject TXID (spendTx1)
|
|
888
|
-
const spendTx1ID = spendTx1.id()
|
|
889
|
-
writer.write(spendTx1ID)
|
|
890
|
-
|
|
891
|
-
// Build BEEF data
|
|
892
|
-
const beefWriter = new Writer()
|
|
893
|
-
beefWriter.writeUInt32LE(BEEF_V1) // BEEF version
|
|
894
|
-
// BUMPs
|
|
895
|
-
beefWriter.writeVarIntNum(2)
|
|
896
|
-
beefWriter.write(sourceTx1.merklePath.toBinary())
|
|
897
|
-
beefWriter.write(sourceTx2.merklePath.toBinary())
|
|
898
|
-
// Transactions
|
|
899
|
-
beefWriter.writeVarIntNum(3)
|
|
900
|
-
// Transaction 1 (sourceTx1)
|
|
901
|
-
beefWriter.write(sourceTx1.toBinary())
|
|
902
|
-
beefWriter.writeUInt8(1) // hasBump
|
|
903
|
-
beefWriter.writeVarIntNum(0) // BUMP index
|
|
904
|
-
// Transaction 2 (sourceTx2) - unrelated
|
|
905
|
-
beefWriter.write(sourceTx2.toBinary())
|
|
906
|
-
beefWriter.writeUInt8(1) // hasBump
|
|
907
|
-
beefWriter.writeVarIntNum(1) // BUMP index
|
|
908
|
-
// Transaction 3 (spendTx1)
|
|
909
|
-
beefWriter.write(spendTx1.toBinary())
|
|
910
|
-
beefWriter.writeUInt8(0) // no BUMP
|
|
911
|
-
|
|
912
|
-
// Combine Atomic BEEF data
|
|
913
|
-
writer.write(beefWriter.toArray())
|
|
914
|
-
const atomicBEEFData = writer.toArray()
|
|
915
|
-
|
|
916
|
-
// Attempt to deserialize
|
|
917
|
-
expect(() => {
|
|
918
|
-
Transaction.fromAtomicBEEF(atomicBEEFData)
|
|
919
|
-
}).toThrowError(/Unrelated transaction with TXID .+ found in Atomic BEEF data./)
|
|
1226
|
+
}).toThrowError('beef must include at least one transaction.')
|
|
920
1227
|
})
|
|
921
1228
|
|
|
922
1229
|
it('should allow selecting a specific TXID from BEEF data', async () => {
|
|
@@ -984,37 +1291,6 @@ describe('Transaction', () => {
|
|
|
984
1291
|
sourceOutputIndex: 0,
|
|
985
1292
|
unlockingScriptTemplate: new P2PKH().unlock(privateKey),
|
|
986
1293
|
})
|
|
987
|
-
tx.addP2PKHOutput(privateKey.toAddress(), 10000)
|
|
988
|
-
expect(tx.outputs.length).toEqual(1)
|
|
989
|
-
expect(tx.outputs[0].satoshis).toEqual(10000)
|
|
990
|
-
expect(tx.outputs[0].lockingScript.toHex() === lockingScript.toHex()).toBeTruthy()
|
|
991
|
-
})
|
|
992
|
-
it('should error is the address is non base58', async () => {
|
|
993
|
-
const tx = new Transaction()
|
|
994
|
-
expect(() => tx.addP2PKHOutput('A small chicken', 10000)).toThrow("Invalid base58 character ")
|
|
995
|
-
})
|
|
996
|
-
it('should error if the address is incorrectly copied', async () => {
|
|
997
|
-
const tx = new Transaction()
|
|
998
|
-
expect(() => tx.addP2PKHOutput('14afWk1jLH9Uwi2mC9C5ehrsvcFxTLYDp', 10000)).toThrow("Invalid checksum")
|
|
999
|
-
})
|
|
1000
|
-
it('should error if the address is a hash of wrong length', async () => {
|
|
1001
|
-
const tx = new Transaction()
|
|
1002
|
-
const address = [1,2,3,4,5]
|
|
1003
|
-
expect(() => tx.addP2PKHOutput(address, 10000)).toThrow("P2PKH hash length must be 20 bytes")
|
|
1004
|
-
})
|
|
1005
|
-
it('should set the output to a change output if the satoshi value is not given', async () => {
|
|
1006
|
-
const tx = new Transaction()
|
|
1007
|
-
tx.addP2PKHOutput('18E63MgXH43KBb288ETM8u91J2cqdGNEmg')
|
|
1008
|
-
expect(tx.outputs[0].change).toBeTruthy()
|
|
1009
|
-
expect(tx.outputs[0].satoshis).toBeUndefined()
|
|
1010
|
-
})
|
|
1011
|
-
it('throw error when satoshi value is negative', async () => {
|
|
1012
|
-
const tx = new Transaction()
|
|
1013
|
-
expect(() => tx.addP2PKHOutput('18E63MgXH43KBb288ETM8u91J2cqdGNEmg', -1000)).toThrow('satoshis must be a positive integer or zero')
|
|
1014
|
-
})
|
|
1015
|
-
it('throw error when output does not set satoshi value', async () => {
|
|
1016
|
-
const tx = new Transaction()
|
|
1017
|
-
expect(() => tx.addOutput({ lockingScript: Script.fromASM('OP_TRUE') })).toThrow('either satoshis must be defined or change must be set to true')
|
|
1018
1294
|
})
|
|
1019
1295
|
})
|
|
1020
1296
|
})
|