@rango-dev/widget-embedded 0.17.1-next.24 → 0.17.1-next.26

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 (45) hide show
  1. package/dist/components/ConfirmWalletsModal/ConfirmWallets.styles.d.ts +3 -3
  2. package/dist/components/Quote/Quote.styles.d.ts +1 -1
  3. package/dist/components/TokenList/TokenList.d.ts.map +1 -1
  4. package/dist/components/TokenList/TokenList.helpers.d.ts +2 -2
  5. package/dist/components/TokenList/TokenList.helpers.d.ts.map +1 -1
  6. package/dist/components/TokenList/TokenList.types.d.ts +3 -9
  7. package/dist/components/TokenList/TokenList.types.d.ts.map +1 -1
  8. package/dist/components/TokenList/index.d.ts +0 -1
  9. package/dist/components/TokenList/index.d.ts.map +1 -1
  10. package/dist/containers/Wallets/Wallets.d.ts.map +1 -1
  11. package/dist/containers/WidgetInfo/WidgetInfo.d.ts.map +1 -1
  12. package/dist/containers/WidgetInfo/WidgetInfo.helpers.d.ts +12 -0
  13. package/dist/containers/WidgetInfo/WidgetInfo.helpers.d.ts.map +1 -0
  14. package/dist/containers/WidgetInfo/WidgetInfo.types.d.ts +2 -2
  15. package/dist/containers/WidgetInfo/WidgetInfo.types.d.ts.map +1 -1
  16. package/dist/index.d.ts +7 -4
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +1 -1
  19. package/dist/index.js.map +4 -4
  20. package/dist/pages/Home.d.ts.map +1 -1
  21. package/dist/pages/SelectSwapItemsPage.d.ts.map +1 -1
  22. package/dist/store/quote.d.ts +4 -5
  23. package/dist/store/quote.d.ts.map +1 -1
  24. package/dist/store/wallets.d.ts +5 -2
  25. package/dist/store/wallets.d.ts.map +1 -1
  26. package/dist/types/wallets.d.ts +15 -1
  27. package/dist/types/wallets.d.ts.map +1 -1
  28. package/dist/utils/wallets.d.ts +6 -8
  29. package/dist/utils/wallets.d.ts.map +1 -1
  30. package/package.json +8 -8
  31. package/src/components/TokenList/TokenList.helpers.ts +2 -2
  32. package/src/components/TokenList/TokenList.tsx +10 -12
  33. package/src/components/TokenList/TokenList.types.ts +3 -10
  34. package/src/components/TokenList/index.ts +0 -1
  35. package/src/containers/Wallets/Wallets.tsx +2 -3
  36. package/src/containers/WidgetInfo/WidgetInfo.helpers.ts +45 -0
  37. package/src/containers/WidgetInfo/WidgetInfo.tsx +4 -3
  38. package/src/containers/WidgetInfo/WidgetInfo.types.ts +2 -2
  39. package/src/index.ts +37 -2
  40. package/src/pages/Home.tsx +9 -33
  41. package/src/pages/SelectSwapItemsPage.tsx +3 -6
  42. package/src/store/quote.ts +2 -3
  43. package/src/store/wallets.ts +56 -29
  44. package/src/types/wallets.ts +18 -1
  45. package/src/utils/wallets.ts +80 -134
@@ -1,4 +1,4 @@
1
- import type { Wallet } from '../types';
1
+ import type { Balance, TokensBalance, Wallet } from '../types';
2
2
  import type { WalletType } from '@rango-dev/wallets-shared';
3
3
  import type { Token } from 'rango-sdk';
4
4
 
@@ -7,8 +7,10 @@ import { subscribeWithSelector } from 'zustand/middleware';
7
7
 
8
8
  import { httpService } from '../services/httpService';
9
9
  import {
10
+ createTokenHash,
10
11
  isAccountAndWalletMatched,
11
12
  makeBalanceFor,
13
+ makeTokensBalance,
12
14
  resetConnectedWalletState,
13
15
  } from '../utils/wallets';
14
16
 
