POWR/lib/initNDK.ts

144 lines
4.6 KiB
TypeScript
Raw Normal View History

// lib/initNDK.ts
import 'react-native-get-random-values'; // This must be the first import
2025-03-09 11:15:28 -04:00
import NDK, { NDKCacheAdapterSqlite } from '@nostr-dev-kit/ndk-mobile';
import * as SecureStore from 'expo-secure-store';
2025-03-09 11:15:28 -04:00
import { openDatabaseSync } from 'expo-sqlite';
import { RelayService, DEFAULT_RELAYS } from '@/lib/db/services/RelayService';
import { NDKCommon } from '@/types/ndk-common';
import { extendNDK } from '@/types/ndk-extensions';
2025-03-09 11:15:28 -04:00
/**
* Initialize NDK with relays from database or defaults
*/
export async function initializeNDK() {
2025-03-09 11:15:28 -04:00
console.log('[NDK] Initializing NDK with mobile adapter...');
// Create a mobile-specific cache adapter
const cacheAdapter = new NDKCacheAdapterSqlite('powr', 1000);
2025-03-09 11:15:28 -04:00
// Initialize database and relay service
const db = openDatabaseSync('powr.db');
const relayService = new RelayService(db);
2025-03-09 12:48:24 -04:00
relayService.enableDebug();
2025-03-09 11:15:28 -04:00
// Load relays from database or use defaults
console.log('[NDK] Loading relay configuration...');
let relays: string[];
try {
// Try to initialize relays from database (will add defaults if none exist)
relays = await relayService.initializeRelays();
console.log(`[NDK] Loaded ${relays.length} relays from database:`, relays);
} catch (error) {
console.error('[NDK] Error loading relays from database:', error);
console.log('[NDK] Falling back to default relays');
relays = DEFAULT_RELAYS;
}
// Create settings store
const settingsStore = {
get: SecureStore.getItemAsync,
set: SecureStore.setItemAsync,
delete: SecureStore.deleteItemAsync,
getSync: (key: string) => {
// This is a synchronous wrapper - for mobile we need to handle this differently
// since SecureStore is async-only
console.log('[Settings] Warning: getSync called but returning null, not supported in this implementation');
return null;
}
};
// Initialize NDK with options
console.log(`[NDK] Creating NDK instance with ${relays.length} relays`);
let ndk = new NDK({
cacheAdapter,
2025-03-09 11:15:28 -04:00
explicitRelayUrls: relays,
enableOutboxModel: true,
2025-03-09 11:15:28 -04:00
autoConnectUserRelays: true,
clientName: 'powr',
});
2025-03-09 11:15:28 -04:00
// Extend NDK with helper methods for better compatibility
ndk = extendNDK(ndk);
// Initialize cache adapter
await cacheAdapter.initialize();
2025-03-09 11:15:28 -04:00
// Set up the RelayService with the NDK instance for future use
relayService.setNDK(ndk as unknown as NDKCommon);
2025-03-07 10:09:55 -05:00
// Setup relay status tracking
const relayStatus: Record<string, 'connected' | 'connecting' | 'disconnected' | 'error'> = {};
2025-03-09 11:15:28 -04:00
relays.forEach(url => {
2025-03-07 10:09:55 -05:00
relayStatus[url] = 'connecting';
});
// Set up listeners before connecting
2025-03-09 11:15:28 -04:00
relays.forEach(url => {
2025-03-07 10:09:55 -05:00
const relay = ndk.pool.getRelay(url);
if (relay) {
// Connection success
relay.on('connect', () => {
console.log(`[NDK] Relay connected: ${url}`);
relayStatus[url] = 'connected';
});
// Connection closed
relay.on('disconnect', () => {
console.log(`[NDK] Relay disconnected: ${url}`);
relayStatus[url] = 'disconnected';
});
// For errors, use the notice event which is used for errors in NDK
relay.on('notice', (notice: string) => {
console.error(`[NDK] Relay notice/error for ${url}:`, notice);
relayStatus[url] = 'error';
});
}
});
2025-03-07 10:09:55 -05:00
try {
console.log('[NDK] Connecting to relays...');
await ndk.connect();
2025-03-09 11:15:28 -04:00
// Wait a moment for connections to establish
await new Promise(resolve => setTimeout(resolve, 2000));
// Count connected relays
const connectedRelays = Object.entries(relayStatus)
.filter(([_, status]) => status === 'connected')
.map(([url]) => url);
2025-03-07 10:09:55 -05:00
2025-03-09 11:15:28 -04:00
console.log(`[NDK] Connected to ${connectedRelays.length}/${relays.length} relays`);
2025-03-07 10:09:55 -05:00
2025-03-09 12:48:24 -04:00
// Add more detailed relay status logging
console.log('[NDK] Detailed relay status:');
relays.forEach(url => {
const relay = ndk.pool.getRelay(url);
console.log(` - ${url}: ${relay ?
(relay.status === 1 ? 'connected' :
relay.status === 0 ? 'connecting' :
relay.status === 3 ? 'disconnected' :
`status=${relay.status}`) : 'not found'}`);
});
2025-03-07 10:09:55 -05:00
return {
ndk,
relayStatus,
2025-03-09 11:15:28 -04:00
relayService,
connectedRelayCount: connectedRelays.length,
2025-03-07 10:09:55 -05:00
connectedRelays
};
} catch (error) {
console.error('[NDK] Error during connection:', error);
// Still return the NDK instance so the app can work offline
return {
ndk,
relayStatus,
2025-03-09 11:15:28 -04:00
relayService,
2025-03-07 10:09:55 -05:00
connectedRelayCount: 0,
connectedRelays: []
};
}
}