@vbyte/btc-dev 1.1.8 → 2.1.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 (181) hide show
  1. package/CHANGELOG.md +127 -0
  2. package/LICENSE +21 -121
  3. package/README.md +69 -3
  4. package/dist/const.d.ts +3 -0
  5. package/dist/const.js +23 -22
  6. package/dist/error.d.ts +11 -0
  7. package/dist/error.js +20 -0
  8. package/dist/index.d.ts +12 -11
  9. package/dist/index.js +11 -10
  10. package/dist/lib/address/api.d.ts +2 -2
  11. package/dist/lib/address/api.js +13 -12
  12. package/dist/lib/address/encode.d.ts +1 -1
  13. package/dist/lib/address/encode.js +26 -24
  14. package/dist/lib/address/index.d.ts +6 -6
  15. package/dist/lib/address/index.js +6 -6
  16. package/dist/lib/address/p2pkh.d.ts +2 -2
  17. package/dist/lib/address/p2pkh.js +15 -15
  18. package/dist/lib/address/p2sh.d.ts +2 -2
  19. package/dist/lib/address/p2sh.js +14 -14
  20. package/dist/lib/address/p2tr.d.ts +2 -2
  21. package/dist/lib/address/p2tr.js +14 -14
  22. package/dist/lib/address/p2wpkh.d.ts +2 -2
  23. package/dist/lib/address/p2wpkh.js +15 -15
  24. package/dist/lib/address/p2wsh.d.ts +2 -2
  25. package/dist/lib/address/p2wsh.js +14 -14
  26. package/dist/lib/address/script.d.ts +1 -1
  27. package/dist/lib/address/script.js +16 -16
  28. package/dist/lib/address/util.d.ts +1 -1
  29. package/dist/lib/address/util.js +24 -22
  30. package/dist/lib/meta/index.d.ts +4 -4
  31. package/dist/lib/meta/index.js +4 -4
  32. package/dist/lib/meta/locktime.d.ts +1 -1
  33. package/dist/lib/meta/locktime.js +13 -12
  34. package/dist/lib/meta/ref.js +13 -9
  35. package/dist/lib/meta/scribe.d.ts +2 -2
  36. package/dist/lib/meta/scribe.js +71 -56
  37. package/dist/lib/meta/sequence.d.ts +1 -1
  38. package/dist/lib/meta/sequence.js +21 -19
  39. package/dist/lib/script/decode.d.ts +2 -2
  40. package/dist/lib/script/decode.js +53 -17
  41. package/dist/lib/script/encode.d.ts +1 -1
  42. package/dist/lib/script/encode.js +21 -16
  43. package/dist/lib/script/index.d.ts +5 -13
  44. package/dist/lib/script/index.js +5 -14
  45. package/dist/lib/script/lock.d.ts +2 -2
  46. package/dist/lib/script/lock.js +15 -12
  47. package/dist/lib/script/util.js +4 -4
  48. package/dist/lib/script/words.js +131 -130
  49. package/dist/lib/sighash/index.d.ts +3 -3
  50. package/dist/lib/sighash/index.js +3 -3
  51. package/dist/lib/sighash/segwit.d.ts +2 -2
  52. package/dist/lib/sighash/segwit.js +18 -14
  53. package/dist/lib/sighash/taproot.d.ts +2 -2
  54. package/dist/lib/sighash/taproot.js +27 -23
  55. package/dist/lib/sighash/util.d.ts +2 -2
  56. package/dist/lib/sighash/util.js +8 -7
  57. package/dist/lib/signer/index.d.ts +2 -2
  58. package/dist/lib/signer/index.js +2 -2
  59. package/dist/lib/signer/sign.d.ts +1 -1
  60. package/dist/lib/signer/sign.js +43 -7
  61. package/dist/lib/signer/verify.d.ts +17 -3
  62. package/dist/lib/signer/verify.js +232 -3
  63. package/dist/lib/taproot/cblock.d.ts +1 -1
  64. package/dist/lib/taproot/cblock.js +16 -17
  65. package/dist/lib/taproot/encode.d.ts +1 -1
  66. package/dist/lib/taproot/encode.js +9 -8
  67. package/dist/lib/taproot/index.d.ts +4 -4
  68. package/dist/lib/taproot/index.js +4 -4
  69. package/dist/lib/taproot/parse.d.ts +1 -1
  70. package/dist/lib/taproot/parse.js +15 -15
  71. package/dist/lib/taproot/tree.d.ts +2 -2
  72. package/dist/lib/taproot/tree.js +12 -7
  73. package/dist/lib/tx/create.d.ts +1 -1
  74. package/dist/lib/tx/create.js +28 -12
  75. package/dist/lib/tx/decode.d.ts +2 -2
  76. package/dist/lib/tx/decode.js +52 -17
  77. package/dist/lib/tx/encode.d.ts +2 -2
  78. package/dist/lib/tx/encode.js +13 -16
  79. package/dist/lib/tx/index.d.ts +7 -7
  80. package/dist/lib/tx/index.js +7 -7
  81. package/dist/lib/tx/parse.d.ts +1 -1
  82. package/dist/lib/tx/parse.js +9 -9
  83. package/dist/lib/tx/size.d.ts +2 -2
  84. package/dist/lib/tx/size.js +9 -11
  85. package/dist/lib/tx/util.d.ts +2 -2
  86. package/dist/lib/tx/util.js +22 -20
  87. package/dist/lib/tx/validate.d.ts +1 -1
  88. package/dist/lib/tx/validate.js +37 -9
  89. package/dist/lib/witness/index.d.ts +2 -2
  90. package/dist/lib/witness/index.js +2 -2
  91. package/dist/lib/witness/parse.d.ts +2 -2
  92. package/dist/lib/witness/parse.js +24 -23
  93. package/dist/lib/witness/util.d.ts +2 -2
  94. package/dist/lib/witness/util.js +5 -5
  95. package/dist/main.cjs +3305 -2035
  96. package/dist/main.cjs.map +1 -1
  97. package/dist/module.mjs +3303 -2036
  98. package/dist/module.mjs.map +1 -1
  99. package/dist/package.json +24 -19
  100. package/dist/schema/base.d.ts +1 -1
  101. package/dist/schema/base.js +17 -13
  102. package/dist/schema/index.d.ts +2 -2
  103. package/dist/schema/index.js +2 -2
  104. package/dist/schema/taproot.d.ts +1 -1
  105. package/dist/schema/taproot.js +2 -2
  106. package/dist/schema/tx.d.ts +1 -1
  107. package/dist/schema/tx.js +4 -4
  108. package/dist/script.js +10 -12
  109. package/dist/script.js.map +1 -1
  110. package/dist/types/address.d.ts +4 -4
  111. package/dist/types/index.d.ts +8 -8
  112. package/dist/types/index.js +8 -8
  113. package/dist/types/meta.d.ts +4 -4
  114. package/dist/types/psbt.d.ts +2 -2
  115. package/dist/types/script.d.ts +2 -2
  116. package/dist/types/sighash.d.ts +2 -2
  117. package/dist/types/witness.d.ts +5 -5
  118. package/docs/API.md +1145 -0
  119. package/docs/CONVENTIONS.md +316 -0
  120. package/docs/FAQ.md +396 -0
  121. package/docs/GUIDE.md +1102 -0
  122. package/package.json +24 -19
  123. package/src/const.ts +0 -61
  124. package/src/index.ts +0 -13
  125. package/src/lib/address/api.ts +0 -50
  126. package/src/lib/address/encode.ts +0 -183
  127. package/src/lib/address/index.ts +0 -7
  128. package/src/lib/address/p2pkh.ts +0 -94
  129. package/src/lib/address/p2sh.ts +0 -96
  130. package/src/lib/address/p2tr.ts +0 -91
  131. package/src/lib/address/p2wpkh.ts +0 -94
  132. package/src/lib/address/p2wsh.ts +0 -92
  133. package/src/lib/address/script.ts +0 -63
  134. package/src/lib/address/util.ts +0 -87
  135. package/src/lib/meta/index.ts +0 -4
  136. package/src/lib/meta/locktime.ts +0 -57
  137. package/src/lib/meta/ref.ts +0 -107
  138. package/src/lib/meta/scribe.ts +0 -256
  139. package/src/lib/meta/sequence.ts +0 -146
  140. package/src/lib/script/decode.ts +0 -85
  141. package/src/lib/script/encode.ts +0 -129
  142. package/src/lib/script/index.ts +0 -20
  143. package/src/lib/script/lock.ts +0 -73
  144. package/src/lib/script/util.ts +0 -78
  145. package/src/lib/script/words.ts +0 -182
  146. package/src/lib/sighash/index.ts +0 -3
  147. package/src/lib/sighash/segwit.ts +0 -152
  148. package/src/lib/sighash/taproot.ts +0 -206
  149. package/src/lib/sighash/util.ts +0 -51
  150. package/src/lib/signer/index.ts +0 -2
  151. package/src/lib/signer/sign.ts +0 -39
  152. package/src/lib/signer/verify.ts +0 -88
  153. package/src/lib/taproot/cblock.ts +0 -96
  154. package/src/lib/taproot/encode.ts +0 -49
  155. package/src/lib/taproot/index.ts +0 -4
  156. package/src/lib/taproot/parse.ts +0 -65
  157. package/src/lib/taproot/tree.ts +0 -94
  158. package/src/lib/tx/create.ts +0 -90
  159. package/src/lib/tx/decode.ts +0 -123
  160. package/src/lib/tx/encode.ts +0 -155
  161. package/src/lib/tx/index.ts +0 -7
  162. package/src/lib/tx/parse.ts +0 -69
  163. package/src/lib/tx/size.ts +0 -68
  164. package/src/lib/tx/util.ts +0 -111
  165. package/src/lib/tx/validate.ts +0 -49
  166. package/src/lib/witness/index.ts +0 -2
  167. package/src/lib/witness/parse.ts +0 -127
  168. package/src/lib/witness/util.ts +0 -18
  169. package/src/schema/base.ts +0 -57
  170. package/src/schema/index.ts +0 -2
  171. package/src/schema/taproot.ts +0 -12
  172. package/src/schema/tx.ts +0 -48
  173. package/src/types/address.ts +0 -35
  174. package/src/types/index.ts +0 -8
  175. package/src/types/meta.ts +0 -48
  176. package/src/types/psbt.ts +0 -15
  177. package/src/types/script.ts +0 -18
  178. package/src/types/sighash.ts +0 -16
  179. package/src/types/taproot.ts +0 -41
  180. package/src/types/txdata.ts +0 -85
  181. package/src/types/witness.ts +0 -42
