@pancakeswap/token-lists 0.0.15 → 0.0.16
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/.turbo/turbo-build.log +9 -9
- package/CHANGELOG.md +7 -0
- package/dist/react.d.ts +17 -2
- package/dist/react.js +52 -3
- package/dist/react.mjs +53 -6
- package/package.json +5 -5
- package/react/getTokenList.ts +6 -4
- package/react/index.test.ts +2 -0
- package/react/lists.ts +53 -1
- package/react/useFetchListCallback.ts +4 -0
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @pancakeswap/token-lists@0.0.
|
|
2
|
+
> @pancakeswap/token-lists@0.0.16 build /home/runner/work/pancake-frontend/pancake-frontend/packages/token-lists
|
|
3
3
|
> tsup
|
|
4
4
|
|
|
5
5
|
CLI Building entry: {"index":"./src/index.ts","react":"./react/index.ts"}
|
|
@@ -9,16 +9,16 @@ CLI Using tsup config: /home/runner/work/pancake-frontend/pancake-frontend/packa
|
|
|
9
9
|
CLI Target: es6
|
|
10
10
|
ESM Build start
|
|
11
11
|
CJS Build start
|
|
12
|
-
CJS dist/index.js 783.00 B
|
|
13
|
-
CJS dist/chunk-YOAEDKQH.js 4.28 KB
|
|
14
|
-
CJS dist/react.js 22.13 KB
|
|
15
|
-
CJS ⚡️ Build success in 984ms
|
|
16
12
|
ESM dist/index.mjs 129.00 B
|
|
17
13
|
ESM dist/chunk-DC45HQOL.mjs 4.05 KB
|
|
18
|
-
ESM dist/react.mjs
|
|
19
|
-
ESM ⚡️ Build success in
|
|
14
|
+
ESM dist/react.mjs 23.29 KB
|
|
15
|
+
ESM ⚡️ Build success in 1305ms
|
|
16
|
+
CJS dist/index.js 783.00 B
|
|
17
|
+
CJS dist/chunk-YOAEDKQH.js 4.28 KB
|
|
18
|
+
CJS dist/react.js 24.16 KB
|
|
19
|
+
CJS ⚡️ Build success in 1305ms
|
|
20
20
|
DTS Build start
|
|
21
|
-
DTS ⚡️ Build success in
|
|
21
|
+
DTS ⚡️ Build success in 13852ms
|
|
22
22
|
DTS dist/index.d.ts 1.68 KB
|
|
23
|
-
DTS dist/react.d.ts
|
|
23
|
+
DTS dist/react.d.ts 3.50 KB
|
|
24
24
|
DTS dist/types-d6730d17.d.ts 1.03 KB
|
package/CHANGELOG.md
CHANGED
package/dist/react.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import * as _reduxjs_toolkit from '@reduxjs/toolkit';
|
|
2
2
|
import { ActionCreatorWithPayload } from '@reduxjs/toolkit';
|
|
3
3
|
import { a as TokenList, V as Version } from './types-d6730d17.js';
|
|
4
|
+
import * as jotai_vanilla_utils_atomFamily from 'jotai/vanilla/utils/atomFamily';
|
|
4
5
|
import * as jotai from 'jotai';
|
|
6
|
+
import * as src from 'src';
|
|
5
7
|
import * as _reduxjs_toolkit_dist_createReducer from '@reduxjs/toolkit/dist/createReducer';
|
|
6
8
|
|
|
7
9
|
declare const fetchTokenList: Readonly<{
|
|
@@ -32,7 +34,7 @@ declare const updateListVersion: _reduxjs_toolkit.ActionCreatorWithoutPayload<"l
|
|
|
32
34
|
* Contains the logic for resolving a list URL to a validated token list
|
|
33
35
|
* @param listUrl list url
|
|
34
36
|
*/
|
|
35
|
-
declare function getTokenList(listUrl: string): Promise<TokenList>;
|
|
37
|
+
declare function getTokenList(listUrl: string): Promise<TokenList | undefined>;
|
|
36
38
|
|
|
37
39
|
interface ListsState {
|
|
38
40
|
readonly byUrl: {
|
|
@@ -50,12 +52,25 @@ type ListByUrlState = ListsState['byUrl'][string];
|
|
|
50
52
|
declare const NEW_LIST_STATE: ListByUrlState;
|
|
51
53
|
declare const createTokenListReducer: (initialState: ListsState, DEFAULT_LIST_OF_LISTS: string[], DEFAULT_ACTIVE_LIST_URLS: string[]) => _reduxjs_toolkit_dist_createReducer.ReducerWithInitialState<ListsState>;
|
|
52
54
|
|
|
55
|
+
declare function findTokenByAddress(state: ListsState, chainId: number, address: string): src.TokenInfo | undefined;
|
|
56
|
+
declare function findTokenBySymbol(state: ListsState, chainId: number, symbol: string): src.TokenInfo | undefined;
|
|
53
57
|
declare const createListsAtom: (storeName: string, reducer: any, initialState: any) => {
|
|
54
58
|
listsAtom: jotai.WritableAtom<ListsState, any, void>;
|
|
59
|
+
tokenAtom: jotai_vanilla_utils_atomFamily.AtomFamily<{
|
|
60
|
+
chainId: number;
|
|
61
|
+
address: string;
|
|
62
|
+
}, jotai.Atom<src.TokenInfo | undefined>>;
|
|
63
|
+
tokenBySymbolAtom: jotai_vanilla_utils_atomFamily.AtomFamily<{
|
|
64
|
+
chainId: number;
|
|
65
|
+
symbol: string;
|
|
66
|
+
}, jotai.Atom<src.TokenInfo | undefined>>;
|
|
67
|
+
fetchListAtom: jotai.WritableAtom<null, [string], Promise<void>> & {
|
|
68
|
+
init: null;
|
|
69
|
+
};
|
|
55
70
|
useListStateReady: () => boolean;
|
|
56
71
|
useListState: () => [ListsState, (...args: any) => void];
|
|
57
72
|
};
|
|
58
73
|
|
|
59
74
|
declare function useFetchListCallback(dispatch: (action?: unknown) => void): (listUrl: string, sendDispatch?: boolean) => Promise<TokenList>;
|
|
60
75
|
|
|
61
|
-
export { ListByUrlState, ListsState, NEW_LIST_STATE, acceptListUpdate, addList, createListsAtom, createTokenListReducer, disableList, enableList, fetchTokenList, getTokenList, rejectVersionUpdate, removeList, updateListVersion, useFetchListCallback };
|
|
76
|
+
export { ListByUrlState, ListsState, NEW_LIST_STATE, acceptListUpdate, addList, createListsAtom, createTokenListReducer, disableList, enableList, fetchTokenList, findTokenByAddress, findTokenBySymbol, getTokenList, rejectVersionUpdate, removeList, updateListVersion, useFetchListCallback };
|
package/dist/react.js
CHANGED
|
@@ -458,9 +458,7 @@ function getTokenList(listUrl) {
|
|
|
458
458
|
}
|
|
459
459
|
return json;
|
|
460
460
|
} catch (error) {
|
|
461
|
-
|
|
462
|
-
throw new Error(`Failed to download list ${listUrl}`);
|
|
463
|
-
}
|
|
461
|
+
return void 0;
|
|
464
462
|
}
|
|
465
463
|
}
|
|
466
464
|
throw new Error("Unrecognized list URL protocol.");
|
|
@@ -482,6 +480,28 @@ var noopStorage = {
|
|
|
482
480
|
removeItem: () => Promise.resolve(noop())
|
|
483
481
|
};
|
|
484
482
|
var EMPTY = Symbol();
|
|
483
|
+
function findTokenByAddress(state, chainId, address) {
|
|
484
|
+
var _a, _b;
|
|
485
|
+
const urls = (_a = state.activeListUrls) != null ? _a : Object.keys(state.byUrl);
|
|
486
|
+
for (const url of urls) {
|
|
487
|
+
const list = (_b = state.byUrl[url]) == null ? void 0 : _b.current;
|
|
488
|
+
const token = list == null ? void 0 : list.tokens.find((t) => t.chainId === chainId && t.address.toLowerCase() === address.toLowerCase());
|
|
489
|
+
if (token)
|
|
490
|
+
return token;
|
|
491
|
+
}
|
|
492
|
+
return void 0;
|
|
493
|
+
}
|
|
494
|
+
function findTokenBySymbol(state, chainId, symbol) {
|
|
495
|
+
var _a, _b;
|
|
496
|
+
const urls = (_a = state.activeListUrls) != null ? _a : Object.keys(state.byUrl);
|
|
497
|
+
for (const url of urls) {
|
|
498
|
+
const list = (_b = state.byUrl[url]) == null ? void 0 : _b.current;
|
|
499
|
+
const token = list == null ? void 0 : list.tokens.find((t) => t.chainId === chainId && t.symbol.toLowerCase() === symbol.toLowerCase());
|
|
500
|
+
if (token)
|
|
501
|
+
return token;
|
|
502
|
+
}
|
|
503
|
+
return void 0;
|
|
504
|
+
}
|
|
485
505
|
var createListsAtom = (storeName, reducer, initialState) => {
|
|
486
506
|
function IndexedDBStorage(dbName) {
|
|
487
507
|
if (typeof window !== "undefined") {
|
|
@@ -521,6 +541,27 @@ var createListsAtom = (storeName, reducer, initialState) => {
|
|
|
521
541
|
})
|
|
522
542
|
);
|
|
523
543
|
const isReadyAtom = utils.loadable(listsStorageAtom);
|
|
544
|
+
const tokenAtom = utils.atomFamily(
|
|
545
|
+
(key) => jotai.atom((get) => findTokenByAddress(get(defaultStateAtom), key.chainId, key.address))
|
|
546
|
+
);
|
|
547
|
+
const tokenBySymbolAtom = utils.atomFamily(
|
|
548
|
+
(key) => jotai.atom((get) => findTokenBySymbol(get(defaultStateAtom), key.chainId, key.symbol))
|
|
549
|
+
);
|
|
550
|
+
const fetchListAtom = jotai.atom(null, (get, set, url) => chunkYOAEDKQH_js.__async(void 0, null, function* () {
|
|
551
|
+
const state = get(defaultStateAtom);
|
|
552
|
+
const listState = state.byUrl[url];
|
|
553
|
+
if ((listState == null ? void 0 : listState.current) || (listState == null ? void 0 : listState.loadingRequestId)) {
|
|
554
|
+
return;
|
|
555
|
+
}
|
|
556
|
+
const requestId = toolkit.nanoid();
|
|
557
|
+
set(defaultStateAtom, fetchTokenList.pending({ url, requestId }));
|
|
558
|
+
try {
|
|
559
|
+
const tokenList = yield getTokenList(url);
|
|
560
|
+
set(defaultStateAtom, fetchTokenList.fulfilled({ url, tokenList, requestId }));
|
|
561
|
+
} catch (error) {
|
|
562
|
+
set(defaultStateAtom, fetchTokenList.rejected({ url, requestId, errorMessage: error.message }));
|
|
563
|
+
}
|
|
564
|
+
}));
|
|
524
565
|
function useListState() {
|
|
525
566
|
return jotai.useAtom(defaultStateAtom);
|
|
526
567
|
}
|
|
@@ -530,6 +571,9 @@ var createListsAtom = (storeName, reducer, initialState) => {
|
|
|
530
571
|
}
|
|
531
572
|
return {
|
|
532
573
|
listsAtom: defaultStateAtom,
|
|
574
|
+
tokenAtom,
|
|
575
|
+
tokenBySymbolAtom,
|
|
576
|
+
fetchListAtom,
|
|
533
577
|
useListStateReady,
|
|
534
578
|
useListState
|
|
535
579
|
};
|
|
@@ -665,6 +709,9 @@ function useFetchListCallback(dispatch) {
|
|
|
665
709
|
dispatch(fetchTokenList.pending({ requestId, url: listUrl }));
|
|
666
710
|
}
|
|
667
711
|
return getTokenList(listUrl).then((tokenList) => {
|
|
712
|
+
if (!tokenList) {
|
|
713
|
+
throw new Error("Token list not found");
|
|
714
|
+
}
|
|
668
715
|
if (sendDispatch) {
|
|
669
716
|
dispatch(fetchTokenList.fulfilled({ url: listUrl, tokenList, requestId }));
|
|
670
717
|
}
|
|
@@ -690,6 +737,8 @@ exports.createTokenListReducer = createTokenListReducer;
|
|
|
690
737
|
exports.disableList = disableList;
|
|
691
738
|
exports.enableList = enableList;
|
|
692
739
|
exports.fetchTokenList = fetchTokenList;
|
|
740
|
+
exports.findTokenByAddress = findTokenByAddress;
|
|
741
|
+
exports.findTokenBySymbol = findTokenBySymbol;
|
|
693
742
|
exports.getTokenList = getTokenList;
|
|
694
743
|
exports.rejectVersionUpdate = rejectVersionUpdate;
|
|
695
744
|
exports.removeList = removeList;
|
package/dist/react.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { __async, __spreadProps, __spreadValues, getVersionUpgrade } from './chunk-DC45HQOL.mjs';
|
|
2
|
-
import { createAction,
|
|
2
|
+
import { createAction, nanoid, createReducer } from '@reduxjs/toolkit';
|
|
3
3
|
import { atom, useAtom, useAtomValue } from 'jotai';
|
|
4
|
-
import { atomWithStorage, loadable } from 'jotai/utils';
|
|
4
|
+
import { atomWithStorage, loadable, atomFamily } from 'jotai/utils';
|
|
5
5
|
import localForage from 'localforage';
|
|
6
6
|
import { useCallback } from 'react';
|
|
7
7
|
|
|
@@ -452,9 +452,7 @@ function getTokenList(listUrl) {
|
|
|
452
452
|
}
|
|
453
453
|
return json;
|
|
454
454
|
} catch (error) {
|
|
455
|
-
|
|
456
|
-
throw new Error(`Failed to download list ${listUrl}`);
|
|
457
|
-
}
|
|
455
|
+
return void 0;
|
|
458
456
|
}
|
|
459
457
|
}
|
|
460
458
|
throw new Error("Unrecognized list URL protocol.");
|
|
@@ -476,6 +474,28 @@ var noopStorage = {
|
|
|
476
474
|
removeItem: () => Promise.resolve(noop())
|
|
477
475
|
};
|
|
478
476
|
var EMPTY = Symbol();
|
|
477
|
+
function findTokenByAddress(state, chainId, address) {
|
|
478
|
+
var _a, _b;
|
|
479
|
+
const urls = (_a = state.activeListUrls) != null ? _a : Object.keys(state.byUrl);
|
|
480
|
+
for (const url of urls) {
|
|
481
|
+
const list = (_b = state.byUrl[url]) == null ? void 0 : _b.current;
|
|
482
|
+
const token = list == null ? void 0 : list.tokens.find((t) => t.chainId === chainId && t.address.toLowerCase() === address.toLowerCase());
|
|
483
|
+
if (token)
|
|
484
|
+
return token;
|
|
485
|
+
}
|
|
486
|
+
return void 0;
|
|
487
|
+
}
|
|
488
|
+
function findTokenBySymbol(state, chainId, symbol) {
|
|
489
|
+
var _a, _b;
|
|
490
|
+
const urls = (_a = state.activeListUrls) != null ? _a : Object.keys(state.byUrl);
|
|
491
|
+
for (const url of urls) {
|
|
492
|
+
const list = (_b = state.byUrl[url]) == null ? void 0 : _b.current;
|
|
493
|
+
const token = list == null ? void 0 : list.tokens.find((t) => t.chainId === chainId && t.symbol.toLowerCase() === symbol.toLowerCase());
|
|
494
|
+
if (token)
|
|
495
|
+
return token;
|
|
496
|
+
}
|
|
497
|
+
return void 0;
|
|
498
|
+
}
|
|
479
499
|
var createListsAtom = (storeName, reducer, initialState) => {
|
|
480
500
|
function IndexedDBStorage(dbName) {
|
|
481
501
|
if (typeof window !== "undefined") {
|
|
@@ -515,6 +535,27 @@ var createListsAtom = (storeName, reducer, initialState) => {
|
|
|
515
535
|
})
|
|
516
536
|
);
|
|
517
537
|
const isReadyAtom = loadable(listsStorageAtom);
|
|
538
|
+
const tokenAtom = atomFamily(
|
|
539
|
+
(key) => atom((get) => findTokenByAddress(get(defaultStateAtom), key.chainId, key.address))
|
|
540
|
+
);
|
|
541
|
+
const tokenBySymbolAtom = atomFamily(
|
|
542
|
+
(key) => atom((get) => findTokenBySymbol(get(defaultStateAtom), key.chainId, key.symbol))
|
|
543
|
+
);
|
|
544
|
+
const fetchListAtom = atom(null, (get, set, url) => __async(void 0, null, function* () {
|
|
545
|
+
const state = get(defaultStateAtom);
|
|
546
|
+
const listState = state.byUrl[url];
|
|
547
|
+
if ((listState == null ? void 0 : listState.current) || (listState == null ? void 0 : listState.loadingRequestId)) {
|
|
548
|
+
return;
|
|
549
|
+
}
|
|
550
|
+
const requestId = nanoid();
|
|
551
|
+
set(defaultStateAtom, fetchTokenList.pending({ url, requestId }));
|
|
552
|
+
try {
|
|
553
|
+
const tokenList = yield getTokenList(url);
|
|
554
|
+
set(defaultStateAtom, fetchTokenList.fulfilled({ url, tokenList, requestId }));
|
|
555
|
+
} catch (error) {
|
|
556
|
+
set(defaultStateAtom, fetchTokenList.rejected({ url, requestId, errorMessage: error.message }));
|
|
557
|
+
}
|
|
558
|
+
}));
|
|
518
559
|
function useListState() {
|
|
519
560
|
return useAtom(defaultStateAtom);
|
|
520
561
|
}
|
|
@@ -524,6 +565,9 @@ var createListsAtom = (storeName, reducer, initialState) => {
|
|
|
524
565
|
}
|
|
525
566
|
return {
|
|
526
567
|
listsAtom: defaultStateAtom,
|
|
568
|
+
tokenAtom,
|
|
569
|
+
tokenBySymbolAtom,
|
|
570
|
+
fetchListAtom,
|
|
527
571
|
useListStateReady,
|
|
528
572
|
useListState
|
|
529
573
|
};
|
|
@@ -659,6 +703,9 @@ function useFetchListCallback(dispatch) {
|
|
|
659
703
|
dispatch(fetchTokenList.pending({ requestId, url: listUrl }));
|
|
660
704
|
}
|
|
661
705
|
return getTokenList(listUrl).then((tokenList) => {
|
|
706
|
+
if (!tokenList) {
|
|
707
|
+
throw new Error("Token list not found");
|
|
708
|
+
}
|
|
662
709
|
if (sendDispatch) {
|
|
663
710
|
dispatch(fetchTokenList.fulfilled({ url: listUrl, tokenList, requestId }));
|
|
664
711
|
}
|
|
@@ -676,4 +723,4 @@ function useFetchListCallback(dispatch) {
|
|
|
676
723
|
}
|
|
677
724
|
var useFetchListCallback_default = useFetchListCallback;
|
|
678
725
|
|
|
679
|
-
export { NEW_LIST_STATE, acceptListUpdate, addList, createListsAtom, createTokenListReducer, disableList, enableList, fetchTokenList, getTokenList, rejectVersionUpdate, removeList, updateListVersion, useFetchListCallback_default as useFetchListCallback };
|
|
726
|
+
export { NEW_LIST_STATE, acceptListUpdate, addList, createListsAtom, createTokenListReducer, disableList, enableList, fetchTokenList, findTokenByAddress, findTokenBySymbol, getTokenList, rejectVersionUpdate, removeList, updateListVersion, useFetchListCallback_default as useFetchListCallback };
|
package/package.json
CHANGED
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pancakeswap/token-lists",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.16",
|
|
4
4
|
"main": "./dist/index.js",
|
|
5
5
|
"module": "./dist/index.mjs",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
7
7
|
"dependencies": {
|
|
8
8
|
"ajv": "^6.12.3",
|
|
9
9
|
"lodash": "^4.17.21",
|
|
10
|
-
"@pancakeswap/swap-sdk-core": "1.
|
|
10
|
+
"@pancakeswap/swap-sdk-core": "1.5.0"
|
|
11
11
|
},
|
|
12
12
|
"peerDependencies": {
|
|
13
13
|
"@reduxjs/toolkit": "^1.9.1",
|
|
14
|
-
"jotai": "
|
|
14
|
+
"jotai": "2.12.5",
|
|
15
15
|
"localforage": "^1.10.0",
|
|
16
16
|
"react": "^18.2.0"
|
|
17
17
|
},
|
|
18
18
|
"devDependencies": {
|
|
19
19
|
"@reduxjs/toolkit": "^1.9.1",
|
|
20
20
|
"@types/react": "^18.2.21",
|
|
21
|
-
"jotai": "
|
|
21
|
+
"jotai": "2.12.5",
|
|
22
22
|
"localforage": "^1.10.0",
|
|
23
23
|
"react": "^18.2.0",
|
|
24
24
|
"tsup": "^6.7.0",
|
|
25
|
-
"@pancakeswap/utils": "
|
|
25
|
+
"@pancakeswap/utils": "8.0.0"
|
|
26
26
|
},
|
|
27
27
|
"exports": {
|
|
28
28
|
".": {
|
package/react/getTokenList.ts
CHANGED
|
@@ -8,7 +8,7 @@ import { TokenList } from '../src/types'
|
|
|
8
8
|
* Contains the logic for resolving a list URL to a validated token list
|
|
9
9
|
* @param listUrl list url
|
|
10
10
|
*/
|
|
11
|
-
export async function getTokenList(listUrl: string): Promise<TokenList> {
|
|
11
|
+
export async function getTokenList(listUrl: string): Promise<TokenList | undefined> {
|
|
12
12
|
const urls: string[] = uriToHttp(listUrl)
|
|
13
13
|
const { default: Ajv } = await import('ajv')
|
|
14
14
|
const validator = new Ajv({ allErrors: true }).compile(schema)
|
|
@@ -27,9 +27,11 @@ export async function getTokenList(listUrl: string): Promise<TokenList> {
|
|
|
27
27
|
}
|
|
28
28
|
return json as TokenList
|
|
29
29
|
} catch (error) {
|
|
30
|
-
if (i === urls.length - 1) {
|
|
31
|
-
|
|
32
|
-
}
|
|
30
|
+
// if (i === urls.length - 1) {
|
|
31
|
+
// throw new Error(`Failed to download list ${listUrl}`)
|
|
32
|
+
// }
|
|
33
|
+
|
|
34
|
+
return undefined
|
|
33
35
|
}
|
|
34
36
|
}
|
|
35
37
|
throw new Error('Unrecognized list URL protocol.')
|
package/react/index.test.ts
CHANGED
package/react/lists.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
import { nanoid } from '@reduxjs/toolkit'
|
|
1
2
|
import { atom, useAtom, useAtomValue } from 'jotai'
|
|
2
|
-
import { atomWithStorage, loadable } from 'jotai/utils'
|
|
3
|
+
import { atomFamily, atomWithStorage, loadable } from 'jotai/utils'
|
|
3
4
|
import { type AsyncStorage } from 'jotai/vanilla/utils/atomWithStorage'
|
|
4
5
|
import localForage from 'localforage'
|
|
6
|
+
import { fetchTokenList } from './actions'
|
|
7
|
+
import { getTokenList } from './getTokenList'
|
|
5
8
|
import { ListsState } from './reducer'
|
|
6
9
|
|
|
7
10
|
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
@@ -16,6 +19,26 @@ const noopStorage: AsyncStorage<any> = {
|
|
|
16
19
|
// eslint-disable-next-line symbol-description
|
|
17
20
|
const EMPTY = Symbol()
|
|
18
21
|
|
|
22
|
+
export function findTokenByAddress(state: ListsState, chainId: number, address: string) {
|
|
23
|
+
const urls = state.activeListUrls ?? Object.keys(state.byUrl)
|
|
24
|
+
for (const url of urls) {
|
|
25
|
+
const list = state.byUrl[url]?.current
|
|
26
|
+
const token = list?.tokens.find((t) => t.chainId === chainId && t.address.toLowerCase() === address.toLowerCase())
|
|
27
|
+
if (token) return token
|
|
28
|
+
}
|
|
29
|
+
return undefined
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function findTokenBySymbol(state: ListsState, chainId: number, symbol: string) {
|
|
33
|
+
const urls = state.activeListUrls ?? Object.keys(state.byUrl)
|
|
34
|
+
for (const url of urls) {
|
|
35
|
+
const list = state.byUrl[url]?.current
|
|
36
|
+
const token = list?.tokens.find((t) => t.chainId === chainId && t.symbol.toLowerCase() === symbol.toLowerCase())
|
|
37
|
+
if (token) return token
|
|
38
|
+
}
|
|
39
|
+
return undefined
|
|
40
|
+
}
|
|
41
|
+
|
|
19
42
|
export const createListsAtom = (storeName: string, reducer: any, initialState: any) => {
|
|
20
43
|
/**
|
|
21
44
|
* Persist you redux state using IndexedDB
|
|
@@ -62,6 +85,32 @@ export const createListsAtom = (storeName: string, reducer: any, initialState: a
|
|
|
62
85
|
|
|
63
86
|
const isReadyAtom = loadable(listsStorageAtom)
|
|
64
87
|
|
|
88
|
+
const tokenAtom = atomFamily((key: { chainId: number; address: string }) =>
|
|
89
|
+
atom((get) => findTokenByAddress(get(defaultStateAtom), key.chainId, key.address)),
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
const tokenBySymbolAtom = atomFamily((key: { chainId: number; symbol: string }) =>
|
|
93
|
+
atom((get) => findTokenBySymbol(get(defaultStateAtom), key.chainId, key.symbol)),
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
const fetchListAtom = atom<null, [string], Promise<void>>(null, async (get, set, url) => {
|
|
97
|
+
const state = get(defaultStateAtom)
|
|
98
|
+
const listState = state.byUrl[url]
|
|
99
|
+
if (listState?.current || listState?.loadingRequestId) {
|
|
100
|
+
return
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const requestId = nanoid()
|
|
104
|
+
set(defaultStateAtom, fetchTokenList.pending({ url, requestId }))
|
|
105
|
+
|
|
106
|
+
try {
|
|
107
|
+
const tokenList = await getTokenList(url)
|
|
108
|
+
set(defaultStateAtom, fetchTokenList.fulfilled({ url, tokenList: tokenList!, requestId }))
|
|
109
|
+
} catch (error: any) {
|
|
110
|
+
set(defaultStateAtom, fetchTokenList.rejected({ url, requestId, errorMessage: error.message }))
|
|
111
|
+
}
|
|
112
|
+
})
|
|
113
|
+
|
|
65
114
|
function useListState() {
|
|
66
115
|
return useAtom(defaultStateAtom)
|
|
67
116
|
}
|
|
@@ -73,6 +122,9 @@ export const createListsAtom = (storeName: string, reducer: any, initialState: a
|
|
|
73
122
|
|
|
74
123
|
return {
|
|
75
124
|
listsAtom: defaultStateAtom,
|
|
125
|
+
tokenAtom,
|
|
126
|
+
tokenBySymbolAtom,
|
|
127
|
+
fetchListAtom,
|
|
76
128
|
useListStateReady,
|
|
77
129
|
useListState,
|
|
78
130
|
}
|
|
@@ -16,6 +16,10 @@ function useFetchListCallback(
|
|
|
16
16
|
}
|
|
17
17
|
return getTokenList(listUrl)
|
|
18
18
|
.then((tokenList) => {
|
|
19
|
+
if (!tokenList) {
|
|
20
|
+
throw new Error('Token list not found')
|
|
21
|
+
}
|
|
22
|
+
|
|
19
23
|
if (sendDispatch) {
|
|
20
24
|
dispatch(fetchTokenList.fulfilled({ url: listUrl, tokenList, requestId }))
|
|
21
25
|
}
|