ecash-lib 2.1.0 → 3.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 (84) hide show
  1. package/README.md +5 -3
  2. package/dist/consts.d.ts +2 -2
  3. package/dist/consts.d.ts.map +1 -1
  4. package/dist/consts.js +3 -3
  5. package/dist/consts.js.map +1 -1
  6. package/dist/ecc.d.ts +18 -1
  7. package/dist/ecc.d.ts.map +1 -1
  8. package/dist/ecc.js +29 -0
  9. package/dist/ecc.js.map +1 -1
  10. package/dist/ffi/ecash_lib_wasm_bg_browser.js +1743 -1679
  11. package/dist/ffi/ecash_lib_wasm_bg_browser.wasm +0 -0
  12. package/dist/ffi/ecash_lib_wasm_bg_browser.wasm.d.ts +13 -11
  13. package/dist/ffi/ecash_lib_wasm_bg_nodejs.wasm +0 -0
  14. package/dist/ffi/ecash_lib_wasm_bg_nodejs.wasm.d.ts +13 -11
  15. package/dist/ffi/ecash_lib_wasm_browser.d.ts +27 -11
  16. package/dist/ffi/ecash_lib_wasm_browser.js +64 -14
  17. package/dist/ffi/ecash_lib_wasm_nodejs.d.ts +14 -0
  18. package/dist/ffi/ecash_lib_wasm_nodejs.js +64 -14
  19. package/dist/hdwallet.d.ts.map +1 -1
  20. package/dist/hdwallet.js +1 -0
  21. package/dist/hdwallet.js.map +1 -1
  22. package/dist/index.d.ts +1 -0
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +1 -0
  25. package/dist/index.js.map +1 -1
  26. package/dist/messages.d.ts +32 -0
  27. package/dist/messages.d.ts.map +1 -0
  28. package/dist/messages.js +102 -0
  29. package/dist/messages.js.map +1 -0
  30. package/dist/op.d.ts.map +1 -1
  31. package/dist/op.js +4 -3
  32. package/dist/op.js.map +1 -1
  33. package/dist/sigHashType.js.map +1 -1
  34. package/dist/test/testRunner.d.ts +2 -2
  35. package/dist/test/testRunner.d.ts.map +1 -1
  36. package/dist/test/testRunner.js +13 -10
  37. package/dist/test/testRunner.js.map +1 -1
  38. package/dist/token/alp.d.ts +6 -6
  39. package/dist/token/alp.d.ts.map +1 -1
  40. package/dist/token/alp.js +13 -13
  41. package/dist/token/alp.js.map +1 -1
  42. package/dist/token/common.d.ts +0 -1
  43. package/dist/token/common.d.ts.map +1 -1
  44. package/dist/token/common.js.map +1 -1
  45. package/dist/token/slp.d.ts +7 -7
  46. package/dist/token/slp.d.ts.map +1 -1
  47. package/dist/token/slp.js +25 -25
  48. package/dist/token/slp.js.map +1 -1
  49. package/dist/tx.d.ts +2 -2
  50. package/dist/tx.d.ts.map +1 -1
  51. package/dist/tx.js +5 -5
  52. package/dist/tx.js.map +1 -1
  53. package/dist/txBuilder.d.ts +3 -3
  54. package/dist/txBuilder.d.ts.map +1 -1
  55. package/dist/txBuilder.js +13 -13
  56. package/dist/txBuilder.js.map +1 -1
  57. package/dist/unsignedTx.js +2 -2
  58. package/dist/unsignedTx.js.map +1 -1
  59. package/package.json +5 -7
  60. package/src/consts.ts +2 -2
  61. package/src/ecc.ts +54 -2
  62. package/src/ffi/ecash_lib_wasm_bg_browser.js +1743 -1679
  63. package/src/ffi/ecash_lib_wasm_bg_browser.wasm +0 -0
  64. package/src/ffi/ecash_lib_wasm_bg_browser.wasm.d.ts +13 -11
  65. package/src/ffi/ecash_lib_wasm_bg_nodejs.wasm +0 -0
  66. package/src/ffi/ecash_lib_wasm_bg_nodejs.wasm.d.ts +13 -11
  67. package/src/ffi/ecash_lib_wasm_browser.d.ts +27 -11
  68. package/src/ffi/ecash_lib_wasm_browser.js +64 -14
  69. package/src/ffi/ecash_lib_wasm_nodejs.d.ts +14 -0
  70. package/src/ffi/ecash_lib_wasm_nodejs.js +64 -14
  71. package/src/hdwallet.ts +1 -0
  72. package/src/index.ts +1 -0
  73. package/src/messages.ts +125 -0
  74. package/src/op.ts +5 -3
  75. package/src/sigHashType.ts +2 -2
  76. package/src/test/testRunner.ts +15 -13
  77. package/src/token/alp.ts +17 -17
  78. package/src/token/common.ts +0 -2
  79. package/src/token/slp.ts +27 -27
  80. package/src/tx.ts +7 -7
  81. package/src/txBuilder.ts +16 -16
  82. package/src/unsignedTx.ts +2 -2
  83. package/.eslintignore +0 -8
  84. package/eslint.config.js +0 -16
