@rango-dev/widget-embedded 0.47.1-next.4 → 0.48.1-next.0

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 (59) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/dist/containers/Inputs/Inputs.d.ts.map +1 -1
  3. package/dist/containers/Refuel/Refuel.d.ts +5 -0
  4. package/dist/containers/Refuel/Refuel.d.ts.map +1 -0
  5. package/dist/containers/Refuel/Refuel.types.d.ts +5 -0
  6. package/dist/containers/Refuel/Refuel.types.d.ts.map +1 -0
  7. package/dist/containers/Refuel/index.d.ts +2 -0
  8. package/dist/containers/Refuel/index.d.ts.map +1 -0
  9. package/dist/containers/WidgetProvider/WidgetProvider.d.ts.map +1 -1
  10. package/dist/hooks/useBootstrap/useBootstrap.d.ts.map +1 -1
  11. package/dist/hooks/useConfirmSwap/useConfirmSwap.d.ts.map +1 -1
  12. package/dist/hooks/useSwapMode.d.ts +11 -0
  13. package/dist/hooks/useSwapMode.d.ts.map +1 -0
  14. package/dist/index.d.ts +3 -1
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +2 -2
  17. package/dist/index.js.map +4 -4
  18. package/dist/pages/HistoryPage.d.ts.map +1 -1
  19. package/dist/pages/Home.d.ts.map +1 -1
  20. package/dist/pages/SelectBlockchainPage.d.ts.map +1 -1
  21. package/dist/store/quote.d.ts +119 -4
  22. package/dist/store/quote.d.ts.map +1 -1
  23. package/dist/store/slices/data.d.ts +1 -0
  24. package/dist/store/slices/data.d.ts.map +1 -1
  25. package/dist/widget-embedded.build.json +1 -1
  26. package/package.json +8 -8
  27. package/src/components/BlockchainsSection/BlockchainsSection.tsx +2 -2
  28. package/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx +1 -1
  29. package/src/components/CustomDestination/CustomDestination.tsx +1 -1
  30. package/src/components/Quotes/Quotes.tsx +1 -1
  31. package/src/components/Quotes/SelectStrategy.tsx +1 -1
  32. package/src/components/SameTokensWarning/SameTokensWarning.tsx +1 -1
  33. package/src/components/SwapDetails/SwapDetails.tsx +1 -1
  34. package/src/components/SwitchFromAndTo/SwitchFromAndTo.tsx +1 -1
  35. package/src/components/TokenList/TokenList.tsx +1 -1
  36. package/src/containers/Inputs/Inputs.tsx +5 -2
  37. package/src/containers/QuoteInfo/QuoteInfo.tsx +1 -1
  38. package/src/containers/Refuel/Refuel.tsx +25 -0
  39. package/src/containers/Refuel/Refuel.types.ts +5 -0
  40. package/src/containers/Refuel/index.ts +1 -0
  41. package/src/containers/WidgetInfo/WidgetInfo.tsx +2 -2
  42. package/src/containers/WidgetProvider/WidgetProvider.tsx +6 -0
  43. package/src/hooks/useBootstrap/useBootstrap.ts +6 -7
  44. package/src/hooks/useConfirmSwap/useConfirmSwap.ts +12 -9
  45. package/src/hooks/useSwapInput.ts +1 -1
  46. package/src/hooks/useSwapMode.ts +20 -0
  47. package/src/hooks/useSyncStoresWithConfig.ts +1 -1
  48. package/src/hooks/useSyncUrlAndStore/useSyncUrlAndStore.ts +1 -1
  49. package/src/hooks/useUpdateQuoteInputs/useUpdateQuoteInputs.ts +1 -1
  50. package/src/index.ts +4 -0
  51. package/src/pages/ConfirmSwapPage.tsx +1 -1
  52. package/src/pages/CustomTokensPage.tsx +1 -1
  53. package/src/pages/HistoryPage.tsx +51 -4
  54. package/src/pages/Home.tsx +19 -9
  55. package/src/pages/Routes.tsx +1 -1
  56. package/src/pages/SelectBlockchainPage.tsx +29 -15
  57. package/src/pages/SelectSwapItemPage/SelectSwapItemsPage.tsx +1 -1
  58. package/src/store/quote.ts +282 -253
  59. package/src/store/slices/data.ts +9 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rango-dev/widget-embedded",
