@vbyte/btc-dev 1.1.7 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. package/CHANGELOG.md +94 -0
  2. package/README.md +260 -3
  3. package/dist/const.d.ts +3 -0
  4. package/dist/const.js +23 -22
  5. package/dist/index.d.ts +11 -11
  6. package/dist/index.js +10 -10
  7. package/dist/lib/address/api.d.ts +2 -2
  8. package/dist/lib/address/api.js +12 -12
  9. package/dist/lib/address/encode.d.ts +1 -1
  10. package/dist/lib/address/encode.js +24 -24
  11. package/dist/lib/address/index.d.ts +6 -6
  12. package/dist/lib/address/index.js +6 -6
  13. package/dist/lib/address/p2pkh.d.ts +2 -2
  14. package/dist/lib/address/p2pkh.js +14 -14
  15. package/dist/lib/address/p2sh.d.ts +2 -2
  16. package/dist/lib/address/p2sh.js +13 -13
  17. package/dist/lib/address/p2tr.d.ts +2 -2
  18. package/dist/lib/address/p2tr.js +13 -13
  19. package/dist/lib/address/p2wpkh.d.ts +2 -2
  20. package/dist/lib/address/p2wpkh.js +14 -14
  21. package/dist/lib/address/p2wsh.d.ts +2 -2
  22. package/dist/lib/address/p2wsh.js +13 -13
  23. package/dist/lib/address/script.d.ts +1 -1
  24. package/dist/lib/address/script.js +16 -16
  25. package/dist/lib/address/util.d.ts +1 -1
  26. package/dist/lib/address/util.js +22 -22
  27. package/dist/lib/meta/index.d.ts +4 -4
  28. package/dist/lib/meta/index.js +4 -4
  29. package/dist/lib/meta/locktime.d.ts +1 -1
  30. package/dist/lib/meta/locktime.js +12 -12
  31. package/dist/lib/meta/ref.js +9 -6
  32. package/dist/lib/meta/scribe.d.ts +2 -2
  33. package/dist/lib/meta/scribe.js +48 -53
  34. package/dist/lib/meta/sequence.d.ts +1 -1
  35. package/dist/lib/meta/sequence.js +16 -15
  36. package/dist/lib/script/decode.d.ts +2 -2
  37. package/dist/lib/script/decode.js +50 -15
  38. package/dist/lib/script/encode.d.ts +1 -1
  39. package/dist/lib/script/encode.js +20 -16
  40. package/dist/lib/script/index.d.ts +5 -13
  41. package/dist/lib/script/index.js +5 -14
  42. package/dist/lib/script/lock.d.ts +2 -2
  43. package/dist/lib/script/lock.js +15 -12
  44. package/dist/lib/script/util.js +4 -4
  45. package/dist/lib/script/words.js +129 -129
  46. package/dist/lib/sighash/index.d.ts +3 -3
  47. package/dist/lib/sighash/index.js +3 -3
  48. package/dist/lib/sighash/segwit.d.ts +2 -2
  49. package/dist/lib/sighash/segwit.js +15 -14
  50. package/dist/lib/sighash/taproot.d.ts +2 -2
  51. package/dist/lib/sighash/taproot.js +24 -23
  52. package/dist/lib/sighash/util.d.ts +2 -2
  53. package/dist/lib/sighash/util.js +7 -7
  54. package/dist/lib/signer/index.d.ts +2 -2
  55. package/dist/lib/signer/index.js +2 -2
  56. package/dist/lib/signer/sign.d.ts +1 -1
  57. package/dist/lib/signer/sign.js +42 -7
  58. package/dist/lib/signer/verify.d.ts +17 -3
  59. package/dist/lib/signer/verify.js +233 -3
  60. package/dist/lib/taproot/cblock.d.ts +1 -1
  61. package/dist/lib/taproot/cblock.js +14 -16
  62. package/dist/lib/taproot/encode.d.ts +1 -1
  63. package/dist/lib/taproot/encode.js +7 -7
  64. package/dist/lib/taproot/index.d.ts +4 -4
  65. package/dist/lib/taproot/index.js +4 -4
  66. package/dist/lib/taproot/parse.d.ts +1 -1
  67. package/dist/lib/taproot/parse.js +12 -14
  68. package/dist/lib/taproot/tree.d.ts +2 -2
  69. package/dist/lib/taproot/tree.js +11 -7
  70. package/dist/lib/tx/create.d.ts +1 -1
  71. package/dist/lib/tx/create.js +28 -12
  72. package/dist/lib/tx/decode.d.ts +2 -2
  73. package/dist/lib/tx/decode.js +50 -17
  74. package/dist/lib/tx/encode.d.ts +2 -2
  75. package/dist/lib/tx/encode.js +13 -16
  76. package/dist/lib/tx/index.d.ts +7 -7
  77. package/dist/lib/tx/index.js +7 -7
  78. package/dist/lib/tx/parse.d.ts +1 -1
  79. package/dist/lib/tx/parse.js +9 -9
  80. package/dist/lib/tx/size.d.ts +2 -2
  81. package/dist/lib/tx/size.js +9 -9
  82. package/dist/lib/tx/util.d.ts +2 -2
  83. package/dist/lib/tx/util.js +23 -22
  84. package/dist/lib/tx/validate.d.ts +1 -1
  85. package/dist/lib/tx/validate.js +3 -3
  86. package/dist/lib/witness/index.d.ts +2 -2
  87. package/dist/lib/witness/index.js +2 -2
  88. package/dist/lib/witness/parse.d.ts +2 -2
  89. package/dist/lib/witness/parse.js +24 -23
  90. package/dist/lib/witness/util.d.ts +2 -2
  91. package/dist/lib/witness/util.js +5 -5
  92. package/dist/main.cjs +2308 -1007
  93. package/dist/main.cjs.map +1 -1
  94. package/dist/module.mjs +2308 -1007
  95. package/dist/module.mjs.map +1 -1
  96. package/dist/package.json +20 -17
  97. package/dist/schema/base.d.ts +1 -1
  98. package/dist/schema/base.js +17 -13
  99. package/dist/schema/index.d.ts +2 -2
  100. package/dist/schema/index.js +2 -2
  101. package/dist/schema/taproot.d.ts +1 -1
  102. package/dist/schema/taproot.js +2 -2
  103. package/dist/schema/tx.d.ts +1 -1
  104. package/dist/schema/tx.js +4 -4
  105. package/dist/script.js +8 -8
  106. package/dist/script.js.map +1 -1
  107. package/dist/types/address.d.ts +4 -4
  108. package/dist/types/index.d.ts +8 -8
  109. package/dist/types/index.js +8 -8
  110. package/dist/types/meta.d.ts +4 -4
  111. package/dist/types/psbt.d.ts +2 -2
  112. package/dist/types/script.d.ts +2 -2
  113. package/dist/types/sighash.d.ts +2 -2
  114. package/dist/types/witness.d.ts +5 -5
  115. package/package.json +20 -17
  116. package/src/const.ts +0 -61
  117. package/src/index.ts +0 -13
  118. package/src/lib/address/api.ts +0 -50
  119. package/src/lib/address/encode.ts +0 -183
  120. package/src/lib/address/index.ts +0 -7
  121. package/src/lib/address/p2pkh.ts +0 -94
  122. package/src/lib/address/p2sh.ts +0 -96
  123. package/src/lib/address/p2tr.ts +0 -91
  124. package/src/lib/address/p2wpkh.ts +0 -94
  125. package/src/lib/address/p2wsh.ts +0 -92
  126. package/src/lib/address/script.ts +0 -63
  127. package/src/lib/address/util.ts +0 -87
  128. package/src/lib/meta/index.ts +0 -4
  129. package/src/lib/meta/locktime.ts +0 -57
  130. package/src/lib/meta/ref.ts +0 -107
  131. package/src/lib/meta/scribe.ts +0 -256
  132. package/src/lib/meta/sequence.ts +0 -146
  133. package/src/lib/script/decode.ts +0 -85
  134. package/src/lib/script/encode.ts +0 -129
  135. package/src/lib/script/index.ts +0 -20
  136. package/src/lib/script/lock.ts +0 -73
  137. package/src/lib/script/util.ts +0 -78
  138. package/src/lib/script/words.ts +0 -182
  139. package/src/lib/sighash/index.ts +0 -3
  140. package/src/lib/sighash/segwit.ts +0 -152
  141. package/src/lib/sighash/taproot.ts +0 -206
  142. package/src/lib/sighash/util.ts +0 -51
  143. package/src/lib/signer/index.ts +0 -2
  144. package/src/lib/signer/sign.ts +0 -39
  145. package/src/lib/signer/verify.ts +0 -88
  146. package/src/lib/taproot/cblock.ts +0 -96
  147. package/src/lib/taproot/encode.ts +0 -49
  148. package/src/lib/taproot/index.ts +0 -4
  149. package/src/lib/taproot/parse.ts +0 -65
  150. package/src/lib/taproot/tree.ts +0 -94
  151. package/src/lib/tx/create.ts +0 -90
  152. package/src/lib/tx/decode.ts +0 -123
  153. package/src/lib/tx/encode.ts +0 -155
  154. package/src/lib/tx/index.ts +0 -7
  155. package/src/lib/tx/parse.ts +0 -69
  156. package/src/lib/tx/size.ts +0 -68
  157. package/src/lib/tx/util.ts +0 -113
  158. package/src/lib/tx/validate.ts +0 -49
  159. package/src/lib/witness/index.ts +0 -2
  160. package/src/lib/witness/parse.ts +0 -127
  161. package/src/lib/witness/util.ts +0 -18
  162. package/src/schema/base.ts +0 -57
  163. package/src/schema/index.ts +0 -2
  164. package/src/schema/taproot.ts +0 -12
  165. package/src/schema/tx.ts +0 -48
  166. package/src/types/address.ts +0 -35
  167. package/src/types/index.ts +0 -8
  168. package/src/types/meta.ts +0 -48
  169. package/src/types/psbt.ts +0 -15
  170. package/src/types/script.ts +0 -18
  171. package/src/types/sighash.ts +0 -16
  172. package/src/types/taproot.ts +0 -41
  173. package/src/types/txdata.ts +0 -85
  174. package/src/types/witness.ts +0 -42
