@rango-dev/widget-embedded 0.37.1-next.1 → 0.38.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 (156) hide show
  1. package/dist/QueueManager.d.ts.map +1 -1
  2. package/dist/components/ConfirmWalletsModal/ConfirmWalletsModal.d.ts.map +1 -1
  3. package/dist/components/ConfirmWalletsModal/WalletList.d.ts.map +1 -1
  4. package/dist/components/Layout/Layout.d.ts.map +1 -1
  5. package/dist/components/Quote/Quote.d.ts.map +1 -1
  6. package/dist/components/Quote/Quote.styles.d.ts +1 -1
  7. package/dist/components/Quote/Quote.types.d.ts +0 -2
  8. package/dist/components/Quote/Quote.types.d.ts.map +1 -1
  9. package/dist/components/Quote/QuoteCostDetails.d.ts.map +1 -1
  10. package/dist/components/Quote/QuoteCostDetails.styles.d.ts.map +1 -1
  11. package/dist/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.d.ts.map +1 -1
  12. package/dist/components/Quotes/Quotes.d.ts.map +1 -1
  13. package/dist/components/RefreshModal/RefreshModal.styles.d.ts +1 -1
  14. package/dist/components/SwapDetails/SwapDetails.d.ts.map +1 -1
  15. package/dist/components/SwapDetailsAlerts/SwapDetailsAlerts.types.d.ts +1 -1
  16. package/dist/components/SwapDetailsAlerts/SwapDetailsAlerts.types.d.ts.map +1 -1
  17. package/dist/components/SwapDetailsModal/SwapDetailsCompleteModal.d.ts.map +1 -1
  18. package/dist/components/TokenList/TokenList.d.ts.map +1 -1
  19. package/dist/components/WalletStatefulConnect/DerivationPath.helpers.d.ts +1 -2
  20. package/dist/components/WalletStatefulConnect/DerivationPath.helpers.d.ts.map +1 -1
  21. package/dist/components/WalletStatefulConnect/Namespaces.d.ts.map +1 -1
  22. package/dist/components/WalletStatefulConnect/Namespaces.types.d.ts +1 -1
  23. package/dist/components/WalletStatefulConnect/Namespaces.types.d.ts.map +1 -1
  24. package/dist/constants/quote.d.ts +0 -10
  25. package/dist/constants/quote.d.ts.map +1 -1
  26. package/dist/constants/warnings.d.ts +3 -0
  27. package/dist/constants/warnings.d.ts.map +1 -0
  28. package/dist/containers/ExpandedQuotes/ExpandedQuotes.styles.d.ts.map +1 -1
  29. package/dist/containers/Inputs/Inputs.d.ts.map +1 -1
  30. package/dist/containers/QuoteInfo/QuoteInfo.d.ts.map +1 -1
  31. package/dist/containers/Wallets/Wallets.d.ts.map +1 -1
  32. package/dist/containers/WidgetInfo/WidgetInfo.d.ts.map +1 -1
  33. package/dist/containers/WidgetInfo/WidgetInfo.helpers.d.ts +1 -1
  34. package/dist/containers/WidgetInfo/WidgetInfo.types.d.ts +3 -3
  35. package/dist/containers/WidgetInfo/WidgetInfo.types.d.ts.map +1 -1
  36. package/dist/hooks/useConfirmSwap/useConfirmSwap.d.ts.map +1 -1
  37. package/dist/hooks/useConfirmSwap/useConfirmSwap.helpers.d.ts +4 -6
  38. package/dist/hooks/useConfirmSwap/useConfirmSwap.helpers.d.ts.map +1 -1
  39. package/dist/hooks/useFetchApiConfig.d.ts.map +1 -1
  40. package/dist/hooks/useFetchCustomToken.d.ts.map +1 -1
  41. package/dist/hooks/useObserveBalanceChanges/index.d.ts +2 -0
  42. package/dist/hooks/useObserveBalanceChanges/index.d.ts.map +1 -0
  43. package/dist/hooks/useObserveBalanceChanges/useObserveBalanceChanges.d.ts +4 -0
  44. package/dist/hooks/useObserveBalanceChanges/useObserveBalanceChanges.d.ts.map +1 -0
  45. package/dist/hooks/useStatefulConnect/useStatefulConnect.d.ts +1 -2
  46. package/dist/hooks/useStatefulConnect/useStatefulConnect.d.ts.map +1 -1
  47. package/dist/hooks/useStatefulConnect/useStatefulConnect.types.d.ts +5 -3
  48. package/dist/hooks/useStatefulConnect/useStatefulConnect.types.d.ts.map +1 -1
  49. package/dist/hooks/useSubscribeToWidgetEvents/useSubscribeToWidgetEvents.d.ts.map +1 -1
  50. package/dist/hooks/useSwapInput.d.ts.map +1 -1
  51. package/dist/hooks/useWalletList.d.ts.map +1 -1
  52. package/dist/hooks/useWalletProviders/useWalletProviders.d.ts +3 -2
  53. package/dist/hooks/useWalletProviders/useWalletProviders.d.ts.map +1 -1
  54. package/dist/index.d.ts +1 -1
  55. package/dist/index.d.ts.map +1 -1
  56. package/dist/index.js +2 -2
  57. package/dist/index.js.map +4 -4
  58. package/dist/pages/ConfirmSwapPage.d.ts.map +1 -1
  59. package/dist/pages/Home.d.ts.map +1 -1
  60. package/dist/pages/SelectSwapItemsPage.d.ts.map +1 -1
  61. package/dist/store/app.d.ts +4 -2
  62. package/dist/store/app.d.ts.map +1 -1
  63. package/dist/store/quote.d.ts.map +1 -1
  64. package/dist/store/slices/config.d.ts +0 -4
  65. package/dist/store/slices/config.d.ts.map +1 -1
  66. package/dist/store/slices/data.d.ts.map +1 -1
  67. package/dist/store/ui.d.ts +0 -4
  68. package/dist/store/ui.d.ts.map +1 -1
  69. package/dist/store/wallets.d.ts +66 -0
  70. package/dist/store/wallets.d.ts.map +1 -0
  71. package/dist/types/config.d.ts +9 -7
  72. package/dist/types/config.d.ts.map +1 -1
  73. package/dist/types/quote.d.ts +17 -8
  74. package/dist/types/quote.d.ts.map +1 -1
  75. package/dist/types/wallets.d.ts +7 -3
  76. package/dist/types/wallets.d.ts.map +1 -1
  77. package/dist/utils/providers.d.ts +9 -8
  78. package/dist/utils/providers.d.ts.map +1 -1
  79. package/dist/utils/quote.d.ts +6 -5
  80. package/dist/utils/quote.d.ts.map +1 -1
  81. package/dist/utils/settings.d.ts +0 -1
  82. package/dist/utils/settings.d.ts.map +1 -1
  83. package/dist/utils/swap.d.ts +5 -5
  84. package/dist/utils/swap.d.ts.map +1 -1
  85. package/dist/utils/wallets.d.ts +14 -12
  86. package/dist/utils/wallets.d.ts.map +1 -1
  87. package/dist/widget-embedded.build.json +1 -1
  88. package/package.json +9 -9
  89. package/src/QueueManager.tsx +11 -17
  90. package/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx +24 -5
  91. package/src/components/ConfirmWalletsModal/WalletList.tsx +7 -10
  92. package/src/components/Layout/Layout.tsx +3 -1
  93. package/src/components/Quote/Quote.tsx +3 -22
  94. package/src/components/Quote/Quote.types.ts +0 -2
  95. package/src/components/Quote/QuoteCostDetails.styles.ts +1 -0
  96. package/src/components/Quote/QuoteCostDetails.tsx +4 -23
  97. package/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts +22 -42
  98. package/src/components/Quotes/Quotes.tsx +3 -2
  99. package/src/components/StatefulConnectModal/StatefulConnectModal.tsx +1 -1
  100. package/src/components/SwapDetails/SwapDetails.tsx +6 -14
  101. package/src/components/SwapDetailsAlerts/SwapDetailsAlerts.types.ts +1 -1
  102. package/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx +13 -26
  103. package/src/components/TokenList/TokenList.tsx +27 -4
  104. package/src/components/WalletStatefulConnect/DerivationPath.helpers.ts +1 -2
  105. package/src/components/WalletStatefulConnect/Namespaces.tsx +38 -31
  106. package/src/components/WalletStatefulConnect/Namespaces.types.tsx +1 -1
  107. package/src/constants/quote.ts +0 -25
  108. package/src/constants/warnings.ts +26 -0
  109. package/src/containers/ExpandedQuotes/ExpandedQuotes.styles.ts +0 -1
  110. package/src/containers/ExpandedQuotes/ExpandedQuotes.tsx +1 -1
  111. package/src/containers/Inputs/Inputs.tsx +7 -20
  112. package/src/containers/QuoteInfo/QuoteInfo.tsx +9 -3
  113. package/src/containers/Wallets/Wallets.tsx +16 -82
  114. package/src/containers/WidgetInfo/WidgetInfo.helpers.ts +2 -2
  115. package/src/containers/WidgetInfo/WidgetInfo.tsx +8 -10
  116. package/src/containers/WidgetInfo/WidgetInfo.types.ts +3 -3
  117. package/src/hooks/useConfirmSwap/useConfirmSwap.helpers.ts +66 -29
  118. package/src/hooks/useConfirmSwap/useConfirmSwap.ts +15 -10
  119. package/src/hooks/useFetchApiConfig.ts +1 -5
  120. package/src/hooks/useFetchCustomToken.ts +0 -5
  121. package/src/hooks/useObserveBalanceChanges/index.ts +1 -0
  122. package/src/hooks/useObserveBalanceChanges/useObserveBalanceChanges.ts +68 -0
  123. package/src/hooks/useStatefulConnect/useStatefulConnect.ts +17 -50
  124. package/src/hooks/useStatefulConnect/useStatefulConnect.types.ts +5 -3
  125. package/src/hooks/useSubscribeToWidgetEvents/useSubscribeToWidgetEvents.ts +6 -7
  126. package/src/hooks/useSwapInput.ts +11 -3
  127. package/src/hooks/useWalletList.ts +8 -6
  128. package/src/hooks/useWalletProviders/useWalletProviders.ts +12 -8
  129. package/src/index.ts +1 -1
  130. package/src/pages/ConfirmSwapPage.tsx +15 -7
  131. package/src/pages/Home.tsx +3 -5
  132. package/src/pages/SelectSwapItemsPage.tsx +2 -1
  133. package/src/store/app.ts +4 -4
  134. package/src/store/quote.ts +13 -3
  135. package/src/store/slices/config.ts +0 -76
  136. package/src/store/slices/data.test.ts +1 -23
  137. package/src/store/slices/data.ts +2 -3
  138. package/src/store/ui.ts +0 -6
  139. package/src/store/wallets.ts +268 -0
  140. package/src/types/config.ts +9 -8
  141. package/src/types/quote.ts +24 -10
  142. package/src/types/wallets.ts +7 -3
  143. package/src/utils/providers.ts +36 -88
  144. package/src/utils/quote.ts +45 -57
  145. package/src/utils/settings.ts +0 -4
  146. package/src/utils/swap.ts +37 -56
  147. package/src/utils/wallets.ts +141 -76
  148. package/dist/store/slices/types.d.ts +0 -6
  149. package/dist/store/slices/types.d.ts.map +0 -1
  150. package/dist/store/slices/wallets.d.ts +0 -80
  151. package/dist/store/slices/wallets.d.ts.map +0 -1
  152. package/dist/store/utils/wallets.d.ts +0 -17
  153. package/dist/store/utils/wallets.d.ts.map +0 -1
  154. package/src/store/slices/types.ts +0 -9
  155. package/src/store/slices/wallets.ts +0 -577
  156. package/src/store/utils/wallets.ts +0 -111
