@rango-dev/widget-embedded 0.14.1-next.15 → 0.14.1-next.17
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/BlockchainsSection/BlockchainsSection.d.ts.map +1 -1
- package/dist/constants/configs.d.ts +2 -0
- package/dist/constants/configs.d.ts.map +1 -0
- package/dist/hooks/usePrepareBlockchainList/index.d.ts +2 -0
- package/dist/hooks/usePrepareBlockchainList/index.d.ts.map +1 -0
- package/dist/hooks/usePrepareBlockchainList/usePrepareBlockchainList.constants.d.ts +2 -0
- package/dist/hooks/usePrepareBlockchainList/usePrepareBlockchainList.constants.d.ts.map +1 -0
- package/dist/hooks/{usePrepareBlockchainList.d.ts → usePrepareBlockchainList/usePrepareBlockchainList.d.ts} +1 -9
- package/dist/hooks/usePrepareBlockchainList/usePrepareBlockchainList.d.ts.map +1 -0
- package/dist/hooks/usePrepareBlockchainList/usePrepareBlockchainList.helpers.d.ts +10 -0
- package/dist/hooks/usePrepareBlockchainList/usePrepareBlockchainList.helpers.d.ts.map +1 -0
- package/dist/hooks/usePrepareBlockchainList/usePrepareBlockchainList.mock.d.ts +3 -0
- package/dist/hooks/usePrepareBlockchainList/usePrepareBlockchainList.mock.d.ts.map +1 -0
- package/dist/hooks/usePrepareBlockchainList/usePrepareBlockchainList.test.d.ts +2 -0
- package/dist/hooks/usePrepareBlockchainList/usePrepareBlockchainList.test.d.ts.map +1 -0
- package/dist/hooks/usePrepareBlockchainList/usePrepareBlockchainList.types.d.ts +11 -0
- package/dist/hooks/usePrepareBlockchainList/usePrepareBlockchainList.types.d.ts.map +1 -0
- package/dist/hooks/useSyncStoresWithConfig.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +4 -4
- package/dist/store/settings.d.ts +5 -0
- package/dist/store/settings.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/BlockchainsSection/BlockchainsSection.tsx +21 -6
- package/src/constants/configs.ts +1 -0
- package/src/hooks/usePrepareBlockchainList/index.ts +1 -0
- package/src/hooks/usePrepareBlockchainList/usePrepareBlockchainList.constants.ts +1 -0
- package/src/hooks/usePrepareBlockchainList/usePrepareBlockchainList.helpers.ts +108 -0
- package/src/hooks/usePrepareBlockchainList/usePrepareBlockchainList.mock.ts +3101 -0
- package/src/hooks/usePrepareBlockchainList/usePrepareBlockchainList.test.ts +273 -0
- package/src/hooks/usePrepareBlockchainList/usePrepareBlockchainList.ts +38 -0
- package/src/hooks/usePrepareBlockchainList/usePrepareBlockchainList.types.ts +12 -0
- package/src/hooks/useSyncStoresWithConfig.ts +49 -1
- package/src/store/settings.ts +34 -1
- package/dist/hooks/usePrepareBlockchainList.d.ts.map +0 -1
- package/src/hooks/usePrepareBlockchainList.ts +0 -125
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
import type { BlockchainMeta } from 'rango-sdk';
|
|
2
|
+
|
|
3
|
+
import { beforeEach, describe, expect, it } from 'vitest';
|
|
4
|
+
|
|
5
|
+
import { MOST_USED_BLOCKChAINS } from './usePrepareBlockchainList.constants';
|
|
6
|
+
import {
|
|
7
|
+
generateSortByPreferredBlockchainsFor,
|
|
8
|
+
prepare,
|
|
9
|
+
sortByMostUsedBlockchains,
|
|
10
|
+
} from './usePrepareBlockchainList.helpers';
|
|
11
|
+
import { sampleBlockchains } from './usePrepareBlockchainList.mock';
|
|
12
|
+
|
|
13
|
+
describe('usePrepareBlockchainList', () => {
|
|
14
|
+
let sample: BlockchainMeta[] = [];
|
|
15
|
+
|
|
16
|
+
beforeEach(() => {
|
|
17
|
+
sample = JSON.parse(JSON.stringify(sampleBlockchains));
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('should sort blockchains by most used ones.', () => {
|
|
21
|
+
const sortedBlockchainsList = sample.sort(sortByMostUsedBlockchains);
|
|
22
|
+
|
|
23
|
+
const mostUsedCount = MOST_USED_BLOCKChAINS.length;
|
|
24
|
+
const expected = MOST_USED_BLOCKChAINS;
|
|
25
|
+
const received = sortedBlockchainsList
|
|
26
|
+
.map((blockchain) => blockchain.name)
|
|
27
|
+
.slice(0, mostUsedCount);
|
|
28
|
+
|
|
29
|
+
expect(expected).toEqual(received);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('should sort blockchains by user preferences', () => {
|
|
33
|
+
const preferredBlockchains = ['UMEE', 'BANDCHAIN', 'LINEA'];
|
|
34
|
+
const sortedBlockchainsList = sample.sort(
|
|
35
|
+
generateSortByPreferredBlockchainsFor(preferredBlockchains)
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
const expected = [
|
|
39
|
+
'UMEE',
|
|
40
|
+
'BANDCHAIN',
|
|
41
|
+
'LINEA',
|
|
42
|
+
'ETH',
|
|
43
|
+
'BSC',
|
|
44
|
+
'ARBITRUM',
|
|
45
|
+
'POLYGON',
|
|
46
|
+
'ZKSYNC',
|
|
47
|
+
'STARKNET',
|
|
48
|
+
'OPTIMISM',
|
|
49
|
+
'AVAX_CCHAIN',
|
|
50
|
+
'POLYGONZK',
|
|
51
|
+
'TRON',
|
|
52
|
+
'BTC',
|
|
53
|
+
'COSMOS',
|
|
54
|
+
'OSMOSIS',
|
|
55
|
+
'NEUTRON',
|
|
56
|
+
'NOBLE',
|
|
57
|
+
'SOLANA',
|
|
58
|
+
'CRONOS',
|
|
59
|
+
'BNB',
|
|
60
|
+
'AURORA',
|
|
61
|
+
'MAYA',
|
|
62
|
+
'THOR',
|
|
63
|
+
'BOBA',
|
|
64
|
+
'MOONBEAM',
|
|
65
|
+
'MOONRIVER',
|
|
66
|
+
'OKC',
|
|
67
|
+
'BOBA_AVALANCHE',
|
|
68
|
+
'LTC',
|
|
69
|
+
'BCH',
|
|
70
|
+
'HECO',
|
|
71
|
+
'STARGAZE',
|
|
72
|
+
'CRYPTO_ORG',
|
|
73
|
+
'CHIHUAHUA',
|
|
74
|
+
'COMDEX',
|
|
75
|
+
'REGEN',
|
|
76
|
+
'IRIS',
|
|
77
|
+
'EMONEY',
|
|
78
|
+
'JUNO',
|
|
79
|
+
'STRIDE',
|
|
80
|
+
'MARS',
|
|
81
|
+
'TERRA',
|
|
82
|
+
'BITSONG',
|
|
83
|
+
'AKASH',
|
|
84
|
+
'KI',
|
|
85
|
+
'PERSISTENCE',
|
|
86
|
+
'MEDIBLOC',
|
|
87
|
+
'KUJIRA',
|
|
88
|
+
'SENTINEL',
|
|
89
|
+
'INJECTIVE',
|
|
90
|
+
'SECRET',
|
|
91
|
+
'KONSTELLATION',
|
|
92
|
+
'STARNAME',
|
|
93
|
+
'BITCANNA',
|
|
94
|
+
'DESMOS',
|
|
95
|
+
'LUMNETWORK',
|
|
96
|
+
];
|
|
97
|
+
const received = sortedBlockchainsList.map((blockchain) => blockchain.name);
|
|
98
|
+
|
|
99
|
+
expect(expected).toEqual(received);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it('should prepare the list by most used and user preferences', () => {
|
|
103
|
+
const listLimit = 10;
|
|
104
|
+
const preferredBlockchains = ['BTC', 'SOLANA', 'COSMOS', 'ETH'];
|
|
105
|
+
const expected = [
|
|
106
|
+
'BTC',
|
|
107
|
+
'SOLANA',
|
|
108
|
+
'ETH',
|
|
109
|
+
'COSMOS',
|
|
110
|
+
'OSMOSIS',
|
|
111
|
+
'BSC',
|
|
112
|
+
'ARBITRUM',
|
|
113
|
+
'POLYGON',
|
|
114
|
+
'ZKSYNC',
|
|
115
|
+
'STARKNET',
|
|
116
|
+
'OPTIMISM',
|
|
117
|
+
'AVAX_CCHAIN',
|
|
118
|
+
'POLYGONZK',
|
|
119
|
+
'LINEA',
|
|
120
|
+
'TRON',
|
|
121
|
+
'NEUTRON',
|
|
122
|
+
'NOBLE',
|
|
123
|
+
'CRONOS',
|
|
124
|
+
'BNB',
|
|
125
|
+
'AURORA',
|
|
126
|
+
'MAYA',
|
|
127
|
+
'THOR',
|
|
128
|
+
'BOBA',
|
|
129
|
+
'MOONBEAM',
|
|
130
|
+
'MOONRIVER',
|
|
131
|
+
'OKC',
|
|
132
|
+
'BOBA_AVALANCHE',
|
|
133
|
+
'LTC',
|
|
134
|
+
'BCH',
|
|
135
|
+
'HECO',
|
|
136
|
+
'STARGAZE',
|
|
137
|
+
'CRYPTO_ORG',
|
|
138
|
+
'CHIHUAHUA',
|
|
139
|
+
'BANDCHAIN',
|
|
140
|
+
'COMDEX',
|
|
141
|
+
'REGEN',
|
|
142
|
+
'IRIS',
|
|
143
|
+
'EMONEY',
|
|
144
|
+
'JUNO',
|
|
145
|
+
'STRIDE',
|
|
146
|
+
'MARS',
|
|
147
|
+
'TERRA',
|
|
148
|
+
'BITSONG',
|
|
149
|
+
'AKASH',
|
|
150
|
+
'KI',
|
|
151
|
+
'PERSISTENCE',
|
|
152
|
+
'MEDIBLOC',
|
|
153
|
+
'KUJIRA',
|
|
154
|
+
'SENTINEL',
|
|
155
|
+
'INJECTIVE',
|
|
156
|
+
'SECRET',
|
|
157
|
+
'KONSTELLATION',
|
|
158
|
+
'STARNAME',
|
|
159
|
+
'BITCANNA',
|
|
160
|
+
'UMEE',
|
|
161
|
+
'DESMOS',
|
|
162
|
+
'LUMNETWORK',
|
|
163
|
+
];
|
|
164
|
+
const received = prepare(sample, preferredBlockchains, {
|
|
165
|
+
limit: listLimit,
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
const receivedListNames = received.list.map(
|
|
169
|
+
(blockchain) => blockchain.name
|
|
170
|
+
);
|
|
171
|
+
const receivedMoreNames = received.more.map(
|
|
172
|
+
(blockchain) => blockchain.name
|
|
173
|
+
);
|
|
174
|
+
|
|
175
|
+
expect(received.list).toHaveLength(listLimit);
|
|
176
|
+
expect(received.more).toHaveLength(expected.length - listLimit);
|
|
177
|
+
expect(expected).toEqual([...receivedListNames, ...receivedMoreNames]);
|
|
178
|
+
|
|
179
|
+
// Check duplication
|
|
180
|
+
receivedListNames.forEach((listName) => {
|
|
181
|
+
expect(receivedMoreNames).not.toContain(listName);
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
// Check preferred blockchains to be on the main list
|
|
185
|
+
preferredBlockchains.forEach((blockchain) => {
|
|
186
|
+
expect(receivedListNames).toContain(blockchain);
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
it('should prepare the list correctly if user has a long list of preferences ', () => {
|
|
191
|
+
const listLimit = 10;
|
|
192
|
+
const preferredBlockchains = [
|
|
193
|
+
'ETH',
|
|
194
|
+
'BTC',
|
|
195
|
+
'SOLANA',
|
|
196
|
+
'CRYPTO_ORG',
|
|
197
|
+
'TRON',
|
|
198
|
+
'BOBA_AVALANCHE',
|
|
199
|
+
'AKASH',
|
|
200
|
+
'LUMNETWORK',
|
|
201
|
+
'KONSTELLATION',
|
|
202
|
+
'BANDCHAIN',
|
|
203
|
+
'INJECTIVE',
|
|
204
|
+
];
|
|
205
|
+
const expected = [
|
|
206
|
+
'ETH',
|
|
207
|
+
'BTC',
|
|
208
|
+
'SOLANA',
|
|
209
|
+
'CRYPTO_ORG',
|
|
210
|
+
'TRON',
|
|
211
|
+
'BOBA_AVALANCHE',
|
|
212
|
+
'AKASH',
|
|
213
|
+
'LUMNETWORK',
|
|
214
|
+
'KONSTELLATION',
|
|
215
|
+
'BANDCHAIN',
|
|
216
|
+
'INJECTIVE',
|
|
217
|
+
'COSMOS',
|
|
218
|
+
'OSMOSIS',
|
|
219
|
+
'BSC',
|
|
220
|
+
'ARBITRUM',
|
|
221
|
+
'POLYGON',
|
|
222
|
+
'ZKSYNC',
|
|
223
|
+
'STARKNET',
|
|
224
|
+
'OPTIMISM',
|
|
225
|
+
'AVAX_CCHAIN',
|
|
226
|
+
'POLYGONZK',
|
|
227
|
+
'LINEA',
|
|
228
|
+
'NEUTRON',
|
|
229
|
+
'NOBLE',
|
|
230
|
+
'CRONOS',
|
|
231
|
+
'BNB',
|
|
232
|
+
'AURORA',
|
|
233
|
+
'MAYA',
|
|
234
|
+
'THOR',
|
|
235
|
+
'BOBA',
|
|
236
|
+
'MOONBEAM',
|
|
237
|
+
'MOONRIVER',
|
|
238
|
+
'OKC',
|
|
239
|
+
'LTC',
|
|
240
|
+
'BCH',
|
|
241
|
+
'HECO',
|
|
242
|
+
'STARGAZE',
|
|
243
|
+
'CHIHUAHUA',
|
|
244
|
+
'COMDEX',
|
|
245
|
+
'REGEN',
|
|
246
|
+
'IRIS',
|
|
247
|
+
'EMONEY',
|
|
248
|
+
'JUNO',
|
|
249
|
+
'STRIDE',
|
|
250
|
+
'MARS',
|
|
251
|
+
'TERRA',
|
|
252
|
+
'BITSONG',
|
|
253
|
+
'KI',
|
|
254
|
+
'PERSISTENCE',
|
|
255
|
+
'MEDIBLOC',
|
|
256
|
+
'KUJIRA',
|
|
257
|
+
'SENTINEL',
|
|
258
|
+
'SECRET',
|
|
259
|
+
'STARNAME',
|
|
260
|
+
'BITCANNA',
|
|
261
|
+
'UMEE',
|
|
262
|
+
'DESMOS',
|
|
263
|
+
];
|
|
264
|
+
const received = prepare(sample, preferredBlockchains, {
|
|
265
|
+
limit: listLimit,
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
expect(expected).toEqual([
|
|
269
|
+
...received.list.map((blockchain) => blockchain.name),
|
|
270
|
+
...received.more.map((blockchain) => blockchain.name),
|
|
271
|
+
]);
|
|
272
|
+
});
|
|
273
|
+
});
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
PrepareListOptions,
|
|
3
|
+
PrepareListOutput,
|
|
4
|
+
} from './usePrepareBlockchainList.types';
|
|
5
|
+
import type { BlockchainMeta } from 'rango-sdk';
|
|
6
|
+
|
|
7
|
+
import { useEffect } from 'react';
|
|
8
|
+
|
|
9
|
+
import { useSettingsStore } from '../../store/settings';
|
|
10
|
+
|
|
11
|
+
import { prepare } from './usePrepareBlockchainList.helpers';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
*
|
|
15
|
+
* UI needs some specific logics like limiting the list and sorting,
|
|
16
|
+
* this function is getting the raw blockchains list and return a list for showing in UI.
|
|
17
|
+
*
|
|
18
|
+
*/
|
|
19
|
+
export function usePrepareBlockchainList(
|
|
20
|
+
blockchains: BlockchainMeta[],
|
|
21
|
+
options?: PrepareListOptions
|
|
22
|
+
): PrepareListOutput {
|
|
23
|
+
const { preferredBlockchains, addPreferredBlockchain } = useSettingsStore();
|
|
24
|
+
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
if (options?.selected) {
|
|
27
|
+
addPreferredBlockchain(options?.selected);
|
|
28
|
+
}
|
|
29
|
+
}, [options?.selected]);
|
|
30
|
+
|
|
31
|
+
const output = prepare(blockchains, preferredBlockchains, options);
|
|
32
|
+
|
|
33
|
+
return {
|
|
34
|
+
list: output.list,
|
|
35
|
+
more: output.more,
|
|
36
|
+
history: [],
|
|
37
|
+
};
|
|
38
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { WidgetConfig } from '../types';
|
|
2
2
|
import type { Asset } from 'rango-sdk';
|
|
3
3
|
|
|
4
|
-
import { useEffect, useRef } from 'react';
|
|
4
|
+
import { useEffect, useMemo, useRef } from 'react';
|
|
5
5
|
|
|
6
6
|
import { useBestRouteStore } from '../store/bestRoute';
|
|
7
7
|
import { useMetaStore } from '../store/meta';
|
|
@@ -15,6 +15,10 @@ export function useSyncStoresWithConfig(config: WidgetConfig | undefined) {
|
|
|
15
15
|
setToBlockchain,
|
|
16
16
|
setFromBlockchain,
|
|
17
17
|
setFromToken,
|
|
18
|
+
fromToken,
|
|
19
|
+
toToken,
|
|
20
|
+
fromBlockchain,
|
|
21
|
+
toBlockchain,
|
|
18
22
|
} = useBestRouteStore();
|
|
19
23
|
|
|
20
24
|
const {
|
|
@@ -25,6 +29,22 @@ export function useSyncStoresWithConfig(config: WidgetConfig | undefined) {
|
|
|
25
29
|
const { setAffiliateRef, setAffiliatePercent, setAffiliateWallets } =
|
|
26
30
|
useSettingsStore();
|
|
27
31
|
|
|
32
|
+
const fromTokensConfig = useMemo(
|
|
33
|
+
() => config?.from?.tokens,
|
|
34
|
+
[config?.from?.tokens]
|
|
35
|
+
);
|
|
36
|
+
const fromBlockchainsConfig = useMemo(
|
|
37
|
+
() => config?.from?.blockchains,
|
|
38
|
+
[config?.from?.blockchains]
|
|
39
|
+
);
|
|
40
|
+
const toTokensConfig = useMemo(
|
|
41
|
+
() => config?.to?.tokens,
|
|
42
|
+
[config?.to?.tokens]
|
|
43
|
+
);
|
|
44
|
+
const toBlockchainsConfig = useMemo(
|
|
45
|
+
() => config?.to?.blockchains,
|
|
46
|
+
[config?.to?.blockchains]
|
|
47
|
+
);
|
|
28
48
|
const prevConfigFromToken = useRef<Asset | undefined>(undefined);
|
|
29
49
|
const prevConfigToToken = useRef<Asset | undefined>(undefined);
|
|
30
50
|
const prevConfigFromBlockchain = useRef<string | undefined>(undefined);
|
|
@@ -62,6 +82,34 @@ export function useSyncStoresWithConfig(config: WidgetConfig | undefined) {
|
|
|
62
82
|
loadingMetaStatus,
|
|
63
83
|
]);
|
|
64
84
|
|
|
85
|
+
useEffect(() => {
|
|
86
|
+
if (fromToken && fromTokensConfig) {
|
|
87
|
+
if (!fromTokensConfig.some((token) => tokensAreEqual(token, fromToken))) {
|
|
88
|
+
setFromToken(null);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (fromBlockchain && fromBlockchainsConfig) {
|
|
93
|
+
if (!fromBlockchainsConfig.includes(fromBlockchain.name)) {
|
|
94
|
+
setFromBlockchain(null);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}, [fromTokensConfig, fromBlockchainsConfig]);
|
|
98
|
+
|
|
99
|
+
useEffect(() => {
|
|
100
|
+
if (toToken && toTokensConfig) {
|
|
101
|
+
if (!toTokensConfig.some((token) => tokensAreEqual(token, toToken))) {
|
|
102
|
+
setToToken(null);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (toBlockchain && toBlockchainsConfig) {
|
|
107
|
+
if (!toBlockchainsConfig.includes(toBlockchain.name)) {
|
|
108
|
+
setToBlockchain(null);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}, [toTokensConfig, toBlockchainsConfig]);
|
|
112
|
+
|
|
65
113
|
useEffect(() => {
|
|
66
114
|
if (loadingMetaStatus === 'success') {
|
|
67
115
|
const chain = blockchains.find(
|
package/src/store/settings.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { type Language } from '@rango-dev/ui';
|
|
|
2
2
|
import { create } from 'zustand';
|
|
3
3
|
import { persist, subscribeWithSelector } from 'zustand/middleware';
|
|
4
4
|
|
|
5
|
+
import { BLOCKCHAIN_LIST_SIZE } from '../constants/configs';
|
|
5
6
|
import { DEFAULT_LANGUAGE } from '../constants/languages';
|
|
6
7
|
import { DEFAULT_SLIPPAGE } from '../constants/swapSettings';
|
|
7
8
|
import { removeDuplicateFrom } from '../utils/common';
|
|
@@ -12,6 +13,8 @@ import createSelectors from './selectors';
|
|
|
12
13
|
export type ThemeMode = 'auto' | 'dark' | 'light';
|
|
13
14
|
|
|
14
15
|
export interface SettingsState {
|
|
16
|
+
/** Keeping a history of blockchains that user has selected (in Swap process) */
|
|
17
|
+
preferredBlockchains: string[];
|
|
15
18
|
slippage: number;
|
|
16
19
|
customSlippage: number | null;
|
|
17
20
|
infiniteApprove: boolean;
|
|
@@ -21,6 +24,7 @@ export interface SettingsState {
|
|
|
21
24
|
affiliateRef: string | null;
|
|
22
25
|
affiliatePercent: number | null;
|
|
23
26
|
affiliateWallets: { [key: string]: string } | null;
|
|
27
|
+
|
|
24
28
|
setSlippage: (slippage: number) => void;
|
|
25
29
|
setCustomSlippage: (customSlippage: number | null) => void;
|
|
26
30
|
toggleInfiniteApprove: () => void;
|
|
@@ -33,12 +37,14 @@ export interface SettingsState {
|
|
|
33
37
|
setAffiliateWallets: (
|
|
34
38
|
affiliateWallets: { [key: string]: string } | null
|
|
35
39
|
) => void;
|
|
40
|
+
addPreferredBlockchain: (blockchain: string) => void;
|
|
36
41
|
}
|
|
37
42
|
|
|
38
43
|
export const useSettingsStore = createSelectors(
|
|
39
44
|
create<SettingsState>()(
|
|
40
45
|
persist(
|
|
41
|
-
subscribeWithSelector((set) => ({
|
|
46
|
+
subscribeWithSelector((set, get) => ({
|
|
47
|
+
preferredBlockchains: [],
|
|
42
48
|
slippage: DEFAULT_SLIPPAGE,
|
|
43
49
|
customSlippage: null,
|
|
44
50
|
infiniteApprove: false,
|
|
@@ -48,6 +54,33 @@ export const useSettingsStore = createSelectors(
|
|
|
48
54
|
disabledLiquiditySources: [],
|
|
49
55
|
theme: 'auto',
|
|
50
56
|
language: DEFAULT_LANGUAGE,
|
|
57
|
+
addPreferredBlockchain: (blockchain) => {
|
|
58
|
+
const currentPreferredBlockchains = get().preferredBlockchains;
|
|
59
|
+
|
|
60
|
+
const noNeedToDoAnything = currentPreferredBlockchains.find(
|
|
61
|
+
(preferredBlockchain, index) => {
|
|
62
|
+
const isSameBlockchain = preferredBlockchain === blockchain;
|
|
63
|
+
const isInVisibleList = index <= BLOCKCHAIN_LIST_SIZE - 1;
|
|
64
|
+
|
|
65
|
+
return isSameBlockchain && isInVisibleList;
|
|
66
|
+
}
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
if (noNeedToDoAnything) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const nextPreferredBlockchains: string[] =
|
|
74
|
+
currentPreferredBlockchains.filter((preferredBlockchain) => {
|
|
75
|
+
const isSameBlockchain = preferredBlockchain === blockchain;
|
|
76
|
+
|
|
77
|
+
return !isSameBlockchain;
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
set(() => ({
|
|
81
|
+
preferredBlockchains: [blockchain, ...nextPreferredBlockchains],
|
|
82
|
+
}));
|
|
83
|
+
},
|
|
51
84
|
setSlippage: (slippage) =>
|
|
52
85
|
set(() => ({
|
|
53
86
|
slippage: slippage,
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"usePrepareBlockchainList.d.ts","sourceRoot":"","sources":["../../src/hooks/usePrepareBlockchainList.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAIhD,UAAU,kBAAkB;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,iBAAiB;IACzB,IAAI,EAAE,cAAc,EAAE,CAAC;IACvB,IAAI,EAAE,cAAc,EAAE,CAAC;CACxB;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,WAAW,EAAE,cAAc,EAAE,EAC7B,OAAO,CAAC,EAAE,kBAAkB,GAC3B,iBAAiB,CAgEnB"}
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
import type { BlockchainMeta } from 'rango-sdk';
|
|
2
|
-
|
|
3
|
-
import { useMemo, useRef } from 'react';
|
|
4
|
-
|
|
5
|
-
interface PrepareListOptions {
|
|
6
|
-
limit?: number;
|
|
7
|
-
selected?: string;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
interface PrepareListOutput {
|
|
11
|
-
list: BlockchainMeta[];
|
|
12
|
-
more: BlockchainMeta[];
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
*
|
|
17
|
-
* UI needs some specific logics like limiting the list and sorting,
|
|
18
|
-
* this function is getting the raw blockchains list and return a list for showing in UI.
|
|
19
|
-
*
|
|
20
|
-
*/
|
|
21
|
-
export function usePrepareBlockchainList(
|
|
22
|
-
blockchains: BlockchainMeta[],
|
|
23
|
-
options?: PrepareListOptions
|
|
24
|
-
): PrepareListOutput {
|
|
25
|
-
const prevSelectedBlockchain = useRef({ index: -1, name: '' });
|
|
26
|
-
|
|
27
|
-
blockchains.sort(sortByMostUsedBlockchains);
|
|
28
|
-
|
|
29
|
-
const blockchainsHash = blockchains
|
|
30
|
-
.map((blockchain) => blockchain.name)
|
|
31
|
-
.join('-');
|
|
32
|
-
|
|
33
|
-
return useMemo(() => {
|
|
34
|
-
const list: BlockchainMeta[] = blockchains;
|
|
35
|
-
let more: BlockchainMeta[] = [];
|
|
36
|
-
|
|
37
|
-
// Checking `limit` has set and it should be more than of the list items.
|
|
38
|
-
if (options?.limit && blockchains.length > options.limit) {
|
|
39
|
-
const start = options.limit;
|
|
40
|
-
/** Try find the blockchain and returns the index. */
|
|
41
|
-
const selectedIndex = options.selected
|
|
42
|
-
? blockchains.findIndex(
|
|
43
|
-
(blockchains) => blockchains.name === options.selected
|
|
44
|
-
)
|
|
45
|
-
: -1;
|
|
46
|
-
|
|
47
|
-
const prevSelectedBlockchainWasInMoreSection =
|
|
48
|
-
prevSelectedBlockchain.current.index > options.limit - 1 &&
|
|
49
|
-
!!blockchains.find(
|
|
50
|
-
(blockchains) =>
|
|
51
|
-
blockchains.name === prevSelectedBlockchain.current.name
|
|
52
|
-
);
|
|
53
|
-
|
|
54
|
-
/*
|
|
55
|
-
* If the selected blockchain is in `more` section, we should move it to front of the list
|
|
56
|
-
*/
|
|
57
|
-
if (
|
|
58
|
-
options.selected &&
|
|
59
|
-
((prevSelectedBlockchainWasInMoreSection &&
|
|
60
|
-
selectedIndex < options.limit - 1) ||
|
|
61
|
-
selectedIndex > options.limit - 1)
|
|
62
|
-
) {
|
|
63
|
-
blockchains.sort(
|
|
64
|
-
generateSortBySelectedFor(
|
|
65
|
-
prevSelectedBlockchainWasInMoreSection
|
|
66
|
-
? prevSelectedBlockchain.current.name
|
|
67
|
-
: options.selected
|
|
68
|
-
)
|
|
69
|
-
);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/*
|
|
73
|
-
* Splice will modify the original list and returns the deleted items
|
|
74
|
-
* We use the deleted items as `more`
|
|
75
|
-
*/
|
|
76
|
-
more = list.splice(start);
|
|
77
|
-
prevSelectedBlockchain.current = {
|
|
78
|
-
index: selectedIndex,
|
|
79
|
-
name: options.selected ?? '',
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
return {
|
|
84
|
-
list,
|
|
85
|
-
more,
|
|
86
|
-
};
|
|
87
|
-
}, [blockchainsHash]);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
function generateSortBySelectedFor(selected: string) {
|
|
91
|
-
/** Move `selected` blockchain to the front of list. */
|
|
92
|
-
return function sortBySelected(a: BlockchainMeta, b: BlockchainMeta) {
|
|
93
|
-
if (a.name === selected) {
|
|
94
|
-
return -1;
|
|
95
|
-
}
|
|
96
|
-
if (b.name === selected) {
|
|
97
|
-
return 1;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
return 0;
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/** There is a hardcoded list of blockchains that we want to show them first in the list. */
|
|
105
|
-
function sortByMostUsedBlockchains(a: BlockchainMeta, b: BlockchainMeta) {
|
|
106
|
-
const mostUsed = ['ETH', 'COSMOS', 'OSMOSIS'];
|
|
107
|
-
const aIndexInMostUsed = mostUsed.findIndex((token) => token === a.name);
|
|
108
|
-
const bIndexInMostUsed = mostUsed.findIndex((token) => token === b.name);
|
|
109
|
-
const aIsMostUsed = aIndexInMostUsed > -1;
|
|
110
|
-
const bIsMostUsed = bIndexInMostUsed > -1;
|
|
111
|
-
|
|
112
|
-
if (aIsMostUsed && bIsMostUsed) {
|
|
113
|
-
return aIndexInMostUsed > bIndexInMostUsed ? 1 : -1;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
if (aIsMostUsed) {
|
|
117
|
-
return -1;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
if (bIsMostUsed) {
|
|
121
|
-
return 1;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
return 0;
|
|
125
|
-
}
|