@rango-dev/widget-embedded 0.1.10-next.106 → 0.1.10-next.114

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.
Files changed (62) hide show
  1. package/dist/App.d.ts.map +1 -1
  2. package/dist/components/AppRoutes.d.ts.map +1 -1
  3. package/dist/components/HeaderButtons.d.ts +4 -1
  4. package/dist/components/HeaderButtons.d.ts.map +1 -1
  5. package/dist/components/Layout.d.ts.map +1 -1
  6. package/dist/components/SwapDetailsPlaceholder.d.ts +9 -0
  7. package/dist/components/SwapDetailsPlaceholder.d.ts.map +1 -0
  8. package/dist/components/TokenPreview.d.ts +1 -1
  9. package/dist/components/TokenPreview.d.ts.map +1 -1
  10. package/dist/globalStyles.d.ts.map +1 -1
  11. package/dist/pages/ConfirmSwapPage.d.ts.map +1 -1
  12. package/dist/pages/HistoryPage.d.ts.map +1 -1
  13. package/dist/pages/Home.d.ts.map +1 -1
  14. package/dist/pages/LiquiditySourcesPage.d.ts.map +1 -1
  15. package/dist/pages/SelectTokenPage.d.ts.map +1 -1
  16. package/dist/pages/SettingsPage.d.ts.map +1 -1
  17. package/dist/pages/SwapDetailsPage.d.ts +1 -1
  18. package/dist/pages/SwapDetailsPage.d.ts.map +1 -1
  19. package/dist/pages/WalletsPage.d.ts +1 -0
  20. package/dist/pages/WalletsPage.d.ts.map +1 -1
  21. package/dist/store/bestRoute.d.ts +1 -1
  22. package/dist/store/bestRoute.d.ts.map +1 -1
  23. package/dist/store/ui.d.ts.map +1 -1
  24. package/dist/store/wallets.d.ts +14 -0
  25. package/dist/store/wallets.d.ts.map +1 -1
  26. package/dist/utils/date.d.ts +3 -0
  27. package/dist/utils/date.d.ts.map +1 -0
  28. package/dist/utils/routing.d.ts +1 -0
  29. package/dist/utils/routing.d.ts.map +1 -1
  30. package/dist/utils/swap.d.ts.map +1 -1
  31. package/dist/widget-embedded.cjs.development.js +249 -115
  32. package/dist/widget-embedded.cjs.development.js.map +1 -1
  33. package/dist/widget-embedded.cjs.production.min.js +249 -115
  34. package/dist/widget-embedded.cjs.production.min.js.map +1 -1
  35. package/dist/widget-embedded.esm.js +250 -116
  36. package/dist/widget-embedded.esm.js.map +1 -1
  37. package/package.json +4 -3
  38. package/readme.md +1 -2
  39. package/src/App.tsx +4 -1
  40. package/src/components/AppRoutes.tsx +15 -10
  41. package/src/components/HeaderButtons.tsx +9 -2
  42. package/src/components/Layout.tsx +25 -6
  43. package/src/components/SwapDetailsPlaceholder.tsx +32 -0
  44. package/src/components/TokenPreview.tsx +7 -4
  45. package/src/globalStyles.ts +2 -1
  46. package/src/pages/ConfirmSwapPage.tsx +9 -2
  47. package/src/pages/HistoryPage.tsx +4 -4
  48. package/src/pages/Home.tsx +18 -7
  49. package/src/pages/LiquiditySourcesPage.tsx +2 -0
  50. package/src/pages/SelectTokenPage.tsx +3 -0
  51. package/src/pages/SettingsPage.tsx +3 -0
  52. package/src/pages/SwapDetailsPage.tsx +63 -4
  53. package/src/pages/WalletsPage.tsx +27 -8
  54. package/src/store/bestRoute.ts +40 -13
  55. package/src/store/ui.ts +4 -0
  56. package/src/store/wallets.ts +4 -1
  57. package/src/utils/date.ts +62 -0
  58. package/src/utils/routing.ts +23 -13
  59. package/src/utils/swap.ts +3 -1
  60. package/dist/components/Header.d.ts +0 -10
  61. package/dist/components/Header.d.ts.map +0 -1
  62. package/src/components/Header.tsx +0 -37
@@ -25,6 +25,7 @@ var providerAll = require('@rango-dev/provider-all');
25
25
  var i18n = require('i18next');
26
26
  var i18n__default = _interopDefault(i18n);
27
27
  var queueManagerReact = require('@rango-dev/queue-manager-react');
28
+ var dayjs = _interopDefault(require('dayjs'));
28
29
  var copy = _interopDefault(require('copy-to-clipboard'));
29
30
  var Backend = _interopDefault(require('i18next-http-backend'));
30
31
  var LanguageDetector = _interopDefault(require('i18next-browser-languagedetector'));
@@ -594,6 +595,7 @@ function createBestRouteRequestBody(fromToken, toToken, inputAmount, wallets, se
594
595
  addresses: [wallet.address]
595
596
  });
596
597
  });
598
+ const filteredBlockchains = selectedWallets.map(wallet => wallet.chain);
597
599
  const requestBody = {
598
600
  amount: inputAmount.toString(),
599
601
  checkPrerequisites,
@@ -611,8 +613,10 @@ function createBestRouteRequestBody(fromToken, toToken, inputAmount, wallets, se
611
613
  selectedWallets: selectedWalletsMap,
612
614
  swapperGroups: disabledLiquiditySources,
613
615
  swappersGroupsExclude: true,
614
- //@ts-ignore
615
- slippage: slippage.toString()
616
+ slippage: slippage.toString(),
617
+ ...(checkPrerequisites && {
618
+ blockchains: filteredBlockchains
619
+ })
616
620
  };
617
621
  return requestBody;
618
622
  }
@@ -750,8 +754,13 @@ function getRequiredBalanceOfWallet(selectedWallet, fee) {
750
754
  return relatedFeeStatus.requiredAssets;
751
755
  }
