Asset Display Components
The asset display layer provides specialized visual components for rendering different types of blockchain assets. These components handle the complexities of displaying fungible tokens, non-fungible tokens, and native currencies with appropriate formatting, error handling, and responsive design.
Component Architecture
The asset display system consists of four interconnected components that work together to present blockchain assets effectively. AssetDisplay serves as the primary component that determines which specialized display to use based on asset type. AssetsGrid provides the layout container for multiple assets with loading and empty states. TokenAccordionContent integrates with the data layer to fetch and display assets on demand. NativeBalance shows blockchain native currencies using real-time balance data from wagmi.
- AssetDisplay.tsx
- AssetsGrid.tsx
- TokenAccordionContent.tsx
- NativeBalance.tsx
- index.ts
AssetDisplay Component
The AssetDisplay component serves as the intelligent router for asset rendering, automatically detecting asset types and delegating to specialized display components. This component demonstrates sophisticated type discrimination and error handling for various blockchain assets.

Type Discrimination Logic
The component uses TypeScript type guards to distinguish between fungible and non-fungible tokens, ensuring type-safe rendering paths. The discrimination logic checks for specific properties unique to each asset type.
function isERC20(asset: Asset): asset is ERC20Asset {
return 'symbol' in asset && 'decimals' in asset
}
This approach provides compile-time type safety while maintaining runtime flexibility for different asset structures.
ERC-20 Token Display
The ERC20Display sub-component handles fungible token presentation with sophisticated balance formatting and visual design. The component addresses several key challenges in token display.

Balance formatting represents one of the most complex aspects of token display due to varying decimal places across tokens. The component implements an intelligent formatting system that handles high-precision numbers up to 16 significant digits, prevents scientific notation for better readability, trims unnecessary trailing zeros, and provides fallback formatting for zero balances.
const formatBalance = (balance: string, decimals: number) => {
const rawStr = formatUnits(BigInt(balance), decimals)
const raw = parseFloat(rawStr)
if (!raw) return '0.00000'
let result = raw.toPrecision(16)
// Prevent exponential notation
if (result.includes('e')) {
const intPart = Math.floor(raw).toString()
const maxDecimals = Math.max(0, 16 - intPart.length - 1)
result = raw.toFixed(maxDecimals)
}
// Clean up formatting
if (result.includes('.')) {
result = result.replace(/\.?0+$/, '')
}
return result.startsWith('.') ? '0' + result : result
}
The visual presentation includes token logos with fallback handling. When logos are unavailable, the component generates placeholder icons using the token symbol’s first two characters. This ensures consistent visual presentation regardless of metadata availability.
NFT Display
The NFTDisplay sub-component handles the unique challenges of presenting non-fungible tokens, including image loading, orientation detection, and metadata display.