3
- "version": "0.47.1-next.4",
3
+ "version": "0.48.1-next.0",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "source": "./src/index.ts",
@@ -25,15 +25,15 @@
25
25
  "@lingui/core": "4.2.1",
26
26
  "@lingui/react": "4.2.1",
27
27
  "@rango-dev/logging-core": "^0.11.0",
28
- "@rango-dev/provider-all": "^0.50.1-next.2",
28
+ "@rango-dev/provider-all": "^0.51.0",
29
29
  "@rango-dev/queue-manager-core": "^0.32.0",
30
- "@rango-dev/queue-manager-rango-preset": "^0.49.1-next.2",
30
+ "@rango-dev/queue-manager-rango-preset": "^0.50.1-next.0",
31
31
  "@rango-dev/queue-manager-react": "^0.32.0",
32
- "@rango-dev/signer-solana": "^0.43.1-next.0",
33
- "@rango-dev/ui": "^0.50.1-next.3",
34
- "@rango-dev/wallets-core": "^0.47.1-next.1",
35
- "@rango-dev/wallets-react": "^0.34.1-next.2",
36
- "@rango-dev/wallets-shared": "^0.48.1-next.2",
32
+ "@rango-dev/signer-solana": "^0.44.0",
33
+ "@rango-dev/ui": "^0.51.1-next.0",
34
+ "@rango-dev/wallets-core": "^0.48.0",
35
+ "@rango-dev/wallets-react": "^0.35.0",
36
+ "@rango-dev/wallets-shared": "^0.49.0",
37
37
  "bignumber.js": "^9.1.1",
38
38
  "copy-to-clipboard": "^3.3.3",
39
39
  "dayjs": "^1.11.7",
@@ -37,8 +37,8 @@ export function BlockchainsSection(props: PropTypes) {
37
37
  });
38
38
 
39
39
  const { fetchStatus } = useAppStore();
40
- const resetToBlockchain = useQuoteStore.use.resetToBlockchain();
41
- const resetFromBlockchain = useQuoteStore.use.resetFromBlockchain();
40
+ const resetToBlockchain = useQuoteStore().use.resetToBlockchain();
41
+ const resetFromBlockchain = useQuoteStore().use.resetFromBlockchain();
42
42
  const hasMoreItemsInList = blockchainsList.more.length > 0;