@@ -33,9 +35,9 @@ export interface ConnectedWallet extends Wallet {
33
35
  loading: boolean;
34
36
  error: boolean;
35
37
  }
36
-
37
38
  interface WalletsStore {
38
39
  connectedWallets: ConnectedWallet[];
40
+ balances: TokensBalance;
39
41
  customDestination: string;
40
42
  loading: boolean;
41
43
  connectWallet: (accounts: Wallet[], tokens: Token[]) => void;
@@ -47,12 +49,14 @@ interface WalletsStore {
47
49
  tokens: Token[],
48
50
  shouldRetry?: boolean
49
51
  ) => void;
52
+ getBalanceFor: (token: Token) => Balance | null;
50
53
  }
51
54
 
52
55
  export const useWalletsStore = createSelectors(
53
56
  create<WalletsStore>()(
54
57
  subscribeWithSelector((set, get) => ({
55
58
  connectedWallets: [],
59
+ balances: {},
56
60
  customDestination: '',
57
61
  loading: false,
58
62
  connectWallet: (accounts, tokens) => {
@@ -92,21 +96,27 @@ export const useWalletsStore = createSelectors(
92
96
  connectedWallet.walletType !== walletType
93
97
  )
94
98
  .map((selectedWallet) => selectedWallet.chain);
99
+
100
+ const connectedWallets = state.connectedWallets
101
+ .filter(
102
+ (connectedWallet) => connectedWallet.walletType !== walletType
103
+ )
104
+ .map((connectedWallet) => {
105
+ const anyWalletSelectedForBlockchain = selectedWallets.includes(
106
+ connectedWallet.chain
107
+ );
108
+ if (anyWalletSelectedForBlockchain) {
109
+ return connectedWallet;
110
+ }
111
+ selectedWallets.push(connectedWallet.chain);
112
+ return { ...connectedWallet, selected: true };
113
+ });
114
+
115
+ const balances = makeTokensBalance(connectedWallets);
116
+
95
117
  return {
96
- connectedWallets: state.connectedWallets
97
- .filter(
98
- (connectedWallet) => connectedWallet.walletType !== walletType
99
- )
100
- .map((connectedWallet) => {
101
- const anyWalletSelectedForBlockchain = selectedWallets.includes(
102
- connectedWallet.chain
103
- );
104
- if (anyWalletSelectedForBlockchain) {
105
- return connectedWallet;
106
- }
107
- selectedWallets.push(connectedWallet.chain);
108
- return { ...connectedWallet, selected: true };
109
- }),
118
+ balances,
119
+ connectedWallets,
110
120
  };
111
121
  });
112
122
  },
@@ -159,9 +169,8 @@ export const useWalletsStore = createSelectors(
159
169
  const response = await httpService().getWalletsDetails(data);
160
170
  const retrievedBalance = response.wallets;
161
171
  if (retrievedBalance) {
162
- set((state) => ({
163
- loading: false,
164
- connectedWallets: state.connectedWallets.map(
172
+ set((state) => {
173
+ const connectedWallets = state.connectedWallets.map(
165
174
  (connectedWallet) => {
166
175
  const matchedAccount = accounts.find((account) =>
167
176
  isAccountAndWalletMatched(account, connectedWallet)
@@ -190,27 +199,45 @@ export const useWalletsStore = createSelectors(
190
199
  }
191
200
  : connectedWallet;
192
201
  }
193
- ),
194
- }));
202
+ );
203
+
204
+ const balances = makeTokensBalance(connectedWallets);
205
+
206
+ return {
207
+ loading: false,
208
+ balances,
209
+ connectedWallets,
210
+ };
211
+ });
195
212
  } else {
196
213
  throw new Error('Wallet not found');
197
214
  }
198
215
  } catch (error) {
199
- set((state) => ({
200
- loading: false,
201
- connectedWallets: state.connectedWallets.map((balance) => {
216
+ set((state) => {
217
+ const connectedWallets = state.connectedWallets.map((balance) => {
202
218
  return accounts.find((account) =>
203
219
  isAccountAndWalletMatched(account, balance)
204
220
  )
205
221
  ? resetConnectedWalletState(balance)
206
222
  : balance;
207
- }),
208
- }));
223
+ });
224
+
225
+ const balances = makeTokensBalance(connectedWallets);
226
+
227
+ return {
228
+ loading: false,
229
+ balances,
230
+ connectedWallets,
231
+ };
232
+ });
209
233
  }
210
234
  },
235
+ getBalanceFor: (token) => {
236
+ const { balances } = get();
237
+ const tokenHash = createTokenHash(token);
238
+ const balance = balances[tokenHash];
239
+ return balance ?? null;
240
+ },
211
241
  }))
