@ledgerhq/live-common 34.54.0 → 34.54.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/lib/e2e/speculosCI.d.ts.map +1 -1
- package/lib/e2e/speculosCI.js +1 -6
- package/lib/e2e/speculosCI.js.map +1 -1
- package/lib/exchange/swap/postSwapState.d.ts.map +1 -1
- package/lib/exchange/swap/postSwapState.js +10 -6
- package/lib/exchange/swap/postSwapState.js.map +1 -1
- package/lib/exchange/swap/transactionStrategies.d.ts +2 -1
- package/lib/exchange/swap/transactionStrategies.d.ts.map +1 -1
- package/lib/exchange/swap/transactionStrategies.js +7 -6
- package/lib/exchange/swap/transactionStrategies.js.map +1 -1
- package/lib/exchange/swap/types.d.ts +3 -1
- package/lib/exchange/swap/types.d.ts.map +1 -1
- package/lib/hw/connectAppEventMapper.d.ts.map +1 -1
- package/lib/hw/connectAppEventMapper.js +21 -2
- package/lib/hw/connectAppEventMapper.js.map +1 -1
- package/lib/hw/getAppAndVersion.d.ts +3 -1
- package/lib/hw/getAppAndVersion.d.ts.map +1 -1
- package/lib/hw/getAppAndVersion.js +2 -2
- package/lib/hw/getAppAndVersion.js.map +1 -1
- package/lib/wallet-api/Exchange/SwapError.d.ts +93 -0
- package/lib/wallet-api/Exchange/SwapError.d.ts.map +1 -0
- package/lib/wallet-api/Exchange/SwapError.js +142 -0
- package/lib/wallet-api/Exchange/SwapError.js.map +1 -0
- package/lib/wallet-api/Exchange/handleSwapErrors.d.ts +40 -0
- package/lib/wallet-api/Exchange/handleSwapErrors.d.ts.map +1 -0
- package/lib/wallet-api/Exchange/handleSwapErrors.js +112 -0
- package/lib/wallet-api/Exchange/handleSwapErrors.js.map +1 -0
- package/lib/wallet-api/Exchange/index.d.ts +4 -0
- package/lib/wallet-api/Exchange/index.d.ts.map +1 -0
- package/lib/wallet-api/Exchange/index.js +27 -0
- package/lib/wallet-api/Exchange/index.js.map +1 -0
- package/lib/wallet-api/Exchange/parser.d.ts +46 -0
- package/lib/wallet-api/Exchange/parser.d.ts.map +1 -0
- package/lib/wallet-api/Exchange/parser.js +97 -0
- package/lib/wallet-api/Exchange/parser.js.map +1 -0
- package/lib/wallet-api/Exchange/server.d.ts.map +1 -1
- package/lib/wallet-api/Exchange/server.js +227 -174
- package/lib/wallet-api/Exchange/server.js.map +1 -1
- package/lib/wallet-api/Exchange/tracking.d.ts +7 -6
- package/lib/wallet-api/Exchange/tracking.d.ts.map +1 -1
- package/lib/wallet-api/Exchange/tracking.js +52 -13
- package/lib/wallet-api/Exchange/tracking.js.map +1 -1
- package/lib/wallet-api/logic.d.ts +1 -1
- package/lib/wallet-api/logic.d.ts.map +1 -1
- package/lib/wallet-api/logic.js +5 -5
- package/lib/wallet-api/logic.js.map +1 -1
- package/lib/wallet-api/react.d.ts.map +1 -1
- package/lib/wallet-api/react.js +9 -6
- package/lib/wallet-api/react.js.map +1 -1
- package/lib/wallet-api/tracking.d.ts +5 -5
- package/lib/wallet-api/tracking.d.ts.map +1 -1
- package/lib/wallet-api/tracking.js +30 -10
- package/lib/wallet-api/tracking.js.map +1 -1
- package/lib-es/e2e/speculosCI.d.ts.map +1 -1
- package/lib-es/e2e/speculosCI.js +1 -6
- package/lib-es/e2e/speculosCI.js.map +1 -1
- package/lib-es/exchange/swap/postSwapState.d.ts.map +1 -1
- package/lib-es/exchange/swap/postSwapState.js +10 -6
- package/lib-es/exchange/swap/postSwapState.js.map +1 -1
- package/lib-es/exchange/swap/transactionStrategies.d.ts +2 -1
- package/lib-es/exchange/swap/transactionStrategies.d.ts.map +1 -1
- package/lib-es/exchange/swap/transactionStrategies.js +7 -6
- package/lib-es/exchange/swap/transactionStrategies.js.map +1 -1
- package/lib-es/exchange/swap/types.d.ts +3 -1
- package/lib-es/exchange/swap/types.d.ts.map +1 -1
- package/lib-es/hw/connectAppEventMapper.d.ts.map +1 -1
- package/lib-es/hw/connectAppEventMapper.js +23 -4
- package/lib-es/hw/connectAppEventMapper.js.map +1 -1
- package/lib-es/hw/getAppAndVersion.d.ts +3 -1
- package/lib-es/hw/getAppAndVersion.d.ts.map +1 -1
- package/lib-es/hw/getAppAndVersion.js +2 -2
- package/lib-es/hw/getAppAndVersion.js.map +1 -1
- package/lib-es/wallet-api/Exchange/SwapError.d.ts +93 -0
- package/lib-es/wallet-api/Exchange/SwapError.d.ts.map +1 -0
- package/lib-es/wallet-api/Exchange/SwapError.js +128 -0
- package/lib-es/wallet-api/Exchange/SwapError.js.map +1 -0
- package/lib-es/wallet-api/Exchange/handleSwapErrors.d.ts +40 -0
- package/lib-es/wallet-api/Exchange/handleSwapErrors.d.ts.map +1 -0
- package/lib-es/wallet-api/Exchange/handleSwapErrors.js +106 -0
- package/lib-es/wallet-api/Exchange/handleSwapErrors.js.map +1 -0
- package/lib-es/wallet-api/Exchange/index.d.ts +4 -0
- package/lib-es/wallet-api/Exchange/index.d.ts.map +1 -0
- package/lib-es/wallet-api/Exchange/index.js +7 -0
- package/lib-es/wallet-api/Exchange/index.js.map +1 -0
- package/lib-es/wallet-api/Exchange/parser.d.ts +46 -0
- package/lib-es/wallet-api/Exchange/parser.d.ts.map +1 -0
- package/lib-es/wallet-api/Exchange/parser.js +90 -0
- package/lib-es/wallet-api/Exchange/parser.js.map +1 -0
- package/lib-es/wallet-api/Exchange/server.d.ts.map +1 -1
- package/lib-es/wallet-api/Exchange/server.js +224 -174
- package/lib-es/wallet-api/Exchange/server.js.map +1 -1
- package/lib-es/wallet-api/Exchange/tracking.d.ts +7 -6
- package/lib-es/wallet-api/Exchange/tracking.d.ts.map +1 -1
- package/lib-es/wallet-api/Exchange/tracking.js +52 -13
- package/lib-es/wallet-api/Exchange/tracking.js.map +1 -1
- package/lib-es/wallet-api/logic.d.ts +1 -1
- package/lib-es/wallet-api/logic.d.ts.map +1 -1
- package/lib-es/wallet-api/logic.js +5 -5
- package/lib-es/wallet-api/logic.js.map +1 -1
- package/lib-es/wallet-api/react.d.ts.map +1 -1
- package/lib-es/wallet-api/react.js +9 -6
- package/lib-es/wallet-api/react.js.map +1 -1
- package/lib-es/wallet-api/tracking.d.ts +5 -5
- package/lib-es/wallet-api/tracking.d.ts.map +1 -1
- package/lib-es/wallet-api/tracking.js +30 -10
- package/lib-es/wallet-api/tracking.js.map +1 -1
- package/package.json +68 -68
- package/src/e2e/speculosCI.ts +1 -6
- package/src/exchange/swap/postSwapState.ts +10 -5
- package/src/exchange/swap/transactionStrategies.ts +8 -7
- package/src/exchange/swap/types.ts +3 -1
- package/src/hw/connectAppEventMapper.ts +28 -4
- package/src/hw/getAppAndVersion.ts +2 -1
- package/src/wallet-api/Exchange/SwapError.test.ts +126 -0
- package/src/wallet-api/Exchange/SwapError.ts +159 -0
- package/src/wallet-api/Exchange/handleSwapErrors.test.ts +46 -0
- package/src/wallet-api/Exchange/handleSwapErrors.ts +161 -0
- package/src/wallet-api/Exchange/index.ts +26 -0
- package/src/wallet-api/Exchange/parser.test.ts +86 -0
- package/src/wallet-api/Exchange/parser.ts +119 -0
- package/src/wallet-api/Exchange/server.ts +289 -232
- package/src/wallet-api/Exchange/tracking.ts +56 -13
- package/src/wallet-api/logic.ts +5 -4
- package/src/wallet-api/react.ts +10 -5
- package/src/wallet-api/tracking.ts +30 -10
|
@@ -53,6 +53,12 @@ import { getSwapStepFromError } from "../../exchange/error";
|
|
|
53
53
|
import { postSwapCancelled } from "../../exchange/swap";
|
|
54
54
|
import { DeviceModelId } from "@ledgerhq/types-devices";
|
|
55
55
|
import { setBroadcastTransaction } from "../../exchange/swap/setBroadcastTransaction";
|
|
56
|
+
import { Transaction as EvmTransaction } from "@ledgerhq/coin-evm/types/index";
|
|
57
|
+
import { padHexString } from "@ledgerhq/hw-app-eth";
|
|
58
|
+
import { createStepError, StepError, toError } from "./parser";
|
|
59
|
+
import { handleErrors } from "./handleSwapErrors";
|
|
60
|
+
import get from "lodash/get";
|
|
61
|
+
import { SwapError } from "./SwapError";
|
|
56
62
|
|
|
57
63
|
export { ExchangeType };
|
|
58
64
|
|
|
@@ -374,237 +380,288 @@ export const handlers = ({
|
|
|
374
380
|
);
|
|
375
381
|
}),
|
|
376
382
|
"custom.exchange.swap": customWrapper<ExchangeSwapParams, SwapResult>(async params => {
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
383
|
+
try {
|
|
384
|
+
if (!params) {
|
|
385
|
+
tracking.startExchangeNoParams(manifest);
|
|
386
|
+
throw new ServerError(createUnknownError({ message: "params is undefined" }));
|
|
387
|
+
}
|
|
381
388
|
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
const trackingParams = {
|
|
394
|
-
provider: params.provider,
|
|
395
|
-
exchangeType: params.exchangeType,
|
|
396
|
-
};
|
|
397
|
-
|
|
398
|
-
tracking.startExchangeRequested(trackingParams);
|
|
399
|
-
|
|
400
|
-
const exchangeStartParams: ExchangeStartParamsUiRequest = (await extractSwapStartParam(
|
|
401
|
-
params,
|
|
402
|
-
accounts,
|
|
403
|
-
)) as SwapStartParamsUiRequest;
|
|
404
|
-
|
|
405
|
-
const {
|
|
406
|
-
fromCurrency,
|
|
407
|
-
fromAccount,
|
|
408
|
-
fromParentAccount,
|
|
409
|
-
toCurrency,
|
|
410
|
-
toAccount,
|
|
411
|
-
toParentAccount,
|
|
412
|
-
} = exchangeStartParams.exchange;
|
|
413
|
-
|
|
414
|
-
if (!fromAccount || !fromCurrency) {
|
|
415
|
-
throw new ServerError(createAccountNotFound(params.fromAccountId));
|
|
416
|
-
}
|
|
389
|
+
const {
|
|
390
|
+
provider,
|
|
391
|
+
fromAmount,
|
|
392
|
+
fromAmountAtomic,
|
|
393
|
+
quoteId,
|
|
394
|
+
toNewTokenId,
|
|
395
|
+
customFeeConfig,
|
|
396
|
+
swapAppVersion,
|
|
397
|
+
sponsored,
|
|
398
|
+
isEmbedded,
|
|
399
|
+
} = params;
|
|
417
400
|
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
? toParentAccount.freshAddress
|
|
424
|
-
: (toAccount as Account).freshAddress;
|
|
425
|
-
|
|
426
|
-
// Step 1: Open the drawer and open exchange app
|
|
427
|
-
const startExchange = async () => {
|
|
428
|
-
return new Promise<{ transactionId: string; device?: ExchangeStartResult["device"] }>(
|
|
429
|
-
(resolve, reject) => {
|
|
430
|
-
uiExchangeStart({
|
|
431
|
-
exchangeParams: exchangeStartParams,
|
|
432
|
-
onSuccess: (nonce, device) => {
|
|
433
|
-
tracking.startExchangeSuccess(trackingParams);
|
|
434
|
-
resolve({ transactionId: nonce, device });
|
|
435
|
-
},
|
|
436
|
-
onCancel: error => {
|
|
437
|
-
tracking.startExchangeFail(trackingParams);
|
|
438
|
-
reject(error);
|
|
439
|
-
},
|
|
440
|
-
});
|
|
441
|
-
},
|
|
442
|
-
);
|
|
443
|
-
};
|
|
444
|
-
|
|
445
|
-
const { transactionId, device: deviceInfo } = await startExchange();
|
|
446
|
-
|
|
447
|
-
const {
|
|
448
|
-
binaryPayload,
|
|
449
|
-
signature,
|
|
450
|
-
payinAddress,
|
|
451
|
-
swapId,
|
|
452
|
-
payinExtraId,
|
|
453
|
-
extraTransactionParameters,
|
|
454
|
-
} = await retrieveSwapPayload({
|
|
455
|
-
provider,
|
|
456
|
-
deviceTransactionId: transactionId,
|
|
457
|
-
fromAccountAddress,
|
|
458
|
-
toAccountAddress,
|
|
459
|
-
fromAccountCurrency: fromCurrency!.id,
|
|
460
|
-
toAccountCurrency: toCurrency!.id,
|
|
461
|
-
amount: fromAmount,
|
|
462
|
-
amountInAtomicUnit: fromAmountAtomic,
|
|
463
|
-
quoteId,
|
|
464
|
-
toNewTokenId,
|
|
465
|
-
}).catch((error: Error) => {
|
|
466
|
-
throw error;
|
|
467
|
-
});
|
|
468
|
-
|
|
469
|
-
// Complete Swap
|
|
470
|
-
const trackingCompleteParams = {
|
|
471
|
-
provider: params.provider,
|
|
472
|
-
exchangeType: params.exchangeType,
|
|
473
|
-
};
|
|
474
|
-
tracking.completeExchangeRequested(trackingCompleteParams);
|
|
475
|
-
|
|
476
|
-
const strategyData = {
|
|
477
|
-
recipient: payinAddress,
|
|
478
|
-
amount: fromAmountAtomic,
|
|
479
|
-
currency: fromCurrency as CryptoOrTokenCurrency,
|
|
480
|
-
customFeeConfig: customFeeConfig ?? {},
|
|
481
|
-
payinExtraId,
|
|
482
|
-
extraTransactionParameters,
|
|
483
|
-
sponsored,
|
|
484
|
-
};
|
|
485
|
-
|
|
486
|
-
const transaction: Transaction = await getStrategy(strategyData, "swap").catch(
|
|
487
|
-
async error => {
|
|
488
|
-
throw error;
|
|
489
|
-
},
|
|
490
|
-
);
|
|
401
|
+
const trackingParams = {
|
|
402
|
+
provider: params.provider,
|
|
403
|
+
exchangeType: params.exchangeType,
|
|
404
|
+
isEmbeddedSwap: isEmbedded,
|
|
405
|
+
};
|
|
491
406
|
|
|
492
|
-
|
|
407
|
+
tracking.startExchangeRequested(trackingParams);
|
|
493
408
|
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
409
|
+
const exchangeStartParams: ExchangeStartParamsUiRequest = (await extractSwapStartParam(
|
|
410
|
+
params,
|
|
411
|
+
accounts,
|
|
412
|
+
)) as SwapStartParamsUiRequest;
|
|
413
|
+
|
|
414
|
+
const {
|
|
415
|
+
fromCurrency,
|
|
416
|
+
fromAccount,
|
|
417
|
+
fromParentAccount,
|
|
418
|
+
toCurrency,
|
|
419
|
+
toAccount,
|
|
420
|
+
toParentAccount,
|
|
421
|
+
} = exchangeStartParams.exchange;
|
|
422
|
+
|
|
423
|
+
if (!fromAccount || !fromCurrency) {
|
|
424
|
+
throw new ServerError(createAccountNotFound(params.fromAccountId));
|
|
425
|
+
}
|
|
501
426
|
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
427
|
+
const fromAccountAddress = fromParentAccount
|
|
428
|
+
? fromParentAccount.freshAddress
|
|
429
|
+
: (fromAccount as Account).freshAddress;
|
|
430
|
+
|
|
431
|
+
const toAccountAddress = toParentAccount
|
|
432
|
+
? toParentAccount.freshAddress
|
|
433
|
+
: (toAccount as Account).freshAddress;
|
|
434
|
+
|
|
435
|
+
// Step 1: Open the drawer and open exchange app
|
|
436
|
+
const startExchange = async () => {
|
|
437
|
+
return new Promise<{ transactionId: string; device?: ExchangeStartResult["device"] }>(
|
|
438
|
+
(resolve, reject) => {
|
|
439
|
+
uiExchangeStart({
|
|
440
|
+
exchangeParams: exchangeStartParams,
|
|
441
|
+
onSuccess: (nonce, device) => {
|
|
442
|
+
tracking.startExchangeSuccess(trackingParams);
|
|
443
|
+
resolve({ transactionId: nonce, device });
|
|
444
|
+
},
|
|
445
|
+
onCancel: error => {
|
|
446
|
+
tracking.startExchangeFail(trackingParams);
|
|
447
|
+
reject(error);
|
|
448
|
+
},
|
|
449
|
+
});
|
|
450
|
+
},
|
|
451
|
+
);
|
|
452
|
+
};
|
|
528
453
|
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
454
|
+
let transactionId: string;
|
|
455
|
+
let deviceInfo: ExchangeStartResult["device"];
|
|
456
|
+
|
|
457
|
+
try {
|
|
458
|
+
const result = await startExchange();
|
|
459
|
+
transactionId = result.transactionId;
|
|
460
|
+
deviceInfo = result.device;
|
|
461
|
+
} catch (error) {
|
|
462
|
+
const rawError = get(error, "response.data.error", error);
|
|
463
|
+
const wrappedError = createStepError({
|
|
464
|
+
error: toError(rawError),
|
|
465
|
+
step: StepError.NONCE,
|
|
466
|
+
});
|
|
467
|
+
throw wrappedError;
|
|
468
|
+
}
|
|
535
469
|
|
|
536
|
-
|
|
537
|
-
|
|
470
|
+
const {
|
|
471
|
+
binaryPayload,
|
|
472
|
+
signature,
|
|
473
|
+
payinAddress,
|
|
474
|
+
swapId,
|
|
475
|
+
payinExtraId,
|
|
476
|
+
extraTransactionParameters,
|
|
477
|
+
} = await retrieveSwapPayload({
|
|
478
|
+
provider,
|
|
479
|
+
deviceTransactionId: transactionId,
|
|
480
|
+
fromAccountAddress,
|
|
481
|
+
toAccountAddress,
|
|
482
|
+
fromAccountCurrency: fromCurrency!.id,
|
|
483
|
+
toAccountCurrency: toCurrency!.id,
|
|
484
|
+
amount: fromAmount,
|
|
485
|
+
amountInAtomicUnit: fromAmountAtomic,
|
|
486
|
+
quoteId,
|
|
487
|
+
toNewTokenId,
|
|
488
|
+
}).catch((error: Error) => {
|
|
489
|
+
const wrappedError = createStepError({
|
|
490
|
+
error: get(error, "response.data.error", error),
|
|
491
|
+
step: StepError.PAYLOAD,
|
|
492
|
+
});
|
|
493
|
+
|
|
494
|
+
throw wrappedError;
|
|
495
|
+
});
|
|
538
496
|
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
swapId: swapId,
|
|
557
|
-
amountExpectedTo: amountExpectedTo.toNumber(),
|
|
558
|
-
magnitudeAwareRate,
|
|
559
|
-
refundAddress,
|
|
560
|
-
payoutAddress,
|
|
561
|
-
sponsored,
|
|
562
|
-
},
|
|
563
|
-
onSuccess: ({ operationHash, swapId }: { operationHash: string; swapId: string }) => {
|
|
564
|
-
tracking.completeExchangeSuccess({
|
|
565
|
-
...trackingParams,
|
|
566
|
-
currency: transaction.family,
|
|
567
|
-
});
|
|
497
|
+
// Complete Swap
|
|
498
|
+
const trackingCompleteParams = {
|
|
499
|
+
provider: params.provider,
|
|
500
|
+
exchangeType: params.exchangeType,
|
|
501
|
+
isEmbeddedSwap: isEmbedded,
|
|
502
|
+
};
|
|
503
|
+
tracking.completeExchangeRequested(trackingCompleteParams);
|
|
504
|
+
|
|
505
|
+
const strategyData = {
|
|
506
|
+
recipient: payinAddress,
|
|
507
|
+
amount: fromAmountAtomic,
|
|
508
|
+
currency: fromCurrency as CryptoOrTokenCurrency,
|
|
509
|
+
customFeeConfig: customFeeConfig ?? {},
|
|
510
|
+
payinExtraId,
|
|
511
|
+
extraTransactionParameters,
|
|
512
|
+
sponsored,
|
|
513
|
+
};
|
|
568
514
|
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
515
|
+
const transaction: Transaction = await getStrategy(strategyData, "swap");
|
|
516
|
+
|
|
517
|
+
const mainFromAccount = getMainAccount(fromAccount, fromParentAccount);
|
|
518
|
+
|
|
519
|
+
if (transaction.family !== mainFromAccount.currency.family) {
|
|
520
|
+
return Promise.reject(
|
|
521
|
+
new Error(
|
|
522
|
+
`Account and transaction must be from the same family. Account family: ${mainFromAccount.currency.family}, Transaction family: ${transaction.family}`,
|
|
523
|
+
),
|
|
524
|
+
);
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
const accountBridge = getAccountBridge(fromAccount, fromParentAccount);
|
|
528
|
+
|
|
529
|
+
/**
|
|
530
|
+
* 'subAccountId' is used for ETH and it's ERC-20 tokens.
|
|
531
|
+
* This field is ignored for BTC
|
|
532
|
+
*/
|
|
533
|
+
const subAccountId =
|
|
534
|
+
fromParentAccount && fromParentAccount.id !== fromAccount.id ? fromAccount.id : undefined;
|
|
580
535
|
|
|
581
|
-
|
|
536
|
+
const bridgeTx = accountBridge.createTransaction(fromAccount);
|
|
537
|
+
/**
|
|
538
|
+
* We append the `recipient` to the tx created from `createTransaction`
|
|
539
|
+
* to avoid having userGasLimit reset to null for ETH txs
|
|
540
|
+
* cf. libs/ledger-live-common/src/families/ethereum/updateTransaction.ts
|
|
541
|
+
*/
|
|
542
|
+
const tx = accountBridge.updateTransaction(
|
|
543
|
+
{
|
|
544
|
+
...bridgeTx,
|
|
545
|
+
recipient: transaction.recipient,
|
|
582
546
|
},
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
547
|
+
{
|
|
548
|
+
...transaction,
|
|
549
|
+
feesStrategy: params.feeStrategy.toLowerCase(),
|
|
550
|
+
subAccountId,
|
|
551
|
+
},
|
|
552
|
+
);
|
|
553
|
+
|
|
554
|
+
// Get amountExpectedTo and magnitudeAwareRate from binary payload
|
|
555
|
+
const decodePayload = await decodeSwapPayload(binaryPayload);
|
|
556
|
+
const amountExpectedTo = new BigNumber(decodePayload.amountToWallet.toString());
|
|
557
|
+
const magnitudeAwareRate = tx.amount && amountExpectedTo.dividedBy(tx.amount);
|
|
558
|
+
const refundAddress = decodePayload.refundAddress;
|
|
559
|
+
const payoutAddress = decodePayload.payoutAddress;
|
|
560
|
+
|
|
561
|
+
// tx.amount should be BigNumber
|
|
562
|
+
tx.amount = new BigNumber(tx.amount);
|
|
563
|
+
|
|
564
|
+
return new Promise((resolve, reject) =>
|
|
565
|
+
uiSwap({
|
|
566
|
+
exchangeParams: {
|
|
567
|
+
exchangeType: ExchangeType.SWAP,
|
|
568
|
+
provider: params.provider,
|
|
569
|
+
transaction: tx,
|
|
570
|
+
signature: signature,
|
|
571
|
+
binaryPayload: binaryPayload,
|
|
572
|
+
exchange: {
|
|
573
|
+
fromAccount,
|
|
574
|
+
fromParentAccount,
|
|
575
|
+
toAccount,
|
|
576
|
+
toParentAccount,
|
|
577
|
+
fromCurrency: fromCurrency!,
|
|
578
|
+
toCurrency: toCurrency!,
|
|
579
|
+
},
|
|
580
|
+
feesStrategy: params.feeStrategy,
|
|
586
581
|
swapId: swapId,
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
errorMessage: error.message,
|
|
590
|
-
sourceCurrencyId: fromCurrency.id,
|
|
591
|
-
targetCurrencyId: toCurrency?.id,
|
|
592
|
-
hardwareWalletType: deviceInfo?.modelId as DeviceModelId,
|
|
593
|
-
swapType: quoteId ? "fixed" : "float",
|
|
594
|
-
swapAppVersion,
|
|
595
|
-
fromAccountAddress,
|
|
596
|
-
toAccountAddress,
|
|
582
|
+
amountExpectedTo: amountExpectedTo.toNumber(),
|
|
583
|
+
magnitudeAwareRate,
|
|
597
584
|
refundAddress,
|
|
598
585
|
payoutAddress,
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
586
|
+
sponsored,
|
|
587
|
+
},
|
|
588
|
+
onSuccess: ({ operationHash, swapId }: { operationHash: string; swapId: string }) => {
|
|
589
|
+
tracking.completeExchangeSuccess({
|
|
590
|
+
...trackingParams,
|
|
591
|
+
currency: transaction.family,
|
|
592
|
+
});
|
|
593
|
+
|
|
594
|
+
setBroadcastTransaction({
|
|
595
|
+
provider,
|
|
596
|
+
result: { operation: operationHash, swapId },
|
|
597
|
+
sourceCurrencyId: fromCurrency.id,
|
|
598
|
+
targetCurrencyId: toCurrency?.id,
|
|
599
|
+
hardwareWalletType: deviceInfo?.modelId as DeviceModelId,
|
|
600
|
+
swapAppVersion,
|
|
601
|
+
fromAccountAddress,
|
|
602
|
+
toAccountAddress,
|
|
603
|
+
fromAmount,
|
|
604
|
+
});
|
|
605
|
+
|
|
606
|
+
resolve({ operationHash, swapId });
|
|
607
|
+
},
|
|
608
|
+
onCancel: error => {
|
|
609
|
+
postSwapCancelled({
|
|
610
|
+
provider: provider,
|
|
611
|
+
swapId: swapId,
|
|
612
|
+
swapStep: getSwapStepFromError(error),
|
|
613
|
+
statusCode: error.name,
|
|
614
|
+
errorMessage: error.message,
|
|
615
|
+
sourceCurrencyId: fromCurrency.id,
|
|
616
|
+
targetCurrencyId: toCurrency?.id,
|
|
617
|
+
hardwareWalletType: deviceInfo?.modelId as DeviceModelId,
|
|
618
|
+
swapType: quoteId ? "fixed" : "float",
|
|
619
|
+
swapAppVersion,
|
|
620
|
+
fromAccountAddress,
|
|
621
|
+
toAccountAddress,
|
|
622
|
+
refundAddress,
|
|
623
|
+
payoutAddress,
|
|
624
|
+
fromAmount,
|
|
625
|
+
seedIdFrom: mainFromAccount.seedIdentifier,
|
|
626
|
+
seedIdTo: toParentAccount?.seedIdentifier || (toAccount as Account)?.seedIdentifier,
|
|
627
|
+
data: (transaction as EvmTransaction).data
|
|
628
|
+
? `0x${padHexString((transaction as EvmTransaction).data?.toString("hex") || "")}`
|
|
629
|
+
: "0x",
|
|
630
|
+
});
|
|
631
|
+
|
|
632
|
+
reject(createStepError({ error, step: StepError.SIGNATURE }));
|
|
633
|
+
},
|
|
634
|
+
}),
|
|
635
|
+
);
|
|
636
|
+
} catch (error) {
|
|
637
|
+
// Skip DrawerClosedError
|
|
638
|
+
// do not redirect to the error screen
|
|
639
|
+
if (isDrawerClosedError(error)) {
|
|
640
|
+
throw error;
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
// Global catch for any errors during the swap process
|
|
644
|
+
// moved out as sonarcloud suggested to avoid 4 level nested functions
|
|
645
|
+
const createErrorRejector = (error: SwapError, reject: (error: SwapError) => void) => {
|
|
646
|
+
return () => reject(error);
|
|
647
|
+
};
|
|
648
|
+
|
|
649
|
+
const displayError = (error: SwapError): Promise<void> =>
|
|
650
|
+
new Promise((resolve, reject) => {
|
|
651
|
+
const rejectWithError = createErrorRejector(error, reject);
|
|
652
|
+
uiError({
|
|
653
|
+
error,
|
|
654
|
+
onSuccess: rejectWithError,
|
|
655
|
+
onCancel: rejectWithError,
|
|
602
656
|
});
|
|
657
|
+
});
|
|
603
658
|
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
})
|
|
607
|
-
|
|
659
|
+
await handleErrors(error, {
|
|
660
|
+
onDisplayError: displayError,
|
|
661
|
+
});
|
|
662
|
+
|
|
663
|
+
throw error;
|
|
664
|
+
}
|
|
608
665
|
}),
|
|
609
666
|
|
|
610
667
|
"custom.isReady": customWrapper<void, void>(async () => {
|
|
@@ -826,21 +883,21 @@ async function getStrategy(
|
|
|
826
883
|
}
|
|
827
884
|
}
|
|
828
885
|
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
)
|
|
845
|
-
|
|
886
|
+
return strategy({
|
|
887
|
+
family,
|
|
888
|
+
amount: new BigNumber(amount),
|
|
889
|
+
recipient,
|
|
890
|
+
customFeeConfig: convertedCustomFeeConfig,
|
|
891
|
+
payinExtraId,
|
|
892
|
+
extraTransactionParameters,
|
|
893
|
+
customErrorType,
|
|
894
|
+
sponsored,
|
|
895
|
+
});
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
function isDrawerClosedError(error: unknown) {
|
|
899
|
+
if (!error || typeof error !== "object") return false;
|
|
900
|
+
return (
|
|
901
|
+
get(error, "name") === "DrawerClosedError" || get(error, "cause.name") === "DrawerClosedError"
|
|
902
|
+
);
|
|
846
903
|
}
|
|
@@ -14,8 +14,15 @@ type TrackExchange = (
|
|
|
14
14
|
interface TrackEventPayload {
|
|
15
15
|
exchangeType: "SELL" | "FUND" | "SWAP";
|
|
16
16
|
provider: string;
|
|
17
|
+
isEmbeddedSwap?: boolean;
|
|
17
18
|
}
|
|
18
19
|
|
|
20
|
+
/**
|
|
21
|
+
* Converts isEmbeddedSwap boolean to string for analytics consistency
|
|
22
|
+
*/
|
|
23
|
+
const formatIsEmbeddedSwap = (isEmbeddedSwap?: boolean): string | undefined =>
|
|
24
|
+
isEmbeddedSwap !== undefined ? String(isEmbeddedSwap) : undefined;
|
|
25
|
+
|
|
19
26
|
function getEventData(manifest: AppManifest) {
|
|
20
27
|
return { walletAPI: manifest.name };
|
|
21
28
|
}
|
|
@@ -29,24 +36,46 @@ function getEventData(manifest: AppManifest) {
|
|
|
29
36
|
// in order to get the exact type matching the tracking wrapper API
|
|
30
37
|
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
|
31
38
|
export default function trackingWrapper(trackCall: TrackExchange) {
|
|
32
|
-
const track = (event: string, properties: Record<string, string> | null) => {
|
|
33
|
-
|
|
39
|
+
const track = (event: string, properties: Record<string, string | undefined> | null) => {
|
|
40
|
+
// Filter out undefined values before passing to trackCall
|
|
41
|
+
if (!properties) {
|
|
42
|
+
return trackCall(event, null, null);
|
|
43
|
+
}
|
|
44
|
+
const filteredProperties: Record<string, string> = {};
|
|
45
|
+
for (const [key, value] of Object.entries(properties)) {
|
|
46
|
+
if (value !== undefined) {
|
|
47
|
+
filteredProperties[key] = value;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return trackCall(event, filteredProperties, null);
|
|
34
51
|
};
|
|
35
52
|
|
|
36
53
|
return {
|
|
37
54
|
// Generate Exchange nonce modal open
|
|
38
|
-
startExchangeRequested: ({ provider, exchangeType }: TrackEventPayload) => {
|
|
39
|
-
track(`Starts Exchange ${exchangeType} Nonce request`, {
|
|
55
|
+
startExchangeRequested: ({ provider, exchangeType, isEmbeddedSwap }: TrackEventPayload) => {
|
|
56
|
+
track(`Starts Exchange ${exchangeType} Nonce request`, {
|
|
57
|
+
provider,
|
|
58
|
+
exchangeType,
|
|
59
|
+
isEmbeddedSwap: formatIsEmbeddedSwap(isEmbeddedSwap),
|
|
60
|
+
});
|
|
40
61
|
},
|
|
41
62
|
|
|
42
63
|
// Successfully generated an Exchange app nonce
|
|
43
|
-
startExchangeSuccess: ({ provider, exchangeType }: TrackEventPayload) => {
|
|
44
|
-
track(`Starts Exchange ${exchangeType} Nonce success`, {
|
|
64
|
+
startExchangeSuccess: ({ provider, exchangeType, isEmbeddedSwap }: TrackEventPayload) => {
|
|
65
|
+
track(`Starts Exchange ${exchangeType} Nonce success`, {
|
|
66
|
+
provider,
|
|
67
|
+
exchangeType,
|
|
68
|
+
isEmbeddedSwap: formatIsEmbeddedSwap(isEmbeddedSwap),
|
|
69
|
+
});
|
|
45
70
|
},
|
|
46
71
|
|
|
47
72
|
// Failed to generate an Exchange app nonce
|
|
48
|
-
startExchangeFail: ({ provider, exchangeType }: TrackEventPayload) => {
|
|
49
|
-
track(`Starts Exchange ${exchangeType} Nonce fail`, {
|
|
73
|
+
startExchangeFail: ({ provider, exchangeType, isEmbeddedSwap }: TrackEventPayload) => {
|
|
74
|
+
track(`Starts Exchange ${exchangeType} Nonce fail`, {
|
|
75
|
+
provider,
|
|
76
|
+
exchangeType,
|
|
77
|
+
isEmbeddedSwap: formatIsEmbeddedSwap(isEmbeddedSwap),
|
|
78
|
+
});
|
|
50
79
|
},
|
|
51
80
|
|
|
52
81
|
// No Params to generate an Exchange app nonce
|
|
@@ -54,8 +83,12 @@ export default function trackingWrapper(trackCall: TrackExchange) {
|
|
|
54
83
|
track("Starts Exchange no params", getEventData(manifest));
|
|
55
84
|
},
|
|
56
85
|
|
|
57
|
-
completeExchangeRequested: ({ provider, exchangeType }: TrackEventPayload) => {
|
|
58
|
-
track(`Completes Exchange ${exchangeType} requested`, {
|
|
86
|
+
completeExchangeRequested: ({ provider, exchangeType, isEmbeddedSwap }: TrackEventPayload) => {
|
|
87
|
+
track(`Completes Exchange ${exchangeType} requested`, {
|
|
88
|
+
provider,
|
|
89
|
+
exchangeType,
|
|
90
|
+
isEmbeddedSwap: formatIsEmbeddedSwap(isEmbeddedSwap),
|
|
91
|
+
});
|
|
59
92
|
},
|
|
60
93
|
|
|
61
94
|
// Successfully completed an Exchange
|
|
@@ -63,13 +96,23 @@ export default function trackingWrapper(trackCall: TrackExchange) {
|
|
|
63
96
|
provider,
|
|
64
97
|
exchangeType,
|
|
65
98
|
currency,
|
|
99
|
+
isEmbeddedSwap,
|
|
66
100
|
}: TrackEventPayload & { currency: string }) => {
|
|
67
|
-
track(`Completes Exchange ${exchangeType} success`, {
|
|
101
|
+
track(`Completes Exchange ${exchangeType} success`, {
|
|
102
|
+
provider,
|
|
103
|
+
exchangeType,
|
|
104
|
+
currency,
|
|
105
|
+
isEmbeddedSwap: formatIsEmbeddedSwap(isEmbeddedSwap),
|
|
106
|
+
});
|
|
68
107
|
},
|
|
69
108
|
|
|
70
109
|
// Failed to complete an Exchange
|
|
71
|
-
completeExchangeFail: ({ provider, exchangeType }: TrackEventPayload) => {
|
|
72
|
-
track(`Completes Exchange ${exchangeType} Nonce fail`, {
|
|
110
|
+
completeExchangeFail: ({ provider, exchangeType, isEmbeddedSwap }: TrackEventPayload) => {
|
|
111
|
+
track(`Completes Exchange ${exchangeType} Nonce fail`, {
|
|
112
|
+
provider,
|
|
113
|
+
exchangeType,
|
|
114
|
+
isEmbeddedSwap: formatIsEmbeddedSwap(isEmbeddedSwap),
|
|
115
|
+
});
|
|
73
116
|
},
|
|
74
117
|
|
|
75
118
|
// No Params to complete an Exchange
|