752
756
  function isRouteParametersChanged(prevParams, currentParams) {
753
- return prevParams.fromChain?.name !== currentParams.fromChain?.name || prevParams.toChain?.name !== currentParams.toChain?.name || prevParams.fromToken?.symbol !== currentParams.fromToken?.symbol || prevParams.toToken?.symbol !== currentParams.toToken?.symbol || prevParams.fromToken?.blockchain !== currentParams.fromToken?.blockchain || prevParams.toToken?.blockchain !== currentParams.toToken?.blockchain || prevParams.fromToken?.address !== currentParams.fromToken?.address || prevParams.toToken?.address !== currentParams.toToken?.address || prevParams.inputAmount !== currentParams.inputAmount || prevParams.slippage !== currentParams.slippage || prevParams.customSlippage !== currentParams.customSlippage || prevParams.disabledLiquiditySources?.length !== currentParams.disabledLiquiditySources?.length;
757
+ return !!currentParams.fromToken && !!currentParams.toToken && (prevParams.fromChain?.name !== currentParams.fromChain?.name || prevParams.toChain?.name !== currentParams.toChain?.name || prevParams.fromToken?.symbol !== currentParams.fromToken?.symbol || prevParams.toToken?.symbol !== currentParams.toToken?.symbol || prevParams.fromToken?.blockchain !== currentParams.fromToken?.blockchain || prevParams.toToken?.blockchain !== currentParams.toToken?.blockchain || prevParams.fromToken?.address !== currentParams.fromToken?.address || prevParams.toToken?.address !== currentParams.toToken?.address || prevParams.inputAmount !== currentParams.inputAmount || prevParams.slippage !== currentParams.slippage || prevParams.customSlippage !== currentParams.customSlippage || prevParams.disabledLiquiditySources?.length !== currentParams.disabledLiquiditySources?.length);
754
758
  }
759
+ //todo: refactor bestRoute store and add loadingStatus
760
+ const getBestRouteStatus = (loading, error) => {
761
+ if (loading) return 'loading';
762
+ if (error) return 'failed';else return 'success';
763
+ };
755
764
 
756
765
  const createSelectors = _store => {
757
766
  let store = _store;
@@ -902,7 +911,7 @@ const useWalletsStore = /*#__PURE__*/createSelectors( /*#__PURE__*/zustand.creat
902
911
  }
903
912
  });
904
913
  return {
905
- selectedWallets: state.selectedWallets.concat(selectedWallets)
914
+ selectedWallets: selectedWallets
906
915
  };
907
916
  }),
