@rango-dev/widget-embedded 0.47.0 → 0.47.1-next.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/components/BlockchainsSection/BlockchainsSection.d.ts.map +1 -1
  3. package/dist/components/HistoryGroupedList/HistoryGroupedList.d.ts.map +1 -1
  4. package/dist/components/HistoryGroupedList/HistoryGroupedList.helpers.d.ts.map +1 -1
  5. package/dist/components/Quote/Quote.d.ts +1 -1
  6. package/dist/components/Quote/Quote.d.ts.map +1 -1
  7. package/dist/components/SwapDetails/SwapDetails.d.ts.map +1 -1
  8. package/dist/components/TokenList/TokenList.d.ts.map +1 -1
  9. package/dist/components/TokenList/TokenList.types.d.ts +6 -6
  10. package/dist/components/TokenList/TokenList.types.d.ts.map +1 -1
  11. package/dist/hooks/useConfirmSwap/useConfirmSwap.helpers.d.ts.map +1 -1
  12. package/dist/hooks/useSyncUrlAndStore/useSyncUrlAndStore.d.ts.map +1 -1
  13. package/dist/hooks/useSyncUrlAndStore/useSyncUrlAndStore.helpers.d.ts +1 -1
  14. package/dist/hooks/useSyncUrlAndStore/useSyncUrlAndStore.helpers.d.ts.map +1 -1
  15. package/dist/index.js +2 -2
  16. package/dist/index.js.map +3 -3
  17. package/dist/store/notification.d.ts.map +1 -1
  18. package/dist/store/slices/wallets.d.ts.map +1 -1
  19. package/dist/store/utils/data.d.ts.map +1 -1
  20. package/dist/store/utils/wallets.d.ts +1 -1
  21. package/dist/store/utils/wallets.d.ts.map +1 -1
  22. package/dist/utils/colors.d.ts.map +1 -1
  23. package/dist/utils/configs.d.ts.map +1 -1
  24. package/dist/utils/quote.d.ts.map +1 -1
  25. package/dist/utils/swap.d.ts +1 -1
  26. package/dist/utils/swap.d.ts.map +1 -1
  27. package/dist/utils/wallets.d.ts.map +1 -1
  28. package/dist/widget-embedded.build.json +1 -1
  29. package/package.json +8 -8
  30. package/src/components/BlockchainsSection/BlockchainsSection.tsx +7 -6
  31. package/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx +1 -1
  32. package/src/components/HistoryGroupedList/HistoryGroupedList.helpers.ts +4 -2
  33. package/src/components/HistoryGroupedList/HistoryGroupedList.tsx +3 -0
  34. package/src/components/Quote/Quote.tsx +14 -9
  35. package/src/components/SwapDetails/SwapDetails.helpers.tsx +2 -2
  36. package/src/components/SwapDetails/SwapDetails.tsx +21 -19
  37. package/src/components/SwapMetrics/SwapMetrics.tsx +2 -2
  38. package/src/components/TokenList/TokenList.tsx +10 -8
  39. package/src/components/TokenList/TokenList.types.ts +9 -6
  40. package/src/components/WalletStatefulConnect/DerivationPath.helpers.ts +1 -1
  41. package/src/hooks/useConfirmSwap/useConfirmSwap.helpers.ts +4 -1
  42. package/src/hooks/usePrepareBlockchainList/usePrepareBlockchainList.helpers.ts +1 -1
  43. package/src/hooks/useStatefulConnect/useStatefulConnect.ts +1 -1
  44. package/src/hooks/useSyncUrlAndStore/useSyncUrlAndStore.helpers.ts +4 -2
  45. package/src/hooks/useSyncUrlAndStore/useSyncUrlAndStore.ts +12 -15
  46. package/src/pages/SelectSwapItemPage/SelectSwapItemPage.helpers.ts +1 -1
  47. package/src/store/notification.ts +3 -1
  48. package/src/store/slices/data.test.ts +9 -9
  49. package/src/store/slices/data.ts +1 -1
  50. package/src/store/slices/wallets.ts +22 -9
  51. package/src/store/utils/data.test.ts +27 -14
  52. package/src/store/utils/data.ts +11 -3
  53. package/src/store/utils/wallets.ts +23 -11
  54. package/src/test-utils/fixtures.ts +1 -1
  55. package/src/utils/colors.ts +4 -1
  56. package/src/utils/configs.ts +10 -6
  57. package/src/utils/quote.ts +16 -5
  58. package/src/utils/swap.ts +11 -4
  59. package/src/utils/wallets.ts +4 -2
