Overview
The SubWallet Extension UI is built with React 18, TypeScript, and Redux Toolkit. It runs in the extension popup and communicates with the background service through Chrome runtime messaging.Architecture
Entry Point
Location:packages/extension-koni-ui/src/Popup/index.tsx
packages/extension-koni-ui/src/Popup/index.tsx:22-43
Context Providers
DataContextProvider
Manages Redux store and background service subscriptions. Location:packages/extension-koni-ui/src/contexts/DataContext.tsx
packages/extension-koni-ui/src/contexts/DataContext.tsx:29-79
Key Features:
- Manages background service subscriptions
- Tracks store readiness states
- Lazy-loads data handlers on demand
- Provides
awaitStores()to wait for data availability
ThemeProvider
Manages dark/light theme switching and persistence.ModalContextProvider
Central modal management for dialogs and overlays.ScannerContextProvider
Handles QR code scanning functionality.State Management
Redux Store Structure
Location:packages/extension-koni-ui/src/stores/index.ts
packages/extension-koni-ui/src/stores/index.ts:49-89
Persisted Stores
The following stores are persisted to local storage:packages/extension-koni-ui/src/stores/index.ts:33-47
Messaging Layer
Message Client
Location:packages/extension-koni-ui/src/messaging/base.ts
packages/extension-koni-ui/src/messaging/base.ts:22-105
Message Types
Messages follow the pattern<scope>(<feature>.<action>):
pri(): Private messages (from UI to background)pub(): Public messages (from dApps to background)
Subscription Pattern
Custom Hooks
The UI provides extensive custom hooks for common operations.Data Hooks
Location:packages/extension-koni-ui/src/hooks/
Example: useSelector Hook
Example: useChainInfo Hook
Component Patterns
Awaiting Store Data
Handling Transactions
File Structure
Performance Optimization
Lazy Loading
Data Handler Pattern
Best Practices
- Use Hooks: Leverage custom hooks for common operations
- Await Stores: Always wait for required stores before rendering
- Cleanup Subscriptions: Unsubscribe in useEffect cleanup
- Error Handling: Use try-catch and error boundaries
- Type Safety: Use TypeScript types from background
- Memoization: Use useMemo/useCallback for expensive operations
Related Documentation
- Message Passing - Communication between UI and background
- State Management - Redux store architecture
- Content Scripts - dApp integration layer