@imtbl/sdk 1.77.4 → 1.77.5-alpha.2
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/dist/{blockchain_data-CSSYwdB-.js → blockchain_data-B74t5SqC.js} +2 -2
- package/dist/blockchain_data.js +3 -3
- package/dist/browser/checkout/{AddTokensWidget-CzAE1d3f.js → AddTokensWidget-ho7XUYky.js} +299 -266
- package/dist/browser/checkout/{BridgeWidget-6snvryex.js → BridgeWidget-CQwF01Ph.js} +9 -9
- package/dist/browser/checkout/{CommerceWidget-BQzxxBBp.js → CommerceWidget-CKBMeuAb.js} +17 -17
- package/dist/browser/checkout/{CryptoFiatProvider-DrL1vFka.js → CryptoFiatProvider-CrDHcmXp.js} +1 -1
- package/dist/browser/checkout/{FeesBreakdown-6N1PBhxc.js → FeesBreakdown-DgXe6Fa2.js} +1 -1
- package/dist/browser/checkout/{HandoverContent-DACeI3Ql.js → HandoverContent-CnLMKDDD.js} +1 -1
- package/dist/browser/checkout/{OnRampWidget-C27NOCDj.js → OnRampWidget-vzsjg7qL.js} +3 -3
- package/dist/browser/checkout/{SaleWidget-0wqfnQkL.js → SaleWidget-BfRakz0n.js} +14 -14
- package/dist/browser/checkout/{SpendingCapHero-se43V9Us.js → SpendingCapHero-CPj8E77p.js} +1 -1
- package/dist/browser/checkout/{SwapWidget-DL3WYUw9.js → SwapWidget-BzWepYEh.js} +9 -9
- package/dist/browser/checkout/{TokenImage-Im5drCmP.js → TokenImage-BIsOhmpw.js} +1 -1
- package/dist/browser/checkout/{TopUpView-h8yzvXWl.js → TopUpView-CmCvLBsf.js} +3 -3
- package/dist/browser/checkout/{WalletApproveHero-ByDRA_kK.js → WalletApproveHero-CxN_lwFf.js} +3 -3
- package/dist/browser/checkout/{WalletWidget-BRLER2vp.js → WalletWidget-uHMLosBc.js} +4 -4
- package/dist/browser/checkout/{auto-track-D_sVcc3q.js → auto-track-DhKG-Aj-.js} +1 -1
- package/dist/browser/checkout/{index-C6VrFT0d.js → index-B6MDZ65f.js} +1 -1
- package/dist/browser/checkout/{index-CpPB7WU9.js → index-BXHgeq5K.js} +1 -1
- package/dist/browser/checkout/{index-CLIIegap.js → index-BZBtvKSM.js} +1 -1
- package/dist/browser/checkout/{index-DIgPyYaY.js → index-CN4mb1eI.js} +1 -1
- package/dist/browser/checkout/{index-ZsTq7hP6.js → index-CThUeEZD.js} +2 -2
- package/dist/browser/checkout/{index-CU8j8oV7.js → index-CdH6Dx3k.js} +1 -1
- package/dist/browser/checkout/{index-D-6LYeBT.js → index-CmhfOYK-.js} +1 -1
- package/dist/browser/checkout/{index-D7zuN_2m.js → index-DD7N6gXr.js} +19 -19
- package/dist/browser/checkout/{index-Ciq_hY6N.js → index-DRsZuMPh.js} +1 -1
- package/dist/browser/checkout/{index-BrPk4SVq.js → index-DTvOW3g2.js} +1 -1
- package/dist/browser/checkout/{index.umd-BTRWYRB0.js → index.umd-BeA2p5DE.js} +1 -1
- package/dist/browser/checkout/sdk.js +4 -4
- package/dist/browser/checkout/{useInterval-DeDgB1gY.js → useInterval-CA09xlan.js} +1 -1
- package/dist/browser/checkout/widgets-esm.js +1 -1
- package/dist/browser/checkout/widgets.js +1143 -1055
- package/dist/{checkout-rc8rFe_T.js → checkout-7WFS_XJj.js} +5 -5
- package/dist/checkout.js +5 -5
- package/dist/{config-B14s5Yki.js → config-BxW6HRZg.js} +1 -1
- package/dist/config.js +1 -1
- package/dist/{index-BJw8kxPo.js → index-B9MfkDaq.js} +1 -1
- package/dist/{index-B6tCwHSk.js → index-BhuY1-GF.js} +3 -3
- package/dist/{index-DaUCuTCV.js → index-Bxz960C5.js} +1 -1
- package/dist/{index-BH4mFAq1.js → index-C1Pjpcef.js} +4 -4
- package/dist/{index-C-psCZRA.js → index-CktTkdn0.js} +1 -1
- package/dist/{index-DvANTswe.js → index-DF-RI8Zc.js} +1 -1
- package/dist/index.browser.js +4 -4
- package/dist/index.browser.js.map +1 -1
- package/dist/index.cjs +7 -7
- package/dist/index.js +14 -14
- package/dist/{minting_backend-CEy7Phcq.js → minting_backend-Ch5w3R8k.js} +3 -3
- package/dist/minting_backend.js +5 -5
- package/dist/{orderbook-BCx_6zlr.js → orderbook-D5HBZMmK.js} +1 -1
- package/dist/orderbook.js +2 -2
- package/dist/{passport-Cl4qWc0E.js → passport-BBQ8BLmA.js} +3 -3
- package/dist/passport.js +4 -4
- package/dist/version.json +1 -1
- package/dist/{webhook-DETmXUX7.js → webhook-UHB7iiVR.js} +1 -1
- package/dist/webhook.js +2 -2
- package/dist/{x-D9HTgYe2.js → x-DPqmRzAY.js} +3 -3
- package/dist/x.js +4 -4
- package/package.json +1 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { r as reactExports, I as IMTBLWidgetEvents, A as AddTokensEventType, w as getDefaultExportFromCjs, x as commonjsGlobal, y as
|
|
2
|
-
import { r as retry, T as TokenImage } from './TokenImage-
|
|
3
|
-
import {
|
|
4
|
-
import { H as HandoverContent } from './HandoverContent-
|
|
5
|
-
import { C as Contract } from './index-
|
|
6
|
-
import { F as FeesBreakdown } from './FeesBreakdown-
|
|
1
|
+
import { r as reactExports, I as IMTBLWidgetEvents, A as AddTokensEventType, w as getDefaultExportFromCjs, x as commonjsGlobal, y as BigNumber, z as useProvidersContext, D as isPassportProvider, o as jsx, p as jsxs, F as Box, u as useTranslation, G as Drawer, H as Divider, J as Heading, K as Button, M as useAnalytics, N as WalletDrawer, U as UnableToConnectDrawer, Q as Fragment, R as WalletProviderRdns, T as UserJourney, X as removeSpace, Y as getProviderSlugFromRdns, Z as Web3Provider, _ as connectEIP6963Provider, $ as identifyUser, a0 as ConnectEIP6963ProviderError, a1 as ProvidersContextActions, a2 as MenuItem, j as ChainId, a3 as commonjsRequire, a4 as getRemoteImage, a5 as vFlex, a6 as OnboardingPagination, a7 as ViewContext, a8 as useHandover, a9 as HandoverTarget, aa as EventTargetContext, V as ViewActions, ab as getRemoteRive, ac as Trans, ad as Link, ae as Body, af as keyframes, ag as getDefaultTokenImage, ah as TokenFilterTypes, h as getL2ChainId, ai as isNativeToken, aj as getTokenImageByAddress, ak as SmartClone, al as FramedImage, am as FramedIcon, an as ButtCon, ao as TextInput, ap as VerticalMenu, aq as EllipsizedText, ar as Tooltip, as as Sticker, at as tokenValueFormat, au as DEFAULT_TOKEN_FORMATTING_DECIMALS, av as Stack, aw as hFlex, ax as centerFlexChildren, ay as Icon, az as Badge, aA as getRemoteVideo, aB as FramedVideo, aC as listVariants, aD as motion, aE as listItemVariants, aF as Banner, aG as fetchRiskAssessment, aH as isAddressSanctioned, aI as useInjectedProviders, aJ as trackFlow, aK as HeroFormControl, aL as SimpleLayout, m as SharedViews, aM as orchestrationEvents, aN as HeroTextInput, aO as requireSecp256k1$1, aP as requireLib_commonjs, aQ as require$$0$2, aR as bech32$2, aS as bnExports$1, aT as require$$0$3, aU as getAugmentedNamespace, aV as require$$0$4, aW as minimalisticAssert, aX as require$$2, aY as hash$6, aZ as trackError, a_ as MaxUint256, a$ as merge$2, b0 as SvgIcon, b1 as WalletWarningHero, b2 as t, b3 as PriceDisplay, L as LoadingView, b4 as useTheme, b5 as viewReducer, b6 as initialViewState, b7 as Environment, b8 as isValidAddress, b9 as amountInputValidation, ba as CloudImage, E as ErrorView, bb as ServiceUnavailableErrorView } from './index-DD7N6gXr.js';
|
|
2
|
+
import { r as retry, T as TokenImage } from './TokenImage-BIsOhmpw.js';
|
|
3
|
+
import { p as parseUnits, f as formatUnits } from './index-BXHgeq5K.js';
|
|
4
|
+
import { H as HandoverContent } from './HandoverContent-CnLMKDDD.js';
|
|
5
|
+
import { C as Contract } from './index-B6MDZ65f.js';
|
|
6
|
+
import { F as FeesBreakdown } from './FeesBreakdown-DgXe6Fa2.js';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* The function `useInterval` sets up an interval that repeatedly calls a given callback function with
|
|
@@ -1312,6 +1312,18 @@ const TOOLKIT_SQUID_URL = 'https://toolkit.immutable.com/squid-bridge/';
|
|
|
1312
1312
|
const FIXED_HANDOVER_DURATION = 2000;
|
|
1313
1313
|
const TOKEN_PRIORITY_ORDER = ['IMX', 'USDC', 'ETH'];
|
|
1314
1314
|
|
|
1315
|
+
const findToken = (tokens, address, chainId) => tokens.find((value) => value.address.toLowerCase() === address.toLowerCase()
|
|
1316
|
+
&& value.chainId === chainId);
|
|
1317
|
+
|
|
1318
|
+
const isRouteToAmountGreaterThanToAmount = (routeResponse, toAmount) => {
|
|
1319
|
+
if (!routeResponse?.route?.estimate?.toAmount || !routeResponse?.route?.estimate?.toToken?.decimals) {
|
|
1320
|
+
throw new Error('Invalid route response or token decimals');
|
|
1321
|
+
}
|
|
1322
|
+
const toAmountInBaseUnits = parseUnits(toAmount, routeResponse?.route.estimate.toToken.decimals);
|
|
1323
|
+
const routeToAmountInBaseUnits = BigNumber.from(routeResponse.route.estimate.toAmount);
|
|
1324
|
+
return routeToAmountInBaseUnits.gt(toAmountInBaseUnits);
|
|
1325
|
+
};
|
|
1326
|
+
|
|
1315
1327
|
const BASE_SLIPPAGE_HIGH_TIER = 0.005;
|
|
1316
1328
|
const BASE_SLIPPAGE_MEDIUM_TIER = 0.01;
|
|
1317
1329
|
const BASE_SLIPPAGE_LOW_TIER = 0.015;
|
|
@@ -1329,33 +1341,35 @@ const SLIPPAGE_TIERS = {
|
|
|
1329
1341
|
value: BASE_SLIPPAGE_LOW_TIER,
|
|
1330
1342
|
},
|
|
1331
1343
|
};
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
const latestRequestIdRef = reactExports.useRef(0);
|
|
1343
|
-
const { addTokensState: { id }, addTokensDispatch } = reactExports.useContext(AddTokensContext);
|
|
1344
|
-
const { providersState: { toProvider, }, } = useProvidersContext();
|
|
1345
|
-
const { track } = useAnalytics();
|
|
1346
|
-
const setRoutes = (routes) => {
|
|
1347
|
-
addTokensDispatch({
|
|
1348
|
-
payload: {
|
|
1349
|
-
type: AddTokensActions.SET_ROUTES,
|
|
1350
|
-
routes,
|
|
1351
|
-
},
|
|
1352
|
-
});
|
|
1344
|
+
/**
|
|
1345
|
+
* Hook to calculate slippage based on thresholds
|
|
1346
|
+
*/
|
|
1347
|
+
const useSlippage = () => {
|
|
1348
|
+
const getSlippageTier = (usdAmount) => {
|
|
1349
|
+
if (usdAmount >= SLIPPAGE_TIERS.high.threshold)
|
|
1350
|
+
return SLIPPAGE_TIERS.high.value;
|
|
1351
|
+
if (usdAmount >= SLIPPAGE_TIERS.medium.threshold)
|
|
1352
|
+
return SLIPPAGE_TIERS.medium.value;
|
|
1353
|
+
return SLIPPAGE_TIERS.low.value;
|
|
1353
1354
|
};
|
|
1354
|
-
const
|
|
1355
|
-
|
|
1355
|
+
const calculateAdjustedAmount = (baseAmount, usdAmount, additionalBuffer = 0) => {
|
|
1356
|
+
const slippage = getSlippageTier(usdAmount);
|
|
1357
|
+
return baseAmount * (1 + slippage + additionalBuffer);
|
|
1356
1358
|
};
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
+
return reactExports.useMemo(() => ({
|
|
1360
|
+
getSlippageTier,
|
|
1361
|
+
calculateAdjustedAmount,
|
|
1362
|
+
}), []);
|
|
1363
|
+
};
|
|
1364
|
+
|
|
1365
|
+
/**
|
|
1366
|
+
* Hook to handle route amount calculations.
|
|
1367
|
+
*/
|
|
1368
|
+
const useRouteCalculation = () => {
|
|
1369
|
+
const { calculateAdjustedAmount } = useSlippage();
|
|
1370
|
+
/**
|
|
1371
|
+
* Calculate the fromAmount based on USD prices and slippage.
|
|
1372
|
+
*/
|
|
1359
1373
|
const calculateFromAmount = (fromToken, toToken, toAmount, additionalBuffer = 0) => {
|
|
1360
1374
|
const toAmountNumber = parseFloat(toAmount);
|
|
1361
1375
|
// Calculate the USD value of the toAmount
|
|
@@ -1363,16 +1377,49 @@ const useRoutes = () => {
|
|
|
1363
1377
|
// Calculate the amount of fromToken needed to match this USD value
|
|
1364
1378
|
const baseFromAmount = toAmountInUsd / fromToken.usdPrice;
|
|
1365
1379
|
// Add a buffer for price fluctuations and fees
|
|
1366
|
-
const fromAmountWithBuffer = baseFromAmount
|
|
1380
|
+
const fromAmountWithBuffer = calculateAdjustedAmount(baseFromAmount, toAmountInUsd, additionalBuffer);
|
|
1367
1381
|
return fromAmountWithBuffer.toString();
|
|
1368
1382
|
};
|
|
1383
|
+
/**
|
|
1384
|
+
* Calculate the fromAmount using exchange rate returned from the route.
|
|
1385
|
+
*/
|
|
1369
1386
|
const calculateFromAmountFromRoute = (exchangeRate, toAmount, toAmountUSD) => {
|
|
1370
1387
|
const toAmountUSDNumber = toAmountUSD ? parseFloat(toAmountUSD) : 0;
|
|
1371
1388
|
const fromAmount = parseFloat(toAmount) / parseFloat(exchangeRate);
|
|
1372
|
-
const fromAmountWithBuffer = fromAmount
|
|
1389
|
+
const fromAmountWithBuffer = calculateAdjustedAmount(fromAmount, toAmountUSDNumber);
|
|
1373
1390
|
return fromAmountWithBuffer.toString();
|
|
1374
1391
|
};
|
|
1375
|
-
|
|
1392
|
+
/**
|
|
1393
|
+
* Convert a string amount to a formatted amount with the specified number of decimals.
|
|
1394
|
+
*/
|
|
1395
|
+
const convertToFormattedFromAmount = (amount, decimals) => {
|
|
1396
|
+
const parsedFromAmount = parseFloat(amount).toFixed(decimals);
|
|
1397
|
+
const formattedFromAmount = parseUnits(parsedFromAmount, decimals);
|
|
1398
|
+
return formattedFromAmount.toString();
|
|
1399
|
+
};
|
|
1400
|
+
return reactExports.useMemo(() => ({
|
|
1401
|
+
calculateFromAmount,
|
|
1402
|
+
calculateFromAmountFromRoute,
|
|
1403
|
+
convertToFormattedFromAmount,
|
|
1404
|
+
}), []);
|
|
1405
|
+
};
|
|
1406
|
+
|
|
1407
|
+
class RouteError extends Error {
|
|
1408
|
+
message;
|
|
1409
|
+
data;
|
|
1410
|
+
constructor(message, data) {
|
|
1411
|
+
super(message);
|
|
1412
|
+
this.message = message;
|
|
1413
|
+
this.data = data;
|
|
1414
|
+
Object.setPrototypeOf(this, RouteError.prototype);
|
|
1415
|
+
}
|
|
1416
|
+
}
|
|
1417
|
+
|
|
1418
|
+
const useRoutes = () => {
|
|
1419
|
+
const latestRequestIdRef = reactExports.useRef(0);
|
|
1420
|
+
const { providersState: { toProvider, }, } = useProvidersContext();
|
|
1421
|
+
const { calculateFromAmount, calculateFromAmountFromRoute, convertToFormattedFromAmount } = useRouteCalculation();
|
|
1422
|
+
const getFromAmountData = (tokens, balance, toAmount, toChainId, toTokenAddress, additionalBuffer = 0) => {
|
|
1376
1423
|
const fromToken = findToken(tokens, balance.address, balance.chainId.toString());
|
|
1377
1424
|
const toToken = findToken(tokens, toTokenAddress, toChainId);
|
|
1378
1425
|
if (!fromToken || !toToken) {
|
|
@@ -1390,114 +1437,48 @@ const useRoutes = () => {
|
|
|
1390
1437
|
const getSufficientFromAmounts = (tokens, balances, toChainId, toTokenAddress, toAmount) => {
|
|
1391
1438
|
const filteredBalances = balances.filter((balance) => !(balance.address.toLowerCase() === toTokenAddress.toLowerCase()
|
|
1392
1439
|
&& balance.chainId === toChainId));
|
|
1393
|
-
const
|
|
1394
|
-
.map((balance) =>
|
|
1440
|
+
const fromAmountDataArray = filteredBalances
|
|
1441
|
+
.map((balance) => getFromAmountData(tokens, balance, toAmount, toChainId, toTokenAddress))
|
|
1395
1442
|
.filter((value) => value !== undefined);
|
|
1396
|
-
return
|
|
1443
|
+
return fromAmountDataArray.filter((data) => {
|
|
1397
1444
|
const formattedBalance = formatUnits(data.balance.balance, data.balance.decimals);
|
|
1398
1445
|
return (parseFloat(formattedBalance.toString()) > parseFloat(data.fromAmount));
|
|
1399
1446
|
});
|
|
1400
1447
|
};
|
|
1401
|
-
const
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
receiveGasOnDestination: !isPassportProvider(toProvider),
|
|
1419
|
-
postHook,
|
|
1420
|
-
}), {
|
|
1421
|
-
retryIntervalMs: 1000,
|
|
1422
|
-
retries: 5,
|
|
1423
|
-
nonRetryable: (err) => err.response?.status !== 429,
|
|
1424
|
-
});
|
|
1425
|
-
}
|
|
1426
|
-
catch (error) {
|
|
1427
|
-
track({
|
|
1428
|
-
userJourney: UserJourney.ADD_TOKENS,
|
|
1429
|
-
screen: 'Routes',
|
|
1430
|
-
action: 'Failed',
|
|
1431
|
-
extras: {
|
|
1432
|
-
contextId: id,
|
|
1433
|
-
fromToken: fromToken.symbol,
|
|
1434
|
-
toToken: toToken.symbol,
|
|
1435
|
-
fromChain: fromToken.chainId,
|
|
1436
|
-
toChain: toToken.chainId,
|
|
1437
|
-
errorStatus: error.response?.status,
|
|
1438
|
-
errorMessage: error.response?.data?.message,
|
|
1439
|
-
errorStack: error.stack,
|
|
1440
|
-
},
|
|
1441
|
-
});
|
|
1442
|
-
throw error;
|
|
1443
|
-
}
|
|
1444
|
-
};
|
|
1445
|
-
const isRouteToAmountGreaterThanToAmount = (routeResponse, toAmount) => {
|
|
1446
|
-
if (!routeResponse?.route?.estimate?.toAmount || !routeResponse?.route?.estimate?.toToken?.decimals) {
|
|
1447
|
-
throw new Error('Invalid route response or token decimals');
|
|
1448
|
-
}
|
|
1449
|
-
const toAmountInBaseUnits = parseUnits(toAmount, routeResponse?.route.estimate.toToken.decimals);
|
|
1450
|
-
const routeToAmountInBaseUnits = BigNumber.from(routeResponse.route.estimate.toAmount);
|
|
1451
|
-
return routeToAmountInBaseUnits.gt(toAmountInBaseUnits);
|
|
1452
|
-
};
|
|
1448
|
+
const getRouteWithRetry = async (squid, fromToken, toToken, toAddress, fromAmount, fromAddress, quoteOnly = true, postHook) => retry(() => squid.getRoute({
|
|
1449
|
+
fromChain: fromToken.chainId,
|
|
1450
|
+
fromToken: fromToken.address,
|
|
1451
|
+
fromAmount: convertToFormattedFromAmount(fromAmount, fromToken.decimals),
|
|
1452
|
+
toChain: toToken.chainId,
|
|
1453
|
+
toToken: toToken.address,
|
|
1454
|
+
fromAddress,
|
|
1455
|
+
toAddress,
|
|
1456
|
+
quoteOnly,
|
|
1457
|
+
enableBoost: true,
|
|
1458
|
+
receiveGasOnDestination: !isPassportProvider(toProvider),
|
|
1459
|
+
postHook,
|
|
1460
|
+
}), {
|
|
1461
|
+
retryIntervalMs: 1000,
|
|
1462
|
+
retries: 5,
|
|
1463
|
+
nonRetryable: (err) => err.response?.status !== 429,
|
|
1464
|
+
});
|
|
1453
1465
|
const getRoute = async (squid, fromToken, toToken, toAddress, fromAmount, toAmount, fromAddress, quoteOnly = true, postHook) => {
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
if (!routeResponse?.route) {
|
|
1457
|
-
return {};
|
|
1458
|
-
}
|
|
1459
|
-
if (isRouteToAmountGreaterThanToAmount(routeResponse, toAmount)) {
|
|
1460
|
-
return { route: routeResponse };
|
|
1461
|
-
}
|
|
1462
|
-
const newFromAmount = calculateFromAmountFromRoute(routeResponse.route.estimate.exchangeRate, toAmount, routeResponse.route.estimate.toAmountUSD);
|
|
1463
|
-
const newRoute = await getRouteWithRetry(squid, fromToken, toToken, toAddress, newFromAmount, fromAddress, quoteOnly, postHook);
|
|
1464
|
-
if (!newRoute?.route) {
|
|
1465
|
-
return {};
|
|
1466
|
-
}
|
|
1467
|
-
if (isRouteToAmountGreaterThanToAmount(newRoute, toAmount)) {
|
|
1468
|
-
return { route: newRoute };
|
|
1469
|
-
}
|
|
1470
|
-
track({
|
|
1471
|
-
userJourney: UserJourney.ADD_TOKENS,
|
|
1472
|
-
screen: 'Routes',
|
|
1473
|
-
action: 'Failed',
|
|
1474
|
-
extras: {
|
|
1475
|
-
contextId: id,
|
|
1476
|
-
fromToken: fromToken.symbol,
|
|
1477
|
-
toToken: toToken.symbol,
|
|
1478
|
-
fromChain: fromToken.chainId,
|
|
1479
|
-
toChain: toToken.chainId,
|
|
1480
|
-
initialRoute: {
|
|
1481
|
-
fromAmount,
|
|
1482
|
-
toAmount,
|
|
1483
|
-
exchangeRate: routeResponse.route.estimate.exchangeRate,
|
|
1484
|
-
routeFromAmount: routeResponse.route.estimate.fromAmount,
|
|
1485
|
-
routeToAmount: routeResponse.route.estimate.toAmount,
|
|
1486
|
-
},
|
|
1487
|
-
newRoute: {
|
|
1488
|
-
fromAmount: newFromAmount,
|
|
1489
|
-
toAmount,
|
|
1490
|
-
exchangeRate: newRoute.route.estimate.exchangeRate,
|
|
1491
|
-
routeFromAmount: newRoute.route.estimate.fromAmount,
|
|
1492
|
-
routeToAmount: newRoute.route.estimate.toAmount,
|
|
1493
|
-
},
|
|
1494
|
-
},
|
|
1495
|
-
});
|
|
1466
|
+
const routeResponse = await getRouteWithRetry(squid, fromToken, toToken, toAddress, fromAmount, fromAddress, quoteOnly, postHook);
|
|
1467
|
+
if (!routeResponse?.route) {
|
|
1496
1468
|
return {};
|
|
1497
1469
|
}
|
|
1498
|
-
|
|
1470
|
+
if (isRouteToAmountGreaterThanToAmount(routeResponse, toAmount)) {
|
|
1471
|
+
return { route: routeResponse };
|
|
1472
|
+
}
|
|
1473
|
+
const newFromAmount = calculateFromAmountFromRoute(routeResponse.route.estimate.exchangeRate, toAmount, routeResponse.route.estimate.toAmountUSD);
|
|
1474
|
+
const newRoute = await getRouteWithRetry(squid, fromToken, toToken, toAddress, newFromAmount, fromAddress, quoteOnly, postHook);
|
|
1475
|
+
if (!newRoute?.route) {
|
|
1499
1476
|
return {};
|
|
1500
1477
|
}
|
|
1478
|
+
if (isRouteToAmountGreaterThanToAmount(newRoute, toAmount)) {
|
|
1479
|
+
return { route: newRoute };
|
|
1480
|
+
}
|
|
1481
|
+
throw new Error('Unable to find a route with sufficient toAmount');
|
|
1501
1482
|
};
|
|
1502
1483
|
const getRoutesWithFeesValidation = async (squid, toTokenAddress, balances, fromAmountArray, postHook) => {
|
|
1503
1484
|
const getGasCost = (route, chainId) => (route.route?.route.estimate.gasCosts || [])
|
|
@@ -1520,59 +1501,68 @@ const useRoutes = () => {
|
|
|
1520
1501
|
return userBalance >= requiredAmount;
|
|
1521
1502
|
};
|
|
1522
1503
|
const routePromises = fromAmountArray.map(async (data) => {
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
if (!routeResponse?.route)
|
|
1526
|
-
return null;
|
|
1527
|
-
const gasCost = getGasCost(routeResponse, data.balance.chainId);
|
|
1528
|
-
const feeCost = getTotalFees(routeResponse, data.balance.chainId);
|
|
1529
|
-
const userGasBalance = findUserGasBalance(data.balance.chainId);
|
|
1530
|
-
return {
|
|
1531
|
-
amountData: data,
|
|
1532
|
-
route: routeResponse.route,
|
|
1533
|
-
isInsufficientGas: !hasSufficientNativeTokenBalance(userGasBalance, data.fromAmount, data.fromToken, gasCost, feeCost),
|
|
1534
|
-
};
|
|
1535
|
-
}
|
|
1536
|
-
catch (error) {
|
|
1504
|
+
const routeResponse = await getRoute(squid, data.fromToken, data.toToken, toTokenAddress, data.fromAmount, data.toAmount, undefined, true, postHook);
|
|
1505
|
+
if (!routeResponse?.route)
|
|
1537
1506
|
return null;
|
|
1538
|
-
|
|
1507
|
+
const gasCost = getGasCost(routeResponse, data.balance.chainId);
|
|
1508
|
+
const feeCost = getTotalFees(routeResponse, data.balance.chainId);
|
|
1509
|
+
const userGasBalance = findUserGasBalance(data.balance.chainId);
|
|
1510
|
+
return {
|
|
1511
|
+
amountData: data,
|
|
1512
|
+
route: routeResponse.route,
|
|
1513
|
+
isInsufficientGas: !hasSufficientNativeTokenBalance(userGasBalance, data.fromAmount, data.fromToken, gasCost, feeCost),
|
|
1514
|
+
};
|
|
1539
1515
|
});
|
|
1540
|
-
const routesData = (await Promise.
|
|
1516
|
+
const routesData = (await Promise.allSettled(routePromises))
|
|
1517
|
+
.filter((result) => result.status === 'fulfilled')
|
|
1518
|
+
.map((result) => result.value)
|
|
1519
|
+
.filter((route) => route !== null);
|
|
1541
1520
|
return routesData;
|
|
1542
1521
|
};
|
|
1543
|
-
const
|
|
1522
|
+
const fetchRoutes = async (squid, tokens, balances, toChainId, toTokenAddress, toAmount, bulkNumber = 5, delayMs = 1000, isSwapAllowed = true) => {
|
|
1544
1523
|
const currentRequestId = ++latestRequestIdRef.current;
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
let allRoutes = [];
|
|
1550
|
-
await Promise.all(fromAmountDataArray
|
|
1551
|
-
.reduce((acc, _, i) => {
|
|
1552
|
-
if (i % bulkNumber === 0) {
|
|
1553
|
-
acc.push(fromAmountDataArray.slice(i, i + bulkNumber));
|
|
1524
|
+
try {
|
|
1525
|
+
let fromAmountDataArray = getSufficientFromAmounts(tokens, balances, toChainId, toTokenAddress, toAmount);
|
|
1526
|
+
if (!isSwapAllowed) {
|
|
1527
|
+
fromAmountDataArray = fromAmountDataArray.filter((amountData) => amountData.balance.chainId !== toChainId);
|
|
1554
1528
|
}
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1529
|
+
let allRoutes = [];
|
|
1530
|
+
await Promise.all(fromAmountDataArray
|
|
1531
|
+
.reduce((acc, _, i) => {
|
|
1532
|
+
if (i % bulkNumber === 0) {
|
|
1533
|
+
acc.push(fromAmountDataArray.slice(i, i + bulkNumber));
|
|
1534
|
+
}
|
|
1535
|
+
return acc;
|
|
1536
|
+
}, [])
|
|
1537
|
+
.map(async (slicedFromAmountDataArray) => {
|
|
1538
|
+
allRoutes.push(...(await getRoutesWithFeesValidation(squid, toTokenAddress, balances, slicedFromAmountDataArray)));
|
|
1539
|
+
await delay(delayMs);
|
|
1540
|
+
}));
|
|
1541
|
+
if (!isSwapAllowed) {
|
|
1542
|
+
allRoutes = allRoutes.filter((routeData) => !routeData.route.route.estimate.actions.find((action) => action.type === dist$3.ActionType.SWAP));
|
|
1543
|
+
}
|
|
1544
|
+
const sortedRoutes = sortRoutesByFastestTime(allRoutes);
|
|
1545
|
+
// Only return routes if the request is the latest one
|
|
1546
|
+
if (currentRequestId === latestRequestIdRef.current) {
|
|
1547
|
+
return sortedRoutes;
|
|
1548
|
+
}
|
|
1549
|
+
return [];
|
|
1563
1550
|
}
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1551
|
+
catch (error) {
|
|
1552
|
+
throw new RouteError('Failed to fetch routes', {
|
|
1553
|
+
fromToken: tokens.find((token) => token.address === toTokenAddress)?.symbol,
|
|
1554
|
+
toToken: tokens.find((token) => token.address === toTokenAddress)?.symbol,
|
|
1555
|
+
toChain: toChainId,
|
|
1556
|
+
errorStatus: error.response?.status,
|
|
1557
|
+
errorMessage: error.response?.data?.message,
|
|
1558
|
+
errorStack: error.stack,
|
|
1559
|
+
});
|
|
1568
1560
|
}
|
|
1569
|
-
return sortedRoutes;
|
|
1570
1561
|
};
|
|
1571
1562
|
return {
|
|
1572
|
-
|
|
1573
|
-
|
|
1563
|
+
fetchRoutes,
|
|
1564
|
+
getFromAmountData,
|
|
1574
1565
|
getRoute,
|
|
1575
|
-
resetRoutes,
|
|
1576
1566
|
};
|
|
1577
1567
|
};
|
|
1578
1568
|
|
|
@@ -5295,7 +5285,7 @@ const checkSanctionedAddresses = async (addresses, config) => {
|
|
|
5295
5285
|
|
|
5296
5286
|
function AddTokens({ checkout, toAmount, config, toTokenAddress, showOnrampOption = true, showSwapOption = true, showBridgeOption = true, onCloseButtonClick, showBackButton, onBackButtonClick, }) {
|
|
5297
5287
|
const inputRef = reactExports.useRef(null);
|
|
5298
|
-
const {
|
|
5288
|
+
const { fetchRoutes } = useRoutes();
|
|
5299
5289
|
const { showErrorHandover } = useError(config.environment);
|
|
5300
5290
|
const { addTokensState, addTokensDispatch, } = reactExports.useContext(AddTokensContext);
|
|
5301
5291
|
const { id, squid, chains, balances, tokens, selectedAmount, routes, selectedRouteData, selectedToken, isSwapAvailable, experiments, } = addTokensState;
|
|
@@ -5326,6 +5316,14 @@ function AddTokens({ checkout, toAmount, config, toTokenAddress, showOnrampOptio
|
|
|
5326
5316
|
setIsAmountInputSynced(false);
|
|
5327
5317
|
debouncedSetSelectedAmount.current(value);
|
|
5328
5318
|
};
|
|
5319
|
+
const resetRoutes = () => {
|
|
5320
|
+
addTokensDispatch({
|
|
5321
|
+
payload: {
|
|
5322
|
+
type: AddTokensActions.SET_ROUTES,
|
|
5323
|
+
routes: [],
|
|
5324
|
+
},
|
|
5325
|
+
});
|
|
5326
|
+
};
|
|
5329
5327
|
reactExports.useEffect(() => {
|
|
5330
5328
|
if (selectedAmount === inputValue) {
|
|
5331
5329
|
setIsAmountInputSynced(true);
|
|
@@ -5450,25 +5448,47 @@ function AddTokens({ checkout, toAmount, config, toTokenAddress, showOnrampOptio
|
|
|
5450
5448
|
&& selectedToken?.address
|
|
5451
5449
|
&& isValidAmount) {
|
|
5452
5450
|
setFetchingRoutes(true);
|
|
5453
|
-
|
|
5454
|
-
|
|
5455
|
-
|
|
5456
|
-
|
|
5457
|
-
|
|
5458
|
-
|
|
5459
|
-
|
|
5460
|
-
|
|
5461
|
-
|
|
5462
|
-
|
|
5463
|
-
|
|
5464
|
-
|
|
5465
|
-
|
|
5466
|
-
|
|
5467
|
-
|
|
5468
|
-
|
|
5469
|
-
|
|
5470
|
-
|
|
5451
|
+
try {
|
|
5452
|
+
const availableRoutes = await fetchRoutes(squid, tokens, balances, ChainId.IMTBL_ZKEVM_MAINNET.toString(), selectedToken.address === 'native'
|
|
5453
|
+
? SQUID_NATIVE_TOKEN
|
|
5454
|
+
: selectedToken.address, selectedAmount, 5, 1000, isSwapAvailable);
|
|
5455
|
+
addTokensDispatch({
|
|
5456
|
+
payload: {
|
|
5457
|
+
type: AddTokensActions.SET_ROUTES,
|
|
5458
|
+
routes: availableRoutes,
|
|
5459
|
+
},
|
|
5460
|
+
});
|
|
5461
|
+
if (availableRoutes.length === 0) {
|
|
5462
|
+
setInsufficientBalance(true);
|
|
5463
|
+
}
|
|
5464
|
+
track({
|
|
5465
|
+
userJourney: UserJourney.ADD_TOKENS,
|
|
5466
|
+
screen: 'InputScreen',
|
|
5467
|
+
control: 'RoutesMenu',
|
|
5468
|
+
controlType: 'MenuItem',
|
|
5469
|
+
action: 'Request',
|
|
5470
|
+
extras: {
|
|
5471
|
+
contextId: id,
|
|
5472
|
+
routesAvailable: availableRoutes.length,
|
|
5473
|
+
geoBlocked: !isSwapAvailable,
|
|
5474
|
+
},
|
|
5475
|
+
});
|
|
5471
5476
|
}
|
|
5477
|
+
catch (error) {
|
|
5478
|
+
if (error instanceof RouteError && error.data) {
|
|
5479
|
+
track({
|
|
5480
|
+
userJourney: UserJourney.ADD_TOKENS,
|
|
5481
|
+
screen: 'Routes',
|
|
5482
|
+
action: 'Failed',
|
|
5483
|
+
extras: {
|
|
5484
|
+
contextId: id,
|
|
5485
|
+
message: error.message,
|
|
5486
|
+
...error.data,
|
|
5487
|
+
},
|
|
5488
|
+
});
|
|
5489
|
+
}
|
|
5490
|
+
}
|
|
5491
|
+
setFetchingRoutes(false);
|
|
5472
5492
|
}
|
|
5473
5493
|
})();
|
|
5474
5494
|
}, [balances, squid, selectedToken, selectedAmount]);
|
|
@@ -172836,10 +172856,8 @@ function isRejectedError(err) {
|
|
|
172836
172856
|
}
|
|
172837
172857
|
|
|
172838
172858
|
const TRANSACTION_NOT_COMPLETED = 'transaction not completed';
|
|
172839
|
-
const useExecute = (
|
|
172840
|
-
const { showErrorHandover } = useError(environment);
|
|
172859
|
+
const useExecute = (userJourney, onTransactionError) => {
|
|
172841
172860
|
const { user } = useAnalytics();
|
|
172842
|
-
const { eventTargetState: { eventTarget }, } = reactExports.useContext(EventTargetContext);
|
|
172843
172861
|
const waitForReceipt = async (provider, txHash, maxAttempts = 120) => {
|
|
172844
172862
|
const result = await retry(async () => {
|
|
172845
172863
|
const receipt = await provider.getTransactionReceipt(txHash);
|
|
@@ -172860,62 +172878,6 @@ const useExecute = (contextId, environment) => {
|
|
|
172860
172878
|
}
|
|
172861
172879
|
return result;
|
|
172862
172880
|
};
|
|
172863
|
-
const handleTransactionError = (err) => {
|
|
172864
|
-
const reason = `${err?.reason || err?.message || ''}`.toLowerCase();
|
|
172865
|
-
let errorType = AddTokensErrorTypes.WALLET_FAILED;
|
|
172866
|
-
if (reason.includes('failed') && reason.includes('open confirmation')) {
|
|
172867
|
-
errorType = AddTokensErrorTypes.WALLET_POPUP_BLOCKED;
|
|
172868
|
-
}
|
|
172869
|
-
if (reason.includes('rejected') && reason.includes('user')) {
|
|
172870
|
-
errorType = AddTokensErrorTypes.WALLET_REJECTED;
|
|
172871
|
-
}
|
|
172872
|
-
if (reason.includes('failed to submit')
|
|
172873
|
-
&& reason.includes('highest gas limit')) {
|
|
172874
|
-
errorType = AddTokensErrorTypes.WALLET_REJECTED_NO_FUNDS;
|
|
172875
|
-
}
|
|
172876
|
-
if (reason.includes('status failed')
|
|
172877
|
-
|| reason.includes('transaction failed')) {
|
|
172878
|
-
errorType = AddTokensErrorTypes.TRANSACTION_FAILED;
|
|
172879
|
-
sendAddTokensFailedEvent(eventTarget, errorType);
|
|
172880
|
-
}
|
|
172881
|
-
if (reason.includes('unrecognized chain')
|
|
172882
|
-
|| reason.includes('unrecognized chain')) {
|
|
172883
|
-
errorType = AddTokensErrorTypes.UNRECOGNISED_CHAIN;
|
|
172884
|
-
}
|
|
172885
|
-
const error = {
|
|
172886
|
-
type: errorType,
|
|
172887
|
-
data: { error: err },
|
|
172888
|
-
};
|
|
172889
|
-
showErrorHandover(errorType, { contextId, error });
|
|
172890
|
-
};
|
|
172891
|
-
// @TODO: Move to util function
|
|
172892
|
-
const checkProviderChain = async (provider, chainId) => {
|
|
172893
|
-
if (!provider.provider.request) {
|
|
172894
|
-
throw new Error('provider does not have request method');
|
|
172895
|
-
}
|
|
172896
|
-
try {
|
|
172897
|
-
const fromChainHex = `0x${parseInt(chainId, 10).toString(16)}`;
|
|
172898
|
-
const providerChainId = await provider.provider.request({
|
|
172899
|
-
method: 'eth_chainId',
|
|
172900
|
-
});
|
|
172901
|
-
if (fromChainHex !== providerChainId) {
|
|
172902
|
-
await provider.provider.request({
|
|
172903
|
-
method: 'wallet_switchEthereumChain',
|
|
172904
|
-
params: [
|
|
172905
|
-
{
|
|
172906
|
-
chainId: fromChainHex,
|
|
172907
|
-
},
|
|
172908
|
-
],
|
|
172909
|
-
});
|
|
172910
|
-
return true;
|
|
172911
|
-
}
|
|
172912
|
-
return true;
|
|
172913
|
-
}
|
|
172914
|
-
catch (error) {
|
|
172915
|
-
handleTransactionError(error);
|
|
172916
|
-
return false;
|
|
172917
|
-
}
|
|
172918
|
-
};
|
|
172919
172881
|
const getAllowance = async (provider, routeResponse) => {
|
|
172920
172882
|
try {
|
|
172921
172883
|
if (!isSquidNativeToken(routeResponse?.route?.params.fromToken)) {
|
|
@@ -172935,7 +172897,7 @@ const useExecute = (contextId, environment) => {
|
|
|
172935
172897
|
return MaxUint256; // no approval is needed for native tokens
|
|
172936
172898
|
}
|
|
172937
172899
|
catch (error) {
|
|
172938
|
-
|
|
172900
|
+
onTransactionError?.(error);
|
|
172939
172901
|
return undefined;
|
|
172940
172902
|
}
|
|
172941
172903
|
};
|
|
@@ -172971,12 +172933,12 @@ const useExecute = (contextId, environment) => {
|
|
|
172971
172933
|
const approve = async (fromProviderInfo, provider, routeResponse) => {
|
|
172972
172934
|
try {
|
|
172973
172935
|
if (!isSquidNativeToken(routeResponse?.route?.params.fromToken)) {
|
|
172974
|
-
return await withMetricsAsync((flow) => callApprove(flow, fromProviderInfo, provider, routeResponse), `${
|
|
172936
|
+
return await withMetricsAsync((flow) => callApprove(flow, fromProviderInfo, provider, routeResponse), `${userJourney}_Approve`, await getAnonymousId(), (error) => (isRejectedError(error) ? 'rejected' : ''));
|
|
172975
172937
|
}
|
|
172976
172938
|
return undefined;
|
|
172977
172939
|
}
|
|
172978
172940
|
catch (error) {
|
|
172979
|
-
|
|
172941
|
+
onTransactionError?.(error);
|
|
172980
172942
|
return undefined;
|
|
172981
172943
|
}
|
|
172982
172944
|
};
|
|
@@ -172994,10 +172956,10 @@ const useExecute = (contextId, environment) => {
|
|
|
172994
172956
|
throw new Error('provider does not have request method');
|
|
172995
172957
|
}
|
|
172996
172958
|
try {
|
|
172997
|
-
return await withMetricsAsync((flow) => callExecute(flow, squid, fromProviderInfo, provider, routeResponse), `${
|
|
172959
|
+
return await withMetricsAsync((flow) => callExecute(flow, squid, fromProviderInfo, provider, routeResponse), `${userJourney}_Execute`, await getAnonymousId(), (error) => (isRejectedError(error) ? 'rejected' : ''));
|
|
172998
172960
|
}
|
|
172999
172961
|
catch (error) {
|
|
173000
|
-
|
|
172962
|
+
onTransactionError?.(error);
|
|
173001
172963
|
return undefined;
|
|
173002
172964
|
}
|
|
173003
172965
|
};
|
|
@@ -173029,12 +172991,11 @@ const useExecute = (contextId, environment) => {
|
|
|
173029
172991
|
});
|
|
173030
172992
|
}
|
|
173031
172993
|
catch (error) {
|
|
173032
|
-
|
|
172994
|
+
onTransactionError?.(error);
|
|
173033
172995
|
return undefined;
|
|
173034
172996
|
}
|
|
173035
172997
|
};
|
|
173036
172998
|
return {
|
|
173037
|
-
checkProviderChain,
|
|
173038
172999
|
getAllowance,
|
|
173039
173000
|
approve,
|
|
173040
173001
|
execute,
|
|
@@ -173128,6 +173089,78 @@ function RouteFees({ visible, onClose, routeData, totalAmount, totalFiatAmount,
|
|
|
173128
173089
|
return (jsx(FeesBreakdown, { visible: visible, loading: !routeData, fees: [...feeCosts, ...gasCosts], tokenSymbol: tokenSymbol, totalAmount: getFormattedNumber(totalAmount, feesToken?.decimals), totalFiatAmount: getFormattedAmounts(totalFiatAmount), onCloseDrawer: onClose }));
|
|
173129
173090
|
}
|
|
173130
173091
|
|
|
173092
|
+
/**
|
|
173093
|
+
* Ensure the provider is connected to the correct chain.
|
|
173094
|
+
* If not, attempts to switch to the desired chain.
|
|
173095
|
+
*/
|
|
173096
|
+
const verifyAndSwitchChain = async (provider, chainId) => {
|
|
173097
|
+
if (!provider.provider.request) {
|
|
173098
|
+
return {
|
|
173099
|
+
isChainCorrect: false,
|
|
173100
|
+
error: 'Provider does not support the request method.',
|
|
173101
|
+
};
|
|
173102
|
+
}
|
|
173103
|
+
try {
|
|
173104
|
+
const targetChainHex = `0x${parseInt(chainId, 10).toString(16)}`;
|
|
173105
|
+
const currentChainId = await provider.provider.request({
|
|
173106
|
+
method: 'eth_chainId',
|
|
173107
|
+
});
|
|
173108
|
+
if (targetChainHex !== currentChainId) {
|
|
173109
|
+
await provider.provider.request({
|
|
173110
|
+
method: 'wallet_switchEthereumChain',
|
|
173111
|
+
params: [
|
|
173112
|
+
{
|
|
173113
|
+
chainId: targetChainHex,
|
|
173114
|
+
},
|
|
173115
|
+
],
|
|
173116
|
+
});
|
|
173117
|
+
}
|
|
173118
|
+
return { isChainCorrect: true };
|
|
173119
|
+
}
|
|
173120
|
+
catch (error) {
|
|
173121
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
|
|
173122
|
+
return {
|
|
173123
|
+
isChainCorrect: false,
|
|
173124
|
+
error: errorMessage,
|
|
173125
|
+
};
|
|
173126
|
+
}
|
|
173127
|
+
};
|
|
173128
|
+
|
|
173129
|
+
const useErrorHandler = () => {
|
|
173130
|
+
const { addTokensState: { id: contextId }, } = reactExports.useContext(AddTokensContext);
|
|
173131
|
+
const { providersState: { checkout, }, } = useProvidersContext();
|
|
173132
|
+
const { showErrorHandover } = useError(checkout.config.environment);
|
|
173133
|
+
const { eventTargetState: { eventTarget }, } = reactExports.useContext(EventTargetContext);
|
|
173134
|
+
const onTransactionError = (err) => {
|
|
173135
|
+
const reason = `${err?.reason || err?.message || ''}`.toLowerCase();
|
|
173136
|
+
let errorType = AddTokensErrorTypes.WALLET_FAILED;
|
|
173137
|
+
if (reason.includes('failed') && reason.includes('open confirmation')) {
|
|
173138
|
+
errorType = AddTokensErrorTypes.WALLET_POPUP_BLOCKED;
|
|
173139
|
+
}
|
|
173140
|
+
if (reason.includes('rejected') && reason.includes('user')) {
|
|
173141
|
+
errorType = AddTokensErrorTypes.WALLET_REJECTED;
|
|
173142
|
+
}
|
|
173143
|
+
if (reason.includes('failed to submit')
|
|
173144
|
+
&& reason.includes('highest gas limit')) {
|
|
173145
|
+
errorType = AddTokensErrorTypes.WALLET_REJECTED_NO_FUNDS;
|
|
173146
|
+
}
|
|
173147
|
+
if (reason.includes('status failed')
|
|
173148
|
+
|| reason.includes('transaction failed')) {
|
|
173149
|
+
errorType = AddTokensErrorTypes.TRANSACTION_FAILED;
|
|
173150
|
+
sendAddTokensFailedEvent(eventTarget, errorType);
|
|
173151
|
+
}
|
|
173152
|
+
if (reason.includes('unrecognized chain')) {
|
|
173153
|
+
errorType = AddTokensErrorTypes.UNRECOGNISED_CHAIN;
|
|
173154
|
+
}
|
|
173155
|
+
const error = {
|
|
173156
|
+
type: errorType,
|
|
173157
|
+
data: { error: err },
|
|
173158
|
+
};
|
|
173159
|
+
showErrorHandover(errorType, { contextId, error });
|
|
173160
|
+
};
|
|
173161
|
+
return { onTransactionError };
|
|
173162
|
+
};
|
|
173163
|
+
|
|
173131
173164
|
const dividerSx = {
|
|
173132
173165
|
content: "''",
|
|
173133
173166
|
pos: 'absolute',
|
|
@@ -173140,6 +173173,7 @@ function Review({ data, showBackButton = false, onBackButtonClick, onCloseButton
|
|
|
173140
173173
|
const { track, page } = useAnalytics();
|
|
173141
173174
|
const { addTokensState: { id, squid, chains, tokens, }, } = reactExports.useContext(AddTokensContext);
|
|
173142
173175
|
const { providersState: { checkout, fromProvider, fromAddress, toAddress, fromProviderInfo, }, } = useProvidersContext();
|
|
173176
|
+
const { showErrorHandover } = useError(checkout.config.environment);
|
|
173143
173177
|
const { eventTargetState: { eventTarget }, } = reactExports.useContext(EventTargetContext);
|
|
173144
173178
|
const [route, setRoute] = reactExports.useState();
|
|
173145
173179
|
const [amountData, setAmountData] = reactExports.useState();
|
|
@@ -173147,12 +173181,12 @@ function Review({ data, showBackButton = false, onBackButtonClick, onCloseButton
|
|
|
173147
173181
|
const [showFeeBreakdown, setShowFeeBreakdown] = reactExports.useState(false);
|
|
173148
173182
|
const [showSecuringQuote, setShowSecuringQuote] = reactExports.useState(false);
|
|
173149
173183
|
const [showAddressMissmatchDrawer, setShowAddressMissmatchDrawer] = reactExports.useState(false);
|
|
173150
|
-
const {
|
|
173184
|
+
const { getFromAmountData, getRoute } = useRoutes();
|
|
173151
173185
|
const { addHandover, closeHandover } = useHandover({
|
|
173152
173186
|
id: HandoverTarget.GLOBAL,
|
|
173153
173187
|
});
|
|
173154
|
-
const {
|
|
173155
|
-
const {
|
|
173188
|
+
const { onTransactionError } = useErrorHandler();
|
|
173189
|
+
const { getAllowance, approve, execute, getStatus, } = useExecute(UserJourney.ADD_TOKENS, onTransactionError);
|
|
173156
173190
|
reactExports.useEffect(() => {
|
|
173157
173191
|
page({
|
|
173158
173192
|
userJourney: UserJourney.ADD_TOKENS,
|
|
@@ -173171,7 +173205,7 @@ function Review({ data, showBackButton = false, onBackButtonClick, onCloseButton
|
|
|
173171
173205
|
if (!fromAddress || !toAddress)
|
|
173172
173206
|
return;
|
|
173173
173207
|
setShowSecuringQuote(true);
|
|
173174
|
-
const updatedAmountData =
|
|
173208
|
+
const updatedAmountData = getFromAmountData(tokens, data.balance, data.toAmount, data.toChainId, data.toTokenAddress === 'native'
|
|
173175
173209
|
? SQUID_NATIVE_TOKEN
|
|
173176
173210
|
: data.toTokenAddress, data.additionalBuffer);
|
|
173177
173211
|
if (!updatedAmountData)
|
|
@@ -173278,8 +173312,8 @@ function Review({ data, showBackButton = false, onBackButtonClick, onCloseButton
|
|
|
173278
173312
|
headingText: t('views.ADD_TOKENS.handover.preparing.heading'),
|
|
173279
173313
|
});
|
|
173280
173314
|
const changeableProvider = await convertToNetworkChangeableProvider(fromProvider);
|
|
173281
|
-
const
|
|
173282
|
-
if (!
|
|
173315
|
+
const verifyChainResult = await verifyAndSwitchChain(changeableProvider, route.route.params.fromChain);
|
|
173316
|
+
if (!verifyChainResult.isChainCorrect) {
|
|
173283
173317
|
return;
|
|
173284
173318
|
}
|
|
173285
173319
|
const allowance = await getAllowance(changeableProvider, route);
|
|
@@ -173434,7 +173468,6 @@ function Review({ data, showBackButton = false, onBackButtonClick, onCloseButton
|
|
|
173434
173468
|
getRouteIntervalIdRef,
|
|
173435
173469
|
approve,
|
|
173436
173470
|
showHandover,
|
|
173437
|
-
checkProviderChain,
|
|
173438
173471
|
getAllowance,
|
|
173439
173472
|
execute,
|
|
173440
173473
|
closeHandover,
|