ecash-lib 1.5.1 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +4 -39
  2. package/dist/ecc.d.ts +3 -7
  3. package/dist/ecc.d.ts.map +1 -1
  4. package/dist/ecc.js +33 -2
  5. package/dist/ecc.js.map +1 -1
  6. package/dist/ffi/ecash_lib_wasm_bg_browser.d.ts +1 -0
  7. package/dist/ffi/ecash_lib_wasm_bg_browser.js +1571 -0
  8. package/dist/ffi/ecash_lib_wasm_bg_browser.wasm +0 -0
  9. package/dist/ffi/ecash_lib_wasm_bg_nodejs.wasm +0 -0
  10. package/dist/hash.d.ts +6 -6
  11. package/dist/hash.d.ts.map +1 -1
  12. package/dist/hash.js +7 -2
  13. package/dist/hash.js.map +1 -1
  14. package/dist/hdwallet.d.ts +2 -4
  15. package/dist/hdwallet.d.ts.map +1 -1
  16. package/dist/hdwallet.js +6 -7
  17. package/dist/hdwallet.js.map +1 -1
  18. package/dist/initBrowser.d.ts +1 -11
  19. package/dist/initBrowser.d.ts.map +1 -1
  20. package/dist/initBrowser.js +14 -25
  21. package/dist/initBrowser.js.map +1 -1
  22. package/dist/initNodeJs.d.ts +1 -2
  23. package/dist/initNodeJs.d.ts.map +1 -1
  24. package/dist/initNodeJs.js +9 -14
  25. package/dist/initNodeJs.js.map +1 -1
  26. package/dist/test/testRunner.d.ts +0 -2
  27. package/dist/test/testRunner.d.ts.map +1 -1
  28. package/dist/test/testRunner.js +3 -6
  29. package/dist/test/testRunner.js.map +1 -1
  30. package/dist/txBuilder.d.ts +5 -1
  31. package/dist/txBuilder.d.ts.map +1 -1
  32. package/dist/txBuilder.js +8 -7
  33. package/dist/txBuilder.js.map +1 -1
  34. package/package.json +1 -1
  35. package/src/ecc.ts +39 -5
  36. package/src/ffi/ecash_lib_wasm_bg_browser.d.ts +1 -0
  37. package/src/ffi/ecash_lib_wasm_bg_browser.js +1571 -0
  38. package/src/ffi/ecash_lib_wasm_bg_browser.wasm +0 -0
  39. package/src/ffi/ecash_lib_wasm_bg_nodejs.wasm +0 -0
  40. package/src/hash.ts +19 -14
  41. package/src/hdwallet.ts +4 -8
  42. package/src/initBrowser.ts +18 -25
  43. package/src/initNodeJs.ts +9 -12
  44. package/src/test/testRunner.ts +3 -11
  45. package/src/txBuilder.ts +12 -7
