@ktmcp-cli/nowpayments 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENT.md +20 -493
- package/README.md +37 -347
- package/bin/nowpayments.js +6 -85
- package/package.json +22 -21
- package/src/api.js +94 -0
- package/src/config.js +34 -0
- package/src/index.js +306 -0
- package/.env.example +0 -17
- package/INSTALL.md +0 -392
- package/OPENCLAW.md +0 -628
- package/PROJECT_SUMMARY.md +0 -305
- package/banner.png +0 -0
- package/examples/basic-payment.js +0 -66
- package/examples/invoice-flow.js +0 -78
- package/examples/monitor-payment.js +0 -94
- package/logo.png +0 -0
- package/openapi.json +0 -2791
- package/src/commands/auth.js +0 -65
- package/src/commands/currencies.js +0 -95
- package/src/commands/estimate.js +0 -85
- package/src/commands/invoice.js +0 -188
- package/src/commands/payment.js +0 -241
- package/src/commands/payout.js +0 -184
- package/src/commands/status.js +0 -28
- package/src/lib/api.js +0 -133
- package/src/lib/auth.js +0 -70
- package/src/lib/config.js +0 -110
- package/test.sh +0 -250
package/src/commands/payout.js
DELETED
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Payout command
|
|
3
|
-
*
|
|
4
|
-
* Create and manage cryptocurrency payouts/withdrawals.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
const { Command } = require('commander');
|
|
8
|
-
const chalk = require('chalk');
|
|
9
|
-
const Table = require('cli-table3');
|
|
10
|
-
const { makeRequest, handleApiError, displayResponse } = require('../lib/api');
|
|
11
|
-
|
|
12
|
-
const command = new Command('payout');
|
|
13
|
-
|
|
14
|
-
command
|
|
15
|
-
.description('Manage payouts and withdrawals')
|
|
16
|
-
.summary('Create and query payout transactions');
|
|
17
|
-
|
|
18
|
-
// Create a new payout
|
|
19
|
-
command
|
|
20
|
-
.command('create')
|
|
21
|
-
.description('Create a new payout/withdrawal')
|
|
22
|
-
.requiredOption('-a, --amount <amount>', 'Payout amount')
|
|
23
|
-
.requiredOption('-c, --currency <currency>', 'Cryptocurrency (e.g., BTC)')
|
|
24
|
-
.requiredOption('--address <address>', 'Destination wallet address')
|
|
25
|
-
.option('--ipn-url <url>', 'IPN callback URL')
|
|
26
|
-
.option('--extra-id <id>', 'Extra ID for currencies that require it (e.g., XRP destination tag)')
|
|
27
|
-
.action(async (options) => {
|
|
28
|
-
try {
|
|
29
|
-
const amount = parseFloat(options.amount);
|
|
30
|
-
|
|
31
|
-
if (isNaN(amount) || amount <= 0) {
|
|
32
|
-
console.error(chalk.red('Error: Amount must be a positive number'));
|
|
33
|
-
process.exit(1);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const payoutData = {
|
|
37
|
-
withdrawals: [{
|
|
38
|
-
address: options.address,
|
|
39
|
-
currency: options.currency.toUpperCase(),
|
|
40
|
-
amount: amount,
|
|
41
|
-
ipn_callback_url: options.ipnUrl,
|
|
42
|
-
extra_id: options.extraId
|
|
43
|
-
}]
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
const data = await makeRequest(command.parent.parent, '/payout', {
|
|
47
|
-
method: 'POST',
|
|
48
|
-
body: payoutData
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
displayResponse(command.parent.parent, data, (response) => {
|
|
52
|
-
console.log(chalk.green('\n✓ Payout created successfully'));
|
|
53
|
-
console.log(chalk.cyan('\nPayout Details:'));
|
|
54
|
-
|
|
55
|
-
if (response.withdrawals && response.withdrawals.length > 0) {
|
|
56
|
-
const payout = response.withdrawals[0];
|
|
57
|
-
console.log(chalk.bold(' Payout ID:'), payout.id);
|
|
58
|
-
console.log(chalk.bold(' Status:'), payout.status);
|
|
59
|
-
console.log(chalk.bold(' Amount:'), `${payout.amount} ${payout.currency}`);
|
|
60
|
-
console.log(chalk.bold(' Address:'), payout.address);
|
|
61
|
-
|
|
62
|
-
if (payout.extra_id) {
|
|
63
|
-
console.log(chalk.bold(' Extra ID:'), payout.extra_id);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
console.log(chalk.yellow('\n⚠ Note: Some payouts may require 2FA verification'));
|
|
68
|
-
});
|
|
69
|
-
} catch (error) {
|
|
70
|
-
handleApiError(error);
|
|
71
|
-
}
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
// Verify payout (2FA)
|
|
75
|
-
command
|
|
76
|
-
.command('verify <payout-id> <verification-code>')
|
|
77
|
-
.description('Verify a payout with 2FA code')
|
|
78
|
-
.action(async (payoutId, code) => {
|
|
79
|
-
try {
|
|
80
|
-
const data = await makeRequest(command.parent.parent, `/payout/${payoutId}/verify`, {
|
|
81
|
-
method: 'POST',
|
|
82
|
-
body: { verification_code: code }
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
displayResponse(command.parent.parent, data, (response) => {
|
|
86
|
-
console.log(chalk.green('\n✓ Payout verified successfully'));
|
|
87
|
-
console.log(chalk.cyan('\nStatus:'), response.status || 'Verified');
|
|
88
|
-
});
|
|
89
|
-
} catch (error) {
|
|
90
|
-
handleApiError(error);
|
|
91
|
-
}
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
// Get payout details
|
|
95
|
-
command
|
|
96
|
-
.command('get <payout-id>')
|
|
97
|
-
.description('Get payout details by ID')
|
|
98
|
-
.action(async (payoutId) => {
|
|
99
|
-
try {
|
|
100
|
-
const data = await makeRequest(command.parent.parent, `/payout/${payoutId}`);
|
|
101
|
-
|
|
102
|
-
displayResponse(command.parent.parent, data, (response) => {
|
|
103
|
-
console.log(chalk.cyan('\nPayout Details:'));
|
|
104
|
-
|
|
105
|
-
const table = new Table({
|
|
106
|
-
chars: { 'mid': '', 'left-mid': '', 'mid-mid': '', 'right-mid': '' }
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
table.push(
|
|
110
|
-
['Payout ID', response.id],
|
|
111
|
-
['Status', response.status],
|
|
112
|
-
['Amount', `${response.amount} ${response.currency}`],
|
|
113
|
-
['Address', response.address]
|
|
114
|
-
);
|
|
115
|
-
|
|
116
|
-
if (response.extra_id) {
|
|
117
|
-
table.push(['Extra ID', response.extra_id]);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
if (response.hash) {
|
|
121
|
-
table.push(['Transaction Hash', response.hash]);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
table.push(
|
|
125
|
-
['Created', new Date(response.created_at).toLocaleString()]
|
|
126
|
-
);
|
|
127
|
-
|
|
128
|
-
console.log(table.toString());
|
|
129
|
-
});
|
|
130
|
-
} catch (error) {
|
|
131
|
-
handleApiError(error);
|
|
132
|
-
}
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
// List payouts
|
|
136
|
-
command
|
|
137
|
-
.command('list')
|
|
138
|
-
.description('List all payouts')
|
|
139
|
-
.option('-l, --limit <number>', 'Number of payouts to return', '10')
|
|
140
|
-
.option('-p, --page <number>', 'Page number', '0')
|
|
141
|
-
.action(async (options) => {
|
|
142
|
-
try {
|
|
143
|
-
const queryParams = {
|
|
144
|
-
limit: parseInt(options.limit),
|
|
145
|
-
page: parseInt(options.page)
|
|
146
|
-
};
|
|
147
|
-
|
|
148
|
-
const data = await makeRequest(command.parent.parent, '/payout', {
|
|
149
|
-
queryParams
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
displayResponse(command.parent.parent, data, (response) => {
|
|
153
|
-
const payouts = response.data || [];
|
|
154
|
-
|
|
155
|
-
if (payouts.length === 0) {
|
|
156
|
-
console.log(chalk.yellow('\nNo payouts found'));
|
|
157
|
-
return;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
console.log(chalk.cyan(`\nPayouts (${payouts.length}):`));
|
|
161
|
-
|
|
162
|
-
const table = new Table({
|
|
163
|
-
head: ['ID', 'Status', 'Amount', 'Currency', 'Created'],
|
|
164
|
-
colWidths: [20, 15, 15, 10, 25]
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
payouts.forEach(payout => {
|
|
168
|
-
table.push([
|
|
169
|
-
payout.id?.toString().substring(0, 18) || 'N/A',
|
|
170
|
-
payout.status || 'N/A',
|
|
171
|
-
payout.amount || 'N/A',
|
|
172
|
-
payout.currency || 'N/A',
|
|
173
|
-
new Date(payout.created_at).toLocaleString()
|
|
174
|
-
]);
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
console.log(table.toString());
|
|
178
|
-
});
|
|
179
|
-
} catch (error) {
|
|
180
|
-
handleApiError(error);
|
|
181
|
-
}
|
|
182
|
-
});
|
|
183
|
-
|
|
184
|
-
module.exports = command;
|
package/src/commands/status.js
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Status command
|
|
3
|
-
*
|
|
4
|
-
* Check API status and availability.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
const { Command } = require('commander');
|
|
8
|
-
const chalk = require('chalk');
|
|
9
|
-
const { makeRequest, handleApiError, displayResponse } = require('../lib/api');
|
|
10
|
-
|
|
11
|
-
const command = new Command('status');
|
|
12
|
-
|
|
13
|
-
command
|
|
14
|
-
.description('Check NOWPayments API status')
|
|
15
|
-
.summary('Verify API connectivity and status')
|
|
16
|
-
.action(async () => {
|
|
17
|
-
try {
|
|
18
|
-
const data = await makeRequest(command.parent, '/status');
|
|
19
|
-
|
|
20
|
-
displayResponse(command.parent, data, (response) => {
|
|
21
|
-
console.log(chalk.green('✓ NOWPayments API is'), chalk.bold(response.message || 'OK'));
|
|
22
|
-
});
|
|
23
|
-
} catch (error) {
|
|
24
|
-
handleApiError(error);
|
|
25
|
-
}
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
module.exports = command;
|
package/src/lib/api.js
DELETED
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* API client for NOWPayments
|
|
3
|
-
*
|
|
4
|
-
* Handles all HTTP requests to the NOWPayments API with proper error handling,
|
|
5
|
-
* authentication, and response formatting.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
const fetch = require('node-fetch');
|
|
9
|
-
const chalk = require('chalk');
|
|
10
|
-
const { getBaseUrl } = require('./config');
|
|
11
|
-
const { getAuthHeaders } = require('./auth');
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Make an API request to NOWPayments
|
|
15
|
-
* @param {Object} program - Commander program instance
|
|
16
|
-
* @param {string} endpoint - API endpoint (e.g., '/status')
|
|
17
|
-
* @param {Object} options - Request options
|
|
18
|
-
* @param {string} options.method - HTTP method (GET, POST, etc.)
|
|
19
|
-
* @param {Object} options.body - Request body for POST/PUT requests
|
|
20
|
-
* @param {Object} options.queryParams - URL query parameters
|
|
21
|
-
* @returns {Promise<Object>} API response data
|
|
22
|
-
*/
|
|
23
|
-
async function makeRequest(program, endpoint, options = {}) {
|
|
24
|
-
const { method = 'GET', body = null, queryParams = {} } = options;
|
|
25
|
-
|
|
26
|
-
// Build URL
|
|
27
|
-
const baseUrl = getBaseUrl(program._sandbox);
|
|
28
|
-
const url = new URL(`${baseUrl}${endpoint}`);
|
|
29
|
-
|
|
30
|
-
// Add query parameters
|
|
31
|
-
Object.keys(queryParams).forEach(key => {
|
|
32
|
-
if (queryParams[key] !== undefined && queryParams[key] !== null) {
|
|
33
|
-
url.searchParams.append(key, queryParams[key]);
|
|
34
|
-
}
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
// Build request options
|
|
38
|
-
const requestOptions = {
|
|
39
|
-
method,
|
|
40
|
-
headers: getAuthHeaders(program)
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
// Add body for POST/PUT requests
|
|
44
|
-
if (body && (method === 'POST' || method === 'PUT' || method === 'PATCH')) {
|
|
45
|
-
requestOptions.body = JSON.stringify(body);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
if (program._debug) {
|
|
49
|
-
console.log(chalk.gray(`[DEBUG] ${method} ${url.toString()}`));
|
|
50
|
-
if (body) {
|
|
51
|
-
console.log(chalk.gray(`[DEBUG] Body: ${JSON.stringify(body, null, 2)}`));
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
try {
|
|
56
|
-
const response = await fetch(url.toString(), requestOptions);
|
|
57
|
-
const data = await response.json();
|
|
58
|
-
|
|
59
|
-
if (program._debug) {
|
|
60
|
-
console.log(chalk.gray(`[DEBUG] Status: ${response.status}`));
|
|
61
|
-
console.log(chalk.gray(`[DEBUG] Response: ${JSON.stringify(data, null, 2)}`));
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// Handle error responses
|
|
65
|
-
if (!response.ok) {
|
|
66
|
-
const error = new Error(data.message || `API request failed with status ${response.status}`);
|
|
67
|
-
error.statusCode = response.status;
|
|
68
|
-
error.data = data;
|
|
69
|
-
throw error;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
return data;
|
|
73
|
-
} catch (error) {
|
|
74
|
-
if (error.statusCode) {
|
|
75
|
-
// API error
|
|
76
|
-
throw error;
|
|
77
|
-
} else if (error.code === 'ENOTFOUND' || error.code === 'ECONNREFUSED') {
|
|
78
|
-
// Network error
|
|
79
|
-
const networkError = new Error('Network error: Unable to reach NOWPayments API');
|
|
80
|
-
networkError.originalError = error;
|
|
81
|
-
throw networkError;
|
|
82
|
-
} else {
|
|
83
|
-
// Other error (parsing, etc.)
|
|
84
|
-
throw error;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Handle and format API errors for display
|
|
91
|
-
* @param {Error} error - Error object
|
|
92
|
-
*/
|
|
93
|
-
function handleApiError(error) {
|
|
94
|
-
if (error.statusCode) {
|
|
95
|
-
console.error(chalk.red(`\nAPI Error (${error.statusCode}):`));
|
|
96
|
-
console.error(chalk.yellow(error.message));
|
|
97
|
-
|
|
98
|
-
if (error.data && error.data.errors) {
|
|
99
|
-
console.error(chalk.yellow('\nDetails:'));
|
|
100
|
-
console.error(JSON.stringify(error.data.errors, null, 2));
|
|
101
|
-
}
|
|
102
|
-
} else if (error.originalError) {
|
|
103
|
-
console.error(chalk.red('\nNetwork Error:'));
|
|
104
|
-
console.error(chalk.yellow(error.message));
|
|
105
|
-
} else {
|
|
106
|
-
console.error(chalk.red('\nUnexpected Error:'));
|
|
107
|
-
console.error(chalk.yellow(error.message));
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
process.exit(1);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* Format and display API response
|
|
115
|
-
* @param {Object} program - Commander program instance
|
|
116
|
-
* @param {Object} data - Response data
|
|
117
|
-
* @param {Function} formatter - Optional custom formatter function
|
|
118
|
-
*/
|
|
119
|
-
function displayResponse(program, data, formatter = null) {
|
|
120
|
-
if (program._json) {
|
|
121
|
-
console.log(JSON.stringify(data, null, 2));
|
|
122
|
-
} else if (formatter) {
|
|
123
|
-
formatter(data);
|
|
124
|
-
} else {
|
|
125
|
-
console.log(JSON.stringify(data, null, 2));
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
module.exports = {
|
|
130
|
-
makeRequest,
|
|
131
|
-
handleApiError,
|
|
132
|
-
displayResponse
|
|
133
|
-
};
|
package/src/lib/auth.js
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Authentication utilities for NOWPayments CLI
|
|
3
|
-
*
|
|
4
|
-
* Handles API key validation and authentication headers.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
const chalk = require('chalk');
|
|
8
|
-
const { getApiKey } = require('./config');
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Validate that an API key is available
|
|
12
|
-
* @param {Object} program - Commander program instance
|
|
13
|
-
* @throws {Error} If no API key is found
|
|
14
|
-
*/
|
|
15
|
-
function requireApiKey(program) {
|
|
16
|
-
const apiKey = getApiKey(program);
|
|
17
|
-
|
|
18
|
-
if (!apiKey) {
|
|
19
|
-
console.error(chalk.red('Error: No API key found'));
|
|
20
|
-
console.error(chalk.yellow('\nPlease set your API key using one of these methods:'));
|
|
21
|
-
console.error(' 1. Environment variable: export NOWPAYMENTS_API_KEY=your_key');
|
|
22
|
-
console.error(' 2. .env file: NOWPAYMENTS_API_KEY=your_key');
|
|
23
|
-
console.error(' 3. Command flag: --api-key your_key');
|
|
24
|
-
console.error(' 4. Save to config: nowpayments auth set your_key');
|
|
25
|
-
console.error(chalk.cyan('\nGet your API key at: https://nowpayments.io'));
|
|
26
|
-
process.exit(1);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
return apiKey;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Get authentication headers for API requests
|
|
34
|
-
* @param {Object} program - Commander program instance
|
|
35
|
-
* @returns {Object} Headers object with authentication
|
|
36
|
-
*/
|
|
37
|
-
function getAuthHeaders(program) {
|
|
38
|
-
const apiKey = requireApiKey(program);
|
|
39
|
-
|
|
40
|
-
return {
|
|
41
|
-
'x-api-key': apiKey,
|
|
42
|
-
'Content-Type': 'application/json'
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Validate API key format (basic check)
|
|
48
|
-
* @param {string} apiKey - API key to validate
|
|
49
|
-
* @returns {boolean} Whether the key appears valid
|
|
50
|
-
*/
|
|
51
|
-
function validateApiKeyFormat(apiKey) {
|
|
52
|
-
// Basic validation - NOWPayments API keys are typically alphanumeric
|
|
53
|
-
if (!apiKey || typeof apiKey !== 'string') {
|
|
54
|
-
return false;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// Check length (typical API keys are 32-64 characters)
|
|
58
|
-
if (apiKey.length < 20 || apiKey.length > 100) {
|
|
59
|
-
return false;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// Check for valid characters (alphanumeric and common symbols)
|
|
63
|
-
return /^[a-zA-Z0-9_-]+$/.test(apiKey);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
module.exports = {
|
|
67
|
-
requireApiKey,
|
|
68
|
-
getAuthHeaders,
|
|
69
|
-
validateApiKeyFormat
|
|
70
|
-
};
|
package/src/lib/config.js
DELETED
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Configuration management for NOWPayments CLI
|
|
3
|
-
*
|
|
4
|
-
* Handles API keys, environment selection, and persistent configuration.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
const fs = require('fs');
|
|
8
|
-
const path = require('path');
|
|
9
|
-
const os = require('os');
|
|
10
|
-
|
|
11
|
-
const CONFIG_DIR = path.join(os.homedir(), '.nowpayments');
|
|
12
|
-
const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Default configuration
|
|
16
|
-
*/
|
|
17
|
-
const DEFAULT_CONFIG = {
|
|
18
|
-
apiKey: null,
|
|
19
|
-
sandbox: false,
|
|
20
|
-
defaultCurrency: 'USD',
|
|
21
|
-
defaultPayCurrency: 'BTC'
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Ensure config directory exists
|
|
26
|
-
*/
|
|
27
|
-
function ensureConfigDir() {
|
|
28
|
-
if (!fs.existsSync(CONFIG_DIR)) {
|
|
29
|
-
fs.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Load configuration from file
|
|
35
|
-
* @returns {Object} Configuration object
|
|
36
|
-
*/
|
|
37
|
-
function loadConfig() {
|
|
38
|
-
try {
|
|
39
|
-
ensureConfigDir();
|
|
40
|
-
if (fs.existsSync(CONFIG_FILE)) {
|
|
41
|
-
const data = fs.readFileSync(CONFIG_FILE, 'utf8');
|
|
42
|
-
return { ...DEFAULT_CONFIG, ...JSON.parse(data) };
|
|
43
|
-
}
|
|
44
|
-
} catch (error) {
|
|
45
|
-
// Return defaults if config file doesn't exist or is invalid
|
|
46
|
-
}
|
|
47
|
-
return { ...DEFAULT_CONFIG };
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Save configuration to file
|
|
52
|
-
* @param {Object} config - Configuration to save
|
|
53
|
-
*/
|
|
54
|
-
function saveConfig(config) {
|
|
55
|
-
ensureConfigDir();
|
|
56
|
-
fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2), 'utf8');
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Get a configuration value
|
|
61
|
-
* @param {string} key - Configuration key
|
|
62
|
-
* @returns {*} Configuration value
|
|
63
|
-
*/
|
|
64
|
-
function getConfig(key) {
|
|
65
|
-
const config = loadConfig();
|
|
66
|
-
return config[key];
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Set a configuration value
|
|
71
|
-
* @param {string} key - Configuration key
|
|
72
|
-
* @param {*} value - Configuration value
|
|
73
|
-
*/
|
|
74
|
-
function setConfig(key, value) {
|
|
75
|
-
const config = loadConfig();
|
|
76
|
-
config[key] = value;
|
|
77
|
-
saveConfig(config);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Get API key from config, environment, or command option
|
|
82
|
-
* @param {Object} program - Commander program instance
|
|
83
|
-
* @returns {string|null} API key
|
|
84
|
-
*/
|
|
85
|
-
function getApiKey(program) {
|
|
86
|
-
// Priority: command option > environment > config file
|
|
87
|
-
return program._apiKey || process.env.NOWPAYMENTS_API_KEY || getConfig('apiKey');
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Get base URL based on environment
|
|
92
|
-
* @param {boolean} sandbox - Whether to use sandbox environment
|
|
93
|
-
* @returns {string} Base URL
|
|
94
|
-
*/
|
|
95
|
-
function getBaseUrl(sandbox = false) {
|
|
96
|
-
return sandbox
|
|
97
|
-
? 'https://api-sandbox.nowpayments.io/v1'
|
|
98
|
-
: 'https://api.nowpayments.io/v1';
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
module.exports = {
|
|
102
|
-
CONFIG_DIR,
|
|
103
|
-
CONFIG_FILE,
|
|
104
|
-
loadConfig,
|
|
105
|
-
saveConfig,
|
|
106
|
-
getConfig,
|
|
107
|
-
setConfig,
|
|
108
|
-
getApiKey,
|
|
109
|
-
getBaseUrl
|
|
110
|
-
};
|