@ktmcp-cli/nowpayments 1.0.1 → 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/LICENSE +1 -1
- package/README.md +37 -346
- package/bin/nowpayments.js +6 -88
- 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/banner.svg +0 -25
- 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/src/lib/welcome.js +0 -47
- package/test.sh +0 -250
package/AGENT.md
CHANGED
|
@@ -1,513 +1,40 @@
|
|
|
1
|
-
# NOWPayments CLI
|
|
1
|
+
# AGENT.md — NOWPayments CLI for AI Agents
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## Overview
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
The `nowpaymentsio` CLI provides cryptocurrency payment processing.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
2. **Clear Exit Codes**: Success (0) and failure (1) for easy status checking
|
|
9
|
-
3. **Composable Commands**: Unix philosophy - do one thing well
|
|
10
|
-
4. **Self-Documenting**: Built-in help text for all commands
|
|
11
|
-
5. **Error Messages**: Structured, informative error responses
|
|
12
|
-
|
|
13
|
-
## Agent Integration Patterns
|
|
14
|
-
|
|
15
|
-
### Pattern 1: Status Checking
|
|
16
|
-
|
|
17
|
-
Before executing operations, verify API connectivity:
|
|
18
|
-
|
|
19
|
-
```bash
|
|
20
|
-
nowpayments status
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
**Agent Decision Tree:**
|
|
24
|
-
- Success → Proceed with operations
|
|
25
|
-
- Failure → Inform user of connectivity issues
|
|
26
|
-
|
|
27
|
-
### Pattern 2: Currency Validation
|
|
28
|
-
|
|
29
|
-
Before creating payments, validate cryptocurrency support:
|
|
30
|
-
|
|
31
|
-
```bash
|
|
32
|
-
# Check if BTC is supported
|
|
33
|
-
nowpayments currencies info BTC
|
|
34
|
-
|
|
35
|
-
# Get all available currencies
|
|
36
|
-
nowpayments --json currencies list --available
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
**Agent Logic:**
|
|
40
|
-
```javascript
|
|
41
|
-
// Pseudo-code for agent
|
|
42
|
-
const result = await exec('nowpayments --json currencies list --available');
|
|
43
|
-
const data = JSON.parse(result.stdout);
|
|
44
|
-
const currencies = data.currencies || [];
|
|
45
|
-
|
|
46
|
-
if (!currencies.includes(requestedCurrency.toLowerCase())) {
|
|
47
|
-
return "Currency not supported. Available: " + currencies.join(', ');
|
|
48
|
-
}
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
### Pattern 3: Price Estimation
|
|
52
|
-
|
|
53
|
-
Always estimate before creating payments:
|
|
54
|
-
|
|
55
|
-
```bash
|
|
56
|
-
nowpayments --json estimate convert \
|
|
57
|
-
--from USD \
|
|
58
|
-
--to BTC \
|
|
59
|
-
--amount 100
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
**Agent Flow:**
|
|
63
|
-
1. Get user's desired amount and currencies
|
|
64
|
-
2. Call estimate to get conversion
|
|
65
|
-
3. Present estimate to user
|
|
66
|
-
4. Wait for confirmation before creating payment
|
|
67
|
-
|
|
68
|
-
### Pattern 4: Payment Creation
|
|
69
|
-
|
|
70
|
-
Create payments with all required parameters:
|
|
71
|
-
|
|
72
|
-
```bash
|
|
73
|
-
nowpayments --json payment create \
|
|
74
|
-
--price 99.99 \
|
|
75
|
-
--currency USD \
|
|
76
|
-
--pay-currency BTC \
|
|
77
|
-
--order-id "ORDER-${timestamp}" \
|
|
78
|
-
--order-description "User's description"
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
**Agent Best Practices:**
|
|
82
|
-
- Generate unique `order-id` (timestamp, UUID, etc.)
|
|
83
|
-
- Include descriptive `order-description`
|
|
84
|
-
- Store `payment_id` for tracking
|
|
85
|
-
- Present `pay_address` and `pay_amount` clearly to user
|
|
86
|
-
|
|
87
|
-
### Pattern 5: Payment Monitoring
|
|
88
|
-
|
|
89
|
-
Poll payment status at reasonable intervals:
|
|
90
|
-
|
|
91
|
-
```bash
|
|
92
|
-
nowpayments --json payment get <payment_id>
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
**Agent Polling Logic:**
|
|
96
|
-
```javascript
|
|
97
|
-
async function monitorPayment(paymentId, maxMinutes = 30) {
|
|
98
|
-
const startTime = Date.now();
|
|
99
|
-
const maxTime = maxMinutes * 60 * 1000;
|
|
100
|
-
|
|
101
|
-
while (Date.now() - startTime < maxTime) {
|
|
102
|
-
const result = await exec(`nowpayments --json payment get ${paymentId}`);
|
|
103
|
-
const payment = JSON.parse(result.stdout);
|
|
104
|
-
|
|
105
|
-
switch (payment.payment_status) {
|
|
106
|
-
case 'finished':
|
|
107
|
-
return { status: 'completed', payment };
|
|
108
|
-
case 'failed':
|
|
109
|
-
case 'expired':
|
|
110
|
-
return { status: 'failed', payment };
|
|
111
|
-
case 'partially_paid':
|
|
112
|
-
return { status: 'underpaid', payment };
|
|
113
|
-
default:
|
|
114
|
-
// Still processing, wait before next check
|
|
115
|
-
await sleep(30000); // 30 seconds
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
return { status: 'timeout' };
|
|
120
|
-
}
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
### Pattern 6: Error Handling
|
|
124
|
-
|
|
125
|
-
Parse errors and provide helpful responses:
|
|
7
|
+
## Setup
|
|
126
8
|
|
|
127
9
|
```bash
|
|
128
|
-
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
**Agent Error Response:**
|
|
132
|
-
```javascript
|
|
133
|
-
try {
|
|
134
|
-
const result = await exec('nowpayments --json payment get invalid_id');
|
|
135
|
-
const data = JSON.parse(result.stdout);
|
|
136
|
-
} catch (error) {
|
|
137
|
-
// Parse error output
|
|
138
|
-
const errorMsg = error.stderr || error.message;
|
|
139
|
-
|
|
140
|
-
if (errorMsg.includes('API Error (401)')) {
|
|
141
|
-
return "Authentication failed. Please check your API key.";
|
|
142
|
-
} else if (errorMsg.includes('API Error (404)')) {
|
|
143
|
-
return "Payment not found. Please verify the payment ID.";
|
|
144
|
-
} else if (errorMsg.includes('Network error')) {
|
|
145
|
-
return "Cannot reach NOWPayments API. Check internet connection.";
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
return "An error occurred: " + errorMsg;
|
|
149
|
-
}
|
|
10
|
+
nowpaymentsio config set --api-key <key>
|
|
150
11
|
```
|
|
151
12
|
|
|
152
|
-
##
|
|
153
|
-
|
|
154
|
-
### Workflow 1: Create Payment
|
|
13
|
+
## Commands
|
|
155
14
|
|
|
15
|
+
### Currencies
|
|
156
16
|
```bash
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
# Step 2: Get estimate
|
|
161
|
-
nowpayments --json estimate convert \
|
|
162
|
-
--from USD \
|
|
163
|
-
--to BTC \
|
|
164
|
-
--amount 100
|
|
165
|
-
|
|
166
|
-
# Step 3: Create payment
|
|
167
|
-
nowpayments --json payment create \
|
|
168
|
-
--price 100 \
|
|
169
|
-
--currency USD \
|
|
170
|
-
--pay-currency BTC \
|
|
171
|
-
--order-id "ORDER-123"
|
|
172
|
-
|
|
173
|
-
# Step 4: Monitor status
|
|
174
|
-
nowpayments --json payment get <payment_id>
|
|
17
|
+
nowpaymentsio currencies list --json
|
|
18
|
+
nowpaymentsio currencies estimate --amount 100 --from USD --to BTC --json
|
|
175
19
|
```
|
|
176
20
|
|
|
177
|
-
|
|
178
|
-
```
|
|
179
|
-
I'll help you create a Bitcoin payment for $100.
|
|
180
|
-
|
|
181
|
-
1. Validating BTC support... ✓
|
|
182
|
-
2. Getting current exchange rate...
|
|
183
|
-
- Rate: 0.00234 BTC = $100 USD
|
|
184
|
-
3. Creating payment...
|
|
185
|
-
- Payment ID: abc123
|
|
186
|
-
- Send exactly 0.00234 BTC to: bc1qxy2kg...
|
|
187
|
-
- Expires in: 1 hour
|
|
188
|
-
4. I'll monitor this payment for you.
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
### Workflow 2: List and Filter Payments
|
|
192
|
-
|
|
21
|
+
### Payments
|
|
193
22
|
```bash
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
# Filter by date range
|
|
198
|
-
nowpayments --json payment list \
|
|
199
|
-
--date-from 2024-01-01 \
|
|
200
|
-
--date-to 2024-01-31
|
|
201
|
-
|
|
202
|
-
# Find specific payment
|
|
203
|
-
nowpayments --json payment get abc123
|
|
23
|
+
nowpaymentsio payments list --json
|
|
24
|
+
nowpaymentsio payments get <id> --json
|
|
25
|
+
nowpaymentsio payments create --amount 100 --from USD --to BTC --json
|
|
204
26
|
```
|
|
205
27
|
|
|
206
|
-
|
|
207
|
-
```javascript
|
|
208
|
-
// Agent keeps track of recent payments
|
|
209
|
-
const recentPayments = await getRecentPayments();
|
|
210
|
-
|
|
211
|
-
// When user says "check my last payment"
|
|
212
|
-
const lastPayment = recentPayments[0];
|
|
213
|
-
const status = await exec(`nowpayments --json payment get ${lastPayment.id}`);
|
|
214
|
-
|
|
215
|
-
// Present status in natural language
|
|
216
|
-
```
|
|
217
|
-
|
|
218
|
-
### Workflow 3: Invoice Management
|
|
219
|
-
|
|
28
|
+
### Invoices
|
|
220
29
|
```bash
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
--price 49.99 \
|
|
224
|
-
--currency USD \
|
|
225
|
-
--order-id "INV-456" \
|
|
226
|
-
--success-url "https://example.com/success"
|
|
227
|
-
|
|
228
|
-
# Share invoice URL with user
|
|
229
|
-
# Returns: { "invoice_url": "https://nowpayments.io/payment/?iid=..." }
|
|
30
|
+
nowpaymentsio invoices list --json
|
|
31
|
+
nowpaymentsio invoices create --amount 50 --currency USD --json
|
|
230
32
|
```
|
|
231
33
|
|
|
232
|
-
|
|
233
|
-
```
|
|
234
|
-
I've created an invoice for $49.99:
|
|
235
|
-
|
|
236
|
-
Invoice ID: 1234567
|
|
237
|
-
Payment URL: https://nowpayments.io/payment/?iid=abc123
|
|
238
|
-
|
|
239
|
-
Share this link with your customer. They can pay with any supported cryptocurrency.
|
|
240
|
-
When payment is complete, they'll be redirected to your success page.
|
|
241
|
-
```
|
|
242
|
-
|
|
243
|
-
## Advanced Agent Techniques
|
|
244
|
-
|
|
245
|
-
### Technique 1: Batch Operations
|
|
246
|
-
|
|
247
|
-
Process multiple payments efficiently:
|
|
248
|
-
|
|
34
|
+
### Subscriptions
|
|
249
35
|
```bash
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
# Check each one
|
|
254
|
-
echo "$payments" | jq -r '.data[] | select(.payment_status == "waiting") | .payment_id' | \
|
|
255
|
-
while read payment_id; do
|
|
256
|
-
nowpayments --json payment get "$payment_id"
|
|
257
|
-
done
|
|
36
|
+
nowpaymentsio subscriptions plans --json
|
|
37
|
+
nowpaymentsio subscriptions list --json
|
|
258
38
|
```
|
|
259
39
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
Implement exponential backoff for API calls:
|
|
263
|
-
|
|
264
|
-
```javascript
|
|
265
|
-
async function withRetry(command, maxRetries = 3) {
|
|
266
|
-
for (let i = 0; i < maxRetries; i++) {
|
|
267
|
-
try {
|
|
268
|
-
return await exec(command);
|
|
269
|
-
} catch (error) {
|
|
270
|
-
if (i === maxRetries - 1) throw error;
|
|
271
|
-
|
|
272
|
-
const delay = Math.pow(2, i) * 1000; // Exponential backoff
|
|
273
|
-
await sleep(delay);
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
```
|
|
278
|
-
|
|
279
|
-
### Technique 3: Caching Currency Lists
|
|
280
|
-
|
|
281
|
-
Cache currency list to reduce API calls:
|
|
282
|
-
|
|
283
|
-
```javascript
|
|
284
|
-
let currencyCache = null;
|
|
285
|
-
let cacheTime = null;
|
|
286
|
-
const CACHE_TTL = 3600000; // 1 hour
|
|
287
|
-
|
|
288
|
-
async function getAvailableCurrencies() {
|
|
289
|
-
const now = Date.now();
|
|
290
|
-
|
|
291
|
-
if (currencyCache && (now - cacheTime) < CACHE_TTL) {
|
|
292
|
-
return currencyCache;
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
const result = await exec('nowpayments --json currencies list --available');
|
|
296
|
-
currencyCache = JSON.parse(result.stdout);
|
|
297
|
-
cacheTime = now;
|
|
298
|
-
|
|
299
|
-
return currencyCache;
|
|
300
|
-
}
|
|
301
|
-
```
|
|
302
|
-
|
|
303
|
-
### Technique 4: Context Preservation
|
|
304
|
-
|
|
305
|
-
Maintain payment context across conversation:
|
|
306
|
-
|
|
307
|
-
```javascript
|
|
308
|
-
// Agent maintains session state
|
|
309
|
-
const session = {
|
|
310
|
-
currentPayment: null,
|
|
311
|
-
recentPayments: [],
|
|
312
|
-
preferences: {
|
|
313
|
-
defaultCurrency: 'USD',
|
|
314
|
-
defaultPayCurrency: 'BTC'
|
|
315
|
-
}
|
|
316
|
-
};
|
|
317
|
-
|
|
318
|
-
// When user says "check the status"
|
|
319
|
-
if (session.currentPayment) {
|
|
320
|
-
const status = await checkPayment(session.currentPayment.id);
|
|
321
|
-
return formatStatus(status);
|
|
322
|
-
}
|
|
323
|
-
```
|
|
324
|
-
|
|
325
|
-
## Output Formatting for Users
|
|
326
|
-
|
|
327
|
-
### Format Payment Details
|
|
328
|
-
|
|
329
|
-
```javascript
|
|
330
|
-
function formatPayment(payment) {
|
|
331
|
-
return `
|
|
332
|
-
Payment Details:
|
|
333
|
-
- Status: ${payment.payment_status}
|
|
334
|
-
- Amount: ${payment.pay_amount} ${payment.pay_currency}
|
|
335
|
-
- Price: ${payment.price_amount} ${payment.price_currency}
|
|
336
|
-
- Address: ${payment.pay_address}
|
|
337
|
-
- Created: ${new Date(payment.created_at).toLocaleString()}
|
|
338
|
-
${payment.order_id ? `- Order: ${payment.order_id}` : ''}
|
|
339
|
-
`.trim();
|
|
340
|
-
}
|
|
341
|
-
```
|
|
342
|
-
|
|
343
|
-
### Format Currency List
|
|
344
|
-
|
|
345
|
-
```javascript
|
|
346
|
-
function formatCurrencies(currencies) {
|
|
347
|
-
const popular = ['BTC', 'ETH', 'USDT', 'USDC', 'LTC'];
|
|
348
|
-
const others = currencies.filter(c => !popular.includes(c.toUpperCase()));
|
|
349
|
-
|
|
350
|
-
return `
|
|
351
|
-
Popular Cryptocurrencies:
|
|
352
|
-
${popular.map(c => ` • ${c}`).join('\n')}
|
|
353
|
-
|
|
354
|
-
Other Available (${others.length}):
|
|
355
|
-
${others.slice(0, 10).map(c => ` • ${c.toUpperCase()}`).join('\n')}
|
|
356
|
-
${others.length > 10 ? ` ... and ${others.length - 10} more` : ''}
|
|
357
|
-
`.trim();
|
|
358
|
-
}
|
|
359
|
-
```
|
|
360
|
-
|
|
361
|
-
## Security Considerations
|
|
362
|
-
|
|
363
|
-
### 1. API Key Management
|
|
364
|
-
|
|
365
|
-
Never expose API keys in logs or responses:
|
|
366
|
-
|
|
367
|
-
```javascript
|
|
368
|
-
// ✗ Bad
|
|
369
|
-
console.log(`Using API key: ${apiKey}`);
|
|
370
|
-
|
|
371
|
-
// ✓ Good
|
|
372
|
-
console.log(`API key configured: ${apiKey.substring(0, 4)}...`);
|
|
373
|
-
```
|
|
374
|
-
|
|
375
|
-
### 2. Input Validation
|
|
376
|
-
|
|
377
|
-
Validate user inputs before passing to CLI:
|
|
378
|
-
|
|
379
|
-
```javascript
|
|
380
|
-
function validateAmount(amount) {
|
|
381
|
-
const num = parseFloat(amount);
|
|
382
|
-
if (isNaN(num) || num <= 0) {
|
|
383
|
-
throw new Error('Amount must be a positive number');
|
|
384
|
-
}
|
|
385
|
-
return num;
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
function validateCurrency(currency) {
|
|
389
|
-
if (!/^[A-Z]{3,5}$/.test(currency.toUpperCase())) {
|
|
390
|
-
throw new Error('Invalid currency format');
|
|
391
|
-
}
|
|
392
|
-
return currency.toUpperCase();
|
|
393
|
-
}
|
|
394
|
-
```
|
|
395
|
-
|
|
396
|
-
### 3. Address Validation
|
|
397
|
-
|
|
398
|
-
Validate cryptocurrency addresses before payouts:
|
|
399
|
-
|
|
400
|
-
```javascript
|
|
401
|
-
// Basic validation (use proper library in production)
|
|
402
|
-
function validateBtcAddress(address) {
|
|
403
|
-
if (address.startsWith('bc1') && address.length >= 42) {
|
|
404
|
-
return true; // Bech32
|
|
405
|
-
}
|
|
406
|
-
if (/^[13][a-km-zA-HJ-NP-Z1-9]{25,34}$/.test(address)) {
|
|
407
|
-
return true; // Legacy
|
|
408
|
-
}
|
|
409
|
-
throw new Error('Invalid Bitcoin address');
|
|
410
|
-
}
|
|
411
|
-
```
|
|
412
|
-
|
|
413
|
-
## Testing Agent Integration
|
|
414
|
-
|
|
415
|
-
### Unit Test Example
|
|
416
|
-
|
|
417
|
-
```javascript
|
|
418
|
-
describe('Payment Creation', () => {
|
|
419
|
-
it('should create payment with valid parameters', async () => {
|
|
420
|
-
const result = await exec(`nowpayments --json payment create \
|
|
421
|
-
--price 100 \
|
|
422
|
-
--currency USD \
|
|
423
|
-
--pay-currency BTC`);
|
|
424
|
-
|
|
425
|
-
const payment = JSON.parse(result.stdout);
|
|
426
|
-
expect(payment.payment_id).toBeDefined();
|
|
427
|
-
expect(payment.pay_address).toBeDefined();
|
|
428
|
-
expect(payment.payment_status).toBe('waiting');
|
|
429
|
-
});
|
|
430
|
-
|
|
431
|
-
it('should fail with invalid amount', async () => {
|
|
432
|
-
await expect(
|
|
433
|
-
exec(`nowpayments payment create --price -10 --currency USD --pay-currency BTC`)
|
|
434
|
-
).rejects.toThrow();
|
|
435
|
-
});
|
|
436
|
-
});
|
|
437
|
-
```
|
|
438
|
-
|
|
439
|
-
### Integration Test Example
|
|
440
|
-
|
|
441
|
-
```javascript
|
|
442
|
-
describe('Full Payment Flow', () => {
|
|
443
|
-
it('should handle complete payment lifecycle', async () => {
|
|
444
|
-
// Create payment
|
|
445
|
-
const createResult = await exec(`nowpayments --json payment create \
|
|
446
|
-
--price 100 --currency USD --pay-currency BTC`);
|
|
447
|
-
const payment = JSON.parse(createResult.stdout);
|
|
448
|
-
|
|
449
|
-
// Verify payment exists
|
|
450
|
-
const getResult = await exec(`nowpayments --json payment get ${payment.payment_id}`);
|
|
451
|
-
const retrieved = JSON.parse(getResult.stdout);
|
|
452
|
-
|
|
453
|
-
expect(retrieved.payment_id).toBe(payment.payment_id);
|
|
454
|
-
expect(retrieved.payment_status).toBe('waiting');
|
|
455
|
-
});
|
|
456
|
-
});
|
|
457
|
-
```
|
|
458
|
-
|
|
459
|
-
## Performance Tips
|
|
460
|
-
|
|
461
|
-
1. **Use JSON mode**: Faster parsing than formatted output
|
|
462
|
-
2. **Batch requests**: Combine operations where possible
|
|
463
|
-
3. **Cache static data**: Currency lists don't change often
|
|
464
|
-
4. **Reasonable polling**: Don't check payment status more than once per 30 seconds
|
|
465
|
-
5. **Parallel requests**: Independent operations can run concurrently
|
|
466
|
-
|
|
467
|
-
## Troubleshooting
|
|
468
|
-
|
|
469
|
-
### Issue: "No API key found"
|
|
470
|
-
|
|
471
|
-
```javascript
|
|
472
|
-
// Check multiple sources
|
|
473
|
-
const apiKey = process.env.NOWPAYMENTS_API_KEY ||
|
|
474
|
-
await getFromConfig() ||
|
|
475
|
-
await promptUser();
|
|
476
|
-
|
|
477
|
-
if (!apiKey) {
|
|
478
|
-
return "Please set your API key: nowpayments auth set YOUR_KEY";
|
|
479
|
-
}
|
|
480
|
-
```
|
|
481
|
-
|
|
482
|
-
### Issue: Rate limiting
|
|
483
|
-
|
|
484
|
-
```javascript
|
|
485
|
-
if (error.includes('429') || error.includes('rate limit')) {
|
|
486
|
-
return "API rate limit reached. Please wait a moment and try again.";
|
|
487
|
-
}
|
|
488
|
-
```
|
|
489
|
-
|
|
490
|
-
### Issue: Network errors
|
|
491
|
-
|
|
492
|
-
```javascript
|
|
493
|
-
if (error.includes('ENOTFOUND') || error.includes('Network error')) {
|
|
494
|
-
return "Cannot connect to NOWPayments. Check your internet connection.";
|
|
495
|
-
}
|
|
496
|
-
```
|
|
497
|
-
|
|
498
|
-
## Best Practices Summary
|
|
499
|
-
|
|
500
|
-
1. Always use `--json` for programmatic access
|
|
501
|
-
2. Validate inputs before calling CLI
|
|
502
|
-
3. Handle all error cases gracefully
|
|
503
|
-
4. Provide clear, natural language responses
|
|
504
|
-
5. Cache where appropriate
|
|
505
|
-
6. Monitor but don't spam (reasonable polling intervals)
|
|
506
|
-
7. Keep context between commands
|
|
507
|
-
8. Test error paths thoroughly
|
|
508
|
-
9. Never expose sensitive data in logs
|
|
509
|
-
10. Use proper exit code checking
|
|
510
|
-
|
|
511
|
-
---
|
|
512
|
-
|
|
513
|
-
This CLI is designed to be a reliable tool for AI agents to integrate cryptocurrency payments into their workflows. The combination of structured JSON output, clear error handling, and comprehensive commands makes it ideal for autonomous operation.
|
|
40
|
+
Always use `--json` for programmatic parsing.
|