@@ -1,6 +1,18 @@
1
1
  /* tslint:disable */
2
2
  /* eslint-disable */
3
3
  export const memory: WebAssembly.Memory;
4
+ export function ecc_new(): number;
5
+ export function ecc_derivePubkey(a: number, b: number, c: number, d: number): void;
6
+ export function ecc_ecdsaSign(a: number, b: number, c: number, d: number, e: number, f: number): void;
7
+ export function ecc_ecdsaVerify(a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number): void;
8
+ export function ecc_schnorrSign(a: number, b: number, c: number, d: number, e: number, f: number): void;
9
+ export function ecc_schnorrVerify(a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number): void;
10
+ export function ecc_isValidSeckey(a: number, b: number, c: number): number;
11
+ export function ecc_seckeyAdd(a: number, b: number, c: number, d: number, e: number, f: number): void;
12
+ export function ecc_pubkeyAdd(a: number, b: number, c: number, d: number, e: number, f: number): void;
13
+ export function ecc_signRecoverable(a: number, b: number, c: number, d: number, e: number, f: number): void;
14
+ export function ecc_recoverSig(a: number, b: number, c: number, d: number, e: number, f: number): void;
15
+ export function __wbg_ecc_free(a: number): void;
4
16
  export function sha512h_new(): number;
5
17
  export function sha512h_update(a: number, b: number, c: number): void;
6
18
  export function sha512h_finalize(a: number, b: number): void;
@@ -14,21 +26,11 @@ export function sha512(a: number, b: number, c: number): void;
14
26
  export function sha256d(a: number, b: number, c: number): void;
15
27
  export function sha256(a: number, b: number, c: number): void;
16
28
  export function shaRmd160(a: number, b: number, c: number): void;
17
- export function ecc_new(): number;
18
- export function ecc_derivePubkey(a: number, b: number, c: number, d: number): void;
19
- export function ecc_ecdsaSign(a: number, b: number, c: number, d: number, e: number, f: number): void;
20
- export function ecc_schnorrSign(a: number, b: number, c: number, d: number, e: number, f: number): void;
21
- export function ecc_isValidSeckey(a: number, b: number, c: number): number;
22
- export function ecc_seckeyAdd(a: number, b: number, c: number, d: number, e: number, f: number): void;
23
- export function ecc_pubkeyAdd(a: number, b: number, c: number, d: number, e: number, f: number): void;
24
- export function ecc_signRecoverable(a: number, b: number, c: number, d: number, e: number, f: number): void;
25
- export function ecc_recoverSig(a: number, b: number, c: number, d: number, e: number, f: number): void;
26
- export function __wbg_ecc_free(a: number): void;
27
29
  export function ecash_secp256k1_context_create(a: number): number;
28
30
  export function ecash_secp256k1_context_destroy(a: number): void;
29
31
  export function secp256k1_default_illegal_callback_fn(a: number, b: number): void;
30
32
  export function secp256k1_default_error_callback_fn(a: number, b: number): void;
31
33
  export function __wbg_sha512h_free(a: number): void;
32
- export function __wbindgen_export_0(a: number, b: number): number;
33
34
  export function __wbindgen_add_to_stack_pointer(a: number): number;
35
+ export function __wbindgen_export_0(a: number, b: number): number;
34
36
  export function __wbindgen_export_1(a: number, b: number, c: number): void;
@@ -1,6 +1,18 @@
1
1
  /* tslint:disable */
2
2
  /* eslint-disable */
3
3
  export const memory: WebAssembly.Memory;
4
+ export function ecc_new(): number;
5
+ export function ecc_derivePubkey(a: number, b: number, c: number, d: number): void;
6
+ export function ecc_ecdsaSign(a: number, b: number, c: number, d: number, e: number, f: number): void;
7
+ export function ecc_ecdsaVerify(a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number): void;
8
+ export function ecc_schnorrSign(a: number, b: number, c: number, d: number, e: number, f: number): void;
9
+ export function ecc_schnorrVerify(a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number): void;
10
+ export function ecc_isValidSeckey(a: number, b: number, c: number): number;
11
+ export function ecc_seckeyAdd(a: number, b: number, c: number, d: number, e: number, f: number): void;
12
+ export function ecc_pubkeyAdd(a: number, b: number, c: number, d: number, e: number, f: number): void;
13
+ export function ecc_signRecoverable(a: number, b: number, c: number, d: number, e: number, f: number): void;
14
+ export function ecc_recoverSig(a: number, b: number, c: number, d: number, e: number, f: number): void;
15
+ export function __wbg_ecc_free(a: number): void;
4
16
  export function sha512h_new(): number;
