#!/usr/bin/env node
/**
* AgentBTC MCP Connection Tester
* Tests Lightning node connectivity and AgentBTC API
*/
import { readFileSync, existsSync } from 'fs';
import https from 'https';
import http from 'http';
function makeRequest(url, headers = {}) {
return new Promise((resolve, reject) => {
const mod = url.startsWith('https') ? https : http;
const req = mod.get(url, { headers, rejectUnauthorized: false, timeout: 10000 }, (res) => {
let data = '';
res.on('data', chunk => data += chunk);
res.on('end', () => {
try { resolve({ status: res.statusCode, data: JSON.parse(data) }); }
catch { resolve({ status: res.statusCode, data }); }
});
});
req.on('error', reject);
req.on('timeout', () => { req.destroy(); reject(new Error('Request timed out')); });
});
}
async function main() {
console.log('π AgentBTC MCP Connection Test\n');
const lndHost = process.env.AGENTBTC_LND_HOST;
const lndMacaroon = process.env.AGENTBTC_LND_MACAROON;
const apiUrl = process.env.AGENTBTC_API_URL || 'http://localhost:8000';
const apiKey = process.env.AGENTBTC_API_KEY;
let passed = 0;
let failed = 0;
// Test 1: LND connection
console.log('1οΈβ£ Lightning Node');
if (!lndHost) {
console.log(' βοΈ Skipped β AGENTBTC_LND_HOST not set\n');
} else {
// Read macaroon
let macaroonHex = '';
if (lndMacaroon) {
if (existsSync(lndMacaroon)) {
macaroonHex = readFileSync(lndMacaroon).toString('hex');
console.log(` π Macaroon: ${lndMacaroon} β`);
} else {
// Treat as hex string
macaroonHex = lndMacaroon;
console.log(` π Macaroon: inline hex (${macaroonHex.length} chars)`);
}
}
try {
const proto = lndHost.includes('443') || lndHost.includes('voltageapp') ? 'https' : 'https';
const url = `${proto}://${lndHost}/v1/getinfo`;
const res = await makeRequest(url, { 'Grpc-Metadata-macaroon': macaroonHex });
if (res.status === 200 && res.data.alias) {
console.log(` β
Connected β alias: ${res.data.alias}, chains: ${res.data.chains?.length || '?'}`);
console.log(` β‘ Channels: ${res.data.num_active_channels || 0} active, ${res.data.num_peers || 0} peers`);
passed++;
} else {
console.log(` β Unexpected response (HTTP ${res.status})`);
failed++;
}
} catch (e) {
console.log(` β Failed: ${e.message}`);
failed++;
}
console.log('');
}
// Test 2: AgentBTC API
console.log('2οΈβ£ AgentBTC API');
try {
const headers = {};
if (apiKey) headers['X-API-Key'] = apiKey;
const res = await makeRequest(`${apiUrl}/api/v1/node/info`, headers);
if (res.status === 200) {
console.log(` β
Connected β ${apiUrl}`);
if (res.data?.alias) console.log(` β‘ Node: ${res.data.alias}`);
passed++;
} else {
console.log(` β οΈ HTTP ${res.status} β server reachable but returned error`);
failed++;
}
} catch (e) {
console.log(` β Failed: ${e.message}`);
console.log(` π‘ Is the AgentBTC server running at ${apiUrl}?`);
failed++;
}
console.log('');
// Test 3: API auth (if key provided)
if (apiKey) {
console.log('3οΈβ£ API Authentication');
try {
const res = await makeRequest(`${apiUrl}/api/v1/me`, { 'X-API-Key': apiKey });
if (res.status === 200) {
const who = res.data?.name || res.data?.owner_id || 'authenticated';
console.log(` β
Authenticated as: ${who}`);
if (res.data?.namespace) console.log(` π·οΈ Namespace: ${res.data.namespace}`);
passed++;
} else {
console.log(` β Auth failed (HTTP ${res.status})`);
failed++;
}
} catch (e) {
console.log(` β Failed: ${e.message}`);
failed++;
}
console.log('');
}
// Summary
console.log('β'.repeat(40));
if (failed === 0 && passed > 0) {
console.log(`β
All ${passed} tests passed β ready to go!`);
} else if (failed > 0) {
console.log(`β οΈ ${passed} passed, ${failed} failed`);
} else {
console.log('βοΈ No tests ran β set environment variables first');
console.log(' AGENTBTC_LND_HOST, AGENTBTC_LND_MACAROON');
}
}
main().catch(console.error);