@@ -339,7 +339,9 @@ export const createWalletsSlice = keepLastUpdated<AppStoreState, WalletsSlice>(
339
339
  if (!acc[wallet.address]) {
340
340
  acc[wallet.address] = [];
341
341
  }
342
- acc[wallet.address].push(...tokensByBlockchain[wallet.chain]);
342
+ acc[wallet.address]?.push(
343
+ ...(tokensByBlockchain[wallet.chain] || [])
344
+ );
343
345
  }
344
346
  return acc;
345
347
  }, {});
@@ -442,9 +444,13 @@ export const createWalletsSlice = keepLastUpdated<AppStoreState, WalletsSlice>(
442
444
  });
443
445
  },
444
446
  newWalletConnected: async (accounts, namespace, derivationPath) => {
447
+ const newAccount = accounts[0];
448
+ if (!newAccount) {
449
+ return;
450
+ }
445
451
  eventEmitter.emit(WidgetEvents.WalletEvent, {
446
452
  type: WalletEventTypes.CONNECT,
447
- payload: { walletType: accounts[0].walletType, accounts },
453
+ payload: { walletType: newAccount.walletType, accounts },
448
454
  });
449
455
 
450
456
  get().addConnectedWallet(accounts, namespace, derivationPath);
@@ -602,7 +608,7 @@ export const createWalletsSlice = keepLastUpdated<AppStoreState, WalletsSlice>(
602
608
  }
603
609
  },
