refactor: config error handle, dvm-bridge improvements

This commit is contained in:
gzuuus
2025-02-08 12:44:03 +01:00
parent 1625661356
commit bf48b4517c
2 changed files with 130 additions and 21 deletions

View File

@@ -1,21 +1,71 @@
import { config } from 'dotenv';
config();
import { join } from 'path';
import { existsSync } from 'fs';
const envPath = join(process.cwd(), '.env');
if (!existsSync(envPath)) {
throw new Error(
'No .env file found. Please create one based on .env.example'
);
}
const result = config();
if (result.error) {
throw new Error(`Error loading .env file: ${result.error.message}`);
}
const HEX_KEYS_REGEX = /^(?:[0-9a-fA-F]{64})$/;
function requireEnvVar(name: string): string {
const value = process.env[name];
if (!value) {
throw new Error(
`Missing required environment variable: ${name}. Check your .env file`
);
}
return value;
}
function getEnvVar(name: string, defaultValue: string): string {
return process.env[name] || defaultValue;
}
export const CONFIG = {
nostr: {
privateKey: process.env.PRIVATE_KEY!,
relayUrls: process.env.RELAY_URLS!.split(',').map((url) => url.trim()),
privateKey: requireEnvVar('PRIVATE_KEY'),
relayUrls: requireEnvVar('RELAY_URLS')
.split(',')
.map((url) => url.trim()),
},
mcp: {
// Service info
name: process.env.MCP_SERVICE_NAME || 'DVM MCP Bridge',
about:
process.env.MCP_SERVICE_ABOUT ||
'MCP-enabled DVM providing AI and computational tools',
// Client connection info
clientName: process.env.MCP_CLIENT_NAME!,
clientVersion: process.env.MCP_CLIENT_VERSION!,
serverCommand: process.env.MCP_SERVER_COMMAND!,
serverArgs: process.env.MCP_SERVER_ARGS!.split(','),
name: getEnvVar('MCP_SERVICE_NAME', 'DVM MCP Bridge'),
about: getEnvVar(
'MCP_SERVICE_ABOUT',
'MCP-enabled DVM providing AI and computational tools'
),
clientName: requireEnvVar('MCP_CLIENT_NAME'),
clientVersion: requireEnvVar('MCP_CLIENT_VERSION'),
serverCommand: requireEnvVar('MCP_SERVER_COMMAND'),
serverArgs: requireEnvVar('MCP_SERVER_ARGS').split(','),
},
};
if (!HEX_KEYS_REGEX.test(CONFIG.nostr.privateKey)) {
throw new Error('PRIVATE_KEY must be a 32-byte hex string');
}
CONFIG.nostr.relayUrls.forEach((url) => {
try {
new URL(url);
if (!url.startsWith('ws://') && !url.startsWith('wss://')) {
throw new Error(`Relay URL must start with ws:// or wss://: ${url}`);
}
} catch (error) {
throw new Error(`Invalid relay URL: ${url}`);
}
});
if (CONFIG.nostr.relayUrls.length === 0) {
throw new Error('At least one relay URL must be provided in RELAY_URLS');
}

View File

@@ -9,22 +9,58 @@ export class DVMBridge {
private mcpClient: MCPClientHandler;
private nostrAnnouncer: NostrAnnouncer;
private relayHandler: RelayHandler;
private isRunning: boolean = false;
constructor() {
console.log('Initializing DVM Bridge...');
this.mcpClient = new MCPClientHandler();
this.nostrAnnouncer = new NostrAnnouncer();
this.relayHandler = new RelayHandler(CONFIG.nostr.relayUrls);
}
async start() {
if (this.isRunning) {
console.log('Bridge is already running');
return;
}
console.log('Starting DVM Bridge...');
try {
console.log('Connecting to MCP server...');
await this.mcpClient.connect();
const tools = await this.mcpClient.listTools();
console.log('Available MCP tools:', tools);
console.log('Announcing service to Nostr network...');
await this.nostrAnnouncer.announceService();
console.log('Setting up request handlers...');
this.relayHandler.subscribeToRequests(this.handleRequest.bind(this));
this.isRunning = true;
console.log('DVM Bridge is now running and ready to handle requests');
} catch (error) {
console.error('Failed to start DVM Bridge:', error);
throw error;
}
}
async stop() {
if (!this.isRunning) {
return;
}
console.log('Stopping DVM Bridge...');
try {
await this.mcpClient.disconnect();
this.relayHandler.cleanup();
this.isRunning = false;
console.log('DVM Bridge stopped successfully');
} catch (error) {
console.error('Error stopping DVM Bridge:', error);
throw error;
}
}
private async handleRequest(event: Event) {
@@ -100,9 +136,32 @@ export class DVMBridge {
console.error('Error handling request:', error);
}
}
}
async stop() {
await this.mcpClient.disconnect();
this.relayHandler.cleanup();
if (import.meta.main) {
console.log('Starting DVM-MCP Bridge service...');
const bridge = new DVMBridge();
const shutdown = async () => {
console.log('Shutting down...');
try {
await bridge.stop();
process.exit(0);
} catch (error) {
console.error('Error during shutdown:', error);
process.exit(1);
}
};
// Handle termination signals
process.on('SIGINT', shutdown);
process.on('SIGTERM', shutdown);
// Start the bridge
try {
await bridge.start();
} catch (error) {
console.error('Failed to start service:', error);
process.exit(1);
}
}