@@ -7,18 +7,27 @@ import type {
7
7
  SelectedQuote,
8
8
  Wallet,
9
9
  } from '../../types';
10
- import type BigNumber from 'bignumber.js';
11
- import type { BlockchainMeta, SwapResult } from 'rango-sdk';
10
+ import type { BlockchainMeta, SwapResult, Token } from 'rango-sdk';
12
11
 
13
12
  import { errorMessages } from '../../constants/errors';
14
- import { QuoteErrorType } from '../../types';
15
- import { generateQuoteWarnings } from '../../utils/quote';
13
+ import { QuoteErrorType, QuoteUpdateType } from '../../types';
14
+ import { numberToString } from '../../utils/numbers';
15
+ import {
16
+ generateQuoteWarnings,
17
+ getPriceImpact,
18
+ isNumberOfSwapsChanged,
19
+ isQuoteChanged,
20
+ isQuoteInternalCoinsUpdated,
21
+ isQuoteSwappersUpdated,
22
+ } from '../../utils/quote';
16
23
  import {
17
24
  checkSlippageErrors,
18
25
  generateBalanceWarnings,
19
26
  getLimitErrorMessage,
20
27
  getMinRequiredSlippage,
28
+ getQuoteOutputAmount,
21
29
  hasLimitError,
30
+ isOutputAmountChangedALot,
22
31
  } from '../../utils/swap';
