@ledgerhq/live-common 34.54.0-nightly.20251206023719 → 34.54.0-nightly.20251209140356
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/__tests__/test-helpers/environment.js +2 -0
- package/lib/__tests__/test-helpers/environment.js.map +1 -1
- package/lib/account/serialization.js +1 -1
- package/lib/account/serialization.js.map +1 -1
- package/lib/account/support.js +1 -1
- package/lib/account/support.js.map +1 -1
- package/lib/bridge/generic-alpaca/getAccountShape.d.ts.map +1 -1
- package/lib/bridge/generic-alpaca/getAccountShape.js +3 -2
- package/lib/bridge/generic-alpaca/getAccountShape.js.map +1 -1
- package/lib/bridge/generic-alpaca/prepareTransaction.d.ts.map +1 -1
- package/lib/bridge/generic-alpaca/prepareTransaction.js +7 -0
- package/lib/bridge/generic-alpaca/prepareTransaction.js.map +1 -1
- package/lib/domain/getTokensWithFunds.d.ts +7 -1
- package/lib/domain/getTokensWithFunds.d.ts.map +1 -1
- package/lib/domain/getTokensWithFunds.js +15 -4
- package/lib/domain/getTokensWithFunds.js.map +1 -1
- package/lib/domain/getTotalStakeableAssets.d.ts +10 -0
- package/lib/domain/getTotalStakeableAssets.d.ts.map +1 -0
- package/lib/domain/getTotalStakeableAssets.js +35 -0
- package/lib/domain/getTotalStakeableAssets.js.map +1 -0
- package/lib/e2e/index.d.ts +9 -0
- package/lib/e2e/index.d.ts.map +1 -1
- package/lib/exchange/swap/api/v5/fetchCurrencyFrom.js +1 -1
- package/lib/exchange/swap/api/v5/fetchCurrencyFrom.js.map +1 -1
- package/lib/exchange/swap/getIncompatibleCurrencyKeys.d.ts.map +1 -1
- package/lib/exchange/swap/getIncompatibleCurrencyKeys.js +4 -0
- package/lib/exchange/swap/getIncompatibleCurrencyKeys.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/featureFlags/defaultFeatures.d.ts +2 -0
- package/lib/featureFlags/defaultFeatures.d.ts.map +1 -1
- package/lib/featureFlags/defaultFeatures.js +3 -0
- package/lib/featureFlags/defaultFeatures.js.map +1 -1
- package/lib/featureFlags/firebaseFeatureFlags.js +1 -1
- package/lib/featureFlags/firebaseFeatureFlags.js.map +1 -1
- package/lib/featureFlags/useFeature.d.ts +1 -1
- package/lib/featureFlags/useFeature.d.ts.map +1 -1
- package/lib/featureFlags/useHasOverriddenFeatureFlags.js +1 -1
- package/lib/featureFlags/useHasOverriddenFeatureFlags.js.map +1 -1
- package/lib/hw/getBitcoinLikeInfo.js +1 -1
- package/lib/hw/getBitcoinLikeInfo.js.map +1 -1
- package/lib/mock/account.js +1 -1
- package/lib/mock/account.js.map +1 -1
- package/lib/modularDrawer/hooks/useCurrenciesUnderFeatureFlag.d.ts.map +1 -1
- package/lib/modularDrawer/hooks/useCurrenciesUnderFeatureFlag.js +6 -0
- package/lib/modularDrawer/hooks/useCurrenciesUnderFeatureFlag.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 +226 -177
- 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/wallet-api/useDappLogic.d.ts.map +1 -1
- package/lib/wallet-api/useDappLogic.js +31 -20
- package/lib/wallet-api/useDappLogic.js.map +1 -1
- package/lib/wallet-api/utils/extractDappURLFromManifest.js +3 -3
- package/lib/wallet-api/utils/extractDappURLFromManifest.js.map +1 -1
- package/lib/wallet-api/utils/extractURLFromManifest.js +1 -1
- package/lib/wallet-api/utils/extractURLFromManifest.js.map +1 -1
- package/lib-es/__tests__/test-helpers/environment.js +2 -0
- package/lib-es/__tests__/test-helpers/environment.js.map +1 -1
- package/lib-es/account/serialization.js +1 -1
- package/lib-es/account/serialization.js.map +1 -1
- package/lib-es/account/support.js +1 -1
- package/lib-es/account/support.js.map +1 -1
- package/lib-es/bridge/generic-alpaca/getAccountShape.d.ts.map +1 -1
- package/lib-es/bridge/generic-alpaca/getAccountShape.js +3 -2
- package/lib-es/bridge/generic-alpaca/getAccountShape.js.map +1 -1
- package/lib-es/bridge/generic-alpaca/prepareTransaction.d.ts.map +1 -1
- package/lib-es/bridge/generic-alpaca/prepareTransaction.js +7 -0
- package/lib-es/bridge/generic-alpaca/prepareTransaction.js.map +1 -1
- package/lib-es/domain/getTokensWithFunds.d.ts +7 -1
- package/lib-es/domain/getTokensWithFunds.d.ts.map +1 -1
- package/lib-es/domain/getTokensWithFunds.js +13 -3
- package/lib-es/domain/getTokensWithFunds.js.map +1 -1
- package/lib-es/domain/getTotalStakeableAssets.d.ts +10 -0
- package/lib-es/domain/getTotalStakeableAssets.d.ts.map +1 -0
- package/lib-es/domain/getTotalStakeableAssets.js +31 -0
- package/lib-es/domain/getTotalStakeableAssets.js.map +1 -0
- package/lib-es/e2e/index.d.ts +9 -0
- package/lib-es/e2e/index.d.ts.map +1 -1
- package/lib-es/exchange/swap/api/v5/fetchCurrencyFrom.js +1 -1
- package/lib-es/exchange/swap/api/v5/fetchCurrencyFrom.js.map +1 -1
- package/lib-es/exchange/swap/getIncompatibleCurrencyKeys.d.ts.map +1 -1
- package/lib-es/exchange/swap/getIncompatibleCurrencyKeys.js +4 -0
- package/lib-es/exchange/swap/getIncompatibleCurrencyKeys.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/featureFlags/defaultFeatures.d.ts +2 -0
- package/lib-es/featureFlags/defaultFeatures.d.ts.map +1 -1
- package/lib-es/featureFlags/defaultFeatures.js +3 -0
- package/lib-es/featureFlags/defaultFeatures.js.map +1 -1
- package/lib-es/featureFlags/firebaseFeatureFlags.js +1 -1
- package/lib-es/featureFlags/firebaseFeatureFlags.js.map +1 -1
- package/lib-es/featureFlags/useFeature.d.ts +1 -1
- package/lib-es/featureFlags/useFeature.d.ts.map +1 -1
- package/lib-es/featureFlags/useHasOverriddenFeatureFlags.js +1 -1
- package/lib-es/featureFlags/useHasOverriddenFeatureFlags.js.map +1 -1
- package/lib-es/hw/getBitcoinLikeInfo.js +1 -1
- package/lib-es/hw/getBitcoinLikeInfo.js.map +1 -1
- package/lib-es/mock/account.js +1 -1
- package/lib-es/mock/account.js.map +1 -1
- package/lib-es/modularDrawer/hooks/useCurrenciesUnderFeatureFlag.d.ts.map +1 -1
- package/lib-es/modularDrawer/hooks/useCurrenciesUnderFeatureFlag.js +6 -0
- package/lib-es/modularDrawer/hooks/useCurrenciesUnderFeatureFlag.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 +223 -177
- 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/lib-es/wallet-api/useDappLogic.d.ts.map +1 -1
- package/lib-es/wallet-api/useDappLogic.js +31 -20
- package/lib-es/wallet-api/useDappLogic.js.map +1 -1
- package/lib-es/wallet-api/utils/extractDappURLFromManifest.js +3 -3
- package/lib-es/wallet-api/utils/extractDappURLFromManifest.js.map +1 -1
- package/lib-es/wallet-api/utils/extractURLFromManifest.js +1 -1
- package/lib-es/wallet-api/utils/extractURLFromManifest.js.map +1 -1
- package/package.json +73 -73
- package/src/__tests__/test-helpers/environment.ts +2 -0
- package/src/account/serialization.ts +1 -1
- package/src/account/support.ts +1 -1
- package/src/bridge/generic-alpaca/getAccountShape.ts +4 -2
- package/src/bridge/generic-alpaca/prepareTransaction.ts +7 -0
- package/src/bridge/generic-alpaca/tests/prepareTransaction.test.ts +42 -0
- package/src/domain/getTokensWithFunds.ts +18 -5
- package/src/domain/getTotalStakeableAssets.test.ts +267 -0
- package/src/domain/getTotalStakeableAssets.ts +47 -0
- package/src/exchange/swap/api/v5/fetchCurrencyFrom.ts +1 -1
- package/src/exchange/swap/getIncompatibleCurrencyKeys.ts +4 -0
- package/src/exchange/swap/transactionStrategies.ts +8 -7
- package/src/featureFlags/defaultFeatures.ts +3 -0
- package/src/featureFlags/firebaseFeatureFlags.ts +1 -1
- package/src/featureFlags/useHasOverriddenFeatureFlags.ts +1 -1
- package/src/hw/getBitcoinLikeInfo.ts +1 -1
- package/src/mock/account.ts +1 -1
- package/src/modularDrawer/hooks/useCurrenciesUnderFeatureFlag.ts +6 -0
- 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 +287 -235
- 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
- package/src/wallet-api/useDappLogic.ts +32 -20
- package/src/wallet-api/utils/extractDappURLFromManifest.ts +3 -3
- package/src/wallet-api/utils/extractURLFromManifest.ts +1 -1
|
@@ -55,6 +55,10 @@ import { DeviceModelId } from "@ledgerhq/types-devices";
|
|
|
55
55
|
import { setBroadcastTransaction } from "../../exchange/swap/setBroadcastTransaction";
|
|
56
56
|
import { Transaction as EvmTransaction } from "@ledgerhq/coin-evm/types/index";
|
|
57
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";
|
|
58
62
|
|
|
59
63
|
export { ExchangeType };
|
|
60
64
|
|
|
@@ -376,240 +380,288 @@ export const handlers = ({
|
|
|
376
380
|
);
|
|
377
381
|
}),
|
|
378
382
|
"custom.exchange.swap": customWrapper<ExchangeSwapParams, SwapResult>(async params => {
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
+
try {
|
|
384
|
+
if (!params) {
|
|
385
|
+
tracking.startExchangeNoParams(manifest);
|
|
386
|
+
throw new ServerError(createUnknownError({ message: "params is undefined" }));
|
|
387
|
+
}
|
|
383
388
|
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
const trackingParams = {
|
|
396
|
-
provider: params.provider,
|
|
397
|
-
exchangeType: params.exchangeType,
|
|
398
|
-
};
|
|
399
|
-
|
|
400
|
-
tracking.startExchangeRequested(trackingParams);
|
|
401
|
-
|
|
402
|
-
const exchangeStartParams: ExchangeStartParamsUiRequest = (await extractSwapStartParam(
|
|
403
|
-
params,
|
|
404
|
-
accounts,
|
|
405
|
-
)) as SwapStartParamsUiRequest;
|
|
406
|
-
|
|
407
|
-
const {
|
|
408
|
-
fromCurrency,
|
|
409
|
-
fromAccount,
|
|
410
|
-
fromParentAccount,
|
|
411
|
-
toCurrency,
|
|
412
|
-
toAccount,
|
|
413
|
-
toParentAccount,
|
|
414
|
-
} = exchangeStartParams.exchange;
|
|
415
|
-
|
|
416
|
-
if (!fromAccount || !fromCurrency) {
|
|
417
|
-
throw new ServerError(createAccountNotFound(params.fromAccountId));
|
|
418
|
-
}
|
|
389
|
+
const {
|
|
390
|
+
provider,
|
|
391
|
+
fromAmount,
|
|
392
|
+
fromAmountAtomic,
|
|
393
|
+
quoteId,
|
|
394
|
+
toNewTokenId,
|
|
395
|
+
customFeeConfig,
|
|
396
|
+
swapAppVersion,
|
|
397
|
+
sponsored,
|
|
398
|
+
isEmbedded,
|
|
399
|
+
} = params;
|
|
419
400
|
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
? toParentAccount.freshAddress
|
|
426
|
-
: (toAccount as Account).freshAddress;
|
|
427
|
-
|
|
428
|
-
// Step 1: Open the drawer and open exchange app
|
|
429
|
-
const startExchange = async () => {
|
|
430
|
-
return new Promise<{ transactionId: string; device?: ExchangeStartResult["device"] }>(
|
|
431
|
-
(resolve, reject) => {
|
|
432
|
-
uiExchangeStart({
|
|
433
|
-
exchangeParams: exchangeStartParams,
|
|
434
|
-
onSuccess: (nonce, device) => {
|
|
435
|
-
tracking.startExchangeSuccess(trackingParams);
|
|
436
|
-
resolve({ transactionId: nonce, device });
|
|
437
|
-
},
|
|
438
|
-
onCancel: error => {
|
|
439
|
-
tracking.startExchangeFail(trackingParams);
|
|
440
|
-
reject(error);
|
|
441
|
-
},
|
|
442
|
-
});
|
|
443
|
-
},
|
|
444
|
-
);
|
|
445
|
-
};
|
|
446
|
-
|
|
447
|
-
const { transactionId, device: deviceInfo } = await startExchange();
|
|
448
|
-
|
|
449
|
-
const {
|
|
450
|
-
binaryPayload,
|
|
451
|
-
signature,
|
|
452
|
-
payinAddress,
|
|
453
|
-
swapId,
|
|
454
|
-
payinExtraId,
|
|
455
|
-
extraTransactionParameters,
|
|
456
|
-
} = await retrieveSwapPayload({
|
|
457
|
-
provider,
|
|
458
|
-
deviceTransactionId: transactionId,
|
|
459
|
-
fromAccountAddress,
|
|
460
|
-
toAccountAddress,
|
|
461
|
-
fromAccountCurrency: fromCurrency!.id,
|
|
462
|
-
toAccountCurrency: toCurrency!.id,
|
|
463
|
-
amount: fromAmount,
|
|
464
|
-
amountInAtomicUnit: fromAmountAtomic,
|
|
465
|
-
quoteId,
|
|
466
|
-
toNewTokenId,
|
|
467
|
-
}).catch((error: Error) => {
|
|
468
|
-
throw error;
|
|
469
|
-
});
|
|
470
|
-
|
|
471
|
-
// Complete Swap
|
|
472
|
-
const trackingCompleteParams = {
|
|
473
|
-
provider: params.provider,
|
|
474
|
-
exchangeType: params.exchangeType,
|
|
475
|
-
};
|
|
476
|
-
tracking.completeExchangeRequested(trackingCompleteParams);
|
|
477
|
-
|
|
478
|
-
const strategyData = {
|
|
479
|
-
recipient: payinAddress,
|
|
480
|
-
amount: fromAmountAtomic,
|
|
481
|
-
currency: fromCurrency as CryptoOrTokenCurrency,
|
|
482
|
-
customFeeConfig: customFeeConfig ?? {},
|
|
483
|
-
payinExtraId,
|
|
484
|
-
extraTransactionParameters,
|
|
485
|
-
sponsored,
|
|
486
|
-
};
|
|
487
|
-
|
|
488
|
-
const transaction: Transaction = await getStrategy(strategyData, "swap").catch(
|
|
489
|
-
async error => {
|
|
490
|
-
throw error;
|
|
491
|
-
},
|
|
492
|
-
);
|
|
401
|
+
const trackingParams = {
|
|
402
|
+
provider: params.provider,
|
|
403
|
+
exchangeType: params.exchangeType,
|
|
404
|
+
isEmbeddedSwap: isEmbedded,
|
|
405
|
+
};
|
|
493
406
|
|
|
494
|
-
|
|
407
|
+
tracking.startExchangeRequested(trackingParams);
|
|
495
408
|
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
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
|
+
}
|
|
503
426
|
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
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
|
+
};
|
|
530
453
|
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
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
|
+
}
|
|
537
469
|
|
|
538
|
-
|
|
539
|
-
|
|
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
|
+
});
|
|
540
496
|
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
swapId: swapId,
|
|
559
|
-
amountExpectedTo: amountExpectedTo.toNumber(),
|
|
560
|
-
magnitudeAwareRate,
|
|
561
|
-
refundAddress,
|
|
562
|
-
payoutAddress,
|
|
563
|
-
sponsored,
|
|
564
|
-
},
|
|
565
|
-
onSuccess: ({ operationHash, swapId }: { operationHash: string; swapId: string }) => {
|
|
566
|
-
tracking.completeExchangeSuccess({
|
|
567
|
-
...trackingParams,
|
|
568
|
-
currency: transaction.family,
|
|
569
|
-
});
|
|
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
|
+
};
|
|
570
514
|
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
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;
|
|
582
535
|
|
|
583
|
-
|
|
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,
|
|
584
546
|
},
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
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,
|
|
588
581
|
swapId: swapId,
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
errorMessage: error.message,
|
|
592
|
-
sourceCurrencyId: fromCurrency.id,
|
|
593
|
-
targetCurrencyId: toCurrency?.id,
|
|
594
|
-
hardwareWalletType: deviceInfo?.modelId as DeviceModelId,
|
|
595
|
-
swapType: quoteId ? "fixed" : "float",
|
|
596
|
-
swapAppVersion,
|
|
597
|
-
fromAccountAddress,
|
|
598
|
-
toAccountAddress,
|
|
582
|
+
amountExpectedTo: amountExpectedTo.toNumber(),
|
|
583
|
+
magnitudeAwareRate,
|
|
599
584
|
refundAddress,
|
|
600
585
|
payoutAddress,
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
:
|
|
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,
|
|
607
656
|
});
|
|
657
|
+
});
|
|
608
658
|
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
})
|
|
612
|
-
|
|
659
|
+
await handleErrors(error, {
|
|
660
|
+
onDisplayError: displayError,
|
|
661
|
+
});
|
|
662
|
+
|
|
663
|
+
throw error;
|
|
664
|
+
}
|
|
613
665
|
}),
|
|
614
666
|
|
|
615
667
|
"custom.isReady": customWrapper<void, void>(async () => {
|
|
@@ -831,21 +883,21 @@ async function getStrategy(
|
|
|
831
883
|
}
|
|
832
884
|
}
|
|
833
885
|
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
)
|
|
850
|
-
|
|
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
|
+
);
|
|
851
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
|