43
43
  /**
44
44
  * When only one item is left on list, we will not show the `More` button and will show the item itself instead.
@@ -51,7 +51,7 @@ export function ConfirmWalletsModal(props: PropTypes) {
51
51
  setQuoteWalletConfirmed: setQuoteWalletConfirmed,
52
52
  customDestination,
53
53
  setCustomDestination,
54
- } = useQuoteStore();
54
+ } = useQuoteStore()();
55
55
  const { config, connectedWallets, setWalletsAsSelected } = useAppStore();
56
56
 
57
57
  const [showMoreWalletFor, setShowMoreWalletFor] = useState('');
@@ -32,7 +32,7 @@ import {
32
32
  export function CustomDestination(props: PropTypes) {
33
33
  const { blockchain, handleOpenChange, open } = props;
34
34
 
35
- const { customDestination, setCustomDestination } = useQuoteStore();
35
+ const { customDestination, setCustomDestination } = useQuoteStore()();
36
36
  const { config } = useAppStore();
37
37
  const blockchains = useAppStore().blockchains();
38
38
  const blockchainName = getBlockchainDisplayNameFor(
@@ -37,7 +37,7 @@ export function Quotes(props: PropTypes) {
37
37
  toToken,
38
38
  sortStrategy,
39
39
  error,
40
- } = useQuoteStore();
40
+ } = useQuoteStore()();
41
41
  const { slippage, customSlippage } = useAppStore();
42
42
  const { findToken } = useAppStore();
43
43
  const container = propContainer || getContainer();
@@ -9,7 +9,7 @@ import { useQuoteStore } from '../../store/quote';
9
9
  import { SelectContainer } from './Quotes.styles';
10
10
 
11
11
  export function SelectStrategy(props: { container: HTMLElement }) {
12
- const { updateQuotePartialState, sortStrategy } = useQuoteStore();
12
+ const { updateQuotePartialState, sortStrategy } = useQuoteStore()();
13
13
 
14
14
  const ROUTE_STRATEGY: { value: PreferenceType; label: string }[] = [
15
15
  {
@@ -8,7 +8,7 @@ import { areTokensEqual } from '../../utils/wallets';
8
8
  import { Container } from './SameTokensWarning.styles';
9
9
 
10
10
  export function SameTokensWarning() {
11
- const { fromToken, toToken } = useQuoteStore();
11
+ const { fromToken, toToken } = useQuoteStore()();
12
12
  const showWarningMessage =
13
13
  !!fromToken && !!toToken && areTokensEqual(fromToken, toToken);
14
14
 
@@ -80,7 +80,7 @@ export function SwapDetails(props: SwapDetailsProps) {
80
80
  const blockchains = useAppStore().blockchains();
81
81
  const swappers = useAppStore().swappers();
82
82
  const { findToken } = useAppStore();
83
- const retry = useQuoteStore.use.retry();
83
+ const retry = useQuoteStore().use.retry();
84
84
  const navigate = useNavigate();
85
85
  const containerRef = useRef<HTMLDivElement | null>(null);
86
86
  const [isModalOpen, setIsModalOpen] = useState(false);
@@ -10,7 +10,7 @@ import {
10
10
  } from './SwitchFromAndTo.styles';
11
11
 
12
12
  export function SwitchFromAndToButton() {
13
- const switchFromAndTo = useQuoteStore.use.switchFromAndTo();
13
+ const switchFromAndTo = useQuoteStore().use.switchFromAndTo();
14
14
 
15
15
  return (
16
16
  <SwitchButtonContainer>
@@ -115,7 +115,7 @@ export function TokenList(props: PropTypes) {
115
115
  const blockchains = useAppStore().blockchains();
116
116
  const { getBalanceFor, fetchingWallets: loadingWallet } = useAppStore();
117
117
  const { isTokenPinned } = useAppStore();
118
- const { setFromToken, setToToken } = useQuoteStore();
118
+ const { setFromToken, setToToken } = useQuoteStore()();
119
119
  const { t } = useTranslation();
120
120
  const navigateBack = useNavigateBack();
121
121
 
@@ -16,6 +16,7 @@ import {
16
16
  USD_VALUE_MAX_DECIMALS,
17
17
  USD_VALUE_MIN_DECIMALS,
18
18
  } from '../../constants/routing';
19
+ import { useSwapMode } from '../../hooks/useSwapMode';
19
20
  import { useAppStore } from '../../store/AppStore';
20
21
  import { useQuoteStore } from '../../store/quote';
21
22
  import { getContainer } from '../../utils/common';
@@ -40,7 +41,8 @@ export function Inputs(props: PropTypes) {
40
41
  outputAmount,
41
42
  outputUsdValue,
42
43
  selectedQuote,
43
- } = useQuoteStore();
44
+ } = useQuoteStore()();
45
+ const { swapMode } = useSwapMode();
44
46
  const { connectedWallets, getBalanceFor } = useAppStore();
45
47
  const fromTokenBalance = fromToken ? getBalanceFor(fromToken) : null;
46
48
  const fromTokenFormattedBalance =
@@ -128,9 +130,10 @@ export function Inputs(props: PropTypes) {
128
130
  }}
129
131
  anyWalletConnected={connectedWallets.length > 0}
130
132
  />
131
- <SwitchFromAndToButton />
133
+ {swapMode === 'swap' && <SwitchFromAndToButton />}
132
134
  </FromContainer>
133
135
  <SwapInput
136
+ selectionType={swapMode === 'swap' ? 'token' : 'chain'}
134
137
  sharpBottomStyle={!isExpandable && (!!selectedQuote || fetchingQuote)}
135
138
  label={i18n.t('To')}
136
139
  mode="To"
@@ -28,7 +28,7 @@ export function QuoteInfo(props: PropTypes) {
28
28
  fullExpandedMode = false,
29
29
  container,
30
30
  } = props;
31
- const { inputAmount, inputUsdValue } = useQuoteStore();
31
+ const { inputAmount, inputUsdValue } = useQuoteStore()();
32
32
 
33
33
  const outputAmount = !!quote?.outputAmount
34
34
  ? new BigNumber(quote?.outputAmount)
@@ -0,0 +1,25 @@
1
+ import type { RefuelProps } from './Refuel.types';
2
+ import type { PropsWithChildren } from 'react';
3
+
4
+ import React from 'react';
5
+
6
+ import { AppRouter } from '../../components/AppRouter';
7
+ import { DEFAULT_CONFIG } from '../../store/slices/config';
8
+ import { Main } from '../App';
9
+ import { WidgetProvider } from '../WidgetProvider';
10
+
11
+ export function Refuel(props: PropsWithChildren<RefuelProps>) {
12
+ const isExternalWalletsEnabled = props.config?.externalWallets;
13
+
14
+ return (
15
+ <AppRouter>
16
+ {isExternalWalletsEnabled ? (
17
+ <Main />
18
+ ) : (
19
+ <WidgetProvider config={props.config ?? DEFAULT_CONFIG}>
20
+ <Main />
21
+ </WidgetProvider>
22
+ )}
23
+ </AppRouter>
24
+ );
25
+ }
@@ -0,0 +1,5 @@
1
+ import type { WidgetConfig } from '../../types';
2
+
3
+ export type RefuelProps = {
4
+ config?: WidgetConfig;
5
+ };
@@ -0,0 +1 @@
1
+ export { Refuel } from './Refuel';
@@ -20,7 +20,7 @@ export const WidgetInfoContext = createContext<
20
20
  export function WidgetInfo(props: React.PropsWithChildren) {
21
21
  const { manager } = useManager();
22
22
  const isActiveTab = useUiStore.use.isActiveTab();
23
- const retrySwap = useQuoteStore.use.retry();
23
+ const retrySwap = useQuoteStore().use.retry();
24
24
  const {
25
25
  findToken,
26
26
  getBalances,
@@ -40,7 +40,7 @@ export function WidgetInfo(props: React.PropsWithChildren) {
40
40
  const clearNotifications = useNotificationStore().clearNotifications;
41
41
  const updateQuoteInputs = useUpdateQuoteInputs();
42
42
  const { fromBlockchain, toBlockchain, fromToken, toToken, inputAmount } =
43
- useQuoteStore();
43
+ useQuoteStore()();
44
44
 
45
45
  // eslint-disable-next-line react/jsx-no-constructed-context-values
46
46
  const value: WidgetInfoContextInterface = {
@@ -5,6 +5,7 @@ import { setSolanaSignerConfig } from '@rango-dev/signer-solana';
5
5
  import React, { useEffect, useMemo } from 'react';
6
6
 
7
7
  import { DEFAULT_BASE_URL, RANGO_PUBLIC_API_KEY } from '../../constants';
8
+ import { useFetchApiConfig } from '../../hooks/useFetchApiConfig';
8
9
  import useFontLoader from '../../hooks/useFontLoader';
9
10
  import QueueManager from '../../QueueManager';
10
11
  import { initConfig } from '../../utils/configs';
@@ -16,8 +17,13 @@ export function WidgetProvider(props: PropsWithChildren<PropTypes>) {
16
17
 
17
18
  const fontFamily = props.config?.theme?.fontFamily;
18
19
 
20
+ const { fetchApiConfig } = useFetchApiConfig();
19
21
  const { handleLoadCustomFont } = useFontLoader();
20
22
 
23
+ useEffect(() => {
24
+ void fetchApiConfig().catch(console.log);
25
+ }, []);
26
+
21
27
  useEffect(() => {
22
28
  if (fontFamily) {
23
29
  handleLoadCustomFont(fontFamily);
@@ -10,9 +10,11 @@ import { WidgetContext } from '../../containers/Wallets';
10
10
  import { globalFont } from '../../globalStyles';
11
11
  import { useAppStore } from '../../store/AppStore';
12
12
  import { useNotificationStore } from '../../store/notification';
13
- import { unsubscribeQuoteStore } from '../../store/quote';
13
+ import {
14
+ unsubscribeRefuelQuoteStore,
15
+ unsubscribeSwapQuoteStore,
16
+ } from '../../store/quote';
14
17
  import { tabManager } from '../../store/ui';
15
- import { useFetchApiConfig } from '../useFetchApiConfig';
16
18
  import { useForceAutoConnect } from '../useForceAutoConnect';
17
19
  import { useSubscribeToWidgetEvents } from '../useSubscribeToWidgetEvents';
18
20
  import { useSyncNotifications } from '../useSyncNotifications';
@@ -31,10 +33,9 @@ export function useBootstrap() {
31
33
 
32
34
  const evmChains = blockchains.filter(isEvmBlockchain);
33
35
 
34
- const { fetchApiConfig } = useFetchApiConfig();
35
-
36
36
  // Unsubscribe QuoteStore listeners
37
- useEffect(() => () => unsubscribeQuoteStore(), []);
37
+ useEffect(() => () => unsubscribeSwapQuoteStore(), []);
38
+ useEffect(() => () => unsubscribeRefuelQuoteStore(), []);
38
39
 
39
40
  // At the moment, we only detect the disconnection of EVM wallets.
40
41
  useQueueManager({
@@ -96,8 +97,6 @@ export function useBootstrap() {
96
97
  );
97
98
  });
98
99
 
99
- void fetchApiConfig().catch(console.log);
100
-
101
100
  return tabManager.destroy;
102
101
  }, []);
103
102
  }
@@ -14,6 +14,7 @@ import {
14
14
  } from '../../types';
15
15
  import { getWalletsForNewSwap } from '../../utils/swap';
16
16
  import { useFetchConfirmQuote } from '../useFetchConfirmQuote';
17
+ import { useSwapMode } from '../useSwapMode';
17
18
 
18
19
  import {
19
20
  generateWarnings,
@@ -31,13 +32,14 @@ export function useConfirmSwap(): ConfirmSwap {
31
32
  selectedQuote: initialQuote,
32
33
  customDestination: customDestinationFromStore,
33
34
  resetAlerts,
34
- } = useQuoteStore();
35
+ } = useQuoteStore()();
35
36
 
36
37
  const { slippage, customSlippage } = useAppStore();
37
38
  const disabledLiquiditySources = useAppStore().getDisabledLiquiditySources();
38
39
  const blockchains = useAppStore().blockchains();
39
40
  const tokens = useAppStore().tokens();
40
41
  const { findToken } = useAppStore();
42
+ const { swapMode } = useSwapMode();
41
43
 
42
44
  const userSlippage = customSlippage || slippage;
43
45
 
@@ -114,14 +116,15 @@ export function useConfirmSwap(): ConfirmSwap {
114
116
 
115
117
  const proceedAnyway = !!confirmSwapWarnings.balance;
116
118
 
117
- const swap = calculatePendingSwap(
118
- inputAmount.toString(),
119
- result,
120
- getWalletsForNewSwap(selectedWallets),
121
- swapSettings,
122
- proceedAnyway ? false : true,
123
- { blockchains, tokens }
124
- );
119
+ const swap = calculatePendingSwap({
120
+ inputAmount: inputAmount.toString(),
121
+ bestRoute: result,
122
+ wallets: getWalletsForNewSwap(selectedWallets),
123
+ settings: swapSettings,
124
+ validateBalanceOrFee: proceedAnyway ? false : true,
125
+ meta: { blockchains, tokens },
126
+ swapMode,
127
+ });
125
128
 
126
129
  return {
127
130
  quote: currentQuote,
@@ -65,7 +65,7 @@ export function useSwapInput({
65
65
  warning,
66
66
  setSelectedQuote,
67
67
  updateQuotePartialState,
68
- } = useQuoteStore();
68
+ } = useQuoteStore()();
69
69
  const {
70
70
  slippage,
71
71
  customSlippage,
@@ -0,0 +1,20 @@
1
+ import { createContext, useContext } from 'react';
2
+
3
+ type SwapModeContextType = {
4
+ swapMode: 'swap' | 'refuel';
5
+ isMultiMode: boolean;
6
+ };
7
+
8
+ export const SwapModeContext = createContext<SwapModeContextType>({
9
+ swapMode: 'swap',
10
+ isMultiMode: false,
11
+ });
12
+
13
+ export function useSwapMode(): {
14
+ swapMode: 'swap' | 'refuel';
15
+ isMultiMode: boolean;
16
+ } {
17
+ const { swapMode, isMultiMode } = useContext(SwapModeContext);
18
+
19
+ return { swapMode: swapMode, isMultiMode: isMultiMode };
20
+ }
@@ -21,7 +21,7 @@ export function useSyncStoresWithConfig() {
21
21
  toToken,
22
22
  fromBlockchain,
23
23
  toBlockchain,
24
- } = useQuoteStore();
24
+ } = useQuoteStore()();
25
25
 
26
26
  const config = useAppStore().config;
27
27
  const fetchMetaStatus = useAppStore().fetchStatus;
@@ -28,7 +28,7 @@ export function useSyncUrlAndStore() {
28
28
  setFromToken,
29
29
  setToToken,
30
30
  setInputAmount,
31
- } = useQuoteStore();
31
+ } = useQuoteStore()();
32
32
  const fetchMetaStatus = useAppStore().fetchStatus;
33
33
  const blockchains = useAppStore().blockchains();
34
34
  const isInRouterContext = useInRouterContext();
@@ -14,7 +14,7 @@ export function useUpdateQuoteInputs() {
14
14
  setToBlockchain,
15
15
  setToToken,
16
16
  setInputAmount,
17
- } = useQuoteStore();
17
+ } = useQuoteStore()();
18
18
 
19
19
  const updateQuoteInputs: UpdateQuoteInputs = (params) => {
20
20
  const { fromBlockchain, fromToken, toBlockchain, toToken, requestAmount } =
package/src/index.ts CHANGED
@@ -69,11 +69,13 @@ import {
69
69
  } from './components/WalletStatefulConnect';
70
70
  import { WIDGET_UI_ID as UI_ID } from './constants';
71
71
  import { SUPPORTED_FONTS } from './constants/fonts';
72
+ import { Refuel } from './containers/Refuel';
72
73
  import { WidgetWallets } from './containers/Wallets';
73
74
  import { Widget } from './containers/Widget';
74
75
  import { useWidget } from './containers/WidgetInfo';
75
76
  import { WidgetProvider } from './containers/WidgetProvider';
76
77
  import { useStatefulConnect } from './hooks/useStatefulConnect';
78
+ import { SwapModeContext } from './hooks/useSwapMode';
77
79
  import { useWalletList } from './hooks/useWalletList';
78
80
  import { useWidgetEvents } from './hooks/useWidgetEvents';
79
81
  import { widgetEventEmitter } from './services/eventEmitter';
@@ -132,6 +134,8 @@ export type {
132
134
  };
133
135
  export {
134
136
  Widget,
137
+ Refuel,
138
+ SwapModeContext,
135
139
  /**
136
140
  * @deprecated Use `WidgetProvider` instead. This component will be removed in future versions.
137
141
  */
