ecash-lib 0.2.0-rc → 0.2.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 (187) hide show
  1. package/README.md +80 -15
  2. package/dist/{src/ecc.d.ts → ecc.d.ts} +6 -2
  3. package/dist/ecc.d.ts.map +1 -0
  4. package/dist/{src/ecc.js → ecc.js} +9 -6
  5. package/dist/ecc.js.map +1 -0
  6. package/dist/ffi/ecash_lib_wasm_bg_browser.wasm +0 -0
  7. package/dist/ffi/ecash_lib_wasm_bg_nodejs.wasm +0 -0
  8. package/dist/ffi/ecash_lib_wasm_bg_nodejs.wasm.d.ts +16 -0
  9. package/dist/ffi/{ecash_lib_wasm.js → ecash_lib_wasm_browser.js} +1 -1
  10. package/dist/ffi/ecash_lib_wasm_nodejs.d.ts +50 -0
  11. package/dist/ffi/ecash_lib_wasm_nodejs.js +265 -0
  12. package/dist/hash.d.ts +11 -0
  13. package/dist/hash.d.ts.map +1 -0
  14. package/dist/hash.js +24 -0
  15. package/dist/hash.js.map +1 -0
  16. package/dist/{src/index.d.ts → index.d.ts} +5 -1
  17. package/dist/index.d.ts.map +1 -0
  18. package/dist/index.js +41 -0
  19. package/dist/index.js.map +1 -0
  20. package/dist/indexBrowser.d.ts +3 -0
  21. package/dist/indexBrowser.d.ts.map +1 -0
  22. package/dist/indexBrowser.js +22 -0
  23. package/dist/indexBrowser.js.map +1 -0
  24. package/dist/indexNodeJs.d.ts +3 -0
  25. package/dist/indexNodeJs.d.ts.map +1 -0
  26. package/dist/indexNodeJs.js +22 -0
  27. package/dist/indexNodeJs.js.map +1 -0
  28. package/dist/initBrowser.d.ts +3 -0
  29. package/dist/initBrowser.d.ts.map +1 -0
  30. package/dist/initBrowser.js +44 -0
  31. package/dist/initBrowser.js.map +1 -0
  32. package/dist/initNodeJs.d.ts +3 -0
  33. package/dist/initNodeJs.d.ts.map +1 -0
  34. package/dist/initNodeJs.js +43 -0
  35. package/dist/initNodeJs.js.map +1 -0
  36. package/dist/io/bytes.d.ts.map +1 -0
  37. package/dist/{src/io → io}/bytes.js +5 -1
  38. package/dist/io/bytes.js.map +1 -0
  39. package/dist/io/hex.d.ts.map +1 -0
  40. package/dist/{src/io → io}/hex.js +11 -4
  41. package/dist/io/hex.js.map +1 -0
  42. package/dist/io/int.d.ts.map +1 -0
  43. package/dist/{src/io → io}/int.js +2 -1
  44. package/dist/io/int.js.map +1 -0
  45. package/dist/io/str.d.ts +5 -0
  46. package/dist/io/str.d.ts.map +1 -0
  47. package/dist/io/str.js +19 -0
  48. package/dist/io/str.js.map +1 -0
  49. package/dist/io/varsize.d.ts.map +1 -0
  50. package/dist/{src/io → io}/varsize.js +7 -2
  51. package/dist/io/varsize.js.map +1 -0
  52. package/dist/io/writer.d.ts.map +1 -0
  53. package/dist/{src/io → io}/writer.js +2 -1
  54. package/dist/io/writer.js.map +1 -0
  55. package/dist/io/writerbytes.d.ts.map +1 -0
  56. package/dist/{src/io → io}/writerbytes.js +5 -1
  57. package/dist/io/writerbytes.js.map +1 -0
  58. package/dist/io/writerlength.d.ts.map +1 -0
  59. package/dist/{src/io → io}/writerlength.js +5 -1
  60. package/dist/io/writerlength.js.map +1 -0
  61. package/dist/op.d.ts.map +1 -0
  62. package/dist/{src/op.js → op.js} +23 -16
  63. package/dist/op.js.map +1 -0
  64. package/dist/opcode.d.ts.map +1 -0
  65. package/dist/opcode.js +141 -0
  66. package/dist/opcode.js.map +1 -0
  67. package/dist/{src/script.d.ts → script.d.ts} +2 -0
  68. package/dist/script.d.ts.map +1 -0
  69. package/dist/script.js +196 -0
  70. package/dist/script.js.map +1 -0
  71. package/dist/sigHashType.d.ts.map +1 -0
  72. package/dist/{src/sigHashType.js → sigHashType.js} +23 -19
  73. package/dist/sigHashType.js.map +1 -0
  74. package/dist/test/testRunner.d.ts +21 -0
  75. package/dist/test/testRunner.d.ts.map +1 -0
  76. package/dist/test/testRunner.js +171 -0
  77. package/dist/test/testRunner.js.map +1 -0
  78. package/dist/token/alp.d.ts.map +1 -0
  79. package/dist/token/alp.js +117 -0
  80. package/dist/token/alp.js.map +1 -0
  81. package/dist/{src/token → token}/common.d.ts +4 -0
  82. package/dist/token/common.d.ts.map +1 -0
  83. package/dist/token/common.js +12 -0
  84. package/dist/token/common.js.map +1 -0
  85. package/dist/token/empp.d.ts.map +1 -0
  86. package/dist/{src/token → token}/empp.js +13 -9
  87. package/dist/token/empp.js.map +1 -0
  88. package/dist/token/slp.d.ts +35 -0
  89. package/dist/token/slp.d.ts.map +1 -0
  90. package/dist/token/slp.js +172 -0
  91. package/dist/token/slp.js.map +1 -0
  92. package/dist/{src/tx.d.ts → tx.d.ts} +4 -0
  93. package/dist/tx.d.ts.map +1 -0
  94. package/dist/{src/tx.js → tx.js} +40 -20
  95. package/dist/tx.js.map +1 -0
  96. package/dist/txBuilder.d.ts.map +1 -0
  97. package/dist/{src/txBuilder.js → txBuilder.js} +36 -25
  98. package/dist/txBuilder.js.map +1 -0
  99. package/dist/unsignedTx.d.ts.map +1 -0
  100. package/dist/{src/unsignedTx.js → unsignedTx.js} +34 -29
  101. package/dist/unsignedTx.js.map +1 -0
  102. package/package.json +7 -4
  103. package/tsconfig.build.json +13 -0
  104. package/tsconfig.json +4 -7
  105. package/.nyc_output/0fc40ca6-d52c-45eb-b31b-2601ce70b887.json +0 -1
  106. package/.nyc_output/ac5be6db-4e40-41f8-8b84-7598d4747e57.json +0 -1
  107. package/.nyc_output/b316d46f-5ea0-4e98-884a-bfbf9cc1d0f8.json +0 -1
  108. package/.nyc_output/f965566b-9422-4874-b45e-9eefda9c769c.json +0 -1
  109. package/.nyc_output/processinfo/0fc40ca6-d52c-45eb-b31b-2601ce70b887.json +0 -1
  110. package/.nyc_output/processinfo/ac5be6db-4e40-41f8-8b84-7598d4747e57.json +0 -1
  111. package/.nyc_output/processinfo/b316d46f-5ea0-4e98-884a-bfbf9cc1d0f8.json +0 -1
  112. package/.nyc_output/processinfo/f965566b-9422-4874-b45e-9eefda9c769c.json +0 -1
  113. package/.nyc_output/processinfo/index.json +0 -1
  114. package/dist/ffi/ecash_lib_wasm_bg.wasm +0 -0
  115. package/dist/src/ecc.d.ts.map +0 -1
  116. package/dist/src/ecc.js.map +0 -1
  117. package/dist/src/hash.d.ts +0 -5
  118. package/dist/src/hash.d.ts.map +0 -1
  119. package/dist/src/hash.js +0 -8
  120. package/dist/src/hash.js.map +0 -1
  121. package/dist/src/index.d.ts.map +0 -1
  122. package/dist/src/index.js +0 -21
  123. package/dist/src/index.js.map +0 -1
  124. package/dist/src/init.d.ts +0 -3
  125. package/dist/src/init.d.ts.map +0 -1
  126. package/dist/src/init.js +0 -18
  127. package/dist/src/init.js.map +0 -1
  128. package/dist/src/io/bytes.d.ts.map +0 -1
  129. package/dist/src/io/bytes.js.map +0 -1
  130. package/dist/src/io/hex.d.ts.map +0 -1
  131. package/dist/src/io/hex.js.map +0 -1
  132. package/dist/src/io/int.d.ts.map +0 -1
  133. package/dist/src/io/int.js.map +0 -1
  134. package/dist/src/io/str.d.ts +0 -3
  135. package/dist/src/io/str.d.ts.map +0 -1
  136. package/dist/src/io/str.js +0 -9
  137. package/dist/src/io/str.js.map +0 -1
  138. package/dist/src/io/varsize.d.ts.map +0 -1
  139. package/dist/src/io/varsize.js.map +0 -1
  140. package/dist/src/io/writer.d.ts.map +0 -1
  141. package/dist/src/io/writer.js.map +0 -1
  142. package/dist/src/io/writerbytes.d.ts.map +0 -1
  143. package/dist/src/io/writerbytes.js.map +0 -1
  144. package/dist/src/io/writerlength.d.ts.map +0 -1
  145. package/dist/src/io/writerlength.js.map +0 -1
  146. package/dist/src/op.d.ts.map +0 -1
  147. package/dist/src/op.js.map +0 -1
  148. package/dist/src/opcode.d.ts.map +0 -1
  149. package/dist/src/opcode.js +0 -136
  150. package/dist/src/opcode.js.map +0 -1
  151. package/dist/src/script.d.ts.map +0 -1
  152. package/dist/src/script.js +0 -132
  153. package/dist/src/script.js.map +0 -1
  154. package/dist/src/sigHashType.d.ts.map +0 -1
  155. package/dist/src/sigHashType.js.map +0 -1
  156. package/dist/src/token/alp.d.ts.map +0 -1
  157. package/dist/src/token/alp.js +0 -110
  158. package/dist/src/token/alp.js.map +0 -1
  159. package/dist/src/token/common.d.ts.map +0 -1
  160. package/dist/src/token/common.js +0 -9
  161. package/dist/src/token/common.js.map +0 -1
  162. package/dist/src/token/empp.d.ts.map +0 -1
  163. package/dist/src/token/empp.js.map +0 -1
  164. package/dist/src/tx.d.ts.map +0 -1
  165. package/dist/src/tx.js.map +0 -1
  166. package/dist/src/txBuilder.d.ts.map +0 -1
  167. package/dist/src/txBuilder.js.map +0 -1
  168. package/dist/src/unsignedTx.d.ts.map +0 -1
  169. package/dist/src/unsignedTx.js.map +0 -1
  170. package/tests/alp.test.ts +0 -515
  171. package/tests/txBuilder.test.ts +0 -680
  172. /package/dist/ffi/{ecash_lib_wasm_bg.wasm.d.ts → ecash_lib_wasm_bg_browser.wasm.d.ts} +0 -0
  173. /package/dist/ffi/{ecash_lib_wasm.d.ts → ecash_lib_wasm_browser.d.ts} +0 -0
  174. /package/dist/{src/io → io}/bytes.d.ts +0 -0
  175. /package/dist/{src/io → io}/hex.d.ts +0 -0
  176. /package/dist/{src/io → io}/int.d.ts +0 -0
  177. /package/dist/{src/io → io}/varsize.d.ts +0 -0
  178. /package/dist/{src/io → io}/writer.d.ts +0 -0
  179. /package/dist/{src/io → io}/writerbytes.d.ts +0 -0
  180. /package/dist/{src/io → io}/writerlength.d.ts +0 -0
  181. /package/dist/{src/op.d.ts → op.d.ts} +0 -0
  182. /package/dist/{src/opcode.d.ts → opcode.d.ts} +0 -0
  183. /package/dist/{src/sigHashType.d.ts → sigHashType.d.ts} +0 -0
  184. /package/dist/{src/token → token}/alp.d.ts +0 -0
  185. /package/dist/{src/token → token}/empp.d.ts +0 -0
  186. /package/dist/{src/txBuilder.d.ts → txBuilder.d.ts} +0 -0
  187. /package/dist/{src/unsignedTx.d.ts → unsignedTx.d.ts} +0 -0
