@@ -24,6 +24,7 @@ import { useMemo } from 'react'
24
24
import { IconCoin , IconError } from 'app/components/icons'
25
25
import { useCoins } from 'app/provider/coins'
26
26
import { investmentCoins as investmentCoinsList } from 'app/data/coins'
27
+ import { formatUnits } from 'viem'
27
28
28
29
export const InvestmentsBalanceCard = ( props : CardProps ) => {
29
30
const media = useMedia ( )
@@ -151,22 +152,41 @@ function OverlappingCoinIcons({
151
152
}
152
153
153
154
function InvestmentsAggregate ( ) {
154
- const tokenIds = useCoins ( )
155
- . investmentCoins . filter ( ( c ) => c ?. balance && c . balance > 0n )
156
- . map ( ( c ) => c . coingeckoTokenId )
155
+ const coins = useCoins ( ) . investmentCoins . filter ( ( c ) => c ?. balance && c . balance > 0n )
157
156
157
+ const tokenIds = coins . map ( ( c ) => c . coingeckoTokenId )
158
158
const { data : marketData , isLoading, isError } = useMultipleTokensMarketData ( tokenIds )
159
+
160
+ const { totalValue, assetValues } = useMemo ( ( ) => {
161
+ if ( ! marketData ?. length ) return { totalValue : 0 , assetValues : [ ] }
162
+
163
+ // Calculate values for each asset and total
164
+ const assetValues = coins . map ( ( coin ) => {
165
+ const marketInfo = marketData . find ( ( m ) => m . id === coin . coingeckoTokenId )
166
+ if ( ! marketInfo || ! coin . balance ) return { value : 0 , percentChange : 0 }
167
+
168
+ const parsedBalance = formatUnits ( coin . balance , coin . decimals )
169
+ return {
170
+ value : Number ( parsedBalance ) * ( marketInfo . current_price ?? 0 ) ,
171
+ percentChange : marketInfo . price_change_percentage_24h ?? 0 ,
172
+ }
173
+ } )
174
+
175
+ const totalValue = assetValues . reduce ( ( sum , asset ) => sum + asset . value , 0 )
176
+
177
+ return { totalValue, assetValues }
178
+ } , [ marketData , coins ] )
179
+
159
180
const aggregatePercentage = useMemo ( ( ) => {
160
- if ( ! marketData ?. length ) return 0
181
+ if ( totalValue <= 0 ) return 0
161
182
162
- // Simple average of percentage changes
163
- const aggregatePercentage =
164
- marketData . reduce ( ( total , coin ) => {
165
- return total + ( coin ?. price_change_percentage_24h ?? 0 )
166
- } , 0 ) / marketData . length
183
+ const weightedPercentage = assetValues . reduce ( ( sum , asset ) => {
184
+ const weight = asset . value / totalValue
185
+ return sum + asset . percentChange * weight
186
+ } , 0 )
167
187
168
- return Number ( aggregatePercentage . toFixed ( 2 ) )
169
- } , [ marketData ] )
188
+ return Math . round ( weightedPercentage * 100 ) / 100
189
+ } , [ totalValue , assetValues ] )
170
190
171
191
if ( tokenIds . length === 0 )
172
192
return (
0 commit comments