@rango-dev/widget-embedded 0.29.1-next.1 → 0.29.1-next.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/dist/components/NotificationContent/NotificationContent.d.ts.map +1 -1
  2. package/dist/components/SwapDetails/SwapDetails.d.ts.map +1 -1
  3. package/dist/containers/WidgetInfo/WidgetInfo.d.ts.map +1 -1
  4. package/dist/containers/WidgetInfo/WidgetInfo.helpers.d.ts +4 -2
  5. package/dist/containers/WidgetInfo/WidgetInfo.helpers.d.ts.map +1 -1
  6. package/dist/hooks/useConfirmSwap/useConfirmSwap.d.ts.map +1 -1
  7. package/dist/hooks/useConfirmSwap/useConfirmSwap.helpers.d.ts +2 -1
  8. package/dist/hooks/useConfirmSwap/useConfirmSwap.helpers.d.ts.map +1 -1
  9. package/dist/hooks/useSyncStoresWithConfig.d.ts.map +1 -1
  10. package/dist/hooks/useSyncUrlAndStore/useSyncUrlAndStore.d.ts.map +1 -1
  11. package/dist/hooks/useSyncUrlAndStore/useSyncUrlAndStore.helpers.d.ts +2 -2
  12. package/dist/hooks/useSyncUrlAndStore/useSyncUrlAndStore.helpers.d.ts.map +1 -1
  13. package/dist/index.js +2 -2
  14. package/dist/index.js.map +4 -4
  15. package/dist/store/quote.d.ts +9 -3
  16. package/dist/store/quote.d.ts.map +1 -1
  17. package/dist/store/selectors.d.ts +1 -1
  18. package/dist/store/selectors.d.ts.map +1 -1
  19. package/dist/store/slices/data.d.ts +5 -3
  20. package/dist/store/slices/data.d.ts.map +1 -1
  21. package/dist/store/wallets.d.ts +5 -4
  22. package/dist/store/wallets.d.ts.map +1 -1
  23. package/dist/test-utils/fixtures.d.ts +1 -1
  24. package/dist/test-utils/fixtures.d.ts.map +1 -1
  25. package/dist/utils/meta.d.ts +2 -1
  26. package/dist/utils/meta.d.ts.map +1 -1
  27. package/dist/utils/quote.d.ts +4 -8
  28. package/dist/utils/quote.d.ts.map +1 -1
  29. package/dist/utils/swap.d.ts +3 -4
  30. package/dist/utils/swap.d.ts.map +1 -1
  31. package/dist/utils/wallets.d.ts +4 -5
  32. package/dist/utils/wallets.d.ts.map +1 -1
  33. package/dist/widget-embedded.build.json +1 -1
  34. package/package.json +2 -2
  35. package/src/components/NotificationContent/NotificationContent.tsx +3 -8
  36. package/src/components/Quote/Quote.tsx +3 -3
  37. package/src/components/Quotes/Quotes.tsx +2 -2
  38. package/src/components/SwapDetails/SwapDetails.tsx +8 -3
  39. package/src/containers/Wallets/Wallets.tsx +2 -2
  40. package/src/containers/WidgetInfo/WidgetInfo.helpers.ts +12 -3
  41. package/src/containers/WidgetInfo/WidgetInfo.tsx +4 -2
  42. package/src/hooks/useConfirmSwap/useConfirmSwap.helpers.ts +4 -2
  43. package/src/hooks/useConfirmSwap/useConfirmSwap.ts +3 -1
  44. package/src/hooks/useSubscribeToWidgetEvents/useSubscribeToWidgetEvents.ts +3 -3
  45. package/src/hooks/useSwapInput.ts +2 -2
  46. package/src/hooks/useSyncStoresWithConfig.ts +6 -7
  47. package/src/hooks/useSyncUrlAndStore/useSyncUrlAndStore.helpers.ts +12 -26
  48. package/src/hooks/useSyncUrlAndStore/useSyncUrlAndStore.ts +19 -12
  49. package/src/store/quote.ts +12 -7
  50. package/src/store/selectors.ts +6 -4
  51. package/src/store/slices/data.test.ts +9 -5
  52. package/src/store/slices/data.ts +26 -7
  53. package/src/store/wallets.ts +9 -8
  54. package/src/test-utils/fixtures.ts +9 -2
  55. package/src/utils/meta.ts +5 -6
  56. package/src/utils/quote.ts +12 -20
  57. package/src/utils/swap.ts +5 -25
  58. package/src/utils/wallets.ts +4 -28
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rango-dev/widget-embedded",
3
- "version": "0.29.1-next.1",
3
+ "version": "0.29.1-next.2",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "source": "./src/index.ts",
@@ -27,7 +27,7 @@
27
27
  "@rango-dev/logging-core": "^0.4.0",