@@ -70,7 +70,7 @@ export function ConfirmSwapPage() {
70
70
  quoteWalletsConfirmed,
71
71
  customDestination,
72
72
  quoteWarningsConfirmed,
73
- } = useQuoteStore();
73
+ } = useQuoteStore()();
74
74
  const navigate = useNavigate();
75
75
  const [dbErrorMessage, setDbErrorMessage] = useState<string>('');
76
76
 
@@ -50,7 +50,7 @@ export function CustomTokensPage() {
50
50
  const [searchedFor, setSearchedFor] = useState<string>('');
51
51
  const { deleteCustomToken } = useAppStore();
52
52
  const customTokens = useAppStore().customTokens();
53
- const { fromToken, toToken, setFromToken, setToToken } = useQuoteStore();
53
+ const { fromToken, toToken, setFromToken, setToToken } = useQuoteStore()();
54
54
  const { mode } = useTheme({});
55
55
  const navigate = useNavigate();
56
56
  const [isDeleteModalOpen, setIsDeleteModalOpen] = useState<boolean>(false);
@@ -7,6 +7,7 @@ import {
7
7
  MessageBox,
8
8
  NotFound,
9
9
  styled,
10
+ Tabs,
10
11
  Typography,
11
12
  } from '@rango-dev/ui';
12
13
  import {
@@ -24,11 +25,14 @@ import { HistoryGroupedList } from '../components/HistoryGroupedList';
24
25
  import { NotFoundContainer } from '../components/HistoryGroupedList/HistoryGroupedList.styles';
25
26
  import { Layout, PageContainer } from '../components/Layout';
26
27
  import { SearchInput } from '../components/SearchInput';
28
+ import { useSwapMode } from '../hooks/useSwapMode';
27
29
  import { getContainer } from '../utils/common';
28
30
  import { groupSwapsByDate } from '../utils/date';
29
31
  import { containsText } from '../utils/numbers';
30
32
  import { getPendingSwaps } from '../utils/queue';
31
33
 
34
+ type SwapModeTab = 'all' | 'swap' | 'refuel';
35
+
32
36
  const HistoryGroupedListContainer = styled('div', {
33
37
  overflowY: 'visible',
34
38
  width: '100%',
@@ -65,6 +69,21 @@ const transactionStatusFilters = [
65
69
  { id: TransactionStatus.FAILED, title: i18n.t('Failed') },
66
70
  ];
67
71
 
72
+ const SWAP_MODE_TAB_ITEMS = [
73
+ {
74
+ id: 'all',
75
+ title: i18n.t('All'),
76
+ },
77
+ {
78
+ id: 'swap',
79
+ title: i18n.t('Swap'),
80
+ },
81
+ {
82
+ id: 'refuel',
83
+ title: i18n.t('Refuel'),
84
+ },
85
+ ];
86
+
68
87
  const isStepContainsText = (steps: PendingSwapStep[], value: string) => {
69
88
  if (!steps?.length) {
70
89
  return false;
@@ -87,18 +106,21 @@ export function HistoryPage() {
87
106
  const loading = !state.loadedFromPersistor;
88
107
  const [filterBy, setFilterBy] = useState('');
89
108
  const [openClearModal, setOpenClearModal] = useState(false);
109
+ const [swapModeActiveTab, setSwapModeActiveTab] =
110
+ useState<SwapModeTab>('all');
90
111
  const handleSearch = (event: React.ChangeEvent<HTMLInputElement>) => {
91
112
  const value = event.target.value;
92
113
  setSearchedFor(value);
93
114
  };
115
+ const { isMultiMode } = useSwapMode();
94
116
 
95
117
  const filteredList = useMemo(() => {
96
- if (!searchedFor && !filterBy) {
118
+ if (!searchedFor && !filterBy && swapModeActiveTab === 'all') {
97
119
  return list;
98
120
  }
99
121
 
100
122
  return list.filter((swap) => {
101
- const { inputAmount, status, steps, requestId } = swap;
123
+ const { inputAmount, status, steps, requestId, mode } = swap;
102
124
 
103
125
  const matchesSearch =
104
126
  !searchedFor ||
@@ -109,9 +131,22 @@ export function HistoryPage() {
109
131
 
110
132
  const matchesFilter = !filterBy || filterBy === status;
111
133
 
112
- return matchesSearch && matchesFilter;
134
+ const matchesSwapMode = (() => {
135
+ if (swapModeActiveTab === 'all') {
136
+ return true;
137
+ }
138
+ if (swapModeActiveTab === 'swap') {
139
+ return !mode || mode === 'swap';
140
+ }
141
+ if (swapModeActiveTab === 'refuel') {
142
+ return mode === 'refuel';
143
+ }
144
+ return false;
145
+ })();
146
+
147
+ return matchesSearch && matchesFilter && matchesSwapMode;
113
148
  });
114
- }, [list, searchedFor, filterBy]);
149
+ }, [list, searchedFor, filterBy, swapModeActiveTab]);
115
150
 
116
151
  const isEmpty = !filteredList?.length && !loading;
117
152
 
@@ -177,6 +212,18 @@ export function HistoryPage() {
177
212
  </SearchAndFilterBar>
178
213
 
179
214
  <Divider size="16" />
215
+
216
+ {isMultiMode && !loading && (
217
+ <>
218
+ <Tabs
219
+ items={SWAP_MODE_TAB_ITEMS}
220
+ onChange={(item) => setSwapModeActiveTab(item.id as SwapModeTab)}
221
+ value={swapModeActiveTab}
222
+ type="secondary"
223
+ />
224
+ <Divider size="12" />
225
+ </>
226
+ )}
180
227
  <HistoryGroupedListContainer>
181
228
  {isEmpty && (
182
229
  <NotFoundContainer>
@@ -19,6 +19,7 @@ import { Inputs } from '../containers/Inputs';
19
19
  import { QuoteInfo } from '../containers/QuoteInfo';
20
20
  import useScreenDetect from '../hooks/useScreenDetect';
21
21
  import { useSwapInput } from '../hooks/useSwapInput';
22
+ import { useSwapMode } from '../hooks/useSwapMode';
22
23
  import { useAppStore } from '../store/AppStore';
23
24
  import { useQuoteStore } from '../store/quote';
24
25
  import { useUiStore } from '../store/ui';
@@ -53,7 +54,7 @@ export function Home() {
53
54
  resetQuoteWallets,
54
55
  setQuoteWarningsConfirmed,
55
56
  updateQuotePartialState,
56
- } = useQuoteStore();
57
+ } = useQuoteStore()();
57
58
 
58
59
  const [isVisibleExpanded, setIsVisibleExpanded] = useState<boolean>(false);
59
60
  const { isLargeScreen, isExtraLargeScreen } = useScreenDetect();
@@ -72,6 +73,7 @@ export function Home() {
72
73
  const { isActiveTab } = useUiStore();
73
74
  const [showQuoteWarningModal, setShowQuoteWarningModal] = useState(false);
74
75
  const currentSlippage = customSlippage !== null ? customSlippage : slippage;
76
+ const { swapMode } = useSwapMode();
75
77
 
76
78
  const slippageValidation = getSlippageValidation(currentSlippage);
77
79
 
@@ -148,6 +150,18 @@ export function Home() {
148
150
  setCustomSlippage(slippage);
149
151
  };
150
152
 
153
+ const handleInputTokenClick = (mode: 'from' | 'to') => {
154
+ if (mode === 'from') {
155
+ onHandleNavigation(navigationRoutes.fromSwap);
156
+ } else {
157
+ onHandleNavigation(
158
+ swapMode === 'swap'
159
+ ? navigationRoutes.toSwap
160
+ : navigationRoutes.toSwap + '/' + navigationRoutes.blockchains
161
+ );
162
+ }
163
+ };
164
+
151
165
  useEffect(() => {
152
166
  resetQuoteWallets();
153
167
  updateQuotePartialState('refetchQuote', true);
@@ -192,7 +206,9 @@ export function Home() {
192
206
  onHandleNavigation(navigationRoutes.wallets);
193
207
  },
194
208
  hasBackButton: false,
195
- title: config.title || i18n.t('Swap'),
209
+ title:
210
+ config.title ||
211
+ (swapMode === 'swap' ? i18n.t('Swap') : i18n.t('Refuel')),
196
212
  suffix: (
197
213
  <HeaderButtons
198
214
  hidden={isExpandable ? ['refresh'] : undefined}
@@ -209,13 +225,7 @@ export function Home() {
209
225
  fetchingQuote={fetchingQuote}
210
226
  fetchMetaStatus={fetchMetaStatus}
211
227
  isExpandable={isExpandable}
212
- onClickToken={(mode) => {
213
- onHandleNavigation(
214
- mode === 'from'
215
- ? navigationRoutes.fromSwap
216
- : navigationRoutes.toSwap
217
- );
218
- }}
228
+ onClickToken={handleInputTokenClick}
219
229
  />
220
230
  <Divider size="2" />
221
231
  {!isExpandable ? (
@@ -21,7 +21,7 @@ export function RoutesPage() {
21
21
  setSelectedQuote,
22
22
  updateQuotePartialState,
23
23
  error: quoteError,
24
- } = useQuoteStore();
24
+ } = useQuoteStore()();
25
25
 
26
26
  const { fetch: fetchQuote, loading: fetchingQuote } = useSwapInput({
27
27
  refetchQuote,