-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathconfig.js
More file actions
176 lines (161 loc) · 6.59 KB
/
Copy pathconfig.js
File metadata and controls
176 lines (161 loc) · 6.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
const { access, constants, readFile } = require('fs/promises');
const path = require('path');
const axios = require('axios');
const { makeRpcCallBTC } = require('./utils/bitcoin-rpc');
const { execThunderCli } = require('./utils/thunder-cli');
const { execBitnamesCli } = require('./utils/bitnames-cli');
// Default configuration values
const defaultConfig = {
bitcoin: {
url: 'http://127.0.0.1:38332',
user: 'user',
password: 'password'
},
thunder: {
cliPath: '~/Downloads/thunder-cli',
rpcUrl: 'http://127.0.0.1:6009' // Add default Thunder RPC address
},
bitnames: {
cliPath: '~/Downloads/bitnames-cli',
// TODO: the URL format is not yet supported by the BitNames CLI,
// update this at a later point
rpcUrl: 'http://127.0.0.1:6002' // Default BitNames RPC address
}
};
// Verify executable exists and is executable
async function verifyExecutable(filePath, name) {
// Expand ~ to home directory if present
const expandedPath = filePath.replace(/^~/, process.env.HOME);
const resolvedPath = path.resolve(expandedPath);
try {
await access(resolvedPath, constants.X_OK);
return true;
} catch (error) {
if (error.code === 'ENOENT') {
throw new Error(`${name} CLI not found at path: ${resolvedPath}`);
} else if (error.code === 'EACCES') {
throw new Error(`${name} CLI at ${resolvedPath} is not executable. Please check permissions.`);
}
throw new Error(`Error checking ${name} CLI at ${resolvedPath}: ${error.message}`);
}
}
// Read Bitcoin Core cookie file and return { user, password }
async function readCookieFile(cookieFile) {
const expandedPath = cookieFile.replace(/^~/, process.env.HOME);
const resolvedPath = path.resolve(expandedPath);
try {
const contents = (await readFile(resolvedPath, 'utf-8')).trim();
const separatorIndex = contents.indexOf(':');
if (separatorIndex === -1) {
throw new Error(`Invalid cookie file format in ${resolvedPath}: expected "user:password"`);
}
return {
user: contents.substring(0, separatorIndex),
password: contents.substring(separatorIndex + 1)
};
} catch (error) {
if (error.code === 'ENOENT') {
throw new Error(`Bitcoin Core cookie file not found at ${resolvedPath}. Is Bitcoin Core running?`);
}
if (error.code === 'EACCES') {
throw new Error(`Permission denied reading cookie file at ${resolvedPath}.`);
}
throw error;
}
}
// Verify Bitcoin Core RPC connection
async function verifyBitcoinRpc(config) {
try {
await makeRpcCallBTC(config, 'getbalance');
return true;
} catch (error) {
if (error.code === 'ECONNREFUSED') {
throw new Error(`Could not connect to Bitcoin Core at ${config.bitcoin.host}:${config.bitcoin.port}`);
} else if (error.response && error.response.status === 401) {
const hint = config.bitcoin.cookieFile
? 'Check your cookie file path.'
: 'Check your username and password.';
throw new Error(`Bitcoin Core RPC authentication failed. ${hint}`);
}
throw new Error(`Bitcoin Core RPC verification failed: ${error.message}`);
}
}
// Verify Thunder node connection
async function verifyThunderConnection(config) {
try {
console.log('Verifying Thunder node connection...');
await execThunderCli(config, 'balance');
return true;
} catch (error) {
if (error.code === 'ECONNREFUSED') {
throw new Error(`Could not connect to Thunder node at ${config.thunder.rpcAddr}`);
}
throw new Error(`Thunder node verification failed: ${error.message}`);
}
}
// Add BitNames verification function
async function verifyBitNamesConnection(config) {
try {
console.log('Verifying BitNames node connection...');
await execBitnamesCli(config, 'balance');
return true;
} catch (error) {
if (error.code === 'ECONNREFUSED') {
throw new Error(`Could not connect to BitNames node at ${config.bitnames.rpcAddr}`);
}
throw new Error(`BitNames node verification failed: ${error.message}`);
}
}
// Verify all CLI tools are available
async function verifyConfig(config) {
try {
// If cookie file is configured, read credentials from it
if (config.bitcoin.cookieFile) {
console.log('Reading Bitcoin Core cookie file...');
const cookie = await readCookieFile(config.bitcoin.cookieFile);
config.bitcoin.user = cookie.user;
config.bitcoin.password = cookie.password;
console.log('Cookie file read successfully');
}
// First verify Bitcoin Core connection
console.log('Verifying Bitcoin Core RPC connection...');
await verifyBitcoinRpc(config);
console.log('Bitcoin Core RPC connection verified successfully');
// Then verify Thunder node connection
await verifyThunderConnection(config);
console.log('Thunder node connection verified successfully');
// Then verify BitNames node connection
await verifyBitNamesConnection(config);
console.log('BitNames node connection verified successfully');
// Then verify CLI tools
console.log('Verifying CLI tools...');
const verifications = [
verifyExecutable(config.thunder.cliPath, 'Thunder'),
verifyExecutable(config.bitnames.cliPath, 'BitNames')
];
await Promise.all(verifications);
console.log('All CLI tools verified successfully');
} catch (error) {
console.error('Configuration Error:', error.message);
process.exit(1);
}
}
// Environment variable based configuration
const config = {
bitcoin: {
url: process.env.BITCOIN_RPC_URL || defaultConfig.bitcoin.url,
user: process.env.BITCOIN_RPC_USER || defaultConfig.bitcoin.user,
password: process.env.BITCOIN_RPC_PASS || defaultConfig.bitcoin.password,
cookieFile: process.env.BITCOIN_RPC_COOKIE_FILE || null
},
thunder: {
cliPath: process.env.THUNDER_CLI_PATH || defaultConfig.thunder.cliPath,
rpcUrl: process.env.THUNDER_RPC_URL || defaultConfig.thunder.rpcUrl
},
bitnames: {
cliPath: process.env.BITNAMES_CLI_PATH || defaultConfig.bitnames.cliPath,
rpcUrl: process.env.BITNAMES_RPC_URL || defaultConfig.bitnames.rpcUrl
}
};
// Export both config and verification function
module.exports = { config, verifyConfig };