From 0f8d3d273ec0ed4aac2dee8dba1f79d9e8e2b216 Mon Sep 17 00:00:00 2001 From: vantuz-subhuman Date: Wed, 19 Jun 2024 13:14:12 +0300 Subject: [PATCH] token metadata batch fetching fix --- .../app/components/swap/SelectAssetDialog.js | 9 ++++++--- .../app/containers/swap/asset-swap/CreateSwapOrder.js | 6 ++++-- .../app/containers/swap/asset-swap/SwapPage.js | 5 ++++- .../asset-swap/edit-buy-amount/SelectBuyTokenFromList.js | 6 +++--- .../edit-sell-amount/SelectSellTokenFromList.js | 6 +++--- .../swap/context/swap-form/SwapFormProvider.js | 2 +- .../app/stores/toplevel/TokenInfoStore.js | 8 ++++++++ 7 files changed, 29 insertions(+), 13 deletions(-) diff --git a/packages/yoroi-extension/app/components/swap/SelectAssetDialog.js b/packages/yoroi-extension/app/components/swap/SelectAssetDialog.js index 5154a897c2..fa1ab44637 100644 --- a/packages/yoroi-extension/app/components/swap/SelectAssetDialog.js +++ b/packages/yoroi-extension/app/components/swap/SelectAssetDialog.js @@ -28,7 +28,7 @@ type Props = {| onAssetSelected: any => void, onClose: void => void, defaultTokenInfo: RemoteTokenInfo, - getTokenInfo: string => Promise, + getTokenInfoBatch: Array => { [string]: Promise }, |}; export default function SelectAssetDialog({ @@ -37,7 +37,7 @@ export default function SelectAssetDialog({ onAssetSelected, onClose, defaultTokenInfo, - getTokenInfo, + getTokenInfoBatch, }: Props): React$Node { const [searchTerm, setSearchTerm] = useState(''); @@ -55,6 +55,9 @@ export default function SelectAssetDialog({ .includes(searchTerm.toLowerCase()); }) || []; + const metadataPromiseMap: { [string]: Promise } = + getTokenInfoBatch(filteredAssets.map(a => a.id)) + return ( metadataPromiseMap[id]} /> ); })} diff --git a/packages/yoroi-extension/app/containers/swap/asset-swap/CreateSwapOrder.js b/packages/yoroi-extension/app/containers/swap/asset-swap/CreateSwapOrder.js index e40ad94472..f675e981fc 100644 --- a/packages/yoroi-extension/app/containers/swap/asset-swap/CreateSwapOrder.js +++ b/packages/yoroi-extension/app/containers/swap/asset-swap/CreateSwapOrder.js @@ -24,6 +24,7 @@ type Props = {| swapStore: SwapStore, defaultTokenInfo: RemoteTokenInfo, getTokenInfo: string => Promise, + getTokenInfoBatch: Array => { [string]: Promise }, priceImpactState: ?PriceImpact, |}; @@ -33,6 +34,7 @@ export const CreateSwapOrder = ({ swapStore, defaultTokenInfo, getTokenInfo, + getTokenInfoBatch, priceImpactState, }: Props): React$Node => { const [openedDialog, setOpenedDialog] = useState(''); @@ -119,7 +121,7 @@ export const CreateSwapOrder = ({ sellTokenInfoChanged(val); }} defaultTokenInfo={defaultTokenInfo} - getTokenInfo={getTokenInfo} + getTokenInfoBatch={getTokenInfoBatch} /> )} {openedDialog === 'to' && ( @@ -131,7 +133,7 @@ export const CreateSwapOrder = ({ buyTokenInfoChanged(val); }} defaultTokenInfo={defaultTokenInfo} - getTokenInfo={getTokenInfo} + getTokenInfoBatch={getTokenInfoBatch} /> )} {openedDialog === 'slippage' && ( diff --git a/packages/yoroi-extension/app/containers/swap/asset-swap/SwapPage.js b/packages/yoroi-extension/app/containers/swap/asset-swap/SwapPage.js index cecf998770..5249a67914 100644 --- a/packages/yoroi-extension/app/containers/swap/asset-swap/SwapPage.js +++ b/packages/yoroi-extension/app/containers/swap/asset-swap/SwapPage.js @@ -88,8 +88,10 @@ function SwapPage(props: StoresAndActionsProps): Node { const defaultTokenInfo = props.stores.tokenInfoStore.getDefaultTokenInfoSummary( network.NetworkId ); + const getTokenInfoBatch: Array => { [string]: Promise } = ids => + props.stores.tokenInfoStore.fetchMissingAndGetLocalOrRemoteMetadata(network, ids); const getTokenInfo: string => Promise = id => - props.stores.tokenInfoStore.getLocalOrRemoteMetadata(network, id); + getTokenInfoBatch([id])[id].then(res => res ?? {}); const disclaimerFlag = props.stores.substores.ada.swapStore.swapDisclaimerAcceptanceFlag; @@ -323,6 +325,7 @@ function SwapPage(props: StoresAndActionsProps): Node { onSetNewSlippage={onSetNewSlippage} defaultTokenInfo={defaultTokenInfo} getTokenInfo={getTokenInfo} + getTokenInfoBatch={getTokenInfoBatch} priceImpactState={priceImpactState} /> )} diff --git a/packages/yoroi-extension/app/containers/swap/asset-swap/edit-buy-amount/SelectBuyTokenFromList.js b/packages/yoroi-extension/app/containers/swap/asset-swap/edit-buy-amount/SelectBuyTokenFromList.js index aad847d842..0efba0d0b7 100644 --- a/packages/yoroi-extension/app/containers/swap/asset-swap/edit-buy-amount/SelectBuyTokenFromList.js +++ b/packages/yoroi-extension/app/containers/swap/asset-swap/edit-buy-amount/SelectBuyTokenFromList.js @@ -12,10 +12,10 @@ type Props = {| onClose(): void, onTokenInfoChanged: * => void, defaultTokenInfo: RemoteTokenInfo, - getTokenInfo: string => Promise, + getTokenInfoBatch: Array => { [string]: Promise }, |}; -export default function SelectBuyTokenFromList({ store, onClose, onTokenInfoChanged, defaultTokenInfo, getTokenInfo }: Props): Node { +export default function SelectBuyTokenFromList({ store, onClose, onTokenInfoChanged, defaultTokenInfo, getTokenInfoBatch }: Props): Node { const { sellQuantity: { isTouched: isSellTouched }, buyQuantity: { isTouched: isBuyTouched }, @@ -67,7 +67,7 @@ export default function SelectBuyTokenFromList({ store, onClose, onTokenInfoChan onAssetSelected={handleAssetSelected} onClose={onClose} defaultTokenInfo={defaultTokenInfo} - getTokenInfo={getTokenInfo} + getTokenInfoBatch={getTokenInfoBatch} /> ); } diff --git a/packages/yoroi-extension/app/containers/swap/asset-swap/edit-sell-amount/SelectSellTokenFromList.js b/packages/yoroi-extension/app/containers/swap/asset-swap/edit-sell-amount/SelectSellTokenFromList.js index 2a6cc0fc00..770000ae23 100644 --- a/packages/yoroi-extension/app/containers/swap/asset-swap/edit-sell-amount/SelectSellTokenFromList.js +++ b/packages/yoroi-extension/app/containers/swap/asset-swap/edit-sell-amount/SelectSellTokenFromList.js @@ -12,10 +12,10 @@ type Props = {| onClose(): void, onTokenInfoChanged: * => void, defaultTokenInfo: RemoteTokenInfo, - getTokenInfo: string => Promise, + getTokenInfoBatch: Array => { [string]: Promise }, |}; -export default function SelectSellTokenFromList({ store, onClose, onTokenInfoChanged, defaultTokenInfo, getTokenInfo }: Props): Node { +export default function SelectSellTokenFromList({ store, onClose, onTokenInfoChanged, defaultTokenInfo, getTokenInfoBatch }: Props): Node { const { onlyVerifiedTokens } = useSwapTokensOnlyVerified(); const assets = store.assets; const walletVerifiedAssets = useMemo(() => { @@ -62,7 +62,7 @@ export default function SelectSellTokenFromList({ store, onClose, onTokenInfoCha onAssetSelected={handleAssetSelected} onClose={onClose} defaultTokenInfo={defaultTokenInfo} - getTokenInfo={getTokenInfo} + getTokenInfoBatch={getTokenInfoBatch} /> ); } diff --git a/packages/yoroi-extension/app/containers/swap/context/swap-form/SwapFormProvider.js b/packages/yoroi-extension/app/containers/swap/context/swap-form/SwapFormProvider.js index 7055241bfa..c65e3854c7 100644 --- a/packages/yoroi-extension/app/containers/swap/context/swap-form/SwapFormProvider.js +++ b/packages/yoroi-extension/app/containers/swap/context/swap-form/SwapFormProvider.js @@ -159,7 +159,7 @@ export default function SwapFormProvider({ swapStore, children }: Props): Node { if (sellTokenId != null && buyTokenId != null && sellTokenId !== buyTokenId) { console.log('fetching pools for pair: ', sellTokenId, buyTokenId); pools.list.byPair({ tokenA: sellTokenId, tokenB: buyTokenId }) - .then(pools => poolPairsChanged(pools)) + .then(poolsArray => poolPairsChanged(poolsArray)) .catch(err => console.error(`Failed to fetch pools for pair: ${sellTokenId}/${buyTokenId}`, err)); } }, [sellTokenId, buyTokenId]); diff --git a/packages/yoroi-extension/app/stores/toplevel/TokenInfoStore.js b/packages/yoroi-extension/app/stores/toplevel/TokenInfoStore.js index d560054b3e..8e1cb7f7f3 100644 --- a/packages/yoroi-extension/app/stores/toplevel/TokenInfoStore.js +++ b/packages/yoroi-extension/app/stores/toplevel/TokenInfoStore.js @@ -84,6 +84,14 @@ export default class TokenInfoStore< return { name: undefined, ticker: undefined, decimals: undefined, logo: undefined }; } + fetchMissingAndGetLocalOrRemoteMetadata(network: $ReadOnly, tokenIds: Array): { [string]: Promise } { + const fetchPromise = this.fetchMissingTokenInfo(network.NetworkId, tokenIds); + return tokenIds.reduce((res, id) => { + res[id] = fetchPromise.then(() => this.getLocalOrRemoteMetadata(network, id)); + return res; + }, {}); + } + fetchMissingTokenInfo: (networkId: number, tokenIds: Array) => Promise = async ( networkId, tokenIds