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}
+
+ onSend(selectedAsset, sendAmount)}
+ className="mt-4 w-full bg-blue-600 text-white py-2 px-4 rounded hover:bg-blue-700"
+ >
+ Send
+
+
+ )}
+
+ );
+};
+
+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';