@rango-dev/widget-embedded 0.1.10-next.100

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 (204) hide show
  1. package/dist/App.d.ts +9 -0
  2. package/dist/App.d.ts.map +1 -0
  3. package/dist/QueueManager.d.ts +4 -0
  4. package/dist/QueueManager.d.ts.map +1 -0
  5. package/dist/components/AppRouter.d.ts +9 -0
  6. package/dist/components/AppRouter.d.ts.map +1 -0
  7. package/dist/components/AppRoutes.d.ts +8 -0
  8. package/dist/components/AppRoutes.d.ts.map +1 -0
  9. package/dist/components/BottomLogo.d.ts +3 -0
  10. package/dist/components/BottomLogo.d.ts.map +1 -0
  11. package/dist/components/ChangeSlippageButton.d.ts +3 -0
  12. package/dist/components/ChangeSlippageButton.d.ts.map +1 -0
  13. package/dist/components/ConfirmSwapErrors.d.ts +4 -0
  14. package/dist/components/ConfirmSwapErrors.d.ts.map +1 -0
  15. package/dist/components/ConfirmSwapWarnings.d.ts +4 -0
  16. package/dist/components/ConfirmSwapWarnings.d.ts.map +1 -0
  17. package/dist/components/Footer.d.ts +2 -0
  18. package/dist/components/Footer.d.ts.map +1 -0
  19. package/dist/components/Header.d.ts +10 -0
  20. package/dist/components/Header.d.ts.map +1 -0
  21. package/dist/components/HeaderButtons.d.ts +4 -0
  22. package/dist/components/HeaderButtons.d.ts.map +1 -0
  23. package/dist/components/Layout.d.ts +7 -0
  24. package/dist/components/Layout.d.ts.map +1 -0
  25. package/dist/components/RoutesOverview.d.ts +10 -0
  26. package/dist/components/RoutesOverview.d.ts.map +1 -0
  27. package/dist/components/SwitchFromAndTo.d.ts +4 -0
  28. package/dist/components/SwitchFromAndTo.d.ts.map +1 -0
  29. package/dist/components/TokenInfo.d.ts +18 -0
  30. package/dist/components/TokenInfo.d.ts.map +1 -0
  31. package/dist/components/TokenPreview.d.ts +20 -0
  32. package/dist/components/TokenPreview.d.ts.map +1 -0
  33. package/dist/components/UpdateUrl.d.ts +2 -0
  34. package/dist/components/UpdateUrl.d.ts.map +1 -0
  35. package/dist/components/warnings/BalanceWarnings.d.ts +7 -0
  36. package/dist/components/warnings/BalanceWarnings.d.ts.map +1 -0
  37. package/dist/components/warnings/ConfirmSwapExtraMessages.d.ts +7 -0
  38. package/dist/components/warnings/ConfirmSwapExtraMessages.d.ts.map +1 -0
  39. package/dist/components/warnings/HighSlippageWarning.d.ts +7 -0
  40. package/dist/components/warnings/HighSlippageWarning.d.ts.map +1 -0
  41. package/dist/components/warnings/MinRequiredSlippage.d.ts +7 -0
  42. package/dist/components/warnings/MinRequiredSlippage.d.ts.map +1 -0
  43. package/dist/constants/errors.d.ts +4 -0
  44. package/dist/constants/errors.d.ts.map +1 -0
  45. package/dist/constants/navigationRoutes.d.ts +15 -0
  46. package/dist/constants/navigationRoutes.d.ts.map +1 -0
  47. package/dist/constants/numbers.d.ts +3 -0
  48. package/dist/constants/numbers.d.ts.map +1 -0
  49. package/dist/constants/searchParams.d.ts +8 -0
  50. package/dist/constants/searchParams.d.ts.map +1 -0
  51. package/dist/constants/swapSettings.d.ts +6 -0
  52. package/dist/constants/swapSettings.d.ts.map +1 -0
  53. package/dist/globalStyles.d.ts +3 -0
  54. package/dist/globalStyles.d.ts.map +1 -0
  55. package/dist/hooks/useConfirmSwap.d.ts +11 -0
  56. package/dist/hooks/useConfirmSwap.d.ts.map +1 -0
  57. package/dist/hooks/useCopyToClipboard.d.ts +2 -0
  58. package/dist/hooks/useCopyToClipboard.d.ts.map +1 -0
  59. package/dist/hooks/useNavigateBack.d.ts +4 -0
  60. package/dist/hooks/useNavigateBack.d.ts.map +1 -0
  61. package/dist/hooks/usePrevious.d.ts +2 -0
  62. package/dist/hooks/usePrevious.d.ts.map +1 -0
  63. package/dist/hooks/useSelectLanguage.d.ts +5 -0
  64. package/dist/hooks/useSelectLanguage.d.ts.map +1 -0
  65. package/dist/hooks/useTheme.d.ts +8 -0
  66. package/dist/hooks/useTheme.d.ts.map +1 -0
  67. package/dist/i18n.d.ts +3 -0
  68. package/dist/i18n.d.ts.map +1 -0
  69. package/dist/index.d.ts +2 -0
  70. package/dist/index.d.ts.map +1 -0
  71. package/dist/index.js +8 -0
  72. package/dist/lib.d.ts +8 -0
  73. package/dist/lib.d.ts.map +1 -0
  74. package/dist/mockData/pendingSwap.d.ts +2 -0
  75. package/dist/mockData/pendingSwap.d.ts.map +1 -0
  76. package/dist/pages/ConfirmSwapPage.d.ts +3 -0
  77. package/dist/pages/ConfirmSwapPage.d.ts.map +1 -0
  78. package/dist/pages/ConfirmWalletsPage.d.ts +3 -0
  79. package/dist/pages/ConfirmWalletsPage.d.ts.map +1 -0
  80. package/dist/pages/HistoryPage.d.ts +3 -0
  81. package/dist/pages/HistoryPage.d.ts.map +1 -0
  82. package/dist/pages/Home.d.ts +9 -0
  83. package/dist/pages/Home.d.ts.map +1 -0
  84. package/dist/pages/LiquiditySourcesPage.d.ts +8 -0
  85. package/dist/pages/LiquiditySourcesPage.d.ts.map +1 -0
  86. package/dist/pages/SelectChainPage.d.ts +9 -0
  87. package/dist/pages/SelectChainPage.d.ts.map +1 -0
  88. package/dist/pages/SelectTokenPage.d.ts +15 -0
  89. package/dist/pages/SelectTokenPage.d.ts.map +1 -0
  90. package/dist/pages/SettingsPage.d.ts +8 -0
  91. package/dist/pages/SettingsPage.d.ts.map +1 -0
  92. package/dist/pages/SwapDetailsPage.d.ts +3 -0
  93. package/dist/pages/SwapDetailsPage.d.ts.map +1 -0
  94. package/dist/pages/WalletsPage.d.ts +9 -0
  95. package/dist/pages/WalletsPage.d.ts.map +1 -0
  96. package/dist/services/httpService.d.ts +3 -0
  97. package/dist/services/httpService.d.ts.map +1 -0
  98. package/dist/store/bestRoute.d.ts +28 -0
  99. package/dist/store/bestRoute.d.ts.map +1 -0
  100. package/dist/store/meta.d.ts +9 -0
  101. package/dist/store/meta.d.ts.map +1 -0
  102. package/dist/store/selectors.d.ts +11 -0
  103. package/dist/store/selectors.d.ts.map +1 -0
  104. package/dist/store/settings.d.ts +17 -0
  105. package/dist/store/settings.d.ts.map +1 -0
  106. package/dist/store/ui.d.ts +2 -0
  107. package/dist/store/ui.d.ts.map +1 -0
  108. package/dist/store/wallets.d.ts +28 -0
  109. package/dist/store/wallets.d.ts.map +1 -0
  110. package/dist/types/config.d.ts +40 -0
  111. package/dist/types/config.d.ts.map +1 -0
  112. package/dist/types/index.d.ts +4 -0
  113. package/dist/types/index.d.ts.map +1 -0
  114. package/dist/types/routing.d.ts +45 -0
  115. package/dist/types/routing.d.ts.map +1 -0
  116. package/dist/types/swap.d.ts +11 -0
  117. package/dist/types/swap.d.ts.map +1 -0
  118. package/dist/utils/common.d.ts +4 -0
  119. package/dist/utils/common.d.ts.map +1 -0
  120. package/dist/utils/numbers.d.ts +14 -0
  121. package/dist/utils/numbers.d.ts.map +1 -0
  122. package/dist/utils/queue.d.ts +4 -0
  123. package/dist/utils/queue.d.ts.map +1 -0
  124. package/dist/utils/routing.d.ts +18 -0
  125. package/dist/utils/routing.d.ts.map +1 -0
  126. package/dist/utils/swap.d.ts +45 -0
  127. package/dist/utils/swap.d.ts.map +1 -0
  128. package/dist/utils/wallets.d.ts +29 -0
  129. package/dist/utils/wallets.d.ts.map +1 -0
  130. package/dist/widget-embedded.cjs.development.js +3101 -0
  131. package/dist/widget-embedded.cjs.development.js.map +1 -0
  132. package/dist/widget-embedded.cjs.production.min.js +3101 -0
  133. package/dist/widget-embedded.cjs.production.min.js.map +1 -0
  134. package/dist/widget-embedded.esm.js +3092 -0
  135. package/dist/widget-embedded.esm.js.map +1 -0
  136. package/package.json +55 -0
  137. package/readme.md +2 -0
  138. package/src/App.tsx +91 -0
  139. package/src/QueueManager.tsx +94 -0
  140. package/src/app.css +27 -0
  141. package/src/components/AppRouter.tsx +60 -0
  142. package/src/components/AppRoutes.tsx +105 -0
  143. package/src/components/BottomLogo.tsx +47 -0
  144. package/src/components/ChangeSlippageButton.tsx +19 -0
  145. package/src/components/ConfirmSwapErrors.tsx +38 -0
  146. package/src/components/ConfirmSwapWarnings.tsx +35 -0
  147. package/src/components/Footer.tsx +8 -0
  148. package/src/components/Header.tsx +37 -0
  149. package/src/components/HeaderButtons.tsx +47 -0
  150. package/src/components/Layout.tsx +96 -0
  151. package/src/components/RoutesOverview.tsx +60 -0
  152. package/src/components/SwitchFromAndTo.tsx +30 -0
  153. package/src/components/TokenInfo.tsx +311 -0
  154. package/src/components/TokenPreview.tsx +175 -0
  155. package/src/components/UpdateUrl.tsx +162 -0
  156. package/src/components/warnings/BalanceWarnings.tsx +39 -0
  157. package/src/components/warnings/ConfirmSwapExtraMessages.tsx +20 -0
  158. package/src/components/warnings/HighSlippageWarning.tsx +18 -0
  159. package/src/components/warnings/MinRequiredSlippage.tsx +18 -0
  160. package/src/constants/errors.ts +3 -0
  161. package/src/constants/navigationRoutes.ts +14 -0
  162. package/src/constants/numbers.ts +3 -0
  163. package/src/constants/searchParams.ts +7 -0
  164. package/src/constants/swapSettings.ts +9 -0
  165. package/src/globalStyles.ts +26 -0
  166. package/src/hooks/useConfirmSwap.ts +260 -0
  167. package/src/hooks/useCopyToClipboard.ts +23 -0
  168. package/src/hooks/useNavigateBack.ts +40 -0
  169. package/src/hooks/usePrevious.ts +13 -0
  170. package/src/hooks/useSelectLanguage.ts +15 -0
  171. package/src/hooks/useTheme.ts +127 -0
  172. package/src/i18n.js +30 -0
  173. package/src/index.tsx +14 -0
  174. package/src/languages/en.json +14 -0
  175. package/src/languages/tr.json +11 -0
  176. package/src/lib.tsx +119 -0
  177. package/src/mockData/pendingSwap.ts +607 -0
  178. package/src/pages/ConfirmSwapPage.tsx +72 -0
  179. package/src/pages/ConfirmWalletsPage.tsx +127 -0
  180. package/src/pages/HistoryPage.tsx +29 -0
  181. package/src/pages/Home.tsx +228 -0
  182. package/src/pages/LiquiditySourcesPage.tsx +64 -0
  183. package/src/pages/SelectChainPage.tsx +42 -0
  184. package/src/pages/SelectTokenPage.tsx +64 -0
  185. package/src/pages/SettingsPage.tsx +98 -0
  186. package/src/pages/SwapDetailsPage.tsx +38 -0
  187. package/src/pages/WalletsPage.tsx +119 -0
  188. package/src/services/httpService.ts +5 -0
  189. package/src/store/bestRoute.ts +245 -0
  190. package/src/store/meta.ts +35 -0
  191. package/src/store/selectors.ts +19 -0
  192. package/src/store/settings.ts +84 -0
  193. package/src/store/ui.ts +21 -0
  194. package/src/store/wallets.ts +190 -0
  195. package/src/types/config.ts +44 -0
  196. package/src/types/index.ts +3 -0
  197. package/src/types/routing.ts +60 -0
  198. package/src/types/swap.ts +13 -0
  199. package/src/utils/common.ts +35 -0
  200. package/src/utils/numbers.ts +133 -0
  201. package/src/utils/queue.ts +24 -0
  202. package/src/utils/routing.ts +150 -0
  203. package/src/utils/swap.ts +552 -0
  204. package/src/utils/wallets.ts +481 -0