212
242
  )
213
243
  );
214
-
215
- export const fetchingBalanceSelector = (state: WalletsStore) =>
216
- !!state.connectedWallets.find((wallet) => wallet.loading);
@@ -1,7 +1,24 @@
1
- import { WalletType } from '@rango-dev/wallets-shared';
1
+ import type { WalletType } from '@rango-dev/wallets-shared';
2
2
 
3
3
  export interface Wallet {
4
4
  chain: string;
5
5
  address: string;
6
6
  walletType: WalletType;
7
7
  }
8
+
9
+ export type Balance = {
10
+ amount: string;
11
+ decimals: number;
12
+ usdValue: string;
13
+ };
14
+
15
+ type Blockchain = string;
16
+ type TokenSymbol = string;
17
+ type Address = string;
18
+
19
+ /** `blockchain-symbol-Address` */
20
+ export type TokenHash = `${Blockchain}-${TokenSymbol}-${Address}`;
21
+
22
+ export type TokensBalance = {
23
+ [key: TokenHash]: Balance;
24
+ };
@@ -1,8 +1,8 @@
1
- import type { TokenWithBalance } from '../components/TokenList';
2
1
  import type { ConnectedWallet, TokenBalance } from '../store/wallets';
3
- import type { Wallet } from '../types';
2
+ import type { Balance, TokenHash, TokensBalance, Wallet } from '../types';
4
3
  import type { WalletInfo as ModalWalletInfo } from '@rango-dev/ui';
