@bsv/sdk 2.0.9 → 2.0.11

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 (44) hide show
  1. package/dist/cjs/package.json +1 -1
  2. package/dist/cjs/src/auth/certificates/Certificate.js +1 -1
  3. package/dist/cjs/src/auth/certificates/Certificate.js.map +1 -1
  4. package/dist/cjs/src/primitives/BigNumber.js +4 -5
  5. package/dist/cjs/src/primitives/BigNumber.js.map +1 -1
  6. package/dist/cjs/src/script/OP.js +22 -16
  7. package/dist/cjs/src/script/OP.js.map +1 -1
  8. package/dist/cjs/src/script/Spend.js +21 -78
  9. package/dist/cjs/src/script/Spend.js.map +1 -1
  10. package/dist/cjs/src/transaction/MerklePath.js +9 -4
  11. package/dist/cjs/src/transaction/MerklePath.js.map +1 -1
  12. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  13. package/dist/esm/src/auth/certificates/Certificate.js +1 -1
  14. package/dist/esm/src/auth/certificates/Certificate.js.map +1 -1
  15. package/dist/esm/src/primitives/BigNumber.js +4 -5
  16. package/dist/esm/src/primitives/BigNumber.js.map +1 -1
  17. package/dist/esm/src/script/OP.js +22 -16
  18. package/dist/esm/src/script/OP.js.map +1 -1
  19. package/dist/esm/src/script/Spend.js +21 -78
  20. package/dist/esm/src/script/Spend.js.map +1 -1
  21. package/dist/esm/src/transaction/MerklePath.js +9 -4
  22. package/dist/esm/src/transaction/MerklePath.js.map +1 -1
  23. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  24. package/dist/types/src/primitives/BigNumber.d.ts.map +1 -1
  25. package/dist/types/src/script/OP.d.ts +9 -7
  26. package/dist/types/src/script/OP.d.ts.map +1 -1
  27. package/dist/types/src/script/Spend.d.ts.map +1 -1
  28. package/dist/types/src/transaction/MerklePath.d.ts.map +1 -1
  29. package/dist/types/tsconfig.types.tsbuildinfo +1 -1
  30. package/dist/umd/bundle.js +3 -3
  31. package/dist/umd/bundle.js.map +1 -1
  32. package/docs/reference/script.md +76 -0
  33. package/docs/reference/transaction.md +63 -6
  34. package/docs/reference/wallet.md +285 -1094
  35. package/package.json +1 -1
  36. package/src/auth/certificates/Certificate.ts +1 -1
  37. package/src/primitives/BigNumber.ts +4 -5
  38. package/src/primitives/__tests/BigNumber.constructor.test.ts +3 -3
  39. package/src/script/OP.ts +21 -16
  40. package/src/script/Spend.ts +21 -28
  41. package/src/script/__tests/Chronicle.test.ts +39 -103
  42. package/src/script/__tests/ChronicleOpcodes.test.ts +548 -0
  43. package/src/transaction/MerklePath.ts +10 -6
  44. package/src/transaction/__tests/MerklePath.test.ts +60 -22
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bsv/sdk",
3
- "version": "2.0.9",
3
+ "version": "2.0.11",
4
4
  "type": "module",
5
5
  "description": "BSV Blockchain Software Development Kit",
6
6
  "main": "dist/cjs/mod.js",
