@dynamic-labs/sdk-react-core 4.5.1 → 4.5.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 (79) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/package.cjs +2 -2
  3. package/package.js +2 -2
  4. package/package.json +12 -12
  5. package/src/lib/components/NetworkPicker/NetworkPicker.cjs +11 -40
  6. package/src/lib/components/NetworkPicker/NetworkPicker.d.ts +2 -6
  7. package/src/lib/components/NetworkPicker/NetworkPicker.js +12 -41
  8. package/src/lib/components/NetworkPicker/components/NetworkControl/NetworkControl.cjs +6 -8
  9. package/src/lib/components/NetworkPicker/components/NetworkControl/NetworkControl.d.ts +2 -4
  10. package/src/lib/components/NetworkPicker/components/NetworkControl/NetworkControl.js +6 -8
  11. package/src/lib/components/NetworkPicker/components/NetworkDropdown/NetworkDropdown.cjs +67 -0
  12. package/src/lib/components/NetworkPicker/components/NetworkDropdown/NetworkDropdown.d.ts +14 -0
  13. package/src/lib/components/NetworkPicker/components/NetworkDropdown/NetworkDropdown.js +63 -0
  14. package/src/lib/components/NetworkPicker/components/NetworkDropdown/index.d.ts +1 -0
  15. package/src/lib/components/NetworkPicker/components/{EvmNetworkControl/EvmNetworkControl.cjs → NetworkSwitchControl/NetworkSwitchControl.cjs} +27 -36
  16. package/src/lib/components/NetworkPicker/components/NetworkSwitchControl/NetworkSwitchControl.d.ts +16 -0
  17. package/src/lib/components/NetworkPicker/components/{EvmNetworkControl/EvmNetworkControl.js → NetworkSwitchControl/NetworkSwitchControl.js} +27 -35
  18. package/src/lib/components/NetworkPicker/components/NetworkSwitchControl/index.d.ts +1 -0
  19. package/src/lib/components/Portal/Portal.cjs +3 -2
  20. package/src/lib/components/Portal/Portal.js +3 -2
  21. package/src/lib/locale/en/translation.cjs +13 -29
  22. package/src/lib/locale/en/translation.d.ts +11 -27
  23. package/src/lib/locale/en/translation.js +13 -29
  24. package/src/lib/shared/assets/index.d.ts +1 -0
  25. package/src/lib/shared/assets/{currency.cjs → wallet-with-sunglasses.cjs} +14 -26
  26. package/src/lib/shared/assets/wallet-with-sunglasses.js +34 -0
  27. package/src/lib/styles/index.shadow.cjs +1 -1
  28. package/src/lib/styles/index.shadow.js +1 -1
  29. package/src/lib/utils/functions/isNetworkUnsupported/isNetworkUnsupported.cjs +2 -4
  30. package/src/lib/utils/functions/isNetworkUnsupported/isNetworkUnsupported.d.ts +2 -2
  31. package/src/lib/utils/functions/isNetworkUnsupported/isNetworkUnsupported.js +2 -4
  32. package/src/lib/views/CollectUserDataView/CollectUserDataView.cjs +2 -4
  33. package/src/lib/views/CollectUserDataView/CollectUserDataView.js +2 -4
  34. package/src/lib/views/NetworkNotSupported/NetworkNotSupported.cjs +3 -4
  35. package/src/lib/views/NetworkNotSupported/NetworkNotSupported.js +3 -4
  36. package/src/lib/widgets/DynamicWidget/components/ActiveWalletInformation/ActiveWalletInformation.cjs +6 -9
  37. package/src/lib/widgets/DynamicWidget/components/ActiveWalletInformation/ActiveWalletInformation.js +7 -10
  38. package/src/lib/widgets/DynamicWidget/components/DynamicNav/DynamicNav.cjs +2 -6
  39. package/src/lib/widgets/DynamicWidget/components/DynamicNav/DynamicNav.js +2 -6
  40. package/src/lib/widgets/DynamicWidget/views/ReceiveExternalWalletFunds/ReceiveExternalWalletFunds.cjs +98 -49
  41. package/src/lib/widgets/DynamicWidget/views/ReceiveExternalWalletFunds/ReceiveExternalWalletFunds.js +94 -45
  42. package/src/lib/widgets/DynamicWidget/views/ReceiveExternalWalletFunds/TokenSelectScreen/TokenOption/TokenOption.cjs +21 -10
  43. package/src/lib/widgets/DynamicWidget/views/ReceiveExternalWalletFunds/TokenSelectScreen/TokenOption/TokenOption.d.ts +2 -0
  44. package/src/lib/widgets/DynamicWidget/views/ReceiveExternalWalletFunds/TokenSelectScreen/TokenOption/TokenOption.js +21 -10
  45. package/src/lib/widgets/DynamicWidget/views/ReceiveExternalWalletFunds/TokenSelectScreen/TokenSelectScreen.cjs +3 -3
  46. package/src/lib/widgets/DynamicWidget/views/ReceiveExternalWalletFunds/TokenSelectScreen/TokenSelectScreen.d.ts +2 -0
  47. package/src/lib/widgets/DynamicWidget/views/ReceiveExternalWalletFunds/TokenSelectScreen/TokenSelectScreen.js +3 -3
  48. package/src/lib/widgets/DynamicWidget/views/ReceiveExternalWalletFunds/types.d.ts +2 -0
  49. package/src/lib/widgets/DynamicWidget/views/ReceiveExternalWalletFunds/utils/calculateFiatBalance/calculateFiatBalance.cjs +27 -0
  50. package/src/lib/widgets/DynamicWidget/views/ReceiveExternalWalletFunds/utils/calculateFiatBalance/calculateFiatBalance.d.ts +2 -0
  51. package/src/lib/widgets/DynamicWidget/views/ReceiveExternalWalletFunds/utils/calculateFiatBalance/calculateFiatBalance.js +23 -0
  52. package/src/lib/widgets/DynamicWidget/views/ReceiveExternalWalletFunds/utils/calculateFiatBalance/index.d.ts +1 -0
  53. package/src/lib/widgets/DynamicWidget/views/ReceiveExternalWalletFunds/utils/convert/convert.cjs +4 -0
  54. package/src/lib/widgets/DynamicWidget/views/ReceiveExternalWalletFunds/utils/convert/convert.js +4 -0
  55. package/src/lib/widgets/DynamicWidget/views/ReceiveExternalWalletFunds/utils/formatValue/convertScientificToDecimal/convertScientificToDecimal.cjs +33 -0
  56. package/src/lib/widgets/DynamicWidget/views/ReceiveExternalWalletFunds/utils/formatValue/convertScientificToDecimal/convertScientificToDecimal.d.ts +8 -0
  57. package/src/lib/widgets/DynamicWidget/views/ReceiveExternalWalletFunds/utils/formatValue/convertScientificToDecimal/convertScientificToDecimal.js +29 -0
  58. package/src/lib/widgets/DynamicWidget/views/ReceiveExternalWalletFunds/utils/formatValue/convertScientificToDecimal/index.d.ts +1 -0
  59. package/src/lib/widgets/DynamicWidget/views/ReceiveExternalWalletFunds/utils/formatValue/formatValue.cjs +26 -27
  60. package/src/lib/widgets/DynamicWidget/views/ReceiveExternalWalletFunds/utils/formatValue/formatValue.d.ts +6 -0
  61. package/src/lib/widgets/DynamicWidget/views/ReceiveExternalWalletFunds/utils/formatValue/formatValue.js +26 -27
  62. package/src/lib/widgets/DynamicWidget/views/ReceiveExternalWalletFunds/utils/isFiatToken/isFiatToken.cjs +2 -0
  63. package/src/lib/widgets/DynamicWidget/views/ReceiveExternalWalletFunds/utils/isFiatToken/isFiatToken.d.ts +1 -0
  64. package/src/lib/widgets/DynamicWidget/views/ReceiveExternalWalletFunds/utils/isFiatToken/isFiatToken.js +2 -1
  65. package/src/lib/widgets/DynamicWidget/views/ReceiveExternalWalletFunds/utils/useExchangeRatesForFunding/index.d.ts +1 -0
  66. package/src/lib/widgets/DynamicWidget/views/ReceiveExternalWalletFunds/utils/useExchangeRatesForFunding/useExchangeRatesForFunding.cjs +32 -0
  67. package/src/lib/widgets/DynamicWidget/views/ReceiveExternalWalletFunds/utils/useExchangeRatesForFunding/useExchangeRatesForFunding.d.ts +9 -0
  68. package/src/lib/widgets/DynamicWidget/views/ReceiveExternalWalletFunds/utils/useExchangeRatesForFunding/useExchangeRatesForFunding.js +28 -0
  69. package/src/lib/widgets/DynamicWidget/views/ReceiveExternalWalletFunds/utils/useTokensForFunding/useTokensForFunding.cjs +27 -15
  70. package/src/lib/widgets/DynamicWidget/views/ReceiveExternalWalletFunds/utils/useTokensForFunding/useTokensForFunding.js +27 -15
  71. package/src/lib/widgets/DynamicWidget/views/SettingsView/EmptyScreen/EmptyScreen.cjs +20 -0
  72. package/src/lib/widgets/DynamicWidget/views/SettingsView/EmptyScreen/EmptyScreen.d.ts +2 -0
  73. package/src/lib/widgets/DynamicWidget/views/SettingsView/EmptyScreen/EmptyScreen.js +16 -0
  74. package/src/lib/widgets/DynamicWidget/views/SettingsView/EmptyScreen/index.d.ts +1 -0
  75. package/src/lib/widgets/DynamicWidget/views/SettingsView/SettingsView.cjs +3 -6
  76. package/src/lib/widgets/DynamicWidget/views/SettingsView/SettingsView.js +3 -6
  77. package/src/lib/components/NetworkPicker/components/EvmNetworkControl/EvmNetworkControl.d.ts +0 -23
  78. package/src/lib/components/NetworkPicker/components/EvmNetworkControl/index.d.ts +0 -1
  79. package/src/lib/shared/assets/currency.js +0 -46