Image handling represents a critical aspect of NFT display. The component implements comprehensive error handling and loading states to ensure smooth user experience even with unreliable image sources. The image loading process includes multiple fallback URLs for maximum compatibility, automatic IPFS gateway conversion for decentralized content, orientation detection for optimal display layout, and graceful error states when images fail to load.
The component tracks image loading state through React hooks and provides detailed console logging for debugging purposes. This approach helps developers identify and resolve image loading issues in production environments.
useEffect(() => {
if (!isERC20(asset) && asset.image && !imageError) {
const img = new Image()
img.onload = () => {
setImageOrientation(img.width > img.height ? 'landscape' : 'portrait')
}
img.onerror = () => {
setImageError(true)
}
img.src = asset.image
}
}, [asset, imageError])
The component displays NFT metadata by showing the token name and ID prominently, followed by up to four attributes. When tokens have more than four attributes, the component displays a count indicator showing how many additional attributes exist.
NFT images from IPFS sources may load slowly or fail due to gateway availability. The component implements automatic IPFS-to-HTTP gateway conversion, but developers should consider implementing their own IPFS infrastructure for production applications.
AssetsGrid Component
The AssetsGrid component provides the layout foundation for displaying multiple assets in a responsive grid format. It handles three distinct states to ensure optimal user experience across all scenarios.
Loading State Management
The component implements a sophisticated loading state that provides visual feedback during data fetching. The loading indicator includes a spinning animation and descriptive text, ensuring users understand the system is actively retrieving their assets.
Empty State Design
When no assets are found, the component displays a clear empty state message. This prevents user confusion and provides immediate feedback about the query results. The empty state design maintains visual consistency with the overall portfolio interface.
Grid Layout System
The responsive grid adapts to different screen sizes and asset counts, providing optimal display across devices. The grid system uses CSS Grid with intelligent breakpoints that adjust column count based on viewport width. This ensures assets remain legible and visually appealing on all devices.
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 1.5rem;
padding: 1rem;
}
TokenAccordionContent Component
The TokenAccordionContent component serves as the integration point between the data layer and display layer, orchestrating asset fetching and rendering within the accordion interface.
Data Integration
The component leverages the useAssets hook to fetch assets on demand, implementing intelligent loading strategies. It only initiates data fetching when the accordion opens, reducing unnecessary API calls and improving initial page load performance.
Prefetch Optimization
The component implements hover-based prefetching through a callback pattern that allows parent components to trigger data preloading. This optimization significantly improves perceived performance by loading data before users request it.
useEffect(() => {
if (onHover) {
onHover()
}
}, [onHover])
Error Recovery
Comprehensive error handling ensures users can recover from temporary failures. The component provides contextual error messages and retry functionality, maintaining user confidence even when services experience issues.
Infinite Scroll Integration
The component seamlessly integrates with the infinite pagination system provided by useAssets. It displays a load more button when additional assets are available and shows loading state during pagination requests. The implementation maintains scroll position and provides smooth transitions between loading states.
NativeBalance Component
The NativeBalance component specializes in displaying blockchain native currencies like ETH, MATIC, and AVAX. It provides real-time balance updates using wagmi’s balance hooks.
Real-Time Balance Updates
The component establishes a direct connection to blockchain data through wagmi, ensuring balance information remains current. It automatically updates when transactions occur or block confirmations arrive.
Chain-Aware Display
The component intelligently adapts to different blockchain networks by dynamically retrieving currency symbols and names from chain configuration. This ensures accurate display regardless of the connected network. The implementation handles edge cases where chain metadata might be incomplete.
const symbol = data.symbol || chain?.nativeCurrency.symbol || 'Native'
const name = chain?.nativeCurrency.name || chain?.name || 'Native Token'
Precision Formatting
Native balance formatting requires special attention to precision and readability. The component implements adaptive formatting that shows up to 8 decimal places for very small amounts, displays 4 decimal places for standard amounts, and removes trailing zeros for cleaner presentation.
Visual Design System
All asset display components follow a cohesive visual design system that ensures consistency across different asset types while allowing for type-specific optimizations.
Design Principles
The visual design prioritizes clarity and information hierarchy. Each asset card uses consistent spacing and typography while adapting layouts based on content type. Color coding and visual indicators help users quickly identify asset types and states.
Responsive Behavior
Components implement responsive design through CSS modules that provide scoped styling without global conflicts. Media queries ensure optimal display across devices, from mobile phones to desktop monitors. The design system maintains touch-friendly interaction targets on mobile devices while providing hover states for desktop users.
Accessibility Features
The asset display components implement comprehensive accessibility features including semantic HTML structure for screen reader compatibility, ARIA labels for interactive elements, keyboard navigation support for all actions, and sufficient color contrast for visual accessibility. Focus indicators ensure keyboard users can navigate effectively.
Performance Optimization
The asset display layer implements several performance optimizations to ensure smooth scrolling and interaction even with large asset collections.
Image Optimization
NFT images often represent the largest performance bottleneck in portfolio applications. The components address this through proper error handling and fallback strategies that ensure the application remains responsive even when images fail to load. The system implements automatic IPFS gateway conversion to improve loading reliability for decentralized content.
Render Optimization
The components are structured to minimize unnecessary renders through careful component hierarchy design and state management. By isolating state changes to the smallest possible component scope, the system reduces the rendering workload during user interactions.
Memory Management
Large asset collections can consume significant memory. The components implement cleanup strategies including proper event listener removal and image object cleanup on unmount. These optimizations prevent memory leaks during extended usage sessions.
Testing Strategies
The asset display components include comprehensive test coverage focusing on visual correctness and user interaction.
AssetDisplay Tests
The AssetDisplay component test suite verifies the correct rendering of both ERC-20 tokens and NFTs. For ERC-20 tokens, tests ensure that token names, symbols, balances, and calculated values display correctly. The formatting logic is tested with various balance amounts, including the edge case of zero balances which should display as ‘0.00000’.
NFT display tests verify fallback behavior when critical data is missing. When no image URL is provided, the component correctly displays a “No Image” placeholder. Similarly, when an NFT lacks a name property, the component falls back to displaying the token ID in the format “Token #1234”.
AssetsGrid Tests
The AssetsGrid component tests focus on the three primary states of the grid system. Loading state tests verify that a loading indicator appears when the loading prop is true, ensuring users receive appropriate feedback during data fetching. Empty state tests confirm that “No Assets Found!” displays when the assets array is empty and loading is false.
The grid rendering logic is tested by providing multiple assets and verifying that each asset results in a corresponding AssetDisplay component being rendered. This ensures the grid correctly maps over the assets array regardless of asset type.
NativeBalance Tests
The NativeBalance component test suite covers all three states of balance fetching. During the loading phase, tests verify that a spinner element renders to provide visual feedback. Error handling is tested by confirming the component returns null when an error occurs, allowing parent components to handle the error state appropriately.
When balance data loads successfully, tests verify the formatting logic correctly converts wei values to human-readable format. The test suite also confirms that chain metadata, including currency symbols, displays correctly alongside the formatted balance.
Error Handling Patterns
The asset display components implement consistent error handling patterns that provide clear feedback for users.
Image Loading Failures
NFT images may fail to load due to various reasons including CORS restrictions, gateway timeouts, or invalid URLs. The components handle these failures by displaying a “No Image” placeholder, logging errors for debugging, and preventing error cascade through proper error boundaries.
Metadata Parsing Errors
Token metadata may be malformed or incomplete. The components implement defensive parsing that provides sensible defaults for missing fields, validates data types before usage, and logs warnings for debugging without disrupting the user experience.
Network Errors
Balance fetching may fail due to network issues. The NativeBalance component handles these scenarios by returning null when errors occur, allowing parent components to implement their own error handling strategies as appropriate for the specific use case.
Best Practices
When working with asset display components, follow these guidelines to ensure optimal results.
Development Guidelines
Always implement proper TypeScript types for asset data to catch errors at compile time. Use the provided formatting utilities rather than creating custom implementations. Test with various asset types and edge cases including zero balances and missing metadata. Implement proper loading and error states for all asynchronous operations. Consider performance implications when displaying large asset collections.
Image Handling
For NFT images, always implement error handling with appropriate fallbacks. Consider implementing custom IPFS gateways for production applications. Monitor image loading performance and implement caching strategies where appropriate.
Balance Display
When displaying token balances, use the provided formatting utilities to ensure consistency. Consider the token’s typical usage when determining display precision. Always handle edge cases like zero balances and extremely large numbers. Implement proper decimal handling based on token configuration.