diff --git a/packages/checkout/widgets-lib/src/locales/en.json b/packages/checkout/widgets-lib/src/locales/en.json
index 6c751ce2f0..1b0882b858 100644
--- a/packages/checkout/widgets-lib/src/locales/en.json
+++ b/packages/checkout/widgets-lib/src/locales/en.json
@@ -793,12 +793,36 @@
"subHeading": "Confirm the transaction request to complete this transaction"
},
"executing": {
- "heading": "Processing"
+ "heading": "Processing",
+ "subHeadingDuration": "This should take {{duration}}",
+ "subHeading": "Go to Axelarscan for transaction details"
},
"executed": {
- "heading": "Funds added successfully",
- "subHeadingGoTo": "Go to",
- "subHeadingTransactionDetails": "for transaction details"
+ "heading": "Tokens Added",
+ "subHeading": "Go to Axelarscan for transaction details",
+ "primaryButtonText": "Done"
+ },
+ "executedZkEVM": {
+ "heading": "Tokens Added",
+ "subHeading": "Go to Immutable zkEVM explorer for transaction details",
+ "primaryButtonText": "Done"
+ },
+ "needsGas": {
+ "heading": "Gas has surged",
+ "subHeading": "You’ll need to pay more gas to complete this transaction. You can do this via Axelarscan.",
+ "primaryButtonText": "Go to Axelarscan",
+ "secondaryButtonText": "Dismiss"
+ },
+ "partialSuccess": {
+ "heading": "You’ve received axlUSDC",
+ "subHeading": "Your transaction was subject to slippage and you’ve received axlUSDC. To receive the token you intended to add, you may need to complete a swap via Squid. ",
+ "primaryButtonText": "Go to Squid",
+ "secondaryButtonText": "Dismiss"
+ },
+ "statusFailed": {
+ "heading": "Unable to complete transaction",
+ "subHeading": "Something went wrong, and we were unable to complete this transaction. Visit Axelarscan for details.",
+ "secondaryButtonText": "Dismiss"
}
},
"onboarding": {
diff --git a/packages/checkout/widgets-lib/src/locales/ja.json b/packages/checkout/widgets-lib/src/locales/ja.json
index bf0f5a3971..361fc8b034 100644
--- a/packages/checkout/widgets-lib/src/locales/ja.json
+++ b/packages/checkout/widgets-lib/src/locales/ja.json
@@ -776,12 +776,36 @@
"subHeading": "取引リクエストを確認してこの取引を完了してください"
},
"executing": {
- "heading": "処理中"
+ "heading": "処理中",
+ "subHeadingDuration": "この処理には{{duration}}かかります",
+ "subHeading": "Axelarscanでトランザクションの詳細をご確認ください"
},
"executed": {
- "heading": "資金が正常に追加されました",
- "subHeadingGoTo": "移動",
- "subHeadingTransactionDetails": "取引詳細はこちら"
+ "heading": "トークンが追加されました",
+ "subHeading": "Axelarscanでトランザクションの詳細をご確認ください",
+ "primaryButtonText": "完了"
+ },
+ "executedZkEVM": {
+ "heading": "トークンが追加されました",
+ "subHeading": "Immutable zkEVM explorerでトランザクションの詳細をご確認ください",
+ "primaryButtonText": "完了"
+ },
+ "needsGas": {
+ "heading": "ガス料金が急騰しました",
+ "subHeading": "このトランザクションを完了するためには、さらにガス料金を支払う必要があります。Axelarscanで手続きを行えます。",
+ "primaryButtonText": "Axelarscanに移動",
+ "secondaryButtonText": "閉じる"
+ },
+ "partialSuccess": {
+ "heading": "axlUSDCを受け取りました",
+ "subHeading": "トランザクションはスリッページの影響を受け、axlUSDCを受け取りました。意図したトークンを受け取るには、Squidでスワップを完了する必要があります。",
+ "primaryButtonText": "Squidに移動",
+ "secondaryButtonText": "閉じる"
+ },
+ "statusFailed": {
+ "heading": "トランザクションを完了できませんでした",
+ "subHeading": "問題が発生し、トランザクションを完了できませんでした。詳細はAxelarscanをご確認ください。",
+ "secondaryButtonText": "閉じる"
}
},
"onboarding": {
diff --git a/packages/checkout/widgets-lib/src/locales/ko.json b/packages/checkout/widgets-lib/src/locales/ko.json
index eca668a4bd..31169ba489 100644
--- a/packages/checkout/widgets-lib/src/locales/ko.json
+++ b/packages/checkout/widgets-lib/src/locales/ko.json
@@ -773,12 +773,36 @@
"subHeading": "거래 요청을 확인하여 이 거래를 완료하세요"
},
"executing": {
- "heading": "처리 중"
+ "heading": "처리 중",
+ "subHeadingDuration": "이 작업은 {{duration}} 소요됩니다",
+ "subHeading": "트랜잭션 세부 정보는 Axelarscan에서 확인하세요"
},
"executed": {
- "heading": "자금이 성공적으로 추가되었습니다",
- "subHeadingGoTo": "이동",
- "subHeadingTransactionDetails": "거래 세부 정보 보기"
+ "heading": "토큰이 추가되었습니다",
+ "subHeading": "트랜잭션 세부 정보는 Axelarscan에서 확인하세요",
+ "primaryButtonText": "완료"
+ },
+ "executedZkEVM": {
+ "heading": "토큰이 추가되었습니다",
+ "subHeading": "트랜잭션 세부 정보는 Immutable zkEVM explorer에서 확인하세요",
+ "primaryButtonText": "완료"
+ },
+ "needsGas": {
+ "heading": "가스 요금 급등",
+ "subHeading": "이 트랜잭션을 완료하려면 더 높은 가스 요금을 지불해야 합니다. Axelarscan에서 진행할 수 있습니다.",
+ "primaryButtonText": "Axelarscan으로 이동",
+ "secondaryButtonText": "닫기"
+ },
+ "partialSuccess": {
+ "heading": "axlUSDC를 받았습니다",
+ "subHeading": "트랜잭션이 슬리피지에 영향을 받아 axlUSDC를 받았습니다. 의도한 토큰을 받으려면 Squid에서 스왑을 완료해야 할 수 있습니다.",
+ "primaryButtonText": "Squid로 이동",
+ "secondaryButtonText": "닫기"
+ },
+ "statusFailed": {
+ "heading": "트랜잭션을 완료할 수 없습니다",
+ "subHeading": "문제가 발생하여 트랜잭션을 완료할 수 없습니다. 자세한 내용은 Axelarscan에서 확인하세요.",
+ "secondaryButtonText": "닫기"
}
},
"onboarding": {
diff --git a/packages/checkout/widgets-lib/src/locales/zh.json b/packages/checkout/widgets-lib/src/locales/zh.json
index d7c0cd1080..ca6c1a8821 100644
--- a/packages/checkout/widgets-lib/src/locales/zh.json
+++ b/packages/checkout/widgets-lib/src/locales/zh.json
@@ -773,12 +773,36 @@
"subHeading": "确认交易请求以完成此交易"
},
"executing": {
- "heading": "处理中"
+ "heading": "处理中",
+ "subHeadingDuration": "预计耗时{{duration}}",
+ "subHeading": "您可以前往Axelarscan查看交易详情"
},
"executed": {
- "heading": "资金添加成功",
- "subHeadingGoTo": "前往",
- "subHeadingTransactionDetails": "查看交易详情"
+ "heading": "代币已添加",
+ "subHeading": "您可以前往Axelarscan查看交易详情",
+ "primaryButtonText": "完成"
+ },
+ "executedZkEVM": {
+ "heading": "代币已添加",
+ "subHeading": "您可以前往Immutable zkEVM explorer查看交易详情",
+ "primaryButtonText": "完成"
+ },
+ "needsGas": {
+ "heading": "Gas费用激增",
+ "subHeading": "完成此交易需要支付更高的Gas费用。您可以通过Axelarscan完成。",
+ "primaryButtonText": "前往Axelarscan",
+ "secondaryButtonText": "关闭"
+ },
+ "partialSuccess": {
+ "heading": "您已收到axlUSDC",
+ "subHeading": "交易受到滑点影响,您已收到axlUSDC。如需获得目标代币,可能需要通过Squid完成兑换。",
+ "primaryButtonText": "前往Squid",
+ "secondaryButtonText": "关闭"
+ },
+ "statusFailed": {
+ "heading": "交易未能完成",
+ "subHeading": "交易发生错误,未能完成。详情请前往Axelarscan查看。",
+ "secondaryButtonText": "关闭"
}
},
"onboarding": {
diff --git a/packages/checkout/widgets-lib/src/widgets/add-tokens/hooks/useExecute.ts b/packages/checkout/widgets-lib/src/widgets/add-tokens/hooks/useExecute.ts
index 0606cc4160..8d3d50b704 100644
--- a/packages/checkout/widgets-lib/src/widgets/add-tokens/hooks/useExecute.ts
+++ b/packages/checkout/widgets-lib/src/widgets/add-tokens/hooks/useExecute.ts
@@ -4,6 +4,8 @@ import { RouteResponse } from '@0xsquid/squid-types';
import { Squid } from '@0xsquid/sdk';
import { ethers } from 'ethers';
import { Environment } from '@imtbl/config';
+
+import { StatusResponse } from '@0xsquid/sdk/dist/types';
import { isSquidNativeToken } from '../functions/isSquidNativeToken';
import { useError } from './useError';
import { AddTokensError, AddTokensErrorTypes } from '../types';
@@ -13,6 +15,8 @@ import { retry } from '../../../lib/retry';
import { withMetricsAsync } from '../../../lib/metrics';
import { UserJourney } from '../../../context/analytics-provider/SegmentAnalyticsProvider';
+const TRANSACTION_NOT_COMPLETED = 'transaction not completed';
+
export const useExecute = (contextId: string, environment: Environment) => {
const { showErrorHandover } = useError(environment);
const {
@@ -165,7 +169,7 @@ export const useExecute = (contextId: string, environment: Environment) => {
const callApprove = async (
provider: Web3Provider,
routeResponse: RouteResponse,
- ):Promise => {
+ ): Promise => {
const erc20Abi = [
'function approve(address spender, uint256 amount) public returns (bool)',
];
@@ -212,7 +216,7 @@ export const useExecute = (contextId: string, environment: Environment) => {
squid: Squid,
provider: Web3Provider,
routeResponse: RouteResponse,
- ):Promise => {
+ ): Promise => {
const tx = (await squid.executeRoute({
signer: provider.getSigner(),
route: routeResponse.route,
@@ -239,10 +243,53 @@ export const useExecute = (contextId: string, environment: Environment) => {
}
};
+ const getStatus = async (
+ squid: Squid,
+ transactionHash: string,
+ ): Promise => {
+ const completedTransactionStatus = [
+ 'success',
+ 'partial_success',
+ 'needs_gas',
+ 'not_found',
+ ];
+ try {
+ return await retry(
+ async () => {
+ const result = await squid.getStatus({
+ transactionId: transactionHash,
+ });
+ if (
+ completedTransactionStatus.includes(
+ result.squidTransactionStatus ?? '',
+ )
+ ) {
+ return result;
+ }
+ return Promise.reject(TRANSACTION_NOT_COMPLETED);
+ },
+ {
+ retries: 240,
+ retryIntervalMs: 5000,
+ nonRetryable: (err) => {
+ if (err.response) {
+ return err.response.status === 400 || err.response.status === 500;
+ }
+ return err !== TRANSACTION_NOT_COMPLETED;
+ },
+ },
+ );
+ } catch (error) {
+ handleTransactionError(error);
+ return undefined;
+ }
+ };
+
return {
checkProviderChain,
getAllowance,
approve,
execute,
+ getStatus,
};
};
diff --git a/packages/checkout/widgets-lib/src/widgets/add-tokens/utils/config.ts b/packages/checkout/widgets-lib/src/widgets/add-tokens/utils/config.ts
index 93ee26afe0..e6d18f9152 100644
--- a/packages/checkout/widgets-lib/src/widgets/add-tokens/utils/config.ts
+++ b/packages/checkout/widgets-lib/src/widgets/add-tokens/utils/config.ts
@@ -8,4 +8,8 @@ export const APPROVE_TXN_ANIMATION = '/access_coins.riv';
export const EXECUTE_TXN_ANIMATION = '/swapping_coins.riv';
+export const BLOCK_TXN_ANIMATION = '/blocked.riv';
+
+export const ERROR_TXN_ANIMATION = '/error.riv';
+
export const TOKEN_PRIORITY_ORDER = ['IMX', 'USDC', 'ETH'];
diff --git a/packages/checkout/widgets-lib/src/widgets/add-tokens/views/Review.tsx b/packages/checkout/widgets-lib/src/widgets/add-tokens/views/Review.tsx
index 1e891392d7..1fde35da82 100644
--- a/packages/checkout/widgets-lib/src/widgets/add-tokens/views/Review.tsx
+++ b/packages/checkout/widgets-lib/src/widgets/add-tokens/views/Review.tsx
@@ -24,6 +24,7 @@ import {
} from '@biom3/react';
import { RouteResponse } from '@0xsquid/squid-types';
import { t } from 'i18next';
+import { Trans } from 'react-i18next';
import { Environment } from '@imtbl/config';
import { SimpleLayout } from '../../../components/SimpleLayout/SimpleLayout';
import { AddTokensContext } from '../context/AddTokensContext';
@@ -65,11 +66,14 @@ import {
getFormattedNumber,
getFormattedNumberWithDecimalPlaces,
} from '../functions/getFormattedNumber';
-import { convertToNetworkChangeableProvider } from '../functions/convertToNetworkChangeableProvider';
import { SquidFooter } from '../components/SquidFooter';
import { useError } from '../hooks/useError';
-import { sendAddTokensSuccessEvent } from '../AddTokensWidgetEvents';
+import {
+ sendAddTokensCloseEvent,
+ sendAddTokensSuccessEvent,
+} from '../AddTokensWidgetEvents';
import { EventTargetContext } from '../../../context/event-target-context/EventTargetContext';
+import { convertToNetworkChangeableProvider } from '../functions/convertToNetworkChangeableProvider';
interface ReviewProps {
data: AddTokensReviewData;
@@ -108,7 +112,9 @@ export function Review({
},
} = useProvidersContext();
- const { eventTargetState: { eventTarget } } = useContext(EventTargetContext);
+ const {
+ eventTargetState: { eventTarget },
+ } = useContext(EventTargetContext);
const [route, setRoute] = useState();
const [proceedDisabled, setProceedDisabled] = useState(true);
@@ -122,10 +128,7 @@ export function Review({
const { showErrorHandover } = useError(checkout.config.environment);
const {
- checkProviderChain,
- getAllowance,
- approve,
- execute,
+ checkProviderChain, getAllowance, approve, execute, getStatus,
} = useExecute(id, checkout?.config.environment || Environment.SANDBOX);
useEffect(() => {
@@ -202,7 +205,9 @@ export function Review({
}}
>
{t('views.ADD_TOKENS.fees.includedFees')}
- {` ${t('views.ADD_TOKENS.fees.fiatPricePrefix')} $${getFormattedAmounts(totalFeesUsd)}`}
+ {` ${t(
+ 'views.ADD_TOKENS.fees.fiatPricePrefix',
+ )} $${getFormattedAmounts(totalFeesUsd)}`}
void;
+ secondaryButtonText?: string;
+ onSecondaryButtonClick?: () => void;
+ duration?: number;
+ }
+
const showHandover = useCallback(
- (
- animationPath: string,
- state: RiveStateMachineInput,
- headingText: string,
- subheadingText?: ReactNode,
- duration?: number,
- ) => {
+ ({
+ animationPath,
+ state,
+ headingText,
+ subheadingText,
+ primaryButtonText,
+ onPrimaryButtonClick,
+ secondaryButtonText,
+ onSecondaryButtonClick,
+ duration,
+ }: HandoverProps) => {
addHandover({
animationUrl: getRemoteRive(
checkout?.config.environment,
@@ -244,6 +265,10 @@ export function Review({
),
});
@@ -278,7 +303,10 @@ export function Review({
try {
currentFromAddress = await fromProvider.getSigner().getAddress();
} catch (error) {
- showErrorHandover(AddTokensErrorTypes.PROVIDER_ERROR, { contextId: id, error });
+ showErrorHandover(AddTokensErrorTypes.PROVIDER_ERROR, {
+ contextId: id,
+ error,
+ });
return;
}
@@ -290,11 +318,11 @@ export function Review({
clearInterval(getRouteIntervalIdRef.current);
setProceedDisabled(true);
- showHandover(
- APPROVE_TXN_ANIMATION,
- RiveStateMachineInput.START,
- t('views.ADD_TOKENS.handover.preparing.heading'),
- );
+ showHandover({
+ animationPath: APPROVE_TXN_ANIMATION,
+ state: RiveStateMachineInput.START,
+ headingText: t('views.ADD_TOKENS.handover.preparing.heading'),
+ });
const changeableProvider = await convertToNetworkChangeableProvider(
fromProvider,
@@ -313,37 +341,38 @@ export function Review({
const { fromAmount } = route.route.params;
if (allowance?.lt(fromAmount)) {
- showHandover(
- APPROVE_TXN_ANIMATION,
- RiveStateMachineInput.WAITING,
- t('views.ADD_TOKENS.handover.requestingApproval.heading'),
- t('views.ADD_TOKENS.handover.requestingApproval.subHeading'),
- );
+ showHandover({
+ animationPath: APPROVE_TXN_ANIMATION,
+ state: RiveStateMachineInput.WAITING,
+ headingText: t('views.ADD_TOKENS.handover.requestingApproval.heading'),
+ subheadingText: t(
+ 'views.ADD_TOKENS.handover.requestingApproval.subHeading',
+ ),
+ });
const approveTxnReceipt = await approve(changeableProvider, route);
if (!approveTxnReceipt) {
return;
}
-
- showHandover(
- APPROVE_TXN_ANIMATION,
- RiveStateMachineInput.COMPLETED,
- t('views.ADD_TOKENS.handover.approved.heading'),
- '',
- FIXED_HANDOVER_DURATION,
- );
+ showHandover({
+ animationPath: APPROVE_TXN_ANIMATION,
+ state: RiveStateMachineInput.COMPLETED,
+ headingText: t('views.ADD_TOKENS.handover.approved.heading'),
+ duration: FIXED_HANDOVER_DURATION,
+ });
}
- showHandover(
- EXECUTE_TXN_ANIMATION,
- RiveStateMachineInput.WAITING,
- t('views.ADD_TOKENS.handover.requestingExecution.heading'),
- t('views.ADD_TOKENS.handover.requestingExecution.subHeading'),
- );
+ showHandover({
+ animationPath: EXECUTE_TXN_ANIMATION,
+ state: RiveStateMachineInput.WAITING,
+ headingText: t('views.ADD_TOKENS.handover.requestingExecution.heading'),
+ subheadingText: t(
+ 'views.ADD_TOKENS.handover.requestingExecution.subHeading',
+ ),
+ });
const executeTxnReceipt = await execute(squid, changeableProvider, route);
-
if (executeTxnReceipt) {
track({
userJourney: UserJourney.ADD_TOKENS,
@@ -357,37 +386,220 @@ export function Review({
sendAddTokensSuccessEvent(eventTarget, executeTxnReceipt.transactionHash);
- showHandover(
- EXECUTE_TXN_ANIMATION,
- RiveStateMachineInput.PROCESSING,
- t('views.ADD_TOKENS.handover.executing.heading'),
- '',
- FIXED_HANDOVER_DURATION,
- );
+ if (toChain === fromChain) {
+ showHandover({
+ animationPath: EXECUTE_TXN_ANIMATION,
+ state: RiveStateMachineInput.COMPLETED,
+ headingText: t('views.ADD_TOKENS.handover.executedZkEVM.heading'),
+ subheadingText: (
+
+ )}
+ />
+ ),
+ }}
+ />
+ ),
+ primaryButtonText: t(
+ 'views.ADD_TOKENS.handover.executed.primaryButtonText',
+ ),
+ onPrimaryButtonClick: () => {
+ sendAddTokensCloseEvent(eventTarget);
+ },
+ });
+ return;
+ }
- showHandover(
- EXECUTE_TXN_ANIMATION,
- RiveStateMachineInput.COMPLETED,
- t('views.ADD_TOKENS.handover.executed.heading'),
- <>
- {t('views.ADD_TOKENS.handover.executed.subHeadingGoTo')}
- {' '}
-
- )}
- >
- Axelarscan
-
- {' '}
- {t('views.ADD_TOKENS.handover.executed.subHeadingTransactionDetails')}
- >,
- );
+ showHandover({
+ animationPath: EXECUTE_TXN_ANIMATION,
+ state: RiveStateMachineInput.PROCESSING,
+ headingText: t('views.ADD_TOKENS.handover.executing.heading'),
+ subheadingText: (
+ <>
+ {t('views.ADD_TOKENS.handover.executing.subHeadingDuration', {
+ duration: getDurationFormatted(
+ route.route.estimate.estimatedRouteDuration,
+ t('views.ADD_TOKENS.routeSelection.minutesText'),
+ t('views.ADD_TOKENS.routeSelection.minuteText'),
+ t('views.ADD_TOKENS.routeSelection.secondsText'),
+ ),
+ })}
+
+
+ )}
+ />
+ ),
+ }}
+ />
+ >
+ ),
+ });
+
+ const status = await getStatus(squid, executeTxnReceipt.transactionHash);
+ const axelarscanUrl = `https://axelarscan.io/gmp/${executeTxnReceipt?.transactionHash}`;
+
+ if (status?.squidTransactionStatus === 'success') {
+ showHandover({
+ animationPath: EXECUTE_TXN_ANIMATION,
+ state: RiveStateMachineInput.COMPLETED,
+ headingText: t('views.ADD_TOKENS.handover.executed.heading'),
+ subheadingText: (
+
+ )}
+ />
+ ),
+ }}
+ />
+ ),
+ primaryButtonText: t(
+ 'views.ADD_TOKENS.handover.executed.primaryButtonText',
+ ),
+ onPrimaryButtonClick: () => {
+ sendAddTokensCloseEvent(eventTarget);
+ },
+ });
+ } else if (status?.squidTransactionStatus === 'needs_gas') {
+ showHandover({
+ animationPath: APPROVE_TXN_ANIMATION,
+ state: RiveStateMachineInput.COMPLETED,
+ headingText: t('views.ADD_TOKENS.handover.needsGas.heading'),
+ subheadingText: (
+
+ )}
+ />
+ ),
+ }}
+ />
+ ),
+ primaryButtonText: t(
+ 'views.ADD_TOKENS.handover.needsGas.primaryButtonText',
+ ),
+ onPrimaryButtonClick: () => {
+ window.open(axelarscanUrl, '_blank', 'noreferrer');
+ },
+ secondaryButtonText: t(
+ 'views.ADD_TOKENS.handover.needsGas.secondaryButtonText',
+ ),
+ onSecondaryButtonClick: () => {
+ sendAddTokensCloseEvent(eventTarget);
+ },
+ });
+ } else if (status?.squidTransactionStatus === 'partial_success') {
+ showHandover({
+ animationPath: APPROVE_TXN_ANIMATION,
+ state: RiveStateMachineInput.COMPLETED,
+ headingText: t('views.ADD_TOKENS.handover.partialSuccess.heading'),
+ subheadingText: (
+
+ )}
+ />
+ ),
+ }}
+ />
+ ),
+ primaryButtonText: t(
+ 'views.ADD_TOKENS.handover.partialSuccess.primaryButtonText',
+ ),
+ onPrimaryButtonClick: () => {
+ window.open(
+ 'https://toolkit.immutable.com/squid-bridge/',
+ '_blank',
+ 'noreferrer',
+ );
+ },
+ secondaryButtonText: t(
+ 'views.ADD_TOKENS.handover.partialSuccess.secondaryButtonText',
+ ),
+ onSecondaryButtonClick: () => {
+ sendAddTokensCloseEvent(eventTarget);
+ },
+ });
+ } else {
+ showHandover({
+ animationPath: APPROVE_TXN_ANIMATION,
+ state: RiveStateMachineInput.COMPLETED,
+ headingText: t('views.ADD_TOKENS.handover.statusFailed.heading'),
+ subheadingText: (
+
+ )}
+ />
+ ),
+ }}
+ />
+ ),
+ secondaryButtonText: t(
+ 'views.ADD_TOKENS.handover.statusFailed.secondaryButtonText',
+ ),
+ onSecondaryButtonClick: () => {
+ sendAddTokensCloseEvent(eventTarget);
+ },
+ });
+ }
}
}, [
route,
@@ -515,7 +727,9 @@ export function Review({
sx={{ flexShrink: 0, alignSelf: 'flex-start' }}
>
- {`${t('views.ADD_TOKENS.fees.fiatPricePrefix')} $${route?.route.estimate.fromAmountUSD ?? ''}`}
+ {`${t('views.ADD_TOKENS.fees.fiatPricePrefix')} $${
+ route?.route.estimate.fromAmountUSD ?? ''
+ }`}
@@ -569,12 +783,13 @@ export function Review({
{t('views.ADD_TOKENS.review.poweredBySquid')}
1
- {' '}
{route.route.estimate.fromToken.symbol}
{' '}
=
{' '}
- {getFormattedNumberWithDecimalPlaces(route.route.estimate.exchangeRate)}
+ {getFormattedNumberWithDecimalPlaces(
+ route.route.estimate.exchangeRate,
+ )}
{' '}
{route.route.estimate.toToken.name}