package/README.md CHANGED
@@ -1,21 +1,84 @@
1
1
  # ecash-lib
2
2
 
3
- Library for eCash transaction building.
3
+ Library for [eCash](https://e.cash) transaction building.
4
+
5
+ - Compatible: Works on the browser using webpack, on NodeJS, jest etc.
6
+ - Fast: Accelerated using the highly optimized secp256k1 library compiled to WebAssembly
7
+ - Simple to use: Describe the tx to build in one TxBuilder object, and build the tx with just one `sign` call
8
+ - SLP/ALP enabled: Functions to build the SLP/ALP eMPP scripts
9
+ - Flexible: The "Signatory" mechanism can accommodate anything from simple wallet transfers to complex Script covenants, e.g. eCash Agora
10
+ - Schnorr: eCash lib supports Schnorr and ECDSA signatures
11
+ - Precise leftover ("change") computation: The tx size estimator will be exact for Schnorr signatures and very close for ECDSA signatures, even for complex scripts
4
12
 
5
13
  ## Usage
6
14
 
15
+ This library works for both browser and NodeJS.
16
+
17
+ ### Installation
18
+
19
+ `npm install --save ecash-lib`
20
+
21
+ ### Setup
22
+
23
+ To use this library, you first have to initialize the WebAssembly module:
24
+
7
25
  ```ts
8
- import { Tx, Script, fromHex, toHex } from 'ecash-lib';
26
+ import { initWasm } from 'ecash-lib';
27
+ await initWasm();
28
+ ```
29
+
30
+ After that, to sign signatures, you need an "Ecc" instance:
31
+
32
+ ```ts
33
+ import { Ecc } from 'ecash-lib';
34
+ const ecc = new Ecc();
35
+ ```
9
36
 
10
- const tx = new Tx({
37
+ **Note: You should only call this function once, as it's fairly expensive to setup, it internally precomputes some elliptic curve field elements, which takes some time**
38
+
39
+ ### Usage
40
+
41
+ Now you're ready to sign your first transactions:
42
+
43
+ ```ts
44
+ import {
45
+ Ecc,
46
+ P2PKHSignatory,
47
+ Script,
48
+ TxBuilder,
49
+ fromHex,
50
+ initWasm,
51
+ shaRmd160,
52
+ toHex,
53
+ } from 'ecash-lib';
54
+
55
+ // Download and compile WebAssembly
56
+ await initWasm();
57
+ // Build a signature context for elliptic curve cryptography (ECC)
58
+ const ecc = new Ecc();
59
+ const walletSk = fromHex(
60
+ 'e6ae1669c47d092eff3eb652bea535331c338e29f34be709bc4055655cd0e950',
61
+ );
62
+ const walletPk = ecc.derivePubkey(walletSk);
63
+ const walletPkh = shaRmd160(walletPk);
64
+ const walletP2pkh = Script.p2pkh(walletPkh);
65
+ // TxId with unspent funds for the above wallet
66
+ const walletUtxo = {
67
+ txid: '0000000000000000000000000000000000000000000000000000000000000000',
68
+ outIdx: 0,
69
+ };
70
+ // Tx builder
71
+ const txBuild = new TxBuilder({
11
72
  inputs: [
12
73
  {
13
- prevOut: {
14
- txid: new Uint8Array(32),
15
- outIdx: 0,
74
+ inputs: {
75
+ prevOut: walletUtxo,
76
+ signData: {
77
+ value: 1000,
78
+ outputScript: walletP2pkh,
79
+ },
16
80
  },
17
- script: new Script(),
18
- sequence: 0xffffffff,
81
+ signatory: P2PKHSignatory(walletSk, walletPk, ALL_BIP143),
19
82
  },
20
83
  ],
21
84
  outputs: [
@@ -23,15 +86,17 @@ const tx = new Tx({
23
86
  value: 0,
24
87
  script: new Script(fromHex('6a68656c6c6f')),
25
88
  },
26
- {
27
- value: 546,
28
- script: new Script(
29
- fromHex('a914d37c4c809fe9840e7bfa77b86bd47163f6fb6c6087'),
30
- ),
31
- },
89
+ walletP2pkh,
32
90
  ],
33
91
  });
34
-
92
+ const tx = txBuild.sign(ecc, 1000, 546);
35
93
  const rawTx = tx.ser();
36
94
  console.log(toHex(rawTx));
37
95
  ```
96
+
97
+ ## Changelog
98
+
99
+ - 0.1.1 - Validation that feePerKb is an integer
100
+ - 0.1.2 - Upgrade dependencies [D16373](https://reviews.bitcoinabc.org/D16373)
101
+ - 0.1.3 - Export `slpAmount` function [D16379](https://reviews.bitcoinabc.org/D16379)
102
+ - 0.2.0 - Add `Script.fromAddress` method to convert cashaddr addresses to `Script`
@@ -1,4 +1,3 @@
1
- import * as ffi from './ffi/ecash_lib_wasm.js';
2
1
  /** Interface to abstract over Elliptic Curve Cryptography */
3
2
  export interface Ecc {
4
3
  /** Derive a public key from secret key. */
@@ -9,11 +8,16 @@ export interface Ecc {
9
8
  schnorrSign(seckey: Uint8Array, msg: Uint8Array): Uint8Array;
10
9
  }
11
10
  /** Ecc implementation using WebAssembly */
12
- export declare const EccWasm: typeof ffi.Ecc;
11
+ export declare let Ecc: {
12
+ new (): Ecc;
13
+ };
13
14
  /** Dummy Ecc impl that always returns 0, useful for measuring tx size */
14
15
  export declare class EccDummy implements Ecc {
15
16
  derivePubkey(_seckey: Uint8Array): Uint8Array;
16
17
  ecdsaSign(_seckey: Uint8Array, _msg: Uint8Array): Uint8Array;
17
18
  schnorrSign(_seckey: Uint8Array, _msg: Uint8Array): Uint8Array;
18
19
  }
20
+ export declare function __setEcc(ecc: {
21
+ new (): Ecc;
22
+ }): void;
19
23
  //# sourceMappingURL=ecc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ecc.d.ts","sourceRoot":"","sources":["../src/ecc.ts"],"names":[],"mappings":"AAIA,6DAA6D;AAC7D,MAAM,WAAW,GAAG;IAChB,2CAA2C;IAC3C,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,UAAU,CAAC;IAE7C,8DAA8D;IAC9D,SAAS,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,UAAU,GAAG,UAAU,CAAC;IAE3D,+DAA+D;IAC/D,WAAW,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,UAAU,GAAG,UAAU,CAAC;CAChE;AAED,2CAA2C;AAC3C,eAAO,IAAI,GAAG,EAAE;IAAE,QAAQ,GAAG,CAAA;CAAE,CAAC;AAEhC,yEAAyE;AACzE,qBAAa,QAAS,YAAW,GAAG;IAChC,YAAY,CAAC,OAAO,EAAE,UAAU,GAAG,UAAU;IAI7C,SAAS,CAAC,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,GAAG,UAAU;IAI5D,WAAW,CAAC,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,GAAG,UAAU;CAGjE;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE;IAAE,QAAQ,GAAG,CAAA;CAAE,QAE5C"}
@@ -1,13 +1,11 @@
1
+ "use strict";
1
2
  // Copyright (c) 2024 The Bitcoin developers
2
3
  // Distributed under the MIT software license, see the accompanying
3
4
  // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
- // These files are generated in "ecash-lib-wasm" via build-wasm.sh or
5
- // dockerbuild.sh.
6
- import * as ffi from './ffi/ecash_lib_wasm.js';
7
- /** Ecc implementation using WebAssembly */
8
- export const EccWasm = ffi.Ecc;
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.__setEcc = exports.EccDummy = exports.Ecc = void 0;
9
7
  /** Dummy Ecc impl that always returns 0, useful for measuring tx size */
10
- export class EccDummy {
8
+ class EccDummy {
11
9
  derivePubkey(_seckey) {
12
10
  return new Uint8Array(33);
13
11
  }
@@ -18,4 +16,9 @@ export class EccDummy {
18
16
  return new Uint8Array(64);
19
17
  }
20
18
  }
19
+ exports.EccDummy = EccDummy;
20
+ function __setEcc(ecc) {
21
+ exports.Ecc = ecc;
22
+ }
23
+ exports.__setEcc = __setEcc;
21
24
  //# sourceMappingURL=ecc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ecc.js","sourceRoot":"","sources":["../src/ecc.ts"],"names":[],"mappings":";AAAA,4CAA4C;AAC5C,mEAAmE;AACnE,sEAAsE;;;AAiBtE,yEAAyE;AACzE,MAAa,QAAQ;IACjB,YAAY,CAAC,OAAmB;QAC5B,OAAO,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC;IAC9B,CAAC;IAED,SAAS,CAAC,OAAmB,EAAE,IAAgB;QAC3C,OAAO,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC;IAC9B,CAAC;IAED,WAAW,CAAC,OAAmB,EAAE,IAAgB;QAC7C,OAAO,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC;IAC9B,CAAC;CACJ;AAZD,4BAYC;AAED,SAAgB,QAAQ,CAAC,GAAoB;IACzC,WAAG,GAAG,GAAG,CAAC;AACd,CAAC;AAFD,4BAEC"}
@@ -0,0 +1,16 @@
1
+ /* tslint:disable */
2
+ /* eslint-disable */
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_schnorrSign(a: number, b: number, c: number, d: number, e: number, f: number): void;
8
+ export function __wbg_ecc_free(a: number): void;
9
+ export function sha256d(a: number, b: number, c: number): void;
10
+ export function sha256(a: number, b: number, c: number): void;
11
+ export function shaRmd160(a: number, b: number, c: number): void;
12
+ export function secp256k1_default_illegal_callback_fn(a: number, b: number): void;
13
+ export function secp256k1_default_error_callback_fn(a: number, b: number): void;
14
+ export function __wbindgen_add_to_stack_pointer(a: number): number;
15
+ export function __wbindgen_export_0(a: number, b: number): number;
16
+ export function __wbindgen_export_1(a: number, b: number, c: number): void;
@@ -321,7 +321,7 @@ async function __wbg_init(input) {
321
321
  if (wasm !== undefined) return wasm;
322
322
 
323
323
  if (typeof input === 'undefined') {
324
- input = new URL('ecash_lib_wasm_bg.wasm', import.meta.url);
324
+ input = new URL('ecash_lib_wasm_bg_browser.wasm', import.meta.url);
325
325
  }
326
326
  const imports = __wbg_get_imports();
327
327
 
@@ -0,0 +1,50 @@
1
+ /* tslint:disable */
2
+ /* eslint-disable */
3
+ /**
4
+ * Calculate SHA256(SHA256(data)).
5
+ * @param {Uint8Array} data
6
+ * @returns {Uint8Array}
7
+ */
8
+ export function sha256d(data: Uint8Array): Uint8Array;
9
+ /**
10
+ * Calculate SHA256(data).
11
+ * @param {Uint8Array} data
12
+ * @returns {Uint8Array}
13
+ */
14
+ export function sha256(data: Uint8Array): Uint8Array;
15
+ /**
16
+ * Calculate RIPEMD160(SHA256(data)), commonly used as address hash.
17
+ * @param {Uint8Array} data
18
+ * @returns {Uint8Array}
19
+ */
20
+ export function shaRmd160(data: Uint8Array): Uint8Array;
21
+ /**
22
+ * ECC signatures with libsecp256k1.
23
+ */
24
+ export class Ecc {
25
+ free(): void;
26
+ /**
27
+ * Create a new Ecc instance.
28
+ */
29
+ constructor();
30
+ /**
31
+ * Derive a public key from secret key.
32
+ * @param {Uint8Array} seckey
33
+ * @returns {Uint8Array}
34
+ */
35
+ derivePubkey(seckey: Uint8Array): Uint8Array;
36
+ /**
37
+ * Sign an ECDSA signature.
38
+ * @param {Uint8Array} seckey
39
+ * @param {Uint8Array} msg
40
+ * @returns {Uint8Array}
41
+ */
42
+ ecdsaSign(seckey: Uint8Array, msg: Uint8Array): Uint8Array;
43
+ /**
44
+ * Sign a Schnorr signature.
45
+ * @param {Uint8Array} seckey
46
+ * @param {Uint8Array} msg
47
+ * @returns {Uint8Array}
48
+ */
49
+ schnorrSign(seckey: Uint8Array, msg: Uint8Array): Uint8Array;
50
+ }
@@ -0,0 +1,265 @@
1
+ let imports = {};
2
+ imports['__wbindgen_placeholder__'] = module.exports;
3
+ let wasm;
4
+ const { TextDecoder } = require(`util`);
5
+
6
+ let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
7
+
8
+ cachedTextDecoder.decode();
9
+
10
+ let cachedUint8Memory0 = null;
11
+
12
+ function getUint8Memory0() {
13
+ if (cachedUint8Memory0 === null || cachedUint8Memory0.byteLength === 0) {
14
+ cachedUint8Memory0 = new Uint8Array(wasm.memory.buffer);
15
+ }
16
+ return cachedUint8Memory0;
17
+ }
18
+
19
+ function getStringFromWasm0(ptr, len) {
20
+ ptr = ptr >>> 0;
21
+ return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len));
22
+ }
23
+
24
+ const heap = new Array(128).fill(undefined);
25
+
26
+ heap.push(undefined, null, true, false);
27
+
28
+ let heap_next = heap.length;
29
+
30
+ function addHeapObject(obj) {
31
+ if (heap_next === heap.length) heap.push(heap.length + 1);
32
+ const idx = heap_next;
33
+ heap_next = heap[idx];
34
+
35
+ heap[idx] = obj;
36
+ return idx;
37
+ }
38
+
39
+ let WASM_VECTOR_LEN = 0;
40
+
41
+ function passArray8ToWasm0(arg, malloc) {
42
+ const ptr = malloc(arg.length * 1, 1) >>> 0;
43
+ getUint8Memory0().set(arg, ptr / 1);
44
+ WASM_VECTOR_LEN = arg.length;
45
+ return ptr;
46
+ }
47
+
48
+ let cachedInt32Memory0 = null;
49
+
50
+ function getInt32Memory0() {
51
+ if (cachedInt32Memory0 === null || cachedInt32Memory0.byteLength === 0) {
52
+ cachedInt32Memory0 = new Int32Array(wasm.memory.buffer);
53
+ }
54
+ return cachedInt32Memory0;
55
+ }
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
+
71
+ function getArrayU8FromWasm0(ptr, len) {
72
+ ptr = ptr >>> 0;
73
+ return getUint8Memory0().subarray(ptr / 1, ptr / 1 + len);
74
+ }
75
+ /**
76
+ * Calculate SHA256(SHA256(data)).
77
+ * @param {Uint8Array} data
78
+ * @returns {Uint8Array}
79
+ */
80
+ module.exports.sha256d = function(data) {
81
+ try {
82
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
83
+ const ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_export_0);
84
+ const len0 = WASM_VECTOR_LEN;
85
+ wasm.sha256d(retptr, ptr0, len0);
86
+ var r0 = getInt32Memory0()[retptr / 4 + 0];
87
+ var r1 = getInt32Memory0()[retptr / 4 + 1];
88
+ var v2 = getArrayU8FromWasm0(r0, r1).slice();
89
+ wasm.__wbindgen_export_1(r0, r1 * 1, 1);
90
+ return v2;
91
+ } finally {
92
+ wasm.__wbindgen_add_to_stack_pointer(16);
93
+ }
94
+ };
95
+
96
+ /**
97
+ * Calculate SHA256(data).
98
+ * @param {Uint8Array} data
99
+ * @returns {Uint8Array}
100
+ */
101
+ module.exports.sha256 = function(data) {
102
+ try {
103
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
104
+ const ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_export_0);
105
+ const len0 = WASM_VECTOR_LEN;
106
+ wasm.sha256(retptr, ptr0, len0);
107
+ var r0 = getInt32Memory0()[retptr / 4 + 0];
108
+ var r1 = getInt32Memory0()[retptr / 4 + 1];
109
+ var v2 = getArrayU8FromWasm0(r0, r1).slice();
110
+ wasm.__wbindgen_export_1(r0, r1 * 1, 1);
111
+ return v2;
112
+ } finally {
113
+ wasm.__wbindgen_add_to_stack_pointer(16);
114
+ }
115
+ };
116
+
117
+ /**
118
+ * Calculate RIPEMD160(SHA256(data)), commonly used as address hash.
119
+ * @param {Uint8Array} data
120
+ * @returns {Uint8Array}
121
+ */
122
+ module.exports.shaRmd160 = function(data) {
123
+ try {
124
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
125
+ const ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_export_0);
126
+ const len0 = WASM_VECTOR_LEN;
127
+ wasm.shaRmd160(retptr, ptr0, len0);
128
+ var r0 = getInt32Memory0()[retptr / 4 + 0];
129
+ var r1 = getInt32Memory0()[retptr / 4 + 1];
130
+ var v2 = getArrayU8FromWasm0(r0, r1).slice();
131
+ wasm.__wbindgen_export_1(r0, r1 * 1, 1);
132
+ return v2;
133
+ } finally {
134
+ wasm.__wbindgen_add_to_stack_pointer(16);
135
+ }
136
+ };
137
+
138
+ const EccFinalization = (typeof FinalizationRegistry === 'undefined')
139
+ ? { register: () => {}, unregister: () => {} }
140
+ : new FinalizationRegistry(ptr => wasm.__wbg_ecc_free(ptr >>> 0));
141
+ /**
142
+ * ECC signatures with libsecp256k1.
143
+ */
144
+ class Ecc {
145
+
146
+ __destroy_into_raw() {
147
+ const ptr = this.__wbg_ptr;
148
+ this.__wbg_ptr = 0;
149
+ EccFinalization.unregister(this);
150
+ return ptr;
151
+ }
152
+
153
+ free() {
154
+ const ptr = this.__destroy_into_raw();
155
+ wasm.__wbg_ecc_free(ptr);
156
+ }
157
+ /**
158
+ * Create a new Ecc instance.
159
+ */
160
+ constructor() {
161
+ const ret = wasm.ecc_new();
162
+ this.__wbg_ptr = ret >>> 0;
163
+ return this;
164
+ }
165
+ /**
166
+ * Derive a public key from secret key.
167
+ * @param {Uint8Array} seckey
168
+ * @returns {Uint8Array}
169
+ */
170
+ derivePubkey(seckey) {
171
+ try {
172
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
173
+ const ptr0 = passArray8ToWasm0(seckey, wasm.__wbindgen_export_0);
174
+ const len0 = WASM_VECTOR_LEN;
175
+ wasm.ecc_derivePubkey(retptr, this.__wbg_ptr, ptr0, len0);
176
+ var r0 = getInt32Memory0()[retptr / 4 + 0];
177
+ var r1 = getInt32Memory0()[retptr / 4 + 1];
178
+ var r2 = getInt32Memory0()[retptr / 4 + 2];
179
+ var r3 = getInt32Memory0()[retptr / 4 + 3];
180
+ if (r3) {
181
+ throw takeObject(r2);
182
+ }
183
+ var v2 = getArrayU8FromWasm0(r0, r1).slice();
184
+ wasm.__wbindgen_export_1(r0, r1 * 1, 1);
185
+ return v2;
186
+ } finally {
187
+ wasm.__wbindgen_add_to_stack_pointer(16);
188
+ }
189
+ }
190
+ /**
191
+ * Sign an ECDSA signature.
192
+ * @param {Uint8Array} seckey
193
+ * @param {Uint8Array} msg
194
+ * @returns {Uint8Array}
195
+ */
196
+ ecdsaSign(seckey, msg) {
197
+ try {
198
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
199
+ const ptr0 = passArray8ToWasm0(seckey, wasm.__wbindgen_export_0);
200
+ const len0 = WASM_VECTOR_LEN;
201
+ const ptr1 = passArray8ToWasm0(msg, wasm.__wbindgen_export_0);
202
+ const len1 = WASM_VECTOR_LEN;
203
+ wasm.ecc_ecdsaSign(retptr, this.__wbg_ptr, ptr0, len0, ptr1, len1);
204
+ var r0 = getInt32Memory0()[retptr / 4 + 0];
205
+ var r1 = getInt32Memory0()[retptr / 4 + 1];
206
+ var r2 = getInt32Memory0()[retptr / 4 + 2];
207
+ var r3 = getInt32Memory0()[retptr / 4 + 3];
208
+ if (r3) {
209
+ throw takeObject(r2);
210
+ }
211
+ var v3 = getArrayU8FromWasm0(r0, r1).slice();
212
+ wasm.__wbindgen_export_1(r0, r1 * 1, 1);
213
+ return v3;
214
+ } finally {
215
+ wasm.__wbindgen_add_to_stack_pointer(16);
216
+ }
217
+ }
218
+ /**
219
+ * Sign a Schnorr signature.
220
+ * @param {Uint8Array} seckey
221
+ * @param {Uint8Array} msg
222
+ * @returns {Uint8Array}
223
+ */
224
+ schnorrSign(seckey, msg) {
225
+ try {
226
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
227
+ const ptr0 = passArray8ToWasm0(seckey, wasm.__wbindgen_export_0);
228
+ const len0 = WASM_VECTOR_LEN;
229
+ const ptr1 = passArray8ToWasm0(msg, wasm.__wbindgen_export_0);
230
+ const len1 = WASM_VECTOR_LEN;
231
+ wasm.ecc_schnorrSign(retptr, this.__wbg_ptr, ptr0, len0, ptr1, len1);
232
+ var r0 = getInt32Memory0()[retptr / 4 + 0];
233
+ var r1 = getInt32Memory0()[retptr / 4 + 1];
234
+ var r2 = getInt32Memory0()[retptr / 4 + 2];
235
+ var r3 = getInt32Memory0()[retptr / 4 + 3];
236
+ if (r3) {
237
+ throw takeObject(r2);
238
+ }
239
+ var v3 = getArrayU8FromWasm0(r0, r1).slice();
240
+ wasm.__wbindgen_export_1(r0, r1 * 1, 1);
241
+ return v3;
242
+ } finally {
243
+ wasm.__wbindgen_add_to_stack_pointer(16);
244
+ }
245
+ }
246
+ }
247
+ module.exports.Ecc = Ecc;
248
+
249
+ module.exports.__wbindgen_string_new = function(arg0, arg1) {
250
+ const ret = getStringFromWasm0(arg0, arg1);
251
+ return addHeapObject(ret);
252
+ };
253
+
254
+ module.exports.__wbindgen_throw = function(arg0, arg1) {
255
+ throw new Error(getStringFromWasm0(arg0, arg1));
256
+ };
257
+
258
+ const path = require('path').join(__dirname, 'ecash_lib_wasm_bg_nodejs.wasm');
259
+ const bytes = require('fs').readFileSync(path);
260
+
261
+ const wasmModule = new WebAssembly.Module(bytes);
262
+ const wasmInstance = new WebAssembly.Instance(wasmModule, imports);
263
+ wasm = wasmInstance.exports;
264
+ module.exports.__wasm = wasm;
265
+
package/dist/hash.d.ts ADDED
@@ -0,0 +1,11 @@
1
+ interface EcashLibHashes {
2
+ sha256: (data: Uint8Array) => Uint8Array;
3
+ sha256d: (data: Uint8Array) => Uint8Array;
4
+ shaRmd160: (data: Uint8Array) => Uint8Array;
5
+ }
6
+ export declare function sha256(data: Uint8Array): Uint8Array;
7
+ export declare function sha256d(data: Uint8Array): Uint8Array;
8
+ export declare function shaRmd160(data: Uint8Array): Uint8Array;
9
+ export declare function __setHashes(hashes: EcashLibHashes): void;
10
+ export {};
11
+ //# sourceMappingURL=hash.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../src/hash.ts"],"names":[],"mappings":"AAIA,UAAU,cAAc;IACpB,MAAM,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,UAAU,CAAC;IACzC,OAAO,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,UAAU,CAAC;IAC1C,SAAS,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,UAAU,CAAC;CAC/C;AAID,wBAAgB,MAAM,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,CAEnD;AACD,wBAAgB,OAAO,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,CAEpD;AACD,wBAAgB,SAAS,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,CAEtD;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,cAAc,QAEjD"}
package/dist/hash.js ADDED
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ // Copyright (c) 2024 The Bitcoin developers
3
+ // Distributed under the MIT software license, see the accompanying
4
+ // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.__setHashes = exports.shaRmd160 = exports.sha256d = exports.sha256 = void 0;
7
+ let HASHES;
8
+ function sha256(data) {
9
+ return HASHES.sha256(data);
10
+ }
11
+ exports.sha256 = sha256;
12
+ function sha256d(data) {
13
+ return HASHES.sha256d(data);
14
+ }
15
+ exports.sha256d = sha256d;
16
+ function shaRmd160(data) {
17
+ return HASHES.shaRmd160(data);
18
+ }
19
+ exports.shaRmd160 = shaRmd160;
20
+ function __setHashes(hashes) {
21
+ HASHES = hashes;
22
+ }
23
+ exports.__setHashes = __setHashes;
24
+ //# sourceMappingURL=hash.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hash.js","sourceRoot":"","sources":["../src/hash.ts"],"names":[],"mappings":";AAAA,4CAA4C;AAC5C,mEAAmE;AACnE,sEAAsE;;;AAQtE,IAAI,MAAsB,CAAC;AAE3B,SAAgB,MAAM,CAAC,IAAgB;IACnC,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC;AAFD,wBAEC;AACD,SAAgB,OAAO,CAAC,IAAgB;IACpC,OAAO,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AAChC,CAAC;AAFD,0BAEC;AACD,SAAgB,SAAS,CAAC,IAAgB;IACtC,OAAO,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;AAClC,CAAC;AAFD,8BAEC;AAED,SAAgB,WAAW,CAAC,MAAsB;IAC9C,MAAM,GAAG,MAAM,CAAC;AACpB,CAAC;AAFD,kCAEC"}
@@ -1,6 +1,5 @@
1
1
  export * from './ecc.js';
2
2
  export * from './hash.js';
3
- export * from './init.js';
4
3
  export * from './op.js';
5
4
  export * from './opcode.js';
6
5
  export * from './script.js';
@@ -11,8 +10,13 @@ export * from './unsignedTx.js';
11
10
  export * from './io/bytes.js';
12
11
  export * from './io/hex.js';
13
12
  export * from './io/int.js';
13
+ export * from './io/str.js';
14
14
  export * from './io/varsize.js';
15
15
  export * from './io/writer.js';
16
16
  export * from './io/writerbytes.js';
17
17
  export * from './io/writerlength.js';
18
+ export * from './token/alp.js';
19
+ export * from './token/common.js';
20
+ export * from './token/empp.js';
21
+ export * from './token/slp.js';
18
22
  //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,SAAS,CAAC;AACxB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ // Copyright (c) 2024 The Bitcoin developers
3
+ // Distributed under the MIT software license, see the accompanying
4
+ // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ var desc = Object.getOwnPropertyDescriptor(m, k);
8
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
9
+ desc = { enumerable: true, get: function() { return m[k]; } };
10
+ }
11
+ Object.defineProperty(o, k2, desc);
12
+ }) : (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ o[k2] = m[k];
15
+ }));
16
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
17
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
18
+ };
19
+ Object.defineProperty(exports, "__esModule", { value: true });
20
+ __exportStar(require("./ecc.js"), exports);
21
+ __exportStar(require("./hash.js"), exports);
22
+ __exportStar(require("./op.js"), exports);
23
+ __exportStar(require("./opcode.js"), exports);
24
+ __exportStar(require("./script.js"), exports);
25
+ __exportStar(require("./sigHashType.js"), exports);
26
+ __exportStar(require("./tx.js"), exports);
27
+ __exportStar(require("./txBuilder.js"), exports);
28
+ __exportStar(require("./unsignedTx.js"), exports);
29
+ __exportStar(require("./io/bytes.js"), exports);
30
+ __exportStar(require("./io/hex.js"), exports);
31
+ __exportStar(require("./io/int.js"), exports);
32
+ __exportStar(require("./io/str.js"), exports);
33
+ __exportStar(require("./io/varsize.js"), exports);
34
+ __exportStar(require("./io/writer.js"), exports);
35
+ __exportStar(require("./io/writerbytes.js"), exports);
36
+ __exportStar(require("./io/writerlength.js"), exports);
37
+ __exportStar(require("./token/alp.js"), exports);
38
+ __exportStar(require("./token/common.js"), exports);
39
+ __exportStar(require("./token/empp.js"), exports);
40
+ __exportStar(require("./token/slp.js"), exports);
41
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,4CAA4C;AAC5C,mEAAmE;AACnE,sEAAsE;;;;;;;;;;;;;;;;AAEtE,2CAAyB;AACzB,4CAA0B;AAC1B,0CAAwB;AACxB,8CAA4B;AAC5B,8CAA4B;AAC5B,mDAAiC;AACjC,0CAAwB;AACxB,iDAA+B;AAC/B,kDAAgC;AAChC,gDAA8B;AAC9B,8CAA4B;AAC5B,8CAA4B;AAC5B,8CAA4B;AAC5B,kDAAgC;AAChC,iDAA+B;AAC/B,sDAAoC;AACpC,uDAAqC;AACrC,iDAA+B;AAC/B,oDAAkC;AAClC,kDAAgC;AAChC,iDAA+B"}
@@ -0,0 +1,3 @@
1
+ export * from './index.js';
2
+ export * from './initBrowser.js';
3
+ //# sourceMappingURL=indexBrowser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"indexBrowser.d.ts","sourceRoot":"","sources":["../src/indexBrowser.ts"],"names":[],"mappings":"AAIA,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ // Copyright (c) 2024 The Bitcoin developers
3
+ // Distributed under the MIT software license, see the accompanying
4
+ // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ var desc = Object.getOwnPropertyDescriptor(m, k);
8
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
9
+ desc = { enumerable: true, get: function() { return m[k]; } };
10
+ }
11
+ Object.defineProperty(o, k2, desc);
12
+ }) : (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ o[k2] = m[k];
15
+ }));
16
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
17
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
18
+ };
19
+ Object.defineProperty(exports, "__esModule", { value: true });
20
+ __exportStar(require("./index.js"), exports);
21
+ __exportStar(require("./initBrowser.js"), exports);
22
+ //# sourceMappingURL=indexBrowser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"indexBrowser.js","sourceRoot":"","sources":["../src/indexBrowser.ts"],"names":[],"mappings":";AAAA,4CAA4C;AAC5C,mEAAmE;AACnE,sEAAsE;;;;;;;;;;;;;;;;AAEtE,6CAA2B;AAC3B,mDAAiC"}