@bsv/sdk 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/README.md +25 -3
  2. package/package.json +9 -5
  3. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -40
  4. package/.github/ISSUE_TEMPLATE/discussion.md +0 -24
  5. package/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md +0 -23
  6. package/CHANGELOG.md +0 -72
  7. package/CONTRIBUTING.md +0 -85
  8. package/ROADMAP.md +0 -3
  9. package/docs/getting-started/COMMONJS.md +0 -94
  10. package/docs/getting-started/REACT-TS.md +0 -131
  11. package/docs/getting-started/TS-NODE.md +0 -106
  12. package/docs/getting-started/VUE.md +0 -103
  13. package/jest.config.js +0 -6
  14. package/mod.ts +0 -8
  15. package/src/compat/BSM.ts +0 -51
  16. package/src/compat/ECIES.ts +0 -557
  17. package/src/compat/HD.ts +0 -348
  18. package/src/compat/Mnemonic.ts +0 -295
  19. package/src/compat/__tests/BSM.test.ts +0 -38
  20. package/src/compat/__tests/ECIES.test.ts +0 -90
  21. package/src/compat/__tests/HD.test.ts +0 -405
  22. package/src/compat/__tests/Mnemonic.test.ts +0 -177
  23. package/src/compat/__tests/Mnemonic.vectors.ts +0 -172
  24. package/src/compat/bip-39-wordlist-en.ts +0 -2053
  25. package/src/compat/index.ts +0 -4
  26. package/src/messages/EncryptedMessage.ts +0 -70
  27. package/src/messages/SignedMessage.ts +0 -87
  28. package/src/messages/__tests/EncryptedMessage.test.ts +0 -36
  29. package/src/messages/__tests/SignedMessage.test.ts +0 -53
  30. package/src/messages/index.ts +0 -2
  31. package/src/primitives/AESGCM.ts +0 -479
  32. package/src/primitives/BasePoint.ts +0 -21
  33. package/src/primitives/BigNumber.ts +0 -4619
  34. package/src/primitives/Curve.ts +0 -1163
  35. package/src/primitives/DRBG.ts +0 -102
  36. package/src/primitives/ECDSA.ts +0 -164
  37. package/src/primitives/Hash.ts +0 -1420
  38. package/src/primitives/JacobianPoint.ts +0 -410
  39. package/src/primitives/K256.ts +0 -116
  40. package/src/primitives/Mersenne.ts +0 -123
  41. package/src/primitives/MontgomoryMethod.ts +0 -160
  42. package/src/primitives/Point.ts +0 -852
  43. package/src/primitives/PrivateKey.ts +0 -195
  44. package/src/primitives/PublicKey.ts +0 -154
  45. package/src/primitives/Random.ts +0 -55
  46. package/src/primitives/ReductionContext.ts +0 -528
  47. package/src/primitives/Signature.ts +0 -235
  48. package/src/primitives/SymmetricKey.ts +0 -75
  49. package/src/primitives/TransactionSignature.ts +0 -189
  50. package/src/primitives/__tests/AESGCM.test.ts +0 -338
  51. package/src/primitives/__tests/BRC42.private.vectors.ts +0 -33
  52. package/src/primitives/__tests/BRC42.public.vectors.ts +0 -33
  53. package/src/primitives/__tests/BigNumber.arithmatic.test.ts +0 -572
  54. package/src/primitives/__tests/BigNumber.binary.test.ts +0 -203
  55. package/src/primitives/__tests/BigNumber.constructor.test.ts +0 -176
  56. package/src/primitives/__tests/BigNumber.dhGroup.test.ts +0 -18
  57. package/src/primitives/__tests/BigNumber.fixtures.ts +0 -264
  58. package/src/primitives/__tests/BigNumber.serializers.test.ts +0 -157
  59. package/src/primitives/__tests/BigNumber.utils.test.ts +0 -347
  60. package/src/primitives/__tests/Curve.unit.test.ts +0 -192
  61. package/src/primitives/__tests/DRBG.test.ts +0 -18
  62. package/src/primitives/__tests/DRBG.vectors.ts +0 -167
  63. package/src/primitives/__tests/ECDH.test.ts +0 -31
  64. package/src/primitives/__tests/ECDSA.test.ts +0 -58
  65. package/src/primitives/__tests/HMAC.test.ts +0 -59
  66. package/src/primitives/__tests/Hash.test.ts +0 -121
  67. package/src/primitives/__tests/PBKDF2.vectors.ts +0 -119
  68. package/src/primitives/__tests/PrivateKey.test.ts +0 -17
  69. package/src/primitives/__tests/PublicKey.test.ts +0 -66
  70. package/src/primitives/__tests/Random.test.ts +0 -14
  71. package/src/primitives/__tests/Reader.test.ts +0 -296
  72. package/src/primitives/__tests/ReductionContext.test.ts +0 -279
  73. package/src/primitives/__tests/SymmetricKey.test.ts +0 -58
  74. package/src/primitives/__tests/SymmetricKey.vectors.ts +0 -40
  75. package/src/primitives/__tests/Writer.test.ts +0 -198
  76. package/src/primitives/__tests/sighash.vectors.ts +0 -3503
  77. package/src/primitives/__tests/utils.test.ts +0 -108
  78. package/src/primitives/index.ts +0 -8
  79. package/src/primitives/utils.ts +0 -665
  80. package/src/script/LockingScript.ts +0 -30
  81. package/src/script/OP.ts +0 -219
  82. package/src/script/Script.ts +0 -426
  83. package/src/script/ScriptChunk.ts +0 -7
  84. package/src/script/ScriptTemplate.ts +0 -36
  85. package/src/script/Spend.ts +0 -1379
  86. package/src/script/UnlockingScript.ts +0 -30
  87. package/src/script/__tests/Script.test.ts +0 -369
  88. package/src/script/__tests/Spend.test.ts +0 -248
  89. package/src/script/__tests/script.invalid.vectors.ts +0 -925
  90. package/src/script/__tests/script.valid.vectors.ts +0 -1120
  91. package/src/script/__tests/scriptFromVector.ts +0 -42
  92. package/src/script/__tests/spend.valid.vectors.ts +0 -2288
  93. package/src/script/index.ts +0 -7
  94. package/src/script/templates/P2PKH.ts +0 -109
  95. package/src/script/templates/RPuzzle.ts +0 -140
  96. package/src/script/templates/index.ts +0 -2
  97. package/src/transaction/Broadcaster.ts +0 -42
  98. package/src/transaction/ChainTracker.ts +0 -22
  99. package/src/transaction/FeeModel.ts +0 -13
  100. package/src/transaction/MerklePath.ts +0 -259
  101. package/src/transaction/Transaction.ts +0 -602
  102. package/src/transaction/TransactionInput.ts +0 -63
  103. package/src/transaction/TransactionOutput.ts +0 -37
  104. package/src/transaction/__tests/MerklePath.test.ts +0 -181
  105. package/src/transaction/__tests/Transaction.test.ts +0 -413
  106. package/src/transaction/__tests/bigtx.vectors.ts +0 -4
  107. package/src/transaction/__tests/bump.invalid.vectors.ts +0 -8
  108. package/src/transaction/__tests/bump.valid.vectors.ts +0 -4
  109. package/src/transaction/__tests/tx.invalid.vectors.ts +0 -281
  110. package/src/transaction/__tests/tx.valid.vectors.ts +0 -364
  111. package/src/transaction/broadcasters/ARC.ts +0 -106
  112. package/src/transaction/broadcasters/__tests/ARC.test.ts +0 -115
  113. package/src/transaction/broadcasters/index.ts +0 -1
  114. package/src/transaction/fee-models/SatoshisPerKilobyte.ts +0 -71
  115. package/src/transaction/fee-models/index.ts +0 -1
  116. package/src/transaction/index.ts +0 -6
  117. package/ts2md.json +0 -5
  118. package/tsconfig.base.json +0 -26
  119. package/tsconfig.cjs.json +0 -11
  120. package/tsconfig.eslint.json +0 -12
  121. package/tsconfig.esm.json +0 -9
  122. package/tsconfig.json +0 -17
  123. package/tsconfig.types.json +0 -11
