- Introduced comprehensive documentation for the new Wallet Module, detailing its purpose, features, and key components. - Added WebSocket integration documentation, outlining real-time balance updates, connection management, and error handling. - Updated README and module index files to include references to the Wallet Module, enhancing overall module visibility and accessibility. These changes improve the clarity and usability of the Wallet Module, providing developers with essential information for implementation and integration.
13 KiB
📦 Module System Overview
Modular architecture enabling feature-based development with plugin-based modules, dependency injection, and clean separation of concerns.
Table of Contents
- #Module Architecture
- #Available Modules
- #Module Development
- #Module Configuration
- #Inter-Module Communication
- #Module Lifecycle
Module Architecture
Plugin-Based Design
Ario uses a plugin-based architecture where each feature is implemented as a self-contained module:
- Independent Development - Modules can be developed, tested, and deployed separately
- Optional Features - Modules can be enabled or disabled via configuration
- Clear Boundaries - Each module owns its domain logic and UI components
- Extensible - New modules can be added without modifying existing code
Module Structure
Each module follows a consistent directory structure:
src/modules/[module-name]/
├── index.ts # Module plugin definition
├── components/ # Module-specific UI components
├── composables/ # Module composables and hooks
├── services/ # Business logic and API services
├── stores/ # Module-specific Pinia stores
├── types/ # TypeScript type definitions
└── views/ # Page components and routes
Module Plugin Interface
All modules implement the ModulePlugin interface:
interface ModulePlugin {
name: string // Unique module identifier
version: string // Semantic version
dependencies: string[] // Required module dependencies
// Installation lifecycle
install(app: App, options?: ModuleConfig): Promise<void>
// Optional exports
routes?: RouteRecordRaw[] // Vue Router routes
components?: Record<string, any> // Global components
composables?: Record<string, any> // Exported composables
}
Available Modules
Base Module 🏗️
Purpose: Core infrastructure and shared services
Location: src/modules/base/
Dependencies: None (foundation module)
Provides:
- Authentication Service - User identity management and Nostr key handling
- Relay Hub - Centralized Nostr relay connection management
- Storage Service - User-scoped localStorage operations
- Toast Service - Application-wide notifications and feedback
- PWA Features - Service worker and offline capabilities
Key Components:
- Identity management UI (key generation, import/export)
- Connection status indicators
- Theme and language switching
- Authentication guards and utilities
See: base-module/index
Wallet Module 💰
Purpose: Lightning Network wallet management with real-time updates
Location: src/modules/wallet/
Dependencies: ['base']
Features:
- Real-time Balance Updates - WebSocket connection to LNbits for instant balance sync
- Payment Processing - Send to Lightning invoices, addresses, and LNURL endpoints
- Transaction Management - Comprehensive history with real-time transaction updates
- Payment Links - Create LNURL payment links and Lightning addresses for receiving
- Multi-wallet Support - Manage multiple wallets with automatic selection
- Battery Optimization - Pauses WebSocket when app not visible to save battery
Key Components:
- SendDialog for payment sending interface
- ReceiveDialog for payment link creation
- TransactionList with real-time updates
- BalanceDisplay with WebSocket synchronization
- PayLinkManager for LNURL link management
WebSocket Integration:
- Real-time balance updates via LNbits WebSocket API
- Smart unit conversion handling (sats/millisats)
- Automatic reconnection with exponential backoff
- VisibilityService integration for mobile battery optimization
See: wallet-module/index
Nostr Feed Module 📰
Purpose: Social feed and content discovery
Location: src/modules/nostr-feed/
Dependencies: ['base']
Features:
- Social Feed - Timeline of Nostr events (kind 1 notes)
- Admin Announcements - Highlighted posts from configured admin pubkeys
- Content Filtering - Filter by author, content type, or keywords
- Real-time Updates - Live feed updates via Nostr subscriptions
- Engagement - Like, repost, and reply to posts
Key Components:
- FeedComponent with infinite scroll
- NoteCard for individual posts
- AdminBadge for announcement highlighting
- Content filtering and search
Chat Module 💬
Purpose: Encrypted direct messaging
Location: src/modules/chat/
Dependencies: ['base']
Features:
- Encrypted Messages - NIP-04 encrypted direct messages
- Contact Management - Add and manage chat contacts
- Real-time Chat - Live message delivery via Nostr relays
- Message History - Persistent chat history with local storage
- Typing Indicators - Real-time typing status (when supported)
Key Components:
- ChatComponent with message bubbles
- ContactList for chat participants
- MessageInput with encryption handling
- Chat history management
See: chat-module/index
Events Module 🎟️
Purpose: Event ticketing and management
Location: src/modules/events/
Dependencies: ['base']
Features:
- Event Creation - Create and publish events to Nostr
- Lightning Tickets - Paid event tickets using Lightning invoices
- Event Discovery - Browse and search upcoming events
- Ticket Management - Purchase, transfer, and validate tickets
- Event Check-in - QR code-based event entry system
Key Components:
- EventCard for event display
- TicketPurchase with Lightning payment flow
- EventCreation form with rich editing
- QR code generation and scanning
See: events-module/index
Market Module 🛒
Purpose: Nostr marketplace functionality
Location: src/modules/market/
Dependencies: ['base']
Features:
- Product Listings - Create and browse marketplace items
- Lightning Payments - Bitcoin payments for products
- Vendor Profiles - Seller reputation and product history
- Order Management - Track purchases and sales
- Product Search - Filter and search marketplace items
Key Components:
- ProductCard for item display
- ProductListing creation form
- OrderHistory and transaction tracking
- Vendor dashboard and analytics
See: market-module/index
Module Development
Creating a New Module
1. Module Structure Setup
mkdir src/modules/my-module
cd src/modules/my-module
# Create module directories
mkdir components composables services stores types views
touch index.ts
2. Module Plugin Definition
// src/modules/my-module/index.ts
import type { App } from 'vue'
import type { ModulePlugin } from '@/core/types'
export const myModule: ModulePlugin = {
name: 'my-module',
version: '1.0.0',
dependencies: ['base'], // Always depend on base for core services
async install(app: App, options?: MyModuleConfig) {
// Register module components
// Initialize module services
// Set up module routes
},
routes: [
{
path: '/my-feature',
component: () => import('./views/MyFeatureView.vue')
}
]
}
3. Service Implementation
// src/modules/my-module/services/my-service.ts
import { BaseService } from '@/core/base/BaseService'
import { injectService, SERVICE_TOKENS } from '@/core/di-container'
export class MyService extends BaseService {
constructor(
private relayHub = injectService(SERVICE_TOKENS.RELAY_HUB)
) {
super()
}
async initialize(): Promise<void> {
// Service initialization logic
this.isInitialized.value = true
}
async dispose(): Promise<void> {
// Cleanup logic
this.isDisposed.value = true
}
}
4. Module Registration
// src/app.config.ts
export const moduleConfigs = {
// ... existing modules
'my-module': {
enabled: true,
customOption: 'value'
}
}
Module Development Best Practices
Dependency Management
- Always declare module dependencies explicitly
- Use dependency injection for cross-module service access
- Avoid direct imports between modules
Service Architecture
- Extend
BaseServicefor consistent lifecycle management - Register services in the DI container during module installation
- Use reactive properties for state that affects UI
Component Patterns
- Export reusable components for other modules
- Use module-specific component naming (e.g.,
ChatMessage,EventCard) - Follow the existing UI component patterns with Shadcn/ui
Module Configuration
Configuration Schema
Modules can be configured via src/app.config.ts:
interface ModuleConfig {
enabled: boolean // Enable/disable module
[key: string]: any // Module-specific configuration
}
export const moduleConfigs: Record<string, ModuleConfig> = {
'base': { enabled: true },
'chat': {
enabled: true,
maxMessageLength: 1000,
enableTypingIndicators: true
},
'events': {
enabled: true,
defaultCurrency: 'sat',
allowedEventTypes: ['meetup', 'conference', 'workshop']
}
}
Runtime Configuration
Configuration is passed to modules during installation:
async install(app: App, options?: ChatModuleConfig) {
const config = options || defaultConfig
// Use configuration to customize module behavior
this.messageService.setMaxLength(config.maxMessageLength)
}
Inter-Module Communication
Service Dependencies
For required functionality between modules:
// ✅ Correct: Use dependency injection
const relayHub = injectService(SERVICE_TOKENS.RELAY_HUB)
// ❌ Wrong: Direct import breaks modularity
import { relayHub } from '../base/services/relay-hub'
Event Bus Communication
For optional cross-module notifications:
// Publishing events
eventBus.emit('user:authenticated', { userId: user.pubkey })
eventBus.emit('payment:received', { amount: 1000, invoiceId: 'abc123' })
// Subscribing to events
eventBus.on('chat:message-received', (message) => {
// Handle message in events module
})
Shared Components
Modules can export components for use by other modules:
// In module plugin definition
export const chatModule: ModulePlugin = {
// ...
components: {
'ChatAvatar': () => import('./components/ChatAvatar.vue'),
'MessageBubble': () => import('./components/MessageBubble.vue')
}
}
// Usage in other modules
<ChatAvatar :pubkey="user.pubkey" :size="32" />
Module Lifecycle
Initialization Order
- Dependency Resolution - PluginManager sorts modules by dependencies
- Service Registration - Modules register services in DI container
- Component Registration - Global components made available
- Route Registration - Module routes added to Vue Router
- Service Initialization - Services initialize in dependency order
Module Installation Process
async install(app: App, options?: ModuleConfig) {
// 1. Register services
container.provide(SERVICE_TOKENS.MY_SERVICE, new MyService())
// 2. Register global components
app.component('MyGlobalComponent', MyGlobalComponent)
// 3. Initialize module-specific logic
await this.initializeModule(options)
}
Service Lifecycle Management
// Service initialization (called automatically)
async initialize(): Promise<void> {
await this.setupEventListeners()
await this.loadUserData()
this.isInitialized.value = true
}
// Service disposal (called on app unmount)
async dispose(): Promise<void> {
this.removeEventListeners()
await this.saveUserData()
this.isDisposed.value = true
}
See Also
Module Documentation
- base-module/index - Core infrastructure services
- wallet-module/index - Lightning wallet with real-time updates
- chat-module/index - Encrypted messaging system
- events-module/index - Lightning event ticketing
- market-module/index - Nostr marketplace
- nostr-feed-module/index - Social feed functionality
Architecture References
- ../01-architecture/modular-design - Architecture principles
- ../01-architecture/dependency-injection - Service container system
- ../04-development/index - Module development workflows
Tags: #modules #architecture #plugin-system #development
Last Updated: 2025-09-06
Author: Development Team