5
17
  export function sha512h_update(a: number, b: number, c: number): void;
6
18
  export function sha512h_finalize(a: number, b: number): void;
@@ -14,21 +26,11 @@ export function sha512(a: number, b: number, c: number): void;
14
26
  export function sha256d(a: number, b: number, c: number): void;
15
27
  export function sha256(a: number, b: number, c: number): void;
16
28
  export function shaRmd160(a: number, b: number, c: number): void;
17
- export function ecc_new(): number;
18
- export function ecc_derivePubkey(a: number, b: number, c: number, d: number): void;
19
- export function ecc_ecdsaSign(a: number, b: number, c: number, d: number, e: number, f: number): void;
20
- export function ecc_schnorrSign(a: number, b: number, c: number, d: number, e: number, f: number): void;
21
- export function ecc_isValidSeckey(a: number, b: number, c: number): number;
22
- export function ecc_seckeyAdd(a: number, b: number, c: number, d: number, e: number, f: number): void;
23
- export function ecc_pubkeyAdd(a: number, b: number, c: number, d: number, e: number, f: number): void;
24
- export function ecc_signRecoverable(a: number, b: number, c: number, d: number, e: number, f: number): void;
25
- export function ecc_recoverSig(a: number, b: number, c: number, d: number, e: number, f: number): void;
26
- export function __wbg_ecc_free(a: number): void;
27
29
  export function ecash_secp256k1_context_create(a: number): number;
28
30
  export function ecash_secp256k1_context_destroy(a: number): void;
29
31
  export function secp256k1_default_illegal_callback_fn(a: number, b: number): void;
30
32
  export function secp256k1_default_error_callback_fn(a: number, b: number): void;
31
33
  export function __wbg_sha512h_free(a: number): void;
32
- export function __wbindgen_export_0(a: number, b: number): number;
33
34
  export function __wbindgen_add_to_stack_pointer(a: number): number;
35
+ export function __wbindgen_export_0(a: number, b: number): number;
34
36
  export function __wbindgen_export_1(a: number, b: number, c: number): void;