908
917
  setSelectedWallet: wallet => set(state => ({
@@ -934,6 +943,7 @@ useWalletsStore.subscribe(state => state.balances, balances => {
934
943
  }, {
935
944
  equalityFn: shallow.shallow
936
945
  });
946
+ const fetchingBalanceSelector = state => !!state.balances.find(wallet => wallet.loading);
937
947
 
938
948
  const getUsdValue = (token, amount) => new BigNumber__default(amount || ZERO).multipliedBy(token?.usdPrice || 0);
939
949
  const useBestRouteStore = /*#__PURE__*/createSelectors( /*#__PURE__*/zustand.create()( /*#__PURE__*/middleware.subscribeWithSelector(set => ({
@@ -953,6 +963,7 @@ const useBestRouteStore = /*#__PURE__*/createSelectors( /*#__PURE__*/zustand.cre
953
963
  setBestRoute: bestRoute => set(state => {
954
964
  let outputAmount = null;
955
965
  let outputUsdValue = ZERO;
966
+ if (!state.inputAmount || state.inputAmount === '0') return {};
956
967
  if (!!bestRoute) {
957
968
  outputAmount = !!bestRoute.result?.outputAmount ? new BigNumber__default(bestRoute.result?.outputAmount) : null;
958
969
  outputUsdValue = calcOutputUsdValue(bestRoute.result?.outputAmount, getBestRouteToTokenUsdPrice(bestRoute) || state.toToken?.usdPrice);
@@ -1009,6 +1020,7 @@ const useBestRouteStore = /*#__PURE__*/createSelectors( /*#__PURE__*/zustand.cre
1009
1020
  toToken: token
1010
1021
  })),
1011
1022
  setInputAmount: amount => {
1023
+ console.log(amount, typeof amount);
1012
1024
  set(state => ({
1013
1025
  inputAmount: amount,
1014
1026
  ...(!amount && {
@@ -1051,7 +1063,7 @@ const useBestRouteStore = /*#__PURE__*/createSelectors( /*#__PURE__*/zustand.cre
1051
1063
  fromToken,
1052
1064
  inputAmount,
1053
1065
  outputAmount: null,
1054
- inputUsdValue: new BigNumber__default(0),
1066
+ inputUsdValue: getUsdValue(fromToken || null, inputAmount),
1055
1067
  outputUsdValue: new BigNumber__default(0),
1056
1068
  toChain,
1057
1069
  toToken,
@@ -1065,7 +1077,7 @@ const useBestRouteStore = /*#__PURE__*/createSelectors( /*#__PURE__*/zustand.cre
1065
1077
  }))));
1066
1078
  const bestRoute = (bestRouteStore, settingsStore) => {
1067
1079
  let abortController = null;
1068
- const fetchBestRoute = debounce(() => {
1080
+ const fetchBestRoute = () => {
1069
1081
  const {
1070
1082
  fromToken,
1071
1083
  toToken,
@@ -1076,12 +1088,12 @@ const bestRoute = (bestRouteStore, settingsStore) => {
1076
1088
  customSlippage,
1077
1089
  disabledLiquiditySources
1078
1090
  } = settingsStore.getState();
1079
- if (!fromToken || !toToken || !inputAmount) return;
1091
+ if (!fromToken || !toToken || !inputAmount || inputAmount === '0') return;
1080
1092
  abortController?.abort();
1081
1093
  abortController = new AbortController();
1082
1094
  const userSlippage = !!customSlippage ? customSlippage : slippage;
1083
1095
  const requestBody = createBestRouteRequestBody(fromToken, toToken, inputAmount, [], [], disabledLiquiditySources, userSlippage, false);
1084
- bestRouteStore.setState({
1096
+ if (!bestRouteStore.getState().loading) bestRouteStore.setState({
1085
1097
  loading: true,
1086
1098
  bestRoute: null,
1087
1099
  outputAmount: null,
@@ -1105,14 +1117,37 @@ const bestRoute = (bestRouteStore, settingsStore) => {
1105
1117
  loading: false
1106
1118
  });
1107
1119
  });
1108
- }, 600);
1120
+ };
1121
+ const debouncedFetchBestRoute = debounce(fetchBestRoute, 600);
1122
+ const bestRouteParamsListener = () => {
1123
+ const {
1124
+ fromToken,
1125
+ toToken,
1126
+ inputAmount,
1127
+ inputUsdValue
1128
+ } = useBestRouteStore.getState();
1129
+ if (!inputAmount || inputAmount === '0') return;
1130
+ if (tokensAreEqual(fromToken, toToken)) return bestRouteStore.setState({
1131
+ loading: false,
1132
+ bestRoute: null,
1133
+ outputAmount: new BigNumber__default(inputAmount),
1134
+ outputUsdValue: inputUsdValue
1135
+ });
1136
+ if (!bestRouteStore.getState().loading) bestRouteStore.setState({
1137
+ loading: true,
1138
+ bestRoute: null,
1139
+ outputAmount: null,
1140
+ outputUsdValue: new BigNumber__default(0)
1141
+ });
1142
+ debouncedFetchBestRoute();
1143
+ };
1109
1144
  useBestRouteStore.subscribe(state => ({
1110
1145
  fromChain: state.fromChain,
1111
1146
  fromToken: state.fromToken,
1112
1147
  toChain: state.toChain,
1113
1148
  toToken: state.toToken,
1114
1149
  inputAmount: state.inputAmount
1115
- }), fetchBestRoute.bind(null), {
1150
+ }), bestRouteParamsListener, {
1116
1151
  equalityFn: (prevState, state) => {
1117
1152
  if (isRouteParametersChanged(prevState, state)) return false;else return true;
1118
1153
  }
@@ -1121,7 +1156,7 @@ const bestRoute = (bestRouteStore, settingsStore) => {
1121
1156
  slippage: state.slippage,
1122
1157
  customSlippage: state.customSlippage,
1123
1158
  disabledLiquiditySources: state.disabledLiquiditySources
1124
- }), fetchBestRoute.bind(null), {
1159
+ }), bestRouteParamsListener, {
1125
1160
  equalityFn: (prevState, state) => {
1126
1161
  if (isRouteParametersChanged(prevState, state)) return false;else return true;
1127
1162
  }
@@ -1146,11 +1181,15 @@ var SearchParams;
1146
1181
  const useUiStore = /*#__PURE__*/createSelectors( /*#__PURE__*/zustand.create()(set => ({
1147
1182
  connectWalletsButtonDisabled: false,
1148
1183
  selectedSwapRequestId: null,
1184
+ currentPage: '',
1149
1185
  toggleConnectWalletsButton: () => set(state => ({
1150
1186
  connectWalletsButtonDisabled: !state.connectWalletsButtonDisabled
1151
1187
  })),
1152
1188
  setSelectedSwap: requestId => set({
1153
1189
  selectedSwapRequestId: requestId
1190
+ }),
1191
+ setCurrentPage: path => set({
1192
+ currentPage: path
1154
1193
  })
1155
1194
  })));
1156
1195
 
@@ -1284,67 +1323,6 @@ function UpdateUrl() {
1284
1323
  return null;
1285
1324
  }
1286
1325
 
1287
- const ButtonsContainer = /*#__PURE__*/ui.styled('div', {
1288
- display: 'flex'
1289
- });
1290
- function HeaderButtons(props) {
1291
- const {
1292
- onClickRefresh
1293
- } = props;
1294
- const navigate = reactRouterDom.useNavigate();
1295
- return React__default.createElement(ButtonsContainer, null, React__default.createElement(ui.Tooltip, {
1296
- content: "Refresh"
1297
- }, React__default.createElement(ui.Button, {
1298
- variant: "ghost",
1299
- onClick: onClickRefresh
1300
- }, React__default.createElement(ui.RetryIcon, {
1301
- size: 24
1302
- }))), React__default.createElement(ui.Tooltip, {
1303
- content: "Transactions History"
1304
- }, React__default.createElement(ui.Button, {
1305
- variant: "ghost",
1306
- onClick: () => navigate(navigationRoutes.swaps)
1307
- }, React__default.createElement(ui.HistoryIcon, {
1308
- size: 24
1309
- }))), React__default.createElement(ui.Tooltip, {
1310
- content: "Settings"
1311
- }, React__default.createElement(ui.Button, {
1312
- variant: "ghost",
1313
- onClick: () => navigate(navigationRoutes.settings)
1314
- }, React__default.createElement(ui.SettingsIcon, {
1315
- size: 24
1316
- }))));
1317
- }
1318
-
1319
- const HeaderContainer = /*#__PURE__*/ui.styled('div', {
1320
- display: 'flex',
1321
- justifyContent: 'space-between',
1322
- alignItems: 'center',
1323
- width: '100%',
1324
- padding: '$16 0'
1325
- });
1326
- function Header(props) {
1327
- const {
1328
- onClickRefresh,
1329
- title,
1330
- titleSize,
1331
- titleWeight
1332
- } = props;
1333
- const {
1334
- t
1335
- } = reactI18next.useTranslation();
1336
- const titleStyle = ui.css({
1337
- fontSize: `${titleSize}px !important`,
1338
- fontWeight: `${titleWeight} !important`
1339
- });
1340
- return React__default.createElement(HeaderContainer, null, React__default.createElement(ui.Typography, {
1341
- variant: "h4",
1342
- className: titleStyle()
1343
- }, title ? t(title.toLocaleLowerCase()) : ''), React__default.createElement(HeaderButtons, {
1344
- onClickRefresh: onClickRefresh
1345
- }));
1346
- }
1347
-
1348
1326
  const Box = /*#__PURE__*/ui.styled('div', {
1349
1327
  display: 'flex',
1350
1328
  flexDirection: 'column',
@@ -1632,6 +1610,39 @@ const errorMessages = {
1632
1610
  genericServerError: 'Error connecting server, please reload the app and try again'
1633
1611
  };
1634
1612
 
1613
+ const ButtonsContainer = /*#__PURE__*/ui.styled('div', {
1614
+ display: 'flex'
1615
+ });
1616
+ function HeaderButtons(props) {
1617
+ const {
1618
+ onClickRefresh
1619
+ } = props;
1620
+ const navigate = reactRouterDom.useNavigate();
1621
+ return React__default.createElement(ButtonsContainer, null, React__default.createElement(ui.Tooltip, {
1622
+ content: "Refresh"
1623
+ }, React__default.createElement(ui.Button, {
1624
+ variant: "ghost",
1625
+ onClick: onClickRefresh,
1626
+ disabled: !onClickRefresh
1627
+ }, React__default.createElement(ui.RetryIcon, {
1628
+ size: 24
1629
+ }))), React__default.createElement(ui.Tooltip, {
1630
+ content: "Transactions History"
1631
+ }, React__default.createElement(ui.Button, {
1632
+ variant: "ghost",
1633
+ onClick: () => navigate(navigationRoutes.swaps)
1634
+ }, React__default.createElement(ui.HistoryIcon, {
1635
+ size: 24
1636
+ }))), React__default.createElement(ui.Tooltip, {
1637
+ content: "Settings"
1638
+ }, React__default.createElement(ui.Button, {
1639
+ variant: "ghost",
1640
+ onClick: () => navigate(navigationRoutes.settings)
1641
+ }, React__default.createElement(ui.SettingsIcon, {
1642
+ size: 24
1643
+ }))));
1644
+ }
1645
+
1635
1646
  const Container$2 = /*#__PURE__*/ui.styled('div', {
1636
1647
  display: 'flex',
1637
1648
  flexDirection: 'column'
@@ -1656,9 +1667,7 @@ const Alerts = /*#__PURE__*/ui.styled('div', {
1656
1667
  });
1657
1668
  function Home(props) {
1658
1669
  const {
1659
- title = 'SWAP',
1660
- titleSize = 18,
1661
- titleWeight = 600
1670
+ title = 'SWAP'
1662
1671
  } = props;
1663
1672
  const isRouterInContext = reactRouterDom.useInRouterContext();
1664
1673
  const navigate = reactRouterDom.useNavigate();
@@ -1682,6 +1691,7 @@ function Home(props) {
1682
1691
  const bestRouteError = useBestRouteStore.use.error();
1683
1692
  const loadingMetaStatus = useMetaStore.use.loadingStatus();
1684
1693
  const accounts = useWalletsStore.use.accounts();
1694
+ const setCurrentPage = useUiStore.use.setCurrentPage();
1685
1695
  const swithFromAndTo = () => {
1686
1696
  setFromChain(toChain);
1687
1697
  setFromToken(toToken);
@@ -1705,11 +1715,15 @@ function Home(props) {
1705
1715
  const swapButtonState = getSwapButtonState(loadingMetaStatus, accounts, fetchingBestRoute, bestRoute, hasLimitError(bestRoute), highValueLoss, priceImpactCanNotBeComputed, needsToWarnEthOnPath, inputIsZero);
1706
1716
  const totalFeeInUsd = getTotalFeeInUsd(bestRoute, tokens);
1707
1717
  const highFee = hasHighFee(totalFeeInUsd);
1708
- return React__default.createElement(Container$2, null, React__default.createElement(Header, {
1718
+ React.useEffect(() => {
1719
+ setCurrentPage(navigationRoutes.home);
1720
+ return setCurrentPage.bind(null, '');
1721
+ }, []);
1722
+ return React__default.createElement(Container$2, null, React__default.createElement(ui.Header, {
1709
1723
  title: title,
1710
- titleSize: titleSize,
1711
- titleWeight: titleWeight,
1712
- onClickRefresh: fetchBestRoute
1724
+ suffix: React__default.createElement(HeaderButtons, {
1725
+ onClickRefresh: !!bestRoute ? fetchBestRoute : undefined
1726
+ })
1713
1727
  }), React__default.createElement(FromContainer, null, React__default.createElement(TokenInfo, {
1714
1728
  type: "From",
1715
1729
  chain: fromChain,
@@ -1720,7 +1734,7 @@ function Home(props) {
1720
1734
  variant: "ghost",
1721
1735
  onClick: swithFromAndTo
1722
1736
  }, React__default.createElement(ui.VerticalSwapIcon, {
1723
- size: 24
1737
+ size: 32
1724
1738
  }), isRouterInContext && React__default.createElement(SwithFromAndTo, {
1725
1739
  count: count
1726
1740
  })))), React__default.createElement(TokenInfo, {
@@ -1915,7 +1929,7 @@ function TokenPreview(props) {
1915
1929
  }, React__default.createElement(ui.Typography, {
1916
1930
  variant: "body2",
1917
1931
  color: "neutrals800"
1918
- }, props.label), React__default.createElement(ui.Typography, {
1932
+ }, props.label), props.usdValue && React__default.createElement(ui.Typography, {
1919
1933
  variant: "caption",
1920
1934
  color: "neutrals600"
1921
1935
  }, `$${numberToString(props.usdValue)}`)), React__default.createElement("div", {
@@ -2285,6 +2299,7 @@ function ConfirmSwapPage() {
2285
2299
  } = useNavigateBack();
2286
2300
  const bestRoute = useBestRouteStore.use.bestRoute();
2287
2301
  const fetchingBestRoute = useBestRouteStore.use.loading();
2302
+ const fetchingBestRouteError = useBestRouteStore.use.error();
2288
2303
  const setSelectedSwap = useUiStore.use.setSelectedSwap();
2289
2304
  const {
2290
2305
  blockchains,
@@ -2296,6 +2311,7 @@ function ConfirmSwapPage() {
2296
2311
  const setSelectedWallet = useWalletsStore.use.setSelectedWallet();
2297
2312
  const slippage = useSettingsStore.use.slippage();
2298
2313
  const customSlippage = useSettingsStore.use.customSlippage();
2314
+ const bestRouteloadingStatus = getBestRouteStatus(fetchingBestRoute, !!fetchingBestRouteError);
2299
2315
  const {
2300
2316
  manager
2301
2317
  } = queueManagerReact.useManager();
@@ -2360,7 +2376,7 @@ function ConfirmSwapPage() {
2360
2376
  usdValue: calcOutputUsdValue(fromAmount, firstStep?.from.usdPrice),
2361
2377
  amount: fromAmount,
2362
2378
  label: i18n.t('From'),
2363
- loadingStatus: 'success'
2379
+ loadingStatus: bestRouteloadingStatus
2364
2380
  }), React__default.createElement(ui.Spacer, {
2365
2381
  size: 12,
2366
2382
  direction: "vertical"
@@ -2376,7 +2392,7 @@ function ConfirmSwapPage() {
2376
2392
  usdValue: calcOutputUsdValue(toAmount, lastStep?.to.usdPrice),
2377
2393
  amount: toAmount,
2378
2394
  label: i18n.t('To'),
2379
- loadingStatus: 'success'
2395
+ loadingStatus: bestRouteloadingStatus
2380
2396
  })),
2381
2397
  previewRoutes: React__default.createElement(RoutesOverview, {
2382
2398
  routes: bestRoute,
@@ -2406,6 +2422,31 @@ const getPendingSwaps = manager => {
2406
2422
  return result.sort((a, b) => Number(b.swap.creationTime) - Number(a.swap.creationTime));
2407
2423
  };
2408
2424
 
2425
+ const groupSwapsByDate = swaps => {
2426
+ const output = new Map([['today', {
2427
+ title: 'Today',
2428
+ swaps: []
2429
+ }], ['week', {
2430
+ title: 'This week',
2431
+ swaps: []
2432
+ }], ['month', {
2433
+ title: 'This month',
2434
+ swaps: []
2435
+ }], ['year', {
2436
+ title: 'This year',
2437
+ swaps: []
2438
+ }], ['history', {
2439
+ title: 'History',
2440
+ swaps: []
2441
+ }]]);
2442
+ const now = dayjs();
2443
+ swaps.forEach(swap => {
2444
+ const swapDate = dayjs(Number(swap.creationTime));
2445
+ if (now.isSame(swapDate, 'day')) output.get('today')?.swaps.push(swap);else if (now.isSame(swapDate, 'week')) output.get('week')?.swaps.push(swap);else if (now.isSame(swapDate, 'month')) output.get('month')?.swaps.push(swap);else if (now.isSame(swapDate, 'year')) output.get('year')?.swaps.push(swap);else output.get('history')?.swaps.push(swap);
2446
+ });
2447
+ return Array.from(output.values());
2448
+ };
2449
+
2409
2450
  function HistoryPage() {
2410
2451
  const setSelectedSwap = useUiStore.use.setSelectedSwap();
2411
2452
  const navigate = reactRouterDom.useNavigate();
@@ -2421,16 +2462,14 @@ function HistoryPage() {
2421
2462
  } = _ref;
2422
2463
  return swap;
2423
2464
  });
2424
- return React__default.createElement(ui.History
2425
- //todo: move PendingSwap type to rango-types
2426
- //@ts-ignore
2427
- , {
2428
- //todo: move PendingSwap type to rango-types
2429
- //@ts-ignore
2465
+ return React__default.createElement(ui.History, {
2430
2466
  list: pendingSwaps,
2467
+ groupBy: groupSwapsByDate,
2431
2468
  onSwapClick: requestId => {
2432
2469
  setSelectedSwap(requestId);
2433
- navigate(navigationRoutes.swaps + `/${requestId}`);
2470
+ navigate(navigationRoutes.swaps + `/${requestId}`, {
2471
+ replace: true
2472
+ });
2434
2473
  },
2435
2474
  onBack: navigateBackFrom.bind(null, navigationRoutes.swaps)
2436
2475
  });
@@ -2441,6 +2480,7 @@ function LiquiditySourcePage(_ref) {
2441
2480
  supportedSwappers
2442
2481
  } = _ref;
2443
2482
  const swappers = useMetaStore.use.meta().swappers;
2483
+ const loadingMetaStatus = useMetaStore.use.loadingStatus();
2444
2484
  const toggleLiquiditySource = useSettingsStore.use.toggleLiquiditySource();
2445
2485
  const disabledLiquiditySources = useSettingsStore.use.disabledLiquiditySources();
2446
2486
  const toggleAllLiquiditySources = useSettingsStore.use.toggleAllLiquiditySources();
@@ -2466,7 +2506,8 @@ function LiquiditySourcePage(_ref) {
2466
2506
  toggleAll: toggleAllLiquiditySources,
2467
2507
  list: supportedSwappers !== 'all' ? uniqueSwappersGroups.filter(item => supportedSwappers.filter(s => s.title === item.title && s.type === item.type).length > 0) : uniqueSwappersGroups,
2468
2508
  onChange: liquiditySource => toggleLiquiditySource(liquiditySource.title),
2469
- onBack: navigateBackFrom.bind(null, navigationRoutes.liquiditySources)
2509
+ onBack: navigateBackFrom.bind(null, navigationRoutes.liquiditySources),
2510
+ loadingStatus: loadingMetaStatus
2470
2511
  });
2471
2512
  }
2472
2513
 
@@ -2513,6 +2554,7 @@ function SelectTokenPage(props) {
2513
2554
  const toToken = useBestRouteStore.use.toToken();
2514
2555
  const setFromToken = useBestRouteStore.use.setFromToken();
2515
2556
  const setToToken = useBestRouteStore.use.setToToken();
2557
+ const loadingMetaStatus = useMetaStore.use.loadingStatus();
2516
2558
  return React__default.createElement(ui.TokenSelector, {
2517
2559
  type: type === 'from' ? 'Source' : 'Destination',
2518
2560
  list: type == 'from' ? supportedSourceTokens : supportedDestinationTokens,
@@ -2521,7 +2563,8 @@ function SelectTokenPage(props) {
2521
2563
  if (type === 'from') setFromToken(token);else setToToken(token);
2522
2564
  navigateBackFrom(navigationRoutes.fromToken);
2523
2565
  },
2524
- onBack: navigateBackFrom.bind(null, navigationRoutes.fromToken)
2566
+ onBack: navigateBackFrom.bind(null, navigationRoutes.fromToken),
2567
+ loadingStatus: loadingMetaStatus
2525
2568
  });
2526
2569
  }
2527
2570
 
@@ -2543,6 +2586,7 @@ function SettingsPage(_ref) {
2543
2586
  } = useNavigateBack();
2544
2587
  const infiniteApprove = useSettingsStore.use.infiniteApprove();
2545
2588
  const toggleInfiniteApprove = useSettingsStore.use.toggleInfiniteApprove();
2589
+ const loadingMetaStatus = useMetaStore.use.loadingStatus();
2546
2590
  const uniqueSwappersGroups = [];
2547
2591
  removeDuplicateFrom(swappers.map(s => s.swapperGroup)).map(swapperGroup => {
2548
2592
  return swappers.find(s => s.swapperGroup === swapperGroup);
@@ -2575,7 +2619,8 @@ function SettingsPage(_ref) {
2575
2619
  selectedTheme: theme,
2576
2620
  onThemeChange: setTheme,
2577
2621
  infiniteApprove: infiniteApprove,
2578
- toggleInfiniteApprove: toggleInfiniteApprove
2622
+ toggleInfiniteApprove: toggleInfiniteApprove,
2623
+ loadingStatus: loadingMetaStatus
2579
2624
  });
2580
2625
  }
2581
2626
 
@@ -2583,9 +2628,16 @@ const ListContainer = /*#__PURE__*/ui.styled('div', {
2583
2628
  display: 'grid',
2584
2629
  gap: '.5rem',
2585
2630
  gridTemplateColumns: ' repeat(2, minmax(0, 1fr))',
2586
- height: '450px',
2587
2631
  alignContent: 'baseline',
2588
- padding: '0.5rem'
2632
+ padding: '0.5rem',
2633
+ overflowY: 'auto'
2634
+ });
2635
+ const LoaderContainer = /*#__PURE__*/ui.styled('div', {
2636
+ display: 'flex',
2637
+ justifyContent: 'center',
2638
+ width: '100%',
2639
+ position: 'absolute',
2640
+ top: '50%'
2589
2641
  });
2590
2642
  const AlertContainer = /*#__PURE__*/ui.styled('div', {
2591
2643
  paddingBottom: '$16'
@@ -2610,6 +2662,7 @@ function WalletsPage(_ref) {
2610
2662
  sortedWallets = sortWalletsBasedOnState(sortedWallets);
2611
2663
  const [walletErrorMessage, setWalletErrorMessage] = React.useState('');
2612
2664
  const toggleConnectWalletsButton = useUiStore.use.toggleConnectWalletsButton();
2665
+ const loadingMetaStatus = useMetaStore.use.loadingStatus();
2613
2666
  const {
2614
2667
  t
2615
2668
  } = reactI18next.useTranslation();
@@ -2651,7 +2704,11 @@ function WalletsPage(_ref) {
2651
2704
  onBack: navigateBackFrom.bind(null, navigationRoutes.wallets)
2652
2705
  }, React__default.createElement(React__default.Fragment, null, walletErrorMessage && React__default.createElement(AlertContainer, null, React__default.createElement(ui.Alert, {
2653
2706
  type: "error"
2654
- }, walletErrorMessage)), React__default.createElement(ListContainer, null, sortedWallets.map((wallet, index) => React__default.createElement(ui.Wallet, Object.assign({}, wallet, {
2707
+ }, walletErrorMessage)), loadingMetaStatus === 'loading' && React__default.createElement(LoaderContainer, {
2708
+ className: "loader"
2709
+ }, React__default.createElement(ui.Spinner, {
2710
+ size: 24
2711
+ })), loadingMetaStatus === 'failed' && React__default.createElement(ui.LoadingFailedAlert, null), React__default.createElement(ListContainer, null, loadingMetaStatus === 'success' && sortedWallets.map((wallet, index) => React__default.createElement(ui.Wallet, Object.assign({}, wallet, {
2655
2712
  key: `${index}-${wallet.type}`,
2656
2713
  onClick: onSelectWallet
2657
2714
  }))))));
@@ -2714,6 +2771,27 @@ function getSwapDate(pendingSwap) {
2714
2771
  return pendingSwap.finishTime ? `Finished ${timeSince(parseInt(pendingSwap.finishTime))} ago @ ${new Date(parseInt(pendingSwap.finishTime)).toLocaleString()}` : `Started ${timeSince(parseInt(pendingSwap.creationTime))} ago @ ${new Date(parseInt(pendingSwap.creationTime)).toLocaleString()}`;
2715
2772
  }
2716
2773
 
2774
+ const PlaceholderContainer = /*#__PURE__*/ui.styled('div', {
2775
+ height: '450px'
2776
+ });
2777
+ function SwapDetailsPlaceholder(props) {
2778
+ const {
2779
+ requestId,
2780
+ loading,
2781
+ onBack
2782
+ } = props;
2783
+ return React__default.createElement(ui.SecondaryPage, {
2784
+ title: "Swap Details",
2785
+ textField: false,
2786
+ onBack: onBack
2787
+ }, React__default.createElement(PlaceholderContainer, null, loading ? React__default.createElement(LoaderContainer, null, React__default.createElement(ui.Spinner, {
2788
+ size: 24
2789
+ })) : React__default.createElement(ui.Alert, {
2790
+ type: "secondary",
2791
+ title: `Swap with request ID = ${requestId} not found.`
2792
+ })));
2793
+ }
2794
+
2717
2795
  function SwapDetailsPage() {
2718
2796
  const selectedSwapRequestId = useUiStore.use.selectedSwapRequestId();
2719
2797
  const {
@@ -2729,6 +2807,12 @@ function SwapDetailsPage() {
2729
2807
  const {
2730
2808
  manager
2731
2809
  } = queueManagerReact.useManager();
2810
+ const [loading, setLoading] = React.useState(true);
2811
+ React.useEffect(() => {
2812
+ setTimeout(() => {
2813
+ setLoading(false);
2814
+ }, 5000);
2815
+ }, []);
2732
2816
  const pendingSwaps = getPendingSwaps(manager);
2733
2817
  const selectedSwap = pendingSwaps.find(_ref => {
2734
2818
  let {
@@ -2741,7 +2825,15 @@ function SwapDetailsPage() {
2741
2825
  if (swap) queueManagerRangoPreset.cancelSwap(swap);
2742
2826
  };
2743
2827
  const swap = selectedSwap?.swap;
2744
- if (!swap) return null;
2828
+ if (!swap) return React__default.createElement(SwapDetailsPlaceholder, {
2829
+ requestId: selectedSwapRequestId || '',
2830
+ loading: loading,
2831
+ onBack: navigateBackFrom.bind(null, navigationRoutes.swapDetails)
2832
+ });
2833
+ const firstStep = swap.steps[0];
2834
+ const lastStep = swap.steps[swap.steps.length - 1];
2835
+ const fromAmount = numberToString(swap.inputAmount);
2836
+ const toAmount = numberToString(swap.simulationResult.outputAmount);
2745
2837
  const currentStep = queueManagerRangoPreset.getCurrentStep(swap);
2746
2838
  const currentStepBlockchain = currentStep ? queueManagerRangoPreset.getCurrentBlockchainOfOrNull(swap, currentStep) : null;
2747
2839
  const currentStepWallet = currentStep ? queueManagerRangoPreset.getRelatedWalletOrNull(swap, currentStep) : null;
@@ -2754,6 +2846,36 @@ function SwapDetailsPage() {
2754
2846
  const lastConvertedTokenInFailedSwap = getLastConvertedTokenInFailedSwap(swap);
2755
2847
  return React__default.createElement(ui.SwapHistory, Object.assign({
2756
2848
  onBack: navigateBackFrom.bind(null, navigationRoutes.swapDetails),
2849
+ previewInputs: React__default.createElement(React__default.Fragment, null, React__default.createElement(TokenPreview, {
2850
+ chain: {
2851
+ displayName: firstStep?.fromBlockchain || '',
2852
+ // @ts-ignore
2853
+ logo: firstStep?.fromBlockchainLogo || ''
2854
+ },
2855
+ token: {
2856
+ symbol: firstStep?.fromSymbol || '',
2857
+ image: firstStep?.fromLogo || ''
2858
+ },
2859
+ amount: fromAmount,
2860
+ label: i18n.t('From'),
2861
+ loadingStatus: 'success'
2862
+ }), React__default.createElement(ui.Spacer, {
2863
+ size: 12,
2864
+ direction: "vertical"
2865
+ }), React__default.createElement(TokenPreview, {
2866
+ chain: {
2867
+ displayName: lastStep?.toBlockchain || '',
2868
+ // @ts-ignore
2869
+ logo: lastStep?.toBlockchainLogo || ''
2870
+ },
2871
+ token: {
2872
+ symbol: lastStep?.toSymbol || '',
2873
+ image: lastStep?.toLogo || ''
2874
+ },
2875
+ amount: toAmount,
2876
+ label: i18n.t('To'),
2877
+ loadingStatus: 'success'
2878
+ })),
2757
2879
  //todo: move PendingSwap type to rango-types
2758
2880
  //@ts-ignore
2759
2881
  pendingSwap: swap,
@@ -2776,79 +2898,83 @@ function SwapDetailsPage() {
2776
2898
  }, lastConvertedTokenInFailedSwap && {
2777
2899
  lastConvertedTokenInFailedSwap: {
2778
2900
  blockchain: lastConvertedTokenInFailedSwap.blockchain,
2779
- outputAmount: lastConvertedTokenInFailedSwap.outputAmount,
2901
+ outputAmount: lastConvertedTokenInFailedSwap.outputAmount || '',
2780
2902
  symbol: lastConvertedTokenInFailedSwap.symbol
2781
2903
  }
2782
2904
  }));
2783
2905
  }
2784
2906
 
2907
+ const getAbsolutePath = path => path.replace('/', '');
2785
2908
  function AppRoutes(props) {
2786
2909
  const {
2787
2910
  configs
2788
2911
  } = props;
2789
2912
  return reactRouterDom.useRoutes([{
2790
- path: navigationRoutes.home,
2913
+ path: getAbsolutePath(navigationRoutes.home),
2791
2914
  element: React__default.createElement(Home, {
2792
2915
  title: configs?.title,
2793
2916
  titleSize: configs?.titleSize,
2794
2917
  titleWeight: configs?.titleWeight
2795
2918
  })
2796
2919
  }, {
2797
- path: navigationRoutes.fromChain,
2920
+ path: getAbsolutePath(navigationRoutes.fromChain),
2798
2921
  element: React__default.createElement(SelectChainPage, {
2799
2922
  type: "from",
2800
2923
  supportedChains: configs?.fromChains || 'all'
2801
2924
  })
2802
2925
  }, {
2803
- path: navigationRoutes.toChain,
2926
+ path: getAbsolutePath(navigationRoutes.toChain),
2804
2927
  element: React__default.createElement(SelectChainPage, {
2805
2928
  type: "to",
2806
2929
  supportedChains: configs?.toChains || 'all'
2807
2930
  })
2808
2931
  }, {
2809
- path: navigationRoutes.fromToken + '/*',
2932
+ path: getAbsolutePath(navigationRoutes.fromToken),
2810
2933
  element: React__default.createElement(SelectTokenPage, {
2811
2934
  type: "from",
2812
2935
  supportedTokens: configs?.fromTokens || 'all'
2813
2936
  })
2814
2937
  }, {
2815
- path: navigationRoutes.toToken,
2938
+ path: getAbsolutePath(navigationRoutes.toToken),
2816
2939
  element: React__default.createElement(SelectTokenPage, {
2817
2940
  type: "to",
2818
2941
  supportedTokens: configs?.toTokens || 'all'
2819
2942
  })
2820
2943
  }, {
2821
- path: navigationRoutes.settings,
2944
+ path: getAbsolutePath(navigationRoutes.settings),
2822
2945
  element: React__default.createElement(SettingsPage, {
2823
2946
  supportedSwappers: configs?.liquiditySources || 'all'
2824
2947
  })
2825
2948
  }, {
2826
- path: navigationRoutes.liquiditySources,
2949
+ path: getAbsolutePath(navigationRoutes.liquiditySources),
2827
2950
  element: React__default.createElement(LiquiditySourcePage, {
2828
2951
  supportedSwappers: configs?.liquiditySources || 'all'
2829
2952
  })
2830
2953
  }, {
2831
- path: navigationRoutes.swaps,
2954
+ path: getAbsolutePath(navigationRoutes.swaps),
2832
2955
  element: React__default.createElement(HistoryPage, null)
2833
2956
  }, {
2834
2957
  path: navigationRoutes.swapDetails,
2835
2958
  element: React__default.createElement(SwapDetailsPage, null)
2836
2959
  }, {
2837
- path: navigationRoutes.wallets,
2960
+ path: getAbsolutePath(navigationRoutes.wallets),
2838
2961
  element: React__default.createElement(WalletsPage, {
2839
2962
  supportedWallets: configs?.wallets || 'all',
2840
2963
  multiWallets: typeof configs?.multiWallets === 'undefined' ? true : configs.multiWallets
2841
2964
  })
2842
2965
  }, {
2843
- path: navigationRoutes.confirmSwap,
2966
+ path: getAbsolutePath(navigationRoutes.confirmSwap),
2844
2967
  element: React__default.createElement(ConfirmSwapPage, null)
2845
2968
  }]);
2846
2969
  }
2847
2970
 
2848
- const Header$1 = /*#__PURE__*/ui.styled('div', {
2971
+ const Header = /*#__PURE__*/ui.styled('div', {
2849
2972
  display: 'flex',
2850
2973
  width: '100%',
2851
- justifyContent: 'end'
2974
+ justifyContent: 'end',
2975
+ '.balance': {
2976
+ display: 'flex'
2977
+ }
2852
2978
  });
2853
2979
  const WalletImage = /*#__PURE__*/ui.styled('img', {
2854
2980
  width: '$24',
@@ -2878,6 +3004,8 @@ function Layout(_ref) {
2878
3004
  const setInputAmount = useBestRouteStore.use.setInputAmount();
2879
3005
  const totalBalance = calculateWalletUsdValue(balances);
2880
3006
  const connectWalletsButtonDisabled = useUiStore.use.connectWalletsButtonDisabled();
3007
+ const loadingMetaStatus = useMetaStore.use.loadingStatus();
3008
+ const fetchingBalance = useWalletsStore(fetchingBalanceSelector);
2881
3009
  const {
2882
3010
  t
2883
3011
  } = reactI18next.useTranslation();
@@ -2898,22 +3026,26 @@ function Layout(_ref) {
2898
3026
  setFromToken(null);
2899
3027
  setToToken(null);
2900
3028
  }, [configs?.fromChains, configs?.toChains, configs?.fromTokens, configs?.toTokens]);
2901
- return React__default.createElement(React__default.Fragment, null, React__default.createElement(Header$1, null, React__default.createElement(ui.Button, {
3029
+ return React__default.createElement(React__default.Fragment, null, React__default.createElement(Header, null, React__default.createElement(ui.Button, {
2902
3030
  size: "small",
2903
3031
  suffix: React__default.createElement(ui.AddWalletIcon, {
2904
3032
  size: 20
2905
3033
  }),
2906
3034
  variant: "ghost",
2907
3035
  flexContent: true,
3036
+ loading: loadingMetaStatus === 'loading',
3037
+ disabled: loadingMetaStatus === 'failed',
2908
3038
  onClick: () => {
2909
3039
  if (!connectWalletsButtonDisabled) navigate(navigationRoutes.wallets);
2910
3040
  }
2911
3041
  }, connectedWalletsImages?.length ? connectedWalletsImages.map((walletImage, index) => React__default.createElement(WalletImage, {
2912
3042
  key: index,
2913
3043
  src: walletImage
2914
- })) : React__default.createElement(React__default.Fragment, null), React__default.createElement(ui.Typography, {
3044
+ })) : React__default.createElement(React__default.Fragment, null), React__default.createElement("div", {
3045
+ className: "balance"
3046
+ }, React__default.createElement(ui.Typography, {
2915
3047
  variant: "body2"
2916
- }, !accounts?.length ? t('Connect Wallet') : `$${totalBalance || 0}`))), React__default.createElement(AppRoutes, {
3048
+ }, !accounts?.length ? t('Connect Wallet') : `$${totalBalance || 0}`), fetchingBalance && React__default.createElement(ui.Spinner, null)))), React__default.createElement(AppRoutes, {
2917
3049
  configs: configs
2918
3050
  }));
2919
3051
  }
@@ -2921,10 +3053,12 @@ function Layout(_ref) {
2921
3053
  const globalStyles = /*#__PURE__*/ui.globalCss({
2922
3054
  '*': {
2923
3055
  '&::-webkit-scrollbar': {
2924
- width: '$8'
3056
+ width: '$8',
3057
+ height: '$8'
2925
3058
  },
2926
3059
  '&::-webkit-scrollbar-thumb': {
2927
- backgroundColor: '$neutrals400'
3060
+ backgroundColor: '$neutrals400',
3061
+ borderRadius: '$10'
2928
3062
  },
2929
3063
  '&::-webkit-scrollbar-thumb:hover': {
2930
3064
  backgroundColor: '$neutrals500'