|
1 | | -import { atom, useAtomValue, useStore } from 'jotai' |
2 | | -import { useMemo } from 'react' |
3 | | -import { AssetLookupResult, AssetResult } from '@algorandfoundation/algokit-utils/types/indexer' |
4 | | -import { atomEffect } from 'jotai-effect' |
5 | | -import { loadable } from 'jotai/utils' |
6 | | -import { JotaiStore } from '@/features/common/data/types' |
7 | | -import { indexer } from '@/features/common/data' |
| 1 | +import { atom } from 'jotai' |
| 2 | +import { AssetResult } from '@algorandfoundation/algokit-utils/types/indexer' |
8 | 3 | import { AssetIndex } from './types' |
9 | 4 | import { ZERO_ADDRESS } from '@/features/common/constants' |
10 | | -import { asError, is404 } from '@/utils/error' |
11 | | - |
12 | | -const deletedAssetBuilder = (assetIndex: AssetIndex) => { |
13 | | - return { |
14 | | - index: assetIndex, |
15 | | - deleted: true, |
16 | | - params: { |
17 | | - creator: ZERO_ADDRESS, |
18 | | - decimals: 0, |
19 | | - total: 0, |
20 | | - name: 'DELETED', |
21 | | - 'unit-name': 'DELETED', |
22 | | - }, |
23 | | - } as AssetResult |
24 | | -} |
| 5 | +export * from './types' |
| 6 | +export * from './asset' |
25 | 7 |
|
26 | 8 | // TODO: Size should be capped at some limit, so memory usage doesn't grow indefinitely |
27 | | -export const assetsAtom = atom<Map<AssetIndex, AssetResult>>(new Map()) |
28 | | - |
29 | | -export const fetchAssetAtomBuilder = (store: JotaiStore, assetIndex: AssetIndex) => { |
30 | | - const syncEffect = atomEffect((get, set) => { |
31 | | - ;(async () => { |
32 | | - try { |
33 | | - const asset = await get(assetAtom) |
34 | | - set(assetsAtom, (prev) => { |
35 | | - return new Map([...prev, [asset.index, asset]]) |
36 | | - }) |
37 | | - } catch (e) { |
38 | | - // Ignore any errors as there is nothing to sync |
39 | | - } |
40 | | - })() |
41 | | - }) |
42 | | - const assetAtom = atom((get) => { |
43 | | - const assets = store.get(assetsAtom) |
44 | | - const cachedAsset = assets.get(assetIndex) |
45 | | - if (cachedAsset) { |
46 | | - return cachedAsset |
47 | | - } |
48 | | - |
49 | | - get(syncEffect) |
50 | | - |
51 | | - return indexer |
52 | | - .lookupAssetByID(assetIndex) |
53 | | - .do() |
54 | | - .then((result) => { |
55 | | - return (result as AssetLookupResult).asset |
56 | | - }) |
57 | | - .catch((e: unknown) => { |
58 | | - if (is404(asError(e))) { |
59 | | - return deletedAssetBuilder(assetIndex) |
60 | | - } |
61 | | - throw e |
62 | | - }) |
63 | | - }) |
64 | | - return assetAtom |
65 | | -} |
66 | | - |
67 | | -export const fetchAssetsAtomBuilder = (store: JotaiStore, assetIndexes: AssetIndex[]) => { |
68 | | - return atom(async (get) => { |
69 | | - return await Promise.all(assetIndexes.map((assetIndex) => get(fetchAssetAtomBuilder(store, assetIndex)))) |
70 | | - }) |
71 | | -} |
72 | | - |
73 | | -export const useAssetAtom = (assetIndex: AssetIndex) => { |
74 | | - const store = useStore() |
75 | | - return useMemo(() => { |
76 | | - return fetchAssetAtomBuilder(store, assetIndex) |
77 | | - }, [store, assetIndex]) |
78 | | -} |
79 | 9 |
|
80 | | -export const useLoadableAsset = (assetIndex: AssetIndex) => { |
81 | | - return useAtomValue(loadable(useAssetAtom(assetIndex))) |
82 | | -} |
| 10 | +export const algoAssetResult = { |
| 11 | + index: 0, |
| 12 | + 'created-at-round': 0, |
| 13 | + params: { |
| 14 | + creator: ZERO_ADDRESS, |
| 15 | + decimals: 6, |
| 16 | + total: 10_000_000_000, |
| 17 | + name: 'ALGO', |
| 18 | + 'unit-name': 'ALGO', |
| 19 | + url: 'https://www.algorand.foundation', |
| 20 | + }, |
| 21 | +} as AssetResult |
| 22 | + |
| 23 | +export const assetsAtom = atom<Map<AssetIndex, AssetResult>>(new Map([[algoAssetResult.index, algoAssetResult]])) |
0 commit comments