23
32
 
24
33
  /**
@@ -73,44 +82,72 @@ export function getQuoteError(swaps: SwapResult[]): QuoteErrorResponse | null {
73
82
  return null;
74
83
  }
75
84
 
76
- export function generateWarnings(params: {
77
- currentQuote: SelectedQuote;
78
- previousQuote?: SelectedQuote;
79
- meta: { blockchains: BlockchainMeta[] };
80
- selectedWallets: Wallet[];
81
- userSlippage: number;
82
- inputUsdValue: BigNumber | null;
83
- findToken: FindToken;
84
- }): ConfirmSwapWarnings {
85
- const {
86
- currentQuote,
87
- previousQuote,
88
- meta,
89
- selectedWallets,
90
- userSlippage,
91
- findToken,
92
- } = params;
93
-
85
+ export function generateWarnings(
86
+ previousQuote: SelectedQuote | undefined,
87
+ currentQuote: SelectedQuote,
88
+ params: {
89
+ fromToken: Token;
90
+ toToken: Token;
91
+ meta: { blockchains: BlockchainMeta[] };
92
+ selectedWallets: Wallet[];
93
+ userSlippage: number;
94
+ findToken: FindToken;
95
+ }
96
+ ): ConfirmSwapWarnings {
97
+ let quoteChanged = false;
98
+ if (previousQuote) {
99
+ quoteChanged = isQuoteChanged(previousQuote, currentQuote);
100
+ }
94
101
  const output: ConfirmSwapWarnings = {
95
102
  quote: null,
103
+ quoteUpdate: null,
96
104
  balance: null,
97
105
  };
98
106
 
99
- const quoteWarning = generateQuoteWarnings({
100
- previousQuote,
101
- currentQuote,
102
- findToken,
103
- userSlippage,
107
+ const quoteWarning = generateQuoteWarnings(currentQuote, {
108
+ fromToken: params.fromToken,
109
+ toToken: params.toToken,
110
+ findToken: params.findToken,
111
+ userSlippage: params.userSlippage,
104
112
  });
105
113
 
106
114
  if (quoteWarning) {
107
115
  output.quote = quoteWarning;
108
116
  }
109
117
 
118
+ if (previousQuote && quoteChanged) {
119
+ if (isOutputAmountChangedALot(previousQuote, currentQuote)) {
120
+ output.quoteUpdate = {
121
+ type: QuoteUpdateType.QUOTE_AND_OUTPUT_AMOUNT_UPDATED,
122
+ newOutputAmount: numberToString(getQuoteOutputAmount(currentQuote)),
123
+ percentageChange: numberToString(
124
+ getPriceImpact(
125
+ getQuoteOutputAmount(previousQuote) ?? '',
126
+ getQuoteOutputAmount(currentQuote) ?? ''
127
+ ),
128
+ null,
129
+ 2
130
+ ),
131
+ };
132
+ } else if (isNumberOfSwapsChanged(previousQuote, currentQuote)) {
133
+ output.quoteUpdate = {
134
+ type: QuoteUpdateType.QUOTE_UPDATED,
135
+ };
136
+ } else if (isQuoteSwappersUpdated(previousQuote, currentQuote)) {
137
+ output.quoteUpdate = {
138
+ type: QuoteUpdateType.QUOTE_SWAPPERS_UPDATED,
139
+ };
140
+ } else if (isQuoteInternalCoinsUpdated(previousQuote, currentQuote)) {
141
+ output.quoteUpdate = {
142
+ type: QuoteUpdateType.QUOTE_COINS_UPDATED,
143
+ };
144
+ }
145
+ }
146
+
110
147
  const balanceWarnings = generateBalanceWarnings(
111
148
  currentQuote,
112
- selectedWallets,
113
- meta.blockchains
149
+ params.selectedWallets,
150
+ params.meta.blockchains
114
151
  );
115
152
 
116
153
  const enoughBalance = balanceWarnings.length === 0;
@@ -21,10 +21,10 @@ export function useConfirmSwap(): ConfirmSwap {
21
21
  fromToken,
22
22
  toToken,
23
23
  inputAmount,
24
- inputUsdValue,
25
24
  setSelectedQuote,
26
25
  selectedQuote: initialQuote,
27
26
  customDestination: customDestinationFromStore,
27
+ setQuoteWarningsConfirmed,
28
28
  resetAlerts,
29
29
  } = useQuoteStore();
30
30
 
@@ -95,16 +95,21 @@ export function useConfirmSwap(): ConfirmSwap {
95
95
  disabledSwappersGroups: disabledLiquiditySources,
96
96
  };
97
97
 
98
- const confirmSwapWarnings = generateWarnings({
99
- previousQuote: initialQuote ?? undefined,
98
+ const confirmSwapWarnings = generateWarnings(
99
+ initialQuote ?? undefined,
100
100
  currentQuote,
101
- meta: { blockchains },
102
- selectedWallets,
103
- userSlippage,
104
- inputUsdValue,
105
- findToken,
106
- });
107
-
101
+ {
102
+ fromToken,
103
+ toToken,
104
+ meta: { blockchains },
105
+ findToken,
106
+ selectedWallets,
107
+ userSlippage,
108
+ }
109
+ );
110
+ if (confirmSwapWarnings.quoteUpdate) {
111
+ setQuoteWarningsConfirmed(false);
112
+ }
108
113
  resetAlerts();
109
114
 
110
115
  const proceedAnyway = !!confirmSwapWarnings.balance;
@@ -6,9 +6,6 @@ export type Watermark = 'NONE' | 'FULL';
6
6
  type ConfigResponse = {
7
7
  config: {
8
8
  watermark: Watermark;
9
- banners: {
10
- profile: boolean;
11
- };
12
9
  };
13
10
  };
14
11
 
@@ -17,7 +14,7 @@ interface UseFetchApiConfig {
17
14
  }
18
15
 
19
16
  export function useFetchApiConfig(): UseFetchApiConfig {
20
- const { setWatermark, setShowProfileBanner } = useUiStore();
17
+ const { setWatermark } = useUiStore();
21
18
 
22
19
  const fetchApiConfig: UseFetchApiConfig['fetchApiConfig'] = async () => {
23
20
  const response = await fetch(
@@ -31,7 +28,6 @@ export function useFetchApiConfig(): UseFetchApiConfig {
31
28
  const data: ConfigResponse = await response.json();
32
29
 
33
30
  setWatermark(data.config.watermark);
34
- setShowProfileBanner(data.config.banners.profile);
35
31
  };
36
32
  return { fetchApiConfig };
37
33
  }
@@ -103,11 +103,6 @@ export function useFetchCustomToken(): UseFetchCustomToken {
103
103
 
104
104
  return token;
105
105
  } catch (error: any) {
106
- if (error?.code === 'ERR_BAD_REQUEST') {
107
- const errorMessage = produceErrorMessage('not-found', blockchain);
108
- setError(errorMessage);
109
- return undefined;
110
- }
111
106
  setError(undefined);
112
107
  throw new Error(error.message);
113
108
  } finally {
@@ -0,0 +1 @@
1
+ export { useObserveBalanceChanges } from './useObserveBalanceChanges';
@@ -0,0 +1,68 @@
1
+ import type { WalletEventData } from '../../types';
2
+
3
+ import { useWallets } from '@rango-dev/wallets-react';
4
+ import { useEffect, useRef, useState } from 'react';
5
+
6
+ import { widgetEventEmitter } from '../../services/eventEmitter';
7
+ import { useWalletsStore } from '../../store/wallets';
8
+ import { WalletEventTypes, WidgetEvents } from '../../types';
9
+
10
+ // A hook to listen for and detect changes in balances on a specific blockchain.
11
+ export function useObserveBalanceChanges(selectedBlockchain?: string) {
12
+ const { connectedWallets } = useWalletsStore();
13
+ const { getWalletInfo } = useWallets();
14
+ const prevFetchingBalanceWallets = useRef<string[]>([]);
15
+ // The "balanceKey" will be updated and incremented after each change in the balance for a blockchain.
16
+ const [balanceKey, setBalanceKey] = useState(0);
17
+
18
+ useEffect(() => {
19
+ const handleWalletEvent = (event: WalletEventData) => {
20
+ if (event.type === WalletEventTypes.DISCONNECT) {
21
+ const walletInfo = getWalletInfo(event.payload.walletType);
22
+ const blockchainSupported = walletInfo.supportedChains.some(
23
+ (chain) => chain.name === selectedBlockchain
24
+ );
25
+
26
+ if (blockchainSupported) {
27
+ setBalanceKey((prev) => prev + 1);
28
+ }
29
+ }
30
+ };
31
+
32
+ widgetEventEmitter.on(WidgetEvents.WalletEvent, handleWalletEvent);
33
+
34
+ if (!selectedBlockchain) {
35
+ return setBalanceKey((prev) => prev + 1);
36
+ }
37
+
38
+ const supportedWallets = connectedWallets.filter(
39
+ (wallet) => wallet.chain === selectedBlockchain
40
+ );
41
+
42
+ supportedWallets.forEach((wallet) => {
43
+ const { walletType } = wallet;
44
+ const walletIsAlreadyFetching =
45
+ prevFetchingBalanceWallets.current.includes(walletType);
46
+
47
+ /**
48
+ * Watching for changes in "wallet.balances.length" is not accurate.
49
+ * Additionally, checking the equality of previous and current balances for a specific blockchain is resource-intensive, so we avoid these methods.
50
+ */
51
+ if (wallet.loading && !walletIsAlreadyFetching) {
52
+ prevFetchingBalanceWallets.current =
53
+ prevFetchingBalanceWallets.current.concat(walletType);
54
+ } else if (!wallet.loading && walletIsAlreadyFetching) {
55
+ prevFetchingBalanceWallets.current =
56
+ prevFetchingBalanceWallets.current.filter(
57
+ (prevWallet) => prevWallet !== walletType
58
+ );
59
+ setBalanceKey((prev) => prev + 1);
60
+ }
61
+ });
62
+
63
+ return () =>
64
+ widgetEventEmitter.off(WidgetEvents.WalletEvent, handleWalletEvent);
65
+ }, [connectedWallets, selectedBlockchain, getWalletInfo]);
66
+
67
+ return { balanceKey };
68
+ }
@@ -1,8 +1,10 @@
1
1
  import type { HandleConnectOptions, Result } from './useStatefulConnect.types';
