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.
- package/README.md +4 -39
- package/dist/ecc.d.ts +3 -7
- package/dist/ecc.d.ts.map +1 -1
- package/dist/ecc.js +33 -2
- package/dist/ecc.js.map +1 -1
- package/dist/ffi/ecash_lib_wasm_bg_browser.d.ts +1 -0
- package/dist/ffi/ecash_lib_wasm_bg_browser.js +1571 -0
- package/dist/ffi/ecash_lib_wasm_bg_browser.wasm +0 -0
- package/dist/ffi/ecash_lib_wasm_bg_nodejs.wasm +0 -0
- package/dist/hash.d.ts +6 -6
- package/dist/hash.d.ts.map +1 -1
- package/dist/hash.js +7 -2
- package/dist/hash.js.map +1 -1
- package/dist/hdwallet.d.ts +2 -4
- package/dist/hdwallet.d.ts.map +1 -1
- package/dist/hdwallet.js +6 -7
- package/dist/hdwallet.js.map +1 -1
- package/dist/initBrowser.d.ts +1 -11
- package/dist/initBrowser.d.ts.map +1 -1
- package/dist/initBrowser.js +14 -25
- package/dist/initBrowser.js.map +1 -1
- package/dist/initNodeJs.d.ts +1 -2
- package/dist/initNodeJs.d.ts.map +1 -1
- package/dist/initNodeJs.js +9 -14
- package/dist/initNodeJs.js.map +1 -1
- package/dist/test/testRunner.d.ts +0 -2
- package/dist/test/testRunner.d.ts.map +1 -1
- package/dist/test/testRunner.js +3 -6
- package/dist/test/testRunner.js.map +1 -1
- package/dist/txBuilder.d.ts +5 -1
- package/dist/txBuilder.d.ts.map +1 -1
- package/dist/txBuilder.js +8 -7
- package/dist/txBuilder.js.map +1 -1
- package/package.json +1 -1
- package/src/ecc.ts +39 -5
- package/src/ffi/ecash_lib_wasm_bg_browser.d.ts +1 -0
- package/src/ffi/ecash_lib_wasm_bg_browser.js +1571 -0
- package/src/ffi/ecash_lib_wasm_bg_browser.wasm +0 -0
- package/src/ffi/ecash_lib_wasm_bg_nodejs.wasm +0 -0
- package/src/hash.ts +19 -14
- package/src/hdwallet.ts +4 -8
- package/src/initBrowser.ts +18 -25
- package/src/initNodeJs.ts +9 -12
- package/src/test/testRunner.ts +3 -11
- package/src/txBuilder.ts +12 -7
|
Binary file
|
|
Binary file
|
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
|
|
16
|
-
sha256d
|
|
17
|
-
shaRmd160
|
|
18
|
-
sha512
|
|
19
|
-
Sha256H
|
|
20
|
-
Sha512H
|
|
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
|
-
|
|
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 =
|
|
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:
|
|
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(
|
|
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(
|
|
175
|
+
return HdNode.fromPrivateKey(hashedLeft, hashedRight);
|
|
180
176
|
}
|
|
181
177
|
}
|
package/src/initBrowser.ts
CHANGED
|
@@ -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
|
|
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
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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
|
+
});
|
package/src/test/testRunner.ts
CHANGED
|
@@ -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(
|
|
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(
|
|
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(
|
|
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
|
}
|