@aurora-is-near/intents-swap-widget 3.18.3 → 3.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/AllNetworksIcon.js +11 -0
- package/dist/components/AllNetworksIcon.js.map +1 -0
- package/dist/components/ChainShortcut.d.ts +15 -0
- package/dist/components/ChainShortcut.js +57 -0
- package/dist/components/ChainShortcut.js.map +1 -0
- package/dist/components/index.d.ts +2 -0
- package/dist/components/index.js +21 -17
- package/dist/components/index.js.map +1 -1
- package/dist/{config-BMvXuF1-.js → config-C47AYcMK.js} +913 -898
- package/dist/config-C47AYcMK.js.map +1 -0
- package/dist/config.d.ts +2 -0
- package/dist/config.js +2 -2
- package/dist/errors.js +1 -1
- package/dist/ext/alchemy/index.js +1 -1
- package/dist/ext/index.js +1 -1
- package/dist/features/BalanceRpcLoader/TokenBalanceLoader.js +1 -1
- package/dist/features/BalanceRpcLoader/index.js +1 -1
- package/dist/features/BalanceRpcLoader/useTokenBalanceRpc.js +1 -1
- package/dist/features/ChainsDropdown/ChainItem.d.ts +1 -0
- package/dist/features/ChainsDropdown/ChainItem.js +23 -14
- package/dist/features/ChainsDropdown/ChainItem.js.map +1 -1
- package/dist/features/ChainsDropdown/index.js +61 -94
- package/dist/features/ChainsDropdown/index.js.map +1 -1
- package/dist/features/ChainsSelector/index.d.ts +15 -0
- package/dist/features/ChainsSelector/index.js +108 -0
- package/dist/features/ChainsSelector/index.js.map +1 -0
- package/dist/features/DepositMethodSwitcher.js +1 -1
- package/dist/features/ErrorBoundary.js +1 -1
- package/dist/features/ExternalDeposit.js +4 -3
- package/dist/features/ExternalDeposit.js.map +1 -1
- package/dist/features/SendAddress/index.js +1 -1
- package/dist/features/SendAddress/useNotification.js +1 -1
- package/dist/features/SubmitButton/index.js +1 -1
- package/dist/features/SuccessScreen/index.js +1 -1
- package/dist/features/SuccessScreen/useSummaryItemsCount.js +1 -1
- package/dist/features/SwapDirectionSwitcher.js +1 -1
- package/dist/features/SwapQuote/SwapQuote.js +1 -1
- package/dist/features/SwapQuote/index.js +1 -1
- package/dist/features/TokenInput/TokenInput.js +1 -1
- package/dist/features/TokenInput/TokenInputEmpty.js +1 -1
- package/dist/features/TokenInput/TokenInputSource.js +1 -1
- package/dist/features/TokenInput/TokenInputTarget.js +1 -1
- package/dist/features/TokenInput/WalletBalance.js +1 -1
- package/dist/features/TokenInput/hooks/index.js +1 -1
- package/dist/features/TokenInput/hooks/useTokenInputBalance.js +1 -1
- package/dist/features/TokenInput/index.js +1 -1
- package/dist/features/TokensList/TokenItem.js +1 -1
- package/dist/features/TokensList/TokensList.js +1 -1
- package/dist/features/TokensList/index.js +1 -1
- package/dist/features/TokensModal.js +62 -64
- package/dist/features/TokensModal.js.map +1 -1
- package/dist/features/WalletCompatibilityCheck/WalletCompatibilityModal.js +5 -4
- package/dist/features/WalletCompatibilityCheck/WalletCompatibilityModal.js.map +1 -1
- package/dist/features/WalletCompatibilityCheck/index.js +1 -1
- package/dist/features/index.js +1 -1
- package/dist/hooks/index.js +1 -1
- package/dist/hooks/useAllTokens.js +1 -1
- package/dist/hooks/useChains.js +1 -1
- package/dist/hooks/useCompatibilityCheck.js +1 -1
- package/dist/hooks/useDefaultToken.js +1 -1
- package/dist/hooks/useExternalDepositStatus/index.js +1 -1
- package/dist/hooks/useExternalDepositStatus/usePoaExternalDepositStatus.js +1 -1
- package/dist/hooks/useIntentsBalance.js +1 -1
- package/dist/hooks/useIsCompatibilityCheckRequired.js +1 -1
- package/dist/hooks/useMakeDepositAddress.js +1 -1
- package/dist/hooks/useMakeIntentsTransfer.js +1 -1
- package/dist/hooks/useMakeNEARFtTransferCall.js +1 -1
- package/dist/hooks/useMakeQuote.js +1 -1
- package/dist/hooks/useMakeQuoteTransfer.js +1 -1
- package/dist/hooks/useMakeTransfer.js +1 -1
- package/dist/hooks/useMergedBalance.js +1 -1
- package/dist/hooks/useSwitchChain.js +1 -1
- package/dist/hooks/useTheme.js +1 -1
- package/dist/hooks/useTokenInputPair.js +1 -1
- package/dist/hooks/useTokens.js +1 -1
- package/dist/hooks/useTokensFiltered.d.ts +3 -1
- package/dist/hooks/useTokensFiltered.js +1 -1
- package/dist/hooks/useTokensIntentsUnique.js +1 -1
- package/dist/index.js +74 -70
- package/dist/index.js.map +1 -1
- package/dist/machine/effects/index.js +1 -1
- package/dist/machine/effects/useAlchemyBalanceEffect.js +1 -1
- package/dist/machine/effects/useBalancesUpdateEffect.js +1 -1
- package/dist/machine/effects/useMakeQuoteEffect.js +1 -1
- package/dist/machine/effects/useSelectedTokensEffect.js +1 -1
- package/dist/machine/effects/useSetTokenBalanceEffect.js +1 -1
- package/dist/machine/effects/useSetTokenIntentsTargetEffect.js +1 -1
- package/dist/machine/effects/useWalletConnEffect.js +1 -1
- package/dist/machine/events/index.js +1 -1
- package/dist/machine/events/tokenSelect.js +1 -1
- package/dist/machine/events/validateInputAndMoveTo.js +1 -1
- package/dist/machine/events/validateInputs.js +1 -1
- package/dist/machine/index.js +1 -1
- package/dist/machine/snap.js +1 -1
- package/dist/machine/subscriptions/checkers/isSendAddressAsConnected.js +1 -1
- package/dist/machine/subscriptions/index.js +1 -1
- package/dist/styles.css +1 -1
- package/dist/theme/ThemeProvider.js +1 -1
- package/dist/types/config.d.ts +3 -0
- package/dist/types/localisation.d.ts +1 -1
- package/dist/utils/intents/signers/near.js +1 -1
- package/dist/utils/intents/signers/privy.js +1 -1
- package/dist/utils/near/getNearNep141StorageBalance.js +1 -1
- package/dist/utils/tokens/sort.d.ts +2 -1
- package/dist/utils/tokens/sort.js +55 -24
- package/dist/utils/tokens/sort.js.map +1 -1
- package/dist/widgets/WidgetDeposit/WidgetDepositContent.js +2 -2
- package/dist/widgets/WidgetDeposit/WidgetDepositSkeleton.js +1 -1
- package/dist/widgets/WidgetSwap/WidgetSwapContent.js +2 -2
- package/dist/widgets/WidgetSwap/WidgetSwapSkeleton.js +1 -1
- package/dist/widgets/WidgetWithdraw/WidgetWithdrawContent.js +2 -2
- package/dist/widgets/WidgetWithdraw/WidgetWithdrawSkeleton.js +1 -1
- package/package.json +1 -1
- package/src/components/AllNetworksIcon.tsx +8 -0
- package/src/components/ChainShortcut.tsx +67 -0
- package/src/components/index.ts +2 -0
- package/src/config.tsx +13 -0
- package/src/features/ChainsDropdown/ChainItem.tsx +17 -4
- package/src/features/ChainsDropdown/index.tsx +10 -41
- package/src/features/ChainsSelector/index.tsx +113 -0
- package/src/features/TokensList/TokensList.tsx +2 -1
- package/src/features/TokensModal.tsx +29 -29
- package/src/hooks/useTokensFiltered.ts +4 -0
- package/src/types/config.ts +8 -0
- package/src/types/localisation.ts +1 -0
- package/src/utils/tokens/sort.ts +107 -20
- package/dist/config-BMvXuF1-.js.map +0 -1
- package/dist/features/ChainsDropdown/AllNetworksIcon.js +0 -7
- package/dist/features/ChainsDropdown/AllNetworksIcon.js.map +0 -1
- package/src/features/ChainsDropdown/AllNetworksIcon.tsx +0 -7
- /package/dist/{features/ChainsDropdown → components}/AllNetworksIcon.d.ts +0 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { ChainsDropdown } from '../ChainsDropdown';
|
|
2
|
+
|
|
3
|
+
import { CHAIN_ICONS } from '@/icons';
|
|
4
|
+
import { ChainShortcut } from '@/components/ChainShortcut';
|
|
5
|
+
|
|
6
|
+
import { cn } from '@/utils/cn';
|
|
7
|
+
import { useChains } from '@/hooks';
|
|
8
|
+
import { useConfig } from '@/config';
|
|
9
|
+
import { noop } from '@/utils/noop';
|
|
10
|
+
import { notReachable } from '@/utils/notReachable';
|
|
11
|
+
import type { Chains, ChainsFilter } from '@/types/chain';
|
|
12
|
+
|
|
13
|
+
type SelectedChain = 'all' | 'intents' | Chains;
|
|
14
|
+
|
|
15
|
+
type Msg = { type: 'on_select_chain'; chain: SelectedChain };
|
|
16
|
+
|
|
17
|
+
type Props = {
|
|
18
|
+
variant: 'source' | 'target';
|
|
19
|
+
chainsFilter: ChainsFilter;
|
|
20
|
+
selectedChain: SelectedChain;
|
|
21
|
+
className?: string;
|
|
22
|
+
onMsg: (msg: Msg) => void;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export const ChainsSelector = ({
|
|
26
|
+
variant,
|
|
27
|
+
chainsFilter,
|
|
28
|
+
selectedChain,
|
|
29
|
+
className,
|
|
30
|
+
onMsg,
|
|
31
|
+
}: Props) => {
|
|
32
|
+
const chains = useChains(variant);
|
|
33
|
+
const {
|
|
34
|
+
appIcon,
|
|
35
|
+
appName,
|
|
36
|
+
topChainShortcuts,
|
|
37
|
+
intentsAccountType,
|
|
38
|
+
showIntentTokens,
|
|
39
|
+
} = useConfig();
|
|
40
|
+
|
|
41
|
+
const topChains =
|
|
42
|
+
topChainShortcuts?.(intentsAccountType) ??
|
|
43
|
+
(['eth', 'btc', 'sol', 'near'] as const);
|
|
44
|
+
|
|
45
|
+
return (
|
|
46
|
+
<div
|
|
47
|
+
className={cn('flex items-center justify-between gap-sw-md', className)}>
|
|
48
|
+
<ChainShortcut.All
|
|
49
|
+
isSelected={selectedChain === 'all'}
|
|
50
|
+
onClick={() => onMsg({ type: 'on_select_chain', chain: 'all' })}
|
|
51
|
+
/>
|
|
52
|
+
|
|
53
|
+
<ul className="flex items-center gap-sw-md">
|
|
54
|
+
{showIntentTokens && (
|
|
55
|
+
<ChainShortcut
|
|
56
|
+
icon={appIcon}
|
|
57
|
+
label={appName}
|
|
58
|
+
isSelected={selectedChain === 'intents'}
|
|
59
|
+
onClick={() => onMsg({ type: 'on_select_chain', chain: 'intents' })}
|
|
60
|
+
/>
|
|
61
|
+
)}
|
|
62
|
+
|
|
63
|
+
{topChains.map((chain, index) => {
|
|
64
|
+
// last shortcut reserved for the selected chain
|
|
65
|
+
if (
|
|
66
|
+
index === topChains.length - 1 &&
|
|
67
|
+
![...topChains, 'all', 'intents'].includes(selectedChain)
|
|
68
|
+
) {
|
|
69
|
+
return (
|
|
70
|
+
<ChainShortcut
|
|
71
|
+
isSelected
|
|
72
|
+
key={selectedChain}
|
|
73
|
+
icon={CHAIN_ICONS[selectedChain as Chains]}
|
|
74
|
+
label={chains.find((c) => c.id === selectedChain)?.label ?? ''}
|
|
75
|
+
onClick={noop}
|
|
76
|
+
/>
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// check it here to respect global chain filters
|
|
81
|
+
if (chains.some((c) => c.id === chain)) {
|
|
82
|
+
return (
|
|
83
|
+
<ChainShortcut
|
|
84
|
+
key={chain}
|
|
85
|
+
icon={CHAIN_ICONS[chain]}
|
|
86
|
+
isSelected={selectedChain === chain}
|
|
87
|
+
label={chains.find((c) => c.id === chain)?.label ?? ''}
|
|
88
|
+
onClick={() => onMsg({ type: 'on_select_chain', chain })}
|
|
89
|
+
/>
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return null;
|
|
94
|
+
})}
|
|
95
|
+
</ul>
|
|
96
|
+
|
|
97
|
+
<ChainsDropdown
|
|
98
|
+
variant={variant}
|
|
99
|
+
selected={selectedChain}
|
|
100
|
+
chainsFilter={chainsFilter}
|
|
101
|
+
onMsg={(msg) => {
|
|
102
|
+
switch (msg.type) {
|
|
103
|
+
case 'on_click_chain':
|
|
104
|
+
onMsg({ type: 'on_select_chain', chain: msg.chain });
|
|
105
|
+
break;
|
|
106
|
+
default:
|
|
107
|
+
notReachable(msg.type, { throwError: false });
|
|
108
|
+
}
|
|
109
|
+
}}
|
|
110
|
+
/>
|
|
111
|
+
</div>
|
|
112
|
+
);
|
|
113
|
+
};
|
|
@@ -60,7 +60,7 @@ export const TokensList = ({
|
|
|
60
60
|
}: Props) => {
|
|
61
61
|
const { t } = useTypedTranslation();
|
|
62
62
|
const { ctx } = useUnsafeSnapshot();
|
|
63
|
-
const { walletSupportedChains, appName } = useConfig();
|
|
63
|
+
const { walletSupportedChains, appName, priorityAssets = [] } = useConfig();
|
|
64
64
|
const { mergedBalance } = useMergedBalance();
|
|
65
65
|
|
|
66
66
|
const filteredTokens = useTokensFiltered({
|
|
@@ -69,6 +69,7 @@ export const TokensList = ({
|
|
|
69
69
|
chainsFilter,
|
|
70
70
|
selectedChain,
|
|
71
71
|
walletSupportedChains,
|
|
72
|
+
priorityAssets,
|
|
72
73
|
});
|
|
73
74
|
|
|
74
75
|
const areTokensGrouped = ctx.walletAddress ? groupTokens : false;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { SearchW700 as Search } from '@material-symbols-svg/react-rounded/icons/search';
|
|
2
1
|
import { useRef, useState } from 'react';
|
|
2
|
+
import { SearchW700 as Search } from '@material-symbols-svg/react-rounded/icons/search';
|
|
3
3
|
|
|
4
|
-
import { TokensList } from './TokensList';
|
|
5
|
-
import { ChainsDropdown } from './ChainsDropdown';
|
|
6
4
|
import { useChains } from '../hooks';
|
|
5
|
+
import { TokensList } from './TokensList';
|
|
6
|
+
import { ChainsSelector } from './ChainsSelector';
|
|
7
|
+
|
|
7
8
|
import { Hr } from '@/components/Hr';
|
|
8
9
|
import { Card } from '@/components/Card';
|
|
9
10
|
import { Input } from '@/components/Input';
|
|
@@ -96,33 +97,32 @@ export const TokensModal = ({
|
|
|
96
97
|
<CloseButton onClick={handleClose} />
|
|
97
98
|
</header>
|
|
98
99
|
|
|
99
|
-
<
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
100
|
+
<Input
|
|
101
|
+
focusOnMount
|
|
102
|
+
icon={Search}
|
|
103
|
+
ref={searchInputRef}
|
|
104
|
+
defaultValue={search}
|
|
105
|
+
className="w-full"
|
|
106
|
+
placeholder="Search or paste address"
|
|
107
|
+
onChange={(e) => setSearch(e.target.value.trim())}
|
|
108
|
+
/>
|
|
109
|
+
|
|
110
|
+
{showChainsSelector && (
|
|
111
|
+
<ChainsSelector
|
|
112
|
+
variant={variant}
|
|
113
|
+
chainsFilter={chainsFilter}
|
|
114
|
+
selectedChain={selectedChain}
|
|
115
|
+
onMsg={(msg) => {
|
|
116
|
+
switch (msg.type) {
|
|
117
|
+
case 'on_select_chain':
|
|
118
|
+
setSelectedChain(msg.chain);
|
|
119
|
+
break;
|
|
120
|
+
default:
|
|
121
|
+
notReachable(msg.type);
|
|
122
|
+
}
|
|
123
|
+
}}
|
|
108
124
|
/>
|
|
109
|
-
|
|
110
|
-
<ChainsDropdown
|
|
111
|
-
variant={variant}
|
|
112
|
-
selected={selectedChain}
|
|
113
|
-
chainsFilter={chainsFilter}
|
|
114
|
-
onMsg={(msg) => {
|
|
115
|
-
switch (msg.type) {
|
|
116
|
-
case 'on_click_chain':
|
|
117
|
-
setSelectedChain(msg.chain);
|
|
118
|
-
break;
|
|
119
|
-
default:
|
|
120
|
-
notReachable(msg.type, { throwError: false });
|
|
121
|
-
}
|
|
122
|
-
}}
|
|
123
|
-
/>
|
|
124
|
-
)}
|
|
125
|
-
</div>
|
|
125
|
+
)}
|
|
126
126
|
|
|
127
127
|
{chainIsNotSupported && !!ctx.walletAddress && (
|
|
128
128
|
<>
|
|
@@ -8,6 +8,7 @@ import { createFilterByIntents } from '@/utils/tokens/filterByIntents';
|
|
|
8
8
|
import { createFilterBySearch } from '@/utils/tokens/filterBySearchString';
|
|
9
9
|
import { createFilterBySelectedChain } from '@/utils/tokens/filterBySelectedChain';
|
|
10
10
|
import type { Chains, ChainsFilter } from '@/types/chain';
|
|
11
|
+
import type { PriorityAssets } from '@/types/config';
|
|
11
12
|
|
|
12
13
|
export type TokensFilterOptions = {
|
|
13
14
|
variant: 'source' | 'target';
|
|
@@ -15,6 +16,7 @@ export type TokensFilterOptions = {
|
|
|
15
16
|
selectedChain: Chains | 'all' | 'intents';
|
|
16
17
|
chainsFilter: ChainsFilter;
|
|
17
18
|
walletSupportedChains: ReadonlyArray<Chains>;
|
|
19
|
+
priorityAssets: PriorityAssets;
|
|
18
20
|
};
|
|
19
21
|
|
|
20
22
|
// TODO: memoize
|
|
@@ -24,6 +26,7 @@ export const useTokensFiltered = ({
|
|
|
24
26
|
selectedChain,
|
|
25
27
|
chainsFilter,
|
|
26
28
|
walletSupportedChains,
|
|
29
|
+
priorityAssets,
|
|
27
30
|
}: TokensFilterOptions) => {
|
|
28
31
|
const chains = useChains(variant);
|
|
29
32
|
const { tokens } = useTokens(variant);
|
|
@@ -35,6 +38,7 @@ export const useTokensFiltered = ({
|
|
|
35
38
|
mergedBalance,
|
|
36
39
|
walletSupportedChains,
|
|
37
40
|
search,
|
|
41
|
+
priorityAssets,
|
|
38
42
|
);
|
|
39
43
|
|
|
40
44
|
const filteredTokens = tokens
|
package/src/types/config.ts
CHANGED
|
@@ -9,6 +9,10 @@ export type WalletAddresses = Partial<
|
|
|
9
9
|
|
|
10
10
|
export type IntentsAccountType = 'evm' | 'near' | 'sol';
|
|
11
11
|
|
|
12
|
+
export type PriorityAssets =
|
|
13
|
+
| ReadonlyArray<string>
|
|
14
|
+
| ReadonlyArray<readonly [Chains, string]>;
|
|
15
|
+
|
|
12
16
|
export type WidgetConfig = {
|
|
13
17
|
// Application metadata
|
|
14
18
|
appName: string;
|
|
@@ -38,6 +42,7 @@ export type WidgetConfig = {
|
|
|
38
42
|
allowedTokensList?: string[]; // assetIDs
|
|
39
43
|
allowedSourceTokensList?: string[];
|
|
40
44
|
allowedTargetTokensList?: string[];
|
|
45
|
+
priorityAssets?: PriorityAssets;
|
|
41
46
|
filterTokens: (token: Token) => boolean;
|
|
42
47
|
|
|
43
48
|
// Chains filtering
|
|
@@ -45,6 +50,9 @@ export type WidgetConfig = {
|
|
|
45
50
|
allowedChainsList?: Chains[];
|
|
46
51
|
allowedSourceChainsList?: Chains[];
|
|
47
52
|
allowedTargetChainsList?: Chains[];
|
|
53
|
+
topChainShortcuts?: (
|
|
54
|
+
intentsAccountType?: IntentsAccountType,
|
|
55
|
+
) => [Chains, Chains, Chains, Chains];
|
|
48
56
|
chainsFilter: {
|
|
49
57
|
source: ChainsFilter;
|
|
50
58
|
target: ChainsFilter;
|
package/src/utils/tokens/sort.ts
CHANGED
|
@@ -2,8 +2,73 @@ import { formatUnits } from 'ethers';
|
|
|
2
2
|
|
|
3
3
|
import { getTokenBalanceKey } from '../intents/getTokenBalanceKey';
|
|
4
4
|
import type { Token, TokenBalances } from '@/types/token';
|
|
5
|
+
import type { PriorityAssets } from '@/types/config';
|
|
5
6
|
import type { Chains } from '@/types/chain';
|
|
6
7
|
|
|
8
|
+
const compareByPriority = (
|
|
9
|
+
a: Token,
|
|
10
|
+
b: Token,
|
|
11
|
+
priorityAssets: PriorityAssets,
|
|
12
|
+
): number | null => {
|
|
13
|
+
if (a.isIntent || b.isIntent || priorityAssets.length === 0) {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const isPriorityToken = (token: Token): boolean => {
|
|
18
|
+
// by assetId
|
|
19
|
+
if (typeof priorityAssets[0] === 'string') {
|
|
20
|
+
return (priorityAssets as ReadonlyArray<string>).includes(token.assetId);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// by blockchain and symbol
|
|
24
|
+
return (priorityAssets as ReadonlyArray<readonly [Chains, string]>).some(
|
|
25
|
+
([blockchain, symbol]) =>
|
|
26
|
+
token.blockchain === blockchain &&
|
|
27
|
+
token.symbol.toLowerCase() === symbol.toLowerCase(),
|
|
28
|
+
);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const getPriorityIndex = (token: Token): number => {
|
|
32
|
+
// by assetId
|
|
33
|
+
if (typeof priorityAssets[0] === 'string') {
|
|
34
|
+
return (priorityAssets as ReadonlyArray<string>).indexOf(token.assetId);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// by blockchain and symbol
|
|
38
|
+
return (
|
|
39
|
+
priorityAssets as ReadonlyArray<readonly [Chains, string]>
|
|
40
|
+
).findIndex(
|
|
41
|
+
([blockchain, symbol]) =>
|
|
42
|
+
token.blockchain === blockchain &&
|
|
43
|
+
token.symbol.toLowerCase() === symbol.toLowerCase(),
|
|
44
|
+
);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const aIsPriority = isPriorityToken(a);
|
|
48
|
+
const bIsPriority = isPriorityToken(b);
|
|
49
|
+
|
|
50
|
+
if (aIsPriority && !bIsPriority) {
|
|
51
|
+
return -1;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (!aIsPriority && bIsPriority) {
|
|
55
|
+
return 1;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// If both are priority tokens, maintain their relative order based on the priority list
|
|
59
|
+
if (aIsPriority && bIsPriority) {
|
|
60
|
+
const aIndex = getPriorityIndex(a);
|
|
61
|
+
const bIndex = getPriorityIndex(b);
|
|
62
|
+
|
|
63
|
+
if (aIndex !== bIndex) {
|
|
64
|
+
return aIndex - bIndex;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Return null to indicate no priority difference, continue with other sorting criteria
|
|
69
|
+
return null;
|
|
70
|
+
};
|
|
71
|
+
|
|
7
72
|
const compareWithSearch = (
|
|
8
73
|
a: Token,
|
|
9
74
|
b: Token,
|
|
@@ -73,8 +138,9 @@ const compareWithSearch = (
|
|
|
73
138
|
return a.chainName.toLowerCase().localeCompare(b.chainName.toLowerCase());
|
|
74
139
|
};
|
|
75
140
|
|
|
76
|
-
const
|
|
141
|
+
const sortTokens = (
|
|
77
142
|
walletSupportedChains: ReadonlyArray<Chains>,
|
|
143
|
+
priorityAssets: PriorityAssets,
|
|
78
144
|
usdBalanceA: number | undefined,
|
|
79
145
|
usdBalanceB: number | undefined,
|
|
80
146
|
searchStr: string | undefined,
|
|
@@ -82,42 +148,61 @@ const sortTokensByUsdBalance = (
|
|
|
82
148
|
b: Token,
|
|
83
149
|
): number => {
|
|
84
150
|
const isIntent = a.isIntent || b.isIntent;
|
|
151
|
+
const hasBalanceA = usdBalanceA !== undefined && usdBalanceA > 0;
|
|
152
|
+
const hasBalanceB = usdBalanceB !== undefined && usdBalanceB > 0;
|
|
85
153
|
|
|
86
|
-
//
|
|
87
|
-
|
|
88
|
-
const bSupported = walletSupportedChains.includes(b.blockchain);
|
|
89
|
-
|
|
90
|
-
if (!isIntent && aSupported && !bSupported) {
|
|
154
|
+
// 1. Tokens with balance always come first
|
|
155
|
+
if (hasBalanceA && !hasBalanceB) {
|
|
91
156
|
return -1;
|
|
92
157
|
}
|
|
93
158
|
|
|
94
|
-
if (!
|
|
159
|
+
if (!hasBalanceA && hasBalanceB) {
|
|
95
160
|
return 1;
|
|
96
161
|
}
|
|
97
162
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
163
|
+
// 2. If both have balance, sort by balance amount and other criteria
|
|
164
|
+
if (hasBalanceA && hasBalanceB) {
|
|
165
|
+
// Sort supported chains first
|
|
166
|
+
const aSupported = walletSupportedChains.includes(a.blockchain);
|
|
167
|
+
const bSupported = walletSupportedChains.includes(b.blockchain);
|
|
168
|
+
|
|
169
|
+
if (!isIntent && aSupported && !bSupported) {
|
|
170
|
+
return -1;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if (!isIntent && !aSupported && bSupported) {
|
|
174
|
+
return 1;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Compare non-zero balances
|
|
178
|
+
if (usdBalanceA !== usdBalanceB) {
|
|
179
|
+
return (usdBalanceB ?? 0) - (usdBalanceA ?? 0);
|
|
180
|
+
}
|
|
101
181
|
|
|
102
|
-
|
|
103
|
-
if (!usdBalanceA && !usdBalanceB) {
|
|
182
|
+
// If balances equal, sort by search/name
|
|
104
183
|
return compareWithSearch(a, b, searchStr);
|
|
105
184
|
}
|
|
106
185
|
|
|
107
|
-
|
|
108
|
-
|
|
186
|
+
// 3. Both have no balance - prioritize by asset IDs or blockchain-symbol pairs (only for non-intent tokens)
|
|
187
|
+
const priorityComparison = compareByPriority(a, b, priorityAssets);
|
|
188
|
+
|
|
189
|
+
if (priorityComparison !== null) {
|
|
190
|
+
return priorityComparison;
|
|
109
191
|
}
|
|
110
192
|
|
|
111
|
-
|
|
193
|
+
// 4. For tokens without balance and not in priority list, sort by supported chains
|
|
194
|
+
const aSupported = walletSupportedChains.includes(a.blockchain);
|
|
195
|
+
const bSupported = walletSupportedChains.includes(b.blockchain);
|
|
196
|
+
|
|
197
|
+
if (!isIntent && aSupported && !bSupported) {
|
|
112
198
|
return -1;
|
|
113
199
|
}
|
|
114
200
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
return (usdBalanceB ?? 0) - (usdBalanceA ?? 0);
|
|
201
|
+
if (!isIntent && !aSupported && bSupported) {
|
|
202
|
+
return 1;
|
|
118
203
|
}
|
|
119
204
|
|
|
120
|
-
//
|
|
205
|
+
// 5. Finally, sort alphabetically by search/name
|
|
121
206
|
return compareWithSearch(a, b, searchStr);
|
|
122
207
|
};
|
|
123
208
|
|
|
@@ -125,6 +210,7 @@ export const createTokenSorter = (
|
|
|
125
210
|
tokensBalance: TokenBalances,
|
|
126
211
|
walletSupportedChains: ReadonlyArray<Chains>,
|
|
127
212
|
searchStr?: string | undefined,
|
|
213
|
+
priorityAssets: PriorityAssets = [],
|
|
128
214
|
) => {
|
|
129
215
|
return (a: Token, b: Token) => {
|
|
130
216
|
const recordA = tokensBalance[getTokenBalanceKey(a)];
|
|
@@ -145,8 +231,9 @@ export const createTokenSorter = (
|
|
|
145
231
|
|
|
146
232
|
const searchLower = searchStr?.trim().toLowerCase() ?? undefined;
|
|
147
233
|
|
|
148
|
-
return
|
|
234
|
+
return sortTokens(
|
|
149
235
|
walletSupportedChains,
|
|
236
|
+
priorityAssets,
|
|
150
237
|
usdBalanceA,
|
|
151
238
|
usdBalanceB,
|
|
152
239
|
searchLower,
|