@@ -47,6 +47,7 @@ interface TokensProviderProps {
47
47
export interface TokenPrice {
48
48
price : number | undefined ; // USD price
49
49
timestamp : Date ;
50
+ isFetching ?: boolean ;
50
51
}
51
52
52
53
export const TokensProvider : React . FC < TokensProviderProps > = ( { children } ) => {
@@ -58,6 +59,10 @@ export const TokensProvider: React.FC<TokensProviderProps> = ({ children }) => {
58
59
const [ tokenPrices , _setTokenPrices ] = useState < TokenMapping < TokenPrice > > (
59
60
new TokenMapping ( ) ,
60
61
) ;
62
+ const [ tokenPricesToFetch , _setTokenPricesToFetch ] = useState <
63
+ TokenMapping < boolean >
64
+ > ( new TokenMapping ( ) ) ;
65
+
61
66
const [ isFetchingTokenPrices , setIsFetchingPrices ] = useState ( false ) ;
62
67
const [ lastTokenPriceUpdate , setLastPriceUpdate ] = useState ( new Date ( ) ) ;
63
68
@@ -104,21 +109,32 @@ export const TokensProvider: React.FC<TokensProviderProps> = ({ children }) => {
104
109
[ ] ,
105
110
) ;
106
111
107
- const tokenPricesToFetch : Set < TokenId > = new Set ( ) ;
108
-
109
112
const updateTokenPrices = useDebouncedCallback ( async ( ) => {
110
- if ( tokenPricesToFetch . size === 0 ) return ;
113
+ if ( tokenPricesToFetch . empty ) return ;
111
114
112
- const tokens = Array . from ( tokenPricesToFetch ) ;
115
+ const tokens = tokenPricesToFetch . getAllTokenIds ( ) ;
113
116
console . info ( 'Fetching token prices' , tokens ) ;
114
117
115
118
try {
116
119
setIsFetchingPrices ( true ) ;
120
+ const timestamp = new Date ( ) ;
121
+
122
+ // Flag that this price is being fetched, so that we don't start another concurrent request for it in getTokenPrice
123
+ for ( const token of tokens ) {
124
+ tokenPrices . add ( token , {
125
+ timestamp,
126
+ price : undefined ,
127
+ isFetching : true ,
128
+ } ) ;
129
+ }
130
+
131
+ // Clear list for future invocations of getTokenPrice
132
+ tokenPricesToFetch . clear ( ) ;
133
+
117
134
const prices = await fetchTokenPrices ( tokens ) ;
118
135
119
- for ( const token of tokenPricesToFetch . values ( ) ) {
136
+ for ( const token of tokens ) {
120
137
const price = prices . get ( token ) ;
121
- const timestamp = new Date ( ) ;
122
138
if ( price ) {
123
139
tokenPrices . add ( token , {
124
140
timestamp,
@@ -134,7 +150,6 @@ export const TokensProvider: React.FC<TokensProviderProps> = ({ children }) => {
134
150
} catch ( e ) {
135
151
console . error ( e ) ;
136
152
} finally {
137
- tokenPricesToFetch . clear ( ) ;
138
153
setIsFetchingPrices ( false ) ;
139
154
setLastPriceUpdate ( new Date ( ) ) ;
140
155
}
@@ -148,7 +163,7 @@ export const TokensProvider: React.FC<TokensProviderProps> = ({ children }) => {
148
163
if ( cachedPrice ) {
149
164
return cachedPrice . price ;
150
165
} else {
151
- tokenPricesToFetch . add ( tokenId ) ;
166
+ tokenPricesToFetch . add ( tokenId , true ) ;
152
167
updateTokenPrices ( ) ;
153
168
return undefined ;
154
169
}
0 commit comments