package/src/hash.ts CHANGED
@@ -12,35 +12,40 @@ export interface Hasher {
12
12
  type HasherClass = { new (): Hasher };
13
13
 
14
14
  interface EcashLibHashes {
15
- sha256: (data: Uint8Array) => Uint8Array;
16
- sha256d: (data: Uint8Array) => Uint8Array;
17
- shaRmd160: (data: Uint8Array) => Uint8Array;
18
- sha512: (data: Uint8Array) => Uint8Array;
19
- Sha256H: HasherClass;
20
- Sha512H: HasherClass;
15
+ sha256?: (data: Uint8Array) => Uint8Array;
16
+ sha256d?: (data: Uint8Array) => Uint8Array;
17
+ shaRmd160?: (data: Uint8Array) => Uint8Array;
18
+ sha512?: (data: Uint8Array) => Uint8Array;
19
+ Sha256H?: HasherClass;
20
+ Sha512H?: HasherClass;
21
21
  }
22
22
 
23
- let HASHES: EcashLibHashes;
23
+ const HASHES: EcashLibHashes = {};
24
24
 
25
25
  export function sha256(data: Uint8Array): Uint8Array {
26
- return HASHES.sha256(data);
26
+ return HASHES.sha256!(data);
27
27
  }
28
28
  export function sha256d(data: Uint8Array): Uint8Array {
29
- return HASHES.sha256d(data);
29
+ return HASHES.sha256d!(data);
30
30
  }
31
31
  export function shaRmd160(data: Uint8Array): Uint8Array {
32
- return HASHES.shaRmd160(data);
32
+ return HASHES.shaRmd160!(data);
33
33
  }
34
34
  export function sha512(data: Uint8Array): Uint8Array {
35
- return HASHES.sha512(data);
35
+ return HASHES.sha512!(data);
36
36
  }
37
37
  export function sha256Hasher(): Hasher {
38
- return new HASHES.Sha256H();
38
+ return new HASHES.Sha256H!();
39
39
  }
40
40
  export function sha512Hasher(): Hasher {
41
- return new HASHES.Sha512H();
41
+ return new HASHES.Sha512H!();
42
42
  }
43
43
 
44
44
  export function __setHashes(hashes: EcashLibHashes) {
45
- HASHES = hashes;
45
+ HASHES.sha256 = hashes.sha256;
46
+ HASHES.sha256d = hashes.sha256d;
47
+ HASHES.shaRmd160 = hashes.shaRmd160;
48
+ HASHES.sha512 = hashes.sha512;
49
+ HASHES.Sha256H = hashes.Sha256H;
50
+ HASHES.Sha512H = hashes.Sha512H;
46
51
  }
package/src/hdwallet.ts CHANGED
@@ -21,7 +21,6 @@ export class HdNode {
21
21
  private _parentFingerprint: number;
22
22
 
23
23
  public constructor(params: {
24
- ecc: Ecc;
25
24
  seckey: Uint8Array | undefined;
26
25
  pubkey: Uint8Array;
27
26
  chainCode: Uint8Array;
@@ -29,7 +28,7 @@ export class HdNode {
29
28
  index: number;
30
29
  parentFingerprint: number;
31
30
  }) {
32
- this._ecc = params.ecc;
31
+ this._ecc = new Ecc();
33
32
  this._seckey = params.seckey;
34
33
  this._pubkey = params.pubkey;
35
34
  this._chainCode = params.chainCode;
@@ -113,7 +112,6 @@ export class HdNode {
113
112
  seckey = undefined;
114
113
  }
115
114
  return new HdNode({
116
- ecc: this._ecc,
117
115
  seckey: seckey,
118
116
  pubkey: pubkey,
119
117
  chainCode: hashedRight,
@@ -154,14 +152,12 @@ export class HdNode {
154
152
  }
155
153
 
156
154
  public static fromPrivateKey(
157
- ecc: Ecc,
158
155
  seckey: Uint8Array,
159
156
  chainCode: Uint8Array,
160
157
  ): HdNode {
161
158
  return new HdNode({
162
- ecc,
163
159
  seckey: seckey,
164
- pubkey: ecc.derivePubkey(seckey),
160
+ pubkey: new Ecc().derivePubkey(seckey),
165
161
  chainCode,
166
162
  depth: 0,
167
163
  index: 0,
@@ -169,13 +165,13 @@ export class HdNode {
169
165
  });
170
166
  }
171
167
 
172
- public static fromSeed(ecc: Ecc, seed: Uint8Array): HdNode {
168
+ public static fromSeed(seed: Uint8Array): HdNode {
173
169
  if (seed.length < 16 || seed.length > 64) {
174
170
  throw new TypeError('Seed must be between 16 and 64 bytes long');
175
171
  }
176
172
  const hashed = hmacSha512(strToBytes('Bitcoin seed'), seed);
177
173
  const hashedLeft = hashed.slice(0, 32);
178
174
  const hashedRight = hashed.slice(32);
179
- return HdNode.fromPrivateKey(ecc, hashedLeft, hashedRight);
175
+ return HdNode.fromPrivateKey(hashedLeft, hashedRight);
180
176
  }
181
177
  }
@@ -2,30 +2,23 @@
2
2
  // Distributed under the MIT software license, see the accompanying
3
3
  // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
4
 
5
- import { __setEcc } from './ecc.js';
6
- import __wbg_init, * as ffi from './ffi/ecash_lib_wasm_browser.js';
5
+ import * as ffi from './ffi/ecash_lib_wasm_browser.js';
7
6
  import { __setHashes } from './hash.js';
7
+ import { __setEcc } from './ecc.js';
8
+
9
+ import { ECASH_LIB_WASM_BASE64 } from './ffi/ecash_lib_wasm_bg_browser.js';
10
+
11
+ const wasmRaw = Uint8Array.from(atob(ECASH_LIB_WASM_BASE64), c =>
12
+ c.charCodeAt(0),
13
+ );
14
+ ffi.initSync(wasmRaw);
8
15
 
9
- /**
10
- * Load and initialize the WASM module for Web.
11
- *
12
- * Some bundlers can't handle WebAssembly yet (at the time of writing, vite).
13
- * If you run into "CompileError: expected magic word 00 61 73 6d", you can
14
- * provide a custom WASM URL or module:
15
- * import ecashLibWasmUrl from 'ecash-lib/dist/ffi/ecash_lib_wasm_bg_browser.wasm?url';
16
- * await initWasm(ecashLibWasmUrl);
17
- **/
18
- export async function initWasm(
19
- module_or_path?: ffi.InitInput | Promise<ffi.InitInput>,
20
- ) {
21
- await __wbg_init(module_or_path);
22
- __setEcc(ffi.Ecc);
23
- __setHashes({
24
- sha256: ffi.sha256,
25
- sha256d: ffi.sha256d,
26
- shaRmd160: ffi.shaRmd160,
27
- sha512: ffi.sha512,
28
- Sha256H: ffi.Sha256H,
29
- Sha512H: ffi.Sha512H,
30
- });
31
- }
16
+ __setEcc(new ffi.Ecc());
17
+ __setHashes({
18
+ sha256: ffi.sha256,
19
+ sha256d: ffi.sha256d,
20
+ shaRmd160: ffi.shaRmd160,
21
+ sha512: ffi.sha512,
22
+ Sha256H: ffi.Sha256H,
23
+ Sha512H: ffi.Sha512H,
24
+ });
package/src/initNodeJs.ts CHANGED
@@ -6,15 +6,12 @@ import { __setEcc } from './ecc.js';
6
6
  import * as ffi from './ffi/ecash_lib_wasm_nodejs.js';
7
7
  import { __setHashes } from './hash.js';
8
8
 
9
- /** Load and initialize the WASM module for NodeJS */
10
- export async function initWasm(_dummy?: any) {
11
- __setEcc(ffi.Ecc);
12
- __setHashes({
13
- sha256: ffi.sha256,
14
- sha256d: ffi.sha256d,
15
- shaRmd160: ffi.shaRmd160,
16
- sha512: ffi.sha512,
17
- Sha256H: ffi.Sha256H,
18
- Sha512H: ffi.Sha512H,
19
- });
20
- }
9
+ __setEcc(new ffi.Ecc());
10
+ __setHashes({
11
+ sha256: ffi.sha256,
12
+ sha256d: ffi.sha256d,
13
+ shaRmd160: ffi.shaRmd160,
14
+ sha512: ffi.sha512,
15
+ Sha256H: ffi.Sha256H,
16
+ Sha512H: ffi.Sha512H,
17
+ });
@@ -23,19 +23,13 @@ const ANYONE_SCRIPT = Script.fromOps([pushBytesOp(fromHex('01'.repeat(100)))]);
23
23
  const ANYONE_SCRIPT_SIG = Script.fromOps([pushBytesOp(ANYONE_SCRIPT.bytecode)]);
24
24
 
25
25
  export class TestRunner {
26
- public ecc: Ecc;
27
26
  public runner: ChildProcess;
28
27
  public chronik: ChronikClient;
29
28
  private coinsTxid: string | undefined;
30
29
  private coinValue: number | undefined;
31
30
  private lastUsedOutIdx: number;
32
31
 
33
- private constructor(
34
- ecc: Ecc,
35
- runner: ChildProcess,
36
- chronik: ChronikClient,
37
- ) {
38
- this.ecc = ecc;
32
+ private constructor(runner: ChildProcess, chronik: ChronikClient) {
39
33
  this.runner = runner;
40
34
  this.chronik = chronik;
41
35
  this.coinsTxid = undefined;
@@ -114,8 +108,6 @@ export class TestRunner {
114
108
  }
115
109
  });
116
110
 
117
- const ecc = new Ecc();
118
-
119
111
  // We got the coins, can fan out now
120
112
  await (events as any).once(statusEvent, 'ready');
121
113
 
@@ -123,7 +115,7 @@ export class TestRunner {
123
115
  throw new Event('Chronik is undefined');
124
116
  }
125
117
 
126
- return new TestRunner(ecc, runner, chronik);
118
+ return new TestRunner(runner, chronik);
127
119
  }
128
120
 
129
121
  public async setupCoins(
@@ -195,7 +187,7 @@ export class TestRunner {
195
187
  Script.fromOps([OP_RETURN]), // burn leftover
196
188
  ],
197
189
  });
198
- const setupTx = setupTxBuilder.sign(this.ecc, 1000, 546);
190
+ const setupTx = setupTxBuilder.sign({ feePerKb: 1000, dustLimit: 546 });
199
191
  return (await this.chronik.broadcastTx(setupTx.ser())).txid;
200
192
  }
201
193
 
package/src/txBuilder.ts CHANGED
@@ -120,7 +120,12 @@ export class TxBuilder {
120
120
  }
121
121
 
122
122
  /** Sign the tx built by this builder and return a Tx */
123
- public sign(ecc: Ecc, feePerKb?: number, dustLimit?: number): Tx {
123
+ public sign(params?: {
124
+ ecc?: Ecc;
125
+ feePerKb?: number;
126
+ dustLimit?: number;
127
+ }): Tx {
128
+ const ecc = params?.ecc ?? new Ecc();
124
129
  const { fixedOutputSum, leftoverIdx, outputs } = this.prepareOutputs();
125
130
  const inputs = this.inputs.map(input => copyTxInput(input.input));
126
131
  const updateSignatories = (ecc: Ecc, unsignedTx: UnsignedTx) => {
@@ -145,15 +150,15 @@ export class TxBuilder {
145
150
  'Using a leftover output requires setting SignData.value for all inputs',
146
151
  );
147
152
  }
148
- if (feePerKb === undefined) {
153
+ if (params?.feePerKb === undefined) {
149
154
  throw new Error(
150
155
  'Using a leftover output requires setting feePerKb',
151
156
  );
152
157
  }
153
- if (!Number.isInteger(feePerKb)) {
158
+ if (!Number.isInteger(params.feePerKb)) {
154
159
  throw new Error('feePerKb must be an integer');
155
160
  }
156
- if (dustLimit === undefined) {
161
+ if (params?.dustLimit === undefined) {
157
162
  throw new Error(
158
163
  'Using a leftover output requires setting dustLimit',
159
164
  );
@@ -169,16 +174,16 @@ export class TxBuilder {
169
174
  // Must use dummy here because ECDSA sigs could be too small for fee calc
170
175
  updateSignatories(new EccDummy(), dummyUnsignedTx);
171
176
  let txSize = dummyUnsignedTx.tx.serSize();
172
- let txFee = calcTxFee(txSize, feePerKb);
177
+ let txFee = calcTxFee(txSize, params.feePerKb);
173
178
  const leftoverValue = inputSum - (fixedOutputSum + txFee);
174
- if (leftoverValue < dustLimit) {
179
+ if (leftoverValue < params.dustLimit) {
175
180
  // inputs cannot pay for a dust leftover -> remove & recalc
176
181
  outputs.splice(leftoverIdx, 1);
177
182
  dummyUnsignedTx.tx.outputs = outputs;
178
183
  // Must update signatories again as they might depend on outputs
179
184
  updateSignatories(new EccDummy(), dummyUnsignedTx);
180
185
  txSize = dummyUnsignedTx.tx.serSize();
181
- txFee = calcTxFee(txSize, feePerKb);
186
+ txFee = calcTxFee(txSize, params.feePerKb);
182
187
  } else {
183
188
  outputs[leftoverIdx].value = leftoverValue;
184
189
  }