@@ -47,7 +47,6 @@ require('../../../../utils/functions/compareChains/compareChains.cjs');
47
47
  require('../../../../context/ThemeContext/ThemeContext.cjs');
48
48
  require('../../../../utils/hooks/useUserUpdateRequest/useUpdateUser/userFieldsSchema.cjs');
49
49
  require('bs58');
50
- var usePromise = require('../../../../utils/hooks/usePromise/usePromise.cjs');
51
50
  require('@dynamic-labs/types');
52
51
  require('../../../../context/SocialRedirectContext/SocialRedirectContext.cjs');
53
52
  require('../../../../context/LoadingContext/LoadingContext.cjs');
@@ -77,6 +76,7 @@ var Icon = require('../../../../components/Icon/Icon.cjs');
77
76
  var DynamicWidgetContext = require('../../context/DynamicWidgetContext.cjs');
78
77
  var IconButton = require('../../../../components/IconButton/IconButton.cjs');
79
78
  require('../../../../components/MenuList/Dropdown/Dropdown.cjs');
79
+ var Image = require('../../../../components/Image/Image.cjs');
80
80
  var TypographyButton = require('../../../../components/TypographyButton/TypographyButton.cjs');
81
81
  require('formik');
82
82
  require('../../../../utils/hooks/useSubdomainCheck/useSubdomainCheck.cjs');
@@ -102,7 +102,6 @@ require('../../../../components/InlineWidget/InlineWidget.cjs');
102
102
  require('../../../../components/IsBrowser/IsBrowser.cjs');
103
103
  require('../../../../components/Popper/Popper/Popper.cjs');
104
104
  require('../../../../components/Popper/PopperContext/PopperContext.cjs');
105
- var exchangeRates = require('../../../../data/api/exchangeRates/exchangeRates.cjs');
106
105
  var FormattedInput = require('./FormattedInput/FormattedInput.cjs');
107
106
  var formattedInputEmitter = require('./FormattedInput/formattedInputEmitter.cjs');
108
107
  var TokenSelectScreen = require('./TokenSelectScreen/TokenSelectScreen.cjs');
@@ -112,8 +111,10 @@ var formatValue = require('./utils/formatValue/formatValue.cjs');
112
111
  var isFiatToken = require('./utils/isFiatToken/isFiatToken.cjs');
113
112
  var isNonZero = require('./utils/isNonZero/isNonZero.cjs');
114
113
  var respectsMinimum = require('./utils/respectsMinimum/respectsMinimum.cjs');
114
+ var useExchangeRatesForFunding = require('./utils/useExchangeRatesForFunding/useExchangeRatesForFunding.cjs');
115
115
  var useSubmitExternalWalletFunding = require('./utils/useSubmitExternalWalletFunding/useSubmitExternalWalletFunding.cjs');
116
116
  var useTokensForFunding = require('./utils/useTokensForFunding/useTokensForFunding.cjs');
117
+ var calculateFiatBalance = require('./utils/calculateFiatBalance/calculateFiatBalance.cjs');
117
118
 
