# ⚙️ Core Services Overview

> **Shared infrastructure services** providing foundational functionality across all modules with reactive architecture, dependency injection, and lifecycle management.

## Table of Contents

- [[#Service Architecture]]
- [[#Available Services]]
- [[#Service Lifecycle]]
- [[#Dependency Injection]]
- [[#Service Development]]
- [[#Testing Services]]

## Service Architecture

### **BaseService Foundation**
All core services extend the `BaseService` abstract class which provides:

- **Reactive State Management** - Integration with Vue's reactivity system
- **Lifecycle Management** - Standardized initialization and disposal
- **Error Handling** - Consistent error patterns across services
- **Type Safety** - Full TypeScript support with strict typing

```typescript
abstract class BaseService {
  protected isInitialized = ref(false)
  protected isDisposed = ref(false)
  
  abstract initialize(): Promise<void>
  abstract dispose(): Promise<void>
  
  // Reactive state helpers
  protected createReactiveState<T>(initialValue: T): Ref<T>
  protected createComputedState<T>(getter: () => T): ComputedRef<T>
}
```

### **Service Registration Pattern**
Services are registered in the dependency injection container during module installation:

```typescript
// Service registration (in base module)
container.provide(SERVICE_TOKENS.RELAY_HUB, relayHub)
container.provide(SERVICE_TOKENS.AUTH_SERVICE, authService)
container.provide(SERVICE_TOKENS.STORAGE_SERVICE, storageService)

// Service consumption (anywhere in app)
const relayHub = injectService(SERVICE_TOKENS.RELAY_HUB)
const auth = injectService(SERVICE_TOKENS.AUTH_SERVICE)
```

## Available Services

### **AuthService** 🔐
**Purpose:** User authentication and identity management  
**Location:** `src/modules/base/auth/auth-service.ts`  
**Token:** `SERVICE_TOKENS.AUTH_SERVICE`

**Key Features:**
- **Key Management** - Secure generation, import, and storage of Nostr keys
- **User Sessions** - Persistent authentication with encrypted storage
- **Profile Management** - User profile creation and updates
- **Security** - Client-side key handling with no server storage

**Reactive State:**
```typescript
interface AuthService {
  user: Ref<NostrUser | null>                    // Current authenticated user
  isAuthenticated: ComputedRef<boolean>          // Authentication status
  isLoading: Ref<boolean>                        // Loading state
  loginError: Ref<string | null>                 // Login error message
}
```

**Key Methods:**
- `generateKeyPair()` - Create new Nostr key pair
- `loginWithPrivateKey(privateKey: string)` - Authenticate with existing key
- `logout()` - Clear session and user data
- `updateProfile(profile: UserMetadata)` - Update user profile

**See:** [[authentication|📖 Authentication Service Documentation]]

### **PaymentService** 💳
**Purpose:** Centralized Lightning payment processing and wallet management
**Location:** `src/core/services/PaymentService.ts`
**Token:** `SERVICE_TOKENS.PAYMENT_SERVICE`

**Key Features:**
- **Wallet Management** - Multi-wallet support with preferred wallet selection
- **Payment Processing** - Lightning invoices, QR code generation, and external wallet handling
- **Balance Management** - Real-time wallet balance updates and tracking
- **Payment Validation** - Balance checking and payment amount validation
- **Error Handling** - Consistent payment error handling and user feedback

**Reactive State:**
```typescript
interface PaymentService {
  isProcessingPayment: ComputedRef<boolean>       // Payment in progress
  paymentError: ComputedRef<string | null>        // Payment error state
  totalBalance: number                            // Total balance across wallets (getter)
  hasWalletWithBalance: boolean                   // Wallet availability check (getter)
}
```

**Key Methods:**
- `payWithWallet(paymentRequest, amount?, options?)` - Process Lightning payment
- `generateQRCode(paymentRequest, options?)` - Generate payment QR codes
- `openExternalWallet(paymentRequest)` - Launch external Lightning wallet
- `updateWalletBalance(balanceMsat, walletId?)` - Update wallet balance from WebSocket
- `getPreferredWallet()` - Get the primary wallet for operations
- `getWalletWithBalance(requiredAmount?)` - Find wallet with sufficient balance

**Wallet Selection Logic:**
- Always uses first wallet (`wallets[0]`) for consistency across modules
- Provides helper methods for wallet selection and balance checking
- Integrates with AuthService for wallet credentials and management

**See:** [[payment-service|📖 Payment Service Documentation]]

### **RelayHub** 🌐
**Purpose:** Centralized Nostr relay connection management  
**Location:** `src/modules/base/nostr/relay-hub.ts`  
**Token:** `SERVICE_TOKENS.RELAY_HUB`

**Key Features:**
- **Connection Management** - Automatic connection, reconnection, and failover
- **Event Publishing** - Reliable event publishing across multiple relays
- **Subscription Management** - Efficient event subscriptions with deduplication
- **Performance Monitoring** - Relay latency and success rate tracking

**Reactive State:**
```typescript
interface RelayHub {
  connectedRelays: Ref<string[]>                 // Currently connected relays
  connectionStatus: ComputedRef<ConnectionStatus> // Overall connection status
  relayStats: Ref<Map<string, RelayStats>>       // Per-relay statistics
  isConnecting: Ref<boolean>                     // Connection in progress
}
```

**Key Methods:**
- `connect(relays: string[])` - Connect to relay URLs
- `publishEvent(event: NostrEvent)` - Publish event to all connected relays
- `subscribe(filters: Filter[], callback: EventCallback)` - Subscribe to events
- `getRelayInfo(url: string)` - Get relay connection information

**See:** [[../01-architecture/relay-hub|📖 Relay Hub Architecture Documentation]]

### **StorageService** 💾
**Purpose:** User-scoped local storage operations  
**Location:** `src/core/services/StorageService.ts`  
**Token:** `SERVICE_TOKENS.STORAGE_SERVICE`

**Key Features:**
- **User-Scoped Storage** - Automatic key prefixing per authenticated user
- **Type-Safe Operations** - Strongly typed get/set operations with JSON serialization
- **Reactive Updates** - Optional reactive storage with Vue refs
- **Migration Support** - Data migration between storage schema versions

**Key Methods:**
```typescript
interface StorageService {
  setUserData<T>(key: string, data: T): void
  getUserData<T>(key: string, defaultValue?: T): T | undefined
  removeUserData(key: string): void
  clearUserData(): void
  
  // Reactive variants
  getReactiveUserData<T>(key: string, defaultValue: T): Ref<T>
  setReactiveUserData<T>(key: string, ref: Ref<T>): void
}
```

**Storage Patterns:**
- User-specific keys: `user:{pubkey}:settings`
- Global application keys: `app:theme`
- Module-specific keys: `user:{pubkey}:chat:contacts`

**See:** [[storage-service|📖 Storage Service Documentation]]

### **ToastService** 📢
**Purpose:** Application-wide notifications and user feedback  
**Location:** `src/core/services/ToastService.ts`  
**Token:** `SERVICE_TOKENS.TOAST_SERVICE`

**Key Features:**
- **Context-Specific Methods** - Pre-configured toasts for common scenarios
- **Consistent Messaging** - Standardized success, error, and info messages
- **Accessibility** - Screen reader compatible notifications
- **Customizable** - Support for custom toast content and actions

**Organized by Context:**
```typescript
interface ToastService {
  // Authentication context
  auth: {
    loginSuccess(): void
    loginError(error?: string): void
    logoutSuccess(): void
    keyGenerated(): void
  }
  
  // Payment context
  payment: {
    invoiceCreated(): void
    paymentReceived(): void
    paymentFailed(error?: string): void
  }
  
  // Clipboard operations
  clipboard: {
    copied(item?: string): void
    copyFailed(): void
  }
  
  // General operations
  operation: {
    success(message: string): void
    error(message: string): void
    info(message: string): void
  }
}
```

**See:** [[toast-service|📖 Toast Service Documentation]]

### **EventBus** 📡
**Purpose:** Inter-module communication and event coordination  
**Location:** `src/core/services/EventBus.ts`  
**Token:** `SERVICE_TOKENS.EVENT_BUS`

**Key Features:**
- **Type-Safe Events** - Strongly typed event payloads
- **Module Isolation** - Clean communication between modules
- **Event Namespacing** - Organized event names by domain
- **Subscription Management** - Easy subscribe/unsubscribe patterns

**Event Categories:**
```typescript
interface EventBusEvents {
  // User events
  'user:authenticated': { userId: string, profile: UserMetadata }
  'user:profile-updated': { userId: string, changes: Partial<UserMetadata> }
  'user:logout': { userId: string }
  
  // Chat events
  'chat:message-received': { messageId: string, from: string, content: string }
  'chat:typing-start': { from: string, chatId: string }
  
  // Payment events
  'payment:invoice-created': { invoiceId: string, amount: number }
  'payment:received': { invoiceId: string, amount: number }
  
  // Relay events
  'relay:connected': { url: string }
  'relay:disconnected': { url: string, reason?: string }
}
```

**See:** [[../01-architecture/event-bus|📖 Event Bus Communication Documentation]]

### **WalletService** 🏦
**Purpose:** Wallet operations and transaction management
**Location:** `src/modules/wallet/services/WalletService.ts`
**Token:** `SERVICE_TOKENS.WALLET_SERVICE`

**Key Features:**
- **Payment Operations** - Send Lightning payments to invoices, addresses, and LNURL
- **Payment Link Management** - Create and manage LNURL payment links and Lightning addresses
- **Transaction History** - Load and manage comprehensive transaction history
- **Real-time Updates** - Add new transactions from WebSocket notifications

**Reactive State:**
```typescript
interface WalletService {
  transactions: ComputedRef<PaymentTransaction[]>   // Transaction history
  payLinks: ComputedRef<PayLink[]>                 // Created payment links
  isCreatingPayLink: ComputedRef<boolean>          // Pay link creation state
  isSendingPayment: ComputedRef<boolean>           // Payment sending state
  error: ComputedRef<string | null>                // Error state
}
```

**Key Methods:**
- `sendPayment(request: SendPaymentRequest)` - Send Lightning payment
- `createReceiveAddress(params)` - Create LNURL payment link with Lightning address
- `deletePayLink(linkId: string)` - Remove payment link
- `addTransaction(payment)` - Add transaction from WebSocket notification
- `refresh()` - Reload transactions and payment links

### **WalletWebSocketService** ⚡
**Purpose:** Real-time wallet balance updates via WebSocket
**Location:** `src/modules/wallet/services/WalletWebSocketService.ts`
**Token:** `SERVICE_TOKENS.WALLET_WEBSOCKET_SERVICE`

**Key Features:**
- **Real-time Connection** - WebSocket connection to LNbits for instant updates
- **Balance Synchronization** - Smart balance updates with unit conversion handling
- **Payment Notifications** - Toast notifications for incoming payments
- **Connection Management** - Automatic reconnection with exponential backoff
- **Battery Optimization** - VisibilityService integration for mobile efficiency

**Reactive State:**
```typescript
interface WalletWebSocketService {
  isConnected: Ref<boolean>                        // WebSocket connection status
  connectionStatus: Ref<string>                    // Connection state details
}
```

**Connection States:**
- `disconnected` - Not connected
- `connecting` - Connection in progress
- `connected` - Successfully connected
- `reconnecting` - Attempting to reconnect
- `error` - Connection failed
- `failed` - Max reconnection attempts reached

**Key Methods:**
- `reconnect()` - Manual reconnection trigger
- `disconnect()` - Graceful disconnection
- `cleanup()` - Service disposal

**WebSocket Integration:**
- Connects to `wss://lnbits-server/api/v1/ws/{walletInkey}`
- Handles incoming/outgoing payment balance differences
- Updates PaymentService with converted balance (sats → millisats)
- Integrates with WalletService for transaction updates

## Service Lifecycle

### **Initialization Phase**
Services are initialized in dependency order during application startup:

```typescript
// 1. Base services (no dependencies)
await authService.initialize()
await storageService.initialize()

// 2. Infrastructure services (depend on base services)
await relayHub.initialize()
await toastService.initialize()

// 3. Feature services (depend on infrastructure)
await chatService.initialize()
await eventsService.initialize()
```

### **Service Dependencies**
Services declare their dependencies through constructor injection:

```typescript
class ChatService extends BaseService {
  constructor(
    private auth = injectService(SERVICE_TOKENS.AUTH_SERVICE),
    private relayHub = injectService(SERVICE_TOKENS.RELAY_HUB),
    private storage = injectService(SERVICE_TOKENS.STORAGE_SERVICE),
    private eventBus = injectService(SERVICE_TOKENS.EVENT_BUS)
  ) {
    super()
  }
}
```

### **Disposal Phase**
Services are disposed in reverse dependency order during application shutdown:

```typescript
async dispose(): Promise<void> {
  // Clean up subscriptions
  this.subscriptions.forEach(sub => sub.close())
  
  // Save persistent state
  await this.storage.setUserData('chat:messages', this.messages.value)
  
  // Mark as disposed
  this.isDisposed.value = true
}
```

## Dependency Injection

### **Service Tokens**
Type-safe service tokens prevent runtime errors and enable proper TypeScript inference:

```typescript
export const SERVICE_TOKENS = {
  AUTH_SERVICE: Symbol('AUTH_SERVICE') as InjectionKey<AuthService>,
  RELAY_HUB: Symbol('RELAY_HUB') as InjectionKey<RelayHub>,
  STORAGE_SERVICE: Symbol('STORAGE_SERVICE') as InjectionKey<StorageService>,
  TOAST_SERVICE: Symbol('TOAST_SERVICE') as InjectionKey<ToastService>,
} as const
```

### **Service Registration**
Services are registered during module installation:

```typescript
// In base module installation
export async function installBaseModule(app: App) {
  // Create service instances
  const authService = new AuthService()
  const relayHub = new RelayHub()
  const storageService = new StorageService()
  
  // Register in container
  container.provide(SERVICE_TOKENS.AUTH_SERVICE, authService)
  container.provide(SERVICE_TOKENS.RELAY_HUB, relayHub)
  container.provide(SERVICE_TOKENS.STORAGE_SERVICE, storageService)
  
  // Initialize services
  await authService.initialize()
  await relayHub.initialize()
}
```

### **Service Consumption**
Services are injected where needed using type-safe injection:

```typescript
// In composables
export function useAuth() {
  const authService = injectService(SERVICE_TOKENS.AUTH_SERVICE)
  
  return {
    user: authService.user,
    login: authService.login,
    logout: authService.logout
  }
}

// In components
<script setup>
const toast = injectService(SERVICE_TOKENS.TOAST_SERVICE)
const handleSuccess = () => toast.operation.success('Action completed!')
</script>
```

## Service Development

### **Creating a New Service**

#### 1. Service Class Implementation
```typescript
// src/core/services/MyService.ts
export class MyService extends BaseService {
  // Reactive state
  private readonly _data = ref<MyData[]>([])
  private readonly _isLoading = ref(false)
  
  // Public readonly access to state
  public readonly data = readonly(this._data)
  public readonly isLoading = readonly(this._isLoading)
  
  constructor(
    private dependency = injectService(SERVICE_TOKENS.DEPENDENCY)
  ) {
    super()
  }
  
  async initialize(): Promise<void> {
    // Initialization logic
    await this.loadInitialData()
    this.isInitialized.value = true
  }
  
  async dispose(): Promise<void> {
    // Cleanup logic
    this._data.value = []
    this.isDisposed.value = true
  }
  
  // Public methods
  async createItem(item: CreateItemRequest): Promise<MyData> {
    this._isLoading.value = true
    try {
      const newItem = await this.dependency.create(item)
      this._data.value.push(newItem)
      return newItem
    } finally {
      this._isLoading.value = false
    }
  }
}
```

#### 2. Service Token Registration
```typescript
// Add to SERVICE_TOKENS
export const SERVICE_TOKENS = {
  // ... existing tokens
  MY_SERVICE: Symbol('MY_SERVICE') as InjectionKey<MyService>,
} as const
```

#### 3. Service Registration in Module
```typescript
// In module installation
const myService = new MyService()
container.provide(SERVICE_TOKENS.MY_SERVICE, myService)
await myService.initialize()
```

### **Service Best Practices**

#### **Reactive State Management**
- Use `ref()` for mutable state, `readonly()` for public access
- Provide computed properties for derived state
- Use `watch()` and `watchEffect()` for side effects

#### **Error Handling**
- Throw descriptive errors with proper types
- Use try/catch blocks with proper cleanup
- Log errors appropriately for debugging

#### **Performance Optimization**
- Implement proper subscription cleanup in `dispose()`
- Use debouncing for frequent operations
- Cache expensive computations with `computed()`

## Testing Services

### **Service Unit Tests**
```typescript
// tests/unit/services/MyService.test.ts
describe('MyService', () => {
  let service: MyService
  let mockDependency: MockType<DependencyService>
  
  beforeEach(() => {
    // Setup mocks
    mockDependency = createMockService()
    
    // Create service with mocks
    service = new MyService(mockDependency)
  })
  
  afterEach(async () => {
    await service.dispose()
  })
  
  it('should initialize correctly', async () => {
    await service.initialize()
    
    expect(service.isInitialized.value).toBe(true)
    expect(service.data.value).toEqual([])
  })
  
  it('should create items', async () => {
    await service.initialize()
    
    const item = await service.createItem({ name: 'test' })
    
    expect(service.data.value).toContain(item)
    expect(mockDependency.create).toHaveBeenCalledWith({ name: 'test' })
  })
})
```

### **Integration Tests**
```typescript
// tests/integration/services/ServiceIntegration.test.ts
describe('Service Integration', () => {
  let container: DIContainer
  
  beforeEach(async () => {
    container = createTestContainer()
    await installTestServices(container)
  })
  
  it('should handle cross-service communication', async () => {
    const authService = container.get(SERVICE_TOKENS.AUTH_SERVICE)
    const chatService = container.get(SERVICE_TOKENS.CHAT_SERVICE)
    
    await authService.login('test-key')
    const message = await chatService.sendMessage('Hello')
    
    expect(message.author).toBe(authService.user.value?.pubkey)
  })
})
```

## See Also

### Service Documentation
- **[[authentication|🔐 Authentication Service]]** - User identity and session management
- **[[payment-service|💳 Payment Service]]** - Lightning payment processing and wallet management
- **[[storage-service|💾 Storage Service]]** - User-scoped data persistence
- **[[toast-service|📢 Toast Service]]** - User notifications and feedback
- **[[visibility-service|👁️ Visibility Service]]** - Dynamic UI component control
- **[[../02-modules/wallet-module/index|💰 Wallet Services]]** - WalletService and WebSocket integration

### Architecture References
- **[[../01-architecture/dependency-injection|⚙️ Dependency Injection]]** - DI container system
- **[[../01-architecture/event-bus|📡 Event Bus Communication]]** - Inter-service messaging
- **[[../02-modules/index|📦 Module System]]** - How services integrate with modules
- **[[../04-development/testing|🧪 Testing Guide]]** - Service testing patterns

---

**Tags:** #services #architecture #dependency-injection #reactive-state  
**Last Updated:** 2025-09-06  
**Author:** Development Team