2
2
  import type { WalletInfoWithExtra } from '../../types';
3
- import type { ExtendedModalWalletInfo } from '../../utils/wallets';
4
- import type { Namespace } from '@rango-dev/wallets-core/namespaces/common';
5
- import type { NamespaceData, WalletType } from '@rango-dev/wallets-shared';
3
+ import type {
4
+ Namespace,
5
+ NamespaceData,
6
+ WalletType,
7
+ } from '@rango-dev/wallets-shared';
6
8
 
7
9
  import { WalletState } from '@rango-dev/ui';
8
10
  import { useWallets } from '@rango-dev/wallets-react';
@@ -59,11 +61,7 @@ export function useStatefulConnect(): UseStatefulConnect {
59
61
  });
60
62
 
61
63
  try {
62
- const legacyNamespacesInput = namespaces?.map((namespaceInput) => ({
63
- ...namespaceInput,
64
- network: undefined,
65
- }));
66
- await connect(type, legacyNamespacesInput);
64
+ await connect(type, undefined, namespaces);
67
65
 
68
66
  return { status: ResultStatus.Connected };
69
67
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -77,7 +75,7 @@ export function useStatefulConnect(): UseStatefulConnect {
77
75
  };
78
76
 
79
77
  const handleConnect = async (
80
- wallet: ExtendedModalWalletInfo,
78
+ wallet: WalletInfoWithExtra,
81
79
  options?: HandleConnectOptions
82
80
  ): Promise<{
83
81
  status: ResultStatus;
@@ -85,60 +83,31 @@ export function useStatefulConnect(): UseStatefulConnect {
85
83
  const isDisconnected = wallet.state === WalletState.DISCONNECTED;
86
84
 
87
85
  if (isDisconnected) {
88
- // Legacy and hub have different structure to check wether we need to show namespace or not.
89
-
90
- // Hub
91
- const isHub = !!wallet.isHub;
92
- if (isHub) {
93
- const detachedInstances = wallet.properties?.find(
94
- (item) => item.name === 'detached'
95
- );
96
- const needsNamespace =
97
- detachedInstances && wallet.state !== 'connected';
98
-
99
- if (needsNamespace) {
100
- dispatch({
101
- type: 'needsNamespace',
102
- payload: {
103
- targetWallet: wallet,
104
- },
105
- });
106
- return { status: ResultStatus.Namespace };
107
- }
108
- }
109
-
110
- /*
111
- * Legacy
112
- *
113
- * For legacy there are 3 states:
114
- * 1. a wallet doesn't have any namespace defined, we call the connect.
115
- * 2. a wallet has more than two namespaces, we should show namepsace modal, and in that place user will be checked to needs derivation path or not.
116
- * 3. a wallet has exactly one namespacesape, in this case we check if that needs derivation or not, if it needs we will do it here by dispatching the action accordingly.
117
- */
118
- if (!wallet.needsNamespace) {
86
+ if (!wallet.namespaces) {
119
87
  return await runConnect(wallet.type, undefined, options);
120
88
  }
121
89
 
122
- const needsNamespace = wallet.needsNamespace.data.length > 1;
90
+ const needsNamespace = wallet.namespaces.length > 1;
123
91
  const needsDerivationPath = wallet.needsDerivationPath;
124
92
 
125
93
  if (needsNamespace) {
126
94
  dispatch({
127
95
  type: 'needsNamespace',
128
96
  payload: {
129
- targetWallet: wallet,
97
+ providerType: wallet.type,
98
+ providerImage: wallet.image,
99
+ availableNamespaces: wallet.namespaces,
100
+ singleNamespace: wallet.singleNamespace,
130
101
  },
131
102
  });
132
103
  return { status: ResultStatus.Namespace };
133
104
  } else if (needsDerivationPath) {
134
- const namespace = wallet.needsNamespace.data[0];
135
-
136
105
  dispatch({
137
106
  type: 'needsDerivationPath',
138
107
  payload: {
139
108
  providerType: wallet.type,
140
109
  providerImage: wallet.image,
141
- namespace: namespace.value,
110
+ namespace: wallet.namespaces[0],
142
111
  },
143
112
  });
144
113
  return { status: ResultStatus.DerivationPath };
@@ -146,9 +115,7 @@ export function useStatefulConnect(): UseStatefulConnect {
146
115
 
147
116
  return await runConnect(
148
117
  wallet.type,
149
- wallet.needsNamespace?.data.map((namespace) => ({
150
- namespace: namespace.value,
151
- })),
118
+ wallet.namespaces.map((namespace) => ({ namespace })),
152
119
  options
153
120
  );
154
121
  }
@@ -165,7 +132,7 @@ export function useStatefulConnect(): UseStatefulConnect {
165
132
  wallet: WalletInfoWithExtra,
166
133
  selectedNamespaces: Namespace[]
167
134
  ): Promise<Result> => {
168
- const isSingleNamespace = wallet.needsNamespace?.selection === 'single';
135
+ const isSingleNamespace = wallet.singleNamespace;
169
136
  const needsDerivationPath = wallet.needsDerivationPath;
170
137
  const firstSelectedNamespace = selectedNamespaces[0];
171
138
 
@@ -205,7 +172,7 @@ export function useStatefulConnect(): UseStatefulConnect {
205
172
  );
206
173
  }
207
174
 
208
- const type = connectState.namespace.targetWallet.type;
175
+ const type = connectState.namespace.providerType;
209
176
  const namespaces = selectedNamespaces.map((namespace) => ({
210
177
  namespace,
211
178
  }));
@@ -1,5 +1,4 @@
1
- import type { ExtendedModalWalletInfo } from '../../utils/wallets';
2
- import type { Namespace } from '@rango-dev/wallets-core/namespaces/common';
1
+ import type { Namespace } from '@rango-dev/wallets-shared';
3
2
 
4
3
  export interface HandleConnectOptions {
5
4
  // To have a switch between connect and disconnect when user is clicking on a button, this option can be helpful.
@@ -7,7 +6,10 @@ export interface HandleConnectOptions {
7
6
  }
8
7
 
9
8
  export interface NeedsNamespacesState {
10
- targetWallet: ExtendedModalWalletInfo;
9
+ providerType: string;
10
+ providerImage: string;
11
+ availableNamespaces?: Namespace[];
12
+ singleNamespace?: boolean;
11
13
  }
12
14
 
13
15
  export interface NeedsDerivationPathState {
@@ -12,10 +12,13 @@ import { useEffect } from 'react';
12
12
  import { eventEmitter } from '../../services/eventEmitter';
13
13
  import { useAppStore } from '../../store/AppStore';
14
14
  import { useNotificationStore } from '../../store/notification';
15
+ import { useWalletsStore } from '../../store/wallets';
15
16
 
16
17
  export function useSubscribeToWidgetEvents() {
18
+ const connectedWallets = useWalletsStore.use.connectedWallets();
19
+ const getWalletsDetails = useWalletsStore.use.getWalletsDetails();
17
20
  const setNotification = useNotificationStore.use.setNotification();
18
- const { connectedWallets, fetchBalances } = useAppStore();
21
+ const { findToken } = useAppStore();
19
22
 
20
23
  useEffect(() => {
21
24
  const handleStepEvent = (widgetEvent: StepEventData) => {
@@ -36,12 +39,8 @@ export function useSubscribeToWidgetEvents() {
36
39
  (wallet) => wallet.chain === step?.toBlockchain
37
40
  );
38
41
 
39
- if (fromAccount) {
40
- void fetchBalances([fromAccount]);
41
- }
42
- if (toAccount) {
43
- void fetchBalances([toAccount]);
44
- }
42
+ fromAccount && getWalletsDetails([fromAccount], findToken);
43
+ toAccount && getWalletsDetails([toAccount], findToken);
45
44
  }
46
45
 
47
46
  setNotification(event, route);
@@ -4,12 +4,15 @@ import { useCallback, useEffect, useRef, useState } from 'react';
4
4
 
5
5
  import { useAppStore } from '../store/AppStore';
6
6
  import { useQuoteStore } from '../store/quote';
7
+ import { useWalletsStore } from '../store/wallets';
7
8
  import { QuoteErrorType } from '../types';
8
9
  import { debounce } from '../utils/common';
9
10
  import { isPositiveNumber } from '../utils/numbers';
10
11
  import {
11
12
  generateQuoteWarnings,
12
13
  getDefaultQuote,
14
+ getQuoteFromTokenUsdPrice,
15
+ getQuoteToTokenUsdPrice,
13
16
  sortQuotesBy,
14
17
  } from '../utils/quote';
15
18
  import { isRoutingEnabled } from '../utils/settings';
@@ -47,7 +50,7 @@ export function useSwapInput({
47
50
  const { fetch: fetchQuote, cancelFetch } = useFetchAllQuotes();
48
51
  const { excludeLiquiditySources: configExcludeLiquiditySources, routing } =
49
52
  useAppStore().config;
50
- const { connectedWallets } = useAppStore();
53
+ const connectedWallets = useWalletsStore.use.connectedWallets();
51
54
 
52
55
  const {
53
56
  fromToken,
@@ -154,10 +157,15 @@ export function useSwapInput({
154
157
  requestId: quote?.requestId || '',
155
158
  swaps: quote?.swaps,
156
159
  });
160
+ const outputUsdValue =
161
+ getQuoteToTokenUsdPrice(quote) || toToken?.usdPrice;
162
+ const inputUsdValue =
163
+ getQuoteFromTokenUsdPrice(quote) || fromToken?.usdPrice;
157
164
  const quoteWarning =
158
165
  quote &&
159
- generateQuoteWarnings({
160
- currentQuote: quote,
166
+ generateQuoteWarnings(quote, {
167
+ fromToken: { ...fromToken, usdPrice: inputUsdValue },
168
+ toToken: { ...toToken, usdPrice: outputUsdValue },
161
169
  userSlippage,
162
170
  findToken,
163
171
  });
@@ -12,6 +12,7 @@ import {
12
12
  import { useCallback, useEffect } from 'react';
13
13
 
14
14
  import { useAppStore } from '../store/AppStore';
15
+ import { useWalletsStore } from '../store/wallets';
15
16
  import { configWalletsToWalletName } from '../utils/providers';
16
17
  import {
17
18
  hashWalletsState,
@@ -22,6 +23,8 @@ import {
22
23
 
23
24
  import { useStatefulConnect } from './useStatefulConnect/useStatefulConnect';
24
25
 
26
+ const ALL_SUPPORTED_WALLETS = Object.values(WalletTypes);
27
+
25
28
  interface Params {
26
29
  chain?: string;
27
30
  }
@@ -40,22 +43,21 @@ interface API {
40
43
  */
41
44
  export function useWalletList(params?: Params): API {
42
45
  const { chain } = params || {};
43
- const { config, connectedWallets, getAvailableProviders } = useAppStore();
46
+ const { config } = useAppStore();
44
47
  const { state, getWalletInfo } = useWallets();
48
+ const { connectedWallets } = useWalletsStore();
45
49
  const blockchains = useAppStore().blockchains();
46
50
  const { handleDisconnect } = useStatefulConnect();
47
51
 
48
52
  /** It can be what has been set by widget config or as a fallback we use all the supported wallets by our library */
49
- const listAvailableWalletTypes = configWalletsToWalletName(
50
- getAvailableProviders(),
51
- {
53
+ const listAvailableWalletTypes =
54
+ configWalletsToWalletName(config?.wallets, {
52
55
  trezorManifest: config?.trezorManifest,
53
56
  walletConnectProjectId: config?.walletConnectProjectId,
54
57
  walletConnectListedDesktopWalletLink:
55
58
  config.__UNSTABLE_OR_INTERNAL__?.walletConnectListedDesktopWalletLink,
56
59
  tonConnect: config.tonConnect,
57
- }
58
- );
60
+ }) || ALL_SUPPORTED_WALLETS;
59
61
 
60
62
  let wallets = mapWalletTypesToWalletInfo(
61
63
  state,
@@ -1,30 +1,34 @@
1
1
  import type { WidgetConfig } from '../../types';
2
2
  import type { ProvidersOptions } from '../../utils/providers';
3
+ import type { ProviderInterface } from '@rango-dev/wallets-react';
3
4
 
4
5
  import { useEffect } from 'react';
5
6
 
6
- import { useAppStore } from '../../store/AppStore';
7
+ import { useWalletsStore } from '../../store/wallets';
8
+ import { matchAndGenerateProviders } from '../../utils/providers';
7
9
 
8
10
  import { hashProviders } from './useWalletProviders.helpers';
9
11
 
10
12
  export function useWalletProviders(
11
- configWallets: WidgetConfig['wallets'],
13
+ providers: WidgetConfig['wallets'],
12
14
  options?: ProvidersOptions
13
15
  ) {
14
- const { clearConnectedWallet, getAvailableProviders, buildAndSetProviders } =
15
- useAppStore();
16
- const providers = getAvailableProviders();
16
+ const clearConnectedWallet = useWalletsStore.use.clearConnectedWallet();
17
+ let generateProviders: ProviderInterface[] = matchAndGenerateProviders(
18
+ providers,
19
+ options
20
+ );
17
21
 
18
22
  useEffect(() => {
19
23
  clearConnectedWallet();
20
- buildAndSetProviders();
24
+ generateProviders = matchAndGenerateProviders(providers, options);
21
25
  }, [
22
- hashProviders(configWallets ?? []),
26
+ hashProviders(providers ?? []),
23
27
  options?.walletConnectProjectId,
24
28
  options?.walletConnectListedDesktopWalletLink,
25
29
  ]);
26
30
 
27
31
  return {
28
- providers,
32
+ providers: generateProviders,
29
33
  };
30
34
  }
package/src/index.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { WidgetProps } from './containers/Widget';
2
- import type { ConnectedWallet } from './store/slices/wallets';
2
+ import type { ConnectedWallet } from './store/wallets';
3
3
  import type {
4
4
  BlockchainAndTokenConfig,
5
5
  QuoteEventData,
@@ -24,12 +24,12 @@ import { RefreshButton } from '../components/HeaderButtons/RefreshButton';
24
24
  import { Layout, PageContainer } from '../components/Layout';
25
25
  import { QuoteWarningsAndErrors } from '../components/QuoteWarningsAndErrors';
26
26
  import { navigationRoutes } from '../constants/navigationRoutes';
27
+ import { getQuoteUpdateWarningMessage } from '../constants/warnings';
27
28
  import { QuoteInfo } from '../containers/QuoteInfo';
28
29
  import { useConfirmSwap } from '../hooks/useConfirmSwap';
29
30
  import { useAppStore } from '../store/AppStore';
30
31
  import { useQuoteStore } from '../store/quote';
31
32
  import { useUiStore } from '../store/ui';
32
- import { isQuoteWarningConfirmationRequired } from '../utils/quote';
33
33
  import { joinList } from '../utils/ui';
34
34
 
35
35
  const Buttons = styled('div', {
@@ -133,12 +133,7 @@ export function ConfirmSwapPage() {
133
133
  };
134
134
 
135
135
  const onStartConfirmSwap = async () => {
136
- const shouldShowWarningModal =
137
- confirmSwapResult.warnings?.quote &&
138
- isQuoteWarningConfirmationRequired(confirmSwapResult.warnings.quote) &&
139
- !quoteWarningsConfirmed;
140
-
141
- if (shouldShowWarningModal) {
136
+ if (confirmSwapResult?.warnings?.quote && !quoteWarningsConfirmed) {
142
137
  setShowQuoteWarningModal(true);
143
138
  } else {
144
139
  await onConfirm();
@@ -201,6 +196,19 @@ export function ConfirmSwapPage() {
201
196
  alerts.push(<Alert type="error" variant="alarm" title={dbErrorMessage} />);
202
197
  }
203
198
 
199
+ if (confirmSwapResult.warnings?.quoteUpdate) {
200
+ alerts.push(
201
+ <Alert
202
+ variant="alarm"
203
+ type="warning"
204
+ title={
205
+ confirmSwapResult.warnings.quoteUpdate &&
206
+ getQuoteUpdateWarningMessage(confirmSwapResult.warnings.quoteUpdate)
207
+ }
208
+ />
209
+ );
210
+ }
211
+
204
212
  if (quoteWarning || quoteError) {
205
213
  const settings_url = `../${navigationRoutes.settings}`;
206
214
  alerts.push(
@@ -19,6 +19,7 @@ import { useSwapInput } from '../hooks/useSwapInput';
19
19
  import { useAppStore } from '../store/AppStore';
20
20
  import { useQuoteStore } from '../store/quote';
21
21
  import { useUiStore } from '../store/ui';
22
+ import { useWalletsStore } from '../store/wallets';
22
23
  import { UiEventTypes } from '../types';
23
24
  import { isVariantExpandable } from '../utils/configs';
24
25
  import { emitPreventableEvent } from '../utils/events';
@@ -54,12 +55,9 @@ export function Home() {
54
55
  const { isLargeScreen, isExtraLargeScreen } = useScreenDetect();
55
56
 
56
57
  const { fetch: fetchQuote, loading } = useSwapInput({ refetchQuote });
57
- const {
58
- config,
59
- fetchStatus: fetchMetaStatus,
60
- connectedWallets,
61
- } = useAppStore();
58
+ const { config, fetchStatus: fetchMetaStatus } = useAppStore();
62
59
 
60
+ const { connectedWallets } = useWalletsStore();
63
61
  const { isActiveTab } = useUiStore();
64
62
  const [showQuoteWarningModal, setShowQuoteWarningModal] = useState(false);
65
63