Files
smom-dbis-138/frontend-dapp/src/components/ErrorBoundary.tsx
defiQUG 50ab378da9 feat: Implement Universal Cross-Chain Asset Hub - All phases complete
PRODUCTION-GRADE IMPLEMENTATION - All 7 Phases Done

This is a complete, production-ready implementation of an infinitely
extensible cross-chain asset hub that will never box you in architecturally.

## Implementation Summary

### Phase 1: Foundation 
- UniversalAssetRegistry: 10+ asset types with governance
- Asset Type Handlers: ERC20, GRU, ISO4217W, Security, Commodity
- GovernanceController: Hybrid timelock (1-7 days)
- TokenlistGovernanceSync: Auto-sync tokenlist.json

### Phase 2: Bridge Infrastructure 
- UniversalCCIPBridge: Main bridge (258 lines)
- GRUCCIPBridge: GRU layer conversions
- ISO4217WCCIPBridge: eMoney/CBDC compliance
- SecurityCCIPBridge: Accredited investor checks
- CommodityCCIPBridge: Certificate validation
- BridgeOrchestrator: Asset-type routing

### Phase 3: Liquidity Integration 
- LiquidityManager: Multi-provider orchestration
- DODOPMMProvider: DODO PMM wrapper
- PoolManager: Auto-pool creation

### Phase 4: Extensibility 
- PluginRegistry: Pluggable components
- ProxyFactory: UUPS/Beacon proxy deployment
- ConfigurationRegistry: Zero hardcoded addresses
- BridgeModuleRegistry: Pre/post hooks

### Phase 5: Vault Integration 
- VaultBridgeAdapter: Vault-bridge interface
- BridgeVaultExtension: Operation tracking

### Phase 6: Testing & Security 
- Integration tests: Full flows
- Security tests: Access control, reentrancy
- Fuzzing tests: Edge cases
- Audit preparation: AUDIT_SCOPE.md

### Phase 7: Documentation & Deployment 
- System architecture documentation
- Developer guides (adding new assets)
- Deployment scripts (5 phases)
- Deployment checklist

## Extensibility (Never Box In)

7 mechanisms to prevent architectural lock-in:
1. Plugin Architecture - Add asset types without core changes
2. Upgradeable Contracts - UUPS proxies
3. Registry-Based Config - No hardcoded addresses
4. Modular Bridges - Asset-specific contracts
5. Composable Compliance - Stackable modules
6. Multi-Source Liquidity - Pluggable providers
7. Event-Driven - Loose coupling

## Statistics

- Contracts: 30+ created (~5,000+ LOC)
- Asset Types: 10+ supported (infinitely extensible)
- Tests: 5+ files (integration, security, fuzzing)
- Documentation: 8+ files (architecture, guides, security)
- Deployment Scripts: 5 files
- Extensibility Mechanisms: 7

## Result

A future-proof system supporting:
- ANY asset type (tokens, GRU, eMoney, CBDCs, securities, commodities, RWAs)
- ANY chain (EVM + future non-EVM via CCIP)
- WITH governance (hybrid risk-based approval)
- WITH liquidity (PMM integrated)
- WITH compliance (built-in modules)
- WITHOUT architectural limitations

Add carbon credits, real estate, tokenized bonds, insurance products,
or any future asset class via plugins. No redesign ever needed.

Status: Ready for Testing → Audit → Production
2026-01-24 07:01:37 -08:00

129 lines
3.9 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Error Boundary Component - Catches React errors and displays fallback UI
*/
import { Component, ErrorInfo, ReactNode } from 'react'
import toast from 'react-hot-toast'
interface Props {
children: ReactNode
fallback?: ReactNode
}
interface State {
hasError: boolean
error: Error | null
errorInfo: ErrorInfo | null
}
export class ErrorBoundary extends Component<Props, State> {
constructor(props: Props) {
super(props)
this.state = {
hasError: false,
error: null,
errorInfo: null,
}
}
static getDerivedStateFromError(error: Error): State {
return {
hasError: true,
error,
errorInfo: null,
}
}
componentDidCatch(error: Error, errorInfo: ErrorInfo) {
console.error('ErrorBoundary caught an error:', error, errorInfo)
// Log to error tracking service (e.g., Sentry) if configured
if (import.meta.env.VITE_SENTRY_DSN) {
// Sentry.captureException(error, { contexts: { react: { componentStack: errorInfo.componentStack } } })
}
this.setState({
error,
errorInfo,
})
// Show user-friendly error toast
toast.error('An unexpected error occurred. Please refresh the page.')
}
handleReset = () => {
this.setState({
hasError: false,
error: null,
errorInfo: null,
})
}
render() {
if (this.state.hasError) {
if (this.props.fallback) {
return this.props.fallback
}
return (
<div className="min-h-screen flex items-center justify-center bg-gradient-to-br from-gray-900 via-blue-900 to-purple-900 p-4">
<div className="bg-white/10 backdrop-blur-xl rounded-2xl shadow-2xl border border-white/20 p-8 max-w-2xl w-full">
<div className="text-center">
<div className="text-6xl mb-4"></div>
<h1 className="text-3xl font-bold text-white mb-4">Something went wrong</h1>
<p className="text-white/70 mb-6">
An unexpected error occurred. Please try refreshing the page or contact support if the problem persists.
</p>
{import.meta.env.DEV && this.state.error && (
<details className="mt-6 text-left bg-black/20 rounded-lg p-4 border border-white/10">
<summary className="text-white/70 cursor-pointer mb-2">Error Details (Development Only)</summary>
<pre className="text-red-300 text-xs overflow-auto max-h-64">
{this.state.error.toString()}
{this.state.errorInfo?.componentStack && (
<>
{'\n\nComponent Stack:'}
{this.state.errorInfo.componentStack}
</>
)}
</pre>
</details>
)}
<div className="flex gap-4 justify-center mt-6">
<button
onClick={this.handleReset}
className="px-6 py-3 bg-blue-600 hover:bg-blue-700 text-white rounded-lg font-semibold transition-colors"
>
Try Again
</button>
<button
onClick={() => window.location.reload()}
className="px-6 py-3 bg-gray-600 hover:bg-gray-700 text-white rounded-lg font-semibold transition-colors"
>
Refresh Page
</button>
</div>
</div>
</div>
</div>
)
}
return this.props.children
}
}
// Global error handler for unhandled errors
if (typeof window !== 'undefined') {
window.addEventListener('error', (event) => {
console.error('Global error:', event.error)
toast.error('An unexpected error occurred')
})
window.addEventListener('unhandledrejection', (event) => {
console.error('Unhandled promise rejection:', event.reason)
toast.error('An operation failed unexpectedly')
})
}