2025-03-04 08:07:27 -05:00
|
|
|
// 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';
|
2025-03-04 08:07:27 -05:00
|
|
|
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-04 08:07:27 -05:00
|
|
|
|
2025-03-09 11:15:28 -04:00
|
|
|
/**
|
|
|
|
* Initialize NDK with relays from database or defaults
|
|
|
|
*/
|
2025-03-04 08:07:27 -05:00
|
|
|
export async function initializeNDK() {
|
2025-03-09 11:15:28 -04:00
|
|
|
console.log('[NDK] Initializing NDK with mobile adapter...');
|
2025-03-04 08:07:27 -05:00
|
|
|
|
2025-03-06 16:34:50 -05:00
|
|
|
// Create a mobile-specific cache adapter
|
|
|
|
const cacheAdapter = new NDKCacheAdapterSqlite('powr', 1000);
|
2025-03-04 08:07:27 -05:00
|
|
|
|
2025-03-09 11:15:28 -04:00
|
|
|
// Initialize database and relay service
|
|
|
|
const db = openDatabaseSync('powr.db');
|
|
|
|
const relayService = new RelayService(db);
|
|
|
|
|
|
|
|
// 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({
|
2025-03-04 08:07:27 -05:00
|
|
|
cacheAdapter,
|
2025-03-09 11:15:28 -04:00
|
|
|
explicitRelayUrls: relays,
|
2025-03-04 08:07:27 -05:00
|
|
|
enableOutboxModel: true,
|
2025-03-09 11:15:28 -04:00
|
|
|
autoConnectUserRelays: true,
|
2025-03-04 08:07:27 -05:00
|
|
|
clientName: 'powr',
|
|
|
|
});
|
|
|
|
|
2025-03-09 11:15:28 -04:00
|
|
|
// Extend NDK with helper methods for better compatibility
|
|
|
|
ndk = extendNDK(ndk);
|
|
|
|
|
2025-03-04 08:07:27 -05:00
|
|
|
// 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-04 08:07:27 -05:00
|
|
|
|
2025-03-07 10:09:55 -05:00
|
|
|
try {
|
2025-03-09 11:15:28 -04:00
|
|
|
// Connect to relays
|
2025-03-07 10:09:55 -05:00
|
|
|
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
|
|
|
|
|
|
|
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: []
|
|
|
|
};
|
|
|
|
}
|
2025-03-04 08:07:27 -05:00
|
|
|
}
|