604
610
  fetchMainTokensBalances: async (accounts, options) => {
605
- if (accounts.length === 0) {
611
+ if (accounts.length === 0 || !accounts[0]) {
606
612
  return;
607
613
  }
608
614
  // All the `accounts` have same `walletType` so we can pick the first one.
@@ -744,18 +750,25 @@ export const createWalletsSlice = keepLastUpdated<AppStoreState, WalletsSlice>(
744
750
  const assetKey = createAssetKey(token);
745
751
  const targetBalanceKeys = get()._aggregatedBalances[assetKey] || [];
746
752
 
747
- if (targetBalanceKeys.length === 0) {
753
+ if (targetBalanceKeys.length === 0 || !targetBalanceKeys[0]) {
748
754
  return null;
749
- } else if (targetBalanceKeys.length === 1) {
750
- const targetKey = targetBalanceKeys[0];
755
+ }
756
+ const targetKey = targetBalanceKeys[0];
757
+ if (targetBalanceKeys.length === 1 && balances[targetKey]) {
751
758
  return balances[targetKey];
752
759
  }
753
760
 
754
761
  // If there are multiple balances for an specific token, we pick the maximum.
755
762
  const firstTargetBalance = balances[targetBalanceKeys[0]];
763
+ if (!firstTargetBalance) {
764
+ return null;
765
+ }
756
766
  let maxBalance: Balance = firstTargetBalance;
757
767
  targetBalanceKeys.forEach((targetBalanceKey) => {
758
768
  const currentBalance = balances[targetBalanceKey];
769
+ if (!currentBalance) {
770
+ return;
771
+ }
759
772
  const currentBalanceAmount = new BigNumber(currentBalance.amount);
760
773
  const prevBalanceAmount = new BigNumber(maxBalance.amount);
761
774
 
@@ -775,7 +788,7 @@ export const createWalletsSlice = keepLastUpdated<AppStoreState, WalletsSlice>(
775
788
 
776
789
  const [, , , balanceWalletAddreess] =
777
790
  balanceKey.split(BALANCE_SEPARATOR);
778
- if (balanceWalletAddreess === address) {
791
+ if (balance && balanceWalletAddreess === address) {
779
792
  output[balanceKey] = balance;
780
793
  }
781
794
 
@@ -799,10 +812,10 @@ export const createWalletsSlice = keepLastUpdated<AppStoreState, WalletsSlice>(
799
812
  const balance = balances[balanceKey];
800
813
  const asset = extractAssetFromBalanceKey(balanceKey);
801
814
 
802
- if (asset.blockchain === wallet.chain) {
815
+ if (asset && asset.blockchain === wallet.chain && balance) {
803
816
  const token = get().findToken(asset);
804
817
 
805
- const amount = balance.amount
818
+ const amount = balance?.amount
806
819
  ? new BigNumber(balance.amount).shiftedBy(-balance.decimals)
807
820
  : ZERO;
808
821
 
@@ -1,6 +1,6 @@
1
1
  import type { Token } from 'rango-sdk';
2
2
 
3
- import { describe, expect, test } from 'vitest';
3
+ import { beforeEach, describe, expect, test } from 'vitest';
4
4
 
5
5
  import { createToken } from '../../test-utils/fixtures';
6
6
  import { createTokenHash } from '../../utils/meta';
@@ -35,25 +35,38 @@ function createMetaForMockData(
35
35
  if (!meta.tokensMapByBlockchainName[token.blockchain]) {
36
36
  meta.tokensMapByBlockchainName[token.blockchain] = [];
37
37
  }
38
- meta.tokensMapByBlockchainName[token.blockchain].push(tokenHash);
38
+ meta.tokensMapByBlockchainName[token.blockchain]?.push(tokenHash);
39
39
  });
40
40
 
41
41
  return meta;
42
42
  }
43
43
 
44
44
  describe('matchTokensFromConfigWithMeta', () => {
45
+ let token0: Token;
46
+ let token1: Token;
47
+ let token2: Token;
48
+
49
+ beforeEach(() => {
50
+ // Assert presence once
51
+ if (!tokens[0] || !tokens[1] || !tokens[2]) {
52
+ throw new Error('Test data not populated correctly');
53
+ }
54
+ token0 = tokens[0];
55
+ token1 = tokens[1];
56
+ token2 = tokens[2];
57
+ });
45
58
  test('should include tokens from config.tokens array that exist in meta', () => {
46
59
  const mockData: MatchTokensFromConfigWithMetaParam = {
47
60
  type: 'source',
48
61
  meta: createMetaForMockData(tokens),
49
62
  config: {
50
63
  blockchains: undefined,
51
- tokens: [tokens[0], tokens[1]],
64
+ tokens: [token0, token1],
52
65
  },
53
66
  };
54
67
 
55
68
  const result = matchTokensFromConfigWithMeta(mockData);
56
- expect(result).toEqual([tokens[0], tokens[1]]);
69
+ expect(result).toEqual([token0, token1]);
57
70
  });
58
71
 
59
72
  test('If config.blockchains is not defined or is empty, we should include all tokens from the meta for every blockchain that does not have tokens specified in the config, as well as tokens specified in the config that exist in the meta.', () => {
@@ -63,7 +76,7 @@ describe('matchTokensFromConfigWithMeta', () => {
63
76
  config: {
64
77
  blockchains: undefined,
65
78
  tokens: {
66
- [BLOCKCHAIN_A]: { tokens: [tokens[0]], isExcluded: false },
79
+ [BLOCKCHAIN_A]: { tokens: [token0], isExcluded: false },
67
80
  },
68
81
  },
69
82
  };
@@ -80,7 +93,7 @@ describe('matchTokensFromConfigWithMeta', () => {
80
93
  * as we have a comprehensive sorting logic applied to tokens within the data slice.
81
94
  */
82
95
  // eslint-disable-next-line @typescript-eslint/no-magic-numbers
83
- expect(result).toEqual([tokens[2], tokens[3], tokens[0]]);
96
+ expect(result).toEqual([token2, tokens[3], token0]);
84
97
  };
85
98
 
86
99
  runTestWithConfig({ blockchains: undefined });
@@ -94,14 +107,14 @@ describe('matchTokensFromConfigWithMeta', () => {
94
107
  config: {
95
108
  blockchains: [BLOCKCHAIN_A, BLOCKCHAIN_B],
96
109
  tokens: {
97
- [BLOCKCHAIN_A]: { tokens: [tokens[0]], isExcluded: false },
98
- [BLOCKCHAIN_B]: { tokens: [tokens[2]], isExcluded: false },
110
+ [BLOCKCHAIN_A]: { tokens: [token0], isExcluded: false },
111
+ [BLOCKCHAIN_B]: { tokens: [token2], isExcluded: false },
99
112
  },
100
113
  },
101
114
  };
102
115
 
103
116
  const result = matchTokensFromConfigWithMeta(mockData);
104
- expect(result).toEqual([tokens[0], tokens[2]]);
117
+ expect(result).toEqual([token0, token2]);
105
118
  });
106
119
 
107
120
  test('should not include tokens from config.tokens whose blockchain does not exist in config.blockchains', () => {
@@ -111,13 +124,13 @@ describe('matchTokensFromConfigWithMeta', () => {
111
124
  config: {
112
125
  blockchains: [BLOCKCHAIN_A],
113
126
  tokens: {
114
- [BLOCKCHAIN_B]: { tokens: [tokens[2]], isExcluded: false },
127
+ [BLOCKCHAIN_B]: { tokens: [token2], isExcluded: false },
115
128
  },
116
129
  },
117
130
  };
118
131
 
119
132
  const result = matchTokensFromConfigWithMeta(mockData);
120
- expect(result).toEqual([tokens[0], tokens[1]]);
133
+ expect(result).toEqual([token0, token1]);
121
134
  });
122
135
 
123
136
  test('should include all tokens from a blockchain if that blockchain does not have any tokens in config.tokens', () => {
@@ -131,7 +144,7 @@ describe('matchTokensFromConfigWithMeta', () => {
131
144
  };
132
145
 
133
146
  const result = matchTokensFromConfigWithMeta(mockData);
134
- expect(result).toEqual([tokens[0], tokens[1]]);
147
+ expect(result).toEqual([token0, token1]);
135
148
  });
136
149
 
137
150
  test('should include all tokens from config.blockchains that exist in the meta, except tokens excluded in config.token', () => {
@@ -141,13 +154,13 @@ describe('matchTokensFromConfigWithMeta', () => {
141
154
  config: {
142
155
  blockchains: [BLOCKCHAIN_A],
143
156
  tokens: {
144
- [BLOCKCHAIN_A]: { tokens: [tokens[0]], isExcluded: true },
157
+ [BLOCKCHAIN_A]: { tokens: [token0], isExcluded: true },
145
158
  },
146
159
  },
147
160
  };
148
161
 
149
162
  const result = matchTokensFromConfigWithMeta(mockData);
150
- expect(result).toEqual([tokens[1]]);
163
+ expect(result).toEqual([token1]);
151
164
  });
152
165
 
153
166
  test('should include all tokens from the meta when config parameters are empty values', () => {
@@ -78,8 +78,13 @@ export function matchTokensFromConfigWithMeta(params: {
78
78
  const configBlockchainsSet = new Set(configBlockchains);
79
79
 
80
80
  Object.keys(meta.tokensMapByBlockchainName).forEach((blockchain) => {
81
- if (!configBlockchainsSet.has(blockchain)) {
82
- addTokens(meta.tokensMapByBlockchainName[blockchain]);
81
+ const metaTokensForSelectedBlockchain =
82
+ meta.tokensMapByBlockchainName[blockchain];
83
+ if (
84
+ !configBlockchainsSet.has(blockchain) &&
85
+ metaTokensForSelectedBlockchain
86
+ ) {
87
+ addTokens(metaTokensForSelectedBlockchain);
83
88
  }
84
89
  });
85
90
  }
@@ -99,7 +104,10 @@ export function matchTokensFromConfigWithMeta(params: {
99
104
  }
100
105
 
101
106
  if (targetTokensForBlockchain) {
102
- if (targetTokensForBlockchain.isExcluded) {
107
+ if (
108
+ targetTokensForBlockchain.isExcluded &&
109
+ meta.tokensMapByBlockchainName[blockchain]
110
+ ) {
103
111
  /**
104
112
  * If tokens are excluded,
105
113
  * we first include all tokens from the meta for that blockchain,
@@ -35,9 +35,13 @@ export function createBalanceKey(
35
35
  return `${assetKey}${BALANCE_SEPARATOR}${accountAddress}`;
36
36
  }
37
37
 
38
- export function extractAssetFromBalanceKey(key: BalanceKey): Asset {
38
+ export function extractAssetFromBalanceKey(key: BalanceKey): Asset | null {
39
39
  const [assetChain, assetAddress, assetSymbol] = key.split(BALANCE_SEPARATOR);
40
40
 
41
+ if (!assetChain || !assetAddress || !assetSymbol) {
42
+ return null;
43
+ }
44
+
41
45
  // null will be serialized to 'null', we need to make it back to a null type
42
46
  const address = assetAddress === 'null' ? null : assetAddress;
43
47
  return {
@@ -113,17 +117,19 @@ export function updateAggregatedBalanceStateForNewAccount(
113
117
  ) {
114
118
  for (const balanceKey in balanceState) {
115
119
  const asset = extractAssetFromBalanceKey(balanceKey as BalanceKey);
116
- const assetKey = createAssetKey(asset);
120
+ if (asset) {
121
+ const assetKey = createAssetKey(asset);
117
122
 
118
- if (!aggregatedBalances[assetKey]) {
119
- aggregatedBalances[assetKey] = [];
120
- }
123
+ if (!aggregatedBalances[assetKey]) {
124
+ aggregatedBalances[assetKey] = [];
125
+ }
121
126
 
122
- if (!aggregatedBalances[assetKey].includes(balanceKey as BalanceKey)) {
123
- aggregatedBalances[assetKey] = [
124
- ...aggregatedBalances[assetKey],
125
- balanceKey as BalanceKey,
126
- ];
127
+ if (!aggregatedBalances[assetKey].includes(balanceKey as BalanceKey)) {
128
+ aggregatedBalances[assetKey] = [
129
+ ...aggregatedBalances[assetKey],
130
+ balanceKey as BalanceKey,
131
+ ];
132
+ }
127
133
  }
128
134
  }
129
135
 
@@ -135,6 +141,9 @@ export function removeBalanceFromAggregatedBalance(
135
141
  balanceKey: BalanceKey
136
142
  ) {
137
143
  const asset = extractAssetFromBalanceKey(balanceKey);
144
+ if (!asset) {
145
+ return aggregatedBalances;
146
+ }
138
147
  const assetKey = createAssetKey(asset);
139
148
 
140
149
  if (aggregatedBalances[assetKey]) {
@@ -205,6 +214,9 @@ export function computeNextStateAfterWalletBalanceRemoval(
205
214
 
206
215
  balanceKeys.forEach((key) => {
207
216
  const asset = extractAssetFromBalanceKey(key);
217
+ if (!asset) {
218
+ return;
219
+ }
208
220
 
209
221
  const shouldBalanceBeRemoved = !!walletsNeedsToBeRemoved.find(
210
222
  (wallet) =>
@@ -221,7 +233,7 @@ export function computeNextStateAfterWalletBalanceRemoval(
221
233
  nextAggregatedBalanceState,
222
234
  key
223
235
  );
224
- } else {
236
+ } else if (currentBalancesState[key]) {
225
237
  nextBalancesState[key] = currentBalancesState[key];
226
238
  }
227
239
  });
@@ -240,7 +240,7 @@ export function createInitialAppStore() {
240
240
  tokensMapByBlockchainName[token.blockchain] = [];
241
241
  }
242
242
  tokensMapByTokenHash.set(tokenHash, token);
243
- tokensMapByBlockchainName[token.blockchain].push(tokenHash);
243
+ tokensMapByBlockchainName[token.blockchain]?.push(tokenHash);
244
244
  });
245
245
 
246
246
  return {
@@ -133,7 +133,10 @@ export function createTintsAndShades(
133
133
 
134
134
  for (let i = 0; i < length; i++) {
135
135
  const index = BASE_INDEX + (isReversed ? length - 1 - i : i) * STEP;
136
- colorMap[`${colorKey}${index}`] = combinedColors[i];
136
+ const color = combinedColors[i];
137
+ if (color) {
138
+ colorMap[`${colorKey}${index}`] = color;
139
+ }
137
140
  }
138
141
 
139
142
  return colorMap;
@@ -54,15 +54,19 @@ export const isTokenExcludedInConfig = (
54
54
  tokensConfig?: TokensConfig
55
55
  ) => {
56
56
  let result = false;
57
+
57
58
  if (tokensConfig && token) {
58
59
  if (Array.isArray(tokensConfig)) {
59
60
  result = !tokensConfig.some((asset) => areTokensEqual(asset, token));
60
- } else if (!Array.isArray(tokensConfig) && tokensConfig[token.blockchain]) {
61
- result = tokensConfig[token.blockchain].tokens.some((asset) =>
62
- areTokensEqual(asset, token)
63
- );
64
- const isExcluded = tokensConfig[token.blockchain].isExcluded;
65
- return (!isExcluded && !result) || (isExcluded && result);
61
+ } else if (!Array.isArray(tokensConfig)) {
62
+ const configForChain = tokensConfig[token.blockchain];
63
+ if (configForChain) {
64
+ result = !!configForChain.tokens.some((asset) =>
65
+ areTokensEqual(asset, token)
66
+ );
67
+ const isExcluded = configForChain.isExcluded;
68
+ return (!isExcluded && !result) || (isExcluded && result);
69
+ }
66
70
  }
67
71
  }
68
72
  return result;
@@ -143,6 +143,16 @@ export function createRetryQuote(
143
143
  const lastStep = pendingSwap.steps[pendingSwap.steps.length - 1];
144
144
  const lastSuccessfulStep = getLastSuccessfulStep(pendingSwap.steps);
145
145
 
146
+ if (!lastStep || !firstStep) {
147
+ return {
148
+ fromBlockchain: null,
149
+ fromToken: undefined,
150
+ toBlockchain: null,
151
+ toToken: undefined,
152
+ inputAmount: '',
153
+ };
154
+ }
155
+
146
156
  const toToken = {
147
157
  blockchain: lastStep.toBlockchain,
148
158
  symbol: lastStep.toSymbol,
@@ -336,15 +346,16 @@ export const getDefaultQuote = (
336
346
  quotes: MultiRouteSimulationResult[],
337
347
  requestAmount: string
338
348
  ): SelectedQuote | null => {
339
- if (!quotes.length) {
349
+ const quote = quotes[0]; // Return the first quote from the quotes array
350
+ if (!quotes.length || !quote) {
340
351
  return null;
341
352
  }
342
353
  if (!currentQuote) {
343
354
  // Handle the case where currentQuote is null
344
355
  return {
345
- requestAmount: requestAmount,
356
+ requestAmount,
346
357
  validationStatus: null,
347
- ...quotes[0], // Return the first quote from the quotes array
358
+ ...quote,
348
359
  };
349
360
  }
350
361
  // Create a set of swapperIds from the currentQuote swaps
@@ -365,9 +376,9 @@ export const getDefaultQuote = (
365
376
 
366
377
  // Return the matchedQuote if found, otherwise return the first quote from the quotes array
367
378
  return {
368
- requestAmount: requestAmount,
379
+ requestAmount,
369
380
  validationStatus: null,
370
- ...(matchedQuote || quotes[0]),
381
+ ...(matchedQuote || quote),
371
382
  };
372
383
  };
373
384
 
package/src/utils/swap.ts CHANGED
@@ -109,7 +109,7 @@ export function hasLimitError(swaps: SwapResult[]): boolean {
109
109
  }
110
110
 
111
111
  export function getLimitErrorMessage(swaps: SwapResult[]): {
112
- swap: SwapResult;
112
+ swap?: SwapResult;
113
113
  fromAmountRangeError: string;
114
114
  recommendation: string;
115
115
  } {
@@ -127,6 +127,13 @@ export function getLimitErrorMessage(swaps: SwapResult[]): {
127
127
  return minimum?.gt(swap.fromAmount) || maximum?.lt(swap.fromAmount);
128
128
  })[0];
129
129
 
130
+ if (!swap) {
131
+ return {
132
+ swap: undefined,
133
+ fromAmountRangeError: '',
134
+ recommendation: '',
135
+ };
136
+ }
130
137
  const minimum = !!swap.fromAmountMinValue
131
138
  ? new BigNumber(swap.fromAmountMinValue)
132
139
  : null;
@@ -279,7 +286,7 @@ export function getUsdFeeOfStep(
279
286
  let totalFeeInUsd = ZERO;
280
287
  for (let i = 0; i < step.fee.length; i++) {
281
288
  const fee = step.fee[i];
282
- if (fee.expenseType === 'DECREASE_FROM_OUTPUT') {
289
+ if (!fee || fee.expenseType === 'DECREASE_FROM_OUTPUT') {
283
290
  continue;
284
291
  }
285
292
 
@@ -557,7 +564,7 @@ export function getWalletsForNewSwap(selectedWallets: Wallet[]) {
557
564
 
558
565
  export function getUsdInputFrom(quote: SelectedQuote): BigNumber | undefined {
559
566
  const inputAmount = quote.requestAmount;
560
- const inputTokenUsdPrice = quote.swaps[0].from.usdPrice;
567
+ const inputTokenUsdPrice = quote.swaps[0]?.from.usdPrice;
561
568
  if (!inputAmount || !inputTokenUsdPrice) {
562
569
  return;
563
570
  }
@@ -566,7 +573,7 @@ export function getUsdInputFrom(quote: SelectedQuote): BigNumber | undefined {
566
573
 
567
574
  export function getUsdOutputFrom(quote: SelectedQuote): BigNumber | undefined {
568
575
  const outputAmount = quote?.outputAmount || null;
569
- const outputTokenUsdPrice = quote.swaps[quote.swaps.length - 1].to.usdPrice;
576
+ const outputTokenUsdPrice = quote.swaps[quote.swaps.length - 1]?.to.usdPrice;
570
577
  if (!outputAmount || !outputTokenUsdPrice) {
571
578
  return;
572
579
  }
@@ -296,7 +296,9 @@ export const calculateWalletUsdValue = (balances: BalanceState) => {
296
296
 
297
297
  function numberWithThousandSeparator(number: string | number): string {
298
298
  const parts = number.toString().split('.');
299
- parts[0] = formatThousandsWithCommas(parts[0]);
299
+ if (parts[0]) {
300
+ parts[0] = formatThousandsWithCommas(parts[0]);
301
+ }
300
302
  return parts.join('.');
301
303
  }
302
304
 
@@ -311,7 +313,7 @@ export const isExperimentalChain = (
311
313
  );
312
314
  return (
313
315
  cosmosExperimentalChainInfo &&
314
- cosmosExperimentalChainInfo[wallet]?.experimental
316
+ !!cosmosExperimentalChainInfo[wallet]?.experimental
315
317
  );
316
318
  };
317
319