@lifi/widget 4.10.0 → 4.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -7
- package/dist/esm/config/version.d.ts +1 -1
- package/dist/esm/config/version.js +1 -1
- package/dist/esm/config/version.js.map +1 -1
- package/dist/esm/hooks/usePacedValue.js +1 -1
- package/dist/esm/hooks/usePacedValue.js.map +1 -1
- package/dist/esm/hooks/useRouteExecutionMessage.d.ts.map +1 -1
- package/dist/esm/hooks/useRouteExecutionMessage.js +4 -8
- package/dist/esm/hooks/useRouteExecutionMessage.js.map +1 -1
- package/dist/esm/i18n/bn.json +567 -270
- package/dist/esm/i18n/de.json +552 -255
- package/dist/esm/i18n/en.json +7 -61
- package/dist/esm/i18n/es.json +522 -225
- package/dist/esm/i18n/fr.json +541 -244
- package/dist/esm/i18n/hi.json +592 -295
- package/dist/esm/i18n/id.json +485 -188
- package/dist/esm/i18n/it.json +546 -249
- package/dist/esm/i18n/ja.json +512 -215
- package/dist/esm/i18n/ko.json +553 -256
- package/dist/esm/i18n/pl.json +598 -301
- package/dist/esm/i18n/pt.json +512 -215
- package/dist/esm/i18n/th.json +554 -257
- package/dist/esm/i18n/tr.json +538 -241
- package/dist/esm/i18n/uk.json +514 -217
- package/dist/esm/i18n/vi.json +550 -253
- package/dist/esm/i18n/zh.json +528 -231
- package/dist/esm/pages/TransactionPage/TransactionFailedButtons.js +70 -18
- package/dist/esm/pages/TransactionPage/TransactionFailedButtons.js.map +1 -1
- package/dist/esm/pages/TransactionPage/utils.d.ts +3 -0
- package/dist/esm/pages/TransactionPage/utils.d.ts.map +1 -1
- package/dist/esm/pages/TransactionPage/utils.js +27 -1
- package/dist/esm/pages/TransactionPage/utils.js.map +1 -1
- package/dist/esm/shared.d.ts +2 -2
- package/dist/esm/shared.js +2 -2
- package/dist/esm/stores/routes/utils.d.ts +1 -1
- package/dist/esm/stores/routes/utils.d.ts.map +1 -1
- package/dist/esm/stores/routes/utils.js +13 -1
- package/dist/esm/stores/routes/utils.js.map +1 -1
- package/dist/esm/utils/getErrorMessage.js +4 -0
- package/dist/esm/utils/getErrorMessage.js.map +1 -1
- package/package.json +4 -4
- package/src/config/version.ts +1 -1
- package/src/hooks/usePacedValue.ts +1 -1
- package/src/hooks/useRouteExecutionMessage.ts +10 -13
- package/src/pages/TransactionPage/TransactionFailedButtons.test.tsx +497 -0
- package/src/pages/TransactionPage/TransactionFailedButtons.tsx +78 -9
- package/src/pages/TransactionPage/utils.ts +81 -0
- package/src/shared.ts +1 -0
- package/src/stores/routes/utils.ts +24 -1
- package/src/utils/getErrorMessage.ts +5 -0
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
import { useWidgetEvents } from "../../hooks/useWidgetEvents.js";
|
|
2
2
|
import "../../types/events.js";
|
|
3
3
|
import { useWidgetConfig } from "../../providers/WidgetProvider/WidgetProvider.js";
|
|
4
|
+
import { navigationRoutes } from "../../utils/navigationRoutes.js";
|
|
5
|
+
import { useSwapOnly } from "../../hooks/useSwapOnly.js";
|
|
6
|
+
import { useBookmarkActions } from "../../stores/bookmarks/useBookmarkActions.js";
|
|
7
|
+
import { useFieldActions } from "../../stores/form/useFieldActions.js";
|
|
4
8
|
import { getAccumulatedFeeCostsBreakdown } from "../../utils/fees.js";
|
|
5
9
|
import { useNavigateBack } from "../../hooks/useNavigateBack.js";
|
|
6
10
|
import { useAddressActivity } from "../../hooks/useAddressActivity.js";
|
|
7
11
|
import { ConfirmToAddressSheet } from "./ConfirmToAddressSheet.js";
|
|
8
12
|
import { StartTransactionButton } from "./StartTransactionButton.js";
|
|
9
|
-
import { calculateValueLossPercentage, getRetryGates, getTokenValueLossThreshold, openNextGate } from "./utils.js";
|
|
13
|
+
import { calculateValueLossPercentage, canStartNewSwap, getNewSwapFormValues, getRetryGates, getTokenValueLossThreshold, isCallBundleNotFound, openNextGate } from "./utils.js";
|
|
10
14
|
import { TokenValueBottomSheet } from "./TokenValueBottomSheet.js";
|
|
11
15
|
import { useRef } from "react";
|
|
16
|
+
import { useNavigate } from "@tanstack/react-router";
|
|
12
17
|
import { Box, Button } from "@mui/material";
|
|
13
18
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
14
19
|
import { useTranslation } from "react-i18next";
|
|
@@ -17,7 +22,11 @@ const TransactionFailedButtons = ({ route, restartRoute, deleteRoute }) => {
|
|
|
17
22
|
const { t } = useTranslation();
|
|
18
23
|
const emitter = useWidgetEvents();
|
|
19
24
|
const navigateBack = useNavigateBack();
|
|
20
|
-
const
|
|
25
|
+
const navigate = useNavigate();
|
|
26
|
+
const { mode, hiddenUI, disabledUI, requiredUI } = useWidgetConfig();
|
|
27
|
+
const swapOnly = useSwapOnly();
|
|
28
|
+
const { setFieldValue, getFieldValues } = useFieldActions();
|
|
29
|
+
const { setSelectedBookmark, getSelectedBookmark } = useBookmarkActions();
|
|
21
30
|
const tokenValueBottomSheetRef = useRef(null);
|
|
22
31
|
const confirmToAddressSheetRef = useRef(null);
|
|
23
32
|
const { toAddress, hasActivity, isLoading: isLoadingAddressActivity, isFetched: isActivityAddressFetched } = useAddressActivity(route.toChainId);
|
|
@@ -25,6 +34,36 @@ const TransactionFailedButtons = ({ route, restartRoute, deleteRoute }) => {
|
|
|
25
34
|
navigateBack();
|
|
26
35
|
deleteRoute();
|
|
27
36
|
};
|
|
37
|
+
const callBundleNotFound = isCallBundleNotFound(route);
|
|
38
|
+
const showStartNewSwap = callBundleNotFound && canStartNewSwap({
|
|
39
|
+
route,
|
|
40
|
+
mode,
|
|
41
|
+
swapOnly
|
|
42
|
+
});
|
|
43
|
+
const showRetry = !callBundleNotFound;
|
|
44
|
+
const handleStartNewSwap = () => {
|
|
45
|
+
const [formReceiver] = getFieldValues("toAddress");
|
|
46
|
+
const keepReceiver = Boolean((disabledUI?.toAddress || hiddenUI?.toAddress) && formReceiver);
|
|
47
|
+
const values = getNewSwapFormValues(route, {
|
|
48
|
+
keepReceiver,
|
|
49
|
+
receiverRequired: requiredUI?.toAddress
|
|
50
|
+
});
|
|
51
|
+
const fieldNames = Object.keys(values);
|
|
52
|
+
const receiver = keepReceiver ? formReceiver : values.toAddress;
|
|
53
|
+
navigate({
|
|
54
|
+
to: navigationRoutes.home,
|
|
55
|
+
replace: true
|
|
56
|
+
}).then(() => {
|
|
57
|
+
for (const fieldName of fieldNames) setFieldValue(fieldName, values[fieldName], {
|
|
58
|
+
isDirty: true,
|
|
59
|
+
isTouched: true
|
|
60
|
+
});
|
|
61
|
+
if (getSelectedBookmark()?.address.toLowerCase() !== receiver?.toLowerCase()) setSelectedBookmark();
|
|
62
|
+
}).catch((error) => {
|
|
63
|
+
console.warn("Filling the new swap failed.", error);
|
|
64
|
+
});
|
|
65
|
+
deleteRoute();
|
|
66
|
+
};
|
|
28
67
|
const retryGates = (() => {
|
|
29
68
|
const { gasCostUSD, feeCostUSD } = getAccumulatedFeeCostsBreakdown(route);
|
|
30
69
|
return getRetryGates({
|
|
@@ -71,22 +110,35 @@ const TransactionFailedButtons = ({ route, restartRoute, deleteRoute }) => {
|
|
|
71
110
|
display: "flex",
|
|
72
111
|
gap: 1.5
|
|
73
112
|
},
|
|
74
|
-
children: [
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
113
|
+
children: [
|
|
114
|
+
/* @__PURE__ */ jsx(Box, {
|
|
115
|
+
sx: { flex: 1 },
|
|
116
|
+
children: /* @__PURE__ */ jsx(Button, {
|
|
117
|
+
onClick: handleRemoveRoute,
|
|
118
|
+
fullWidth: true,
|
|
119
|
+
children: t("button.delete")
|
|
120
|
+
})
|
|
121
|
+
}),
|
|
122
|
+
showStartNewSwap ? /* @__PURE__ */ jsx(Box, {
|
|
123
|
+
sx: { flex: 1 },
|
|
124
|
+
children: /* @__PURE__ */ jsx(Button, {
|
|
125
|
+
variant: "contained",
|
|
126
|
+
color: "primary",
|
|
127
|
+
onClick: handleStartNewSwap,
|
|
128
|
+
fullWidth: true,
|
|
129
|
+
children: t("button.startNewSwap")
|
|
130
|
+
})
|
|
131
|
+
}) : null,
|
|
132
|
+
showRetry ? /* @__PURE__ */ jsx(Box, {
|
|
133
|
+
sx: { flex: 1 },
|
|
134
|
+
children: /* @__PURE__ */ jsx(StartTransactionButton, {
|
|
135
|
+
text: t("button.tryAgain"),
|
|
136
|
+
onClick: handleRetryClick,
|
|
137
|
+
route,
|
|
138
|
+
loading: isLoadingAddressActivity
|
|
139
|
+
})
|
|
140
|
+
}) : null
|
|
141
|
+
]
|
|
90
142
|
}),
|
|
91
143
|
mode !== "custom" ? /* @__PURE__ */ jsx(TokenValueBottomSheet, {
|
|
92
144
|
route,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TransactionFailedButtons.js","names":[],"sources":["../../../../src/pages/TransactionPage/TransactionFailedButtons.tsx"],"sourcesContent":["import type { RouteExtended } from '@lifi/sdk'\nimport { Box, Button } from '@mui/material'\nimport { useRef } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport type { BottomSheetBase } from '../../components/BottomSheet/types.js'\nimport { useAddressActivity } from '../../hooks/useAddressActivity.js'\nimport { useNavigateBack } from '../../hooks/useNavigateBack.js'\nimport { useWidgetEvents } from '../../hooks/useWidgetEvents.js'\nimport { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js'\nimport { WidgetEvent } from '../../types/events.js'\nimport { getAccumulatedFeeCostsBreakdown } from '../../utils/fees.js'\nimport { ConfirmToAddressSheet } from './ConfirmToAddressSheet.js'\nimport { StartTransactionButton } from './StartTransactionButton.js'\nimport { TokenValueBottomSheet } from './TokenValueBottomSheet.js'\nimport type { RetryGate } from './utils.js'\nimport {\n calculateValueLossPercentage,\n getRetryGates,\n getTokenValueLossThreshold,\n openNextGate,\n} from './utils.js'\n\ninterface TransactionFailedButtonsProps {\n route: RouteExtended\n restartRoute: () => void\n deleteRoute: () => void\n}\n\nexport const TransactionFailedButtons: React.FC<\n TransactionFailedButtonsProps\n> = ({ route, restartRoute, deleteRoute }) => {\n const { t } = useTranslation()\n const emitter = useWidgetEvents()\n const navigateBack = useNavigateBack()\n const { mode, hiddenUI } = useWidgetConfig()\n\n const tokenValueBottomSheetRef = useRef<BottomSheetBase>(null)\n const confirmToAddressSheetRef = useRef<BottomSheetBase>(null)\n\n const {\n toAddress,\n hasActivity,\n isLoading: isLoadingAddressActivity,\n isFetched: isActivityAddressFetched,\n } = useAddressActivity(route.toChainId)\n\n const handleRemoveRoute = () => {\n navigateBack()\n deleteRoute()\n }\n\n const retryGates = (() => {\n const { gasCostUSD, feeCostUSD } = getAccumulatedFeeCostsBreakdown(route)\n return getRetryGates({\n toAddress,\n hasActivity,\n isLoadingAddressActivity,\n isActivityAddressFetched,\n confirmationHidden: Boolean(hiddenUI?.lowAddressActivityConfirmation),\n valueLossExceeded: getTokenValueLossThreshold(\n Number.parseFloat(route.fromAmountUSD),\n Number.parseFloat(route.toAmountUSD),\n gasCostUSD,\n feeCostUSD\n ),\n isCustomMode: mode === 'custom',\n })\n })()\n\n const openGate = (after?: RetryGate) =>\n openNextGate(\n retryGates,\n {\n address: () => confirmToAddressSheetRef.current?.open(),\n value: () => tokenValueBottomSheetRef.current?.open(),\n },\n handleRestartRoute,\n after\n )\n\n const handleRestartRoute = () => {\n if (tokenValueBottomSheetRef.current?.isOpen()) {\n const { gasCostUSD, feeCostUSD } = getAccumulatedFeeCostsBreakdown(route)\n const fromAmountUSD = Number.parseFloat(route.fromAmountUSD)\n const toAmountUSD = Number.parseFloat(route.toAmountUSD)\n emitter.emit(WidgetEvent.RouteHighValueLoss, {\n fromAmountUSD,\n toAmountUSD,\n gasCostUSD,\n feeCostUSD,\n valueLoss: calculateValueLossPercentage(\n fromAmountUSD,\n toAmountUSD,\n gasCostUSD,\n feeCostUSD\n ),\n })\n }\n tokenValueBottomSheetRef.current?.close()\n restartRoute()\n }\n\n const handleRetryClick = () => openGate()\n\n const handleConfirmToAddressContinue = () => openGate('address')\n\n return (\n <Box sx={{ display: 'flex', flexDirection: 'column', gap: 1.5 }}>\n <Box sx={{ display: 'flex', gap: 1.5 }}>\n <Box sx={{ flex: 1 }}>\n <Button onClick={handleRemoveRoute} fullWidth>\n {t('button.delete')}\n </Button>\n </Box>\n <Box sx={{ flex: 1 }}>\n <StartTransactionButton\n
|
|
1
|
+
{"version":3,"file":"TransactionFailedButtons.js","names":[],"sources":["../../../../src/pages/TransactionPage/TransactionFailedButtons.tsx"],"sourcesContent":["import type { RouteExtended } from '@lifi/sdk'\nimport { Box, Button } from '@mui/material'\nimport { useNavigate } from '@tanstack/react-router'\nimport { useRef } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport type { BottomSheetBase } from '../../components/BottomSheet/types.js'\nimport { useAddressActivity } from '../../hooks/useAddressActivity.js'\nimport { useNavigateBack } from '../../hooks/useNavigateBack.js'\nimport { useSwapOnly } from '../../hooks/useSwapOnly.js'\nimport { useWidgetEvents } from '../../hooks/useWidgetEvents.js'\nimport { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js'\nimport { useBookmarkActions } from '../../stores/bookmarks/useBookmarkActions.js'\nimport { useFieldActions } from '../../stores/form/useFieldActions.js'\nimport { WidgetEvent } from '../../types/events.js'\nimport { getAccumulatedFeeCostsBreakdown } from '../../utils/fees.js'\nimport { navigationRoutes } from '../../utils/navigationRoutes.js'\nimport { ConfirmToAddressSheet } from './ConfirmToAddressSheet.js'\nimport { StartTransactionButton } from './StartTransactionButton.js'\nimport { TokenValueBottomSheet } from './TokenValueBottomSheet.js'\nimport type { RetryGate } from './utils.js'\nimport {\n calculateValueLossPercentage,\n canStartNewSwap,\n getNewSwapFormValues,\n getRetryGates,\n getTokenValueLossThreshold,\n isCallBundleNotFound,\n openNextGate,\n} from './utils.js'\n\ninterface TransactionFailedButtonsProps {\n route: RouteExtended\n restartRoute: () => void\n deleteRoute: () => void\n}\n\nexport const TransactionFailedButtons: React.FC<\n TransactionFailedButtonsProps\n> = ({ route, restartRoute, deleteRoute }) => {\n const { t } = useTranslation()\n const emitter = useWidgetEvents()\n const navigateBack = useNavigateBack()\n const navigate = useNavigate()\n const { mode, hiddenUI, disabledUI, requiredUI } = useWidgetConfig()\n const swapOnly = useSwapOnly()\n const { setFieldValue, getFieldValues } = useFieldActions()\n const { setSelectedBookmark, getSelectedBookmark } = useBookmarkActions()\n\n const tokenValueBottomSheetRef = useRef<BottomSheetBase>(null)\n const confirmToAddressSheetRef = useRef<BottomSheetBase>(null)\n\n const {\n toAddress,\n hasActivity,\n isLoading: isLoadingAddressActivity,\n isFetched: isActivityAddressFetched,\n } = useAddressActivity(route.toChainId)\n\n const handleRemoveRoute = () => {\n navigateBack()\n deleteRoute()\n }\n\n const callBundleNotFound = isCallBundleNotFound(route)\n const showStartNewSwap =\n callBundleNotFound && canStartNewSwap({ route, mode, swapOnly })\n // Try again would only wait for the same bundle again.\n const showRetry = !callBundleNotFound\n\n // Home, not back: after a reload, the route is opened from Activities.\n const handleStartNewSwap = () => {\n // An empty hidden or locked field still needs the route's receiver.\n const [formReceiver] = getFieldValues('toAddress')\n const keepReceiver = Boolean(\n (disabledUI?.toAddress || hiddenUI?.toAddress) && formReceiver\n )\n const values = getNewSwapFormValues(route, {\n keepReceiver,\n receiverRequired: requiredUI?.toAddress,\n })\n const fieldNames = Object.keys(values) as (keyof typeof values)[]\n const receiver = keepReceiver ? formReceiver : values.toAddress\n // Fill after navigate resolves: this page's unmount cleanup has run by then,\n // as TransactionFailedButtons.test.tsx checks.\n navigate({ to: navigationRoutes.home, replace: true })\n .then(() => {\n for (const fieldName of fieldNames) {\n setFieldValue(fieldName, values[fieldName], {\n isDirty: true,\n isTouched: true,\n })\n }\n // A bookmark name from an earlier receiver must not label this one.\n if (\n getSelectedBookmark()?.address.toLowerCase() !==\n receiver?.toLowerCase()\n ) {\n setSelectedBookmark()\n }\n })\n .catch((error) => {\n console.warn('Filling the new swap failed.', error)\n })\n deleteRoute()\n }\n\n const retryGates = (() => {\n const { gasCostUSD, feeCostUSD } = getAccumulatedFeeCostsBreakdown(route)\n return getRetryGates({\n toAddress,\n hasActivity,\n isLoadingAddressActivity,\n isActivityAddressFetched,\n confirmationHidden: Boolean(hiddenUI?.lowAddressActivityConfirmation),\n valueLossExceeded: getTokenValueLossThreshold(\n Number.parseFloat(route.fromAmountUSD),\n Number.parseFloat(route.toAmountUSD),\n gasCostUSD,\n feeCostUSD\n ),\n isCustomMode: mode === 'custom',\n })\n })()\n\n const openGate = (after?: RetryGate) =>\n openNextGate(\n retryGates,\n {\n address: () => confirmToAddressSheetRef.current?.open(),\n value: () => tokenValueBottomSheetRef.current?.open(),\n },\n handleRestartRoute,\n after\n )\n\n const handleRestartRoute = () => {\n if (tokenValueBottomSheetRef.current?.isOpen()) {\n const { gasCostUSD, feeCostUSD } = getAccumulatedFeeCostsBreakdown(route)\n const fromAmountUSD = Number.parseFloat(route.fromAmountUSD)\n const toAmountUSD = Number.parseFloat(route.toAmountUSD)\n emitter.emit(WidgetEvent.RouteHighValueLoss, {\n fromAmountUSD,\n toAmountUSD,\n gasCostUSD,\n feeCostUSD,\n valueLoss: calculateValueLossPercentage(\n fromAmountUSD,\n toAmountUSD,\n gasCostUSD,\n feeCostUSD\n ),\n })\n }\n tokenValueBottomSheetRef.current?.close()\n restartRoute()\n }\n\n const handleRetryClick = () => openGate()\n\n const handleConfirmToAddressContinue = () => openGate('address')\n\n return (\n <Box sx={{ display: 'flex', flexDirection: 'column', gap: 1.5 }}>\n <Box sx={{ display: 'flex', gap: 1.5 }}>\n <Box sx={{ flex: 1 }}>\n <Button onClick={handleRemoveRoute} fullWidth>\n {t('button.delete')}\n </Button>\n </Box>\n {showStartNewSwap ? (\n <Box sx={{ flex: 1 }}>\n <Button\n variant=\"contained\"\n color=\"primary\"\n onClick={handleStartNewSwap}\n fullWidth\n >\n {t('button.startNewSwap')}\n </Button>\n </Box>\n ) : null}\n {showRetry ? (\n <Box sx={{ flex: 1 }}>\n <StartTransactionButton\n text={t('button.tryAgain')}\n onClick={handleRetryClick}\n route={route}\n loading={isLoadingAddressActivity}\n />\n </Box>\n ) : null}\n </Box>\n {mode !== 'custom' ? (\n <TokenValueBottomSheet\n route={route}\n ref={tokenValueBottomSheetRef}\n onContinue={handleRestartRoute}\n />\n ) : null}\n {!hiddenUI?.lowAddressActivityConfirmation ? (\n <ConfirmToAddressSheet\n ref={confirmToAddressSheetRef}\n onContinue={handleConfirmToAddressContinue}\n toAddress={toAddress!}\n toChainId={route.toChainId!}\n />\n ) : null}\n </Box>\n )\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
import "../../types/widget.js";
|
|
2
|
+
import { RouteExtended } from "@lifi/sdk";
|
|
1
3
|
//#region src/pages/TransactionPage/utils.d.ts
|
|
2
4
|
export declare const calculateValueLossPercentage: (fromAmountUSD: number, toAmountUSD: number, gasCostUSD: number, feeCostUSD: number) => number;
|
|
3
5
|
export declare const getTokenValueLossThreshold: (fromAmountUSD: number, toAmountUSD: number, gasCostUSD: number, feeCostUSD: number) => boolean;
|
|
6
|
+
export declare const isCallBundleNotFound: (route: RouteExtended) => boolean;
|
|
4
7
|
//#endregion
|
|
5
8
|
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","names":[],"sources":["../../../../src/pages/TransactionPage/utils.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"utils.d.ts","names":[],"sources":["../../../../src/pages/TransactionPage/utils.ts"],"mappings":";;;qBAKa,+BACX,uBACA,qBACA,oBACA;qBAUW,6BACX,uBACA,qBACA,oBACA;qBA6FW,uBAAwB,OAAO"}
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { formatTokenAmount } from "../../utils/format.js";
|
|
2
|
+
import { getFailedStepAction } from "../../stores/routes/utils.js";
|
|
3
|
+
import { LiFiErrorCode } from "@lifi/sdk";
|
|
1
4
|
//#region src/pages/TransactionPage/utils.ts
|
|
2
5
|
const calculateValueLossPercentage = (fromAmountUSD, toAmountUSD, gasCostUSD, feeCostUSD) => {
|
|
3
6
|
return Number.parseFloat(((toAmountUSD / (fromAmountUSD + gasCostUSD + feeCostUSD) - 1) * 100).toFixed(2));
|
|
@@ -28,7 +31,30 @@ const getStartGates = (input) => [
|
|
|
28
31
|
["address", needsAddressConfirmation(input)],
|
|
29
32
|
["value", input.valueLossExceeded && !input.isCustomMode]
|
|
30
33
|
];
|
|
34
|
+
const newSwapModes = [
|
|
35
|
+
void 0,
|
|
36
|
+
"default",
|
|
37
|
+
"split"
|
|
38
|
+
];
|
|
39
|
+
const isCallBundleNotFound = (route) => getFailedStepAction(route)?.action.error?.code === LiFiErrorCode.CallBundleNotFound;
|
|
40
|
+
const canStartNewSwap = ({ route, mode, swapOnly }) => {
|
|
41
|
+
const failed = getFailedStepAction(route);
|
|
42
|
+
if (!failed || !isCallBundleNotFound(route)) return false;
|
|
43
|
+
return failed.step === route.steps[0] && route.steps.every((step) => step === failed.step || !step.execution?.actions?.length) && newSwapModes.includes(mode) && !(swapOnly && route.fromChainId !== route.toChainId);
|
|
44
|
+
};
|
|
45
|
+
const getNewSwapFormValues = (route, { keepReceiver = false, receiverRequired = false } = {}) => {
|
|
46
|
+
const receiver = route.toAddress || route.fromAddress;
|
|
47
|
+
const values = {
|
|
48
|
+
fromChain: route.fromChainId,
|
|
49
|
+
fromToken: route.fromToken.address,
|
|
50
|
+
fromAmount: formatTokenAmount(BigInt(route.fromAmount), route.fromToken.decimals),
|
|
51
|
+
toChain: route.toChainId,
|
|
52
|
+
toToken: route.toToken.address
|
|
53
|
+
};
|
|
54
|
+
if (!keepReceiver) values.toAddress = receiver && (receiverRequired || receiver.toLowerCase() !== route.fromAddress?.toLowerCase()) ? receiver : "";
|
|
55
|
+
return values;
|
|
56
|
+
};
|
|
31
57
|
//#endregion
|
|
32
|
-
export { calculateValueLossPercentage, getRetryGates, getStartGates, getTokenValueLossThreshold, nextGate, openNextGate };
|
|
58
|
+
export { calculateValueLossPercentage, canStartNewSwap, getNewSwapFormValues, getRetryGates, getStartGates, getTokenValueLossThreshold, isCallBundleNotFound, nextGate, openNextGate };
|
|
33
59
|
|
|
34
60
|
//# sourceMappingURL=utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","names":[],"sources":["../../../../src/pages/TransactionPage/utils.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"utils.js","names":[],"sources":["../../../../src/pages/TransactionPage/utils.ts"],"sourcesContent":["import { LiFiErrorCode, type RouteExtended } from '@lifi/sdk'\nimport { getFailedStepAction } from '../../stores/routes/utils.js'\nimport type { WidgetMode } from '../../types/widget.js'\nimport { formatTokenAmount } from '../../utils/format.js'\n\nexport const calculateValueLossPercentage = (\n fromAmountUSD: number,\n toAmountUSD: number,\n gasCostUSD: number,\n feeCostUSD: number\n): number => {\n return Number.parseFloat(\n (\n (toAmountUSD / (fromAmountUSD + gasCostUSD + feeCostUSD) - 1) *\n 100\n ).toFixed(2)\n )\n}\n\nexport const getTokenValueLossThreshold = (\n fromAmountUSD: number,\n toAmountUSD: number,\n gasCostUSD: number,\n feeCostUSD: number\n): boolean => {\n if (!fromAmountUSD || !toAmountUSD) {\n return false\n }\n return toAmountUSD / (fromAmountUSD + gasCostUSD + feeCostUSD) < 0.9\n}\n\ninterface AddressGateInput {\n toAddress: string | undefined\n hasActivity: boolean | undefined\n isLoadingAddressActivity: boolean\n isActivityAddressFetched: boolean\n confirmationHidden: boolean\n}\n\nconst needsAddressConfirmation = ({\n toAddress,\n hasActivity,\n isLoadingAddressActivity,\n isActivityAddressFetched,\n confirmationHidden,\n}: AddressGateInput): boolean =>\n Boolean(\n toAddress &&\n !hasActivity &&\n !isLoadingAddressActivity &&\n isActivityAddressFetched &&\n !confirmationHidden\n )\n\nexport type RetryGate = 'address' | 'value'\n\nexport const getRetryGates = (\n input: AddressGateInput & {\n valueLossExceeded: boolean\n isCustomMode: boolean\n }\n): readonly (readonly [gate: RetryGate, needed: boolean])[] => [\n ['address', needsAddressConfirmation(input)],\n ['value', input.valueLossExceeded && !input.isCustomMode],\n]\n\n/** Ordering lives here so no sheet decides what follows it — that is how gates came to be skipped. */\nexport const nextGate = <T extends string>(\n gates: readonly (readonly [gate: T, needed: boolean])[],\n after?: T\n): T | undefined => {\n if (!after) {\n return gates.find(([, needed]) => needed)?.[0]\n }\n const index = gates.findIndex(([gate]) => gate === after)\n if (index < 0) {\n return undefined\n }\n return gates.slice(index + 1).find(([, needed]) => needed)?.[0]\n}\n\nexport const openNextGate = <T extends string>(\n gates: readonly (readonly [gate: T, needed: boolean])[],\n open: Record<T, () => void>,\n done: () => void,\n after?: T\n): void => {\n const gate = nextGate(gates, after)\n if (gate) {\n open[gate]()\n return\n }\n done()\n}\n\nexport type StartGate = 'flagged' | 'address' | 'value'\n\nexport const getStartGates = (\n input: AddressGateInput & {\n flaggedTokenCount: number\n valueLossExceeded: boolean\n isCustomMode: boolean\n }\n): readonly (readonly [gate: StartGate, needed: boolean])[] => [\n ['flagged', input.flaggedTokenCount > 0],\n ['address', needsAddressConfirmation(input)],\n ['value', input.valueLossExceeded && !input.isCustomMode],\n]\n\n// Only these modes show the plain from/to swap form.\nconst newSwapModes: readonly (WidgetMode | undefined)[] = [\n undefined,\n 'default',\n 'split',\n]\n\nexport const isCallBundleNotFound = (route: RouteExtended): boolean =>\n getFailedStepAction(route)?.action.error?.code ===\n LiFiErrorCode.CallBundleNotFound\n\n// A new swap repeats the whole route.\nexport const canStartNewSwap = ({\n route,\n mode,\n swapOnly,\n}: {\n route: RouteExtended\n mode: WidgetMode | undefined\n swapOnly: boolean\n}): boolean => {\n const failed = getFailedStepAction(route)\n if (!failed || !isCallBundleNotFound(route)) {\n return false\n }\n return (\n failed.step === route.steps[0] &&\n route.steps.every(\n (step) => step === failed.step || !step.execution?.actions?.length\n ) &&\n newSwapModes.includes(mode) &&\n // A swap-only form requests no bridges.\n !(swapOnly && route.fromChainId !== route.toChainId)\n )\n}\n\ninterface NewSwapFormValues {\n fromChain: number\n fromToken: string\n fromAmount: string\n toChain: number\n toToken: string\n toAddress?: string\n}\n\nexport const getNewSwapFormValues = (\n route: RouteExtended,\n {\n keepReceiver = false,\n receiverRequired = false,\n }: { keepReceiver?: boolean; receiverRequired?: boolean } = {}\n): NewSwapFormValues => {\n const receiver = route.toAddress || route.fromAddress\n const values: NewSwapFormValues = {\n fromChain: route.fromChainId,\n fromToken: route.fromToken.address,\n // The quote's amount, not a step amount trimmed to the balance: the new quote checks it.\n fromAmount: formatTokenAmount(\n BigInt(route.fromAmount),\n route.fromToken.decimals\n ),\n toChain: route.toChainId,\n toToken: route.toToken.address,\n }\n if (!keepReceiver) {\n // A required receiver stays, also when it is the sender.\n values.toAddress =\n receiver &&\n (receiverRequired ||\n receiver.toLowerCase() !== route.fromAddress?.toLowerCase())\n ? receiver\n : ''\n }\n return values\n}\n"],"mappings":";;;;AAKA,MAAa,gCACX,eACA,aACA,YACA,eACW;CACX,OAAO,OAAO,aAET,eAAe,gBAAgB,aAAa,cAAc,KAC3D,IAAA,CACA,QAAQ,CAAC,CACb;AACF;AAEA,MAAa,8BACX,eACA,aACA,YACA,eACY;CACZ,IAAI,CAAC,iBAAiB,CAAC,aACrB,OAAO;CAET,OAAO,eAAe,gBAAgB,aAAa,cAAc;AACnE;AAUA,MAAM,4BAA4B,EAChC,WACA,aACA,0BACA,0BACA,yBAEA,QACE,aACE,CAAC,eACD,CAAC,4BACD,4BACA,CAAC,kBACL;AAIF,MAAa,iBACX,UAI6D,CAC7D,CAAC,WAAW,yBAAyB,KAAK,CAAC,GAC3C,CAAC,SAAS,MAAM,qBAAqB,CAAC,MAAM,YAAY,CAC1D;;AAGA,MAAa,YACX,OACA,UACkB;CAClB,IAAI,CAAC,OACH,OAAO,MAAM,MAAM,GAAG,YAAY,MAAM,CAAC,GAAG;CAE9C,MAAM,QAAQ,MAAM,WAAW,CAAC,UAAU,SAAS,KAAK;CACxD,IAAI,QAAQ,GACV;CAEF,OAAO,MAAM,MAAM,QAAQ,CAAC,CAAC,CAAC,MAAM,GAAG,YAAY,MAAM,CAAC,GAAG;AAC/D;AAEA,MAAa,gBACX,OACA,MACA,MACA,UACS;CACT,MAAM,OAAO,SAAS,OAAO,KAAK;CAClC,IAAI,MAAM;EACR,KAAK,KAAK,CAAC;EACX;CACF;CACA,KAAK;AACP;AAIA,MAAa,iBACX,UAK6D;CAC7D,CAAC,WAAW,MAAM,oBAAoB,CAAC;CACvC,CAAC,WAAW,yBAAyB,KAAK,CAAC;CAC3C,CAAC,SAAS,MAAM,qBAAqB,CAAC,MAAM,YAAY;AAC1D;AAGA,MAAM,eAAoD;CACxD,KAAA;CACA;CACA;AACF;AAEA,MAAa,wBAAwB,UACnC,oBAAoB,KAAK,CAAC,EAAE,OAAO,OAAO,SAC1C,cAAc;AAGhB,MAAa,mBAAmB,EAC9B,OACA,MACA,eAKa;CACb,MAAM,SAAS,oBAAoB,KAAK;CACxC,IAAI,CAAC,UAAU,CAAC,qBAAqB,KAAK,GACxC,OAAO;CAET,OACE,OAAO,SAAS,MAAM,MAAM,MAC5B,MAAM,MAAM,OACT,SAAS,SAAS,OAAO,QAAQ,CAAC,KAAK,WAAW,SAAS,MAC9D,KACA,aAAa,SAAS,IAAI,KAE1B,EAAE,YAAY,MAAM,gBAAgB,MAAM;AAE9C;AAWA,MAAa,wBACX,OACA,EACE,eAAe,OACf,mBAAmB,UACuC,CAAC,MACvC;CACtB,MAAM,WAAW,MAAM,aAAa,MAAM;CAC1C,MAAM,SAA4B;EAChC,WAAW,MAAM;EACjB,WAAW,MAAM,UAAU;EAE3B,YAAY,kBACV,OAAO,MAAM,UAAU,GACvB,MAAM,UAAU,QAClB;EACA,SAAS,MAAM;EACf,SAAS,MAAM,QAAQ;CACzB;CACA,IAAI,CAAC,cAEH,OAAO,YACL,aACC,oBACC,SAAS,YAAY,MAAM,MAAM,aAAa,YAAY,KACxD,WACA;CAER,OAAO;AACT"}
|
package/dist/esm/shared.d.ts
CHANGED
|
@@ -85,7 +85,7 @@ import { RouteTracker } from "./pages/TransactionPage/RouteTracker.js";
|
|
|
85
85
|
import { StartTransactionButton } from "./pages/TransactionPage/StartTransactionButton.js";
|
|
86
86
|
import { TokenValueBottomSheet } from "./pages/TransactionPage/TokenValueBottomSheet.js";
|
|
87
87
|
import { TransactionDoneButtons } from "./pages/TransactionPage/TransactionDoneButtons.js";
|
|
88
|
-
import { calculateValueLossPercentage, getTokenValueLossThreshold } from "./pages/TransactionPage/utils.js";
|
|
88
|
+
import { calculateValueLossPercentage, getTokenValueLossThreshold, isCallBundleNotFound } from "./pages/TransactionPage/utils.js";
|
|
89
89
|
import { I18nProvider } from "./providers/I18nProvider/I18nProvider.js";
|
|
90
90
|
import { QueryClientProvider } from "./providers/QueryClientProvider.js";
|
|
91
91
|
import { SDKClientProvider, useSDKClient } from "./providers/SDKClientProvider.js";
|
|
@@ -106,4 +106,4 @@ import { fitInputText } from "./utils/input.js";
|
|
|
106
106
|
import { resolveStorageScopeKey } from "./utils/scopeKeys.js";
|
|
107
107
|
import { isHttpUrl, openInNewTab } from "./utils/url.js";
|
|
108
108
|
import { shortenAddress } from "./utils/wallet.js";
|
|
109
|
-
export { ActionRow, AddressType, AmountInputEndAdornment, AvatarBadgedDefault, BaseTransactionButton, BookmarkStoreProvider, type BottomSheetBase, ButtonTertiary, Card, CardIconButton, CardTitle, ChainAvatar, ChainSelect, ConfirmToAddressSheet, ContactSupportButton, ContractComponent, DateLabelContainer, DateLabelText, DetailInfoIcon, DetailLabel, DetailLabelContainer, DetailRow, DetailValue, ElementId, ExchangeRateBottomSheet, type ExchangeRateBottomSheetBase, ExecutionDoneCard, type ExecutionRow, ExecutionStatusCard, ExternalLink, FeeBreakdownTooltip, FormControl, FormKeyHelper, type FormRef, type FormType, type FormTypeProps, I18nProvider, IconCircle, IconTypography, Input, InputCard, InputPriceButton, ListItemButton, MainWarningMessages, PageContainer, PoweredBy, ProgressToNextUpdate, QueryClientProvider, RouteCard, RouteCardSkeleton, RouteDetails, RouteExecutionStatus, RouteNotFoundCard, RouteTokens, RouteTracker, SDKClientProvider, SearchInput, SearchTokenInput, SelectChainPage, SendToWalletButton, SentToWalletRow, SettingsStoreProvider, Stack, StartTransactionButton, StatusIcon, StepActionsList, StoreProvider, Token, TokenAvatar, TokenNotFound, TokenRate, TokenValueBottomSheet, TransactionDoneButtons, VirtualizedTokenList, WalletProvider, WarningMessages, type WidgetConfig, WidgetEvent, WidgetProvider, type WidgetTheme, buildRouteFromTxHistory, calculateValueLossPercentage, createElementId, createTheme, fitInputText, formatDuration, formatInputAmount, formatTokenAmount, formatTokenPrice, getAccumulatedFeeCostsBreakdown, getPriceImpact, getSourceTxHash, getTokenValueLossThreshold, hasEnumFlag, isHttpUrl, isRouteActive, isRouteDone, isRouteFailed, navigationRoutes, openInNewTab, priceToTokenAmount, resolveStorageScopeKey, shortenAddress, usdDecimals, useAddressActivity, useAddressValidation, useAvailableChains, useChain, useChainOrderStore, useContactSupport, useDebouncedWatch, useExecutionRows, useExplorer, useFieldActions, useFieldValues, useHeader, useHeaderStore, useInputModeStore, useListHeight, useNavigateBack, useRouteExecution, useRouteExecutionMessage, useRouteExecutionStore, useRouteExecutionStoreContext, useRoutes, useSDKClient, useSetHeaderHeight, useSettingsStoreContext, useToAddressRequirements, useToken, useTokenAddressBalance, useTokenBalances, useTokenList, useTokenSelect, useTools, useWidgetConfig, useWidgetEvents };
|
|
109
|
+
export { ActionRow, AddressType, AmountInputEndAdornment, AvatarBadgedDefault, BaseTransactionButton, BookmarkStoreProvider, type BottomSheetBase, ButtonTertiary, Card, CardIconButton, CardTitle, ChainAvatar, ChainSelect, ConfirmToAddressSheet, ContactSupportButton, ContractComponent, DateLabelContainer, DateLabelText, DetailInfoIcon, DetailLabel, DetailLabelContainer, DetailRow, DetailValue, ElementId, ExchangeRateBottomSheet, type ExchangeRateBottomSheetBase, ExecutionDoneCard, type ExecutionRow, ExecutionStatusCard, ExternalLink, FeeBreakdownTooltip, FormControl, FormKeyHelper, type FormRef, type FormType, type FormTypeProps, I18nProvider, IconCircle, IconTypography, Input, InputCard, InputPriceButton, ListItemButton, MainWarningMessages, PageContainer, PoweredBy, ProgressToNextUpdate, QueryClientProvider, RouteCard, RouteCardSkeleton, RouteDetails, RouteExecutionStatus, RouteNotFoundCard, RouteTokens, RouteTracker, SDKClientProvider, SearchInput, SearchTokenInput, SelectChainPage, SendToWalletButton, SentToWalletRow, SettingsStoreProvider, Stack, StartTransactionButton, StatusIcon, StepActionsList, StoreProvider, Token, TokenAvatar, TokenNotFound, TokenRate, TokenValueBottomSheet, TransactionDoneButtons, VirtualizedTokenList, WalletProvider, WarningMessages, type WidgetConfig, WidgetEvent, WidgetProvider, type WidgetTheme, buildRouteFromTxHistory, calculateValueLossPercentage, createElementId, createTheme, fitInputText, formatDuration, formatInputAmount, formatTokenAmount, formatTokenPrice, getAccumulatedFeeCostsBreakdown, getPriceImpact, getSourceTxHash, getTokenValueLossThreshold, hasEnumFlag, isCallBundleNotFound, isHttpUrl, isRouteActive, isRouteDone, isRouteFailed, navigationRoutes, openInNewTab, priceToTokenAmount, resolveStorageScopeKey, shortenAddress, usdDecimals, useAddressActivity, useAddressValidation, useAvailableChains, useChain, useChainOrderStore, useContactSupport, useDebouncedWatch, useExecutionRows, useExplorer, useFieldActions, useFieldValues, useHeader, useHeaderStore, useInputModeStore, useListHeight, useNavigateBack, useRouteExecution, useRouteExecutionMessage, useRouteExecutionStore, useRouteExecutionStoreContext, useRoutes, useSDKClient, useSetHeaderHeight, useSettingsStoreContext, useToAddressRequirements, useToken, useTokenAddressBalance, useTokenBalances, useTokenList, useTokenSelect, useTools, useWidgetConfig, useWidgetEvents };
|
package/dist/esm/shared.js
CHANGED
|
@@ -96,7 +96,7 @@ import { TransactionDoneButtons } from "./pages/TransactionPage/TransactionDoneB
|
|
|
96
96
|
import { useAddressActivity } from "./hooks/useAddressActivity.js";
|
|
97
97
|
import { ConfirmToAddressSheet } from "./pages/TransactionPage/ConfirmToAddressSheet.js";
|
|
98
98
|
import { StartTransactionButton } from "./pages/TransactionPage/StartTransactionButton.js";
|
|
99
|
-
import { calculateValueLossPercentage, getTokenValueLossThreshold } from "./pages/TransactionPage/utils.js";
|
|
99
|
+
import { calculateValueLossPercentage, getTokenValueLossThreshold, isCallBundleNotFound } from "./pages/TransactionPage/utils.js";
|
|
100
100
|
import { TokenValueBottomSheet } from "./pages/TransactionPage/TokenValueBottomSheet.js";
|
|
101
101
|
import { I18nProvider } from "./providers/I18nProvider/I18nProvider.js";
|
|
102
102
|
import { QueryClientProvider } from "./providers/QueryClientProvider.js";
|
|
@@ -104,4 +104,4 @@ import { createTheme } from "./themes/createTheme.js";
|
|
|
104
104
|
import { WalletProvider } from "./providers/WalletProvider/WalletProvider.js";
|
|
105
105
|
import { StoreProvider } from "./stores/StoreProvider.js";
|
|
106
106
|
import { useTokenList } from "./hooks/useTokenList.js";
|
|
107
|
-
export { ActionRow, AddressType, AmountInputEndAdornment, AvatarBadgedDefault, BaseTransactionButton, BookmarkStoreProvider, ButtonTertiary, Card, CardIconButton, CardTitle, ChainAvatar, ChainSelect, ConfirmToAddressSheet, ContactSupportButton, ContractComponent, DateLabelContainer, DateLabelText, DetailInfoIcon, DetailLabel, DetailLabelContainer, DetailRow, DetailValue, ElementId, ExchangeRateBottomSheet, ExecutionDoneCard, ExecutionStatusCard, ExternalLink, FeeBreakdownTooltip, FormControl, FormKeyHelper, I18nProvider, IconCircle, IconTypography, Input, InputCard, InputPriceButton, ListItemButton, MainWarningMessages, PageContainer, PoweredBy, ProgressToNextUpdate, QueryClientProvider, RouteCard, RouteCardSkeleton, RouteDetails, RouteExecutionStatus, RouteNotFoundCard, RouteTokens, RouteTracker, SDKClientProvider, SearchInput, SearchTokenInput, SelectChainPage, SendToWalletButton, SentToWalletRow, SettingsStoreProvider, Stack, StartTransactionButton, StatusIcon, StepActionsList, StoreProvider, Token, TokenAvatar, TokenNotFound, TokenRate, TokenValueBottomSheet, TransactionDoneButtons, VirtualizedTokenList, WalletProvider, WarningMessages, WidgetEvent, WidgetProvider, buildRouteFromTxHistory, calculateValueLossPercentage, createElementId, createTheme, fitInputText, formatDuration, formatInputAmount, formatTokenAmount, formatTokenPrice, getAccumulatedFeeCostsBreakdown, getPriceImpact, getSourceTxHash, getTokenValueLossThreshold, hasEnumFlag, isHttpUrl, isRouteActive, isRouteDone, isRouteFailed, navigationRoutes, openInNewTab, priceToTokenAmount, resolveStorageScopeKey, shortenAddress, usdDecimals, useAddressActivity, useAddressValidation, useAvailableChains, useChain, useChainOrderStore, useContactSupport, useDebouncedWatch, useExecutionRows, useExplorer, useFieldActions, useFieldValues, useHeader, useHeaderStore, useInputModeStore, useListHeight, useNavigateBack, useRouteExecution, useRouteExecutionMessage, useRouteExecutionStore, useRouteExecutionStoreContext, useRoutes, useSDKClient, useSetHeaderHeight, useSettingsStoreContext, useToAddressRequirements, useToken, useTokenAddressBalance, useTokenBalances, useTokenList, useTokenSelect, useTools, useWidgetConfig, useWidgetEvents };
|
|
107
|
+
export { ActionRow, AddressType, AmountInputEndAdornment, AvatarBadgedDefault, BaseTransactionButton, BookmarkStoreProvider, ButtonTertiary, Card, CardIconButton, CardTitle, ChainAvatar, ChainSelect, ConfirmToAddressSheet, ContactSupportButton, ContractComponent, DateLabelContainer, DateLabelText, DetailInfoIcon, DetailLabel, DetailLabelContainer, DetailRow, DetailValue, ElementId, ExchangeRateBottomSheet, ExecutionDoneCard, ExecutionStatusCard, ExternalLink, FeeBreakdownTooltip, FormControl, FormKeyHelper, I18nProvider, IconCircle, IconTypography, Input, InputCard, InputPriceButton, ListItemButton, MainWarningMessages, PageContainer, PoweredBy, ProgressToNextUpdate, QueryClientProvider, RouteCard, RouteCardSkeleton, RouteDetails, RouteExecutionStatus, RouteNotFoundCard, RouteTokens, RouteTracker, SDKClientProvider, SearchInput, SearchTokenInput, SelectChainPage, SendToWalletButton, SentToWalletRow, SettingsStoreProvider, Stack, StartTransactionButton, StatusIcon, StepActionsList, StoreProvider, Token, TokenAvatar, TokenNotFound, TokenRate, TokenValueBottomSheet, TransactionDoneButtons, VirtualizedTokenList, WalletProvider, WarningMessages, WidgetEvent, WidgetProvider, buildRouteFromTxHistory, calculateValueLossPercentage, createElementId, createTheme, fitInputText, formatDuration, formatInputAmount, formatTokenAmount, formatTokenPrice, getAccumulatedFeeCostsBreakdown, getPriceImpact, getSourceTxHash, getTokenValueLossThreshold, hasEnumFlag, isCallBundleNotFound, isHttpUrl, isRouteActive, isRouteDone, isRouteFailed, navigationRoutes, openInNewTab, priceToTokenAmount, resolveStorageScopeKey, shortenAddress, usdDecimals, useAddressActivity, useAddressValidation, useAvailableChains, useChain, useChainOrderStore, useContactSupport, useDebouncedWatch, useExecutionRows, useExplorer, useFieldActions, useFieldValues, useHeader, useHeaderStore, useInputModeStore, useListHeight, useNavigateBack, useRouteExecution, useRouteExecutionMessage, useRouteExecutionStore, useRouteExecutionStoreContext, useRoutes, useSDKClient, useSetHeaderHeight, useSettingsStoreContext, useToAddressRequirements, useToken, useTokenAddressBalance, useTokenBalances, useTokenList, useTokenSelect, useTools, useWidgetConfig, useWidgetEvents };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ExecutionAction, RouteExtended } from "@lifi/sdk";
|
|
1
|
+
import { ExecutionAction, LiFiStepExtended, RouteExtended } from "@lifi/sdk";
|
|
2
2
|
//#region src/stores/routes/utils.d.ts
|
|
3
3
|
export declare const isRouteDone: (route: RouteExtended) => boolean;
|
|
4
4
|
export declare const isRouteFailed: (route: RouteExtended) => boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","names":[],"sources":["../../../../src/stores/routes/utils.ts"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"utils.d.ts","names":[],"sources":["../../../../src/stores/routes/utils.ts"],"mappings":";;qBAQa,cAAe,OAAO;qBAgBtB,gBAAiB,OAAO;qBAsBxB,gBAAiB,QAAQ;qBAgCzB,kBAAmB,QAAQ"}
|
|
@@ -12,6 +12,18 @@ const isRouteRefunded = (route) => {
|
|
|
12
12
|
const isRouteFailed = (route) => {
|
|
13
13
|
return route.steps.some((step) => step.execution?.status === "FAILED");
|
|
14
14
|
};
|
|
15
|
+
const getFailedStepAction = (route) => {
|
|
16
|
+
const step = route.steps.find((step) => step.execution?.status === "FAILED");
|
|
17
|
+
if (!step) return;
|
|
18
|
+
return {
|
|
19
|
+
step,
|
|
20
|
+
action: step.execution?.actions?.find((action) => action.status === "FAILED") || {
|
|
21
|
+
status: "FAILED",
|
|
22
|
+
type: "EXECUTION",
|
|
23
|
+
error: step.execution?.error
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
};
|
|
15
27
|
const isRouteActive = (route) => {
|
|
16
28
|
if (!route) return false;
|
|
17
29
|
const isDone = isRouteDone(route);
|
|
@@ -30,6 +42,6 @@ const getSourceTxHash = (route) => {
|
|
|
30
42
|
return sourceAction?.txHash || sourceAction?.taskId;
|
|
31
43
|
};
|
|
32
44
|
//#endregion
|
|
33
|
-
export { getSourceTxHash, getUpdatedAction, isRouteActive, isRouteDone, isRouteFailed, isRoutePartiallyDone, isRouteRefunded };
|
|
45
|
+
export { getFailedStepAction, getSourceTxHash, getUpdatedAction, isRouteActive, isRouteDone, isRouteFailed, isRoutePartiallyDone, isRouteRefunded };
|
|
34
46
|
|
|
35
47
|
//# sourceMappingURL=utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","names":[],"sources":["../../../../src/stores/routes/utils.ts"],"sourcesContent":["import type {
|
|
1
|
+
{"version":3,"file":"utils.js","names":[],"sources":["../../../../src/stores/routes/utils.ts"],"sourcesContent":["import type {\n ExecutionAction,\n ExecutionActionType,\n LiFiStepExtended,\n RouteExtended,\n} from '@lifi/sdk'\nimport microdiff from 'microdiff'\n\nexport const isRouteDone = (route: RouteExtended): boolean => {\n return route.steps.every((step) => step.execution?.status === 'DONE')\n}\n\nexport const isRoutePartiallyDone = (route: RouteExtended): boolean => {\n return route.steps.some((step) =>\n step.execution?.actions?.some((action) => action.substatus === 'PARTIAL')\n )\n}\n\nexport const isRouteRefunded = (route: RouteExtended): boolean => {\n return route.steps.some((step) =>\n step.execution?.actions?.some((action) => action.substatus === 'REFUNDED')\n )\n}\n\nexport const isRouteFailed = (route: RouteExtended): boolean => {\n return route.steps.some((step) => step.execution?.status === 'FAILED')\n}\n\n// A step can fail before any action, so its own error then stands in.\nexport const getFailedStepAction = (\n route: RouteExtended\n): { step: LiFiStepExtended; action: ExecutionAction } | undefined => {\n const step = route.steps.find((step) => step.execution?.status === 'FAILED')\n if (!step) {\n return undefined\n }\n const action = step.execution?.actions?.find(\n (action) => action.status === 'FAILED'\n ) || {\n status: 'FAILED',\n type: 'EXECUTION' as ExecutionActionType,\n error: step.execution?.error,\n }\n return { step, action }\n}\n\nexport const isRouteActive = (route?: RouteExtended): boolean => {\n if (!route) {\n return false\n }\n const isDone = isRouteDone(route)\n const isFailed = isRouteFailed(route)\n const alreadyStarted = route.steps.some((step) => step.execution)\n return !isDone && !isFailed && alreadyStarted\n}\n\nexport const getUpdatedAction = (\n currentRoute: RouteExtended,\n updatedRoute: RouteExtended\n): ExecutionAction | undefined => {\n const actionDiff = microdiff(currentRoute, updatedRoute).find((diff) =>\n diff.path.includes('actions')\n )\n if (!actionDiff) {\n return undefined\n }\n // Find action index in the diff array so we can slice the complete action object\n // e.g. ['steps', 0, 'execution', 'actions', 0, 'message']\n const actionDiffIndex = actionDiff.path.indexOf('actions') + 2\n const actionPathSlice = actionDiff.path.slice(0, actionDiffIndex)\n // Reduce updated route using the diff path to get updated process\n const action = actionPathSlice.reduce(\n (obj, path) => obj[path],\n updatedRoute as any\n ) as ExecutionAction\n return action\n}\n\nexport const getSourceTxHash = (route?: RouteExtended): string | undefined => {\n const sourceAction = route?.steps[0].execution?.actions\n ?.filter(\n (action) => !['RESET_ALLOWANCE', 'SET_ALLOWANCE'].includes(action.type)\n )\n .find((action) => action.txHash || action.taskId)\n return sourceAction?.txHash || sourceAction?.taskId\n}\n"],"mappings":";;AAQA,MAAa,eAAe,UAAkC;CAC5D,OAAO,MAAM,MAAM,OAAO,SAAS,KAAK,WAAW,WAAW,MAAM;AACtE;AAEA,MAAa,wBAAwB,UAAkC;CACrE,OAAO,MAAM,MAAM,MAAM,SACvB,KAAK,WAAW,SAAS,MAAM,WAAW,OAAO,cAAc,SAAS,CAC1E;AACF;AAEA,MAAa,mBAAmB,UAAkC;CAChE,OAAO,MAAM,MAAM,MAAM,SACvB,KAAK,WAAW,SAAS,MAAM,WAAW,OAAO,cAAc,UAAU,CAC3E;AACF;AAEA,MAAa,iBAAiB,UAAkC;CAC9D,OAAO,MAAM,MAAM,MAAM,SAAS,KAAK,WAAW,WAAW,QAAQ;AACvE;AAGA,MAAa,uBACX,UACoE;CACpE,MAAM,OAAO,MAAM,MAAM,MAAM,SAAS,KAAK,WAAW,WAAW,QAAQ;CAC3E,IAAI,CAAC,MACH;CASF,OAAO;EAAE;EAAM,QAPA,KAAK,WAAW,SAAS,MACrC,WAAW,OAAO,WAAW,QAChC,KAAK;GACH,QAAQ;GACR,MAAM;GACN,OAAO,KAAK,WAAW;EACzB;CACsB;AACxB;AAEA,MAAa,iBAAiB,UAAmC;CAC/D,IAAI,CAAC,OACH,OAAO;CAET,MAAM,SAAS,YAAY,KAAK;CAChC,MAAM,WAAW,cAAc,KAAK;CACpC,MAAM,iBAAiB,MAAM,MAAM,MAAM,SAAS,KAAK,SAAS;CAChE,OAAO,CAAC,UAAU,CAAC,YAAY;AACjC;AAEA,MAAa,oBACX,cACA,iBACgC;CAChC,MAAM,aAAa,UAAU,cAAc,YAAY,CAAC,CAAC,MAAM,SAC7D,KAAK,KAAK,SAAS,SAAS,CAC9B;CACA,IAAI,CAAC,YACH;CAIF,MAAM,kBAAkB,WAAW,KAAK,QAAQ,SAAS,IAAI;CAO7D,OANwB,WAAW,KAAK,MAAM,GAAG,eAEpB,CAAC,CAAC,QAC5B,KAAK,SAAS,IAAI,OACnB,YAEU;AACd;AAEA,MAAa,mBAAmB,UAA8C;CAC5E,MAAM,eAAe,OAAO,MAAM,EAAE,CAAC,WAAW,SAC5C,QACC,WAAW,CAAC,CAAC,mBAAmB,eAAe,CAAC,CAAC,SAAS,OAAO,IAAI,CACxE,CAAC,CACA,MAAM,WAAW,OAAO,UAAU,OAAO,MAAM;CAClD,OAAO,cAAc,UAAU,cAAc;AAC/C"}
|
|
@@ -99,6 +99,10 @@ function getErrorMessage(t, getChainById, step, failedAction) {
|
|
|
99
99
|
chainName: getChainById(step.action.fromChainId)?.name ?? ""
|
|
100
100
|
});
|
|
101
101
|
break;
|
|
102
|
+
case LiFiErrorCode.CallBundleNotFound:
|
|
103
|
+
title = t("error.title.callBundleNotFound");
|
|
104
|
+
message = t("error.message.callBundleNotFound");
|
|
105
|
+
break;
|
|
102
106
|
default:
|
|
103
107
|
title = t("error.title.unknown");
|
|
104
108
|
if (failedAction?.txHash) message = t("error.message.transactionFailed");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getErrorMessage.js","names":[],"sources":["../../../src/utils/getErrorMessage.ts"],"sourcesContent":["import {\n type EVMChain,\n type ExecutionAction,\n LiFiErrorCode,\n type LiFiStepExtended,\n} from '@lifi/sdk'\nimport type { TFunction } from 'i18next'\nimport { formatTokenAmount, wrapLongWords } from '../utils/format.js'\n\nexport function getErrorMessage(\n t: TFunction,\n getChainById: (chainId: number) => EVMChain | undefined,\n step: LiFiStepExtended,\n failedAction?: ExecutionAction\n): { title: string; message: string } {\n const error = failedAction?.error\n if (!error) {\n return {\n title: t('error.title.unknown'),\n message: t('error.message.unknown'),\n }\n }\n\n const getDefaultErrorMessage = (key?: string) =>\n `${t((key as any) ?? 'error.message.transactionNotSent')} ${t(\n 'error.message.remainInYourWallet',\n {\n amount: formatTokenAmount(\n BigInt(step.action.fromAmount),\n step.action.fromToken.decimals\n ),\n tokenSymbol: step.action.fromToken.symbol,\n chainName: getChainById(step.action.fromChainId)?.name ?? '',\n }\n )}`\n\n let title = ''\n let message = ''\n switch (error.code) {\n case LiFiErrorCode.AllowanceRequired:\n title = t('error.title.allowanceRequired')\n message = t('error.message.allowanceRequired', {\n tokenSymbol: step.action.fromToken.symbol,\n })\n break\n case LiFiErrorCode.BalanceError:\n title = t('error.title.balanceIsTooLow')\n message = getDefaultErrorMessage()\n break\n case LiFiErrorCode.ChainSwitchError:\n title = t('error.title.chainSwitch')\n message = getDefaultErrorMessage()\n break\n case LiFiErrorCode.GasLimitError:\n title = t('error.title.gasLimitIsTooLow')\n message = getDefaultErrorMessage()\n break\n case LiFiErrorCode.InsufficientFunds:\n title = t('error.title.insufficientFunds')\n message = `${t(\n 'error.message.insufficientFunds'\n )} ${getDefaultErrorMessage()}`\n break\n case LiFiErrorCode.InsufficientGas:\n title = t('error.title.insufficientGas')\n message = `${t(\n 'error.message.insufficientFunds'\n )} ${getDefaultErrorMessage()}`\n break\n case LiFiErrorCode.SlippageError:\n title = t('error.title.slippageNotMet')\n message = t('error.message.slippageThreshold')\n break\n case LiFiErrorCode.TransactionFailed:\n title = t('error.title.transactionFailed')\n message = t('error.message.transactionFailed')\n break\n case LiFiErrorCode.TransactionExpired:\n title = t('error.title.transactionExpired')\n message = t('error.message.transactionExpired')\n break\n case LiFiErrorCode.TransactionSimulationFailed:\n title = t('error.title.transactionSimulationFailed')\n message = t('error.message.transactionSimulationFailed')\n break\n case LiFiErrorCode.WalletChangedDuringExecution:\n title = t('error.title.walletMismatch')\n message = t('error.message.walletChangedDuringExecution')\n break\n case LiFiErrorCode.RateLimitExceeded:\n title = t('error.title.rateLimitExceeded')\n message = t('error.message.rateLimitExceeded')\n break\n case LiFiErrorCode.ThirdPartyError:\n title = t('error.title.thirdPartyError')\n message = t('error.message.thirdPartyError')\n break\n case LiFiErrorCode.TransactionUnderpriced:\n title = t('error.title.transactionUnderpriced')\n message = getDefaultErrorMessage()\n break\n case LiFiErrorCode.TransactionUnprepared:\n title = t('error.title.transactionUnprepared')\n message = getDefaultErrorMessage()\n break\n case LiFiErrorCode.TransactionCanceled:\n title = t('error.title.transactionCanceled')\n message = getDefaultErrorMessage('error.message.transactionCanceled')\n break\n case LiFiErrorCode.TransactionRejected:\n title = t('error.title.transactionRejected')\n message = getDefaultErrorMessage('error.message.transactionRejected')\n break\n case LiFiErrorCode.TransactionConflict:\n title = t('error.title.transactionConflict')\n message = getDefaultErrorMessage('error.message.transactionConflict')\n break\n case LiFiErrorCode.ExchangeRateUpdateCanceled:\n title = t('error.title.exchangeRateUpdateCanceled')\n message = getDefaultErrorMessage()\n break\n case LiFiErrorCode.SignatureRejected:\n title = t('error.title.signatureRejected')\n message = t('error.message.signatureRejected', {\n amount: formatTokenAmount(\n BigInt(step.action.fromAmount),\n step.action.fromToken.decimals\n ),\n tokenSymbol: step.action.fromToken.symbol,\n chainName: getChainById(step.action.fromChainId)?.name ?? '',\n })\n break\n default:\n title = t('error.title.unknown')\n if (failedAction?.txHash) {\n message = t('error.message.transactionFailed')\n } else {\n message = error.message || t('error.message.unknown')\n }\n break\n }\n message = wrapLongWords(message)\n return { title, message }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"getErrorMessage.js","names":[],"sources":["../../../src/utils/getErrorMessage.ts"],"sourcesContent":["import {\n type EVMChain,\n type ExecutionAction,\n LiFiErrorCode,\n type LiFiStepExtended,\n} from '@lifi/sdk'\nimport type { TFunction } from 'i18next'\nimport { formatTokenAmount, wrapLongWords } from '../utils/format.js'\n\nexport function getErrorMessage(\n t: TFunction,\n getChainById: (chainId: number) => EVMChain | undefined,\n step: LiFiStepExtended,\n failedAction?: ExecutionAction\n): { title: string; message: string } {\n const error = failedAction?.error\n if (!error) {\n return {\n title: t('error.title.unknown'),\n message: t('error.message.unknown'),\n }\n }\n\n const getDefaultErrorMessage = (key?: string) =>\n `${t((key as any) ?? 'error.message.transactionNotSent')} ${t(\n 'error.message.remainInYourWallet',\n {\n amount: formatTokenAmount(\n BigInt(step.action.fromAmount),\n step.action.fromToken.decimals\n ),\n tokenSymbol: step.action.fromToken.symbol,\n chainName: getChainById(step.action.fromChainId)?.name ?? '',\n }\n )}`\n\n let title = ''\n let message = ''\n switch (error.code) {\n case LiFiErrorCode.AllowanceRequired:\n title = t('error.title.allowanceRequired')\n message = t('error.message.allowanceRequired', {\n tokenSymbol: step.action.fromToken.symbol,\n })\n break\n case LiFiErrorCode.BalanceError:\n title = t('error.title.balanceIsTooLow')\n message = getDefaultErrorMessage()\n break\n case LiFiErrorCode.ChainSwitchError:\n title = t('error.title.chainSwitch')\n message = getDefaultErrorMessage()\n break\n case LiFiErrorCode.GasLimitError:\n title = t('error.title.gasLimitIsTooLow')\n message = getDefaultErrorMessage()\n break\n case LiFiErrorCode.InsufficientFunds:\n title = t('error.title.insufficientFunds')\n message = `${t(\n 'error.message.insufficientFunds'\n )} ${getDefaultErrorMessage()}`\n break\n case LiFiErrorCode.InsufficientGas:\n title = t('error.title.insufficientGas')\n message = `${t(\n 'error.message.insufficientFunds'\n )} ${getDefaultErrorMessage()}`\n break\n case LiFiErrorCode.SlippageError:\n title = t('error.title.slippageNotMet')\n message = t('error.message.slippageThreshold')\n break\n case LiFiErrorCode.TransactionFailed:\n title = t('error.title.transactionFailed')\n message = t('error.message.transactionFailed')\n break\n case LiFiErrorCode.TransactionExpired:\n title = t('error.title.transactionExpired')\n message = t('error.message.transactionExpired')\n break\n case LiFiErrorCode.TransactionSimulationFailed:\n title = t('error.title.transactionSimulationFailed')\n message = t('error.message.transactionSimulationFailed')\n break\n case LiFiErrorCode.WalletChangedDuringExecution:\n title = t('error.title.walletMismatch')\n message = t('error.message.walletChangedDuringExecution')\n break\n case LiFiErrorCode.RateLimitExceeded:\n title = t('error.title.rateLimitExceeded')\n message = t('error.message.rateLimitExceeded')\n break\n case LiFiErrorCode.ThirdPartyError:\n title = t('error.title.thirdPartyError')\n message = t('error.message.thirdPartyError')\n break\n case LiFiErrorCode.TransactionUnderpriced:\n title = t('error.title.transactionUnderpriced')\n message = getDefaultErrorMessage()\n break\n case LiFiErrorCode.TransactionUnprepared:\n title = t('error.title.transactionUnprepared')\n message = getDefaultErrorMessage()\n break\n case LiFiErrorCode.TransactionCanceled:\n title = t('error.title.transactionCanceled')\n message = getDefaultErrorMessage('error.message.transactionCanceled')\n break\n case LiFiErrorCode.TransactionRejected:\n title = t('error.title.transactionRejected')\n message = getDefaultErrorMessage('error.message.transactionRejected')\n break\n case LiFiErrorCode.TransactionConflict:\n title = t('error.title.transactionConflict')\n message = getDefaultErrorMessage('error.message.transactionConflict')\n break\n case LiFiErrorCode.ExchangeRateUpdateCanceled:\n title = t('error.title.exchangeRateUpdateCanceled')\n message = getDefaultErrorMessage()\n break\n case LiFiErrorCode.SignatureRejected:\n title = t('error.title.signatureRejected')\n message = t('error.message.signatureRejected', {\n amount: formatTokenAmount(\n BigInt(step.action.fromAmount),\n step.action.fromToken.decimals\n ),\n tokenSymbol: step.action.fromToken.symbol,\n chainName: getChainById(step.action.fromChainId)?.name ?? '',\n })\n break\n // No \"remain in your wallet\" suffix: the funds may already be gone.\n case LiFiErrorCode.CallBundleNotFound:\n title = t('error.title.callBundleNotFound')\n message = t('error.message.callBundleNotFound')\n break\n default:\n title = t('error.title.unknown')\n if (failedAction?.txHash) {\n message = t('error.message.transactionFailed')\n } else {\n message = error.message || t('error.message.unknown')\n }\n break\n }\n message = wrapLongWords(message)\n return { title, message }\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lifi/widget",
|
|
3
|
-
"version": "4.10.
|
|
3
|
+
"version": "4.10.1",
|
|
4
4
|
"description": "LI.FI Widget for cross-chain bridging and swapping. It will drive your multi-chain strategy and attract new users from everywhere.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/esm/index.js",
|
|
@@ -57,9 +57,9 @@
|
|
|
57
57
|
"dependencies": {
|
|
58
58
|
"@emotion/react": "^11.14.0",
|
|
59
59
|
"@emotion/styled": "^11.14.1",
|
|
60
|
-
"@lifi/sdk": "^4.
|
|
61
|
-
"@lifi/wallet-management": "4.3.
|
|
62
|
-
"@lifi/widget-provider": "4.6.
|
|
60
|
+
"@lifi/sdk": "^4.12.0",
|
|
61
|
+
"@lifi/wallet-management": "4.3.3",
|
|
62
|
+
"@lifi/widget-provider": "4.6.1",
|
|
63
63
|
"@mui/icons-material": "^9.4.0",
|
|
64
64
|
"@mui/material": "^9.4.0",
|
|
65
65
|
"@mui/system": "^9.4.0",
|
package/src/config/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export const name = '@lifi/widget'
|
|
2
|
-
export const version = '4.10.
|
|
2
|
+
export const version = '4.10.1'
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useEffect, useRef, useState } from 'react'
|
|
2
2
|
|
|
3
3
|
/** Smallest gap between UI updates, in milliseconds. */
|
|
4
|
-
const DISPLAY_INTERVAL = 1200
|
|
4
|
+
export const DISPLAY_INTERVAL = 1200
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Returns `live`, but changes it at most once every {@link DISPLAY_INTERVAL}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { RouteExtended } from '@lifi/sdk'
|
|
2
2
|
import { useTranslation } from 'react-i18next'
|
|
3
3
|
import { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'
|
|
4
4
|
import { RouteExecutionStatus } from '../stores/routes/types.js'
|
|
5
|
+
import { getFailedStepAction } from '../stores/routes/utils.js'
|
|
5
6
|
import { getActionMessage } from '../utils/getActionMessage.js'
|
|
6
7
|
import { getErrorMessage } from '../utils/getErrorMessage.js'
|
|
7
8
|
import { useAvailableChains } from './useAvailableChains.js'
|
|
@@ -76,20 +77,16 @@ export const useRouteExecutionMessage = (
|
|
|
76
77
|
break
|
|
77
78
|
}
|
|
78
79
|
case RouteExecutionStatus.Failed: {
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
)
|
|
82
|
-
if (!step) {
|
|
80
|
+
const failed = getFailedStepAction(route)
|
|
81
|
+
if (!failed) {
|
|
83
82
|
break
|
|
84
83
|
}
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
} // synthetic action to represent a failed execution with no actions
|
|
92
|
-
const actionMessage = getErrorMessage(t, getChainById, step, action)
|
|
84
|
+
const actionMessage = getErrorMessage(
|
|
85
|
+
t,
|
|
86
|
+
getChainById,
|
|
87
|
+
failed.step,
|
|
88
|
+
failed.action
|
|
89
|
+
)
|
|
93
90
|
title = actionMessage.title
|
|
94
91
|
message = actionMessage.message
|
|
95
92
|
break
|