@@ -1,146 +1,146 @@
1
1
  export const OPCODE_MAP = {
2
- OP_0: 0,
3
- OP_PUSHDATA1: 76,
4
- OP_PUSHDATA2: 77,
5
- OP_PUSHDATA4: 78,
6
- OP_1NEGATE: 79,
7
- OP_SUCCESS80: 80,
8
- OP_1: 81,
9
- OP_2: 82,
10
- OP_3: 83,
11
- OP_4: 84,
12
- OP_5: 85,
13
- OP_6: 86,
14
- OP_7: 87,
15
- OP_8: 88,
16
- OP_9: 89,
17
- OP_10: 90,
18
- OP_11: 91,
19
- OP_12: 92,
20
- OP_13: 93,
21
- OP_14: 94,
22
- OP_15: 95,
23
- OP_16: 96,
24
- OP_NOP: 97,
25
- OP_SUCCESS98: 98,
26
- OP_IF: 99,
27
- OP_NOTIF: 100,
28
- OP_ELSE: 103,
29
- OP_ENDIF: 104,
30
- OP_VERIFY: 105,
31
- OP_RETURN: 106,
32
- OP_TOALTSTACK: 107,
33
- OP_FROMALTSTACK: 108,
34
- OP_2DROP: 109,
35
- OP_2DUP: 110,
36
- OP_3DUP: 111,
37
- OP_2OVER: 112,
38
- OP_2ROT: 113,
39
- OP_2SWAP: 114,
40
- OP_IFDUP: 115,
41
- OP_DEPTH: 116,
42
- OP_DROP: 117,
43
- OP_DUP: 118,
44
- OP_NIP: 119,
45
- OP_OVER: 120,
46
- OP_PICK: 121,
47
- OP_ROLL: 122,
48
- OP_ROT: 123,
49
- OP_SWAP: 124,
50
- OP_TUCK: 125,
51
- OP_SUCCESS126: 126,
52
- OP_SUCCESS127: 127,
53
- OP_SUCCESS128: 128,
54
- OP_SUCCESS129: 129,
55
- OP_SIZE: 130,
56
- OP_SUCCESS131: 131,
57
- OP_SUCCESS132: 132,
58
- OP_SUCCESS133: 133,
59
- OP_SUCCESS134: 134,
60
- OP_EQUAL: 135,
61
- OP_EQUALVERIFY: 136,
62
- OP_SUCCESS137: 137,
63
- OP_SUCCESS138: 138,
64
- OP_1ADD: 139,
65
- OP_1SUB: 140,
66
- OP_SUCCESS141: 141,
67
- OP_SUCCESS142: 142,
68
- OP_NEGATE: 143,
69
- OP_ABS: 144,
70
- OP_NOT: 145,
71
- OP_0NOTEQUAL: 146,
72
- OP_ADD: 147,
73
- OP_SUB: 148,
74
- OP_SUCCESS149: 149,
75
- OP_SUCCESS150: 150,
76
- OP_SUCCESS151: 151,
77
- OP_SUCCESS152: 152,
78
- OP_SUCCESS153: 153,
79
- OP_BOOLAND: 154,
80
- OP_BOOLOR: 155,
81
- OP_NUMEQUAL: 156,
82
- OP_NUMEQUALVERIFY: 157,
83
- OP_NUMNOTEQUAL: 158,
84
- OP_LESSTHAN: 159,
85
- OP_GREATERTHAN: 160,
86
- OP_LESSTHANOREQUAL: 161,
87
- OP_GREATERTHANOREQUAL: 162,
88
- OP_MIN: 163,
89
- OP_MAX: 164,
90
- OP_WITHIN: 165,
91
- OP_RIPEMD160: 166,
92
- OP_SHA1: 167,
93
- OP_SHA256: 168,
94
- OP_HASH160: 169,
95
- OP_HASH256: 170,
96
- OP_CODESEPARATOR: 171,
97
- OP_CHECKSIG: 172,
98
- OP_CHECKSIGVERIFY: 173,
99
- OP_CHECKMULTISIG: 174,
100
- OP_CHECKMULTISIGVERIFY: 175,
101
- OP_NOP1: 176,
102
- OP_CHECKLOCKTIMEVERIFY: 177,
103
- OP_CHECKSEQUENCEVERIFY: 178,
104
- OP_NOP4: 179,
105
- OP_NOP5: 180,
106
- OP_NOP6: 181,
107
- OP_NOP7: 182,
108
- OP_NOP8: 183,
109
- OP_NOP9: 184,
110
- OP_NOP10: 185,
111
- OP_CHECKSIGADD: 186
2
+ OP_0: 0x00,
3
+ OP_PUSHDATA1: 0x4c,
4
+ OP_PUSHDATA2: 0x4d,
5
+ OP_PUSHDATA4: 0x4e,
6
+ OP_1NEGATE: 0x4f,
7
+ OP_SUCCESS80: 0x50,
8
+ OP_1: 0x51,
9
+ OP_2: 0x52,
10
+ OP_3: 0x53,
11
+ OP_4: 0x54,
12
+ OP_5: 0x55,
13
+ OP_6: 0x56,
14
+ OP_7: 0x57,
15
+ OP_8: 0x58,
16
+ OP_9: 0x59,
17
+ OP_10: 0x5a,
18
+ OP_11: 0x5b,
19
+ OP_12: 0x5c,
20
+ OP_13: 0x5d,
21
+ OP_14: 0x5e,
22
+ OP_15: 0x5f,
23
+ OP_16: 0x60,
24
+ OP_NOP: 0x61,
25
+ OP_SUCCESS98: 0x62,
26
+ OP_IF: 0x63,
27
+ OP_NOTIF: 0x64,
28
+ OP_ELSE: 0x67,
29
+ OP_ENDIF: 0x68,
30
+ OP_VERIFY: 0x69,
31
+ OP_RETURN: 0x6a,
32
+ OP_TOALTSTACK: 0x6b,
33
+ OP_FROMALTSTACK: 0x6c,
34
+ OP_2DROP: 0x6d,
35
+ OP_2DUP: 0x6e,
36
+ OP_3DUP: 0x6f,
37
+ OP_2OVER: 0x70,
38
+ OP_2ROT: 0x71,
39
+ OP_2SWAP: 0x72,
40
+ OP_IFDUP: 0x73,
41
+ OP_DEPTH: 0x74,
42
+ OP_DROP: 0x75,
43
+ OP_DUP: 0x76,
44
+ OP_NIP: 0x77,
45
+ OP_OVER: 0x78,
46
+ OP_PICK: 0x79,
47
+ OP_ROLL: 0x7a,
48
+ OP_ROT: 0x7b,
49
+ OP_SWAP: 0x7c,
50
+ OP_TUCK: 0x7d,
51
+ OP_SUCCESS126: 0x7e,
52
+ OP_SUCCESS127: 0x7f,
53
+ OP_SUCCESS128: 0x80,
54
+ OP_SUCCESS129: 0x81,
55
+ OP_SIZE: 0x82,
56
+ OP_SUCCESS131: 0x83,
57
+ OP_SUCCESS132: 0x84,
58
+ OP_SUCCESS133: 0x85,
59
+ OP_SUCCESS134: 0x86,
60
+ OP_EQUAL: 0x87,
61
+ OP_EQUALVERIFY: 0x88,
62
+ OP_SUCCESS137: 0x89,
63
+ OP_SUCCESS138: 0x8a,
64
+ OP_1ADD: 0x8b,
65
+ OP_1SUB: 0x8c,
66
+ OP_SUCCESS141: 0x8d,
67
+ OP_SUCCESS142: 0x8e,
68
+ OP_NEGATE: 0x8f,
69
+ OP_ABS: 0x90,
70
+ OP_NOT: 0x91,
71
+ OP_0NOTEQUAL: 0x92,
72
+ OP_ADD: 0x93,
73
+ OP_SUB: 0x94,
74
+ OP_SUCCESS149: 0x95,
75
+ OP_SUCCESS150: 0x96,
76
+ OP_SUCCESS151: 0x97,
77
+ OP_SUCCESS152: 0x98,
78
+ OP_SUCCESS153: 0x99,
79
+ OP_BOOLAND: 0x9a,
80
+ OP_BOOLOR: 0x9b,
81
+ OP_NUMEQUAL: 0x9c,
82
+ OP_NUMEQUALVERIFY: 0x9d,
83
+ OP_NUMNOTEQUAL: 0x9e,
84
+ OP_LESSTHAN: 0x9f,
85
+ OP_GREATERTHAN: 0xa0,
86
+ OP_LESSTHANOREQUAL: 0xa1,
87
+ OP_GREATERTHANOREQUAL: 0xa2,
88
+ OP_MIN: 0xa3,
89
+ OP_MAX: 0xa4,
90
+ OP_WITHIN: 0xa5,
91
+ OP_RIPEMD160: 0xa6,
92
+ OP_SHA1: 0xa7,
93
+ OP_SHA256: 0xa8,
94
+ OP_HASH160: 0xa9,
95
+ OP_HASH256: 0xaa,
96
+ OP_CODESEPARATOR: 0xab,
97
+ OP_CHECKSIG: 0xac,
98
+ OP_CHECKSIGVERIFY: 0xad,
99
+ OP_CHECKMULTISIG: 0xae,
100
+ OP_CHECKMULTISIGVERIFY: 0xaf,
101
+ OP_NOP1: 0xb0,
102
+ OP_CHECKLOCKTIMEVERIFY: 0xb1,
103
+ OP_CHECKSEQUENCEVERIFY: 0xb2,
104
+ OP_NOP4: 0xb3,
105
+ OP_NOP5: 0xb4,
106
+ OP_NOP6: 0xb5,
107
+ OP_NOP7: 0xb6,
108
+ OP_NOP8: 0xb7,
109
+ OP_NOP9: 0xb8,
110
+ OP_NOP10: 0xb9,
111
+ OP_CHECKSIGADD: 0xba,
112
112
  };