@@ -1,5 +1,7 @@
1
- import { Buff, Stream } from '@vbyte/buff';
2
- import { get_asm_code, } from './words.js';
1
+ import { Buff, Stream } from "@vbyte/buff";
2
+ import { MAX_SCRIPT_SIZE, OP_1_OFFSET } from "../../const.js";
3
+ import { ValidationError } from "../../error.js";
4
+ import { get_asm_code } from "./words.js";
3
5
  const MAX_WORD_SIZE = 520;
4
6
  export function encode_script(words, varint = false) {
5
7
  if (words.length === 0)
@@ -9,14 +11,17 @@ export function encode_script(words, varint = false) {
9
11
  bytes.push(encode_script_word(word));
10
12
  }
11
13
  const buffer = Buff.join(bytes);
12
- return (varint)
13
- ? buffer.prepend(Buff.varint(buffer.length, 'le'))
14
+ if (buffer.length > MAX_SCRIPT_SIZE) {
15
+ throw new ValidationError(`script size ${buffer.length} exceeds consensus limit of ${MAX_SCRIPT_SIZE} bytes`);
16
+ }
17
+ return varint
18
+ ? buffer.prepend(Buff.create_varint(buffer.length, "le"))
14
19
  : buffer;
15
20
  }
16
21
  export function encode_script_word(word) {
17
22
  let buff;
18
- if (typeof (word) === 'string') {
19
- if (word.startsWith('OP_')) {
23
+ if (typeof word === "string") {
24
+ if (word.startsWith("OP_")) {
20
25
  const asm_code = get_asm_code(word);
21
26
  return Buff.num(asm_code, 1);
22
27
  }
@@ -27,23 +32,23 @@ export function encode_script_word(word) {
27
32
  buff = Buff.str(word);
28
33
  }
29
34
  }
30
- else if (typeof (word) === 'number') {
35
+ else if (typeof word === "number") {
31
36
  buff = Buff.num(word);
32
37
  }
33
38
  else if (word instanceof Uint8Array) {
34
39
  buff = new Buff(word);
35
40
  }
36
41
  else {
37
- throw new Error('invalid word type:' + typeof (word));
42
+ throw new ValidationError(`invalid script word type: ${typeof word}. Expected string, number, or Uint8Array`);
38
43
  }
39
44
  if (buff.length === 1 && buff[0] <= 16) {
40
45
  if (buff[0] !== 0)
41
- buff[0] += 0x50;
46
+ buff[0] += OP_1_OFFSET;
42
47
  }
43
48
  else if (buff.length > MAX_WORD_SIZE) {
44
49
  let words;
45
50
  words = split_script_word(buff);
46
- words = words.map(e => prefix_word_size(e));
51
+ words = words.map((e) => prefix_word_size(e));
47
52
  buff = Buff.join(words);
48
53
  }
49
54
  else {
@@ -68,13 +73,13 @@ export function get_size_varint(size) {
68
73
  const OP_PUSHDATA1 = Buff.num(0x4c, 1);
69
74
  const OP_PUSHDATA2 = Buff.num(0x4d, 1);
70
75
  switch (true) {
71
- case (size <= 0x4b):
76
+ case size <= 0x4b:
72
77
  return Buff.num(size);
73
- case (size > 0x4b && size < 0x100):
74
- return Buff.join([OP_PUSHDATA1, Buff.num(size, 1, 'le')]);
75
- case (size >= 0x100 && size <= MAX_WORD_SIZE):
76
- return Buff.join([OP_PUSHDATA2, Buff.num(size, 2, 'le')]);
78
+ case size > 0x4b && size < 0x100:
79
+ return Buff.join([OP_PUSHDATA1, Buff.num(size, 1, "le")]);
80
+ case size >= 0x100 && size <= MAX_WORD_SIZE:
81
+ return Buff.join([OP_PUSHDATA2, Buff.num(size, 2, "le")]);
77
82
  default:
78
- throw new Error('Invalid word size:' + size.toString());
83
+ throw new ValidationError(`invalid script word size: ${size}. Maximum allowed is ${MAX_WORD_SIZE} bytes`);
79
84
  }
80
85
  }
@@ -1,13 +1,5 @@
1
- import { encode_script } from './encode.js';
2
- import { decode_script, is_valid_script, parse_script } from './decode.js';
3
- export * from './decode.js';
4
- export * from './encode.js';
5
- export * from './lock.js';
6
- export * from './util.js';
7
- export * from './words.js';
8
- export declare namespace ScriptUtil {
9
- const parse: typeof parse_script;
10
- const decode: typeof decode_script;
11
- const encode: typeof encode_script;
12
- const is_valid: typeof is_valid_script;
13
- }
1
+ export * from "./decode.js";
2
+ export * from "./encode.js";
3
+ export * from "./lock.js";
4
+ export * from "./util.js";
5
+ export * from "./words.js";
@@ -1,14 +1,5 @@
1
- import { encode_script } from './encode.js';
2
- import { decode_script, is_valid_script, parse_script } from './decode.js';
3
- export * from './decode.js';
4
- export * from './encode.js';
5
- export * from './lock.js';
6
- export * from './util.js';
7
- export * from './words.js';
8
- export var ScriptUtil;
9
- (function (ScriptUtil) {
10
- ScriptUtil.parse = parse_script;
11
- ScriptUtil.decode = decode_script;
12
- ScriptUtil.encode = encode_script;
13
- ScriptUtil.is_valid = is_valid_script;
14
- })(ScriptUtil || (ScriptUtil = {}));
1
+ export * from "./decode.js";
2
+ export * from "./encode.js";
3
+ export * from "./lock.js";
4
+ export * from "./util.js";
5
+ export * from "./words.js";
@@ -1,5 +1,5 @@
1
- import { Bytes } from '@vbyte/buff';
2
- import type { LockScriptInfo, LockScriptType, WitnessVersion } from '../../types/index.js';
1
+ import { type Bytes } from "@vbyte/buff";
2
+ import type { LockScriptInfo, LockScriptType, WitnessVersion } from "../../types/index.js";
3
3
  export declare function is_return_script(script: Bytes): boolean;
4
4
  export declare function get_lock_script_info(script: Bytes): LockScriptInfo;
5
5
  export declare function get_lock_script_type(script: Bytes): LockScriptType | null;
@@ -1,5 +1,5 @@
1
- import { Buff } from '@vbyte/buff';
2
- import { LOCK_SCRIPT_REGEX } from '../../const.js';
1
+ import { Buff } from "@vbyte/buff";
2
+ import { LOCK_SCRIPT_REGEX } from "../../const.js";
3
3
  export function is_return_script(script) {
4
4
  const bytes = Buff.bytes(script);
5
5
  return bytes.at(0) === 0x6a;
@@ -7,7 +7,7 @@ export function is_return_script(script) {
7
7
  export function get_lock_script_info(script) {
8
8
  return {
9
9
  type: get_lock_script_type(script),
10
- version: get_lock_script_version(script)
10
+ version: get_lock_script_version(script),
11
11
  };
12
12
  }
13
13
  export function get_lock_script_type(script) {
@@ -21,32 +21,35 @@ export function get_lock_script_type(script) {
21
21
  export function get_lock_script_version(script) {
22
22
  const version = Buff.bytes(script);
23
23
  switch (version.at(0)) {
24
- case 0x00: return 0;
25
- case 0x51: return 1;
26
- default: return null;
24
+ case 0x00:
25
+ return 0;
26
+ case 0x51:
27
+ return 1;
28
+ default:
29
+ return null;
27
30
  }
28
31
  }
29
32
  export function is_p2pkh_script(script) {
30
33
  const hex = Buff.bytes(script).hex;
31
- return LOCK_SCRIPT_REGEX['p2pkh'].test(hex);
34
+ return LOCK_SCRIPT_REGEX.p2pkh.test(hex);
32
35
  }
33
36
  export function is_p2sh_script(script) {
34
37
  const hex = Buff.bytes(script).hex;
35
- return LOCK_SCRIPT_REGEX['p2sh'].test(hex);
38
+ return LOCK_SCRIPT_REGEX.p2sh.test(hex);
36
39
  }
37
40
  export function is_p2wpkh_script(script) {
38
41
  const hex = Buff.bytes(script).hex;
39
- return LOCK_SCRIPT_REGEX['p2wpkh'].test(hex);
42
+ return LOCK_SCRIPT_REGEX.p2wpkh.test(hex);
40
43
  }
41
44
  export function is_p2wsh_script(script) {
42
45
  const hex = Buff.bytes(script).hex;
43
- return LOCK_SCRIPT_REGEX['p2wsh'].test(hex);
46
+ return LOCK_SCRIPT_REGEX.p2wsh.test(hex);
44
47
  }
45
48
  export function is_p2tr_script(script) {
46
49
  const hex = Buff.bytes(script).hex;
47
- return LOCK_SCRIPT_REGEX['p2tr'].test(hex);
50
+ return LOCK_SCRIPT_REGEX.p2tr.test(hex);
48
51
  }
49
52
  export function is_opreturn_script(script) {
50
53
  const hex = Buff.bytes(script).hex;
51
- return LOCK_SCRIPT_REGEX['opreturn'].test(hex);
54
+ return LOCK_SCRIPT_REGEX.opreturn.test(hex);
52
55
  }
@@ -1,10 +1,10 @@
1
- import { Buff } from '@vbyte/buff';
1
+ import { Buff } from "@vbyte/buff";
2
2
  export function prefix_script_size(script) {
3
- return Buff.bytes(script).prefix_varint('le').hex;
3
+ return Buff.bytes(script).prefix_varint("le").hex;
4
4
  }
5
5
  export function parse_script_pubkeys(script) {
6
- const scriptHex = typeof script === 'string' ? script : Buff.bytes(script).hex;
6
+ const scriptHex = typeof script === "string" ? script : Buff.bytes(script).hex;
7
7
  const pubkeyPattern = /20([0-9a-f]{64})(ac|ad|ba)/gi;
8
8
  const matches = [...scriptHex.matchAll(pubkeyPattern)];
9
- return matches.map(match => match[1]);
9
+ return matches.map((match) => match[1]);
10
10
  }
@@ -1,148 +1,149 @@
1
+ import { ValidationError } from "../../error.js";
1
2
  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
3
+ OP_0: 0x00,
4
+ OP_PUSHDATA1: 0x4c,
5
+ OP_PUSHDATA2: 0x4d,
6
+ OP_PUSHDATA4: 0x4e,
7
+ OP_1NEGATE: 0x4f,
8
+ OP_SUCCESS80: 0x50,
9
+ OP_1: 0x51,
10
+ OP_2: 0x52,
11
+ OP_3: 0x53,
12
+ OP_4: 0x54,
13
+ OP_5: 0x55,
14
+ OP_6: 0x56,
15
+ OP_7: 0x57,
16
+ OP_8: 0x58,
17
+ OP_9: 0x59,
18
+ OP_10: 0x5a,
19
+ OP_11: 0x5b,
20
+ OP_12: 0x5c,
21
+ OP_13: 0x5d,
22
+ OP_14: 0x5e,
23
+ OP_15: 0x5f,
24
+ OP_16: 0x60,
25
+ OP_NOP: 0x61,
26
+ OP_SUCCESS98: 0x62,
27
+ OP_IF: 0x63,
28
+ OP_NOTIF: 0x64,
29
+ OP_ELSE: 0x67,
30
+ OP_ENDIF: 0x68,
31
+ OP_VERIFY: 0x69,
32
+ OP_RETURN: 0x6a,
33
+ OP_TOALTSTACK: 0x6b,
34
+ OP_FROMALTSTACK: 0x6c,
35
+ OP_2DROP: 0x6d,
36
+ OP_2DUP: 0x6e,
37
+ OP_3DUP: 0x6f,
38
+ OP_2OVER: 0x70,
39
+ OP_2ROT: 0x71,
40
+ OP_2SWAP: 0x72,
41
+ OP_IFDUP: 0x73,
42
+ OP_DEPTH: 0x74,
43
+ OP_DROP: 0x75,
44
+ OP_DUP: 0x76,
45
+ OP_NIP: 0x77,
46
+ OP_OVER: 0x78,
47
+ OP_PICK: 0x79,
48
+ OP_ROLL: 0x7a,
49
+ OP_ROT: 0x7b,
50
+ OP_SWAP: 0x7c,
51
+ OP_TUCK: 0x7d,
52
+ OP_SUCCESS126: 0x7e,
53
+ OP_SUCCESS127: 0x7f,
54
+ OP_SUCCESS128: 0x80,
55
+ OP_SUCCESS129: 0x81,
56
+ OP_SIZE: 0x82,
57
+ OP_SUCCESS131: 0x83,
58
+ OP_SUCCESS132: 0x84,
59
+ OP_SUCCESS133: 0x85,
60
+ OP_SUCCESS134: 0x86,
61
+ OP_EQUAL: 0x87,
62
+ OP_EQUALVERIFY: 0x88,
63
+ OP_SUCCESS137: 0x89,
64
+ OP_SUCCESS138: 0x8a,
65
+ OP_1ADD: 0x8b,
66
+ OP_1SUB: 0x8c,
67
+ OP_SUCCESS141: 0x8d,
68
+ OP_SUCCESS142: 0x8e,
69
+ OP_NEGATE: 0x8f,
70
+ OP_ABS: 0x90,
71
+ OP_NOT: 0x91,
72
+ OP_0NOTEQUAL: 0x92,
73
+ OP_ADD: 0x93,
74
+ OP_SUB: 0x94,
75
+ OP_SUCCESS149: 0x95,
76
+ OP_SUCCESS150: 0x96,
77
+ OP_SUCCESS151: 0x97,
78
+ OP_SUCCESS152: 0x98,
79
+ OP_SUCCESS153: 0x99,
80
+ OP_BOOLAND: 0x9a,
81
+ OP_BOOLOR: 0x9b,
82
+ OP_NUMEQUAL: 0x9c,
83
+ OP_NUMEQUALVERIFY: 0x9d,
84
+ OP_NUMNOTEQUAL: 0x9e,
85
+ OP_LESSTHAN: 0x9f,
86
+ OP_GREATERTHAN: 0xa0,
87
+ OP_LESSTHANOREQUAL: 0xa1,
88
+ OP_GREATERTHANOREQUAL: 0xa2,
89
+ OP_MIN: 0xa3,
90
+ OP_MAX: 0xa4,
91
+ OP_WITHIN: 0xa5,
92
+ OP_RIPEMD160: 0xa6,
93
+ OP_SHA1: 0xa7,
94
+ OP_SHA256: 0xa8,
95
+ OP_HASH160: 0xa9,
96
+ OP_HASH256: 0xaa,
97
+ OP_CODESEPARATOR: 0xab,
98
+ OP_CHECKSIG: 0xac,
99
+ OP_CHECKSIGVERIFY: 0xad,
100
+ OP_CHECKMULTISIG: 0xae,
101
+ OP_CHECKMULTISIGVERIFY: 0xaf,
102
+ OP_NOP1: 0xb0,
103
+ OP_CHECKLOCKTIMEVERIFY: 0xb1,
104
+ OP_CHECKSEQUENCEVERIFY: 0xb2,
105
+ OP_NOP4: 0xb3,
106
+ OP_NOP5: 0xb4,
107
+ OP_NOP6: 0xb5,
108
+ OP_NOP7: 0xb6,
109
+ OP_NOP8: 0xb7,
110
+ OP_NOP9: 0xb8,
111
+ OP_NOP10: 0xb9,
112
+ OP_CHECKSIGADD: 0xba,
112
113
  };
113
114
  export function get_op_code(num) {
114
115
  if (num > 186 && num < 255) {
115
- return 'OP_SUCCESS' + String(num);
116
+ return `OP_SUCCESS${String(num)}`;
116
117
  }
117
118
  for (const [k, v] of Object.entries(OPCODE_MAP)) {
118
119
  if (v === num)
119
120
  return k;
120
121
  }
121
- throw new Error('OPCODE not found:' + String(num));
122
+ throw new ValidationError(`opcode not found for value: ${num} (0x${num.toString(16)}). Valid range is 0x00-0xba`);
122
123
  }
123
124
  export function get_asm_code(string) {
124
125
  for (const [k, v] of Object.entries(OPCODE_MAP)) {
125
126
  if (k === string)
126
127
  return Number(v);
127
128
  }
128
- throw new Error('OPCODE not found:' + string);
129
+ throw new ValidationError(`opcode not found: "${string}". Valid opcodes start with "OP_" (e.g., OP_DUP, OP_CHECKSIG)`);
129
130
  }
130
131
  export function get_op_type(word) {
131
132
  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';
133
+ case word === 0:
134
+ return "opcode";
135
+ case word >= 1 && word <= 75:
136
+ return "varint";
137
+ case word === 76:
138
+ return "pushdata1";
139
+ case word === 77:
140
+ return "pushdata2";
141
+ case word === 78:
142
+ return "pushdata4";
143
+ case word <= 254:
144
+ return "opcode";
144
145
  default:
145
- throw new Error(`Invalid word range: ${word}`);
146
+ throw new ValidationError(`invalid word value: ${word}. Expected 0-254`);
146
147
  }
147
148
  }
148
149
  export function is_valid_op(word) {
@@ -150,13 +151,13 @@ export function is_valid_op(word) {
150
151
  const MAX_RANGE = 254;
151
152
  const DISABLED_OPCODES = [];
152
153
  switch (true) {
153
- case (typeof (word) !== 'number'):
154
+ case typeof word !== "number":
154
155
  return false;
155
- case (word === 0):
156
+ case word === 0:
156
157
  return true;
157
- case (DISABLED_OPCODES.includes(word)):
158
+ case DISABLED_OPCODES.includes(word):
158
159
  return false;
159
- case (MIN_RANGE < word && word < MAX_RANGE):
160
+ case MIN_RANGE < word && word < MAX_RANGE:
160
161
  return true;
161
162
  default:
162
163
  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,27 @@
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/util";
3
+ import { hash160, hash256 } from "@vbyte/crypto/hash";
4
+ import * as CONST from "../../const.js";
5
+ import { ValidationError } from "../../error.js";
6
+ import { decode_script, prefix_script_size } from "../../lib/script/index.js";
7
+ 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";
8
+ import { parse_txinput } from "./util.js";
8
9
  export function hash_segwit_tx(txdata, options = {}) {
9
10
  const { sigflag = 0x01, txindex } = options;
10
11
  const tx = parse_tx(txdata);
11
12
  const is_anypay = (sigflag & 0x80) === 0x80;
12
13
  const flag = sigflag % 0x80;
13
14
  if (!CONST.SIGHASH_SEGWIT.includes(flag)) {
14
- throw new Error('Invalid hash type: ' + String(sigflag));
15
+ throw new ValidationError(`invalid sighash type: 0x${sigflag.toString(16)}. ` +
16
+ `Valid values: SIGHASH_ALL (0x01), SIGHASH_NONE (0x02), SIGHASH_SINGLE (0x03), ` +
17
+ `or combined with ANYONECANPAY (0x81, 0x82, 0x83)`);
15
18
  }
16
19
  const { version, vin, vout, locktime } = tx;
17
20
  const txinput = parse_txinput(tx, options);
18
21
  const { txid, vout: prevIdx, prevout, sequence } = txinput;
19
22
  const { value } = prevout ?? {};
20
23
  if (value === undefined) {
21
- throw new Error('Prevout value is empty!');
24
+ throw new ValidationError("Prevout value is required for segwit sighash calculation", "prevout.value");
22
25
  }
23
26
  let { pubkey, script } = options;
24
27
  if (script === undefined && pubkey !== undefined) {
@@ -26,10 +29,10 @@ export function hash_segwit_tx(txdata, options = {}) {
26
29
  script = `76a914${String(pkhash)}88ac`;
27
30
  }
28
31
  if (script === undefined) {
29
- throw new Error('No pubkey / script has been set!');
32
+ throw new ValidationError("Either pubkey or script must be provided for segwit sighash", "pubkey/script");
30
33
  }
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.');
34
+ if (decode_script(script).includes("OP_CODESEPARATOR")) {
35
+ throw new ValidationError("OP_CODESEPARATOR is not supported in segwit scripts", "script");
33
36
  }
34
37
  const sighash = [
35
38
  encode_tx_version(version),
@@ -42,7 +45,7 @@ export function hash_segwit_tx(txdata, options = {}) {
42
45
  encode_txin_sequence(sequence),
43
46
  bip143_hash_outputs(vout, flag, txindex),
44
47
  encode_tx_locktime(locktime),
45
- Buff.num(sigflag, 4).reverse()
48
+ Buff.num(sigflag, 4).reverse(),
46
49
  ];
47
50
  return hash256(Buff.join(sighash));
48
51
  }
@@ -77,7 +80,8 @@ export function bip143_hash_outputs(vout, sigflag, idx) {
77
80
  return hash256(Buff.join(stack));
78
81
  }
79
82
  if (sigflag === 0x03) {
80
- Assert.ok(idx !== undefined);
83
+ Assert.ok(idx !== undefined, "txindex required for SIGHASH_SINGLE");
84
+ Assert.ok(idx >= 0, "txindex must be non-negative");
81
85
  if (idx < vout.length) {
82
86
  const { value, script_pk } = vout[idx];
83
87
  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;