# Central Relay Hub Architecture

## Overview

The Ario application uses a centralized relay hub architecture to manage all Nostr relay connections. This design provides a single point of connection management, efficient resource sharing, and consistent relay behavior across all components.

## Architecture Components

### 1. Core Relay Hub (`relayHub.ts`)

The `RelayHub` class is the foundation of the relay management system, built on top of `nostr-tools` SimplePool.

**Key Features:**
- **Singleton Pattern**: Single instance manages all relay connections
- **Connection Pooling**: Efficiently manages multiple relay connections
- **Automatic Reconnection**: Handles connection failures and reconnection logic
- **Health Monitoring**: Regular health checks and status reporting
- **Mobile Optimization**: Handles mobile app visibility changes
- **Event Emission**: Provides event-driven architecture for status updates

**Location:** `src/modules/base/nostr/relay-hub.ts` *(moved from legacy lib/nostr location)*

### 2. Relay Hub Composable (`useRelayHub.ts`)

A Vue 3 composable that provides a reactive interface to the relay hub.

**Key Features:**
- **Reactive State**: `isConnected`, `connectionStatus`, `relayStatuses`
- **Connection Management**: `initialize()`, `connect()`, `disconnect()`
- **Subscription Management**: `subscribe()`, `unsubscribe()`
- **Event Publishing**: `publishEvent()`, `queryEvents()`
- **Health Monitoring**: Connection health percentages and status

**Location:** `src/composables/useRelayHub.ts`

### 3. Application Integration (`App.vue`)

The main application component initializes the relay hub at startup.

**Key Integration Points:**
```typescript
// Initialize relay hub
const relayHub = useRelayHub()

onMounted(async () => {
  // Initialize relay hub
  try {
    await relayHub.initialize()
    console.log('Relay hub initialized successfully')
  } catch (error) {
    console.error('Failed to initialize relay hub:', error)
  }
})
```

## How Components Plug Into the Relay Hub

### 1. Direct Integration via `useRelayHub()`

Components can directly use the relay hub composable:

```typescript
import { useRelayHub } from '@/composables/useRelayHub'

export default {
  setup() {
    const relayHub = useRelayHub()
    
    // Access reactive state
    const isConnected = relayHub.isConnected
    const connectionStatus = relayHub.connectionStatus
    
    // Use connection methods
    const connect = async () => {
      await relayHub.connect()
    }
    
    // Subscribe to events
    const unsubscribe = relayHub.subscribe({
      id: 'my-subscription',
      filters: [{ kinds: [1] }], // Text notes
      onEvent: (event) => {
        console.log('Received event:', event)
      }
    })
    
    // Clean up on unmount
    onUnmounted(() => {
      unsubscribe()
    })
    
    return {
      isConnected,
      connectionStatus,
      connect
    }
  }
}
```

### 2. Indirect Integration via Specialized Composables

Components can use specialized composables that internally use the relay hub:

#### Chat Integration (`useNostrChat.ts`)

The chat system integrates with the relay hub for message handling:

```typescript
// Inside useNostrChat.ts
const subscribeToPeer = async (peerPubkey: string) => {
  // Check connection status
  if (!relayHub.isConnected.value) {
    await relayHub.connect()
  }
  
  // Subscribe to peer messages
  const unsubscribe = relayHub.subscribe({
    id: `peer-${peerPubkey}`,
    filters: [
      {
        kinds: [4], // Direct messages
        '#p': [currentUser.value.pubkey],
        authors: [peerPubkey]
      }
    ],
    onEvent: (event) => handleIncomingMessage(event, peerPubkey)
  })
  
  return unsubscribe
}
```

#### Market Integration (`useMarket.ts`)

The market system can integrate similarly:

```typescript
// Example market integration
const subscribeToMarketEvents = async () => {
  if (!relayHub.isConnected.value) {
    await relayHub.connect()
  }
  
  return relayHub.subscribe({
    id: 'market-events',
    filters: [
      {
        kinds: [30000], // Custom market events
        '#t': ['market']
      }
    ],
    onEvent: (event) => handleMarketEvent(event)
  })
}
```

### 3. Configuration and Setup

#### Relay Configuration

Relays are configured in the application config:

```typescript
// src/lib/config.ts
export const config = {
  nostr: {
    relays: [
      'wss://relay.ariege.io',
      'wss://lnbits.ariege.io/nostrrelay/benac'
    ]
  }
}
```