113
113
  export function get_op_code(num) {
114
114
  if (num > 186 && num < 255) {
115
- return 'OP_SUCCESS' + String(num);
115
+ return `OP_SUCCESS${String(num)}`;
116
116
  }
117
117
  for (const [k, v] of Object.entries(OPCODE_MAP)) {
118
118
  if (v === num)
119
119
  return k;
120
120
  }
121
- throw new Error('OPCODE not found:' + String(num));
121
+ throw new Error(`OPCODE not found:${String(num)}`);
122
122
  }
123
123
  export function get_asm_code(string) {
124
124
  for (const [k, v] of Object.entries(OPCODE_MAP)) {
125
125
  if (k === string)
126
126
  return Number(v);
127
127
  }
128
- throw new Error('OPCODE not found:' + string);
128
+ throw new Error(`OPCODE not found:${string}`);
129
129
  }
130
130
  export function get_op_type(word) {
131
131
  switch (true) {
132
- case (word === 0):
133
- return 'opcode';
134
- case (word >= 1 && word <= 75):
135
- return 'varint';
136
- case (word === 76):
137
- return 'pushdata1';
138
- case (word === 77):
139
- return 'pushdata2';
140
- case (word === 78):
141
- return 'pushdata4';
142
- case (word <= 254):
143
- return 'opcode';
132
+ case word === 0:
133
+ return "opcode";
134
+ case word >= 1 && word <= 75:
135
+ return "varint";
136
+ case word === 76:
137
+ return "pushdata1";
138
+ case word === 77:
139
+ return "pushdata2";
140
+ case word === 78:
141
+ return "pushdata4";
142
+ case word <= 254:
143
+ return "opcode";
144
144
  default:
145
145
  throw new Error(`Invalid word range: ${word}`);
146
146
  }
@@ -150,13 +150,13 @@ export function is_valid_op(word) {
150
150
  const MAX_RANGE = 254;
151
151
  const DISABLED_OPCODES = [];
152
152
  switch (true) {
153
- case (typeof (word) !== 'number'):
153
+ case typeof word !== "number":
154
154
  return false;
155
- case (word === 0):
155
+ case word === 0:
156
156
  return true;
157
- case (DISABLED_OPCODES.includes(word)):
157
+ case DISABLED_OPCODES.includes(word):
158
158
  return false;
159
- case (MIN_RANGE < word && word < MAX_RANGE):
159
+ case MIN_RANGE < word && word < MAX_RANGE:
160
160
  return true;
161
161
  default:
162
162
  return false;
@@ -1,3 +1,3 @@
1
- export * from './segwit.js';
2
- export * from './taproot.js';
3
- export * from './util.js';
1
+ export * from "./segwit.js";
2
+ export * from "./taproot.js";
3
+ export * from "./util.js";
@@ -1,3 +1,3 @@
1
- export * from './segwit.js';
2
- export * from './taproot.js';
3
- export * from './util.js';
1
+ export * from "./segwit.js";
2
+ export * from "./taproot.js";
3
+ export * from "./util.js";
@@ -1,5 +1,5 @@
1
- import { Buff } from '@vbyte/buff';
2
- import { SigHashOptions, TxData, TxInput, TxOutput } from '../../types/index.js';
1
+ import { Buff } from "@vbyte/buff";
2
+ import type { SigHashOptions, TxData, TxInput, TxOutput } from "../../types/index.js";
3
3
  export declare function hash_segwit_tx(txdata: TxData, options?: SigHashOptions): Buff;
4
4
  export declare function bip143_hash_prevouts(vin: TxInput[], isAnypay?: boolean): Uint8Array;
5
5
  export declare function bip143_hash_sequence(vin: TxInput[], sigflag: number, isAnyPay: boolean): Uint8Array;
@@ -1,24 +1,24 @@
1
- import { Buff } from '@vbyte/buff';
2
- import { hash160, hash256 } from '@vbyte/micro-lib/hash';
3
- import { Assert } from '@vbyte/micro-lib';
4
- import { parse_txinput } from './util.js';
5
- import { prefix_script_size, decode_script } from '../../lib/script/index.js';
6
- import { encode_txin_vout, encode_tx_locktime, encode_txin_sequence, encode_txin_txid, encode_vout_value, encode_tx_version, parse_tx } from '../../lib/tx/index.js';
7
- import * as CONST from '../../const.js';
1
+ import { Buff } from "@vbyte/buff";
2
+ import { Assert } from "@vbyte/micro-lib";
3
+ import { hash160, hash256 } from "@vbyte/micro-lib/hash";
4
+ import * as CONST from "../../const.js";
5
+ import { decode_script, prefix_script_size } from "../../lib/script/index.js";
6
+ import { encode_tx_locktime, encode_tx_version, encode_txin_sequence, encode_txin_txid, encode_txin_vout, encode_vout_value, parse_tx, } from "../../lib/tx/index.js";
7
+ import { parse_txinput } from "./util.js";
8
8
  export function hash_segwit_tx(txdata, options = {}) {
9
9
  const { sigflag = 0x01, txindex } = options;
10
10
  const tx = parse_tx(txdata);
11
11
  const is_anypay = (sigflag & 0x80) === 0x80;
12
12
  const flag = sigflag % 0x80;
13
13
  if (!CONST.SIGHASH_SEGWIT.includes(flag)) {
14
- throw new Error('Invalid hash type: ' + String(sigflag));
14
+ throw new Error(`Invalid hash type: ${String(sigflag)}`);
15
15
  }
16
16
  const { version, vin, vout, locktime } = tx;
17
17
  const txinput = parse_txinput(tx, options);
18
18
  const { txid, vout: prevIdx, prevout, sequence } = txinput;
19
19
  const { value } = prevout ?? {};
20
20
  if (value === undefined) {
21
- throw new Error('Prevout value is empty!');
21
+ throw new Error("Prevout value is empty!");
22
22
  }
23
23
  let { pubkey, script } = options;
24
24
  if (script === undefined && pubkey !== undefined) {
@@ -26,10 +26,10 @@ export function hash_segwit_tx(txdata, options = {}) {
26
26
  script = `76a914${String(pkhash)}88ac`;
27
27
  }
28
28
  if (script === undefined) {
29
- throw new Error('No pubkey / script has been set!');
29
+ throw new Error("No pubkey / script has been set!");
30
30
  }
31
- if (decode_script(script).includes('OP_CODESEPARATOR')) {
32
- throw new Error('This library does not currently support the use of OP_CODESEPARATOR in segwit scripts.');
31
+ if (decode_script(script).includes("OP_CODESEPARATOR")) {
32
+ throw new Error("This library does not currently support the use of OP_CODESEPARATOR in segwit scripts.");
33
33
  }
34
34
  const sighash = [
35
35
  encode_tx_version(version),
@@ -42,7 +42,7 @@ export function hash_segwit_tx(txdata, options = {}) {
42
42
  encode_txin_sequence(sequence),
43
43
  bip143_hash_outputs(vout, flag, txindex),
44
44
  encode_tx_locktime(locktime),
45
- Buff.num(sigflag, 4).reverse()
45
+ Buff.num(sigflag, 4).reverse(),
46
46
  ];
47
47
  return hash256(Buff.join(sighash));
48
48
  }
@@ -77,7 +77,8 @@ export function bip143_hash_outputs(vout, sigflag, idx) {
77
77
  return hash256(Buff.join(stack));
78
78
  }
79
79
  if (sigflag === 0x03) {
80
- Assert.ok(idx !== undefined);
80
+ Assert.ok(idx !== undefined, "txindex required for SIGHASH_SINGLE");
81
+ Assert.ok(idx >= 0, "txindex must be non-negative");
81
82
  if (idx < vout.length) {
82
83
  const { value, script_pk } = vout[idx];
83
84
  stack.push(encode_vout_value(value));
@@ -1,5 +1,5 @@
1
- import { Buff } from '@vbyte/buff';
2
- import type { SigHashOptions, TxData, TxInput, TxOutput } from '../../types/index.js';
1
+ import { Buff } from "@vbyte/buff";
2
+ import type { SigHashOptions, TxData, TxInput, TxOutput } from "../../types/index.js";
3
3
  export declare function hash_taproot_tx(template: TxData | string, config?: SigHashOptions): Buff;
4
4
  export declare function get_taproot_tx_preimage(template: TxData | string, config?: SigHashOptions): Buff;
5
5
  export declare function bip341_hash_outpoints(vin: TxInput[]): Buff;
@@ -1,26 +1,26 @@
1
- import { Buff } from '@vbyte/buff';
2
- import { Assert } from '@vbyte/micro-lib';
3
- import { hash340, sha256 } from '@vbyte/micro-lib/hash';
4
- import { encode_tapscript } from '../../lib/taproot/encode.js';
5
- import { parse_tx } from '../../lib/tx/parse.js';
6
- import * as CONST from '../../const.js';
7
- import { parse_txinput, get_annex_data, get_prevout } from './util.js';
8
- import { encode_txin_vout, encode_tx_locktime, encode_txin_sequence, encode_txin_txid, encode_vout_value, encode_tx_version, encode_script_data } from '../../lib/tx/encode.js';
1
+ import { Buff } from "@vbyte/buff";
2
+ import { Assert } from "@vbyte/micro-lib";
3
+ import { hash340, sha256 } from "@vbyte/micro-lib/hash";
4
+ import * as CONST from "../../const.js";
5
+ import { encode_tapscript } from "../../lib/taproot/encode.js";
6
+ import { encode_script_data, encode_tx_locktime, encode_tx_version, encode_txin_sequence, encode_txin_txid, encode_txin_vout, encode_vout_value, } from "../../lib/tx/encode.js";
7
+ import { parse_tx } from "../../lib/tx/parse.js";
8
+ import { get_annex_data, get_prevout, parse_txinput } from "./util.js";
9
9
  export function hash_taproot_tx(template, config = {}) {
10
10
  const preimage = get_taproot_tx_preimage(template, config);
11
- return hash340('TapSighash', preimage);
11
+ return hash340("TapSighash", preimage);
12
12
  }
13
13
  export function get_taproot_tx_preimage(template, config = {}) {
14
- const { script, txindex, sigflag = 0x00, extflag = 0x00, key_version = 0x00, separator_pos = 0xFFFFFFFF } = config;
14
+ const { script, txindex, sigflag = 0x00, extflag = 0x00, key_version = 0x00, separator_pos = 0xffffffff, } = config;
15
15
  const tx = parse_tx(template);
16
16
  const { version, vin: input, vout: output, locktime } = tx;
17
17
  const txinput = parse_txinput(tx, config);
18
18
  const { txid, vout, sequence, witness = [] } = txinput;
19
19
  if (!CONST.SIGHASH_TAPROOT.includes(sigflag)) {
20
- throw new Error('Invalid hash type: ' + String(sigflag));
20
+ throw new Error(`Invalid hash type: ${String(sigflag)}`);
21
21
  }
22
22
  if (extflag < 0 || extflag > 127) {
23
- throw new Error('Extention flag out of range: ' + String(extflag));
23
+ throw new Error(`Extention flag out of range: ${String(extflag)}`);
24
24
  }
25
25
  let { extension } = config;
26
26
  if (script !== undefined) {
@@ -28,17 +28,17 @@ export function get_taproot_tx_preimage(template, config = {}) {
28
28
  }
29
29
  const is_anypay = (sigflag & 0x80) === 0x80;
30
30
  const annex = get_annex_data(witness);
31
- const annexBit = (annex !== undefined) ? 1 : 0;
32
- const extendBit = (extension !== undefined) ? 1 : 0;
33
- const spendType = ((extflag + extendBit) * 2) + annexBit;
31
+ const annexBit = annex !== undefined ? 1 : 0;
32
+ const extendBit = extension !== undefined ? 1 : 0;
33
+ const spendType = (extflag + extendBit) * 2 + annexBit;
34
34
  const preimage = [
35
35
  Buff.num(0x00, 1),
36
36
  Buff.num(sigflag, 1),
37
37
  encode_tx_version(version),
38
- encode_tx_locktime(locktime)
38
+ encode_tx_locktime(locktime),
39
39
  ];
40
40
  if (!is_anypay) {
41
- const prevouts = input.map(e => get_prevout(e));
41
+ const prevouts = input.map((e) => get_prevout(e));
42
42
  preimage.push(bip341_hash_outpoints(input), bip341_hash_amounts(prevouts), bip341_hash_scripts(prevouts), bip341_hash_sequence(input));
43
43
  }
44
44
  if ((sigflag & 0x03) < 2 || (sigflag & 0x03) > 3) {
@@ -50,18 +50,19 @@ export function get_taproot_tx_preimage(template, config = {}) {
50
50
  preimage.push(encode_txin_txid(txid), encode_txin_vout(vout), encode_vout_value(value), encode_script_data(script_pk), encode_txin_sequence(sequence));
51
51
  }
52
52
  else {
53
- Assert.ok(typeof txindex === 'number');
53
+ Assert.ok(typeof txindex === "number");
54
54
  preimage.push(Buff.num(txindex, 4).reverse());
55
55
  }
56
56
  if (annex !== undefined) {
57
57
  preimage.push(annex);
58
58
  }
59
59
  if ((sigflag & 0x03) === 0x03) {
60
- Assert.ok(typeof txindex === 'number');
60
+ Assert.ok(typeof txindex === "number", "txindex required for SIGHASH_SINGLE");
61
+ Assert.ok(txindex >= 0 && txindex < output.length, `txindex ${txindex} out of bounds for ${output.length} outputs`);
61
62
  preimage.push(bip341_hash_output(output[txindex]));
62
63
  }
63
64
  if (extension !== undefined) {
64
- preimage.push(Buff.bytes(extension), Buff.num(key_version), Buff.num(separator_pos, 4, 'le'));
65
+ preimage.push(Buff.bytes(extension), Buff.num(key_version), Buff.num(separator_pos, 4, "le"));
65
66
  }
66
67
  return Buff.join(preimage);
67
68
  }
@@ -74,13 +75,13 @@ export function bip341_hash_outpoints(vin) {
74
75
  return sha256(Buff.join(stack));
75
76
  }
76
77
  export function bip341_hash_sequence(vin) {
77
- return sha256(...vin.map(vin => encode_txin_sequence(vin.sequence)));
78
+ return sha256(...vin.map((vin) => encode_txin_sequence(vin.sequence)));
78
79
  }
79
80
  export function bip341_hash_amounts(prevouts) {
80
- return sha256(...prevouts.map(prevout => encode_vout_value(prevout.value)));
81
+ return sha256(...prevouts.map((prevout) => encode_vout_value(prevout.value)));
81
82
  }
82
83
  export function bip341_hash_scripts(prevouts) {
83
- return sha256(...prevouts.map(prevout => encode_script_data(prevout.script_pk)));
84
+ return sha256(...prevouts.map((prevout) => encode_script_data(prevout.script_pk)));
84
85
  }
85
86
  export function bip341_hash_outputs(vout) {
86
87
  const stack = [];
@@ -1,5 +1,5 @@
1
- import { Buff } from '@vbyte/buff';
2
- import type { SigHashOptions, TxInput, TxData, TxOutput } from '../../types/index.js';
1
+ import { Buff } from "@vbyte/buff";
2
+ import type { SigHashOptions, TxData, TxInput, TxOutput } from "../../types/index.js";
3
3
  export declare function get_prevout(vin: TxInput): TxOutput;
4
4
  export declare function parse_txinput(txdata: TxData, config?: SigHashOptions): TxInput;
5
5
  export declare function get_annex_data(witness?: string[]): Buff | undefined;
@@ -1,15 +1,15 @@
1
- import { Buff } from '@vbyte/buff';
2
- import { Assert } from '@vbyte/micro-lib';
3
- import { sha256 } from '@vbyte/micro-lib/hash';
1
+ import { Buff } from "@vbyte/buff";
2
+ import { Assert } from "@vbyte/micro-lib";
3
+ import { sha256 } from "@vbyte/micro-lib/hash";
4
4
  export function get_prevout(vin) {
5
- Assert.exists(vin.prevout, 'Prevout data missing for input: ' + String(vin.txid));
5
+ Assert.exists(vin.prevout, `Prevout data missing for input: ${String(vin.txid)}`);
6
6
  return vin.prevout;
7
7
  }
8
8
  export function parse_txinput(txdata, config) {
9
9
  let { txindex, txinput } = config ?? {};
10
10
  if (txindex !== undefined) {
11
11
  if (txindex >= txdata.vin.length) {
12
- throw new Error('Input index out of bounds: ' + String(txindex));
12
+ throw new Error(`Input index out of bounds: ${String(txindex)}`);
13
13
  }
14
14
  txinput = txdata.vin.at(txindex);
15
15
  }
@@ -22,8 +22,8 @@ export function get_annex_data(witness) {
22
22
  if (witness.length < 2)
23
23
  return;
24
24
  const annex = witness.at(-1);
25
- if (typeof annex === 'string' && annex.startsWith('50')) {
26
- const bytes = Buff.hex(annex).prefix_varint('be');
25
+ if (typeof annex === "string" && annex.startsWith("50")) {
26
+ const bytes = Buff.hex(annex).prefix_varint("be");
27
27
  return sha256(bytes);
28
28
  }
29
29
  return undefined;
@@ -1,2 +1,2 @@
1
- export * from './sign.js';
2
- export * from './verify.js';
1
+ export * from "./sign.js";
2
+ export * from "./verify.js";
@@ -1,2 +1,2 @@
1
- export * from './sign.js';
2
- export * from './verify.js';
1
+ export * from "./sign.js";
2
+ export * from "./verify.js";
@@ -1,3 +1,3 @@
1
- import type { SigHashOptions, TxData } from '../../types/index.js';
1
+ import type { SigHashOptions, TxData } from "../../types/index.js";
2
2
  export declare function sign_segwit_tx(seckey: string, txdata: TxData, options: SigHashOptions): string;
3
3
  export declare function sign_taproot_tx(seckey: string, txdata: TxData, options: SigHashOptions): string;
@@ -1,10 +1,43 @@
1
- import { Buff } from '@vbyte/buff';
2
- import { ECC } from '@vbyte/micro-lib';
3
- import { parse_tx } from '../../lib/tx/parse.js';
4
- import { SIGHASH_DEFAULT } from '../../const.js';
5
- import { hash_segwit_tx } from '../../lib/sighash/segwit.js';
6
- import { hash_taproot_tx } from '../../lib/sighash/taproot.js';
1
+ import { Buff } from "@vbyte/buff";
2
+ import { ECC } from "@vbyte/micro-lib";
3
+ import { SIGHASH_DEFAULT, SIGHASH_SEGWIT, SIGHASH_TAPROOT } from "../../const.js";
4
+ import { hash_segwit_tx } from "../../lib/sighash/segwit.js";
5
+ import { hash_taproot_tx } from "../../lib/sighash/taproot.js";
6
+ import { parse_tx } from "../../lib/tx/parse.js";
7
+ const SECKEY_REGEX = /^[0-9a-fA-F]{64}$/;
8
+ function validate_seckey(seckey) {
9
+ if (typeof seckey !== "string") {
10
+ throw new Error("Secret key must be a string");
11
+ }
12
+ if (!SECKEY_REGEX.test(seckey)) {
13
+ throw new Error("Invalid secret key format: expected 32-byte hex string (64 characters)");
14
+ }
15
+ }
16
+ function validate_sighash_options(options, validFlags) {
17
+ const { sigflag, txindex } = options;
18
+ if (sigflag !== undefined) {
19
+ if (typeof sigflag !== "number" || !Number.isInteger(sigflag)) {
20
+ throw new Error("sigflag must be an integer");
21
+ }
22
+ const normalizedFlag = sigflag & 0x7f;
23
+ const isAnypay = (sigflag & 0x80) === 0x80;
24
+ const baseFlag = isAnypay ? normalizedFlag | 0x80 : normalizedFlag;
25
+ if (!validFlags.includes(baseFlag) &&
26
+ !validFlags.includes(normalizedFlag)) {
27
+ throw new Error(`Invalid sigflag: ${sigflag}`);
28
+ }
29
+ }
30
+ if (txindex !== undefined) {
31
+ if (typeof txindex !== "number" ||
32
+ !Number.isInteger(txindex) ||
33
+ txindex < 0) {
34
+ throw new Error("txindex must be a non-negative integer");
35
+ }
36
+ }
37
+ }
7
38
  export function sign_segwit_tx(seckey, txdata, options) {
39
+ validate_seckey(seckey);
40
+ validate_sighash_options(options, SIGHASH_SEGWIT);
8
41
  const tx = parse_tx(txdata);
9
42
  const msg = hash_segwit_tx(tx, options);
10
43
  const sig = ECC.sign_ecdsa(seckey, msg).hex;
@@ -12,6 +45,8 @@ export function sign_segwit_tx(seckey, txdata, options) {
12
45
  return sig + flag;
13
46
  }
14
47
  export function sign_taproot_tx(seckey, txdata, options) {
48
+ validate_seckey(seckey);
49
+ validate_sighash_options(options, SIGHASH_TAPROOT);
15
50
  const tx = parse_tx(txdata);
16
51
  const msg = hash_taproot_tx(tx, options);
17
52
  const sig = ECC.sign_bip340(seckey, msg).hex;
@@ -19,5 +54,5 @@ export function sign_taproot_tx(seckey, txdata, options) {
19
54
  return sig + flag;
20
55
  }
21
56
  function format_sigflag(flag) {
22
- return (flag !== 0) ? Buff.num(flag, 1).hex : '';
57
+ return flag !== 0 ? Buff.num(flag, 1).hex : "";
23
58
  }
@@ -1,3 +1,17 @@
1
- import { Bytes } from '@vbyte/buff';
2
- import type { SigHashOptions, TxData } from '../../types/index.js';
3
- export declare function verify_tx(_txdata: TxData | Bytes, _config?: SigHashOptions): boolean;
1
+ import { type Bytes } from "@vbyte/buff";
2
+ import type { SigHashOptions, TxData } from "../../types/index.js";
3
+ export interface VerifyOptions extends SigHashOptions {
4
+ throws?: boolean;
5
+ }
6
+ export interface VerifyResult {
7
+ valid: boolean;
8
+ inputs: InputVerifyResult[];
9
+ error?: string;
10
+ }
11
+ export interface InputVerifyResult {
12
+ index: number;
13
+ valid: boolean;
14
+ type?: string | null;
15
+ error?: string;
16
+ }
17
+ export declare function verify_tx(txdata: TxData | Bytes, options?: VerifyOptions): VerifyResult;