@@ -47,6 +47,13 @@ export class Ecc {
47
47
  */
48
48
  ecdsaSign(seckey: Uint8Array, msg: Uint8Array): Uint8Array;
49
49
  /**
50
+ * Verify an ECDSA signature.
51
+ * @param {Uint8Array} sig
52
+ * @param {Uint8Array} msg
53
+ * @param {Uint8Array} pk
54
+ */
55
+ ecdsaVerify(sig: Uint8Array, msg: Uint8Array, pk: Uint8Array): void;
56
+ /**
50
57
  * Sign a Schnorr signature.
51
58
  * @param {Uint8Array} seckey
52
59
  * @param {Uint8Array} msg
@@ -54,6 +61,13 @@ export class Ecc {
54
61
  */
55
62
  schnorrSign(seckey: Uint8Array, msg: Uint8Array): Uint8Array;
56
63
  /**
64
+ * Verify a Schnorr signature.
65
+ * @param {Uint8Array} sig
66
+ * @param {Uint8Array} msg
67
+ * @param {Uint8Array} pk
68
+ */
69
+ schnorrVerify(sig: Uint8Array, msg: Uint8Array, pk: Uint8Array): void;
70
+ /**
57
71
  * Return whether the given secret key is valid, i.e. whether is of correct
58
72
  * length (32 bytes) and is on the curve.
59
73
  * @param {Uint8Array} seckey
@@ -152,6 +166,18 @@ export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembl
152
166
 
153
167
  export interface InitOutput {
154
168
  readonly memory: WebAssembly.Memory;
169
+ readonly ecc_new: () => number;
170
+ readonly ecc_derivePubkey: (a: number, b: number, c: number, d: number) => void;
171
+ readonly ecc_ecdsaSign: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
172
+ readonly ecc_ecdsaVerify: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number) => void;
173
+ readonly ecc_schnorrSign: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
174
+ readonly ecc_schnorrVerify: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number) => void;
175
+ readonly ecc_isValidSeckey: (a: number, b: number, c: number) => number;
176
+ readonly ecc_seckeyAdd: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
177
+ readonly ecc_pubkeyAdd: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
178
+ readonly ecc_signRecoverable: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
179
+ readonly ecc_recoverSig: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
180
+ readonly __wbg_ecc_free: (a: number) => void;
155
181
  readonly sha512h_new: () => number;
156
182
  readonly sha512h_update: (a: number, b: number, c: number) => void;
157
183
  readonly sha512h_finalize: (a: number, b: number) => void;
@@ -165,23 +191,13 @@ export interface InitOutput {
165
191
  readonly sha256d: (a: number, b: number, c: number) => void;
166
192
  readonly sha256: (a: number, b: number, c: number) => void;
167
193
  readonly shaRmd160: (a: number, b: number, c: number) => void;
168
- readonly ecc_new: () => number;
169
- readonly ecc_derivePubkey: (a: number, b: number, c: number, d: number) => void;
170
- readonly ecc_ecdsaSign: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
171
- readonly ecc_schnorrSign: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
172
- readonly ecc_isValidSeckey: (a: number, b: number, c: number) => number;
173
- readonly ecc_seckeyAdd: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
174
- readonly ecc_pubkeyAdd: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
175
- readonly ecc_signRecoverable: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
176
- readonly ecc_recoverSig: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
177
- readonly __wbg_ecc_free: (a: number) => void;
178
194
  readonly ecash_secp256k1_context_create: (a: number) => number;
179
195
  readonly ecash_secp256k1_context_destroy: (a: number) => void;
180
196
  readonly secp256k1_default_illegal_callback_fn: (a: number, b: number) => void;
181
197
  readonly secp256k1_default_error_callback_fn: (a: number, b: number) => void;
182
198
  readonly __wbg_sha512h_free: (a: number) => void;
183
- readonly __wbindgen_export_0: (a: number, b: number) => number;
184
199
  readonly __wbindgen_add_to_stack_pointer: (a: number) => number;
200
+ readonly __wbindgen_export_0: (a: number, b: number) => number;
185
201
  readonly __wbindgen_export_1: (a: number, b: number, c: number) => void;
186
202
  }
187
203
 
@@ -51,6 +51,20 @@ function getInt32Memory0() {
51
51
  return cachedInt32Memory0;
52
52
  }
53
53
 
54
+ function getObject(idx) { return heap[idx]; }
55
+
56
+ function dropObject(idx) {
57
+ if (idx < 132) return;
58
+ heap[idx] = heap_next;
59
+ heap_next = idx;
60
+ }
61
+
62
+ function takeObject(idx) {
63
+ const ret = getObject(idx);
64
+ dropObject(idx);
65
+ return ret;
66
+ }
67
+
54
68
  function getArrayU8FromWasm0(ptr, len) {
55
69
  ptr = ptr >>> 0;
56
70
  return getUint8Memory0().subarray(ptr / 1, ptr / 1 + len);
@@ -139,20 +153,6 @@ export function shaRmd160(data) {
139
153
  }
140
154
  }
141
155
 
142
- function getObject(idx) { return heap[idx]; }
143
-
144
- function dropObject(idx) {
145
- if (idx < 132) return;
146
- heap[idx] = heap_next;
147
- heap_next = idx;
148
- }
149
-
150
- function takeObject(idx) {
151
- const ret = getObject(idx);
152
- dropObject(idx);
153
- return ret;
154
- }
155
-
156
156
  const EccFinalization = (typeof FinalizationRegistry === 'undefined')
157
157
  ? { register: () => {}, unregister: () => {} }
158
158
  : new FinalizationRegistry(ptr => wasm.__wbg_ecc_free(ptr >>> 0));
@@ -234,6 +234,31 @@ export class Ecc {
234
234
  }
235
235
  }
236
236
  /**
237
+ * Verify an ECDSA signature.
238
+ * @param {Uint8Array} sig
239
+ * @param {Uint8Array} msg
240
+ * @param {Uint8Array} pk
241
+ */
242
+ ecdsaVerify(sig, msg, pk) {
243
+ try {
244
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
245
+ const ptr0 = passArray8ToWasm0(sig, wasm.__wbindgen_export_0);
246
+ const len0 = WASM_VECTOR_LEN;
247
+ const ptr1 = passArray8ToWasm0(msg, wasm.__wbindgen_export_0);
248
+ const len1 = WASM_VECTOR_LEN;
249
+ const ptr2 = passArray8ToWasm0(pk, wasm.__wbindgen_export_0);
250
+ const len2 = WASM_VECTOR_LEN;
251
+ wasm.ecc_ecdsaVerify(retptr, this.__wbg_ptr, ptr0, len0, ptr1, len1, ptr2, len2);
252
+ var r0 = getInt32Memory0()[retptr / 4 + 0];
253
+ var r1 = getInt32Memory0()[retptr / 4 + 1];
254
+ if (r1) {
255
+ throw takeObject(r0);
256
+ }
257
+ } finally {
258
+ wasm.__wbindgen_add_to_stack_pointer(16);
259
+ }
260
+ }
261
+ /**
237
262
  * Sign a Schnorr signature.
238
263
  * @param {Uint8Array} seckey
239
264
  * @param {Uint8Array} msg
@@ -262,6 +287,31 @@ export class Ecc {
262
287
  }
263
288
  }
264
289
  /**
290
+ * Verify a Schnorr signature.
291
+ * @param {Uint8Array} sig
292
+ * @param {Uint8Array} msg
293
+ * @param {Uint8Array} pk
294
+ */
295
+ schnorrVerify(sig, msg, pk) {
296
+ try {
297
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
298
+ const ptr0 = passArray8ToWasm0(sig, wasm.__wbindgen_export_0);
299
+ const len0 = WASM_VECTOR_LEN;
300
+ const ptr1 = passArray8ToWasm0(msg, wasm.__wbindgen_export_0);
301
+ const len1 = WASM_VECTOR_LEN;
302
+ const ptr2 = passArray8ToWasm0(pk, wasm.__wbindgen_export_0);
303
+ const len2 = WASM_VECTOR_LEN;
304
+ wasm.ecc_schnorrVerify(retptr, this.__wbg_ptr, ptr0, len0, ptr1, len1, ptr2, len2);
305
+ var r0 = getInt32Memory0()[retptr / 4 + 0];
306
+ var r1 = getInt32Memory0()[retptr / 4 + 1];
307
+ if (r1) {
308
+ throw takeObject(r0);
309
+ }
310
+ } finally {
311
+ wasm.__wbindgen_add_to_stack_pointer(16);
312
+ }
313
+ }
314
+ /**
265
315
  * Return whether the given secret key is valid, i.e. whether is of correct
266
316
  * length (32 bytes) and is on the curve.
267
317
  * @param {Uint8Array} seckey
@@ -47,6 +47,13 @@ export class Ecc {
47
47
  */
48
48
  ecdsaSign(seckey: Uint8Array, msg: Uint8Array): Uint8Array;
49
49
  /**
50
+ * Verify an ECDSA signature.
51
+ * @param {Uint8Array} sig
52
+ * @param {Uint8Array} msg
53
+ * @param {Uint8Array} pk
54
+ */
55
+ ecdsaVerify(sig: Uint8Array, msg: Uint8Array, pk: Uint8Array): void;
56
+ /**
50
57
  * Sign a Schnorr signature.
51
58
  * @param {Uint8Array} seckey
52
59
  * @param {Uint8Array} msg
@@ -54,6 +61,13 @@ export class Ecc {
54
61
  */
55
62
  schnorrSign(seckey: Uint8Array, msg: Uint8Array): Uint8Array;
56
63
  /**
64
+ * Verify a Schnorr signature.
65
+ * @param {Uint8Array} sig
66
+ * @param {Uint8Array} msg
67
+ * @param {Uint8Array} pk
68
+ */
69
+ schnorrVerify(sig: Uint8Array, msg: Uint8Array, pk: Uint8Array): void;
70
+ /**
57
71
  * Return whether the given secret key is valid, i.e. whether is of correct
58
72
  * length (32 bytes) and is on the curve.
59
73
  * @param {Uint8Array} seckey
@@ -54,6 +54,20 @@ function getInt32Memory0() {
54
54
  return cachedInt32Memory0;
55
55
  }
56
56
 
57
+ function getObject(idx) { return heap[idx]; }
58
+
59
+ function dropObject(idx) {
60
+ if (idx < 132) return;
61
+ heap[idx] = heap_next;
62
+ heap_next = idx;
63
+ }
64
+
65
+ function takeObject(idx) {
66
+ const ret = getObject(idx);
67
+ dropObject(idx);
68
+ return ret;
69
+ }
70
+
57
71
  function getArrayU8FromWasm0(ptr, len) {
58
72
  ptr = ptr >>> 0;
59
73
  return getUint8Memory0().subarray(ptr / 1, ptr / 1 + len);
@@ -142,20 +156,6 @@ module.exports.shaRmd160 = function(data) {
142
156
  }
143
157
  };
144
158
 
145
- function getObject(idx) { return heap[idx]; }
146
-
147
- function dropObject(idx) {
148
- if (idx < 132) return;
149
- heap[idx] = heap_next;
150
- heap_next = idx;
151
- }
152
-
153
- function takeObject(idx) {
154
- const ret = getObject(idx);
155
- dropObject(idx);
156
- return ret;
157
- }
158
-
159
159
  const EccFinalization = (typeof FinalizationRegistry === 'undefined')
160
160
  ? { register: () => {}, unregister: () => {} }
161
161
  : new FinalizationRegistry(ptr => wasm.__wbg_ecc_free(ptr >>> 0));
@@ -237,6 +237,31 @@ class Ecc {
237
237
  }
238
238
  }
239
239
  /**
240
+ * Verify an ECDSA signature.
241
+ * @param {Uint8Array} sig
242
+ * @param {Uint8Array} msg
243
+ * @param {Uint8Array} pk
244
+ */
245
+ ecdsaVerify(sig, msg, pk) {
246
+ try {
247
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
248
+ const ptr0 = passArray8ToWasm0(sig, wasm.__wbindgen_export_0);
249
+ const len0 = WASM_VECTOR_LEN;
250
+ const ptr1 = passArray8ToWasm0(msg, wasm.__wbindgen_export_0);
251
+ const len1 = WASM_VECTOR_LEN;
252
+ const ptr2 = passArray8ToWasm0(pk, wasm.__wbindgen_export_0);
253
+ const len2 = WASM_VECTOR_LEN;
254
+ wasm.ecc_ecdsaVerify(retptr, this.__wbg_ptr, ptr0, len0, ptr1, len1, ptr2, len2);
255
+ var r0 = getInt32Memory0()[retptr / 4 + 0];
256
+ var r1 = getInt32Memory0()[retptr / 4 + 1];
257
+ if (r1) {
258
+ throw takeObject(r0);
259
+ }
260
+ } finally {
261
+ wasm.__wbindgen_add_to_stack_pointer(16);
262
+ }
263
+ }
264
+ /**
240
265
  * Sign a Schnorr signature.
241
266
  * @param {Uint8Array} seckey
242
267
  * @param {Uint8Array} msg
@@ -265,6 +290,31 @@ class Ecc {
265
290
  }
266
291
  }
267
292
  /**
293
+ * Verify a Schnorr signature.
294
+ * @param {Uint8Array} sig
295
+ * @param {Uint8Array} msg
296
+ * @param {Uint8Array} pk
297
+ */
298
+ schnorrVerify(sig, msg, pk) {
299
+ try {
300
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
301
+ const ptr0 = passArray8ToWasm0(sig, wasm.__wbindgen_export_0);
302
+ const len0 = WASM_VECTOR_LEN;
303
+ const ptr1 = passArray8ToWasm0(msg, wasm.__wbindgen_export_0);
304
+ const len1 = WASM_VECTOR_LEN;
305
+ const ptr2 = passArray8ToWasm0(pk, wasm.__wbindgen_export_0);
306
+ const len2 = WASM_VECTOR_LEN;
307
+ wasm.ecc_schnorrVerify(retptr, this.__wbg_ptr, ptr0, len0, ptr1, len1, ptr2, len2);
308
+ var r0 = getInt32Memory0()[retptr / 4 + 0];
309
+ var r1 = getInt32Memory0()[retptr / 4 + 1];
310
+ if (r1) {
311
+ throw takeObject(r0);
312
+ }
313
+ } finally {
314
+ wasm.__wbindgen_add_to_stack_pointer(16);
315
+ }
316
+ }
317
+ /**
268
318
  * Return whether the given secret key is valid, i.e. whether is of correct
269
319
  * length (32 bytes) and is on the curve.
270
320
  * @param {Uint8Array} seckey
package/src/hdwallet.ts CHANGED
@@ -139,6 +139,7 @@ export class HdNode {
139
139
  splitPath = splitPath.slice(1);
140
140
  }
141
141
 
142
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
142
143
  let hd: HdNode = this;
143
144
  for (const step of splitPath) {
144
145
  if (step.slice(-1) === `'`) {
package/src/index.ts CHANGED
@@ -8,6 +8,7 @@ export * from './hash.js';
8
8
  export * from './op.js';
9
9
  export * from './opcode.js';
10
10
  export * from './script.js';
11
+ export * from './messages.js';
11
12
  export * from './mnemonic.js';
12
13
  export * from './hdwallet.js';
13
14
  export * from './address/address.js';
@@ -0,0 +1,125 @@
1
+ // Copyright (c) 2025 The Bitcoin developers
2
+ // Distributed under the MIT software license, see the accompanying
3
+ // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
+
5
+ import { sha256d, shaRmd160 } from './hash';
6
+ import { Ecc } from './ecc';
7
+ import { WriterBytes } from './io/writerbytes';
8
+ import { writeVarSize } from './io/varsize';
9
+ import { toHex } from './io/hex';
10
+ import { Address } from './address/address';
11
+
12
+ /**
13
+ * messages.ts
14
+ *
15
+ * Sign and verify messages
16
+ */
17
+
18
+ const ECASH_MSG_SIGNING_PREFIX = '\x16eCash Signed Message:\n';
19
+
20
+ /**
21
+ * Messages are prepared in a standard way before signing and verifying
22
+ *
23
+ * - The raw message (e.g., "Hello, world!") is encoded as a UTF-8 byte array
24
+ * - The prefixed message is constructed as:
25
+ *
26
+ * [prefix][message_length][message]
27
+ *
28
+ * where message_length is a variable-length integer (varint) encoding the
29
+ * byte length of the message
30
+ *
31
+ * We keep the "magicHash" name used in bitcoinjs-message as we do the same thing here
32
+ * with eCash tools
33
+ *
34
+ * ref https://github.com/bitcoinjs/bitcoinjs-message/blob/master/index.js#L57
35
+ */
36
+ export const magicHash = (
37
+ message: string,
38
+ messagePrefix = ECASH_MSG_SIGNING_PREFIX,
39
+ ): Uint8Array => {
40
+ const encoder = new TextEncoder();
41
+
42
+ // Convert prefix to Uint8Array
43
+ const prefixBytes = encoder.encode(messagePrefix);
44
+
45
+ // Convert message to Uint8Array
46
+ const messageBytes = encoder.encode(message);
47
+
48
+ // Calculate the maximum possible size of the varint for message length
49
+ const maxVarintSize =
50
+ messageBytes.length <= 0xfc
51
+ ? 1
52
+ : messageBytes.length <= 0xffff
53
+ ? 3
54
+ : messageBytes.length <= 0xffffffff
55
+ ? 5
56
+ : 9;
57
+
58
+ // Create a WriterBytes instance with enough capacity
59
+ const writer = new WriterBytes(
60
+ prefixBytes.length + maxVarintSize + messageBytes.length,
61
+ );
62
+
63
+ // Write the prefix
64
+ writer.putBytes(prefixBytes);
65
+
66
+ // Write the message length as a varint
67
+ writeVarSize(messageBytes.length, writer);
68
+
69
+ // Write the message
70
+ writer.putBytes(messageBytes);
71
+
72
+ // Return double SHA-256 hash
73
+ return sha256d(writer.data);
74
+ };
75
+
76
+ /**
77
+ * Sign a message
78
+ *
79
+ * While there is not an official BIP or spec here, there is
80
+ * a de facto standard
81
+ *
82
+ * See implementation in bitcoinjs-lib and electrum
83
+ */
84
+ export const signMsg = (
85
+ msg: string,
86
+ sk: Uint8Array,
87
+ prefix = ECASH_MSG_SIGNING_PREFIX,
88
+ ): string => {
89
+ const preparedMsg = magicHash(msg, prefix);
90
+ const sig = new Ecc().signRecoverable(sk, preparedMsg);
91
+
92
+ // Convert Uint8Array to binary string and encode with btoa
93
+ const binaryString = String.fromCharCode(...sig);
94
+ return btoa(binaryString);
95
+ };
96
+
97
+ /**
98
+ * Verify that a given message and signature
99
+ * came from a given address
100
+ */
101
+ export const verifyMsg = (
102
+ msg: string,
103
+ signature: string,
104
+ address: string,
105
+ prefix = ECASH_MSG_SIGNING_PREFIX,
106
+ ): boolean => {
107
+ try {
108
+ const preparedMsg = magicHash(msg, prefix);
109
+
110
+ // Decode base64 signature to binary string and convert to Uint8Array
111
+ const binaryString = atob(signature);
112
+ const sig = new Uint8Array(binaryString.length);
113
+ for (let i = 0; i < binaryString.length; i++) {
114
+ sig[i] = binaryString.charCodeAt(i);
115
+ }
116
+ const recoveredPk = new Ecc().recoverSig(sig, preparedMsg);
117
+ // Get recovered hash as a hex string and compare to tested hash
118
+ const recoveredHash = toHex(shaRmd160(recoveredPk));
119
+ const testedHash = Address.fromCashAddress(address).hash;
120
+ return recoveredHash === testedHash;
121
+ } catch (err) {
122
+ console.error(`Error verifying signature`, err);
123
+ return false;
124
+ }
125
+ };
package/src/op.ts CHANGED
@@ -33,6 +33,8 @@ export function isPushOp(op: any): op is PushOp {
33
33
  if (!op || typeof op !== 'object') {
34
34
  return false;
35
35
  }
36
+
37
+ // eslint-disable-next-line no-prototype-builtins
36
38
  if (!op.hasOwnProperty('opcode') || !op.hasOwnProperty('data')) {
37
39
  return false;
38
40
  }
@@ -137,8 +139,8 @@ export function pushNumberOp(value: number | bigint): Op {
137
139
  // Prepare number for encoding. The algorithm below replicates the one used
138
140
  // in `src/script/script.h` intentionally to avoid discrepancies.
139
141
  const auxValue = BigInt(value);
140
- let bytes: number[] = [];
141
- let negative = auxValue < 0;
142
+ const bytes: number[] = [];
143
+ const negative = auxValue < 0;
142
144
  let absvalue = negative ? ~auxValue + 1n : auxValue;
143
145
 
144
146
  // Encode value in little endian byte order by iteratively pushing the
@@ -151,7 +153,7 @@ export function pushNumberOp(value: number | bigint): Op {
151
153
  // The MSB will encode the sign which means that, if the previous encoding
152
154
  // of the absolute value uses that bit, a new byte must be added to encode
153
155
  // the sign. If bit is not set, then it must be set for negative numbers.
154
- let last = bytes[bytes.length - 1];
156
+ const last = bytes[bytes.length - 1];
155
157
  if (last & 0x80) {
156
158
  bytes.push(negative ? 0x80 : 0x00);
157
159
  } else if (negative) {
@@ -48,8 +48,8 @@ export class SigHashType {
48
48
  outputFlags == 1
49
49
  ? SigHashTypeOutputs.ALL
50
50
  : outputFlags == 2
51
- ? SigHashTypeOutputs.NONE
52
- : SigHashTypeOutputs.SINGLE,
51
+ ? SigHashTypeOutputs.NONE
52
+ : SigHashTypeOutputs.SINGLE,
53
53
  });
54
54
  }
55
55
 
@@ -5,7 +5,6 @@
5
5
  import type { ChronikClient } from 'chronik-client';
6
6
  import type { ChildProcess } from 'node:child_process';
7
7
 
8
- import { Ecc } from '../ecc.js';
9
8
  import { shaRmd160 } from '../hash.js';
10
9
  import { fromHex, toHex } from '../io/hex.js';
11
10
  import { pushBytesOp } from '../op.js';
@@ -26,7 +25,7 @@ export class TestRunner {
26
25
  public runner: ChildProcess;
27
26
  public chronik: ChronikClient;
28
27
  private coinsTxid: string | undefined;
29
- private coinValue: number | undefined;
28
+ private coinValue: bigint | undefined;
30
29
  private lastUsedOutIdx: number;
31
30
 
32
31
  private constructor(runner: ChildProcess, chronik: ChronikClient) {
@@ -120,7 +119,7 @@ export class TestRunner {
120
119
 
121
120
  public async setupCoins(
122
121
  numCoins: number,
123
- coinValue: number,
122
+ coinValue: bigint,
124
123
  ): Promise<void> {
125
124
  const opTrueScriptHash = shaRmd160(OP_TRUE_SCRIPT.bytecode);
126
125
  const utxos = (
@@ -135,19 +134,19 @@ export class TestRunner {
135
134
  sequence: 0xffffffff,
136
135
  })),
137
136
  });
138
- const utxosValue = utxos.reduce((a, b) => a + b.value, 0);
137
+ const utxosValue = utxos.reduce((a, b) => a + b.sats, 0n);
139
138
  for (let i = 0; i < numCoins; ++i) {
140
139
  tx.outputs.push({
141
- value: coinValue,
140
+ sats: coinValue,
142
141
  script: anyoneP2sh,
143
142
  });
144
143
  }
145
144
  tx.outputs.push({
146
- value: 0,
145
+ sats: 0n,
147
146
  script: Script.fromOps([OP_RETURN]),
148
147
  });
149
- tx.outputs[tx.outputs.length - 1].value =
150
- utxosValue - numCoins * coinValue - tx.serSize();
148
+ tx.outputs[tx.outputs.length - 1].sats =
149
+ utxosValue - BigInt(numCoins) * coinValue - BigInt(tx.serSize());
151
150
 
152
151
  this.coinsTxid = (await this.chronik.broadcastTx(tx.ser())).txid;
153
152
  this.coinValue = coinValue;
@@ -164,11 +163,11 @@ export class TestRunner {
164
163
  }
165
164
 
166
165
  public async sendToScript(
167
- value: number | number[],
166
+ sats: bigint | bigint[],
168
167
  script: Script,
169
168
  ): Promise<string> {
170
169
  const coinValue = this.coinValue!;
171
- const values = Array.isArray(value) ? value : [value];
170
+ const satsArr = Array.isArray(sats) ? sats : [sats];
172
171
  const setupTxBuilder = new TxBuilder({
173
172
  inputs: [
174
173
  {
@@ -177,17 +176,20 @@ export class TestRunner {
177
176
  script: ANYONE_SCRIPT_SIG,
178
177
  sequence: 0xffffffff,
179
178
  signData: {
180
- value: coinValue,
179
+ sats: coinValue,
181
180
  },
182
181
  },
183
182
  },
184
183
  ],
185
184
  outputs: [
186
- ...values.map(value => ({ value, script })),
185
+ ...satsArr.map(sats => ({ sats, script })),
187
186
  Script.fromOps([OP_RETURN]), // burn leftover
188
187
  ],
189
188
  });
190
- const setupTx = setupTxBuilder.sign({ feePerKb: 1000, dustLimit: 546 });
189
+ const setupTx = setupTxBuilder.sign({
190
+ feePerKb: 1000n,
191
+ dustSats: 546n,
192
+ });
191
193
  return (await this.chronik.broadcastTx(setupTx.ser())).txid;
192
194
  }
193
195