@@ -1,181 +0,0 @@
1
- import MerklePath from '../../../dist/cjs/src/transaction/MerklePath'
2
- import invalidBumps from './bump.invalid.vectors'
3
- import validBumps from './bump.valid.vectors'
4
-
5
- const BRC74Hex = 'fe8a6a0c000c04fde80b0011774f01d26412f0d16ea3f0447be0b5ebec67b0782e321a7a01cbdf7f734e30fde90b02004e53753e3fe4667073063a17987292cfdea278824e9888e52180581d7188d8fdea0b025e441996fc53f0191d649e68a200e752fb5f39e0d5617083408fa179ddc5c998fdeb0b0102fdf405000671394f72237d08a4277f4435e5b6edf7adc272f25effef27cdfe805ce71a81fdf50500262bccabec6c4af3ed00cc7a7414edea9c5efa92fb8623dd6160a001450a528201fdfb020101fd7c010093b3efca9b77ddec914f8effac691ecb54e2c81d0ab81cbc4c4b93befe418e8501bf01015e005881826eb6973c54003a02118fe270f03d46d02681c8bc71cd44c613e86302f8012e00e07a2bb8bb75e5accff266022e1e5e6e7b4d6d943a04faadcf2ab4a22f796ff30116008120cafa17309c0bb0e0ffce835286b3a2dcae48e4497ae2d2b7ced4f051507d010a00502e59ac92f46543c23006bff855d96f5e648043f0fb87a7a5949e6a9bebae430104001ccd9f8f64f4d0489b30cc815351cf425e0e78ad79a589350e4341ac165dbe45010301010000af8764ce7e1cc132ab5ed2229a005c87201c9a5ee15c0f91dd53eff31ab30cd4'
6
-
7
- const BRC74JSON = {
8
- blockHeight: 813706,
9
- path: [
10
- [
11
- {
12
- offset: 3048,
13
- hash: '304e737fdfcb017a1a322e78b067ecebb5e07b44f0a36ed1f01264d2014f7711'
14
- },
15
- {
16
- offset: 3049,
17
- txid: true,
18
- hash: 'd888711d588021e588984e8278a2decf927298173a06737066e43f3e75534e00'
19
- },
20
- {
21
- offset: 3050,
22
- txid: true,
23
- hash: '98c9c5dd79a18f40837061d5e0395ffb52e700a2689e641d19f053fc9619445e'
24
- },
25
- {
26
- offset: 3051,
27
- duplicate: true
28
- }
29
- ],
30
- [
31
- {
32
- offset: 1524,
33
- hash: '811ae75c80fecd27efff5ef272c2adf7edb6e535447f27a4087d23724f397106'
34
- },
35
- {
36
- offset: 1525,
37
- hash: '82520a4501a06061dd2386fb92fa5e9ceaed14747acc00edf34a6cecabcc2b26'
38
- }
39
- ],
40
- [
41
- {
42
- offset: 763,
43
- duplicate: true
44
- }
45
- ],
46
- [
47
- {
48
- offset: 380,
49
- hash: '858e41febe934b4cbc1cb80a1dc8e254cb1e69acff8e4f91ecdd779bcaefb393'
50
- }
51
- ],
52
- [
53
- {
54
- offset: 191,
55
- duplicate: true
56
- }
57
- ],
58
- [
59
- {
60
- offset: 94,
61
- hash: 'f80263e813c644cd71bcc88126d0463df070e28f11023a00543c97b66e828158'
62
- }
63
- ],
64
- [
65
- {
66
- offset: 46,
67
- hash: 'f36f792fa2b42acfadfa043a946d4d7b6e5e1e2e0266f2cface575bbb82b7ae0'
68
- }
69
- ],
70
- [
71
- {
72
- offset: 22,
73
- hash: '7d5051f0d4ceb7d2e27a49e448aedca2b3865283ceffe0b00b9c3017faca2081'
74
- }
75
- ],
76
- [
77
- {
78
- offset: 10,
79
- hash: '43aeeb9b6a9e94a5a787fbf04380645e6fd955f8bf0630c24365f492ac592e50'
80
- }
81
- ],
82
- [
83
- {
84
- offset: 4,
85
- hash: '45be5d16ac41430e3589a579ad780e5e42cf515381cc309b48d0f4648f9fcd1c'
86
- }
87
- ],
88
- [
89
- {
90
- offset: 3,
91
- duplicate: true
92
- }
93
- ],
94
- [
95
- {
96
- offset: 0,
97
- hash: 'd40cb31af3ef53dd910f5ce15e9a1c20875c009a22d25eab32c11c7ece6487af'
98
- }
99
- ]
100
- ]
101
- }
102
-
103
- const BRC74Root = '57aab6e6fb1b697174ffb64e062c4728f2ffd33ddcfa02a43b64d8cd29b483b4'
104
- const BRC74TXID1 = '304e737fdfcb017a1a322e78b067ecebb5e07b44f0a36ed1f01264d2014f7711'
105
- const BRC74TXID2 = 'd888711d588021e588984e8278a2decf927298173a06737066e43f3e75534e00'
106
- const BRC74TXID3 = '98c9c5dd79a18f40837061d5e0395ffb52e700a2689e641d19f053fc9619445e'
107
-
108
- describe('MerklePath', () => {
109
- it('Parses from hex', () => {
110
- const path = MerklePath.fromHex(BRC74Hex)
111
- expect(path.path).toEqual(BRC74JSON.path)
112
- })
113
- it('Serializes to hex', () => {
114
- const path = new MerklePath(BRC74JSON.blockHeight, BRC74JSON.path)
115
- expect(path.toHex()).toEqual(BRC74Hex)
116
- })
117
- it('Computes a root', () => {
118
- const path = new MerklePath(BRC74JSON.blockHeight, BRC74JSON.path)
119
- expect(path.computeRoot(BRC74TXID1)).toEqual(BRC74Root)
120
- expect(path.computeRoot(BRC74TXID2)).toEqual(BRC74Root)
121
- expect(path.computeRoot(BRC74TXID3)).toEqual(BRC74Root)
122
- })
123
- it('Verifies using a ChainTracker', async () => {
124
- const path = new MerklePath(BRC74JSON.blockHeight, BRC74JSON.path)
125
- const tracker = {
126
- isValidRootForHeight: jest.fn((root, height) => root === BRC74Root && height === BRC74JSON.blockHeight)
127
- }
128
- const result = await path.verify(BRC74TXID1, tracker)
129
- expect(result).toBe(true)
130
- expect(tracker.isValidRootForHeight).toHaveBeenCalledWith(BRC74Root, BRC74JSON.blockHeight)
131
- })
132
- it('Combines two paths', () => {
133
- const path0A = [...BRC74JSON.path[0]]
134
- const path0B = [...BRC74JSON.path[0]]
135
- const path1A = [...BRC74JSON.path[1]]
136
- const path1B = [...BRC74JSON.path[1]]
137
- const pathRest = [...BRC74JSON.path]
138
- pathRest.shift()
139
- pathRest.shift()
140
- path0A.splice(2, 2)
141
- path0B.shift()
142
- path0B.shift()
143
- path1A.shift()
144
- path1B.pop()
145
- const pathAJSON = {
146
- blockHeight: BRC74JSON.blockHeight,
147
- path: [
148
- path0A,
149
- path1A,
150
- ...pathRest
151
- ]
152
- }
153
- const pathBJSON = {
154
- blockHeight: BRC74JSON.blockHeight,
155
- path: [
156
- path0B,
157
- path1B,
158
- ...pathRest
159
- ]
160
- }
161
- const pathA = new MerklePath(pathAJSON.blockHeight, pathAJSON.path)
162
- const pathB = new MerklePath(pathBJSON.blockHeight, pathBJSON.path)
163
- expect(pathA.computeRoot(BRC74TXID2)).toEqual(BRC74Root)
164
- expect(() => pathA.computeRoot(BRC74TXID3)).toThrow()
165
- expect(() => pathB.computeRoot(BRC74TXID2)).toThrow()
166
- expect(pathB.computeRoot(BRC74TXID3)).toEqual(BRC74Root)
167
- pathA.combine(pathB)
168
- expect(pathA.computeRoot(BRC74TXID2)).toEqual(BRC74Root)
169
- expect(pathA.computeRoot(BRC74TXID3)).toEqual(BRC74Root)
170
- })
171
- it('Rejects invalid bumps', () => {
172
- for (const invalid of invalidBumps) {
173
- expect(() => MerklePath.fromHex(invalid.bump)).toThrow(invalid.error)
174
- }
175
- })
176
- it('Verifies valid bumps', async () => {
177
- for (const valid of validBumps) {
178
- expect(() => MerklePath.fromHex(valid.bump)).not.toThrowError()
179
- }
180
- })
181
- })
@@ -1,413 +0,0 @@
1
- import BigNumber from '../../../dist/cjs/src/primitives/BigNumber'
2
- import TransactionSignature from '../../../dist/cjs/src/primitives/TransactionSignature'
3
- import { toHex, toArray } from '../../../dist/cjs/src/primitives/utils'
4
- import Script from '../../../dist/cjs/src/script/Script'
5
- import UnlockingScript from '../../../dist/cjs/src/script/UnlockingScript'
6
- import LockingScript from '../../../dist/cjs/src/script/LockingScript'
7
- import Transaction from '../../../dist/cjs/src/transaction/Transaction'
8
- import { hash256, hash160 } from '../../../dist/cjs/src/primitives/Hash'
9
- import PrivateKey from '../../../dist/cjs/src/primitives/PrivateKey'
10
- import Curve from '../../../dist/cjs/src/primitives/Curve'
11
- import P2PKH from '../../../dist/cjs/src/script/templates/P2PKH'
12
-
13
- import sighashVectors from '../../primitives/__tests/sighash.vectors'
14
- import invalidTransactions from './tx.invalid.vectors'
15
- import validTransactions from './tx.valid.vectors'
16
- import bigTX from './bigtx.vectors'
17
-
18
- const BRC62Hex = '0100beef01fe636d0c0007021400fe507c0c7aa754cef1f7889d5fd395cf1f785dd7de98eed895dbedfe4e5bc70d1502ac4e164f5bc16746bb0868404292ac8318bbac3800e4aad13a014da427adce3e010b00bc4ff395efd11719b277694cface5aa50d085a0bb81f613f70313acd28cf4557010400574b2d9142b8d28b61d88e3b2c3f44d858411356b49a28a4643b6d1a6a092a5201030051a05fc84d531b5d250c23f4f886f6812f9fe3f402d61607f977b4ecd2701c19010000fd781529d58fc2523cf396a7f25440b409857e7e221766c57214b1d38c7b481f01010062f542f45ea3660f86c013ced80534cb5fd4c19d66c56e7e8c5d4bf2d40acc5e010100b121e91836fd7cd5102b654e9f72f3cf6fdbfd0b161c53a9c54b12c841126331020100000001cd4e4cac3c7b56920d1e7655e7e260d31f29d9a388d04910f1bbd72304a79029010000006b483045022100e75279a205a547c445719420aa3138bf14743e3f42618e5f86a19bde14bb95f7022064777d34776b05d816daf1699493fcdf2ef5a5ab1ad710d9c97bfb5b8f7cef3641210263e2dee22b1ddc5e11f6fab8bcd2378bdd19580d640501ea956ec0e786f93e76ffffffff013e660000000000001976a9146bfd5c7fbe21529d45803dbcf0c87dd3c71efbc288ac0000000001000100000001ac4e164f5bc16746bb0868404292ac8318bbac3800e4aad13a014da427adce3e000000006a47304402203a61a2e931612b4bda08d541cfb980885173b8dcf64a3471238ae7abcd368d6402204cbf24f04b9aa2256d8901f0ed97866603d2be8324c2bfb7a37bf8fc90edd5b441210263e2dee22b1ddc5e11f6fab8bcd2378bdd19580d640501ea956ec0e786f93e76ffffffff013c660000000000001976a9146bfd5c7fbe21529d45803dbcf0c87dd3c71efbc288ac0000000000'
19
-
20
- describe('Transaction', () => {
21
- const txIn = {
22
- sourceTXID: '0000000000000000000000000000000000000000000000000000000000000000',
23
- sourceOutputIndex: 0,
24
- unlockingScript: UnlockingScript.fromHex('ae'),
25
- sequence: 0
26
- }
27
- const txOut = {
28
- satoshis: BigNumber.fromHex('0500000000000000', 'be'),
29
- lockingScript: LockingScript.fromHex('ae')
30
- }
31
- const tx = new Transaction(0, [txIn], [txOut], 0)
32
- const txhex =
33
- '000000000100000000000000000000000000000000000000000000000000000000000000000000000001ae0000000001050000000000000001ae00000000'
34
- const txbuf = toArray(txhex, 'hex')
35
-
36
- const tx2idhex = '8c9aa966d35bfeaf031409e0001b90ccdafd8d859799eb945a3c515b8260bcf2'
37
- const tx2hex =
38
- '01000000029e8d016a7b0dc49a325922d05da1f916d1e4d4f0cb840c9727f3d22ce8d1363f000000008c493046022100e9318720bee5425378b4763b0427158b1051eec8b08442ce3fbfbf7b30202a44022100d4172239ebd701dae2fbaaccd9f038e7ca166707333427e3fb2a2865b19a7f27014104510c67f46d2cbb29476d1f0b794be4cb549ea59ab9cc1e731969a7bf5be95f7ad5e7f904e5ccf50a9dc1714df00fbeb794aa27aaff33260c1032d931a75c56f2ffffffffa3195e7a1ab665473ff717814f6881485dc8759bebe97e31c301ffe7933a656f020000008b48304502201c282f35f3e02a1f32d2089265ad4b561f07ea3c288169dedcf2f785e6065efa022100e8db18aadacb382eed13ee04708f00ba0a9c40e3b21cf91da8859d0f7d99e0c50141042b409e1ebbb43875be5edde9c452c82c01e3903d38fa4fd89f3887a52cb8aea9dc8aec7e2c9d5b3609c03eb16259a2537135a1bf0f9c5fbbcbdbaf83ba402442ffffffff02206b1000000000001976a91420bb5c3bfaef0231dc05190e7f1c8e22e098991e88acf0ca0100000000001976a9149e3e2d23973a04ec1b02be97c30ab9f2f27c3b2c88ac00000000'
39
- const tx2buf = toArray(tx2hex, 'hex')
40
-
41
- it('should make a new transaction', () => {
42
- let tx = new Transaction()
43
- expect(tx).toBeDefined()
44
- tx = new Transaction()
45
- expect(tx).toBeDefined()
46
-
47
- expect(Transaction.fromBinary(txbuf).toHex()).toEqual(txhex)
48
-
49
- // should set known defaults
50
- expect(tx.version).toEqual(1)
51
- expect(tx.inputs.length).toEqual(0)
52
- expect(tx.outputs.length).toEqual(0)
53
- expect(tx.lockTime).toEqual(0)
54
- })
55
-
56
- describe('#constructor', () => {
57
- it('should set these known defaults', () => {
58
- const tx = new Transaction()
59
- expect(tx.version).toEqual(1)
60
- expect(tx.inputs.length).toEqual(0)
61
- expect(tx.outputs.length).toEqual(0)
62
- expect(tx.lockTime).toEqual(0)
63
- })
64
- })
65
-
66
- describe('#fromHex', () => {
67
- it('should recover from this known tx', () => {
68
- expect(Transaction.fromHex(txhex).toHex()).toEqual(txhex)
69
- })
70
-
71
- it('should recover from this known tx from the blockchain', () => {
72
- expect(Transaction.fromHex(tx2hex).toHex()).toEqual(tx2hex)
73
- })
74
- })
75
-
76
- describe('#fromBinary', () => {
77
- it('should recover from this known tx', () => {
78
- expect(toHex(Transaction.fromBinary(txbuf).toBinary())).toEqual(txhex)
79
- })
80
-
81
- it('should recover from this known tx from the blockchain', () => {
82
- expect(toHex(Transaction.fromBinary(tx2buf).toBinary())).toEqual(tx2hex)
83
- })
84
- })
85
-
86
- describe('#toHex', () => {
87
- it('should produce this known tx', () => {
88
- expect(Transaction.fromHex(txhex).toHex()).toEqual(txhex)
89
- })
90
- })
91
-
92
- describe('#toBinary', () => {
93
- it('should produce this known tx', () => {
94
- expect(toHex(Transaction.fromBinary(txbuf).toBinary())).toEqual(txhex)
95
- })
96
- })
97
-
98
- describe('#hash', () => {
99
- it('should correctly calculate the hash of this known transaction', () => {
100
- const tx = Transaction.fromBinary(tx2buf)
101
- expect(toHex(tx.hash().reverse())).toEqual(tx2idhex)
102
- })
103
- })
104
-
105
- describe('#id', () => {
106
- it('should correctly calculate the txid of this known transaction', () => {
107
- const tx = Transaction.fromBinary(tx2buf)
108
- expect(tx.id('hex')).toEqual(tx2idhex)
109
- })
110
- })
111
-
112
- describe('#addInput', () => {
113
- it('should add an input', () => {
114
- const txIn = {
115
- sourceTXID: '0000000000000000000000000000000000000000000000000000000000000000',
116
- sourceOutputIndex: 0,
117
- unlockingScript: new UnlockingScript(),
118
- sequence: 0xffffffff
119
- }
120
- const tx = new Transaction()
121
- expect(tx.inputs.length).toEqual(0)
122
- tx.addInput(txIn)
123
- expect(tx.inputs.length).toEqual(1)
124
- })
125
- })
126
-
127
- describe('#addOutput', () => {
128
- it('should add an output', () => {
129
- const txOut = {
130
- lockingScript: new LockingScript(),
131
- satoshis: new BigNumber(0)
132
- }
133
- const tx = new Transaction()
134
- expect(tx.outputs.length).toEqual(0)
135
- tx.addOutput(txOut)
136
- expect(tx.outputs.length).toEqual(1)
137
- })
138
- })
139
-
140
- describe('Signing', () => {
141
- it('Signs unlocking script templates, hydrating the scripts', async () => {
142
- const privateKey = new PrivateKey(1)
143
- const publicKey = new Curve().g.mul(privateKey)
144
- const publicKeyHash = hash160(publicKey.encode(true)) as number[]
145
- const p2pkh = new P2PKH()
146
- const sourceTx = new Transaction(1, [], [{
147
- lockingScript: p2pkh.lock(publicKeyHash),
148
- satoshis: new BigNumber(4000)
149
- }], 0)
150
- const spendTx = new Transaction(1, [{
151
- sourceTransaction: sourceTx,
152
- sourceOutputIndex: 0,
153
- unlockingScriptTemplate: p2pkh.unlock(privateKey),
154
- sequence: 0xffffffff
155
- }], [{
156
- satoshis: new BigNumber(1000),
157
- lockingScript: p2pkh.lock(publicKeyHash)
158
- }, {
159
- lockingScript: p2pkh.lock(publicKeyHash),
160
- change: true
161
- }], 0)
162
- expect(spendTx.inputs[0].unlockingScript).not.toBeDefined()
163
- await spendTx.fee()
164
- await spendTx.sign()
165
- expect(spendTx.inputs[0].unlockingScript).toBeDefined()
166
- // P2PKH unlocking scripts have two chunks (the signature and public key)
167
- expect(spendTx.inputs[0].unlockingScript.chunks.length).toBe(2)
168
- })
169
- it('Throws an Error if signing before the fee is computed', async () => {
170
- const privateKey = new PrivateKey(1)
171
- const publicKey = new Curve().g.mul(privateKey)
172
- const publicKeyHash = hash160(publicKey.encode(true)) as number[]
173
- const p2pkh = new P2PKH()
174
- const sourceTx = new Transaction(1, [], [{
175
- lockingScript: p2pkh.lock(publicKeyHash),
176
- satoshis: new BigNumber(4000)
177
- }], 0)
178
- const spendTx = new Transaction(1, [{
179
- sourceTransaction: sourceTx,
180
- sourceOutputIndex: 0,
181
- unlockingScriptTemplate: p2pkh.unlock(privateKey),
182
- sequence: 0xffffffff
183
- }], [{
184
- satoshis: new BigNumber(1000),
185
- lockingScript: p2pkh.lock(publicKeyHash)
186
- }, {
187
- lockingScript: p2pkh.lock(publicKeyHash),
188
- change: true
189
- }], 0)
190
- await expect(spendTx.sign()).rejects.toThrow()
191
- })
192
- })
193
-
194
- describe('Fees', () => {
195
- it('Computes fees with the default fee model', async () => {
196
- const privateKey = new PrivateKey(1)
197
- const publicKey = new Curve().g.mul(privateKey)
198
- const publicKeyHash = hash160(publicKey.encode(true)) as number[]
199
- const p2pkh = new P2PKH()
200
- const sourceTx = new Transaction(1, [], [{
201
- lockingScript: p2pkh.lock(publicKeyHash),
202
- satoshis: 4000
203
- }], 0)
204
- const spendTx = new Transaction(1, [{
205
- sourceTransaction: sourceTx,
206
- sourceOutputIndex: 0,
207
- unlockingScriptTemplate: p2pkh.unlock(privateKey),
208
- sequence: 0xffffffff
209
- }], [{
210
- satoshis: new BigNumber(1000),
211
- lockingScript: p2pkh.lock(publicKeyHash)
212
- }, {
213
- lockingScript: p2pkh.lock(publicKeyHash),
214
- change: true
215
- }], 0)
216
- expect(spendTx.outputs[1].satoshis).not.toBeDefined()
217
- await spendTx.fee()
218
- // Transaction size is 225 bytes for one-input two-output P2PKH.
219
- // Default fee rate is 10 sat/kb = 2.25 sats (round up to 3).
220
- // 4000 sats in - 1000 sats out - 3 sats fee = expected 2997 sats change.
221
- expect(spendTx.outputs[1].satoshis).toEqual(2997)
222
- })
223
- it('Computes fees with a custom fee model', async () => {
224
- const privateKey = new PrivateKey(1)
225
- const publicKey = new Curve().g.mul(privateKey)
226
- const publicKeyHash = hash160(publicKey.encode(true)) as number[]
227
- const p2pkh = new P2PKH()
228
- const sourceTx = new Transaction(1, [], [{
229
- lockingScript: p2pkh.lock(publicKeyHash),
230
- satoshis: 4000
231
- }], 0)
232
- const spendTx = new Transaction(1, [{
233
- sourceTransaction: sourceTx,
234
- sourceOutputIndex: 0,
235
- unlockingScriptTemplate: p2pkh.unlock(privateKey),
236
- sequence: 0xffffffff
237
- }], [{
238
- satoshis: 1000,
239
- lockingScript: p2pkh.lock(publicKeyHash)
240
- }, {
241
- lockingScript: p2pkh.lock(publicKeyHash),
242
- change: true
243
- }], 0)
244
- expect(spendTx.outputs[1].satoshis).not.toBeDefined()
245
- await spendTx.fee({
246
- // Our custom fee model will always charge 1033 sats for a tx.
247
- computeFee: async () => 1033
248
- })
249
- // 4000 sats in - 1000 sats out - 1033 sats fee = expected 1967 sats change
250
- expect(spendTx.outputs[1].satoshis).toEqual(1967)
251
- })
252
- it('Distributes change among multiple change outputs', async () => {
253
- const privateKey = new PrivateKey(1)
254
- const publicKey = new Curve().g.mul(privateKey)
255
- const publicKeyHash = hash160(publicKey.encode(true)) as number[]
256
- const p2pkh = new P2PKH()
257
- const sourceTx = new Transaction(1, [], [{
258
- lockingScript: p2pkh.lock(publicKeyHash),
259
- satoshis: 4000
260
- }], 0)
261
- const spendTx = new Transaction(1, [{
262
- sourceTransaction: sourceTx,
263
- sourceOutputIndex: 0,
264
- unlockingScriptTemplate: p2pkh.unlock(privateKey),
265
- sequence: 0xffffffff
266
- }], [{
267
- satoshis: 1000,
268
- lockingScript: p2pkh.lock(publicKeyHash)
269
- }, {
270
- lockingScript: p2pkh.lock(publicKeyHash),
271
- change: true
272
- }, {
273
- lockingScript: p2pkh.lock(publicKeyHash),
274
- change: true
275
- }], 0)
276
- expect(spendTx.outputs[1].satoshis).not.toBeDefined()
277
- expect(spendTx.outputs[2].satoshis).not.toBeDefined()
278
- await spendTx.fee({
279
- // Our custom fee model will always charge 1033 sats for a tx.
280
- computeFee: async () => 1033
281
- })
282
- // 4000 sats in - 1000 sats out - 1033 sats fee = expected 1967 sats change
283
- // Divide by 2 (no remainder) = 983 sats per change output
284
- expect(spendTx.outputs[1].satoshis).toEqual(983)
285
- expect(spendTx.outputs[2].satoshis).toEqual(983)
286
- })
287
- })
288
-
289
- describe('Broadcast', () => {
290
- it('Broadcasts with the provided Broadcaster instance', async () => {
291
- const mockBroadcast = jest.fn(() => 'MOCK_RV')
292
- const tx = new Transaction()
293
- const rv = await tx.broadcast({
294
- broadcast: mockBroadcast
295
- })
296
- expect(mockBroadcast).toHaveBeenCalledWith(tx)
297
- expect(rv).toEqual('MOCK_RV')
298
- })
299
- })
300
-
301
- describe('BEEF', () => {
302
- it('Serialization and deserialization', async () => {
303
- const tx = Transaction.fromBEEF(toArray(BRC62Hex, 'hex'))
304
- expect(tx.inputs[0].sourceTransaction.merklePath.blockHeight).toEqual(814435)
305
- const beef = toHex(tx.toBEEF())
306
- expect(beef).toEqual(BRC62Hex)
307
- })
308
- })
309
-
310
- describe('EF', () => {
311
- it('Serialization and deserialization', async () => {
312
- const tx = Transaction.fromBEEF(toArray(BRC62Hex, 'hex'))
313
- const ef = toHex(tx.toEF())
314
- expect(ef).toEqual('010000000000000000ef01ac4e164f5bc16746bb0868404292ac8318bbac3800e4aad13a014da427adce3e000000006a47304402203a61a2e931612b4bda08d541cfb980885173b8dcf64a3471238ae7abcd368d6402204cbf24f04b9aa2256d8901f0ed97866603d2be8324c2bfb7a37bf8fc90edd5b441210263e2dee22b1ddc5e11f6fab8bcd2378bdd19580d640501ea956ec0e786f93e76ffffffff3e660000000000001976a9146bfd5c7fbe21529d45803dbcf0c87dd3c71efbc288ac013c660000000000001976a9146bfd5c7fbe21529d45803dbcf0c87dd3c71efbc288ac00000000')
315
- })
316
- })
317
-
318
- describe('Verification', () => {
319
- it('Verifies the transaction from the BEEF spec', async () => {
320
- const tx = Transaction.fromBEEF(toArray(BRC62Hex, 'hex'))
321
- const alwaysYesChainTracker = {
322
- isValidRootForHeight: async () => true
323
- }
324
- const verified = await tx.verify(alwaysYesChainTracker)
325
- expect(verified).toBe(true)
326
- })
327
- })
328
-
329
- describe('vectors: a 1mb transaction', () => {
330
- it('should find the correct id of this (valid, on the blockchain) 1 mb transaction', () => {
331
- const txidhex = bigTX.txidhex
332
- const txhex = bigTX.txhex
333
- const tx = Transaction.fromHex(txhex)
334
- const txid = tx.id('hex')
335
- expect(txid).toEqual(txidhex)
336
- })
337
- })
338
-
339
- describe('vectors: sighash and serialization', () => {
340
- sighashVectors.forEach((vector, i) => {
341
- if (i === 0) {
342
- return
343
- }
344
- it(`should pass bitcoin-abc sighash test vector ${i}`, () => {
345
- const txbuf = toArray(vector[0], 'hex')
346
- const scriptbuf = toArray(vector[1], 'hex')
347
- const subScript = Script.fromBinary(scriptbuf)
348
- const nIn = (vector[2]) as number
349
- const nHashType = (vector[3]) as number
350
- const sighashBuf = toArray(vector[4], 'hex')
351
- const tx = Transaction.fromBinary(txbuf)
352
-
353
- // make sure transacion to/from buffer is isomorphic
354
- expect(toHex(tx.toBinary())).toEqual(toHex(txbuf))
355
-
356
- // sighash ought to be correct
357
- const valueBn = new BigNumber(0)
358
- const otherInputs = [...tx.inputs]
359
- const [input] = otherInputs.splice(nIn, 1)
360
- const preimage = TransactionSignature.format({
361
- sourceTXID: input.sourceTXID,
362
- sourceOutputIndex: input.sourceOutputIndex,
363
- sourceSatoshis: valueBn,
364
- transactionVersion: tx.version,
365
- otherInputs,
366
- outputs: tx.outputs,
367
- inputIndex: nIn,
368
- subscript: subScript,
369
- inputSequence: input.sequence,
370
- lockTime: tx.lockTime,
371
- scope: nHashType
372
- })
373
- const hash = hash256(preimage) as number[]
374
- hash.reverse()
375
- expect(toHex(hash)).toEqual(toHex(sighashBuf))
376
- })
377
- })
378
-
379
- validTransactions.forEach((vector, i) => {
380
- if (vector.length === 1) {
381
- return
382
- }
383
- it(`should correctly serialized/deserialize tx_valid test vector ${i}`, () => {
384
- const expectedHex = vector[1]
385
- const expectedBin = toArray(vector[1], 'hex')
386
- const actualTX = Transaction.fromBinary(expectedBin)
387
- const actualBin = actualTX.toBinary()
388
- const actualHex = toHex(actualBin)
389
- expect(actualHex).toEqual(expectedHex)
390
- })
391
- })
392
-
393
- invalidTransactions.forEach((vector, i) => {
394
- if (vector.length === 1) {
395
- return
396
- }
397
-
398
- // 151, 142 and 25 have invalid Satoshi amounts that exceed 53 bits in length, causing exceptions that make serialization and deserialization impossible.
399
- if (i === 151 || i === 142 || i === 25) {
400
- return
401
- }
402
-
403
- it(`should correctly serialized/deserialize tx_invalid test vector ${i}`, () => {
404
- const expectedHex = vector[1]
405
- const expectedBin = toArray(vector[1], 'hex')
406
- const actualTX = Transaction.fromBinary(expectedBin)
407
- const actualBin = actualTX.toBinary()
408
- const actualHex = toHex(actualBin)
409
- expect(actualHex).toEqual(expectedHex)
410
- })
411
- })
412
- })
413
- })