28
28
  "@rango-dev/provider-all": "^0.34.1-next.0",
29
29
  "@rango-dev/queue-manager-core": "^0.26.0",
30
- "@rango-dev/queue-manager-rango-preset": "^0.34.1-next.0",
30
+ "@rango-dev/queue-manager-rango-preset": "^0.34.1-next.1",
31
31
  "@rango-dev/queue-manager-react": "^0.26.0",
32
32
  "@rango-dev/signer-solana": "^0.29.1-next.0",
33
33
  "@rango-dev/ui": "^0.35.1-next.1",
@@ -14,7 +14,6 @@ import { useNavigate } from 'react-router-dom';
14
14
  import { navigationRoutes } from '../../constants/navigationRoutes';
15
15
  import { useAppStore } from '../../store/AppStore';
16
16
  import { useNotificationStore } from '../../store/notification';
17
- import { areTokensEqual } from '../../utils/wallets';
18
17
 
19
18
  import {
20
19
  ClearAllButton,
@@ -36,7 +35,7 @@ export function NotificationContent() {
36
35
 
37
36
  const notifications: Notification[] = getNotifications();
38
37
  const blockchains = useAppStore().blockchains();
39
- const tokens = useAppStore().tokens();
38
+ const { findToken } = useAppStore();
40
39
  const sortedNotification = notifications
41
40
  .sort((a, b) => b.creationTime - a.creationTime)
42
41
  .slice(0, MAX_NOTIFICATIONS_DISPLAYED);
@@ -69,17 +68,13 @@ export function NotificationContent() {
69
68
  <List>
70
69
  {sortedNotification.map((notificationItem, index) => {
71
70
  const { route, requestId, event } = notificationItem;
72
- const fromToken = tokens.find((tokenItem) =>
73
- areTokensEqual(tokenItem, route.from)
74
- );
71
+ const fromToken = findToken(route.from);
75
72
 
76
73
  const fromBlockchain = blockchains.find(
77
74
  (blockchainItem) => blockchainItem.name === route.from.blockchain
78
75
  );
79
76
 
80
- const toToken = tokens.find((tokenItem) =>
81
- areTokensEqual(tokenItem, route.to)
82
- );
77
+ const toToken = findToken(route.to);
83
78
 
84
79
  const toBlockchain = blockchains.find(
85
80
  (blockchainItem) => blockchainItem.name === route.to.blockchain
@@ -88,7 +88,7 @@ export function Quote(props: QuoteProps) {
88
88
  container: propContainer,
89
89
  } = props;
90
90
  const blockchains = useAppStore().blockchains();
91
- const tokens = useAppStore().tokens();
91
+ const { findToken } = useAppStore();
92
92
  const swappers = useAppStore().swappers();
93
93
  const { customSlippage, slippage } = useAppStore();
94
94
  const userSlippage = customSlippage || slippage;
@@ -303,7 +303,7 @@ export function Quote(props: QuoteProps) {
303
303
  ) : undefined,
304
304
  time: roundedSecondsToString(swap.estimatedTimeInSeconds),
305
305
  fee: numberToString(
306
- getUsdFeeOfStep(swap, tokens),
306
+ getUsdFeeOfStep(swap, findToken),
307
307
  GAS_FEE_MIN_DECIMALS,
308
308
  GAS_FEE_MAX_DECIMALS
309
309
  ),
@@ -320,7 +320,7 @@ export function Quote(props: QuoteProps) {
320
320
  const sortedQuoteTags = sortTags(props.quote.tags || []);
321
321
  const showAllRoutesButton = !!onClickAllRoutes;
322
322
  const totalTime = roundedSecondsToString(totalArrivalTime(quote?.swaps));
323
- const totalFee = getTotalFeeInUsd(quote?.swaps ?? [], tokens);
323
+ const totalFee = getTotalFeeInUsd(quote?.swaps ?? [], findToken);
324
324
  const fee = numberToString(
325
325
  totalFee,
326
326
  GAS_FEE_MIN_DECIMALS,
@@ -39,7 +39,7 @@ export function Quotes(props: PropTypes) {
39
39
  error,
40
40
  } = useQuoteStore();
41
41
  const { slippage, customSlippage } = useAppStore();
42
- const tokens = useAppStore().tokens();
42
+ const { findToken } = useAppStore();
43
43
  const container = propContainer || getContainer();
44
44
  const hasQuotes = !!quotes && quotes.results.length;
45
45
  const userSlippage = customSlippage ?? slippage;
@@ -56,7 +56,7 @@ export function Quotes(props: PropTypes) {
56
56
  fromToken,
57
57
  toToken,
58
58
  userSlippage,
59
- tokens,
59
+ findToken,
60
60
  });
61
61
  };
62
62
  const showNoResultMessage =
@@ -47,7 +47,11 @@ import {
47
47
  roundedSecondsToString,
48
48
  totalArrivalTime,
49
49
  } from '../../utils/numbers';
50
- import { getPriceImpact, getPriceImpactLevel } from '../../utils/quote';
50
+ import {
51
+ createRetryQuote,
52
+ getPriceImpact,
53
+ getPriceImpactLevel,
54
+ } from '../../utils/quote';
51
55
  import {
52
56
  getLastConvertedTokenInFailedSwap,
53
57
  getSwapMessages,
@@ -81,7 +85,7 @@ export function SwapDetails(props: SwapDetailsProps) {
81
85
  const { canSwitchNetworkTo, connect, getWalletInfo } = useWallets();
82
86
  const blockchains = useAppStore().blockchains();
83
87
  const swappers = useAppStore().swappers();
84
- const tokens = useAppStore().tokens();
88
+ const { findToken } = useAppStore();
85
89
  const retry = useQuoteStore.use.retry();
86
90
  const isActiveTab = useUiStore.use.isActiveTab();
87
91
  const navigate = useNavigate();
@@ -294,7 +298,8 @@ export function SwapDetails(props: SwapDetailsProps) {
294
298
  type="primary"
295
299
  size="large"
296
300
  onClick={() => {
297
- retry(swap, { blockchains: blockchains, tokens: tokens });
301
+ const swapInput = createRetryQuote(swap, blockchains, findToken);
302
+ retry(swapInput);
298
303
  setTimeout(() => {
299
304
  const home = '../../';
300
305
  navigate(home);
@@ -33,7 +33,7 @@ export const WidgetContext = createContext<WidgetContextInterface>({
33
33
  function Main(props: PropsWithChildren<PropTypes>) {
34
34
  const { updateConfig, updateSettings, fetch: fetchMeta } = useAppStore();
35
35
  const blockchains = useAppStore().blockchains();
36
- const tokens = useAppStore().tokens();
36
+ const { findToken } = useAppStore();
37
37
  const config = useAppStore().config;
38
38
 
39
39
  const walletOptions: ProvidersOptions = {
@@ -79,7 +79,7 @@ function Main(props: PropsWithChildren<PropTypes>) {
79
79
  meta.isContractWallet
80
80
  );
81
81
  if (data.length) {
82
- connectWallet(data, tokens);
82
+ connectWallet(data, findToken);
83
83
  }
84
84
  } else {
85
85
  disconnectWallet(type);
@@ -1,4 +1,5 @@
1
- import type { Meta } from '../../store/quote';
1
+ import type { Meta, RetryQuote } from '../../store/quote';
2
+ import type { FindToken } from '../../store/slices/data';
2
3
  import type { Manager } from '@rango-dev/queue-manager-core';
3
4
  import type { PendingSwap } from 'rango-types/lib';
4
5
 
@@ -10,9 +11,11 @@ import {
10
11
  } from '@rango-dev/queue-manager-rango-preset';
11
12
 
12
13
  import { getPendingSwaps } from '../../utils/queue';
14
+ import { createRetryQuote } from '../../utils/quote';
13
15
 
14
16
  interface WidgetHistoryActions {
15
- retrySwap: (pendingSwap: PendingSwap, meta: Meta) => void;
17
+ retrySwap: (retryQuote: RetryQuote) => void;
18
+ findToken: FindToken;
16
19
  }
17
20
 
18
21
  export class WidgetHistory {
@@ -41,7 +44,13 @@ export class WidgetHistory {
41
44
  }
42
45
 
43
46
  public retry(swap: PendingSwap, meta: Meta) {
44
- return this.actions.retrySwap(swap, meta);
47
+ const retryQuote = createRetryQuote(
48
+ swap,
49
+ meta.blockchains,
50
+ this.actions.findToken
51
+ );
52
+
53
+ return this.actions.retrySwap(retryQuote);
45
54
  }
46
55
 
47
56
  public cancel(id: string) {
@@ -21,7 +21,9 @@ export function WidgetInfo(props: React.PropsWithChildren) {
21
21
  const { manager } = useManager();
22
22
  const isActiveTab = useUiStore.use.isActiveTab();
23
23
  const retrySwap = useQuoteStore.use.retry();
24
- const history = new WidgetHistory(manager, { retrySwap });
24
+ const { findToken } = useAppStore();
25
+
26
+ const history = new WidgetHistory(manager, { retrySwap, findToken });
25
27
  const details = useWalletsStore.use.connectedWallets();
26
28
  const isLoading = useWalletsStore.use.loading();
27
29
  const totalBalance = calculateWalletUsdValue(details);
@@ -42,7 +44,7 @@ export function WidgetInfo(props: React.PropsWithChildren) {
42
44
  isLoading,
43
45
  details,
44
46
  totalBalance,
45
- refetch,
47
+ refetch: (accounts) => refetch(accounts, findToken),
46
48
  },
47
49
  meta: {
48
50
  blockchains,
@@ -1,4 +1,5 @@
1
1
  import type { ConfirmSwapFetchResult } from './useConfirmSwap.types';
2
+ import type { FindToken } from '../../store/slices/data';
2
3
  import type {
3
4
  ConfirmSwapWarnings,
4
5
  QuoteErrorResponse,
@@ -87,9 +88,10 @@ export function generateWarnings(
87
88
  params: {
88
89
  fromToken: Token;
89
90
  toToken: Token;
90
- meta: { blockchains: BlockchainMeta[]; tokens: Token[] };
91
+ meta: { blockchains: BlockchainMeta[] };
91
92
  selectedWallets: Wallet[];
92
93
  userSlippage: number;
94
+ findToken: FindToken;
93
95
  }
94
96
  ): ConfirmSwapWarnings {
95
97
  let quoteChanged = false;
@@ -105,7 +107,7 @@ export function generateWarnings(
105
107
  const quoteWarning = generateQuoteWarnings(currentQuote, {
106
108
  fromToken: params.fromToken,
107
109
  toToken: params.toToken,
108
- tokens: params.meta.tokens,
110
+ findToken: params.findToken,
109
111
  userSlippage: params.userSlippage,
110
112
  });
111
113
 
@@ -32,6 +32,7 @@ export function useConfirmSwap(): ConfirmSwap {
32
32
  const disabledLiquiditySources = useAppStore().getDisabledLiquiditySources();
33
33
  const blockchains = useAppStore().blockchains();
34
34
  const tokens = useAppStore().tokens();
35
+ const { findToken } = useAppStore();
35
36
 
36
37
  const userSlippage = customSlippage || slippage;
37
38
 
@@ -96,7 +97,8 @@ export function useConfirmSwap(): ConfirmSwap {
96
97
  {
97
98
  fromToken,
98
99
  toToken,
99
- meta: { blockchains, tokens },
100
+ meta: { blockchains },
101
+ findToken,
100
102
  selectedWallets,
101
103
  userSlippage,
102
104
  }
@@ -15,10 +15,10 @@ import { useNotificationStore } from '../../store/notification';
15
15
  import { useWalletsStore } from '../../store/wallets';
16
16
 
17
17
  export function useSubscribeToWidgetEvents() {
18
- const tokens = useAppStore().tokens();
19
18
  const connectedWallets = useWalletsStore.use.connectedWallets();
20
19
  const getWalletsDetails = useWalletsStore.use.getWalletsDetails();
21
20
  const setNotification = useNotificationStore.use.setNotification();
21
+ const { findToken } = useAppStore();
22
22
  const widgetEvents = useEvents();
23
23
 
24
24
  useEffect(() => {
@@ -40,8 +40,8 @@ export function useSubscribeToWidgetEvents() {
40
40
  (wallet) => wallet.chain === step?.toBlockchain
41
41
  );
42
42
 
43
- fromAccount && getWalletsDetails([fromAccount], tokens);
44
- toAccount && getWalletsDetails([toAccount], tokens);
43
+ fromAccount && getWalletsDetails([fromAccount], findToken);
44
+ toAccount && getWalletsDetails([toAccount], findToken);
45
45
  }
46
46
 
47
47
  setNotification(event, route);
@@ -53,7 +53,6 @@ export function useSwapInput({
53
53
  } = useAppStore().config;
54
54
  const connectedWallets = useWalletsStore.use.connectedWallets();
55
55
 
56
- const tokens = useAppStore().tokens();
57
56
  const {
58
57
  fromToken,
59
58
  toToken,
@@ -78,6 +77,7 @@ export function useSwapInput({
78
77
  const liquiditySources = useAppStore().getLiquiditySources();
79
78
  const disabledLiquiditySources = useAppStore().getDisabledLiquiditySources();
80
79
  const excludeLiquiditySources = useAppStore().excludeLiquiditySources();
80
+ const { findToken } = useAppStore();
81
81
 
82
82
  const [loading, setLoading] = useState(true);
83
83
  const prevInputAmount = useRef(inputAmount);
@@ -153,7 +153,7 @@ export function useSwapInput({
153
153
  fromToken,
154
154
  toToken,
155
155
  userSlippage,
156
- tokens,
156
+ findToken,
157
157
  });
158
158
  updateQuotePartialState('warning', quoteWarning);
159
159
  })
@@ -8,7 +8,6 @@ import {
8
8
  isBlockchainExcludedInConfig,
9
9
  isTokenExcludedInConfig,
10
10
  } from '../utils/configs';
11
- import { areTokensEqual } from '../utils/wallets';
12
11
 
13
12
  export function useSyncStoresWithConfig() {
14
13
  const {
@@ -28,6 +27,7 @@ export function useSyncStoresWithConfig() {
28
27
  const fetchMetaStatus = useAppStore().fetchStatus;
29
28
  const blockchains = useAppStore().blockchains();
30
29
  const tokens = useAppStore().tokens();
30
+ const { findToken } = useAppStore();
31
31
 
32
32
  const { setAffiliateRef, setAffiliatePercent, setAffiliateWallets } =
33
33
  useAppStore();
@@ -51,9 +51,8 @@ export function useSyncStoresWithConfig() {
51
51
  const chain = blockchains.find(
52
52
  (chain) => chain.name === config?.from?.blockchain
53
53
  );
54
- const token = tokens.find((t) =>
55
- areTokensEqual(t, config?.from?.token || null)
56
- );
54
+ const fromToken = config?.from?.token;
55
+ const token = fromToken && findToken(fromToken);
57
56
 
58
57
  if (chain || (!chain && prevConfigFromBlockchain.current)) {
59
58
  setFromBlockchain(chain ?? null);
@@ -101,9 +100,9 @@ export function useSyncStoresWithConfig() {
101
100
  const chain = blockchains.find(
102
101
  (chain) => chain.name === config?.to?.blockchain
103
102
  );
104
- const token = tokens.find((t) =>
105
- areTokensEqual(t, config?.to?.token || null)
106
- );
103
+
104
+ const toToken = config?.to?.token;
105
+ const token = toToken && findToken(toToken);
107
106
 
108
107
  if (chain || (!chain && prevConfigToBlockchain.current)) {
109
108
  setToBlockchain(chain ?? null);
@@ -1,30 +1,16 @@
1
- import type { BlockchainMeta, Token } from 'rango-sdk';
1
+ import type { Asset, BlockchainMeta, Token } from 'rango-sdk';
2
2
 
3
- export function searchParamToToken(
4
- tokens: Token[],
5
- searchParam: string | null,
6
- chain: BlockchainMeta | null
7
- ): Token | null {
8
- if (!chain) {
9
- return null;
10
- }
11
- return (
12
- tokens.find((token) => {
13
- const symbolAndAddress = searchParam?.split('--');
14
- if (symbolAndAddress?.length === 1) {
15
- return (
16
- token.symbol === symbolAndAddress[0] &&
17
- token.address === null &&
18
- token.blockchain === chain.name
19
- );
20
- }
21
- return (
22
- token.symbol === symbolAndAddress?.[0] &&
23
- token.address === symbolAndAddress?.[1] &&
24
- token.blockchain === chain.name
25
- );
26
- }) || null
27
- );
3
+ export function convertTokenSearchParamToAsset(
4
+ searchParam: string,
5
+ chain: BlockchainMeta
6
+ ): Asset {
7
+ const symbolAndAddress = searchParam.split('--');
8
+
9
+ return {
10
+ blockchain: chain.name,
11
+ address: symbolAndAddress?.[1] || null,
12
+ symbol: symbolAndAddress[0],
13
+ };
28
14
  }
29
15
 
30
16
  export function tokenToSearchParam(token: Token | null): string | undefined {
@@ -10,7 +10,7 @@ import { useAppStore } from '../../store/AppStore';
10
10
  import { useQuoteStore } from '../../store/quote';
11
11
 
12
12
  import {
13
- searchParamToToken,
13
+ convertTokenSearchParamToAsset,
14
14
  tokenToSearchParam,
15
15
  } from './useSyncUrlAndStore.helpers';
16
16
 
@@ -36,7 +36,7 @@ export function useSyncUrlAndStore() {
36
36
  const { updateIframe, updateCampaignMode } = useAppStore();
37
37
  const campaignMode = useAppStore().isInCampaignMode();
38
38
  const liquiditySourcesParamsRef = useRef<string>();
39
-
39
+ const { findToken } = useAppStore();
40
40
  const getUrlSearchParams = () => {
41
41
  const utmQueryParams: Record<string, string> = {};
42
42
 
@@ -124,19 +124,26 @@ export function useSyncUrlAndStore() {
124
124
  const fromBlockchain = blockchains.find(
125
125
  (blockchain) => blockchain.name === searchParams.fromBlockchain
126
126
  );
127
- const fromToken = searchParamToToken(
128
- tokens,
129
- searchParams.fromToken,
130
- fromBlockchain ?? null
131
- );
127
+
128
+ const fromToken =
129
+ searchParams.fromToken && fromBlockchain
130
+ ? findToken(
131
+ convertTokenSearchParamToAsset(
132
+ searchParams.fromToken,
133
+ fromBlockchain
134
+ )
135
+ )
136
+ : undefined;
132
137
  const toBlockchain = blockchains.find(
133
138
  (blockchain) => blockchain.name === searchParams.toBlockchain
134
139
  );
135
- const toToken = searchParamToToken(
136
- tokens,
137
- searchParams.toToken,
138
- toBlockchain ?? null
139
- );
140
+
141
+ const toToken =
142
+ searchParams.toToken && toBlockchain
143
+ ? findToken(
144
+ convertTokenSearchParamToAsset(searchParams.toToken, toBlockchain)
145
+ )
146
+ : undefined;
140
147
 
141
148
  if (!!fromBlockchain) {
142
149
  setFromBlockchain(fromBlockchain);
@@ -6,7 +6,6 @@ import type {
6
6
  PreferenceType,
7
7
  Token,
8
8
  } from 'rango-sdk';
9
- import type { PendingSwap } from 'rango-types';
10
9
 
11
10
  import BigNumber from 'bignumber.js';
12
11
  import { create } from 'zustand';
@@ -14,7 +13,7 @@ import { subscribeWithSelector } from 'zustand/middleware';
14
13
 
15
14
  import { ZERO } from '../constants/numbers';
16
15
  import { isPositiveNumber } from '../utils/numbers';
17
- import { createRetryQuote, getQuoteToTokenUsdPrice } from '../utils/quote';
16
+ import { getQuoteToTokenUsdPrice } from '../utils/quote';
18
17
  import { calcOutputUsdValue } from '../utils/swap';
19
18
 
20
19
  import createSelectors from './selectors';
@@ -38,7 +37,13 @@ type SomeQuoteState = {
38
37
  error: QuoteError | null;
39
38
  warning: QuoteWarning | null;
40
39
  };
41
-
40
+ export type RetryQuote = {
41
+ fromBlockchain: BlockchainMeta | null;
42
+ fromToken?: Token;
43
+ toBlockchain: BlockchainMeta | null;
44
+ toToken?: Token;
45
+ inputAmount: string;
46
+ };
42
47
  export interface QuoteState {
43
48
  fromBlockchain: BlockchainMeta | null;
44
49
  toBlockchain: BlockchainMeta | null;
@@ -73,7 +78,7 @@ export interface QuoteState {
73
78
  ) => void;
74
79
  setInputAmount: (amount: string) => void;
75
80
  setSelectedQuote: (quote: SelectedQuote | null) => void;
76
- retry: (pendingSwap: PendingSwap, meta: Meta) => void;
81
+ retry: (retryQuote: RetryQuote) => void;
77
82
  switchFromAndTo: () => void;
78
83
  setQuoteWalletConfirmed: (flag: boolean) => void;
79
84
  setSelectedWallets: (wallets: Wallet[]) => void;
@@ -219,15 +224,15 @@ export const useQuoteStore = createSelectors(
219
224
  }),
220
225
  }));
221
226
  },
222
- retry: (pendingSwap, meta) => {
223
- const { tokens, blockchains } = meta;
227
+ retry: (retryQuote) => {
224
228
  const {
225
229
  fromBlockchain,
226
230
  fromToken,
227
231
  toBlockchain,
228
232
  toToken,
229
233
  inputAmount,
230
- } = createRetryQuote(pendingSwap, blockchains, tokens);
234
+ } = retryQuote;
235
+
231
236
  set({
232
237
  fromBlockchain,
233
238
  fromToken,
@@ -1,4 +1,4 @@
1
- import { StoreApi, UseBoundStore } from 'zustand';
1
+ import type { StoreApi, UseBoundStore } from 'zustand';
2
2
 
3
3
  type State = object;
4
4
 
@@ -6,10 +6,12 @@ type WithSelectors<S> = S extends { getState: () => infer T }
6
6
  ? S & { use: { [K in keyof T]: () => T[K] } }
7
7
  : never;
8
8
 
9
- const createSelectors = <S extends UseBoundStore<StoreApi<State>>>(_store: S) => {
10
- let store = _store as WithSelectors<typeof _store>;
9
+ const createSelectors = <S extends UseBoundStore<StoreApi<State>>>(
10
+ _store: S
11
+ ) => {
12
+ const store = _store as WithSelectors<typeof _store>;
11
13
  store.use = {};
12
- for (let k of Object.keys(store.getState())) {
14
+ for (const k of Object.keys(store.getState())) {
13
15
  (store.use as any)[k] = () => store((s) => s[k as keyof typeof s]);
14
16
  }
15
17
 
@@ -9,6 +9,7 @@ import {
9
9
  createToken,
10
10
  updateAppStoreConfig,
11
11
  } from '../../test-utils/fixtures';
12
+ import { createTokenHash } from '../../utils/meta';
12
13
  import { createAppStore } from '../app';
13
14
 
14
15
  let appStoreState: AppStoreState;
@@ -48,7 +49,10 @@ beforeEach(() => {
48
49
 
49
50
  const initData = createInitialAppStore();
50
51
  initData._blockchainsMapByName.set(rangoBlockchain.name, rangoBlockchain);
51
- customTokens.forEach((token) => initData._tokens.push(token));
52
+ customTokens.forEach((token) => {
53
+ const tokenHash = createTokenHash(token);
54
+ initData._tokensMapByTokenHash.set(tokenHash, token);
55
+ });
52
56
 
53
57
  const appStore = createAppStore();
54
58
  appStore.setState(initData);
@@ -149,10 +153,10 @@ describe('check sorting tokens is working correctly in app store', () => {
149
153
 
150
154
  test('put popular token with lowest blockchain sort at first', () => {
151
155
  const rangoToken = customTokens[0];
152
- const rangoIndex = appStoreState._tokens.findIndex(
153
- (tokenItem) => tokenItem.symbol === rangoToken.symbol
154
- );
155
- appStoreState._tokens[rangoIndex].isPopular = true;
156
+ const token = appStoreState.findToken(rangoToken);
157
+ if (token) {
158
+ token.isPopular = true;
159
+ }
156
160
  appStoreState._blockchainsMapByName.set(rangoToken.blockchain, {
157
161
  ...rangoBlockchain,
158
162
  sort: 0,
@@ -1,14 +1,14 @@
1
1
  // We keep all the received data from server in this slice
2
2
 
3
3
  import type { ConfigSlice } from './config';
4
- import type { Balance } from '../../types';
5
- import type { BlockchainMeta, SwapperMeta, Token } from 'rango-sdk';
4
+ import type { Balance, TokenHash } from '../../types';
5
+ import type { Asset, BlockchainMeta, SwapperMeta, Token } from 'rango-sdk';
6
6
  import type { StateCreator } from 'zustand';
7
7
 
8
8
  import { httpService as sdk } from '../../services/httpService';
9
9
  import { compareWithSearchFor, containsText } from '../../utils/common';
10
10
  import { isTokenExcludedInConfig } from '../../utils/configs';
11
- import { isTokenNative } from '../../utils/meta';
11
+ import { createTokenHash, isTokenNative } from '../../utils/meta';
12
12
  import { sortLiquiditySourcesByGroupTitle } from '../../utils/settings';
13
13
  import { areTokensEqual, compareTokenBalance } from '../../utils/wallets';
14
14
 
@@ -24,10 +24,12 @@ type TokenOptions = {
24
24
  getBalanceFor?: (token: Token) => Balance | null;
25
25
  };
26
26
 
27
+ export type FindToken = (asset: Asset) => Token | undefined;
28
+
27
29
  export type FetchStatus = 'loading' | 'success' | 'failed';
28
30
  export interface DataSlice {
29
31
  _blockchainsMapByName: Map<string, BlockchainMeta>;
30
- _tokens: Token[];
32
+ _tokensMapByTokenHash: Map<TokenHash, Token>;
31
33
  _popularTokens: Token[];
32
34
  _swappers: SwapperMeta[];
33
35
  fetchStatus: FetchStatus;
@@ -35,6 +37,7 @@ export interface DataSlice {
35
37
  tokens: (options?: TokenOptions) => Token[];
36
38
  swappers: () => SwapperMeta[];
37
39
  isTokenPinned: (token: Token, type: 'source' | 'destination') => boolean;
40
+ findToken: FindToken;
38
41
  fetch: () => Promise<void>;
39
42
  }
40
43
 
@@ -46,7 +49,7 @@ export const createDataSlice: StateCreator<
46
49
  > = (set, get) => ({
47
50
  // State
48
51
  _blockchainsMapByName: new Map<string, BlockchainMeta>(),
49
- _tokens: [],
52
+ _tokensMapByTokenHash: new Map<TokenHash, Token>(),
50
53
  _popularTokens: [],
51
54
  _swappers: [],
52
55
  fetchStatus: 'loading',
@@ -81,7 +84,8 @@ export const createDataSlice: StateCreator<
81
84
  return list;
82
85
  },
83
86
  tokens: (options) => {
84
- const tokensFromState = get()._tokens;
87
+ const tokensMapByHashToken = get()._tokensMapByTokenHash;
88
+ const tokensFromState = Array.from(tokensMapByHashToken?.values() || []);
85
89
  const blockchainsMapByName = get()._blockchainsMapByName;
86
90
 
87
91
  if (!options || !options?.type) {
@@ -197,6 +201,12 @@ export const createDataSlice: StateCreator<
197
201
 
198
202
  return list;
199
203
  },
204
+ findToken: (asset) => {
205
+ const tokensMapByHashToken = get()._tokensMapByTokenHash;
206
+ const tokenHash = createTokenHash(asset);
207
+ const token = tokensMapByHashToken.get(tokenHash);
208
+ return token;
209
+ },
200
210
  isTokenPinned: (token, type) => {
201
211
  const pinnedTokens =
202
212
  type === 'source'
@@ -258,6 +268,10 @@ export const createDataSlice: StateCreator<
258
268
  BlockchainMeta
259
269
  >();
260
270
 
271
+ const tokensMapByHashToken: Map<TokenHash, Token> = new Map<
272
+ TokenHash,
273
+ Token
274
+ >();
261
275
  const tokens: Token[] = [];
262
276
  const popularTokens: Token[] = response.popularTokens;
263
277
  const swappers: SwapperMeta[] = response.swappers;
@@ -283,9 +297,14 @@ export const createDataSlice: StateCreator<
283
297
  }
284
298
  });
285
299
 
300
+ tokens.forEach((token) => {
301
+ const tokenHash = createTokenHash(token);
302
+ tokensMapByHashToken.set(tokenHash, token);
303
+ });
304
+
286
305
  set({
287
306
  _blockchainsMapByName: blockchainsMapByName,
288
- _tokens: tokens,
307
+ _tokensMapByTokenHash: tokensMapByHashToken,
289
308
  _popularTokens: popularTokens,
290
309
  _swappers: swappers,
291
310
  });