mainnet-js 3.0.1 → 3.1.1
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/dist/index.html +1 -1
- package/dist/{mainnet-3.0.1.js → mainnet-3.1.1.js} +5 -5
- package/dist/module/history/getHistory.js +10 -10
- package/dist/module/history/getHistory.js.map +1 -1
- package/dist/module/network/ElectrumNetworkProvider.d.ts +7 -3
- package/dist/module/network/ElectrumNetworkProvider.d.ts.map +1 -1
- package/dist/module/network/ElectrumNetworkProvider.js +51 -25
- package/dist/module/network/ElectrumNetworkProvider.js.map +1 -1
- package/dist/module/network/NetworkProvider.d.ts +14 -6
- package/dist/module/network/NetworkProvider.d.ts.map +1 -1
- package/dist/module/network/index.d.ts +1 -1
- package/dist/module/network/index.d.ts.map +1 -1
- package/dist/module/network/interface.d.ts +4 -3
- package/dist/module/network/interface.d.ts.map +1 -1
- package/dist/module/wallet/Base.d.ts.map +1 -1
- package/dist/module/wallet/Base.js +1 -2
- package/dist/module/wallet/Base.js.map +1 -1
- package/dist/module/wallet/HDWallet.d.ts +8 -0
- package/dist/module/wallet/HDWallet.d.ts.map +1 -1
- package/dist/module/wallet/HDWallet.js +28 -0
- package/dist/module/wallet/HDWallet.js.map +1 -1
- package/dist/module/wallet/Util.d.ts +5 -3
- package/dist/module/wallet/Util.d.ts.map +1 -1
- package/dist/module/wallet/Util.js +28 -22
- package/dist/module/wallet/Util.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/history/getHistory.ts +15 -15
- package/src/network/ElectrumNetworkProvider.ts +105 -39
- package/src/network/NetworkProvider.ts +44 -6
- package/src/network/index.ts +5 -1
- package/src/network/interface.ts +8 -3
- package/src/wallet/Base.ts +1 -4
- package/src/wallet/HDWallet.test.ts +239 -0
- package/src/wallet/HDWallet.ts +36 -0
- package/src/wallet/Util.test.ts +56 -6
- package/src/wallet/Util.ts +67 -46
- package/src/wallet/Wif.test.ts +3 -9
|
@@ -14,7 +14,12 @@ import {
|
|
|
14
14
|
HeaderI,
|
|
15
15
|
} from "../interface.js";
|
|
16
16
|
import { Network } from "../interface.js";
|
|
17
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
ElectrumRawTransaction,
|
|
19
|
+
ElectrumRawTransactionVinWithValues,
|
|
20
|
+
ElectrumRawTransactionWithInputValues,
|
|
21
|
+
ElectrumUtxo,
|
|
22
|
+
} from "./interface.js";
|
|
18
23
|
|
|
19
24
|
import { CancelFn } from "../wallet/interface.js";
|
|
20
25
|
import { getTransactionHash } from "../util/transaction.js";
|
|
@@ -25,6 +30,9 @@ import { IndexedDbCache } from "../cache/IndexedDbCache.js";
|
|
|
25
30
|
import { WebStorageCache } from "../cache/WebStorageCache.js";
|
|
26
31
|
import { MemoryCache } from "../cache/MemoryCache.js";
|
|
27
32
|
|
|
33
|
+
/** Internal type for cached verbose transactions. fetchHeight is stripped before returning. */
|
|
34
|
+
type CachedRawTransaction = ElectrumRawTransaction & { fetchHeight: number };
|
|
35
|
+
|
|
28
36
|
export default class ElectrumNetworkProvider implements NetworkProvider {
|
|
29
37
|
public electrum: ElectrumClient<ElectrumClientEvents>;
|
|
30
38
|
public subscriptions: number = 0;
|
|
@@ -135,7 +143,7 @@ export default class ElectrumNetworkProvider implements NetworkProvider {
|
|
|
135
143
|
if (hashes.length === 0) return new Map();
|
|
136
144
|
|
|
137
145
|
const results = new Map<string, string>();
|
|
138
|
-
const keys = hashes.map((
|
|
146
|
+
const keys = hashes.map((hash) => `txraw-${this.network}-${hash}`);
|
|
139
147
|
|
|
140
148
|
// batch cache read
|
|
141
149
|
let cached: Map<string, string | null> | undefined;
|
|
@@ -168,7 +176,7 @@ export default class ElectrumNetworkProvider implements NetworkProvider {
|
|
|
168
176
|
// batch cache write
|
|
169
177
|
if (this.cache) {
|
|
170
178
|
const entries: [string, string][] = fetched.map(([hash, tx]) => [
|
|
171
|
-
`
|
|
179
|
+
`txraw-${this.network}-${hash}`,
|
|
172
180
|
tx,
|
|
173
181
|
]);
|
|
174
182
|
await this.cache.setItems(entries);
|
|
@@ -186,7 +194,9 @@ export default class ElectrumNetworkProvider implements NetworkProvider {
|
|
|
186
194
|
if (heights.length === 0) return new Map();
|
|
187
195
|
|
|
188
196
|
const results = new Map<number, HeaderI>();
|
|
189
|
-
const keys = heights.map(
|
|
197
|
+
const keys = heights.map(
|
|
198
|
+
(height) => `header-${this.network}-${height}-true`
|
|
199
|
+
);
|
|
190
200
|
|
|
191
201
|
// batch cache read
|
|
192
202
|
let cached: Map<string, string | null> | undefined;
|
|
@@ -251,56 +261,84 @@ export default class ElectrumNetworkProvider implements NetworkProvider {
|
|
|
251
261
|
return this.currentHeight;
|
|
252
262
|
}
|
|
253
263
|
|
|
264
|
+
async getRawTransaction(
|
|
265
|
+
txHash: string,
|
|
266
|
+
verbose: true,
|
|
267
|
+
loadInputValues: true
|
|
268
|
+
): Promise<ElectrumRawTransactionWithInputValues>;
|
|
269
|
+
async getRawTransaction(
|
|
270
|
+
txHash: string,
|
|
271
|
+
verbose: true,
|
|
272
|
+
loadInputValues?: false
|
|
273
|
+
): Promise<ElectrumRawTransaction>;
|
|
274
|
+
async getRawTransaction(
|
|
275
|
+
txHash: string,
|
|
276
|
+
verbose?: false,
|
|
277
|
+
loadInputValues?: false
|
|
278
|
+
): Promise<string>;
|
|
254
279
|
async getRawTransaction(
|
|
255
280
|
txHash: string,
|
|
256
281
|
verbose: boolean = false,
|
|
257
282
|
loadInputValues: boolean = false
|
|
258
|
-
): Promise<
|
|
259
|
-
|
|
283
|
+
): Promise<
|
|
284
|
+
string | ElectrumRawTransaction | ElectrumRawTransactionWithInputValues
|
|
285
|
+
> {
|
|
286
|
+
const nonVerboseKey = `txraw-${this.network}-${txHash}`;
|
|
287
|
+
const verboseKey = `tx-${this.network}-${txHash}`;
|
|
288
|
+
const key = verbose ? verboseKey : nonVerboseKey;
|
|
260
289
|
|
|
261
290
|
if (this.cache) {
|
|
262
291
|
const cached = await this.cache.getItem(key);
|
|
263
292
|
if (cached) {
|
|
264
|
-
|
|
293
|
+
if (!verbose) {
|
|
294
|
+
return cached;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
const cachedTx = JSON.parse(cached) as CachedRawTransaction;
|
|
298
|
+
if (cachedTx.confirmations > 0) {
|
|
299
|
+
const currentHeight = await this.getBlockHeight();
|
|
300
|
+
cachedTx.confirmations += currentHeight - cachedTx.fetchHeight;
|
|
301
|
+
}
|
|
302
|
+
const { fetchHeight: _, ...transaction } = cachedTx;
|
|
303
|
+
|
|
304
|
+
if (loadInputValues) {
|
|
305
|
+
return this.enrichWithInputValues(transaction);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
return transaction;
|
|
265
309
|
}
|
|
266
310
|
}
|
|
267
311
|
|
|
268
312
|
try {
|
|
269
|
-
const
|
|
313
|
+
const result = await this.performRequest(
|
|
270
314
|
"blockchain.transaction.get",
|
|
271
315
|
txHash,
|
|
272
316
|
verbose
|
|
273
|
-
)
|
|
317
|
+
);
|
|
318
|
+
|
|
319
|
+
if (!verbose) {
|
|
320
|
+
const hex = result as string;
|
|
321
|
+
if (this.cache) {
|
|
322
|
+
await this.cache.setItem(key, hex);
|
|
323
|
+
}
|
|
324
|
+
return hex;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
const cachedTx = result as CachedRawTransaction;
|
|
328
|
+
cachedTx.confirmations ??= 0;
|
|
329
|
+
cachedTx.fetchHeight = await this.getBlockHeight();
|
|
274
330
|
|
|
275
331
|
if (this.cache) {
|
|
276
|
-
await this.cache.setItem(
|
|
277
|
-
key,
|
|
278
|
-
verbose
|
|
279
|
-
? JSON.stringify(transaction)
|
|
280
|
-
: (transaction as unknown as string)
|
|
281
|
-
);
|
|
332
|
+
await this.cache.setItem(key, JSON.stringify(cachedTx));
|
|
282
333
|
}
|
|
283
334
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
hashes.map((hash) => this.getRawTransactionObject(hash, false))
|
|
289
|
-
);
|
|
290
|
-
const transactionMap = new Map<string, ElectrumRawTransaction>();
|
|
291
|
-
transactions.forEach((val) => transactionMap.set(val.hash, val));
|
|
292
|
-
|
|
293
|
-
transaction.vin.forEach((input) => {
|
|
294
|
-
const output = transactionMap
|
|
295
|
-
.get(input.txid)!
|
|
296
|
-
.vout.find((val) => val.n === input.vout)!;
|
|
297
|
-
input.address = output.scriptPubKey.addresses[0];
|
|
298
|
-
input.value = output.value;
|
|
299
|
-
input.tokenData = output.tokenData;
|
|
300
|
-
});
|
|
335
|
+
const { fetchHeight: _, ...transaction } = cachedTx;
|
|
336
|
+
|
|
337
|
+
if (loadInputValues) {
|
|
338
|
+
return this.enrichWithInputValues(transaction);
|
|
301
339
|
}
|
|
302
340
|
|
|
303
|
-
return transaction
|
|
341
|
+
return transaction;
|
|
304
342
|
} catch (error: any) {
|
|
305
343
|
if (
|
|
306
344
|
(error.message as string).indexOf(
|
|
@@ -314,16 +352,44 @@ export default class ElectrumNetworkProvider implements NetworkProvider {
|
|
|
314
352
|
}
|
|
315
353
|
}
|
|
316
354
|
|
|
355
|
+
private async enrichWithInputValues(
|
|
356
|
+
transaction: ElectrumRawTransaction
|
|
357
|
+
): Promise<ElectrumRawTransactionWithInputValues> {
|
|
358
|
+
const hashes = [...new Set(transaction.vin.map((val) => val.txid))];
|
|
359
|
+
const transactions = await Promise.all(
|
|
360
|
+
hashes.map((hash) => this.getRawTransactionObject(hash, false))
|
|
361
|
+
);
|
|
362
|
+
const transactionMap = new Map<string, ElectrumRawTransaction>();
|
|
363
|
+
transactions.forEach((val) => transactionMap.set(val.hash, val));
|
|
364
|
+
|
|
365
|
+
const enrichedVin: ElectrumRawTransactionVinWithValues[] =
|
|
366
|
+
transaction.vin.map((input) => {
|
|
367
|
+
const output = transactionMap
|
|
368
|
+
.get(input.txid)!
|
|
369
|
+
.vout.find((val) => val.n === input.vout)!;
|
|
370
|
+
return { ...input, ...output };
|
|
371
|
+
});
|
|
372
|
+
|
|
373
|
+
return { ...transaction, vin: enrichedVin };
|
|
374
|
+
}
|
|
375
|
+
|
|
317
376
|
// gets the decoded transaction in human readable form
|
|
377
|
+
async getRawTransactionObject(
|
|
378
|
+
txHash: string,
|
|
379
|
+
loadInputValues: true
|
|
380
|
+
): Promise<ElectrumRawTransactionWithInputValues>;
|
|
381
|
+
async getRawTransactionObject(
|
|
382
|
+
txHash: string,
|
|
383
|
+
loadInputValues?: false
|
|
384
|
+
): Promise<ElectrumRawTransaction>;
|
|
318
385
|
async getRawTransactionObject(
|
|
319
386
|
txHash: string,
|
|
320
387
|
loadInputValues: boolean = false
|
|
321
|
-
): Promise<ElectrumRawTransaction> {
|
|
322
|
-
|
|
323
|
-
txHash,
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
)) as unknown as ElectrumRawTransaction;
|
|
388
|
+
): Promise<ElectrumRawTransaction | ElectrumRawTransactionWithInputValues> {
|
|
389
|
+
if (loadInputValues) {
|
|
390
|
+
return this.getRawTransaction(txHash, true, true);
|
|
391
|
+
}
|
|
392
|
+
return this.getRawTransaction(txHash, true);
|
|
327
393
|
}
|
|
328
394
|
|
|
329
395
|
async sendRawTransaction(
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import { TxI, Utxo, Network, HexHeaderI, HeaderI } from "../interface.js";
|
|
2
|
+
import {
|
|
3
|
+
ElectrumRawTransaction,
|
|
4
|
+
ElectrumRawTransactionWithInputValues,
|
|
5
|
+
} from "./interface.js";
|
|
2
6
|
import { CancelFn } from "../wallet/interface.js";
|
|
3
7
|
|
|
4
8
|
export default interface NetworkProvider {
|
|
@@ -38,13 +42,35 @@ export default interface NetworkProvider {
|
|
|
38
42
|
getRelayFee(): Promise<number>;
|
|
39
43
|
|
|
40
44
|
/**
|
|
41
|
-
* Retrieve
|
|
45
|
+
* Retrieve transaction details for a given transaction ID.
|
|
42
46
|
* @param txHash Hex of transaction hash.
|
|
43
|
-
* @param verbose
|
|
47
|
+
* @param verbose When true, returns a decoded transaction object instead of hex.
|
|
48
|
+
* @param loadInputValues When true (requires verbose), each vin is enriched with value, address and tokenData from the parent output.
|
|
44
49
|
* @throws {Error} If the transaction does not exist
|
|
45
|
-
* @returns The
|
|
50
|
+
* @returns The hex string (non-verbose) or decoded transaction object (verbose).
|
|
46
51
|
*/
|
|
47
|
-
getRawTransaction(
|
|
52
|
+
getRawTransaction(
|
|
53
|
+
txHash: string,
|
|
54
|
+
verbose: true,
|
|
55
|
+
loadInputValues: true
|
|
56
|
+
): Promise<ElectrumRawTransactionWithInputValues>;
|
|
57
|
+
getRawTransaction(
|
|
58
|
+
txHash: string,
|
|
59
|
+
verbose: true,
|
|
60
|
+
loadInputValues?: false
|
|
61
|
+
): Promise<ElectrumRawTransaction>;
|
|
62
|
+
getRawTransaction(
|
|
63
|
+
txHash: string,
|
|
64
|
+
verbose?: false,
|
|
65
|
+
loadInputValues?: false
|
|
66
|
+
): Promise<string>;
|
|
67
|
+
getRawTransaction(
|
|
68
|
+
txHash: string,
|
|
69
|
+
verbose?: boolean,
|
|
70
|
+
loadInputValues?: boolean
|
|
71
|
+
): Promise<
|
|
72
|
+
string | ElectrumRawTransaction | ElectrumRawTransactionWithInputValues
|
|
73
|
+
>;
|
|
48
74
|
|
|
49
75
|
/**
|
|
50
76
|
* Batch retrieve raw transactions by their hashes.
|
|
@@ -63,10 +89,22 @@ export default interface NetworkProvider {
|
|
|
63
89
|
/**
|
|
64
90
|
* Retrieve a verbose coin-specific response transaction details for a given transaction ID.
|
|
65
91
|
* @param txHash Hex of transaction hash.
|
|
92
|
+
* @param loadInputValues When true, each vin is enriched with value, address and tokenData from the parent output.
|
|
66
93
|
* @throws {Error} If the transaction does not exist
|
|
67
|
-
* @returns The
|
|
94
|
+
* @returns The decoded transaction object.
|
|
68
95
|
*/
|
|
69
|
-
getRawTransactionObject(
|
|
96
|
+
getRawTransactionObject(
|
|
97
|
+
txHash: string,
|
|
98
|
+
loadInputValues: true
|
|
99
|
+
): Promise<ElectrumRawTransactionWithInputValues>;
|
|
100
|
+
getRawTransactionObject(
|
|
101
|
+
txHash: string,
|
|
102
|
+
loadInputValues?: false
|
|
103
|
+
): Promise<ElectrumRawTransaction>;
|
|
104
|
+
getRawTransactionObject(
|
|
105
|
+
txHash: string,
|
|
106
|
+
loadInputValues?: boolean
|
|
107
|
+
): Promise<ElectrumRawTransaction | ElectrumRawTransactionWithInputValues>;
|
|
70
108
|
|
|
71
109
|
/**
|
|
72
110
|
* Broadcast a raw hex transaction to the Bitcoin Cash network.
|
package/src/network/index.ts
CHANGED
|
@@ -7,4 +7,8 @@ export {
|
|
|
7
7
|
} from "./Connection.js";
|
|
8
8
|
export { default as ElectrumNetworkProvider } from "./ElectrumNetworkProvider.js";
|
|
9
9
|
export { default as NetworkProvider } from "./NetworkProvider.js";
|
|
10
|
-
export {
|
|
10
|
+
export {
|
|
11
|
+
ElectrumRawTransaction,
|
|
12
|
+
ElectrumRawTransactionWithInputValues,
|
|
13
|
+
ElectrumRawTransactionVinWithValues,
|
|
14
|
+
} from "./interface.js";
|
package/src/network/interface.ts
CHANGED
|
@@ -54,9 +54,14 @@ export interface ElectrumRawTransactionVin {
|
|
|
54
54
|
sequence: number;
|
|
55
55
|
txid: string;
|
|
56
56
|
vout: number;
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export type ElectrumRawTransactionVinWithValues = ElectrumRawTransactionVin &
|
|
60
|
+
ElectrumRawTransactionVout;
|
|
61
|
+
|
|
62
|
+
export interface ElectrumRawTransactionWithInputValues
|
|
63
|
+
extends Omit<ElectrumRawTransaction, "vin"> {
|
|
64
|
+
vin: ElectrumRawTransactionVinWithValues[];
|
|
60
65
|
}
|
|
61
66
|
|
|
62
67
|
export interface ElectrumRawTransactionVout {
|
package/src/wallet/Base.ts
CHANGED
|
@@ -571,10 +571,7 @@ export class BaseWallet implements WalletI {
|
|
|
571
571
|
): Promise<CancelFn> {
|
|
572
572
|
return this.watchTransactions(
|
|
573
573
|
async (transaction: ElectrumRawTransaction) => {
|
|
574
|
-
if (
|
|
575
|
-
transaction.vin.some((val) => val.tokenData) ||
|
|
576
|
-
transaction.vout.some((val) => val.tokenData)
|
|
577
|
-
) {
|
|
574
|
+
if (transaction.vout.some((val) => val.tokenData)) {
|
|
578
575
|
callback(transaction);
|
|
579
576
|
}
|
|
580
577
|
}
|