@ledgerhq/live-cli 24.36.0 → 24.37.0-nightly.20260331030457
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/lib/465.js +517 -0
- package/lib/{740.js → 660.js} +19 -19
- package/lib/cli.js +288515 -292362
- package/package.json +2 -4
package/lib/465.js
ADDED
|
@@ -0,0 +1,517 @@
|
|
|
1
|
+
const __rslib_import_meta_url__ = /*#__PURE__*/ (function () {
|
|
2
|
+
return typeof document === 'undefined'
|
|
3
|
+
? new (require('url'.replace('', '')).URL)('file:' + __filename).href
|
|
4
|
+
: (document.currentScript && document.currentScript.src) ||
|
|
5
|
+
new URL('main.js', document.baseURI).href;
|
|
6
|
+
})();
|
|
7
|
+
exports.ids = ["465"];
|
|
8
|
+
exports.modules = {
|
|
9
|
+
"../../node_modules/.pnpm/@ledgerhq+zcash-decrypt@0.2.0/node_modules/@ledgerhq/zcash-decrypt/pkg/zcash_decrypt.js"(__unused_rspack_module, exports, __webpack_require__) {
|
|
10
|
+
/* @ts-self-types="./zcash_decrypt.d.ts" */
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @param {string} tx_hex
|
|
14
|
+
* @param {string} viewing_key
|
|
15
|
+
* @returns {any}
|
|
16
|
+
*/
|
|
17
|
+
function decrypt_tx(tx_hex, viewing_key) {
|
|
18
|
+
const ptr0 = passStringToWasm0(tx_hex, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
19
|
+
const len0 = WASM_VECTOR_LEN;
|
|
20
|
+
const ptr1 = passStringToWasm0(viewing_key, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
21
|
+
const len1 = WASM_VECTOR_LEN;
|
|
22
|
+
const ret = wasm.decrypt_tx(ptr0, len0, ptr1, len1);
|
|
23
|
+
if (ret[2]) {
|
|
24
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
25
|
+
}
|
|
26
|
+
return takeFromExternrefTable0(ret[0]);
|
|
27
|
+
}
|
|
28
|
+
exports.decrypt_tx = decrypt_tx;
|
|
29
|
+
|
|
30
|
+
function __wbg_get_imports() {
|
|
31
|
+
const import0 = {
|
|
32
|
+
__proto__: null,
|
|
33
|
+
__wbg_Error_8c4e43fe74559d73: function(arg0, arg1) {
|
|
34
|
+
const ret = Error(getStringFromWasm0(arg0, arg1));
|
|
35
|
+
return ret;
|
|
36
|
+
},
|
|
37
|
+
__wbg___wbindgen_throw_be289d5034ed271b: function(arg0, arg1) {
|
|
38
|
+
throw new Error(getStringFromWasm0(arg0, arg1));
|
|
39
|
+
},
|
|
40
|
+
__wbg_new_361308b2356cecd0: function() {
|
|
41
|
+
const ret = new Object();
|
|
42
|
+
return ret;
|
|
43
|
+
},
|
|
44
|
+
__wbg_new_3eb36ae241fe6f44: function() {
|
|
45
|
+
const ret = new Array();
|
|
46
|
+
return ret;
|
|
47
|
+
},
|
|
48
|
+
__wbg_set_3f1d0b984ed272ed: function(arg0, arg1, arg2) {
|
|
49
|
+
arg0[arg1] = arg2;
|
|
50
|
+
},
|
|
51
|
+
__wbg_set_f43e577aea94465b: function(arg0, arg1, arg2) {
|
|
52
|
+
arg0[arg1 >>> 0] = arg2;
|
|
53
|
+
},
|
|
54
|
+
__wbindgen_cast_0000000000000001: function(arg0) {
|
|
55
|
+
// Cast intrinsic for `F64 -> Externref`.
|
|
56
|
+
const ret = arg0;
|
|
57
|
+
return ret;
|
|
58
|
+
},
|
|
59
|
+
__wbindgen_cast_0000000000000002: function(arg0, arg1) {
|
|
60
|
+
// Cast intrinsic for `Ref(String) -> Externref`.
|
|
61
|
+
const ret = getStringFromWasm0(arg0, arg1);
|
|
62
|
+
return ret;
|
|
63
|
+
},
|
|
64
|
+
__wbindgen_cast_0000000000000003: function(arg0) {
|
|
65
|
+
// Cast intrinsic for `U64 -> Externref`.
|
|
66
|
+
const ret = BigInt.asUintN(64, arg0);
|
|
67
|
+
return ret;
|
|
68
|
+
},
|
|
69
|
+
__wbindgen_init_externref_table: function() {
|
|
70
|
+
const table = wasm.__wbindgen_externrefs;
|
|
71
|
+
const offset = table.grow(4);
|
|
72
|
+
table.set(0, undefined);
|
|
73
|
+
table.set(offset + 0, undefined);
|
|
74
|
+
table.set(offset + 1, null);
|
|
75
|
+
table.set(offset + 2, true);
|
|
76
|
+
table.set(offset + 3, false);
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
return {
|
|
80
|
+
__proto__: null,
|
|
81
|
+
"./zcash_decrypt_bg.js": import0,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function getStringFromWasm0(ptr, len) {
|
|
86
|
+
ptr = ptr >>> 0;
|
|
87
|
+
return decodeText(ptr, len);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
let cachedUint8ArrayMemory0 = null;
|
|
91
|
+
function getUint8ArrayMemory0() {
|
|
92
|
+
if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) {
|
|
93
|
+
cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer);
|
|
94
|
+
}
|
|
95
|
+
return cachedUint8ArrayMemory0;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function passStringToWasm0(arg, malloc, realloc) {
|
|
99
|
+
if (realloc === undefined) {
|
|
100
|
+
const buf = cachedTextEncoder.encode(arg);
|
|
101
|
+
const ptr = malloc(buf.length, 1) >>> 0;
|
|
102
|
+
getUint8ArrayMemory0().subarray(ptr, ptr + buf.length).set(buf);
|
|
103
|
+
WASM_VECTOR_LEN = buf.length;
|
|
104
|
+
return ptr;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
let len = arg.length;
|
|
108
|
+
let ptr = malloc(len, 1) >>> 0;
|
|
109
|
+
|
|
110
|
+
const mem = getUint8ArrayMemory0();
|
|
111
|
+
|
|
112
|
+
let offset = 0;
|
|
113
|
+
|
|
114
|
+
for (; offset < len; offset++) {
|
|
115
|
+
const code = arg.charCodeAt(offset);
|
|
116
|
+
if (code > 0x7F) break;
|
|
117
|
+
mem[ptr + offset] = code;
|
|
118
|
+
}
|
|
119
|
+
if (offset !== len) {
|
|
120
|
+
if (offset !== 0) {
|
|
121
|
+
arg = arg.slice(offset);
|
|
122
|
+
}
|
|
123
|
+
ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0;
|
|
124
|
+
const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len);
|
|
125
|
+
const ret = cachedTextEncoder.encodeInto(arg, view);
|
|
126
|
+
|
|
127
|
+
offset += ret.written;
|
|
128
|
+
ptr = realloc(ptr, len, offset, 1) >>> 0;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
WASM_VECTOR_LEN = offset;
|
|
132
|
+
return ptr;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function takeFromExternrefTable0(idx) {
|
|
136
|
+
const value = wasm.__wbindgen_externrefs.get(idx);
|
|
137
|
+
wasm.__externref_table_dealloc(idx);
|
|
138
|
+
return value;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
|
|
142
|
+
cachedTextDecoder.decode();
|
|
143
|
+
function decodeText(ptr, len) {
|
|
144
|
+
return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const cachedTextEncoder = new TextEncoder();
|
|
148
|
+
|
|
149
|
+
if (!('encodeInto' in cachedTextEncoder)) {
|
|
150
|
+
cachedTextEncoder.encodeInto = function (arg, view) {
|
|
151
|
+
const buf = cachedTextEncoder.encode(arg);
|
|
152
|
+
view.set(buf);
|
|
153
|
+
return {
|
|
154
|
+
read: arg.length,
|
|
155
|
+
written: buf.length
|
|
156
|
+
};
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
let WASM_VECTOR_LEN = 0;
|
|
161
|
+
|
|
162
|
+
const wasmPath = `${__dirname}/zcash_decrypt_bg.wasm`;
|
|
163
|
+
const wasmBytes = (__webpack_require__("fs")/* .readFileSync */.readFileSync)(wasmPath);
|
|
164
|
+
const wasmModule = new WebAssembly.Module(wasmBytes);
|
|
165
|
+
const wasm = new WebAssembly.Instance(wasmModule, __wbg_get_imports()).exports;
|
|
166
|
+
wasm.__wbindgen_start();
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
},
|
|
170
|
+
"../../libs/coin-modules/zcash-shielded/lib-es/ZCash.js"(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
171
|
+
"use strict";
|
|
172
|
+
// ESM COMPAT FLAG
|
|
173
|
+
__webpack_require__.r(__webpack_exports__);
|
|
174
|
+
|
|
175
|
+
// EXPORTS
|
|
176
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
177
|
+
ZCASH_JSON_RPC_SERVER_MAINNET: () => (/* reexport */ ZCASH_JSON_RPC_SERVER_MAINNET),
|
|
178
|
+
ZCASH_JSON_RPC_SERVER_TESTNET: () => (/* reexport */ ZCASH_JSON_RPC_SERVER_TESTNET),
|
|
179
|
+
ZCash: () => (/* binding */ ZCash)
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
// EXTERNAL MODULE: ../../libs/ledgerjs/packages/logs/lib-es/index.js
|
|
183
|
+
var lib_es = __webpack_require__("../../libs/ledgerjs/packages/logs/lib-es/index.js");
|
|
184
|
+
// EXTERNAL MODULE: ../../node_modules/.pnpm/@ledgerhq+zcash-decrypt@0.2.0/node_modules/@ledgerhq/zcash-decrypt/pkg/zcash_decrypt.js
|
|
185
|
+
var zcash_decrypt = __webpack_require__("../../node_modules/.pnpm/@ledgerhq+zcash-decrypt@0.2.0/node_modules/@ledgerhq/zcash-decrypt/pkg/zcash_decrypt.js");
|
|
186
|
+
// EXTERNAL MODULE: ../../libs/live-network/lib-es/index.js
|
|
187
|
+
var live_network_lib_es = __webpack_require__("../../libs/live-network/lib-es/index.js");
|
|
188
|
+
// EXTERNAL MODULE: ../../node_modules/.pnpm/bignumber.js@9.1.2/node_modules/bignumber.js/bignumber.mjs
|
|
189
|
+
var bignumber = __webpack_require__("../../node_modules/.pnpm/bignumber.js@9.1.2/node_modules/bignumber.js/bignumber.mjs");
|
|
190
|
+
;// CONCATENATED MODULE: ../../libs/coin-modules/zcash-shielded/lib-es/constants.js
|
|
191
|
+
|
|
192
|
+
const ZCASH_LOG_TYPE = "zcash-shielded";
|
|
193
|
+
const ZCASH_JSON_RPC_SERVER_TESTNET = "https://explorers.api.vault.ledger-test.com/nodes/zec_testnet/zaino/jsonrpc";
|
|
194
|
+
const ZCASH_JSON_RPC_SERVER_MAINNET = "https://explorers.api.vault.ledger-test.com/nodes/zec_testnet/zaino/jsonrpc";
|
|
195
|
+
const ZCASH_ACTIVATION_DATE = new Date("2016-10-28");
|
|
196
|
+
const ZCASH_ACTIVATION_DATE_STRING = "2016-10-28";
|
|
197
|
+
const ZCASH_OUTDATED_SYNC_INTERVAL_MINUTES = 2;
|
|
198
|
+
const DEFAULT_ZCASH_PRIVATE_INFO = {
|
|
199
|
+
orchardBalance: new bignumber/* .BigNumber */.g(0),
|
|
200
|
+
saplingBalance: new bignumber/* .BigNumber */.g(0),
|
|
201
|
+
ufvk: null,
|
|
202
|
+
syncState: "disabled",
|
|
203
|
+
birthday: ZCASH_ACTIVATION_DATE_STRING,
|
|
204
|
+
lastSyncTimestamp: null,
|
|
205
|
+
lastBlockProcessed: null,
|
|
206
|
+
transactions: []
|
|
207
|
+
}; //# sourceMappingURL=constants.js.map
|
|
208
|
+
|
|
209
|
+
;// CONCATENATED MODULE: ../../libs/coin-modules/zcash-shielded/lib-es/jsonRpcClient.js
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
class JsonRpcClient {
|
|
214
|
+
serverUrl;
|
|
215
|
+
constructor(serverUrl){
|
|
216
|
+
this.serverUrl = serverUrl;
|
|
217
|
+
}
|
|
218
|
+
async _jsonRpcRequest(args) {
|
|
219
|
+
let data;
|
|
220
|
+
try {
|
|
221
|
+
const response = await (0,live_network_lib_es/* ["default"] */.A)({
|
|
222
|
+
url: this.serverUrl,
|
|
223
|
+
method: "POST",
|
|
224
|
+
data: {
|
|
225
|
+
jsonrpc: "2.0",
|
|
226
|
+
...args,
|
|
227
|
+
id: 1
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
data = response.data;
|
|
231
|
+
} catch (err) {
|
|
232
|
+
(0,lib_es/* .log */.Rm)(ZCASH_LOG_TYPE, "error: Network error");
|
|
233
|
+
throw err;
|
|
234
|
+
}
|
|
235
|
+
if ("error" in data) {
|
|
236
|
+
const message = data.error.message ?? "unknown error";
|
|
237
|
+
(0,lib_es/* .log */.Rm)(ZCASH_LOG_TYPE, `error: Zcash RPC ${args.method} failed - ${message}`);
|
|
238
|
+
} else if (data.result === undefined || data.result === null) {
|
|
239
|
+
(0,lib_es/* .log */.Rm)(ZCASH_LOG_TYPE, `error: Zcash RPC ${args.method} returned no result`);
|
|
240
|
+
} else {
|
|
241
|
+
return data.result;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
getBlock(blockHashOrHeight) {
|
|
245
|
+
return this._jsonRpcRequest({
|
|
246
|
+
method: "getblock",
|
|
247
|
+
params: [
|
|
248
|
+
blockHashOrHeight,
|
|
249
|
+
1
|
|
250
|
+
]
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
async getBlockCount() {
|
|
254
|
+
const result = await this._jsonRpcRequest({
|
|
255
|
+
method: "getblockcount",
|
|
256
|
+
params: []
|
|
257
|
+
});
|
|
258
|
+
if (result === undefined) {
|
|
259
|
+
return undefined;
|
|
260
|
+
}
|
|
261
|
+
if (typeof result !== "number") {
|
|
262
|
+
(0,lib_es/* .log */.Rm)(ZCASH_LOG_TYPE, "error: Zcash RPC getblockcount returned non-numeric result");
|
|
263
|
+
return undefined;
|
|
264
|
+
}
|
|
265
|
+
return result;
|
|
266
|
+
}
|
|
267
|
+
getRawTransaction(txId) {
|
|
268
|
+
return this._jsonRpcRequest({
|
|
269
|
+
method: "getrawtransaction",
|
|
270
|
+
params: [
|
|
271
|
+
txId,
|
|
272
|
+
1
|
|
273
|
+
]
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
} //# sourceMappingURL=jsonRpcClient.js.map
|
|
277
|
+
|
|
278
|
+
;// CONCATENATED MODULE: ../../libs/coin-modules/zcash-shielded/lib-es/shieldedTransaction.js
|
|
279
|
+
|
|
280
|
+
const toShieldedTransaction = (tx, decryptedTx)=>({
|
|
281
|
+
id: tx.txid,
|
|
282
|
+
hex: tx.hex,
|
|
283
|
+
blockHash: tx.blockhash,
|
|
284
|
+
blockHeight: tx.height,
|
|
285
|
+
timestamp: tx.time,
|
|
286
|
+
fee: new bignumber/* .BigNumber */.g(tx.orchard.valueBalanceZat),
|
|
287
|
+
decryptedData: {
|
|
288
|
+
orchard_outputs: decryptedTx.orchard_outputs.map((output)=>({
|
|
289
|
+
...output,
|
|
290
|
+
amount: new bignumber/* .BigNumber */.g(output.amount)
|
|
291
|
+
})),
|
|
292
|
+
sapling_outputs: decryptedTx.sapling_outputs.map((output)=>({
|
|
293
|
+
...output,
|
|
294
|
+
amount: new bignumber/* .BigNumber */.g(output.amount)
|
|
295
|
+
}))
|
|
296
|
+
}
|
|
297
|
+
}); //# sourceMappingURL=shieldedTransaction.js.map
|
|
298
|
+
|
|
299
|
+
// EXTERNAL MODULE: ../../node_modules/.pnpm/rxjs@7.8.2/node_modules/rxjs/dist/cjs/index.js
|
|
300
|
+
var cjs = __webpack_require__("../../node_modules/.pnpm/rxjs@7.8.2/node_modules/rxjs/dist/cjs/index.js");
|
|
301
|
+
;// CONCATENATED MODULE: ../../libs/coin-modules/zcash-shielded/lib-es/ZCash.js
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* ZCash API
|
|
310
|
+
*/
|
|
311
|
+
class ZCash {
|
|
312
|
+
jsonRpcClient;
|
|
313
|
+
constructor(args){
|
|
314
|
+
this.jsonRpcClient = new JsonRpcClient(args.nodeUrl);
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Estimates sync time given a total number of blocks to process.
|
|
318
|
+
* This is a curried function that returns a function that returns the estimated sync time.
|
|
319
|
+
* It should be called when processing a block (passing the total number of blocks to process)
|
|
320
|
+
* and then called again when processing the next block.
|
|
321
|
+
* The function will return the estimated sync time in hours and minutes.
|
|
322
|
+
*
|
|
323
|
+
* @param totalBlocks total blocks to process
|
|
324
|
+
* @return an object with the estimated sync time in hours and minutes
|
|
325
|
+
*/ async estimatedSyncTime(totalBlocks) {
|
|
326
|
+
const start = Date.now();
|
|
327
|
+
let end = null;
|
|
328
|
+
return ()=>{
|
|
329
|
+
end = Date.now();
|
|
330
|
+
const totalSeconds = (end - start) / 1000 * totalBlocks;
|
|
331
|
+
const totalMinutes = Math.floor(totalSeconds / 60);
|
|
332
|
+
const hours = Math.floor(totalMinutes / 60);
|
|
333
|
+
const minutes = totalMinutes % 60;
|
|
334
|
+
return {
|
|
335
|
+
hours,
|
|
336
|
+
minutes
|
|
337
|
+
};
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Scans a block for shielded transactions matching the given viewing key.
|
|
342
|
+
*
|
|
343
|
+
* @param {{
|
|
344
|
+
* block: Block,
|
|
345
|
+
* viewingKey: string
|
|
346
|
+
* }} args, Block and the UFVK - unified full viewing key.
|
|
347
|
+
* @returns {ShieldedTransaction[]} list of shielded transactions
|
|
348
|
+
*/ async findShieldedTxsInBlock(args) {
|
|
349
|
+
const { block, viewingKey } = args;
|
|
350
|
+
// 1. get list of tx
|
|
351
|
+
const transactions = block?.tx;
|
|
352
|
+
const decryptedTransactions = [];
|
|
353
|
+
// 2. retrieve each tx hash
|
|
354
|
+
if (transactions) {
|
|
355
|
+
for (const txId of transactions){
|
|
356
|
+
if (!txId) {
|
|
357
|
+
continue;
|
|
358
|
+
}
|
|
359
|
+
const tx = await this.jsonRpcClient.getRawTransaction(txId);
|
|
360
|
+
// 3. call decryptTransaction for each tx hash containing orchard actions
|
|
361
|
+
if (tx?.orchard.actions.length) {
|
|
362
|
+
const decryptedTx = await this.decryptTransaction(tx, viewingKey);
|
|
363
|
+
if (decryptedTx) {
|
|
364
|
+
decryptedTransactions.push(decryptedTx);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
// 4. return list of transaction for the given viewingKey
|
|
370
|
+
return decryptedTransactions;
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* Decrypts a ZCash shielded - i.e., encrypted - transaction.
|
|
374
|
+
*
|
|
375
|
+
* @param {RawTransaction} rawTransaction, raw data representing an encrypted transaction.
|
|
376
|
+
* @param {string} viewingKey the UFVK - unified full viewing key.
|
|
377
|
+
* @return {Promise<ShieldedTransaction | undefined>} the decrypted shielded transaction.
|
|
378
|
+
*/ async decryptTransaction(rawTransaction, viewingKey) {
|
|
379
|
+
try {
|
|
380
|
+
const decryptedTx = (0,zcash_decrypt.decrypt_tx)(rawTransaction.hex, viewingKey);
|
|
381
|
+
return toShieldedTransaction(rawTransaction, decryptedTx);
|
|
382
|
+
} catch (error) {
|
|
383
|
+
(0,lib_es/* .log */.Rm)(ZCASH_LOG_TYPE, "error: failed to decrypt transaction", error);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Finds the lowest block height correspondent to a given timestamp.
|
|
388
|
+
*
|
|
389
|
+
* @param {number} timestamp
|
|
390
|
+
* @returns {Promise<number>} a block height
|
|
391
|
+
*/ async findBlockHeight(timestamp) {
|
|
392
|
+
if (timestamp < 0 || !Number.isFinite(timestamp)) {
|
|
393
|
+
(0,lib_es/* .log */.Rm)(ZCASH_LOG_TYPE, `error: findBlockHeight invalid timestamp: ${timestamp}`);
|
|
394
|
+
return undefined;
|
|
395
|
+
}
|
|
396
|
+
const maxHeight = await this.jsonRpcClient.getBlockCount();
|
|
397
|
+
if (maxHeight === undefined) {
|
|
398
|
+
(0,lib_es/* .log */.Rm)(ZCASH_LOG_TYPE, "error: findBlockHeight failed to fetch block count from RPC node (getBlockCount returned undefined).");
|
|
399
|
+
return;
|
|
400
|
+
}
|
|
401
|
+
if (maxHeight <= 0) {
|
|
402
|
+
return 0;
|
|
403
|
+
}
|
|
404
|
+
let low = 0;
|
|
405
|
+
let high = maxHeight;
|
|
406
|
+
let candidate = 0;
|
|
407
|
+
while(low <= high){
|
|
408
|
+
const mid = Math.floor((low + high) / 2);
|
|
409
|
+
const block = await this.jsonRpcClient.getBlock(mid.toString());
|
|
410
|
+
if (!block) {
|
|
411
|
+
(0,lib_es/* .log */.Rm)(ZCASH_LOG_TYPE, `Block ${mid} not found.`);
|
|
412
|
+
return;
|
|
413
|
+
}
|
|
414
|
+
if (block.time <= timestamp) {
|
|
415
|
+
candidate = mid;
|
|
416
|
+
low = mid + 1;
|
|
417
|
+
} else {
|
|
418
|
+
high = mid - 1;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
return candidate;
|
|
422
|
+
}
|
|
423
|
+
/**
|
|
424
|
+
* Parses the blocks in the provided range and, after each iteration,
|
|
425
|
+
* it returns a synced shielded context including aggregate information
|
|
426
|
+
* like the shielded transactions and processing progress.
|
|
427
|
+
*
|
|
428
|
+
* ### Stop the iterator
|
|
429
|
+
* The sync operation can be gracefully stopped by calling unsubscribe on the
|
|
430
|
+
* observable subscription.
|
|
431
|
+
*
|
|
432
|
+
* @param {{
|
|
433
|
+
* startBlockHeight: number
|
|
434
|
+
* viewingKey: string
|
|
435
|
+
* maxBatchSize: number
|
|
436
|
+
* }} args, Block, the UFVK - unified full viewing key, and max batch size.
|
|
437
|
+
* @returns {Observable<ShieldedSyncResult>} the current synced shielded context.
|
|
438
|
+
*/ syncShielded(args) {
|
|
439
|
+
return new cjs.Observable((subscriber)=>{
|
|
440
|
+
this._syncShieldedObsFunc(args)(subscriber).then(()=>subscriber.complete(), (error)=>subscriber.error(error));
|
|
441
|
+
});
|
|
442
|
+
}
|
|
443
|
+
_syncShieldedObsFunc(args) {
|
|
444
|
+
return async (subscriber)=>{
|
|
445
|
+
const { startBlockHeight, viewingKey, maxBatchSize } = args;
|
|
446
|
+
const syncedShielded = {
|
|
447
|
+
processedBlocks: 0,
|
|
448
|
+
remainingBlocks: 0,
|
|
449
|
+
transactions: []
|
|
450
|
+
};
|
|
451
|
+
// 0. validate args
|
|
452
|
+
if (startBlockHeight < 0) {
|
|
453
|
+
(0,lib_es/* .log */.Rm)(ZCASH_LOG_TYPE, "error: invalid negative arg startBlockHeight");
|
|
454
|
+
subscriber.error("error: invalid negative arg startBlockHeight");
|
|
455
|
+
return;
|
|
456
|
+
}
|
|
457
|
+
if (maxBatchSize <= 0) {
|
|
458
|
+
(0,lib_es/* .log */.Rm)(ZCASH_LOG_TYPE, "error: invalid negative or zero arg maxBatchSize");
|
|
459
|
+
subscriber.error("error: invalid negative or zero arg maxBatchSize");
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
462
|
+
// 1. get end block height before the start of the cycle
|
|
463
|
+
let endBlockHeight = await this.jsonRpcClient.getBlockCount();
|
|
464
|
+
if (endBlockHeight === undefined) {
|
|
465
|
+
(0,lib_es/* .log */.Rm)(ZCASH_LOG_TYPE, "error: could not retrieve the last block");
|
|
466
|
+
subscriber.error("error: could not retrieve the last block");
|
|
467
|
+
return;
|
|
468
|
+
}
|
|
469
|
+
for(let blockHeight = startBlockHeight; blockHeight <= endBlockHeight; blockHeight++){
|
|
470
|
+
if (subscriber.closed) {
|
|
471
|
+
break;
|
|
472
|
+
}
|
|
473
|
+
// 2. on the last iteration, update the end block height and process until the end
|
|
474
|
+
if (blockHeight === endBlockHeight) {
|
|
475
|
+
endBlockHeight = await this.jsonRpcClient.getBlockCount();
|
|
476
|
+
if (endBlockHeight === undefined) {
|
|
477
|
+
(0,lib_es/* .log */.Rm)(ZCASH_LOG_TYPE, "error: could not retrieve the last block");
|
|
478
|
+
subscriber.error("error: could not retrieve the last block");
|
|
479
|
+
break;
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
// 3. get current block
|
|
483
|
+
const block = await this.jsonRpcClient.getBlock(blockHeight.toString());
|
|
484
|
+
if (!block) {
|
|
485
|
+
(0,lib_es/* .log */.Rm)(ZCASH_LOG_TYPE, `error: invalid block height ${blockHeight}`);
|
|
486
|
+
break;
|
|
487
|
+
}
|
|
488
|
+
// 4. find shielded tx in block
|
|
489
|
+
const shieldedTxs = await this.findShieldedTxsInBlock({
|
|
490
|
+
block,
|
|
491
|
+
viewingKey
|
|
492
|
+
});
|
|
493
|
+
// 5. update syncedShielded's context: list of shielded transactions and counters
|
|
494
|
+
syncedShielded.transactions.push(...shieldedTxs);
|
|
495
|
+
syncedShielded.processedBlocks++;
|
|
496
|
+
syncedShielded.remainingBlocks = endBlockHeight - blockHeight;
|
|
497
|
+
syncedShielded.lastProcessedBlock = block.height;
|
|
498
|
+
if (!(syncedShielded.processedBlocks % maxBatchSize) || blockHeight === endBlockHeight) {
|
|
499
|
+
subscriber.next({
|
|
500
|
+
...syncedShielded,
|
|
501
|
+
transactions: [
|
|
502
|
+
...syncedShielded.transactions
|
|
503
|
+
]
|
|
504
|
+
});
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
subscriber.complete();
|
|
508
|
+
return;
|
|
509
|
+
};
|
|
510
|
+
}
|
|
511
|
+
} //# sourceMappingURL=ZCash.js.map
|
|
512
|
+
|
|
513
|
+
|
|
514
|
+
},
|
|
515
|
+
|
|
516
|
+
};
|
|
517
|
+
;
|