5
4
  import type {
5
+ Asset,
6
6
  Network,
7
7
  WalletInfo,
8
8
  WalletState,
@@ -29,6 +29,12 @@ import BigNumber from 'bignumber.js';
29
29
  import { isCosmosBlockchain } from 'rango-types';
30
30
 
31
31
  import { ZERO } from '../constants/numbers';
32
+ import {
33
+ BALANCE_MAX_DECIMALS,
34
+ BALANCE_MIN_DECIMALS,
35
+ USD_VALUE_MAX_DECIMALS,
36
+ USD_VALUE_MIN_DECIMALS,
37
+ } from '../constants/routing';
32
38
  import { EXCLUDED_WALLETS } from '../constants/wallets';
33
39
 
34
40
  import { numberToString } from './numbers';
@@ -218,43 +224,6 @@ export function getRequiredChains(quote: BestRouteResponse | null) {
218
224
 
219
225
  type Blockchain = { name: string; accounts: ConnectedWallet[] };
220
226
 
221
- export function getBalanceFromWallet(
222
- connectedWallets: ConnectedWallet[],
223
- chain: string,
224
- symbol: string,
225
- address: string | null
226
- ): TokenBalance | null {
227
- if (connectedWallets.length === 0) {
228
- return null;
229
- }
230
-
231
- const selectedChainWallets = connectedWallets.filter(
232
- (wallet) => wallet.chain === chain
233
- );
234
- if (selectedChainWallets.length === 0) {
235
- return null;
236
- }
237
-
238
- return (
239
- selectedChainWallets
240
- .map(
241
- (wallet) =>
242
- wallet.balances?.find(
243
- (balance) =>
244
- (address !== null && balance.address === address) ||
245
- (address === null &&
246
- balance.address === address &&
247
- balance.symbol === symbol)
248
- ) || null
249
- )
250
- .filter((balance) => balance !== null)
251
- .sort(
252
- (a, b) => parseFloat(b?.amount || '0') - parseFloat(a?.amount || '1')
253
- )
254
- .find(() => true) || null
255
- );
256
- }
257
-
258
227
  export function isAccountAndWalletMatched(
259
228
  account: Wallet,
260
229
  connectedWallet: ConnectedWallet
@@ -348,30 +317,6 @@ function numberWithThousandSeparator(number: string | number): string {
348
317
  return parts.join('.');
349
318
  }
350
319
 
351
- export const sortTokens = (tokens: TokenWithBalance[]): TokenWithBalance[] => {
352
- const walletConnected = !!tokens.some((token) => token.balance);
353
- if (!walletConnected) {
354
- return tokens
355
- .filter((token) => !token.address)
356
- .concat(
357
- tokens.filter((token) => token.address && !token.isSecondaryCoin),
358
- tokens.filter((token) => token.isSecondaryCoin)
359
- );
360
- }
361
-
362
- return tokens
363
- .filter((token) => !!token.balance)
364
- .sort(
365
- (tokenA, tokenB) =>
366
- parseFloat(tokenB.balance?.usdValue || '0') -
367
- parseFloat(tokenA.balance?.usdValue || '0')
368
- )
369
- .concat(
370
- tokens.filter((token) => !token.balance && !token.isSecondaryCoin),
371
- tokens.filter((token) => !token.balance && token.isSecondaryCoin)
372
- );
373
- };
374
-
375
320
  export const getUsdPrice = (
376
321
  blockchain: string,
377
322
  symbol: string,
@@ -415,98 +360,58 @@ export const getKeplrCompatibleConnectedWallets = (
415
360
  );
416
361
  };
417
362
 
418
- export function getTokensWithBalance(
419
- tokens: TokenWithBalance[],
420
- connectedWallets: ConnectedWallet[]
421
- ): TokenWithBalance[] {
422
- return tokens.map(({ balance, ...otherProps }) => {
423
- const tokenAmount = numberToString(
424
- new BigNumber(
425
- getBalanceFromWallet(
426
- connectedWallets,
427
- otherProps.blockchain,
428
- otherProps.symbol,
429
- otherProps.address
430
- )?.amount || ZERO
431
- )
432
- );
433
-
434
- let tokenUsdValue = '';
435
- if (otherProps.usdPrice) {
436
- tokenUsdValue = numberToString(
437
- new BigNumber(
438
- getBalanceFromWallet(
439
- connectedWallets,
440
- otherProps.blockchain,
441
- otherProps.symbol,
442
- otherProps.address
443
- )?.amount || ZERO
444
- ).multipliedBy(otherProps.usdPrice)
445
- );
446
- }
363
+ export function formatBalance(balance: Balance | null): Balance | null {
364
+ const formattedBalance: Balance | null = balance
365
+ ? {
366
+ ...balance,
367
+ amount: numberToString(
368
+ balance.amount,
369
+ BALANCE_MIN_DECIMALS,
370
+ BALANCE_MAX_DECIMALS
371
+ ),
372
+ usdValue: numberToString(
373
+ balance.usdValue,
374
+ USD_VALUE_MIN_DECIMALS,
375
+ USD_VALUE_MAX_DECIMALS
376
+ ),
377
+ }
378
+ : null;
447
379
 
448
- return {
449
- ...otherProps,
450
- ...(tokenAmount !== '0' && {
451
- balance: { amount: tokenAmount, usdValue: tokenUsdValue },
452
- }),
453
- };
454
- });
380
+ return formattedBalance;
455
381
  }
456
382
 
457
- export function getTokensBalanceFromWalletAndSort(
458
- tokens: TokenWithBalance[],
459
- connectedWallets: ConnectedWallet[]
383
+ export function sortTokensByBalance(
384
+ tokens: Token[],
385
+ getBalanceFor: (token: Token) => Balance | null
460
386
  ) {
461
- const list =
462
- connectedWallets.length > 0
463
- ? getTokensWithBalance(tokens, connectedWallets)
464
- : tokens;
465
- list.sort((tokenA, tokenB) => {
466
- if (tokenA.balance?.usdValue && tokenB.balance?.usdValue) {
387
+ tokens.sort((token1, token2) => {
388
+ const token1Balance = getBalanceFor(token1);
389
+ const token2Balance = getBalanceFor(token2);
390
+ if (token1Balance?.usdValue && token2Balance?.usdValue) {
467
391
  return (
468
- parseFloat(tokenB.balance.usdValue) -
469
- parseFloat(tokenA.balance.usdValue)
392
+ parseFloat(token2Balance.usdValue) - parseFloat(token1Balance.usdValue)
470
393
  );
471
394
  }
472
395
 
473
- if (!tokenA.balance?.usdValue && tokenB.balance?.usdValue) {
396
+ if (!token1Balance?.usdValue && token2Balance?.usdValue) {
474
397
  return 1;
475
398
  }
476
399
 
477
- if (tokenA.balance?.usdValue && !tokenB.balance?.usdValue) {
400
+ if (token1Balance?.usdValue && !token2Balance?.usdValue) {
478
401
  return -1;
479
402
  }
480
403
 
481
- if (!tokenA.balance?.usdValue && !tokenB.balance?.usdValue) {
404
+ if (!token1Balance?.usdValue && !token2Balance?.usdValue) {
482
405
  return (
483
- parseFloat(tokenB.balance?.amount || '0') -
484
- parseFloat(tokenA.balance?.amount || '0')
406
+ parseFloat(token2Balance?.amount || '0') -
407
+ parseFloat(token1Balance?.amount || '0')
485
408
  );
486
409
  }
487
410
 
488
411
  return 0;
489
412
  });
490
413
 
491
- return list;
492
- }
493
-
494
- export function getSortedTokens(
495
- chain: BlockchainMeta | null,
496
- tokens: Token[],
497
- connectedWallets: ConnectedWallet[],
498
- otherChainTokens: TokenWithBalance[]
499
- ): TokenWithBalance[] {
500
- const fromChainEqualsToToBlockchain =
501
- chain?.name === otherChainTokens[0]?.name;
502
- if (fromChainEqualsToToBlockchain) {
503
- return otherChainTokens;
504
- }
505
-
506
- const filteredTokens = tokens.filter(
507
- (token) => token.blockchain === chain?.name
508
- );
509
- return sortTokens(getTokensWithBalance(filteredTokens, connectedWallets));
414
+ return tokens;
510
415
  }
511
416
 
512
417
  export function tokensAreEqual(
@@ -568,3 +473,44 @@ export function getAddress({
568
473
  connectedWallet.chain === chain
569
474
  )?.address;
570
475
  }
476
+
477
+ export function createTokenHash(token: Asset): TokenHash {
478
+ return `${token.blockchain}-${token.symbol}-${token.address ?? ''}`;
479
+ }
480
+
481
+ export function makeTokensBalance(connectedWallets: ConnectedWallet[]) {
482
+ return connectedWallets
483
+ .flatMap((wallet) => wallet.balances)
484
+ .reduce((balances: TokensBalance, balance) => {
485
+ const currentBalance = {
486
+ amount: balance?.amount ?? '',
487
+ decimals: balance?.decimal ?? 0,
488
+ usdValue: balance?.usdPrice
489
+ ? new BigNumber(balance?.usdPrice ?? ZERO)
490
+ .multipliedBy(balance?.amount)
491
+ .toString()
492
+ : '',
493
+ };
494
+
495
+ const tokenHash = balance
496
+ ? createTokenHash({
497
+ symbol: balance.symbol,
498
+ blockchain: balance.chain,
499
+ address: balance.address,
500
+ })
501
+ : null;
502
+
503
+ const prevBalance = tokenHash ? balances[tokenHash] : null;
504
+
505
+ const shouldUpdateBalance =
506
+ tokenHash &&
507
+ (!prevBalance ||
508
+ (prevBalance && prevBalance.amount < currentBalance.amount));
509
+
510
+ if (shouldUpdateBalance) {
511
+ balances[tokenHash] = currentBalance;
512
+ }
513
+
514
+ return balances;
515
+ }, {});
516
+ }