import { CryptoPrice , CurrencyType } from '@masknet/web3-shared-evm' ; import { pollingTask } from '@masknet/shared-base' ; import { getTokenPrices , getNativeTokenPrice } from '../../../extension/background-script/EthereumService' ; import { startEffects } from '../../../../utils-pure' ; import { UPDATE_CHAIN_STATE_DELAY } from '../constants' ; import { currentTokenPricesSettings } from '../settings' ; import { uniq } from 'lodash-unified' ; const { run } = startEffects ( import . meta . webpackHot ) ; function updateCurrentPrices ( data ) { const currentPrices = { ... currentTokenPricesSettings . value } ; Object . keys ( data ) . forEach ( ( category ) => { Object . keys ( data [ category ] ) . forEach ( ( currency ) => { currentPrices [ category ] = { ... currentPrices [ category ] , [ currency ] : data [ category ] [ currency ] , } ; } ) ; } ) ; currentTokenPricesSettings . value = currentPrices ; } let tokenTrackingCount = 0 ; let nativeTokenCount = 0 ; export function kickToUpdateTokenPrices ( ) { tokenTrackingCount += 1 ; nativeTokenCount += 1 ; } const trackingContracts = Object . create ( null ) ; export function trackContract ( platform , address ) { trackingContracts [ platform ] = uniq ( [ ... ( trackingContracts [ platform ] ?? [ ] ) , address ] ) ; } export async function updateTokenPrices ( ) { resetPoolTask ( ) ; tokenTrackingCount = 0 ; try { const platforms = Object . keys ( trackingContracts ) ; await Promise . allSettled ( platforms . map ( async ( platform ) => { const prices = await getTokenPrices ( platform , trackingContracts [ platform ] , CurrencyType . USD ) ; updateCurrentPrices ( prices ) ; } ) ) ; } finally { resetPoolTask ( ) ; } } const trackingNativeTokenIds = [ ] ; export function trackNativeToken ( id ) { if ( ! trackingNativeTokenIds . includes ( id ) ) { trackingNativeTokenIds . push ( id ) ; } } export async function updateNativeTokenPrices ( ) { resetPoolTask ( ) ; nativeTokenCount = 0 ; try { const prices = await getNativeTokenPrice ( trackingNativeTokenIds , CurrencyType . USD ) ; updateCurrentPrices ( prices ) ; } catch { } finally { resetPoolTask ( ) ; } } let resetPoolTask = ( ) => { } ; run ( ( ) => { const { reset , cancel } = pollingTask ( async ( ) => { if ( tokenTrackingCount > 0 ) { await updateTokenPrices ( ) ; } if ( nativeTokenCount > 0 ) { await updateNativeTokenPrices ( ) ; } return false ; } , { delay : UPDATE_CHAIN_STATE_DELAY , } ) ; resetPoolTask = reset ; return cancel ; } ) ; const ETH_PRICE_POLLING_DELAY = 30 * 1000 ; run ( ( ) => { trackNativeToken ( 'ethereum' ) ; const { cancel } = pollingTask ( async ( ) => { updateNativeTokenPrices ( ) ; return false ; } , { autoStart : true , delay : ETH_PRICE_POLLING_DELAY , } ) ; return cancel ; } ) ;