#### Initialization Order

1. **App.vue** initializes the relay hub
2. **Components** can use the relay hub immediately after initialization
3. **Specialized composables** handle their own relay hub integration

## Benefits of the Central Relay Hub Architecture

### 1. **Resource Efficiency**
- Single connection pool for all relay connections
- Shared connection management across components
- Reduced memory usage and connection overhead

### 2. **Consistent Behavior**
- Unified connection status across the application
- Consistent error handling and reconnection logic
- Standardized relay health monitoring

### 3. **Scalability**
- Easy to add new relay endpoints
- Centralized configuration management
- Simple to extend with new relay features

### 4. **Maintainability**
- Single point of truth for relay logic
- Easier debugging and monitoring
- Centralized relay-related bug fixes

## Best Practices for Component Integration

### 1. **Always Check Connection Status**

```typescript
const myFunction = async () => {
  if (!relayHub.isConnected.value) {
    await relayHub.connect()
  }
  // Proceed with relay operations
}
```

### 2. **Use Subscription IDs**

```typescript
const subscriptionId = `my-component-${Date.now()}`
const unsubscribe = relayHub.subscribe({
  id: subscriptionId,
  filters: [...],
  onEvent: handleEvent
})
```

### 3. **Clean Up Subscriptions**

```typescript
onUnmounted(() => {
  if (unsubscribe) {
    unsubscribe()
  }
})
```

### 4. **Handle Connection Errors**

```typescript
const connect = async () => {
  try {
    await relayHub.connect()
  } catch (error) {
    console.error('Failed to connect:', error)
    // Handle error appropriately
  }
}
```

### 5. **Monitor Connection Health**

```typescript
const connectionHealth = computed(() => relayHub.connectionHealth)
const isHealthy = computed(() => connectionHealth.value > 50)
```

## Example: Creating a New Relay-Enabled Component

Here's a complete example of a new component that uses the relay hub:

```vue
<template>
  <div>
    <div>Connection Status: {{ connectionStatus }}</div>
    <div>Connected Relays: {{ connectedRelayCount }}/{{ totalRelayCount }}</div>
    <button @click="subscribeToEvents" :disabled="!isConnected">
      Subscribe to Events
    </button>
    <div v-if="events.length">
      <h3>Received Events:</h3>
      <div v-for="event in events" :key="event.id">
        {{ event.content }}
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue'
import { useRelayHub } from '@/composables/useRelayHub'

const relayHub = useRelayHub()
const events = ref<any[]>([])
let unsubscribe: (() => void) | null = null

const { isConnected, connectionStatus, connectedRelayCount, totalRelayCount } = relayHub

const subscribeToEvents = async () => {
  if (!relayHub.isConnected.value) {
    await relayHub.connect()
  }
  
  unsubscribe = relayHub.subscribe({
    id: 'my-component-events',
    filters: [
      {
        kinds: [1], // Text notes
        limit: 10
      }
    ],
    onEvent: (event) => {
      events.value.push(event)
    }
  })
}

onUnmounted(() => {
  if (unsubscribe) {
    unsubscribe()
  }
})
</script>
```

## Troubleshooting

### Common Issues

1. **Connection Not Established**
   - Check if relay hub is initialized in App.vue
   - Verify relay URLs in configuration
   - Check browser console for connection errors

2. **Subscriptions Not Working**
   - Ensure connection is established before subscribing
   - Verify subscription filters are correct
   - Check if unsubscribe function is called prematurely

3. **Performance Issues**
   - Monitor number of active subscriptions
   - Use appropriate filter limits
   - Clean up unused subscriptions

### Debug Tools

The relay hub provides several debugging capabilities:

```typescript
// Check connection status
console.log('Connected:', relayHub.isConnected.value)
console.log('Relay count:', relayHub.totalRelayCount)

// Monitor relay health
console.log('Health:', relayHub.connectionHealth.value)

// Check specific relay status
const status = relayHub.getRelayStatus('wss://relay.example.com')
console.log('Relay status:', status)
```

## Conclusion

The central relay hub architecture provides a robust, efficient, and maintainable way to manage Nostr relay connections across the Ario application. By following the integration patterns outlined in this document, components can easily leverage the relay hub's capabilities while maintaining clean separation of concerns and optimal performance.

For questions or issues with relay hub integration, refer to the existing implementations in `useNostrChat.ts` and `useMarket.ts` as reference examples.
