@ledgerhq/coin-framework 0.3.5 → 0.3.6-next.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/.eslintrc.js +8 -46
- package/CHANGELOG.md +13 -0
- package/package.json +9 -18
- package/src/account/accountId.ts +20 -30
- package/src/account/accountName.ts +1 -4
- package/src/account/balanceHistoryCache.ts +18 -37
- package/src/account/groupOperations.ts +4 -6
- package/src/account/helpers.test.ts +6 -26
- package/src/account/helpers.ts +33 -66
- package/src/account/ordering.ts +10 -18
- package/src/account/pending.ts +6 -15
- package/src/account/serialization.ts +8 -19
- package/src/account/support.ts +8 -18
- package/src/account.test.ts +25 -40
- package/src/bot/specs.ts +24 -43
- package/src/bot/types.ts +1 -1
- package/src/bridge/getAddressWrapper.ts +5 -13
- package/src/bridge/jsHelpers.ts +215 -259
- package/src/cache.ts +4 -4
- package/src/currencies/BigNumberToLocaleString.test.ts +25 -33
- package/src/currencies/BigNumberToLocaleString.ts +3 -8
- package/src/currencies/CurrencyURIScheme.ts +1 -3
- package/src/currencies/chopCurrencyUnitDecimals.ts +1 -4
- package/src/currencies/formatCurrencyUnit.ts +11 -21
- package/src/currencies/index.ts +1 -4
- package/src/currencies/localeUtility.ts +2 -4
- package/src/currencies/parseCurrencyUnit.ts +1 -4
- package/src/currencies/sanitizeValueString.ts +1 -1
- package/src/currencies/support.ts +3 -9
- package/src/derivation.test.ts +1 -4
- package/src/derivation.ts +45 -95
- package/src/errors.test.ts +1 -1
- package/src/errors.ts +2 -6
- package/src/mocks/account.ts +27 -80
- package/src/mocks/fixtures/nfts.test.ts +2 -6
- package/src/mocks/fixtures/nfts.ts +12 -38
- package/src/mocks/helpers.ts +2 -8
- package/src/nft/nftId.ts +2 -2
- package/src/operation.test.ts +6 -31
- package/src/operation.ts +12 -26
- package/src/transaction/common.ts +9 -22
package/src/bridge/jsHelpers.ts
CHANGED
|
@@ -82,13 +82,12 @@ export type AccountShapeInfo = {
|
|
|
82
82
|
|
|
83
83
|
export type GetAccountShape = (
|
|
84
84
|
arg0: AccountShapeInfo,
|
|
85
|
-
arg1: SyncConfig
|
|
85
|
+
arg1: SyncConfig,
|
|
86
86
|
) => Promise<Partial<Account>>;
|
|
87
87
|
type AccountUpdater = (arg0: Account) => Account;
|
|
88
88
|
|
|
89
89
|
// compare that two dates are roughly the same date in order to update the case it would have drastically changed
|
|
90
|
-
const sameDate = (a: Date, b: Date) =>
|
|
91
|
-
Math.abs(a.getTime() - b.getTime()) < 1000 * 60 * 30;
|
|
90
|
+
const sameDate = (a: Date, b: Date) => Math.abs(a.getTime() - b.getTime()) < 1000 * 60 * 30;
|
|
92
91
|
|
|
93
92
|
// an operation is relatively immutable, however we saw that sometimes it can temporarily change due to reorg,..
|
|
94
93
|
export const sameOp = (a: Operation, b: Operation): boolean =>
|
|
@@ -104,7 +103,7 @@ export const sameOp = (a: Operation, b: Operation): boolean =>
|
|
|
104
103
|
// efficiently prepend newFetched operations to existing operations
|
|
105
104
|
export function mergeOps( // existing operations. sorted (newer to older). deduped.
|
|
106
105
|
existing: Operation[], // new fetched operations. not sorted. not deduped. time is allowed to overlap inside existing.
|
|
107
|
-
newFetched: Operation[]
|
|
106
|
+
newFetched: Operation[],
|
|
108
107
|
): // return a list of operations, deduped and sorted from newer to older
|
|
109
108
|
Operation[] {
|
|
110
109
|
// there is new fetched
|
|
@@ -118,12 +117,12 @@ Operation[] {
|
|
|
118
117
|
|
|
119
118
|
// only keep the newFetched that are not in existing. this array will be mutated
|
|
120
119
|
let newOps = newFetched
|
|
121
|
-
.filter(
|
|
120
|
+
.filter(o => !existingIds[o.id] || !sameOp(existingIds[o.id], o))
|
|
122
121
|
.sort((a, b) => b.date.valueOf() - a.date.valueOf());
|
|
123
122
|
|
|
124
123
|
// Deduplicate new ops to guarantee operations don't have dups
|
|
125
124
|
const newOpsIds: Record<string, Operation> = {};
|
|
126
|
-
newOps.forEach(
|
|
125
|
+
newOps.forEach(op => {
|
|
127
126
|
newOpsIds[op.id] = op;
|
|
128
127
|
});
|
|
129
128
|
newOps = Object.values(newOpsIds);
|
|
@@ -149,13 +148,10 @@ Operation[] {
|
|
|
149
148
|
return all;
|
|
150
149
|
}
|
|
151
150
|
|
|
152
|
-
export const mergeNfts = (
|
|
153
|
-
oldNfts: ProtoNFT[],
|
|
154
|
-
newNfts: ProtoNFT[]
|
|
155
|
-
): ProtoNFT[] => {
|
|
151
|
+
export const mergeNfts = (oldNfts: ProtoNFT[], newNfts: ProtoNFT[]): ProtoNFT[] => {
|
|
156
152
|
// Getting a map of id => NFT
|
|
157
153
|
const newNftsPerId: Record<string, ProtoNFT> = {};
|
|
158
|
-
newNfts.forEach(
|
|
154
|
+
newNfts.forEach(n => {
|
|
159
155
|
newNftsPerId[n.id] = n;
|
|
160
156
|
});
|
|
161
157
|
|
|
@@ -206,7 +202,7 @@ export const makeSync =
|
|
|
206
202
|
try {
|
|
207
203
|
const freshAddressPath = getSeedIdentifierDerivation(
|
|
208
204
|
initial.currency,
|
|
209
|
-
initial.derivationMode as DerivationMode
|
|
205
|
+
initial.derivationMode as DerivationMode,
|
|
210
206
|
);
|
|
211
207
|
|
|
212
208
|
const shape = await getAccountShape(
|
|
@@ -218,7 +214,7 @@ export const makeSync =
|
|
|
218
214
|
derivationMode: initial.derivationMode as DerivationMode,
|
|
219
215
|
initialAccount: needClear ? clearAccount(initial) : initial,
|
|
220
216
|
},
|
|
221
|
-
syncConfig
|
|
217
|
+
syncConfig,
|
|
222
218
|
);
|
|
223
219
|
|
|
224
220
|
const updater = (acc: Account): Account => {
|
|
@@ -240,13 +236,11 @@ export const makeSync =
|
|
|
240
236
|
operationsCount: shape.operationsCount || operations.length,
|
|
241
237
|
lastSyncDate: new Date(),
|
|
242
238
|
creationDate:
|
|
243
|
-
operations.length > 0
|
|
244
|
-
? operations[operations.length - 1].date
|
|
245
|
-
: new Date(),
|
|
239
|
+
operations.length > 0 ? operations[operations.length - 1].date : new Date(),
|
|
246
240
|
...shape,
|
|
247
241
|
operations,
|
|
248
|
-
pendingOperations: a.pendingOperations.filter(
|
|
249
|
-
shouldRetainPendingOperation(a, op)
|
|
242
|
+
pendingOperations: a.pendingOperations.filter(op =>
|
|
243
|
+
shouldRetainPendingOperation(a, op),
|
|
250
244
|
),
|
|
251
245
|
});
|
|
252
246
|
|
|
@@ -271,7 +265,7 @@ export const makeSync =
|
|
|
271
265
|
|
|
272
266
|
// Use for withDevice
|
|
273
267
|
export type DeviceCommunication = (
|
|
274
|
-
deviceId: string
|
|
268
|
+
deviceId: string,
|
|
275
269
|
) => <T>(job: (transport: Transport) => Observable<T>) => Observable<T>;
|
|
276
270
|
|
|
277
271
|
const defaultIterateResultBuilder = (getAddressFn: Resolver) => () =>
|
|
@@ -304,7 +298,7 @@ const defaultIterateResultBuilder = (getAddressFn: Resolver) => () =>
|
|
|
304
298
|
derivationsCache[freshAddressPath] = res;
|
|
305
299
|
}
|
|
306
300
|
return res as Result;
|
|
307
|
-
}
|
|
301
|
+
},
|
|
308
302
|
);
|
|
309
303
|
|
|
310
304
|
export const makeScanAccounts =
|
|
@@ -320,266 +314,235 @@ export const makeScanAccounts =
|
|
|
320
314
|
getAddressFn: Resolver;
|
|
321
315
|
}): CurrencyBridge["scanAccounts"] =>
|
|
322
316
|
({ currency, deviceId, syncConfig }): Observable<ScanAccountEvent> =>
|
|
323
|
-
deviceCommunication(deviceId)(
|
|
324
|
-
Observable.create(
|
|
325
|
-
|
|
326
|
-
let finished = false;
|
|
317
|
+
deviceCommunication(deviceId)(transport =>
|
|
318
|
+
Observable.create((o: Observer<{ type: "discovered"; account: Account }>) => {
|
|
319
|
+
let finished = false;
|
|
327
320
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
321
|
+
const unsubscribe = () => {
|
|
322
|
+
finished = true;
|
|
323
|
+
};
|
|
331
324
|
|
|
332
|
-
|
|
325
|
+
const derivationsCache: Record<string, Result> = {};
|
|
333
326
|
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
327
|
+
async function stepAccount(
|
|
328
|
+
index: number,
|
|
329
|
+
res: Result,
|
|
330
|
+
derivationMode: DerivationMode,
|
|
331
|
+
seedIdentifier: string,
|
|
332
|
+
transport: Transport,
|
|
333
|
+
): Promise<Account | null | undefined> {
|
|
334
|
+
if (finished) return;
|
|
342
335
|
|
|
343
|
-
|
|
336
|
+
const { address, path: freshAddressPath, ...rest } = res;
|
|
344
337
|
|
|
345
|
-
|
|
338
|
+
const accountShape: Partial<Account> = await getAccountShape(
|
|
339
|
+
{
|
|
340
|
+
transport,
|
|
341
|
+
currency,
|
|
342
|
+
index,
|
|
343
|
+
address,
|
|
344
|
+
derivationPath: freshAddressPath,
|
|
345
|
+
derivationMode,
|
|
346
|
+
rest,
|
|
347
|
+
},
|
|
348
|
+
syncConfig,
|
|
349
|
+
);
|
|
350
|
+
if (finished) return;
|
|
351
|
+
|
|
352
|
+
const freshAddress = address;
|
|
353
|
+
const operations = accountShape.operations || [];
|
|
354
|
+
const operationsCount = accountShape.operationsCount || operations.length;
|
|
355
|
+
const creationDate =
|
|
356
|
+
operations.length > 0 ? operations[operations.length - 1].date : new Date();
|
|
357
|
+
const balance = accountShape.balance || new BigNumber(0);
|
|
358
|
+
const spendableBalance = accountShape.spendableBalance || new BigNumber(0);
|
|
359
|
+
if (!accountShape.id) throw new Error("account ID must be provided");
|
|
360
|
+
if (balance.isNaN()) throw new Error("invalid balance NaN");
|
|
361
|
+
const initialAccount: Account = {
|
|
362
|
+
type: "Account",
|
|
363
|
+
id: accountShape.id,
|
|
364
|
+
seedIdentifier,
|
|
365
|
+
freshAddress,
|
|
366
|
+
freshAddressPath,
|
|
367
|
+
freshAddresses: [
|
|
346
368
|
{
|
|
347
|
-
|
|
348
|
-
currency,
|
|
349
|
-
index,
|
|
350
|
-
address,
|
|
369
|
+
address: freshAddress,
|
|
351
370
|
derivationPath: freshAddressPath,
|
|
352
|
-
derivationMode,
|
|
353
|
-
rest,
|
|
354
371
|
},
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
seedIdentifier,
|
|
377
|
-
freshAddress,
|
|
378
|
-
freshAddressPath,
|
|
379
|
-
freshAddresses: [
|
|
380
|
-
{
|
|
381
|
-
address: freshAddress,
|
|
382
|
-
derivationPath: freshAddressPath,
|
|
383
|
-
},
|
|
384
|
-
],
|
|
385
|
-
derivationMode,
|
|
386
|
-
name: "",
|
|
387
|
-
starred: false,
|
|
388
|
-
used: false,
|
|
389
|
-
index,
|
|
390
|
-
currency,
|
|
391
|
-
operationsCount,
|
|
392
|
-
operations: [],
|
|
393
|
-
swapHistory: [],
|
|
394
|
-
pendingOperations: [],
|
|
395
|
-
unit: currency.units[0],
|
|
396
|
-
lastSyncDate: new Date(),
|
|
397
|
-
creationDate,
|
|
398
|
-
// overrides
|
|
399
|
-
balance,
|
|
400
|
-
spendableBalance,
|
|
401
|
-
blockHeight: 0,
|
|
402
|
-
balanceHistoryCache: emptyHistoryCache,
|
|
403
|
-
};
|
|
404
|
-
const account = { ...initialAccount, ...accountShape };
|
|
405
|
-
|
|
406
|
-
if (account.balanceHistoryCache === emptyHistoryCache) {
|
|
407
|
-
account.balanceHistoryCache =
|
|
408
|
-
generateHistoryFromOperations(account);
|
|
409
|
-
}
|
|
372
|
+
],
|
|
373
|
+
derivationMode,
|
|
374
|
+
name: "",
|
|
375
|
+
starred: false,
|
|
376
|
+
used: false,
|
|
377
|
+
index,
|
|
378
|
+
currency,
|
|
379
|
+
operationsCount,
|
|
380
|
+
operations: [],
|
|
381
|
+
swapHistory: [],
|
|
382
|
+
pendingOperations: [],
|
|
383
|
+
unit: currency.units[0],
|
|
384
|
+
lastSyncDate: new Date(),
|
|
385
|
+
creationDate,
|
|
386
|
+
// overrides
|
|
387
|
+
balance,
|
|
388
|
+
spendableBalance,
|
|
389
|
+
blockHeight: 0,
|
|
390
|
+
balanceHistoryCache: emptyHistoryCache,
|
|
391
|
+
};
|
|
392
|
+
const account = { ...initialAccount, ...accountShape };
|
|
410
393
|
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
394
|
+
if (account.balanceHistoryCache === emptyHistoryCache) {
|
|
395
|
+
account.balanceHistoryCache = generateHistoryFromOperations(account);
|
|
396
|
+
}
|
|
414
397
|
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
398
|
+
if (!account.used) {
|
|
399
|
+
account.used = !isAccountEmpty(account);
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
// Bitcoin needs to compute the freshAddressPath itself,
|
|
403
|
+
// so we update it afterwards
|
|
404
|
+
if (account?.freshAddressPath) {
|
|
405
|
+
res.address = account.freshAddress;
|
|
406
|
+
derivationsCache[account.freshAddressPath] = res;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
log("scanAccounts", "derivationsCache", res);
|
|
421
410
|
|
|
422
|
-
|
|
411
|
+
log(
|
|
412
|
+
"scanAccounts",
|
|
413
|
+
`scanning ${currency.id} at ${freshAddressPath}: ${res.address} resulted of ${
|
|
414
|
+
account ? `Account with ${account.operations.length} txs` : "no account"
|
|
415
|
+
}`,
|
|
416
|
+
);
|
|
417
|
+
if (!account) return;
|
|
418
|
+
account.name = !account.used
|
|
419
|
+
? getNewAccountPlaceholderName({
|
|
420
|
+
currency,
|
|
421
|
+
index,
|
|
422
|
+
derivationMode,
|
|
423
|
+
})
|
|
424
|
+
: getAccountPlaceholderName({
|
|
425
|
+
currency,
|
|
426
|
+
index,
|
|
427
|
+
derivationMode,
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
const showNewAccount = shouldShowNewAccount(currency, derivationMode);
|
|
423
431
|
|
|
432
|
+
if (account.used || showNewAccount) {
|
|
424
433
|
log(
|
|
425
|
-
"
|
|
426
|
-
`
|
|
427
|
-
res.address
|
|
428
|
-
} resulted of ${
|
|
429
|
-
account
|
|
430
|
-
? `Account with ${account.operations.length} txs`
|
|
431
|
-
: "no account"
|
|
432
|
-
}`
|
|
434
|
+
"debug",
|
|
435
|
+
`Emit 'discovered' event for a new account found. AccountUsed: ${account.used} - showNewAccount: ${showNewAccount}`,
|
|
433
436
|
);
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
derivationMode,
|
|
440
|
-
})
|
|
441
|
-
: getAccountPlaceholderName({
|
|
442
|
-
currency,
|
|
443
|
-
index,
|
|
444
|
-
derivationMode,
|
|
445
|
-
});
|
|
437
|
+
o.next({
|
|
438
|
+
type: "discovered",
|
|
439
|
+
account,
|
|
440
|
+
});
|
|
441
|
+
}
|
|
446
442
|
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
derivationMode
|
|
450
|
-
);
|
|
443
|
+
return account;
|
|
444
|
+
}
|
|
451
445
|
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
`Emit 'discovered' event for a new account found. AccountUsed: ${account.used} - showNewAccount: ${showNewAccount}`
|
|
456
|
-
);
|
|
457
|
-
o.next({
|
|
458
|
-
type: "discovered",
|
|
459
|
-
account,
|
|
460
|
-
});
|
|
461
|
-
}
|
|
446
|
+
if (buildIterateResult === undefined) {
|
|
447
|
+
buildIterateResult = defaultIterateResultBuilder(getAddressFn);
|
|
448
|
+
}
|
|
462
449
|
|
|
463
|
-
|
|
464
|
-
|
|
450
|
+
async function main() {
|
|
451
|
+
try {
|
|
452
|
+
const derivationModes = getDerivationModesForCurrency(currency);
|
|
465
453
|
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
454
|
+
for (const derivationMode of derivationModes) {
|
|
455
|
+
if (finished) break;
|
|
456
|
+
const path = getSeedIdentifierDerivation(currency, derivationMode);
|
|
457
|
+
log("scanAccounts", `scanning ${currency.id} on derivationMode=${derivationMode}`);
|
|
458
|
+
let result: Result = derivationsCache[path];
|
|
469
459
|
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
460
|
+
if (!result) {
|
|
461
|
+
try {
|
|
462
|
+
result = await getAddressFn(transport, {
|
|
463
|
+
currency,
|
|
464
|
+
path,
|
|
465
|
+
derivationMode,
|
|
466
|
+
});
|
|
473
467
|
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
);
|
|
480
|
-
log(
|
|
481
|
-
"scanAccounts",
|
|
482
|
-
`scanning ${currency.id} on derivationMode=${derivationMode}`
|
|
483
|
-
);
|
|
484
|
-
let result: Result = derivationsCache[path];
|
|
485
|
-
|
|
486
|
-
if (!result) {
|
|
487
|
-
try {
|
|
488
|
-
result = await getAddressFn(transport, {
|
|
489
|
-
currency,
|
|
490
|
-
path,
|
|
491
|
-
derivationMode,
|
|
492
|
-
});
|
|
493
|
-
|
|
494
|
-
derivationsCache[path] = result;
|
|
495
|
-
} catch (e) {
|
|
496
|
-
if (e instanceof UnsupportedDerivation) {
|
|
497
|
-
log(
|
|
498
|
-
"scanAccounts",
|
|
499
|
-
"ignore derivationMode=" + derivationMode
|
|
500
|
-
);
|
|
501
|
-
continue;
|
|
502
|
-
}
|
|
503
|
-
throw e;
|
|
468
|
+
derivationsCache[path] = result;
|
|
469
|
+
} catch (e) {
|
|
470
|
+
if (e instanceof UnsupportedDerivation) {
|
|
471
|
+
log("scanAccounts", "ignore derivationMode=" + derivationMode);
|
|
472
|
+
continue;
|
|
504
473
|
}
|
|
474
|
+
throw e;
|
|
505
475
|
}
|
|
476
|
+
}
|
|
506
477
|
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
});
|
|
478
|
+
if (!result) continue;
|
|
479
|
+
const seedIdentifier = result.publicKey;
|
|
480
|
+
let emptyCount = 0;
|
|
481
|
+
const mandatoryEmptyAccountSkip = getMandatoryEmptyAccountSkip(derivationMode);
|
|
482
|
+
const derivationScheme = getDerivationScheme({
|
|
483
|
+
derivationMode,
|
|
484
|
+
currency,
|
|
485
|
+
});
|
|
516
486
|
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
: 1;
|
|
520
|
-
const startsAt = getDerivationModeStartsAt(derivationMode);
|
|
487
|
+
const stopAt = isIterableDerivationMode(derivationMode) ? 255 : 1;
|
|
488
|
+
const startsAt = getDerivationModeStartsAt(derivationMode);
|
|
521
489
|
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
490
|
+
log(
|
|
491
|
+
"debug",
|
|
492
|
+
`start scanning account process. MandatoryEmptyAccountSkip ${mandatoryEmptyAccountSkip} / StartsAt: ${startsAt} - StopAt: ${stopAt}`,
|
|
493
|
+
);
|
|
526
494
|
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
495
|
+
const iterateResult = await buildIterateResult!({
|
|
496
|
+
result,
|
|
497
|
+
derivationMode,
|
|
498
|
+
derivationScheme,
|
|
499
|
+
});
|
|
532
500
|
|
|
533
|
-
|
|
534
|
-
|
|
501
|
+
for (let index = startsAt; index < stopAt; index++) {
|
|
502
|
+
log("debug", `start to scan a new account. Index: ${index}`);
|
|
535
503
|
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
);
|
|
541
|
-
break;
|
|
542
|
-
}
|
|
504
|
+
if (finished) {
|
|
505
|
+
log("debug", `new account scanning process has been finished`);
|
|
506
|
+
break;
|
|
507
|
+
}
|
|
543
508
|
|
|
544
|
-
|
|
545
|
-
continue;
|
|
509
|
+
if (!derivationModeSupportsIndex(derivationMode, index)) continue;
|
|
546
510
|
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
511
|
+
const res = await iterateResult({
|
|
512
|
+
transport,
|
|
513
|
+
index,
|
|
514
|
+
derivationsCache,
|
|
515
|
+
derivationMode,
|
|
516
|
+
derivationScheme,
|
|
517
|
+
currency,
|
|
518
|
+
});
|
|
555
519
|
|
|
556
|
-
|
|
520
|
+
if (!res) break;
|
|
557
521
|
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
522
|
+
const account = await stepAccount(
|
|
523
|
+
index,
|
|
524
|
+
res,
|
|
525
|
+
derivationMode,
|
|
526
|
+
seedIdentifier,
|
|
527
|
+
transport,
|
|
528
|
+
);
|
|
565
529
|
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
}
|
|
530
|
+
if (account && !account.used) {
|
|
531
|
+
if (emptyCount >= mandatoryEmptyAccountSkip) break;
|
|
532
|
+
emptyCount++;
|
|
570
533
|
}
|
|
571
534
|
}
|
|
572
|
-
|
|
573
|
-
o.complete();
|
|
574
|
-
} catch (e) {
|
|
575
|
-
o.error(e);
|
|
576
535
|
}
|
|
577
|
-
}
|
|
578
536
|
|
|
579
|
-
|
|
580
|
-
|
|
537
|
+
o.complete();
|
|
538
|
+
} catch (e) {
|
|
539
|
+
o.error(e);
|
|
540
|
+
}
|
|
581
541
|
}
|
|
582
|
-
|
|
542
|
+
|
|
543
|
+
main();
|
|
544
|
+
return unsubscribe;
|
|
545
|
+
}),
|
|
583
546
|
);
|
|
584
547
|
export function makeAccountBridgeReceive(
|
|
585
548
|
getAddressFn: Resolver,
|
|
@@ -588,7 +551,7 @@ export function makeAccountBridgeReceive(
|
|
|
588
551
|
injectGetAddressParams,
|
|
589
552
|
}: {
|
|
590
553
|
injectGetAddressParams?: (account: Account) => any;
|
|
591
|
-
} = {}
|
|
554
|
+
} = {},
|
|
592
555
|
): (
|
|
593
556
|
account: Account,
|
|
594
557
|
option: {
|
|
@@ -596,7 +559,7 @@ export function makeAccountBridgeReceive(
|
|
|
596
559
|
deviceId: string;
|
|
597
560
|
subAccountId?: string;
|
|
598
561
|
freshAddressIndex?: number;
|
|
599
|
-
}
|
|
562
|
+
},
|
|
600
563
|
) => Observable<{
|
|
601
564
|
address: string;
|
|
602
565
|
path: string;
|
|
@@ -616,30 +579,23 @@ export function makeAccountBridgeReceive(
|
|
|
616
579
|
verify,
|
|
617
580
|
currency: account.currency,
|
|
618
581
|
derivationMode: account.derivationMode,
|
|
619
|
-
path: freshAddress
|
|
620
|
-
? freshAddress.derivationPath
|
|
621
|
-
: account.freshAddressPath,
|
|
582
|
+
path: freshAddress ? freshAddress.derivationPath : account.freshAddressPath,
|
|
622
583
|
...(injectGetAddressParams && injectGetAddressParams(account)),
|
|
623
584
|
};
|
|
624
585
|
return deviceCommunication(deviceId)((transport: Transport) =>
|
|
625
586
|
from(
|
|
626
|
-
getAddressFn(transport, arg).then(
|
|
627
|
-
const accountAddress = freshAddress
|
|
628
|
-
? freshAddress.address
|
|
629
|
-
: account.freshAddress;
|
|
587
|
+
getAddressFn(transport, arg).then(r => {
|
|
588
|
+
const accountAddress = freshAddress ? freshAddress.address : account.freshAddress;
|
|
630
589
|
|
|
631
590
|
if (r.address !== accountAddress) {
|
|
632
|
-
throw new WrongDeviceForAccount(
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
accountName: account.name,
|
|
636
|
-
}
|
|
637
|
-
);
|
|
591
|
+
throw new WrongDeviceForAccount(`WrongDeviceForAccount ${account.name}`, {
|
|
592
|
+
accountName: account.name,
|
|
593
|
+
});
|
|
638
594
|
}
|
|
639
595
|
|
|
640
596
|
return r;
|
|
641
|
-
})
|
|
642
|
-
)
|
|
597
|
+
}),
|
|
598
|
+
),
|
|
643
599
|
);
|
|
644
600
|
};
|
|
645
601
|
}
|
package/src/cache.ts
CHANGED
|
@@ -15,20 +15,20 @@ export type CacheRes<A extends Array<any>, T> = {
|
|
|
15
15
|
export type LRUCacheFn = <A extends Array<any>, T>(
|
|
16
16
|
f: (...args: A) => Promise<T>,
|
|
17
17
|
keyExtractor?: (...args: A) => string,
|
|
18
|
-
lruOpts?: LRU.Options<string, any
|
|
18
|
+
lruOpts?: LRU.Options<string, any>,
|
|
19
19
|
) => CacheRes<A, T>;
|
|
20
20
|
|
|
21
21
|
export const makeNoCache: LRUCacheFn = <A extends Array<any>, T>(
|
|
22
|
-
f: (...args: A) => Promise<T
|
|
22
|
+
f: (...args: A) => Promise<T>,
|
|
23
23
|
): CacheRes<A, T> => {
|
|
24
24
|
const result = (...args: A) => {
|
|
25
|
-
return f(...args).catch(
|
|
25
|
+
return f(...args).catch(e => {
|
|
26
26
|
throw e;
|
|
27
27
|
});
|
|
28
28
|
};
|
|
29
29
|
|
|
30
30
|
result.force = (...args: A) => {
|
|
31
|
-
return f(...args).catch(
|
|
31
|
+
return f(...args).catch(e => {
|
|
32
32
|
throw e;
|
|
33
33
|
});
|
|
34
34
|
};
|