@@ -113,7 +113,7 @@ export default class Certificate {
113
113
 
114
114
  // Write fields
115
115
  // Sort field names lexicographically
116
- const fieldNames = Object.keys(this.fields).sort()
116
+ const fieldNames = Object.keys(this.fields).sort((a, b) => a.localeCompare(b))
117
117
  writer.writeVarIntNum(fieldNames.length)
118
118
  for (const fieldName of fieldNames) {
119
119
  const fieldValue = this.fields[fieldName]
@@ -664,9 +664,8 @@ export default class BigNumber {
664
664
  neg (): BigNumber { return this.clone().ineg() }
665
665
  ineg (): this { if (this._magnitude !== 0n) this._sign = this._sign === 1 ? 0 : 1; return this }
666
666
 
667
- private _iuop (num: BigNumber, op: (a: bigint, b: bigint) => bigint): this {
667
+ private _iuop (num: BigNumber, op: (a: bigint, b: bigint) => bigint, isXor: boolean = false): this {
668
668
  const newMag = op(this._magnitude, num._magnitude)
669
- const isXor = op === ((a: bigint, b: bigint) => a ^ b)
670
669
  let targetNominalLength = this._nominalWordLength
671
670
  if (isXor) targetNominalLength = Math.max(this.length, num.length)
672
671
 
@@ -678,11 +677,11 @@ export default class BigNumber {
678
677
 
679
678
  iuor (num: BigNumber): this { return this._iuop(num, (a, b) => a | b) }
680
679
  iuand (num: BigNumber): this { return this._iuop(num, (a, b) => a & b) }
681
- iuxor (num: BigNumber): this { return this._iuop(num, (a, b) => a ^ b) }
682
- private _iop (num: BigNumber, op: (a: bigint, b: bigint) => bigint): this { this.assert(this._sign === 0 && num._sign === 0); return this._iuop(num, op) }
680
+ iuxor (num: BigNumber): this { return this._iuop(num, (a, b) => a ^ b, true) }
681
+ private _iop (num: BigNumber, op: (a: bigint, b: bigint) => bigint, isXor: boolean = false): this { this.assert(this._sign === 0 && num._sign === 0); return this._iuop(num, op, isXor) }
683
682
  ior (num: BigNumber): this { return this._iop(num, (a, b) => a | b) }
684
683
  iand (num: BigNumber): this { return this._iop(num, (a, b) => a & b) }
685
- ixor (num: BigNumber): this { return this._iop(num, (a, b) => a ^ b) }
684
+ ixor (num: BigNumber): this { return this._iop(num, (a, b) => a ^ b, true) }
686
685
  private _uop_new (num: BigNumber, opName: 'iuor' | 'iuand' | 'iuxor'): BigNumber { if (this.length >= num.length) return this.clone()[opName](num); return num.clone()[opName](this) }
687
686
  or (num: BigNumber): BigNumber { this.assert(this._sign === 0 && num._sign === 0); return this._uop_new(num, 'iuor') }
688
687
  uor (num: BigNumber): BigNumber { return this._uop_new(num, 'iuor') }
@@ -117,11 +117,11 @@ describe('BN.js/Constructor', () => {
117
117
 
118
118
  it('should not accept decimal', () => {
119
119
  expect(() => {
120
- new BigNumber('10.00', 10) // eslint-disable-line no-new
120
+ return new BigNumber('10.00', 10)
121
121
  }).toThrow(new Error('Invalid character'))
122
122
 
123
123
  expect(() => {
124
- new BigNumber('16.00', 16) // eslint-disable-line no-new
124
+ return new BigNumber('16.00', 16)
125
125
  }).toThrow(/* new Error('Invalid character') */)
126
126
  })
127
127
 
@@ -137,7 +137,7 @@ describe('BN.js/Constructor', () => {
137
137
  'hexadecimal'
138
138
  ].forEach(function (str) {
139
139
  expect(() => {
140
- new BigNumber(str, 16) // eslint-disable-line no-new
140
+ return new BigNumber(str, 16)
141
141
  }).toThrow(/* Invalid character in */)
142
142
  })
143
143
  })
package/src/script/OP.ts CHANGED
@@ -3,15 +3,15 @@
3
3
  */
4
4
  const OP = {
5
5
  // push value
6
+ OP_0: 0x00, // when two op codes have the same value, the top one will be used in standard ASM output
6
7
  OP_FALSE: 0x00,
7
- OP_0: 0x00,
8
8
  OP_PUSHDATA1: 0x4c,
9
9
  OP_PUSHDATA2: 0x4d,
10
10
  OP_PUSHDATA4: 0x4e,
11
11
  OP_1NEGATE: 0x4f,
12
12
  OP_RESERVED: 0x50,
13
- OP_TRUE: 0x51,
14
13
  OP_1: 0x51,
14
+ OP_TRUE: 0x51,
15
15
  OP_2: 0x52,
16
16
  OP_3: 0x53,
17
17
  OP_4: 0x54,
@@ -124,20 +124,24 @@ const OP = {
124
124
 
125
125
  // expansion
126
126
  OP_NOP1: 0xb0,
127
- OP_NOP2: 0xb1, // Used on BTC for OP_CHECKLOCKTIMEVERIFY
128
- OP_NOP3: 0xb2, // Used on BTC for OP_CHECKSEQUENCEVERIFY
129
- OP_NOP4: 0xb3, // OP_NOP4 allocated to restore OP_SUBSTR in 2026 CHRONICLE upgrade
130
- OP_SUBSTR: 0xb3, // OP_NOP4 allocated to restore OP_SUBSTR in 2026 CHRONICLE upgrade
131
- OP_NOP5: 0xb4, // OP_NOP5 allocated to restore OP_LEFT in 2026 CHRONICLE upgrade
132
- OP_LEFT: 0xb4, // OP_NOP5 allocated to restore OP_LEFT in 2026 CHRONICLE upgrade
133
- OP_NOP6: 0xb5, // OP_NOP6 allocated to restore OP_RIGHT in 2026 CHRONICLE upgrade
134
- OP_RIGHT: 0xb5, // OP_NOP6 allocated to restore OP_RIGHT in 2026 CHRONICLE upgrade
135
- OP_NOP7: 0xb6, // OP_NOP7 allocated to restore OP_LSHIFTNUM in 2026 CHRONICLE upgrade
136
- OP_LSHIFTNUM: 0xb6, // OP_NOP7 allocated to restore OP_LSHIFTNUM in 2026 CHRONICLE upgrade
137
- OP_NOP8: 0xb7, // OP_NOP7 allocated to restore OP_RSHIFTNUM in 2026 CHRONICLE upgrade
138
- OP_RSHIFTNUM: 0xb7, // OP_NOP7 allocated to restore OP_RSHIFTNUM in 2026 CHRONICLE upgrade
127
+ OP_CHECKLOCKTIMEVERIFY: 0xb1, // BIP65 - on BSV post-genesis acts as NOP
128
+ OP_NOP2: 0xb1, // alias for OP_CHECKLOCKTIMEVERIFY
129
+ OP_CHECKSEQUENCEVERIFY: 0xb2, // BIP112 - on BSV post-genesis acts as NOP
130
+ OP_NOP3: 0xb2, // alias for OP_CHECKSEQUENCEVERIFY
131
+ OP_SUBSTR: 0xb3, // restored in 2026 CHRONICLE upgrade (was OP_NOP4)
132
+ OP_NOP4: 0xb3, // alias for OP_SUBSTR
133
+ OP_LEFT: 0xb4, // restored in 2026 CHRONICLE upgrade (was OP_NOP5)
134
+ OP_NOP5: 0xb4, // alias for OP_LEFT
135
+ OP_RIGHT: 0xb5, // restored in 2026 CHRONICLE upgrade (was OP_NOP6)
136
+ OP_NOP6: 0xb5, // alias for OP_RIGHT
137
+ OP_LSHIFTNUM: 0xb6, // restored in 2026 CHRONICLE upgrade (was OP_NOP7)
138
+ OP_NOP7: 0xb6, // alias for OP_LSHIFTNUM
139
+ OP_RSHIFTNUM: 0xb7, // restored in 2026 CHRONICLE upgrade (was OP_NOP8)
140
+ OP_NOP8: 0xb7, // alias for OP_RSHIFTNUM
139
141
  OP_NOP9: 0xb8,
140
142
  OP_NOP10: 0xb9,
143
+ // 0xba–0xf9 are FIRST_UNDEFINED_OP_VALUE in node v1.2.0 and return SCRIPT_ERR_BAD_OPCODE
144
+ // when executed. The names below are retained for ASM parsing/serialisation only.
141
145
  OP_NOP11: 0xba,
142
146
  OP_NOP12: 0xbb,
143
147
  OP_NOP13: 0xbc,
@@ -203,7 +207,8 @@ const OP = {
203
207
  OP_NOP73: 0xf8,
204
208
  OP_NOP77: 0xfc,
205
209
 
206
- // template matching params
210
+ // template matching params (not executable opcodes; 0xf9 was removed from node v1.2.0 opcodes.h
211
+ // but retained here for ASM round-trip compatibility)
207
212
  OP_SMALLDATA: 0xf9,
208
213
  OP_SMALLINTEGER: 0xfa,
209
214
  OP_PUBKEYS: 0xfb,
@@ -214,7 +219,7 @@ const OP = {
214
219
  }
215
220
 
216
221
  for (const name in OP) {
217
- OP[OP[name]] = name
222
+ if (OP[OP[name]] === undefined) OP[OP[name]] = name
218
223
  }
219
224
 
220
225
  export default OP
@@ -419,9 +419,12 @@ export default class Spend {
419
419
  let i: number, ikey: number, isig: number, nKeysCount: number, nSigsCount: number, fOk: boolean
420
420
 
421
421
  switch (currentOpcode) {
422
- case OP.OP_VER:
423
- this.pushStackCopy(new BigNumber(this.transactionVersion).toScriptNum())
422
+ case OP.OP_VER: {
423
+ // Node v1.2.0: pushes tx_version as a 4-byte little-endian integer (to_le encoding)
424
+ const ver = this.transactionVersion
425
+ this.pushStack([ver & 0xff, (ver >>> 8) & 0xff, (ver >>> 16) & 0xff, (ver >>> 24) & 0xff])
424
426
  break
427
+ }
425
428
  case OP.OP_SUBSTR: {
426
429
  if (this.stack.length < 3) this.scriptEvaluationError('OP_SUBSTR requires at least three items to be on the stack.')
427
430
  const len = BigNumber.fromScriptNum(this.popStack(), !this.isRelaxed()).toNumber()
@@ -459,7 +462,7 @@ export default class Spend {
459
462
  this.scriptEvaluationError(`OP_RIGHT length (${len}) must be in range [0, ${size}]`)
460
463
  }
461
464
 
462
- this.pushStack(buf.slice(size - len, len))
465
+ this.pushStack(buf.slice(size - len))
463
466
  break
464
467
  }
465
468
  case OP.OP_LSHIFTNUM: {
@@ -501,32 +504,18 @@ export default class Spend {
501
504
  break
502
505
 
503
506
  case OP.OP_NOP:
507
+ // OP_NOP1 (0xb0), OP_NOP9 (0xb8), OP_NOP10 (0xb9) are the only defined upgrade-NOP slots
508
+ // in node v1.2.0. All other values above 0xb9 are FIRST_UNDEFINED_OP_VALUE and invalid.
509
+ // falls through
504
510
  case OP.OP_NOP1:
505
- case OP.OP_NOP2:
506
- case OP.OP_NOP3:
507
- // case OP.OP_NOP4: // Allocated to OP_SUBSTR
508
- // case OP.OP_NOP5: // Allocated to OP_LEFT
509
- // case OP.OP_NOP6: // Allocated to OP_RIGHT
510
- // eslint-disable-next-line no-fallthrough
511
- case OP.OP_NOP7:
512
- case OP.OP_NOP8:
511
+ // OP_NOP2 (0xb1) = OP_CHECKLOCKTIMEVERIFY: on BSV post-genesis treated as NOP
512
+ // falls through
513
+ case OP.OP_CHECKLOCKTIMEVERIFY:
514
+ // OP_NOP3 (0xb2) = OP_CHECKSEQUENCEVERIFY: on BSV post-genesis treated as NOP
515
+ // falls through
516
+ case OP.OP_CHECKSEQUENCEVERIFY:
513
517
  case OP.OP_NOP9:
514
518
  case OP.OP_NOP10:
515
- // eslint-disable-next-line no-fallthrough
516
- case OP.OP_NOP11: case OP.OP_NOP12: case OP.OP_NOP13: case OP.OP_NOP14: case OP.OP_NOP15:
517
- case OP.OP_NOP16: case OP.OP_NOP17: case OP.OP_NOP18: case OP.OP_NOP19: case OP.OP_NOP20:
518
- case OP.OP_NOP21: case OP.OP_NOP22: case OP.OP_NOP23: case OP.OP_NOP24: case OP.OP_NOP25:
519
- case OP.OP_NOP26: case OP.OP_NOP27: case OP.OP_NOP28: case OP.OP_NOP29: case OP.OP_NOP30:
520
- case OP.OP_NOP31: case OP.OP_NOP32: case OP.OP_NOP33: case OP.OP_NOP34: case OP.OP_NOP35:
521
- case OP.OP_NOP36: case OP.OP_NOP37: case OP.OP_NOP38: case OP.OP_NOP39: case OP.OP_NOP40:
522
- case OP.OP_NOP41: case OP.OP_NOP42: case OP.OP_NOP43: case OP.OP_NOP44: case OP.OP_NOP45:
523
- case OP.OP_NOP46: case OP.OP_NOP47: case OP.OP_NOP48: case OP.OP_NOP49: case OP.OP_NOP50:
524
- case OP.OP_NOP51: case OP.OP_NOP52: case OP.OP_NOP53: case OP.OP_NOP54: case OP.OP_NOP55:
525
- case OP.OP_NOP56: case OP.OP_NOP57: case OP.OP_NOP58: case OP.OP_NOP59: case OP.OP_NOP60:
526
- case OP.OP_NOP61: case OP.OP_NOP62: case OP.OP_NOP63: case OP.OP_NOP64: case OP.OP_NOP65:
527
- case OP.OP_NOP66: case OP.OP_NOP67: case OP.OP_NOP68: case OP.OP_NOP69: case OP.OP_NOP70:
528
- case OP.OP_NOP71: case OP.OP_NOP72: case OP.OP_NOP73:
529
- case OP.OP_NOP77:
530
519
  break
531
520
 
532
521
  case OP.OP_VERIF:
@@ -534,9 +523,13 @@ export default class Spend {
534
523
  fValue = false
535
524
  if (isScriptExecuting) {
536
525
  if (this.stack.length < 1) this.scriptEvaluationError('OP_VERIF and OP_VERNOTIF require at least one item on the stack when they are used!')
537
- buf2 = new BigNumber(this.transactionVersion).toScriptNum()
538
526
  buf1 = this.popStack()
539
- fValue = compareNumberArrays(buf1, buf2)
527
+ // Node v1.2.0: compares against 4-byte little-endian tx_version (only matches when item is exactly 4 bytes)
528
+ if (buf1.length === 4) {
529
+ const ver = this.transactionVersion
530
+ buf2 = [ver & 0xff, (ver >>> 8) & 0xff, (ver >>> 16) & 0xff, (ver >>> 24) & 0xff]
531
+ fValue = compareNumberArrays(buf1, buf2)
532
+ }
540
533
  if (currentOpcode === OP.OP_VERNOTIF) fValue = !fValue
541
534
  }
542
535
  this.ifStack.push(fValue)
@@ -37,120 +37,56 @@ describe('Chronicle Tests', () => {
37
37
  })
38
38
 
39
39
  /**
40
- * At present only the first two test vectors added as real transaction (pre and post fork) compute a sighash known to match a valid signagure.
40
+ * At present only the first test vector added as real transaction (pre and post fork) compute a sighash known to match a valid signagure.
41
41
  * The remaining test vectors come from bitcoin-sv-staging repo as of 2025-06-23, but appear to be at least somewhat randomly generated.
42
42
  * The "scope" (SigHashType) values are all over the place.
43
43
  * Working with Teranode team to determine correct preimage values...
44
44
  */
45
- it('sighashTestData', () => {
46
- let log = ''
47
- let i = -1
48
- for (const t of sighashTestData) {
49
- i++
50
- const tx = Transaction.fromHex(t.rawTxHex)
51
- const script = Script.fromHex(t.scriptHex)
52
- const input = tx.inputs[t.inputIndex]
53
- if (input.unlockingScript?.chunks.length != 2)
54
- continue;
55
- const otherInputs = [...tx.inputs]
56
- otherInputs.splice(t.inputIndex, 1)
57
- const params = {
58
- sourceTXID: input.sourceTXID!,
59
- sourceOutputIndex: input.sourceOutputIndex,
60
- sourceSatoshis: t.satoshis,
61
- transactionVersion: tx.version,
62
- otherInputs,
63
- outputs: tx.outputs,
64
- inputIndex: t.inputIndex,
65
- subscript: Script.fromHex(t.scriptHex),
66
- inputSequence: input.sequence ?? 0xffffffff, // Default to max sequence number
67
- lockTime: tx.lockTime,
68
- scope: t.hashType,
69
- }
70
- let ok = false
71
- let okReg = false
72
- let okOTDA = false
73
- {
74
- const sighash = t.sighashReg
75
- const buf = TransactionSignature.format(params)
76
- const ret = Utils.toHex(Hash.hash256(buf).reverse())
77
- if (ret === sighash) {
78
- ok = true
79
- okReg = true
80
- }
81
- if (!okReg)
82
- log += `${i+1} Reg ${okReg} ${!okReg ? ret : ''}\n`
83
- }
84
- {
85
- const sighash = t.sighashOTDA
86
- const buf = TransactionSignature.formatOTDA(params)
87
- const ret = Utils.toHex(Hash.hash256(buf).reverse())
88
- if (ret === sighash) {
89
- ok = true
90
- okOTDA = true
91
- }
92
- if (!okOTDA)
93
- log += `${i+1} OTDA ${okOTDA} ${!okOTDA ? ret : ''}\n`
94
- }
95
- }
96
- //console.log(log)
97
- //expect(log).toBe('')
98
- })
99
45
 
100
46
  it('wip sighashTestData', () => {
101
- let log = ''
102
- let i = -1
103
- for (const t of sighashTestDataWip) {
104
- i++
105
- const tx = Transaction.fromHex(t.rawTxHex)
106
- const script = Script.fromHex(t.scriptHex)
107
- const input = tx.inputs[t.inputIndex]
108
- const otherInputs = [...tx.inputs]
109
- otherInputs.splice(t.inputIndex, 1)
110
- const params = {
111
- sourceTXID: input.sourceTXID!,
112
- sourceOutputIndex: input.sourceOutputIndex,
113
- sourceSatoshis: t.satoshis,
114
- transactionVersion: tx.version,
115
- otherInputs,
116
- outputs: tx.outputs,
117
- inputIndex: t.inputIndex,
118
- subscript: Script.fromHex(t.scriptHex),
119
- inputSequence: input.sequence ?? 0xffffffff, // Default to max sequence number
120
- lockTime: tx.lockTime,
121
- scope: t.hashType,
122
- }
123
- let ok = false
124
- let okReg = false
125
- let okOTDA = false
126
- {
127
- const sighash = t.sighashReg
128
- const buf = TransactionSignature.format(params)
129
- const ret = Utils.toHex(Hash.hash256(buf).reverse())
130
- if (ret === sighash) {
131
- ok = true
132
- okReg = true
133
- }
134
- if (!okReg)
135
- log += `${i+1} Reg ${okReg} ${!okReg ? ret : ''}\n`
136
- }
137
- {
138
- const sighash = t.sighashOTDA
139
- const buf = TransactionSignature.formatOTDA(params)
140
- const ret = Utils.toHex(Hash.hash256(buf).reverse())
141
- if (ret === sighash) {
142
- ok = true
143
- okOTDA = true
144
- }
145
- if (!okOTDA)
146
- log += `${i+1} OTDA ${okOTDA} ${!okOTDA ? ret : ''}\n`
147
- }
148
- }
47
+ const log = computeSighashLog(sighashTestDataWip)
149
48
  console.log(log)
150
49
  expect(log).toBe('')
151
50
  })
152
51
  })
153
52
 
53
+ function computeSighashLog (
54
+ data: typeof sighashTestData,
55
+ filterByUnlockingChunks: boolean = false
56
+ ): string {
57
+ let log = ''
58
+ let i = -1
59
+ for (const t of data) {
60
+ i++
61
+ const tx = Transaction.fromHex(t.rawTxHex)
62
+ const input = tx.inputs[t.inputIndex]
63
+ if (filterByUnlockingChunks && input.unlockingScript?.chunks.length !== 2)
64
+ continue
65
+ const otherInputs = [...tx.inputs]
66
+ otherInputs.splice(t.inputIndex, 1)
67
+ const params = {
68
+ sourceTXID: input.sourceTXID!,
69
+ sourceOutputIndex: input.sourceOutputIndex,
70
+ sourceSatoshis: t.satoshis,
71
+ transactionVersion: tx.version,
72
+ otherInputs,
73
+ outputs: tx.outputs,
74
+ inputIndex: t.inputIndex,
75
+ subscript: Script.fromHex(t.scriptHex),
76
+ inputSequence: input.sequence ?? 0xffffffff,
77
+ lockTime: tx.lockTime,
78
+ scope: t.hashType,
79
+ }
80
+ const reg = Utils.toHex(Hash.hash256(TransactionSignature.format(params)).reverse())
81
+ if (reg !== t.sighashReg)
82
+ log += `${i+1} Reg false ${reg}\n`
83
+ const otda = Utils.toHex(Hash.hash256(TransactionSignature.formatOTDA(params)).reverse())
84
+ if (otda !== t.sighashOTDA)
85
+ log += `${i+1} OTDA false ${otda}\n`
86
+ }
87
+ return log
88
+ }
89
+
154
90
  function verifyTruthy<T> (v: T | undefined): T {
155
91
  if (v == null) throw new Error('must have value')
156
92
  return v