diff --git a/packages/app/src/systems/Asset/AssetValueDisplay.tsx b/packages/app/src/systems/Asset/AssetValueDisplay.tsx new file mode 100644 index 000000000..1934b85b0 --- /dev/null +++ b/packages/app/src/systems/Asset/AssetValueDisplay.tsx @@ -0,0 +1,138 @@ +import React, { useState, useEffect } from 'react'; +import { formatUnits } from 'ethers/utils'; +import { Loader2 } from 'lucide-react'; + +// Verified assets with their decimal places +const VERIFIED_ASSETS = { + 'ETH': { decimals: 18, symbol: 'ETH', name: 'Ether' }, + 'USDC': { decimals: 6, symbol: 'USDC', name: 'USD Coin' }, + 'USDT': { decimals: 6, symbol: 'USDT', name: 'Tether' }, + 'sDAI': { decimals: 18, symbol: 'sDAI', name: 'Savings DAI' }, + 'ezETH': { decimals: 18, symbol: 'ezETH', name: 'Easy ETH' } +}; + +const AssetRow = ({ assetSymbol, balance, usdPrice, isLoading }) => { + const asset = VERIFIED_ASSETS[assetSymbol]; + const formattedBalance = formatUnits(balance, asset.decimals); + const usdValue = parseFloat(formattedBalance) * usdPrice; + + return ( +
+
+
{asset.name}
+
({asset.symbol})
+
+ +
+
+ {formattedBalance} {asset.symbol} +
+
+ {isLoading ? ( + + ) : ( + `$${usdValue.toLocaleString(undefined, { + minimumFractionDigits: 2, + maximumFractionDigits: 2 + })}` + )} +
+
+
+ ); +}; + +const TransactionInput = ({ assetSymbol, amount, usdPrice, onChange }) => { + const asset = VERIFIED_ASSETS[assetSymbol]; + const usdValue = amount ? parseFloat(amount) * usdPrice : 0; + + return ( +
+
+ onChange(e.target.value)} + className="w-full p-2 border rounded" + placeholder={`Enter ${asset.symbol} amount`} + /> +
{asset.symbol}
+
+
+ ≈ ${usdValue.toLocaleString(undefined, { + minimumFractionDigits: 2, + maximumFractionDigits: 2 + })} +
+
+ ); +}; + +const AssetDisplay = ({ balances, onSend }) => { + const [prices, setPrices] = useState({}); + const [isLoading, setIsLoading] = useState(true); + const [sendAmount, setSendAmount] = useState(''); + const [selectedAsset, setSelectedAsset] = useState(null); + + useEffect(() => { + // Simulated price fetching - replace with actual price API + const fetchPrices = async () => { + setIsLoading(true); + // Mock prices - replace with actual price fetching logic + const mockPrices = { + 'ETH': 2150.75, + 'USDC': 1.00, + 'USDT': 1.00, + 'sDAI': 1.00, + 'ezETH': 2150.75 + }; + setPrices(mockPrices); + setIsLoading(false); + }; + + fetchPrices(); + // Set up periodic price updates + const interval = setInterval(fetchPrices, 60000); + return () => clearInterval(interval); + }, []); + + return ( +
+ {/* Balance Display */} +
+ {Object.entries(balances).map(([symbol, balance]) => ( + VERIFIED_ASSETS[symbol] && ( + + ) + ))} +
+ + {/* Send Transaction UI */} + {selectedAsset && ( +
+

Send {selectedAsset}

+ + +
+ )} +
+ ); +}; + +export default AssetDisplay; \ No newline at end of file diff --git a/packages/app/src/systems/Asset/index.tsx b/packages/app/src/systems/Asset/index.tsx index 570206475..e9aa313c9 100644 --- a/packages/app/src/systems/Asset/index.tsx +++ b/packages/app/src/systems/Asset/index.tsx @@ -6,3 +6,4 @@ export * from './services'; export * from './events'; export * from './routes'; export * from './utils'; +export * from './AssetValueDisplay';