@@ -0,0 +1,119 @@
1
+ import {
2
+ Alert,
3
+ SecondaryPage,
4
+ styled,
5
+ Wallet,
6
+ WalletState,
7
+ WalletInfo,
8
+ } from '@rango-dev/ui';
9
+ import React, { useEffect, useRef, useState } from 'react';
10
+ import { getlistWallet, sortWalletsBasedOnState } from '../utils/wallets';
11
+ import { WalletType, detectMobileScreens } from '@rango-dev/wallets-shared';
12
+ import { useWallets } from '@rango-dev/wallets-core';
13
+
14
+ import { useUiStore } from '../store/ui';
15
+ import { useNavigateBack } from '../hooks/useNavigateBack';
16
+ import { navigationRoutes } from '../constants/navigationRoutes';
17
+ import { useTranslation } from 'react-i18next';
18
+
19
+ interface PropTypes {
20
+ supportedWallets: 'all' | WalletType[];
21
+ multiWallets: boolean;
22
+ }
23
+
24
+ const ListContainer = styled('div', {
25
+ display: 'grid',
26
+ gap: '.5rem',
27
+ gridTemplateColumns: ' repeat(2, minmax(0, 1fr))',
28
+ height: '450px',
29
+ alignContent: 'baseline',
30
+ padding: '0.5rem',
31
+ });
32
+
33
+ const AlertContainer = styled('div', {
34
+ paddingBottom: '$16',
35
+ });
36
+ export function WalletsPage({ supportedWallets, multiWallets }: PropTypes) {
37
+ const { navigateBackFrom } = useNavigateBack();
38
+ const { state, disconnect, getWalletInfo, connect } = useWallets();
39
+ const wallets = getlistWallet(
40
+ state,
41
+ getWalletInfo,
42
+ supportedWallets === 'all' ? Object.values(WalletType) : supportedWallets
43
+ );
44
+ const walletsRef = useRef<WalletInfo[]>();
45
+
46
+ let sortedWallets = detectMobileScreens()
47
+ ? wallets.filter((wallet) => wallet.showOnMobile)
48
+ : wallets;
49
+ sortedWallets = sortWalletsBasedOnState(sortedWallets);
50
+ const [walletErrorMessage, setWalletErrorMessage] = useState('');
51
+ const toggleConnectWalletsButton =
52
+ useUiStore.use.toggleConnectWalletsButton();
53
+ const { t } = useTranslation();
54
+
55
+ const onSelectWallet = async (type: WalletType) => {
56
+ const wallet = state(type);
57
+ try {
58
+ if (walletErrorMessage) setWalletErrorMessage('');
59
+ if (wallet.connected) {
60
+ await disconnect(type);
61
+ } else {
62
+ if (
63
+ !multiWallets &&
64
+ !!wallets.find((w) => w.state === WalletState.CONNECTED)
65
+ ) {
66
+ return;
67
+ }
68
+ await connect(type);
69
+ }
70
+ } catch (e) {
71
+ setWalletErrorMessage('Error: ' + (e as any)?.message);
72
+ }
73
+ };
74
+ const disconnectConnectingWallets = () => {
75
+ const connectingWallets =
76
+ walletsRef.current?.filter(
77
+ (wallet) => wallet.state === WalletState.CONNECTING
78
+ ) || [];
79
+ for (const wallet of connectingWallets) {
80
+ disconnect(wallet.type);
81
+ }
82
+ };
83
+ useEffect(() => {
84
+ toggleConnectWalletsButton();
85
+ return () => {
86
+ disconnectConnectingWallets();
87
+ toggleConnectWalletsButton();
88
+ };
89
+ }, []);
90
+
91
+ useEffect(() => {
92
+ walletsRef.current = wallets;
93
+ }, [wallets]);
94
+
95
+ return (
96
+ <SecondaryPage
97
+ title={t('Select Wallet') || ''}
98
+ textField={false}
99
+ onBack={navigateBackFrom.bind(null, navigationRoutes.wallets)}
100
+ >
101
+ <>
102
+ {walletErrorMessage && (
103
+ <AlertContainer>
104
+ <Alert type="error">{walletErrorMessage}</Alert>
105
+ </AlertContainer>
106
+ )}
107
+ <ListContainer>
108
+ {sortedWallets.map((wallet, index) => (
109
+ <Wallet
110
+ {...wallet}
111
+ key={`${index}-${wallet.type}`}
112
+ onClick={onSelectWallet}
113
+ />
114
+ ))}
115
+ </ListContainer>
116
+ </>
117
+ </SecondaryPage>
118
+ );
119
+ }
@@ -0,0 +1,5 @@
1
+ import { RangoClient } from 'rango-sdk';
2
+
3
+ export const httpService = new RangoClient(
4
+ process.env.REACT_APP_API_KEY as string
5
+ );
@@ -0,0 +1,245 @@
1
+ import { BestRouteResponse, BlockchainMeta } from 'rango-sdk';
2
+ import { Token } from 'rango-sdk';
3
+ import { create } from 'zustand';
4
+ import BigNumber from 'bignumber.js';
5
+ import { ZERO } from '../constants/numbers';
6
+ import {
7
+ getBestRouteToTokenUsdPrice,
8
+ isRouteParametersChanged,
9
+ } from '../utils/routing';
10
+ import createSelectors from './selectors';
11
+ import { subscribeWithSelector } from 'zustand/middleware';
12
+ import { httpService } from '../services/httpService';
13
+ import { useSettingsStore } from './settings';
14
+ import { calcOutputUsdValue, createBestRouteRequestBody } from '../utils/swap';
15
+ import { useMetaStore } from './meta';
16
+ import { getDefaultToken, getSortedTokens } from '../utils/wallets';
17
+ import { useWalletsStore } from './wallets';
18
+ import { TokenWithBalance } from '../pages/SelectTokenPage';
19
+
20
+ const getUsdValue = (token: Token | null, amount: string) =>
21
+ new BigNumber(amount || ZERO).multipliedBy(token?.usdPrice || 0);
22
+
23
+ export interface RouteState {
24
+ fromChain: BlockchainMeta | null;
25
+ toChain: BlockchainMeta | null;
26
+ inputAmount: string;
27
+ inputUsdValue: BigNumber;
28
+ outputAmount: BigNumber | null;
29
+ outputUsdValue: BigNumber;
30
+ fromToken: TokenWithBalance | null;
31
+ toToken: TokenWithBalance | null;
32
+ loading: boolean;
33
+ error: string;
34
+ sourceTokens: Token[];
35
+ destinationTokens: Token[];
36
+ setFromChain: (
37
+ chain: BlockchainMeta | null,
38
+ setDefaultToken?: boolean
39
+ ) => void;
40
+ setToChain: (chian: BlockchainMeta | null, setDefaultToken?: boolean) => void;
41
+ setFromToken: (token: Token | null) => void;
42
+ setToToken: (token: Token | null) => void;
43
+ setInputAmount: (amount: string) => void;
44
+ bestRoute: BestRouteResponse | null;
45
+ setBestRoute: (bestRoute: BestRouteResponse | null) => void;
46
+ }
47
+
48
+ export const useBestRouteStore = createSelectors(
49
+ create<RouteState>()(
50
+ subscribeWithSelector((set) => ({
51
+ fromChain: null,
52
+ fromToken: null,
53
+ inputAmount: '',
54
+ outputAmount: null,
55
+ inputUsdValue: new BigNumber(0),
56
+ outputUsdValue: new BigNumber(0),
57
+ toChain: null,
58
+ toToken: null,
59
+ bestRoute: null,
60
+ loading: false,
61
+ error: '',
62
+ sourceTokens: [],
63
+ destinationTokens: [],
64
+ setBestRoute: (bestRoute) =>
65
+ set((state) => {
66
+ let outputAmount: BigNumber | null = null;
67
+ let outputUsdValue: BigNumber = ZERO;
68
+ if (!!bestRoute) {
69
+ outputAmount = !!bestRoute.result?.outputAmount
70
+ ? new BigNumber(bestRoute.result?.outputAmount)
71
+ : null;
72
+ outputUsdValue = calcOutputUsdValue(
73
+ bestRoute.result?.outputAmount,
74
+ getBestRouteToTokenUsdPrice(bestRoute) || state.toToken?.usdPrice
75
+ );
76
+ }
77
+ return {
78
+ bestRoute,
79
+ ...(!!bestRoute && {
80
+ outputAmount,
81
+ outputUsdValue,
82
+ }),
83
+ };
84
+ }),
85
+ setFromChain: (chain, setDefaultToken) => {
86
+ set((state) => {
87
+ if (state.fromChain?.name === chain?.name) return {};
88
+ const tokens = useMetaStore.getState().meta.tokens;
89
+ const balances = useWalletsStore.getState().balances;
90
+ const sortedTokens = getSortedTokens(
91
+ chain,
92
+ tokens,
93
+ balances,
94
+ state.destinationTokens
95
+ );
96
+ const fromToken = getDefaultToken(sortedTokens, state.toToken);
97
+ return {
98
+ fromChain: chain,
99
+ sourceTokens: sortedTokens,
100
+ ...(setDefaultToken && {
101
+ fromToken,
102
+ }),
103
+ ...(!!state.inputAmount && {
104
+ inputUsdValue: getUsdValue(fromToken, state.inputAmount),
105
+ }),
106
+ };
107
+ });
108
+ },
109
+ setFromToken: (token) =>
110
+ set((state) => ({
111
+ fromToken: token,
112
+ ...(!!state.inputAmount && {
113
+ inputUsdValue: getUsdValue(token, state.inputAmount),
114
+ }),
115
+ })),
116
+ setToChain: (chain, setDefaultToken) => {
117
+ set((state) => {
118
+ if (state.toChain?.name === chain?.name) return {};
119
+ const tokens = useMetaStore.getState().meta.tokens;
120
+ const balances = useWalletsStore.getState().balances;
121
+ const sortedTokens = getSortedTokens(
122
+ chain,
123
+ tokens,
124
+ balances,
125
+ state.destinationTokens
126
+ );
127
+
128
+ return {
129
+ toChain: chain,
130
+ destinationTokens: sortedTokens,
131
+ ...(setDefaultToken && {
132
+ toToken: getDefaultToken(sortedTokens, state.fromToken),
133
+ }),
134
+ };
135
+ });
136
+ },
137
+ setToToken: (token) =>
138
+ set(() => ({
139
+ toToken: token,
140
+ })),
141
+ setInputAmount: (amount) => {
142
+ set((state) => ({
143
+ inputAmount: amount,
144
+ ...(!amount && {
145
+ outputAmount: new BigNumber(0),
146
+ outputUsdValue: new BigNumber(0),
147
+ bestRoute: null,
148
+ }),
149
+ ...(!!state.fromToken && {
150
+ inputUsdValue: getUsdValue(state.fromToken, amount),
151
+ }),
152
+ }));
153
+ },
154
+ }))
155
+ )
156
+ );
157
+
158
+ const bestRoute = (
159
+ bestRouteStore: typeof useBestRouteStore,
160
+ settingsStore: typeof useSettingsStore
161
+ ) => {
162
+ let abortController: AbortController | null = null;
163
+ const fetchBestRoute = () => {
164
+ const { fromToken, toToken, inputAmount } = bestRouteStore.getState();
165
+ const { slippage, customSlippage, disabledLiquiditySources } =
166
+ settingsStore.getState();
167
+ if (!fromToken || !toToken || !inputAmount) return;
168
+ abortController?.abort();
169
+ abortController = new AbortController();
170
+ const userSlippage = !!customSlippage ? customSlippage : slippage;
171
+ const requestBody = createBestRouteRequestBody(
172
+ fromToken,
173
+ toToken,
174
+ inputAmount,
175
+ [],
176
+ [],
177
+ disabledLiquiditySources,
178
+ userSlippage,
179
+ false
180
+ );
181
+ bestRouteStore.setState({
182
+ loading: true,
183
+ bestRoute: null,
184
+ outputAmount: null,
185
+ outputUsdValue: new BigNumber(0),
186
+ });
187
+ httpService
188
+ .getBestRoute(requestBody, {
189
+ signal: abortController.signal,
190
+ })
191
+ .then((res) => {
192
+ const { setBestRoute } = bestRouteStore.getState();
193
+ setBestRoute(res);
194
+ bestRouteStore.setState({ loading: false });
195
+ abortController = null;
196
+ })
197
+ .catch((error) => {
198
+ if (error.code === 'ERR_CANCELED') return;
199
+ bestRouteStore.setState({
200
+ error: error.message,
201
+ loading: false,
202
+ });
203
+ });
204
+ };
205
+
206
+ useBestRouteStore.subscribe(
207
+ (state) => ({
208
+ fromChain: state.fromChain,
209
+ fromToken: state.fromToken,
210
+ toChain: state.toChain,
211
+ toToken: state.toToken,
212
+ inputAmount: state.inputAmount,
213
+ }),
214
+
215
+ fetchBestRoute.bind(null),
216
+ {
217
+ equalityFn: (prevState, state) => {
218
+ if (isRouteParametersChanged(prevState, state)) return false;
219
+ else return true;
220
+ },
221
+ }
222
+ );
223
+
224
+ useSettingsStore.subscribe(
225
+ (state) => ({
226
+ slippage: state.slippage,
227
+ customSlippage: state.customSlippage,
228
+ disabledLiquiditySources: state.disabledLiquiditySources,
229
+ }),
230
+ fetchBestRoute.bind(null),
231
+ {
232
+ equalityFn: (prevState, state) => {
233
+ if (isRouteParametersChanged(prevState, state)) return false;
234
+ else return true;
235
+ },
236
+ }
237
+ );
238
+
239
+ return { fetchBestRoute };
240
+ };
241
+
242
+ export const { fetchBestRoute } = bestRoute(
243
+ useBestRouteStore,
244
+ useSettingsStore
245
+ );
@@ -0,0 +1,35 @@
1
+ import { create } from 'zustand';
2
+ import { MetaResponse } from 'rango-sdk';
3
+ import { httpService } from '../services/httpService';
4
+ import createSelectors from './selectors';
5
+ import { removeDuplicateFrom } from '../utils/common';
6
+
7
+ export type LoadingStatus = 'loading' | 'success' | 'failed';
8
+
9
+ export interface MetaState {
10
+ meta: MetaResponse;
11
+ loadingStatus: LoadingStatus;
12
+ fetchMeta: () => Promise<void>;
13
+ }
14
+
15
+ export const useMetaStore = createSelectors(
16
+ create<MetaState>()((set) => ({
17
+ meta: { blockchains: [], popularTokens: [], swappers: [], tokens: [] },
18
+ loadingStatus: 'loading',
19
+ fetchMeta: async () => {
20
+ try {
21
+ const response = await httpService.getAllMetadata();
22
+ const chainThatHasTokenInMetaResponse = removeDuplicateFrom(
23
+ response.tokens.map((t) => t.blockchain),
24
+ );
25
+ const enabledChains = response.blockchains.filter(
26
+ (chain) => chain.enabled && chainThatHasTokenInMetaResponse.includes(chain.name),
27
+ );
28
+ response.blockchains = enabledChains.sort((a, b) => a.sort - b.sort);
29
+ set({ meta: response, loadingStatus: 'success' });
30
+ } catch (error) {
31
+ set({ loadingStatus: 'failed' });
32
+ }
33
+ },
34
+ })),
35
+ );
@@ -0,0 +1,19 @@
1
+ import { StoreApi, UseBoundStore } from 'zustand';
2
+
3
+ type State = object;
4
+
5
+ type WithSelectors<S> = S extends { getState: () => infer T }
6
+ ? S & { use: { [K in keyof T]: () => T[K] } }
7
+ : never;
8
+
9
+ const createSelectors = <S extends UseBoundStore<StoreApi<State>>>(_store: S) => {
10
+ let store = _store as WithSelectors<typeof _store>;
11
+ store.use = {};
12
+ for (let k of Object.keys(store.getState())) {
13
+ (store.use as any)[k] = () => store((s) => s[k as keyof typeof s]);
14
+ }
15
+
16
+ return store;
17
+ };
18
+
19
+ export default createSelectors;
@@ -0,0 +1,84 @@
1
+ import { create } from 'zustand';
2
+ import { persist, subscribeWithSelector } from 'zustand/middleware';
3
+ import { DEFAULT_SLIPPAGE } from '../constants/swapSettings';
4
+ import { removeDuplicateFrom } from '../utils/common';
5
+ import { useMetaStore } from './meta';
6
+ import createSelectors from './selectors';
7
+
8
+ type Theme = 'auto' | 'dark' | 'light';
9
+
10
+ export interface SettingsState {
11
+ slippage: number;
12
+ customSlippage: number | null;
13
+ infiniteApprove: boolean;
14
+ disabledLiquiditySources: string[];
15
+ theme: Theme;
16
+ setSlippage: (slippage: number) => void;
17
+ setCustomSlippage: (customSlippage: number | null) => void;
18
+ toggleInfiniteApprove: () => void;
19
+ toggleLiquiditySource: (name: string) => void;
20
+ setTheme: (theme: Theme) => void;
21
+ toggleAllLiquiditySources: () => void;
22
+ }
23
+
24
+ export const useSettingsStore = createSelectors(
25
+ create<SettingsState>()(
26
+ persist(
27
+ subscribeWithSelector((set) => ({
28
+ slippage: DEFAULT_SLIPPAGE,
29
+ customSlippage: null,
30
+ infiniteApprove: false,
31
+ disabledLiquiditySources: [],
32
+ theme: 'auto',
33
+ setSlippage: (slippage) =>
34
+ set(() => ({
35
+ slippage: slippage,
36
+ })),
37
+ setCustomSlippage: (customSlippage) =>
38
+ set(() => ({
39
+ customSlippage: customSlippage,
40
+ })),
41
+ toggleAllLiquiditySources: () =>
42
+ set((state) => {
43
+ const { swappers } = useMetaStore.getState().meta;
44
+ const swappersGroup = removeDuplicateFrom(
45
+ swappers.map((swapper) => swapper.swapperGroup)
46
+ );
47
+
48
+ if (swappersGroup.length === state.disabledLiquiditySources.length)
49
+ return { disabledLiquiditySources: [] };
50
+ else {
51
+ return {
52
+ disabledLiquiditySources: swappersGroup,
53
+ };
54
+ }
55
+ }),
56
+ toggleInfiniteApprove: () =>
57
+ set((state) => ({
58
+ infiniteApprove: !state.infiniteApprove,
59
+ })),
60
+ toggleLiquiditySource: (name) =>
61
+ set((state) => {
62
+ if (state.disabledLiquiditySources.includes(name))
63
+ return {
64
+ disabledLiquiditySources: state.disabledLiquiditySources.filter(
65
+ (liquiditySource) => liquiditySource != name
66
+ ),
67
+ };
68
+ else
69
+ return {
70
+ disabledLiquiditySources:
71
+ state.disabledLiquiditySources.concat(name),
72
+ };
73
+ }),
74
+ setTheme: (theme) =>
75
+ set(() => ({
76
+ theme,
77
+ })),
78
+ })),
79
+ {
80
+ name: 'user-settings',
81
+ }
82
+ )
83
+ )
84
+ );
@@ -0,0 +1,21 @@
1
+ import { create } from 'zustand';
2
+ import createSelectors from './selectors';
3
+
4
+ interface UiState {
5
+ connectWalletsButtonDisabled: boolean;
6
+ selectedSwapRequestId: string | null;
7
+ toggleConnectWalletsButton: () => void;
8
+ setSelectedSwap: (requestId: string | null) => void;
9
+ }
10
+
11
+ export const useUiStore = createSelectors(
12
+ create<UiState>()((set) => ({
13
+ connectWalletsButtonDisabled: false,
14
+ selectedSwapRequestId: null,
15
+ toggleConnectWalletsButton: () =>
16
+ set((state) => ({
17
+ connectWalletsButtonDisabled: !state.connectWalletsButtonDisabled,
18
+ })),
19
+ setSelectedSwap: (requestId) => set({ selectedSwapRequestId: requestId }),
20
+ }))
21
+ );