118
119
  const defaultQuickSuggestions = {
119
120
  token: 'USD',
@@ -123,7 +124,7 @@ const rulesThatHideQuickSuggestions = ['exact', 'minimum'];
123
124
  const rulesThatDisableTokenSelect = ['exact', 'exact-with-amount'];
124
125
  const inputEmitter = formattedInputEmitter.createFormattedInputEmitter();
125
126
  const ReceiveExternalWalletFunds = ({ amount: initialAmount, token: initialTokenRaw, externalWallet, quickSuggestions = defaultQuickSuggestions, }) => {
126
- var _a, _b, _c, _d, _e, _f, _g;
127
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
127
128
  // For now we hardcode the default value, soon we will fetch this from project settings
128
129
  const initialToken = initialTokenRaw !== null && initialTokenRaw !== void 0 ? initialTokenRaw : {
129
130
  rule: 'recommended',
@@ -146,10 +147,9 @@ const ReceiveExternalWalletFunds = ({ amount: initialAmount, token: initialToken
146
147
  const { isLoading: tokenBalancesLoading, tokens: tokenBalances } = useTokensForFunding.useTokensForFunding({
147
148
  wallet: externalWallet,
148
149
  });
149
- const { data: exchangeRates$1 } = usePromise.usePromise(exchangeRates.getExchangeRates, {
150
- initialData: {},
150
+ const exchangeRates = useExchangeRatesForFunding.useExchangeRatesForFunding({
151
151
  // Initialize amounts after exchange rates are fetched
152
- onResolve: (exchangeRates) => {
152
+ onFetch: (exchangeRates) => {
153
153
  if (tokenAmount === undefined && fiatAmount !== undefined) {
154
154
  setTokenAmount(convert.convertFromFiat(fiatAmount, tokenSymbol, exchangeRates));
155
155
  }
@@ -157,39 +157,46 @@ const ReceiveExternalWalletFunds = ({ amount: initialAmount, token: initialToken
157
157
  setFiatAmount(convert.convertToFiat(tokenAmount, tokenSymbol, exchangeRates));
158
158
  }
159
159
  },
160
+ tokenBalances,
160
161
  });
161
162
  const [tokenAmount, setTokenAmount] = React.useState(isInitialAmountValueForToken
162
163
  ? (_a = initialAmount === null || initialAmount === void 0 ? void 0 : initialAmount.value.toString()) !== null && _a !== void 0 ? _a : ''
163
- : convert.convertFromFiat((_b = initialAmount === null || initialAmount === void 0 ? void 0 : initialAmount.value.toString()) !== null && _b !== void 0 ? _b : '', initialToken.value, exchangeRates$1));
164
+ : convert.convertFromFiat((_b = initialAmount === null || initialAmount === void 0 ? void 0 : initialAmount.value.toString()) !== null && _b !== void 0 ? _b : '', initialToken.value, exchangeRates));
164
165
  const [tokenSymbol, _setTokenSymbol] = React.useState(initialToken.value);
165
- const setTokenSymbol = (symbol) => {
166
+ const [fiatAmount, setFiatAmount] = React.useState(isInitialAmountValueForToken
167
+ ? convert.convertToFiat(tokenAmount !== null && tokenAmount !== void 0 ? tokenAmount : '', tokenSymbol, exchangeRates)
168
+ : (_c = initialAmount === null || initialAmount === void 0 ? void 0 : initialAmount.value.toString()) !== null && _c !== void 0 ? _c : '');
169
+ const setTokenSymbol = React.useCallback((symbol) => {
166
170
  setHasUserInteracted(true);
167
171
  _setTokenSymbol(symbol);
168
172
  if (fiatAmount)
169
- setTokenAmount(convert.convertFromFiat(fiatAmount, symbol, exchangeRates$1));
170
- };
171
- const [fiatAmount, setFiatAmount] = React.useState(isInitialAmountValueForToken
172
- ? convert.convertToFiat(tokenAmount !== null && tokenAmount !== void 0 ? tokenAmount : '', tokenSymbol, exchangeRates$1)
173
- : (_c = initialAmount === null || initialAmount === void 0 ? void 0 : initialAmount.value.toString()) !== null && _c !== void 0 ? _c : '');
173
+ setTokenAmount(convert.convertFromFiat(fiatAmount, symbol, exchangeRates));
174
+ }, [fiatAmount, exchangeRates]);
174
175
  // When we eventually allow changing this, add setter as _setFiatSymbol
175
176
  // And then create a setFiatSymbol function similar to how we have setTokenSymbol
176
177
  const [fiatSymbol] = React.useState('USD');
177
- const setAmountsByTokenValue = (amount) => {
178
+ const setAmountsByTokenValue = React.useCallback((amount) => {
178
179
  setTokenAmount(amount);
179
- setFiatAmount(convert.convertToFiat(amount, tokenSymbol, exchangeRates$1));
180
- };
181
- const setAmountsByFiatValue = (amount) => {
180
+ setFiatAmount(convert.convertToFiat(amount, tokenSymbol, exchangeRates));
181
+ }, [tokenSymbol, exchangeRates]);
182
+ const setAmountsByFiatValue = React.useCallback((amount) => {
182
183
  setFiatAmount(amount);
183
- setTokenAmount(convert.convertFromFiat(amount, tokenSymbol, exchangeRates$1));
184
- };
184
+ setTokenAmount(convert.convertFromFiat(amount, tokenSymbol, exchangeRates));
185
+ }, [tokenSymbol, exchangeRates]);
185
186
  const [showTokenAsPrimary, setShowTokenAsPrimary] = React.useState(false);
186
- const switchPrimaryAndSecondary = () => {
187
+ const switchPrimaryAndSecondary = React.useCallback(() => {
187
188
  setHasUserInteracted(true);
188
189
  setShowTokenAsPrimary(!showTokenAsPrimary);
190
+ if (tokenAmount && isNaN(parseFloat(tokenAmount))) {
191
+ setTokenAmount('');
192
+ }
193
+ if (fiatAmount && isNaN(parseFloat(fiatAmount))) {
194
+ setFiatAmount('');
195
+ }
189
196
  inputEmitter.emit('focus');
190
- };
197
+ }, [fiatAmount, showTokenAsPrimary, tokenAmount]);
191
198
  const isMinimumRespected = minimum
192
- ? respectsMinimum.respectsMinimum({ token: fiatSymbol, value: fiatAmount !== null && fiatAmount !== void 0 ? fiatAmount : '' }, minimum, exchangeRates$1)
199
+ ? respectsMinimum.respectsMinimum({ token: fiatSymbol, value: fiatAmount !== null && fiatAmount !== void 0 ? fiatAmount : '' }, minimum, exchangeRates)
193
200
  : true;
194
201
  const [primaryData, secondaryData] = showTokenAsPrimary
195
202
  ? [
@@ -208,17 +215,17 @@ const ReceiveExternalWalletFunds = ({ amount: initialAmount, token: initialToken
208
215
  },
209
216
  { amount: tokenAmount, symbol: tokenSymbol },
210
217
  ];
211
- const secondaryDisplayHasFixedZeros = isFiatToken.isFiatToken(secondaryData.symbol) || secondaryData.symbol === 'USDC';
212
218
  const secondaryDisplay = formatValue.formatValue({
219
+ maxDecimals: isFiatToken.isFiatOrStablecoin(secondaryData.symbol) ? 2 : undefined,
213
220
  symbol: secondaryData.symbol,
214
221
  value: secondaryData.amount,
215
- withFixedZeros: secondaryDisplayHasFixedZeros,
222
+ withFixedZeros: isFiatToken.isFiatOrStablecoin(secondaryData.symbol),
216
223
  });
217
224
  const quickSuggestionsWithToken = Array.isArray(quickSuggestions)
218
225
  ? { token: 'USD', values: quickSuggestions }
219
226
  : quickSuggestions;
220
227
  const quickSuggestionsParsed = quickSuggestionsWithToken.values
221
- .filter((value) => respectsMinimum.respectsMinimum({ token: quickSuggestionsWithToken.token, value: value.toString() }, minimum, exchangeRates$1))
228
+ .filter((value) => respectsMinimum.respectsMinimum({ token: quickSuggestionsWithToken.token, value: value.toString() }, minimum, exchangeRates))
222
229
  .map((value) => ({
223
230
  display: formatValue.formatValue({
224
231
  symbol: quickSuggestionsWithToken.token,
@@ -227,10 +234,33 @@ const ReceiveExternalWalletFunds = ({ amount: initialAmount, token: initialToken
227
234
  value,
228
235
  }))
229
236
  .filter(({ display }) => display !== undefined);
230
- const balanceNumber = (_e = (_d = tokenBalances === null || tokenBalances === void 0 ? void 0 : tokenBalances.find(({ symbol }) => symbol === tokenSymbol)) === null || _d === void 0 ? void 0 : _d.balance) !== null && _e !== void 0 ? _e : 0;
231
- const showNotEnoughBalance = Boolean(isNonZero.isNonZero(tokenAmount) &&
232
- tokenAmount !== undefined &&
233
- balanceNumber < parseFloat(tokenAmount));
237
+ const currentToken = tokenBalances === null || tokenBalances === void 0 ? void 0 : tokenBalances.find(({ symbol }) => symbol === tokenSymbol);
238
+ const fiatBalance = calculateFiatBalance.calculateFiatBalance(currentToken, exchangeRates);
239
+ const [primaryBalance, secondaryBalance] = showTokenAsPrimary
240
+ ? [
241
+ {
242
+ symbol: tokenSymbol,
243
+ value: (_d = currentToken === null || currentToken === void 0 ? void 0 : currentToken.balance) !== null && _d !== void 0 ? _d : 0,
244
+ },
245
+ {
246
+ symbol: fiatSymbol,
247
+ value: fiatBalance,
248
+ },
249
+ ]
250
+ : [
251
+ {
252
+ symbol: fiatSymbol,
253
+ value: fiatBalance,
254
+ },
255
+ {
256
+ symbol: tokenSymbol,
257
+ value: (_e = currentToken === null || currentToken === void 0 ? void 0 : currentToken.balance) !== null && _e !== void 0 ? _e : 0,
258
+ },
259
+ ];
260
+ const showNotEnoughBalance = Boolean(!currentToken ||
261
+ (isNonZero.isNonZero(tokenAmount) &&
262
+ tokenAmount !== undefined &&
263
+ currentToken.balance < parseFloat(tokenAmount)));
234
264
  const showMinimumRequired = Boolean(!isMinimumRespected && !showNotEnoughBalance);
235
265
  const showQuickSuggestions = quickSuggestionsParsed.length > 0 &&
236
266
  !hasUserInteracted &&
@@ -239,62 +269,81 @@ const ReceiveExternalWalletFunds = ({ amount: initialAmount, token: initialToken
239
269
  isFiatToken.isFiatToken(quickSuggestionsWithToken.token));
240
270
  const disableTokenSelect = rulesThatDisableTokenSelect.includes(initialToken.rule);
241
271
  const [showTokenSelect, setShowTokenSelect] = React.useState(false);
242
- const handleSelectToken = (token) => {
272
+ const handleSelectToken = React.useCallback((token) => {
243
273
  setTokenSymbol(token);
244
274
  setShowTokenSelect(false);
245
- };
246
- const handleQuickSuggestion = (value) => {
275
+ }, [setTokenSymbol]);
276
+ const handleQuickSuggestion = React.useCallback((value) => {
247
277
  setHasUserInteracted(true);
248
278
  if (isFiatToken.isFiatToken(quickSuggestionsWithToken.token))
249
279
  setAmountsByFiatValue(value.toString());
250
280
  else
251
281
  setAmountsByTokenValue(value.toString());
252
282
  inputEmitter.emit('focus');
253
- };
283
+ }, [
284
+ quickSuggestionsWithToken.token,
285
+ setAmountsByFiatValue,
286
+ setAmountsByTokenValue,
287
+ ]);
254
288
  const handleSubmit = useSubmitExternalWalletFunding.useSubmitExternalWalletFunding();
289
+ const disableSubmit = !isMinimumRespected || showNotEnoughBalance || !isNonZero.isNonZero(tokenAmount);
290
+ const closeTokenSelect = React.useCallback(() => {
291
+ setShowTokenSelect(false);
292
+ inputEmitter.emit('focus');
293
+ }, []);
255
294
  const grayOutSecondaryDisplay = !isNonZero.isNonZero(secondaryData.amount) ||
256
- (secondaryDisplayHasFixedZeros &&
295
+ (isFiatToken.isFiatOrStablecoin(secondaryData.symbol) &&
257
296
  parseFloat((_f = secondaryData.amount) !== null && _f !== void 0 ? _f : '0') < 0.0099);
258
297
  const inputSymbolProp = primaryData.symbol === 'USD'
259
298
  ? { leading: '$' }
260
299
  : { trailing: primaryData.symbol };
261
300
  const backButton = (jsxRuntime.jsx(IconButton.IconButton, { type: 'button', id: 'back-button', "data-testid": 'back-button', onClick: () => setDynamicWidgetView('choose-wallet-funding-method'), children: jsxRuntime.jsx(arrowLeft.ReactComponent, {}) }));
262
- return (jsxRuntime.jsxs("div", { className: 'fund-from-wallet', children: [!disableTokenSelect && (jsxRuntime.jsx(TokenSelectScreen.TokenSelectScreen, { onClose: () => setShowTokenSelect(false), onSelectToken: handleSelectToken, tokens: tokenBalances !== null && tokenBalances !== void 0 ? tokenBalances : [], currentToken: tokenSymbol, className: classNames.classNames('fund-from-wallet__token-select', {
301
+ return (jsxRuntime.jsxs("div", { className: 'fund-from-wallet', children: [!disableTokenSelect && (jsxRuntime.jsx(TokenSelectScreen.TokenSelectScreen, { onClose: closeTokenSelect, onSelectToken: handleSelectToken, tokens: tokenBalances !== null && tokenBalances !== void 0 ? tokenBalances : [], currentToken: tokenSymbol, className: classNames.classNames('fund-from-wallet__token-select', {
263
302
  'fund-from-wallet__token-select--open': showTokenSelect,
264
- }) })), jsxRuntime.jsx(ModalHeader.ModalHeader, { leading: backButton, children: jsxRuntime.jsx(Typography.Typography, { variant: 'title', children: t('dyn_wallet_funding.from_external_wallet.funding_view.title') }) }), jsxRuntime.jsxs("div", { className: 'fund-from-wallet__content', children: [jsxRuntime.jsxs("div", { className: 'fund-from-wallet__content__amount-container', children: [minimum && (jsxRuntime.jsx(Typography.Typography, { color: 'error-1', className: classNames.classNames('fund-from-wallet__content__amount-container__minimum-error', {
303
+ }), showTokenAsPrimary: showTokenAsPrimary, exchangeRates: exchangeRates })), jsxRuntime.jsx(ModalHeader.ModalHeader, { leading: backButton, children: jsxRuntime.jsx(Typography.Typography, { variant: 'title', children: t('dyn_wallet_funding.from_external_wallet.funding_view.title') }) }), jsxRuntime.jsxs("div", { className: 'fund-from-wallet__content', children: [jsxRuntime.jsxs("div", { className: 'fund-from-wallet__content__amount-container', children: [minimum && (jsxRuntime.jsx(Typography.Typography, { color: 'error-1', className: classNames.classNames('fund-from-wallet__content__amount-container__minimum-error', {
265
304
  'fund-from-wallet__content__amount-container__minimum-error--visible': showMinimumRequired,
266
- }), variant: 'body_normal', children: t('dyn_wallet_funding.from_external_wallet.funding_view.minimum_error', {
305
+ }), variant: 'body_normal', weight: 'medium', children: t('dyn_wallet_funding.from_external_wallet.funding_view.minimum_error', {
267
306
  minimum: formatValue.formatValue({
268
307
  symbol: minimum.token,
269
308
  value: minimum.value,
270
309
  }),
271
310
  }) })), primaryData.amount !== undefined && (jsxRuntime.jsx(FormattedInput.FormattedInput, Object.assign({ className: 'fund-from-wallet__content__amount-container__amount', value: (initialAmount === null || initialAmount === void 0 ? void 0 : initialAmount.rule) === 'exact'
272
311
  ? (_g = formatValue.formatValue({
273
- maxDecimals: 8,
312
+ maxDecimals: isFiatToken.isFiatOrStablecoin(primaryData.symbol)
313
+ ? 2
314
+ : 8,
274
315
  symbol: undefined,
275
316
  value: primaryData.amount,
276
- withFixedZeros: isFiatToken.isFiatToken(primaryData.symbol) ||
277
- primaryData.symbol === 'USDC',
317
+ withFixedZeros: isFiatToken.isFiatOrStablecoin(primaryData.symbol),
278
318
  })) !== null && _g !== void 0 ? _g : primaryData.amount
279
319
  : primaryData.amount, onChange: primaryData.setAmount, emitter: inputEmitter, onInteraction: () => setHasUserInteracted(true), locked: (initialAmount === null || initialAmount === void 0 ? void 0 : initialAmount.rule) === 'exact' }, inputSymbolProp))), primaryData.amount === undefined && (jsxRuntime.jsx(Skeleton.Skeleton, { dataTestId: 'primary-amount-skeleton', container: {
280
320
  className: 'fund-from-wallet__content__amount-container__skeleton',
281
- } })), showQuickSuggestions && (jsxRuntime.jsx("div", { className: 'fund-from-wallet__content__amount-container__quick-suggestions', children: quickSuggestionsParsed.map(({ display, value }) => (jsxRuntime.jsx(Typography.Typography, { variant: 'body_small', color: 'secondary', onClick: () => handleQuickSuggestion(value), children: display }, value))) })), !showQuickSuggestions && secondaryDisplay && (jsxRuntime.jsxs("div", { className: 'fund-from-wallet__content__amount-container__secondary-amount-container', children: [jsxRuntime.jsx(Typography.Typography, { weight: 'medium', className: classNames.classNames('fund-from-wallet__content__amount-container__secondary-amount-container__amount', {
321
+ } })), showQuickSuggestions && (jsxRuntime.jsx("div", { className: 'fund-from-wallet__content__amount-container__quick-suggestions', children: quickSuggestionsParsed.map(({ display, value }) => (jsxRuntime.jsx(Typography.Typography, { variant: 'body_small', color: 'secondary', onClick: () => handleQuickSuggestion(value), weight: 'medium', children: display }, value))) })), !showQuickSuggestions && secondaryDisplay && (jsxRuntime.jsxs("div", { className: 'fund-from-wallet__content__amount-container__secondary-amount-container', children: [(currentToken === null || currentToken === void 0 ? void 0 : currentToken.logoURI) ? (jsxRuntime.jsx(Image.Image, { dataTestId: 'token-icon', alt: tokenSymbol, src: currentToken.logoURI, className: 'fund-from-wallet__content__token-icon' })) : null, jsxRuntime.jsx(Typography.Typography, { weight: 'medium', className: classNames.classNames('fund-from-wallet__content__amount-container__secondary-amount-container__amount', {
282
322
  'fund-from-wallet__content__amount-container__secondary-amount-container__amount--grayed-out': grayOutSecondaryDisplay,
283
323
  }), children: secondaryDisplay }), jsxRuntime.jsx(Icon.Icon, { size: 'small', color: 'text-secondary', className: 'fund-from-wallet__content__amount-container__secondary-amount-container__switch', children: jsxRuntime.jsx(switchToggle.ReactComponent, { "data-testid": 'switch-primary-and-secondary', onClick: switchPrimaryAndSecondary }) })] })), !showQuickSuggestions && !secondaryDisplay && (jsxRuntime.jsxs("div", { className: 'fund-from-wallet__content__amount-container__secondary-missing', children: [jsxRuntime.jsx(Typography.Typography, { weight: 'medium', children: formatValue.formatValue({
284
324
  symbol: secondaryData.symbol,
285
325
  value: consts.UNAVAILABLE_VALUE,
286
- }) }), jsxRuntime.jsx("div", { ref: setConversionErrorIconRef, children: jsxRuntime.jsx(Icon.Icon, { size: 'medium', color: 'text-tertiary', children: jsxRuntime.jsx(footerInfoIcon.ReactComponent, {}) }) }), jsxRuntime.jsx(Tooltip.Tooltip, { content: t('dyn_wallet_funding.from_external_wallet.funding_view.network_conversion_error'), targetRef: conversionErrorIconRef, className: 'fund-from-wallet__content__amount-container__secondary-missing__tooltip' })] })), jsxRuntime.jsx(Typography.Typography, { color: 'error-1', className: classNames.classNames('fund-from-wallet__content__amount-container__balance-error', {
326
+ }) }), jsxRuntime.jsx("div", { ref: setConversionErrorIconRef, children: jsxRuntime.jsx(Icon.Icon, { size: 'medium', color: 'text-tertiary', children: jsxRuntime.jsx(footerInfoIcon.ReactComponent, {}) }) }), jsxRuntime.jsx(Tooltip.Tooltip, { content: t('dyn_wallet_funding.from_external_wallet.funding_view.pricing_unavailable'), targetRef: conversionErrorIconRef, className: 'fund-from-wallet__content__amount-container__secondary-missing__tooltip' })] })), jsxRuntime.jsx(Typography.Typography, { color: 'error-1', className: classNames.classNames('fund-from-wallet__content__amount-container__balance-error', {
287
327
  'fund-from-wallet__content__amount-container__balance-error--visible': showNotEnoughBalance,
288
- }), variant: 'body_normal', children: t('dyn_wallet_funding.from_external_wallet.funding_view.balance_error') })] }), jsxRuntime.jsxs("div", { className: 'fund-from-wallet__content__wallet-card', children: [jsxRuntime.jsxs("div", { className: 'fund-from-wallet__content__wallet-card__wallet-details', children: [jsxRuntime.jsx(walletBook.WalletIcon, { icon: externalWallet.connector.metadata.icon, walletKey: externalWallet.connector.key, className: 'fund-from-wallet__content__wallet-card__wallet-details__icon' }), jsxRuntime.jsxs("div", { className: 'fund-from-wallet__content__wallet-card__wallet-details__rows', children: [jsxRuntime.jsx(Typography.Typography, { variant: 'body_small', color: 'secondary', children: t('dyn_wallet_funding.from_external_wallet.funding_view.wallet_detail_from') }), jsxRuntime.jsx(Typography.Typography, { variant: 'body_small', children: shortenWalletAddress.shortenWalletAddress(externalWallet.address) })] })] }), tokenBalancesLoading && (jsxRuntime.jsx(Skeleton.Skeleton, { dataTestId: 'balance-skeleton', container: {
328
+ }), variant: 'body_normal', weight: 'medium', children: t('dyn_wallet_funding.from_external_wallet.funding_view.balance_error') })] }), jsxRuntime.jsxs("div", { className: 'fund-from-wallet__content__wallet-card', children: [jsxRuntime.jsxs("div", { className: 'fund-from-wallet__content__wallet-card__wallet-details', children: [jsxRuntime.jsx(walletBook.WalletIcon, { icon: externalWallet.connector.metadata.icon, walletKey: externalWallet.connector.key, className: 'fund-from-wallet__content__wallet-card__wallet-details__icon' }), jsxRuntime.jsxs("div", { className: 'fund-from-wallet__content__wallet-card__wallet-details__rows', children: [jsxRuntime.jsx(Typography.Typography, { variant: 'body_small', weight: 'medium', children: t('dyn_wallet_funding.from_external_wallet.funding_view.wallet_detail_from') }), jsxRuntime.jsx(Typography.Typography, { variant: 'body_small', color: 'secondary', weight: 'medium', children: shortenWalletAddress.shortenWalletAddress(externalWallet.address) })] })] }), tokenBalancesLoading && (jsxRuntime.jsx(Skeleton.Skeleton, { dataTestId: 'balance-skeleton', container: {
289
329
  className: 'fund-from-wallet__content__wallet-card__balance-skeleton',
290
330
  } })), !tokenBalancesLoading && (jsxRuntime.jsxs("div", { className: classNames.classNames('fund-from-wallet__content__wallet-card__balance', {
291
331
  'fund-from-wallet__content__wallet-card__balance--disable-select': disableTokenSelect,
292
- }), onClick: () => !disableTokenSelect && setShowTokenSelect(true), children: [jsxRuntime.jsxs("div", { className: 'fund-from-wallet__content__wallet-card__balance__rows', children: [jsxRuntime.jsx(Typography.Typography, { variant: 'body_small', color: 'secondary', weight: 'bold', children: t('dyn_wallet_funding.from_external_wallet.funding_view.balance') }), jsxRuntime.jsx(Typography.Typography, { variant: 'body_small', weight: 'bold', "data-testid": `balance-amount-${tokenSymbol}`, children: formatValue.formatValue({
293
- maxDecimals: 8,
294
- symbol: tokenSymbol,
295
- value: balanceNumber,
296
- withFixedZeros: isFiatToken.isFiatToken(tokenSymbol) || tokenSymbol === 'USDC',
297
- }) })] }), !disableTokenSelect && (jsxRuntime.jsx(Icon.Icon, { color: 'text-tertiary', size: 'small', className: 'fund-from-wallet__content__wallet-card__balance__icon', children: jsxRuntime.jsx(chevronDown.ReactComponent, {}) }))] }))] })] }), jsxRuntime.jsx(TypographyButton.TypographyButton, { dataTestId: 'confirm-button', buttonVariant: 'brand-primary', buttonPadding: 'large', typographyProps: { color: 'white' }, className: 'fund-from-wallet__confirm-button', disabled: !isMinimumRespected || showNotEnoughBalance || !isNonZero.isNonZero(tokenAmount), onClick: () => handleSubmit({
332
+ }), onClick: () => !disableTokenSelect && setShowTokenSelect(true), children: [jsxRuntime.jsxs("div", { className: 'fund-from-wallet__content__wallet-card__balance__rows', children: [jsxRuntime.jsx(Typography.Typography, { variant: 'body_small', "data-testid": `primary-balance-amount-${primaryBalance.symbol}`, weight: 'medium', children: formatValue.formatValue({
333
+ maxDecimals: isFiatToken.isFiatOrStablecoin(primaryBalance.symbol)
334
+ ? 2
335
+ : 6,
336
+ symbol: primaryBalance.symbol,
337
+ value: (_h = primaryBalance.value) !== null && _h !== void 0 ? _h : consts.UNAVAILABLE_VALUE,
338
+ withFixedZeros: isFiatToken.isFiatOrStablecoin(primaryBalance.symbol),
339
+ }) }), jsxRuntime.jsx(Typography.Typography, { variant: 'body_small', "data-testid": `secondary-balance-amount-${secondaryBalance.symbol}`, color: 'secondary', weight: 'medium', children: formatValue.formatValue({
340
+ maxDecimals: isFiatToken.isFiatOrStablecoin(secondaryBalance.symbol)
341
+ ? 2
342
+ : 6,
343
+ symbol: secondaryBalance.symbol,
344
+ value: (_j = secondaryBalance.value) !== null && _j !== void 0 ? _j : consts.UNAVAILABLE_VALUE,
345
+ withFixedZeros: isFiatToken.isFiatOrStablecoin(secondaryBalance.symbol),
346
+ }) })] }), !disableTokenSelect && (jsxRuntime.jsx(Icon.Icon, { color: 'text-tertiary', size: 'small', className: 'fund-from-wallet__content__wallet-card__balance__icon', children: jsxRuntime.jsx(chevronDown.ReactComponent, { "data-testid": 'token-select-dropdown' }) }))] }))] })] }), jsxRuntime.jsx(TypographyButton.TypographyButton, { dataTestId: 'confirm-button', buttonVariant: 'brand-primary', buttonPadding: 'large', typographyProps: { color: 'white' }, className: 'fund-from-wallet__confirm-button', disabled: disableSubmit, onClick: () => handleSubmit({
298
347
  externalWallet,
299
348
  tokenAmount,
300
349
  tokenBalances,
@@ -1,6 +1,6 @@
1
1
  'use client'
2
2
  import { jsx, jsxs } from 'react/jsx-runtime';
3
- import { useState } from 'react';
3
+ import { useState, useCallback } from 'react';
4
4
  import { useTranslation } from 'react-i18next';
5
5
  import { WalletIcon } from '@dynamic-labs/wallet-book';
6
6
  import { classNames } from '../../../../utils/functions/classNames/classNames.js';
@@ -43,7 +43,6 @@ import '../../../../utils/functions/compareChains/compareChains.js';
43
43
  import '../../../../context/ThemeContext/ThemeContext.js';
44
44
  import '../../../../utils/hooks/useUserUpdateRequest/useUpdateUser/userFieldsSchema.js';
45
45
  import 'bs58';
46
- import { usePromise } from '../../../../utils/hooks/usePromise/usePromise.js';
47
46
  import '@dynamic-labs/types';
48
47
  import '../../../../context/SocialRedirectContext/SocialRedirectContext.js';
49
48
  import '../../../../context/LoadingContext/LoadingContext.js';
@@ -73,6 +72,7 @@ import { Icon } from '../../../../components/Icon/Icon.js';
73
72
  import { useWidgetContext } from '../../context/DynamicWidgetContext.js';
74
73
  import { IconButton } from '../../../../components/IconButton/IconButton.js';
75
74
  import '../../../../components/MenuList/Dropdown/Dropdown.js';
75
+ import { Image } from '../../../../components/Image/Image.js';
76
76
  import { TypographyButton } from '../../../../components/TypographyButton/TypographyButton.js';
77
77
  import 'formik';
78
78
  import '../../../../utils/hooks/useSubdomainCheck/useSubdomainCheck.js';
@@ -98,18 +98,19 @@ import '../../../../components/InlineWidget/InlineWidget.js';
98
98
  import '../../../../components/IsBrowser/IsBrowser.js';
99
99
  import '../../../../components/Popper/Popper/Popper.js';
100
100
  import '../../../../components/Popper/PopperContext/PopperContext.js';
101
- import { getExchangeRates } from '../../../../data/api/exchangeRates/exchangeRates.js';
102
101
  import { FormattedInput } from './FormattedInput/FormattedInput.js';
103
102
  import { createFormattedInputEmitter } from './FormattedInput/formattedInputEmitter.js';
104
103
  import { TokenSelectScreen } from './TokenSelectScreen/TokenSelectScreen.js';
105
104
  import { UNAVAILABLE_VALUE } from './consts.js';
106
105
  import { convertFromFiat, convertToFiat } from './utils/convert/convert.js';
107
106
  import { formatValue } from './utils/formatValue/formatValue.js';
108
- import { isFiatToken } from './utils/isFiatToken/isFiatToken.js';
107
+ import { isFiatOrStablecoin, isFiatToken } from './utils/isFiatToken/isFiatToken.js';
109
108
  import { isNonZero } from './utils/isNonZero/isNonZero.js';
110
109
  import { respectsMinimum } from './utils/respectsMinimum/respectsMinimum.js';
110
+ import { useExchangeRatesForFunding } from './utils/useExchangeRatesForFunding/useExchangeRatesForFunding.js';
111
111
  import { useSubmitExternalWalletFunding } from './utils/useSubmitExternalWalletFunding/useSubmitExternalWalletFunding.js';
112
112
  import { useTokensForFunding } from './utils/useTokensForFunding/useTokensForFunding.js';
113
+ import { calculateFiatBalance } from './utils/calculateFiatBalance/calculateFiatBalance.js';
113
114
 
114
115
  const defaultQuickSuggestions = {
115
116
  token: 'USD',
@@ -119,7 +120,7 @@ const rulesThatHideQuickSuggestions = ['exact', 'minimum'];
119
120
  const rulesThatDisableTokenSelect = ['exact', 'exact-with-amount'];
120
121
  const inputEmitter = createFormattedInputEmitter();
121
122
  const ReceiveExternalWalletFunds = ({ amount: initialAmount, token: initialTokenRaw, externalWallet, quickSuggestions = defaultQuickSuggestions, }) => {
122
- var _a, _b, _c, _d, _e, _f, _g;
123
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
123
124
  // For now we hardcode the default value, soon we will fetch this from project settings
124
125
  const initialToken = initialTokenRaw !== null && initialTokenRaw !== void 0 ? initialTokenRaw : {
125
126
  rule: 'recommended',
@@ -142,10 +143,9 @@ const ReceiveExternalWalletFunds = ({ amount: initialAmount, token: initialToken
142
143
  const { isLoading: tokenBalancesLoading, tokens: tokenBalances } = useTokensForFunding({
143
144
  wallet: externalWallet,
144
145
  });
145
- const { data: exchangeRates } = usePromise(getExchangeRates, {
146
- initialData: {},
146
+ const exchangeRates = useExchangeRatesForFunding({
147
147
  // Initialize amounts after exchange rates are fetched
148
- onResolve: (exchangeRates) => {
148
+ onFetch: (exchangeRates) => {
149
149
  if (tokenAmount === undefined && fiatAmount !== undefined) {
150
150
  setTokenAmount(convertFromFiat(fiatAmount, tokenSymbol, exchangeRates));
151
151
  }
@@ -153,37 +153,44 @@ const ReceiveExternalWalletFunds = ({ amount: initialAmount, token: initialToken
153
153
  setFiatAmount(convertToFiat(tokenAmount, tokenSymbol, exchangeRates));
154
154
  }
155
155
  },
156
+ tokenBalances,
156
157
  });
157
158
  const [tokenAmount, setTokenAmount] = useState(isInitialAmountValueForToken
158
159
  ? (_a = initialAmount === null || initialAmount === void 0 ? void 0 : initialAmount.value.toString()) !== null && _a !== void 0 ? _a : ''
159
160
  : convertFromFiat((_b = initialAmount === null || initialAmount === void 0 ? void 0 : initialAmount.value.toString()) !== null && _b !== void 0 ? _b : '', initialToken.value, exchangeRates));
160
161
  const [tokenSymbol, _setTokenSymbol] = useState(initialToken.value);
161
- const setTokenSymbol = (symbol) => {
162
+ const [fiatAmount, setFiatAmount] = useState(isInitialAmountValueForToken
163
+ ? convertToFiat(tokenAmount !== null && tokenAmount !== void 0 ? tokenAmount : '', tokenSymbol, exchangeRates)
164
+ : (_c = initialAmount === null || initialAmount === void 0 ? void 0 : initialAmount.value.toString()) !== null && _c !== void 0 ? _c : '');
165
+ const setTokenSymbol = useCallback((symbol) => {
162
166
  setHasUserInteracted(true);
163
167
  _setTokenSymbol(symbol);
164
168
  if (fiatAmount)
165
169
  setTokenAmount(convertFromFiat(fiatAmount, symbol, exchangeRates));
166
- };
167
- const [fiatAmount, setFiatAmount] = useState(isInitialAmountValueForToken
168
- ? convertToFiat(tokenAmount !== null && tokenAmount !== void 0 ? tokenAmount : '', tokenSymbol, exchangeRates)
169
- : (_c = initialAmount === null || initialAmount === void 0 ? void 0 : initialAmount.value.toString()) !== null && _c !== void 0 ? _c : '');
170
+ }, [fiatAmount, exchangeRates]);
170
171
  // When we eventually allow changing this, add setter as _setFiatSymbol
171
172
  // And then create a setFiatSymbol function similar to how we have setTokenSymbol
172
173
  const [fiatSymbol] = useState('USD');
173
- const setAmountsByTokenValue = (amount) => {
174
+ const setAmountsByTokenValue = useCallback((amount) => {
174
175
  setTokenAmount(amount);
175
176
  setFiatAmount(convertToFiat(amount, tokenSymbol, exchangeRates));
176
- };
177
- const setAmountsByFiatValue = (amount) => {
177
+ }, [tokenSymbol, exchangeRates]);
178
+ const setAmountsByFiatValue = useCallback((amount) => {
178
179
  setFiatAmount(amount);
179
180
  setTokenAmount(convertFromFiat(amount, tokenSymbol, exchangeRates));
180
- };
181
+ }, [tokenSymbol, exchangeRates]);
181
182
  const [showTokenAsPrimary, setShowTokenAsPrimary] = useState(false);
182
- const switchPrimaryAndSecondary = () => {
183
+ const switchPrimaryAndSecondary = useCallback(() => {
183
184
  setHasUserInteracted(true);
184
185
  setShowTokenAsPrimary(!showTokenAsPrimary);
186
+ if (tokenAmount && isNaN(parseFloat(tokenAmount))) {
187
+ setTokenAmount('');
188
+ }
189
+ if (fiatAmount && isNaN(parseFloat(fiatAmount))) {
190
+ setFiatAmount('');
191
+ }
185
192
  inputEmitter.emit('focus');
186
- };
193
+ }, [fiatAmount, showTokenAsPrimary, tokenAmount]);
187
194
  const isMinimumRespected = minimum
188
195
  ? respectsMinimum({ token: fiatSymbol, value: fiatAmount !== null && fiatAmount !== void 0 ? fiatAmount : '' }, minimum, exchangeRates)
189
196
  : true;
@@ -204,11 +211,11 @@ const ReceiveExternalWalletFunds = ({ amount: initialAmount, token: initialToken
204
211
  },
205
212
  { amount: tokenAmount, symbol: tokenSymbol },
206
213
  ];
207
- const secondaryDisplayHasFixedZeros = isFiatToken(secondaryData.symbol) || secondaryData.symbol === 'USDC';
208
214
  const secondaryDisplay = formatValue({
215
+ maxDecimals: isFiatOrStablecoin(secondaryData.symbol) ? 2 : undefined,
209
216
  symbol: secondaryData.symbol,
210
217
  value: secondaryData.amount,
211
- withFixedZeros: secondaryDisplayHasFixedZeros,
218
+ withFixedZeros: isFiatOrStablecoin(secondaryData.symbol),
212
219
  });
213
220
  const quickSuggestionsWithToken = Array.isArray(quickSuggestions)
214
221
  ? { token: 'USD', values: quickSuggestions }
@@ -223,10 +230,33 @@ const ReceiveExternalWalletFunds = ({ amount: initialAmount, token: initialToken
223
230
  value,
224
231
  }))
225
232
  .filter(({ display }) => display !== undefined);
226
- const balanceNumber = (_e = (_d = tokenBalances === null || tokenBalances === void 0 ? void 0 : tokenBalances.find(({ symbol }) => symbol === tokenSymbol)) === null || _d === void 0 ? void 0 : _d.balance) !== null && _e !== void 0 ? _e : 0;
227
- const showNotEnoughBalance = Boolean(isNonZero(tokenAmount) &&
228
- tokenAmount !== undefined &&
229
- balanceNumber < parseFloat(tokenAmount));
233
+ const currentToken = tokenBalances === null || tokenBalances === void 0 ? void 0 : tokenBalances.find(({ symbol }) => symbol === tokenSymbol);
234
+ const fiatBalance = calculateFiatBalance(currentToken, exchangeRates);
235
+ const [primaryBalance, secondaryBalance] = showTokenAsPrimary
236
+ ? [
237
+ {
238
+ symbol: tokenSymbol,
239
+ value: (_d = currentToken === null || currentToken === void 0 ? void 0 : currentToken.balance) !== null && _d !== void 0 ? _d : 0,
240
+ },
241
+ {
242
+ symbol: fiatSymbol,
243
+ value: fiatBalance,
244
+ },
245
+ ]
246
+ : [
247
+ {
248
+ symbol: fiatSymbol,
249
+ value: fiatBalance,
250
+ },
251
+ {
252
+ symbol: tokenSymbol,
253
+ value: (_e = currentToken === null || currentToken === void 0 ? void 0 : currentToken.balance) !== null && _e !== void 0 ? _e : 0,
254
+ },
255
+ ];
256
+ const showNotEnoughBalance = Boolean(!currentToken ||
257
+ (isNonZero(tokenAmount) &&
258
+ tokenAmount !== undefined &&
259
+ currentToken.balance < parseFloat(tokenAmount)));
230
260
  const showMinimumRequired = Boolean(!isMinimumRespected && !showNotEnoughBalance);
231
261
  const showQuickSuggestions = quickSuggestionsParsed.length > 0 &&
232
262
  !hasUserInteracted &&
@@ -235,62 +265,81 @@ const ReceiveExternalWalletFunds = ({ amount: initialAmount, token: initialToken
235
265
  isFiatToken(quickSuggestionsWithToken.token));
236
266
  const disableTokenSelect = rulesThatDisableTokenSelect.includes(initialToken.rule);
237
267
  const [showTokenSelect, setShowTokenSelect] = useState(false);
238
- const handleSelectToken = (token) => {
268
+ const handleSelectToken = useCallback((token) => {
239
269
  setTokenSymbol(token);
240
270
  setShowTokenSelect(false);
241
- };
242
- const handleQuickSuggestion = (value) => {
271
+ }, [setTokenSymbol]);
272
+ const handleQuickSuggestion = useCallback((value) => {
243
273
  setHasUserInteracted(true);
244
274
  if (isFiatToken(quickSuggestionsWithToken.token))
245
275
  setAmountsByFiatValue(value.toString());
246
276
  else
247
277
  setAmountsByTokenValue(value.toString());
248
278
  inputEmitter.emit('focus');
249
- };
279
+ }, [
280
+ quickSuggestionsWithToken.token,
281
+ setAmountsByFiatValue,
282
+ setAmountsByTokenValue,
283
+ ]);
250
284
  const handleSubmit = useSubmitExternalWalletFunding();
285
+ const disableSubmit = !isMinimumRespected || showNotEnoughBalance || !isNonZero(tokenAmount);
286
+ const closeTokenSelect = useCallback(() => {
287
+ setShowTokenSelect(false);
288
+ inputEmitter.emit('focus');
289
+ }, []);
251
290
  const grayOutSecondaryDisplay = !isNonZero(secondaryData.amount) ||
252
- (secondaryDisplayHasFixedZeros &&
291
+ (isFiatOrStablecoin(secondaryData.symbol) &&
253
292
  parseFloat((_f = secondaryData.amount) !== null && _f !== void 0 ? _f : '0') < 0.0099);
254
293
  const inputSymbolProp = primaryData.symbol === 'USD'
255
294
  ? { leading: '$' }
256
295
  : { trailing: primaryData.symbol };
257
296
  const backButton = (jsx(IconButton, { type: 'button', id: 'back-button', "data-testid": 'back-button', onClick: () => setDynamicWidgetView('choose-wallet-funding-method'), children: jsx(SvgArrowLeft, {}) }));
258
- return (jsxs("div", { className: 'fund-from-wallet', children: [!disableTokenSelect && (jsx(TokenSelectScreen, { onClose: () => setShowTokenSelect(false), onSelectToken: handleSelectToken, tokens: tokenBalances !== null && tokenBalances !== void 0 ? tokenBalances : [], currentToken: tokenSymbol, className: classNames('fund-from-wallet__token-select', {
297
+ return (jsxs("div", { className: 'fund-from-wallet', children: [!disableTokenSelect && (jsx(TokenSelectScreen, { onClose: closeTokenSelect, onSelectToken: handleSelectToken, tokens: tokenBalances !== null && tokenBalances !== void 0 ? tokenBalances : [], currentToken: tokenSymbol, className: classNames('fund-from-wallet__token-select', {
259
298
  'fund-from-wallet__token-select--open': showTokenSelect,
260
- }) })), jsx(ModalHeader, { leading: backButton, children: jsx(Typography, { variant: 'title', children: t('dyn_wallet_funding.from_external_wallet.funding_view.title') }) }), jsxs("div", { className: 'fund-from-wallet__content', children: [jsxs("div", { className: 'fund-from-wallet__content__amount-container', children: [minimum && (jsx(Typography, { color: 'error-1', className: classNames('fund-from-wallet__content__amount-container__minimum-error', {
299
+ }), showTokenAsPrimary: showTokenAsPrimary, exchangeRates: exchangeRates })), jsx(ModalHeader, { leading: backButton, children: jsx(Typography, { variant: 'title', children: t('dyn_wallet_funding.from_external_wallet.funding_view.title') }) }), jsxs("div", { className: 'fund-from-wallet__content', children: [jsxs("div", { className: 'fund-from-wallet__content__amount-container', children: [minimum && (jsx(Typography, { color: 'error-1', className: classNames('fund-from-wallet__content__amount-container__minimum-error', {
261
300
  'fund-from-wallet__content__amount-container__minimum-error--visible': showMinimumRequired,
262
- }), variant: 'body_normal', children: t('dyn_wallet_funding.from_external_wallet.funding_view.minimum_error', {
301
+ }), variant: 'body_normal', weight: 'medium', children: t('dyn_wallet_funding.from_external_wallet.funding_view.minimum_error', {
263
302
  minimum: formatValue({
264
303
  symbol: minimum.token,
265
304
  value: minimum.value,
266
305
  }),
267
306
  }) })), primaryData.amount !== undefined && (jsx(FormattedInput, Object.assign({ className: 'fund-from-wallet__content__amount-container__amount', value: (initialAmount === null || initialAmount === void 0 ? void 0 : initialAmount.rule) === 'exact'
268
307
  ? (_g = formatValue({
269
- maxDecimals: 8,
308
+ maxDecimals: isFiatOrStablecoin(primaryData.symbol)
309
+ ? 2
310
+ : 8,
270
311
  symbol: undefined,
271
312
  value: primaryData.amount,
272
- withFixedZeros: isFiatToken(primaryData.symbol) ||
273
- primaryData.symbol === 'USDC',
313
+ withFixedZeros: isFiatOrStablecoin(primaryData.symbol),
274
314
  })) !== null && _g !== void 0 ? _g : primaryData.amount
275
315
  : primaryData.amount, onChange: primaryData.setAmount, emitter: inputEmitter, onInteraction: () => setHasUserInteracted(true), locked: (initialAmount === null || initialAmount === void 0 ? void 0 : initialAmount.rule) === 'exact' }, inputSymbolProp))), primaryData.amount === undefined && (jsx(Skeleton, { dataTestId: 'primary-amount-skeleton', container: {
276
316
  className: 'fund-from-wallet__content__amount-container__skeleton',
277
- } })), showQuickSuggestions && (jsx("div", { className: 'fund-from-wallet__content__amount-container__quick-suggestions', children: quickSuggestionsParsed.map(({ display, value }) => (jsx(Typography, { variant: 'body_small', color: 'secondary', onClick: () => handleQuickSuggestion(value), children: display }, value))) })), !showQuickSuggestions && secondaryDisplay && (jsxs("div", { className: 'fund-from-wallet__content__amount-container__secondary-amount-container', children: [jsx(Typography, { weight: 'medium', className: classNames('fund-from-wallet__content__amount-container__secondary-amount-container__amount', {
317
+ } })), showQuickSuggestions && (jsx("div", { className: 'fund-from-wallet__content__amount-container__quick-suggestions', children: quickSuggestionsParsed.map(({ display, value }) => (jsx(Typography, { variant: 'body_small', color: 'secondary', onClick: () => handleQuickSuggestion(value), weight: 'medium', children: display }, value))) })), !showQuickSuggestions && secondaryDisplay && (jsxs("div", { className: 'fund-from-wallet__content__amount-container__secondary-amount-container', children: [(currentToken === null || currentToken === void 0 ? void 0 : currentToken.logoURI) ? (jsx(Image, { dataTestId: 'token-icon', alt: tokenSymbol, src: currentToken.logoURI, className: 'fund-from-wallet__content__token-icon' })) : null, jsx(Typography, { weight: 'medium', className: classNames('fund-from-wallet__content__amount-container__secondary-amount-container__amount', {
278
318
  'fund-from-wallet__content__amount-container__secondary-amount-container__amount--grayed-out': grayOutSecondaryDisplay,
279
319
  }), children: secondaryDisplay }), jsx(Icon, { size: 'small', color: 'text-secondary', className: 'fund-from-wallet__content__amount-container__secondary-amount-container__switch', children: jsx(SvgSwitchToggle, { "data-testid": 'switch-primary-and-secondary', onClick: switchPrimaryAndSecondary }) })] })), !showQuickSuggestions && !secondaryDisplay && (jsxs("div", { className: 'fund-from-wallet__content__amount-container__secondary-missing', children: [jsx(Typography, { weight: 'medium', children: formatValue({
280
320
  symbol: secondaryData.symbol,
281
321
  value: UNAVAILABLE_VALUE,
282
- }) }), jsx("div", { ref: setConversionErrorIconRef, children: jsx(Icon, { size: 'medium', color: 'text-tertiary', children: jsx(SvgFooterInfoIcon, {}) }) }), jsx(Tooltip, { content: t('dyn_wallet_funding.from_external_wallet.funding_view.network_conversion_error'), targetRef: conversionErrorIconRef, className: 'fund-from-wallet__content__amount-container__secondary-missing__tooltip' })] })), jsx(Typography, { color: 'error-1', className: classNames('fund-from-wallet__content__amount-container__balance-error', {
322
+ }) }), jsx("div", { ref: setConversionErrorIconRef, children: jsx(Icon, { size: 'medium', color: 'text-tertiary', children: jsx(SvgFooterInfoIcon, {}) }) }), jsx(Tooltip, { content: t('dyn_wallet_funding.from_external_wallet.funding_view.pricing_unavailable'), targetRef: conversionErrorIconRef, className: 'fund-from-wallet__content__amount-container__secondary-missing__tooltip' })] })), jsx(Typography, { color: 'error-1', className: classNames('fund-from-wallet__content__amount-container__balance-error', {
283
323
  'fund-from-wallet__content__amount-container__balance-error--visible': showNotEnoughBalance,
284
- }), variant: 'body_normal', children: t('dyn_wallet_funding.from_external_wallet.funding_view.balance_error') })] }), jsxs("div", { className: 'fund-from-wallet__content__wallet-card', children: [jsxs("div", { className: 'fund-from-wallet__content__wallet-card__wallet-details', children: [jsx(WalletIcon, { icon: externalWallet.connector.metadata.icon, walletKey: externalWallet.connector.key, className: 'fund-from-wallet__content__wallet-card__wallet-details__icon' }), jsxs("div", { className: 'fund-from-wallet__content__wallet-card__wallet-details__rows', children: [jsx(Typography, { variant: 'body_small', color: 'secondary', children: t('dyn_wallet_funding.from_external_wallet.funding_view.wallet_detail_from') }), jsx(Typography, { variant: 'body_small', children: shortenWalletAddress(externalWallet.address) })] })] }), tokenBalancesLoading && (jsx(Skeleton, { dataTestId: 'balance-skeleton', container: {
324
+ }), variant: 'body_normal', weight: 'medium', children: t('dyn_wallet_funding.from_external_wallet.funding_view.balance_error') })] }), jsxs("div", { className: 'fund-from-wallet__content__wallet-card', children: [jsxs("div", { className: 'fund-from-wallet__content__wallet-card__wallet-details', children: [jsx(WalletIcon, { icon: externalWallet.connector.metadata.icon, walletKey: externalWallet.connector.key, className: 'fund-from-wallet__content__wallet-card__wallet-details__icon' }), jsxs("div", { className: 'fund-from-wallet__content__wallet-card__wallet-details__rows', children: [jsx(Typography, { variant: 'body_small', weight: 'medium', children: t('dyn_wallet_funding.from_external_wallet.funding_view.wallet_detail_from') }), jsx(Typography, { variant: 'body_small', color: 'secondary', weight: 'medium', children: shortenWalletAddress(externalWallet.address) })] })] }), tokenBalancesLoading && (jsx(Skeleton, { dataTestId: 'balance-skeleton', container: {
285
325
  className: 'fund-from-wallet__content__wallet-card__balance-skeleton',
286
326
  } })), !tokenBalancesLoading && (jsxs("div", { className: classNames('fund-from-wallet__content__wallet-card__balance', {
287
327
  'fund-from-wallet__content__wallet-card__balance--disable-select': disableTokenSelect,
288
- }), onClick: () => !disableTokenSelect && setShowTokenSelect(true), children: [jsxs("div", { className: 'fund-from-wallet__content__wallet-card__balance__rows', children: [jsx(Typography, { variant: 'body_small', color: 'secondary', weight: 'bold', children: t('dyn_wallet_funding.from_external_wallet.funding_view.balance') }), jsx(Typography, { variant: 'body_small', weight: 'bold', "data-testid": `balance-amount-${tokenSymbol}`, children: formatValue({
289
- maxDecimals: 8,
290
- symbol: tokenSymbol,
291
- value: balanceNumber,
292
- withFixedZeros: isFiatToken(tokenSymbol) || tokenSymbol === 'USDC',
293
- }) })] }), !disableTokenSelect && (jsx(Icon, { color: 'text-tertiary', size: 'small', className: 'fund-from-wallet__content__wallet-card__balance__icon', children: jsx(SvgChevronDown, {}) }))] }))] })] }), jsx(TypographyButton, { dataTestId: 'confirm-button', buttonVariant: 'brand-primary', buttonPadding: 'large', typographyProps: { color: 'white' }, className: 'fund-from-wallet__confirm-button', disabled: !isMinimumRespected || showNotEnoughBalance || !isNonZero(tokenAmount), onClick: () => handleSubmit({
328
+ }), onClick: () => !disableTokenSelect && setShowTokenSelect(true), children: [jsxs("div", { className: 'fund-from-wallet__content__wallet-card__balance__rows', children: [jsx(Typography, { variant: 'body_small', "data-testid": `primary-balance-amount-${primaryBalance.symbol}`, weight: 'medium', children: formatValue({
329
+ maxDecimals: isFiatOrStablecoin(primaryBalance.symbol)
330
+ ? 2
331
+ : 6,
332
+ symbol: primaryBalance.symbol,
333
+ value: (_h = primaryBalance.value) !== null && _h !== void 0 ? _h : UNAVAILABLE_VALUE,
334
+ withFixedZeros: isFiatOrStablecoin(primaryBalance.symbol),
335
+ }) }), jsx(Typography, { variant: 'body_small', "data-testid": `secondary-balance-amount-${secondaryBalance.symbol}`, color: 'secondary', weight: 'medium', children: formatValue({
336
+ maxDecimals: isFiatOrStablecoin(secondaryBalance.symbol)
337
+ ? 2
338
+ : 6,
339
+ symbol: secondaryBalance.symbol,
340
+ value: (_j = secondaryBalance.value) !== null && _j !== void 0 ? _j : UNAVAILABLE_VALUE,
341
+ withFixedZeros: isFiatOrStablecoin(secondaryBalance.symbol),
342
+ }) })] }), !disableTokenSelect && (jsx(Icon, { color: 'text-tertiary', size: 'small', className: 'fund-from-wallet__content__wallet-card__balance__icon', children: jsx(SvgChevronDown, { "data-testid": 'token-select-dropdown' }) }))] }))] })] }), jsx(TypographyButton, { dataTestId: 'confirm-button', buttonVariant: 'brand-primary', buttonPadding: 'large', typographyProps: { color: 'white' }, className: 'fund-from-wallet__confirm-button', disabled: disableSubmit, onClick: () => handleSubmit({
294
343
  externalWallet,
295
344
  tokenAmount,
296
345
  tokenBalances,