@ktmcp-cli/nowpayments 1.0.0

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/OPENCLAW.md ADDED
@@ -0,0 +1,628 @@
1
+ # NOWPayments CLI - OpenClaw Integration Guide
2
+
3
+ This guide covers integration of the NOWPayments CLI with the OpenClaw agent framework, enabling cryptocurrency payment processing in OpenClaw-based applications.
4
+
5
+ ## What is OpenClaw?
6
+
7
+ OpenClaw is an open-source agent framework for building autonomous AI applications. It provides:
8
+ - Multi-agent coordination
9
+ - Tool/skill registration
10
+ - Context management
11
+ - Session persistence
12
+ - Event-driven architecture
13
+
14
+ ## Integration Overview
15
+
16
+ The NOWPayments CLI integrates with OpenClaw as a **tool/skill**, allowing OpenClaw agents to:
17
+ - Accept cryptocurrency payments
18
+ - Process invoices
19
+ - Manage payouts
20
+ - Monitor transaction status
21
+ - Handle payment webhooks
22
+
23
+ ## Installation
24
+
25
+ ### 1. Install NOWPayments CLI
26
+
27
+ ```bash
28
+ npm install -g @ktmcp-cli/nowpayments
29
+ ```
30
+
31
+ ### 2. Configure API Key
32
+
33
+ ```bash
34
+ # Set API key globally
35
+ nowpayments auth set YOUR_API_KEY
36
+
37
+ # Or use environment variable in OpenClaw config
38
+ export NOWPAYMENTS_API_KEY=your_api_key
39
+ ```
40
+
41
+ ### 3. Verify Installation
42
+
43
+ ```bash
44
+ nowpayments status
45
+ ```
46
+
47
+ ## OpenClaw Skill Definition
48
+
49
+ Create a skill definition file for OpenClaw:
50
+
51
+ ### `skills/nowpayments.json`
52
+
53
+ ```json
54
+ {
55
+ "name": "nowpayments",
56
+ "version": "1.0.0",
57
+ "description": "Cryptocurrency payment processing via NOWPayments",
58
+ "category": "payment",
59
+ "commands": {
60
+ "status": {
61
+ "description": "Check NOWPayments API status",
62
+ "execute": "nowpayments status"
63
+ },
64
+ "list_currencies": {
65
+ "description": "List available cryptocurrencies",
66
+ "execute": "nowpayments --json currencies list --available",
67
+ "output": "json"
68
+ },
69
+ "estimate": {
70
+ "description": "Estimate cryptocurrency amount",
71
+ "parameters": {
72
+ "from": { "type": "string", "required": true },
73
+ "to": { "type": "string", "required": true },
74
+ "amount": { "type": "number", "required": true }
75
+ },
76
+ "execute": "nowpayments --json estimate convert --from {from} --to {to} --amount {amount}",
77
+ "output": "json"
78
+ },
79
+ "create_payment": {
80
+ "description": "Create a new payment",
81
+ "parameters": {
82
+ "price": { "type": "number", "required": true },
83
+ "currency": { "type": "string", "required": true },
84
+ "pay_currency": { "type": "string", "required": true },
85
+ "order_id": { "type": "string", "required": false },
86
+ "order_description": { "type": "string", "required": false }
87
+ },
88
+ "execute": "nowpayments --json payment create --price {price} --currency {currency} --pay-currency {pay_currency} {order_id:--order-id} {order_description:--order-description}",
89
+ "output": "json"
90
+ },
91
+ "get_payment": {
92
+ "description": "Get payment status and details",
93
+ "parameters": {
94
+ "payment_id": { "type": "string", "required": true }
95
+ },
96
+ "execute": "nowpayments --json payment get {payment_id}",
97
+ "output": "json"
98
+ },
99
+ "list_payments": {
100
+ "description": "List all payments",
101
+ "parameters": {
102
+ "limit": { "type": "number", "default": 10 },
103
+ "page": { "type": "number", "default": 0 }
104
+ },
105
+ "execute": "nowpayments --json payment list --limit {limit} --page {page}",
106
+ "output": "json"
107
+ },
108
+ "create_invoice": {
109
+ "description": "Create a payment invoice",
110
+ "parameters": {
111
+ "price": { "type": "number", "required": true },
112
+ "currency": { "type": "string", "required": true },
113
+ "order_id": { "type": "string", "required": false },
114
+ "success_url": { "type": "string", "required": false }
115
+ },
116
+ "execute": "nowpayments --json invoice create --price {price} --currency {currency} {order_id:--order-id} {success_url:--success-url}",
117
+ "output": "json"
118
+ }
119
+ },
120
+ "events": {
121
+ "payment_created": {
122
+ "description": "Emitted when a payment is created",
123
+ "data": {
124
+ "payment_id": "string",
125
+ "pay_address": "string",
126
+ "pay_amount": "number",
127
+ "pay_currency": "string"
128
+ }
129
+ },
130
+ "payment_completed": {
131
+ "description": "Emitted when a payment is confirmed",
132
+ "data": {
133
+ "payment_id": "string",
134
+ "status": "string"
135
+ }
136
+ }
137
+ }
138
+ }
139
+ ```
140
+
141
+ ## Usage Examples
142
+
143
+ ### Example 1: Simple Payment Flow
144
+
145
+ ```javascript
146
+ // OpenClaw agent code
147
+ async function processPayment(agent, amount, currency) {
148
+ // 1. Check API status
149
+ const status = await agent.execute('nowpayments', 'status');
150
+ if (!status.success) {
151
+ throw new Error('NOWPayments API unavailable');
152
+ }
153
+
154
+ // 2. Get estimate
155
+ const estimate = await agent.execute('nowpayments', 'estimate', {
156
+ from: currency,
157
+ to: 'BTC',
158
+ amount: amount
159
+ });
160
+
161
+ // 3. Create payment
162
+ const payment = await agent.execute('nowpayments', 'create_payment', {
163
+ price: amount,
164
+ currency: currency,
165
+ pay_currency: 'BTC',
166
+ order_id: `ORDER-${Date.now()}`,
167
+ order_description: 'Product purchase'
168
+ });
169
+
170
+ // 4. Emit event
171
+ agent.emit('payment_created', payment);
172
+
173
+ // 5. Return payment details
174
+ return {
175
+ paymentId: payment.payment_id,
176
+ address: payment.pay_address,
177
+ amount: payment.pay_amount,
178
+ currency: payment.pay_currency
179
+ };
180
+ }
181
+ ```
182
+
183
+ ### Example 2: Payment Monitoring
184
+
185
+ ```javascript
186
+ // Monitor payment status
187
+ async function monitorPayment(agent, paymentId) {
188
+ const maxAttempts = 60; // 30 minutes (30s intervals)
189
+ let attempts = 0;
190
+
191
+ while (attempts < maxAttempts) {
192
+ const payment = await agent.execute('nowpayments', 'get_payment', {
193
+ payment_id: paymentId
194
+ });
195
+
196
+ switch (payment.payment_status) {
197
+ case 'finished':
198
+ agent.emit('payment_completed', {
199
+ payment_id: paymentId,
200
+ status: 'completed'
201
+ });
202
+ return { success: true, payment };
203
+
204
+ case 'failed':
205
+ case 'expired':
206
+ agent.emit('payment_failed', {
207
+ payment_id: paymentId,
208
+ status: payment.payment_status
209
+ });
210
+ return { success: false, payment };
211
+
212
+ case 'partially_paid':
213
+ agent.emit('payment_underpaid', {
214
+ payment_id: paymentId,
215
+ expected: payment.pay_amount,
216
+ received: payment.actually_paid
217
+ });
218
+ break;
219
+ }
220
+
221
+ // Wait 30 seconds before next check
222
+ await agent.sleep(30000);
223
+ attempts++;
224
+ }
225
+
226
+ return { success: false, timeout: true };
227
+ }
228
+ ```
229
+
230
+ ### Example 3: Invoice Generation
231
+
232
+ ```javascript
233
+ // Generate and track invoice
234
+ async function createInvoice(agent, productId, amount, customerEmail) {
235
+ // Create invoice
236
+ const invoice = await agent.execute('nowpayments', 'create_invoice', {
237
+ price: amount,
238
+ currency: 'USD',
239
+ order_id: `INV-${productId}-${Date.now()}`,
240
+ success_url: `https://example.com/success?product=${productId}`
241
+ });
242
+
243
+ // Store invoice in agent context
244
+ await agent.context.set(`invoice:${invoice.id}`, {
245
+ invoiceId: invoice.id,
246
+ productId: productId,
247
+ customerEmail: customerEmail,
248
+ amount: amount,
249
+ created: new Date(),
250
+ url: invoice.invoice_url
251
+ });
252
+
253
+ // Send invoice to customer
254
+ await agent.execute('email', 'send', {
255
+ to: customerEmail,
256
+ subject: 'Your Payment Invoice',
257
+ body: `Please complete your payment: ${invoice.invoice_url}`
258
+ });
259
+
260
+ return invoice;
261
+ }
262
+ ```
263
+
264
+ ### Example 4: Multi-Currency Support
265
+
266
+ ```javascript
267
+ // Let customer choose payment currency
268
+ async function createFlexiblePayment(agent, priceUSD) {
269
+ // Get available currencies
270
+ const currencies = await agent.execute('nowpayments', 'list_currencies');
271
+
272
+ // Get estimates for popular currencies
273
+ const options = await Promise.all([
274
+ agent.execute('nowpayments', 'estimate', {
275
+ from: 'USD',
276
+ to: 'BTC',
277
+ amount: priceUSD
278
+ }),
279
+ agent.execute('nowpayments', 'estimate', {
280
+ from: 'USD',
281
+ to: 'ETH',
282
+ amount: priceUSD
283
+ }),
284
+ agent.execute('nowpayments', 'estimate', {
285
+ from: 'USD',
286
+ to: 'USDT',
287
+ amount: priceUSD
288
+ })
289
+ ]);
290
+
291
+ // Present options to user
292
+ const choice = await agent.prompt('Choose payment currency:', [
293
+ `Bitcoin: ${options[0].estimated_amount} BTC`,
294
+ `Ethereum: ${options[1].estimated_amount} ETH`,
295
+ `Tether: ${options[2].estimated_amount} USDT`
296
+ ]);
297
+
298
+ const selectedCurrency = ['BTC', 'ETH', 'USDT'][choice];
299
+
300
+ // Create payment with selected currency
301
+ return await agent.execute('nowpayments', 'create_payment', {
302
+ price: priceUSD,
303
+ currency: 'USD',
304
+ pay_currency: selectedCurrency,
305
+ order_id: `ORDER-${Date.now()}`
306
+ });
307
+ }
308
+ ```
309
+
310
+ ## Event Handling
311
+
312
+ ### Set Up Event Listeners
313
+
314
+ ```javascript
315
+ // In OpenClaw agent initialization
316
+ agent.on('nowpayments:payment_created', async (data) => {
317
+ console.log('Payment created:', data.payment_id);
318
+
319
+ // Store payment in database
320
+ await agent.db.payments.insert({
321
+ paymentId: data.payment_id,
322
+ address: data.pay_address,
323
+ amount: data.pay_amount,
324
+ currency: data.pay_currency,
325
+ status: 'waiting',
326
+ createdAt: new Date()
327
+ });
328
+
329
+ // Start monitoring
330
+ agent.schedule('monitor_payment', {
331
+ paymentId: data.payment_id
332
+ });
333
+ });
334
+
335
+ agent.on('nowpayments:payment_completed', async (data) => {
336
+ console.log('Payment completed:', data.payment_id);
337
+
338
+ // Update database
339
+ await agent.db.payments.update(
340
+ { paymentId: data.payment_id },
341
+ { status: 'completed', completedAt: new Date() }
342
+ );
343
+
344
+ // Fulfill order
345
+ await agent.execute('order', 'fulfill', {
346
+ paymentId: data.payment_id
347
+ });
348
+
349
+ // Send confirmation
350
+ await agent.execute('notification', 'send', {
351
+ type: 'payment_success',
352
+ paymentId: data.payment_id
353
+ });
354
+ });
355
+ ```
356
+
357
+ ## Webhook Integration
358
+
359
+ ### Set Up IPN Handler
360
+
361
+ ```javascript
362
+ // In your OpenClaw web server
363
+ app.post('/webhooks/nowpayments/ipn', async (req, res) => {
364
+ const ipnData = req.body;
365
+
366
+ // Verify IPN signature (HMAC-SHA512)
367
+ const signature = req.headers['x-nowpayments-sig'];
368
+ const isValid = verifyIpnSignature(ipnData, signature);
369
+
370
+ if (!isValid) {
371
+ return res.status(401).send('Invalid signature');
372
+ }
373
+
374
+ // Process payment update
375
+ const { payment_id, payment_status } = ipnData;
376
+
377
+ // Emit event to OpenClaw agents
378
+ await openclaw.broadcast('nowpayments:payment_update', {
379
+ paymentId: payment_id,
380
+ status: payment_status,
381
+ data: ipnData
382
+ });
383
+
384
+ res.status(200).send('OK');
385
+ });
386
+
387
+ // IPN signature verification
388
+ function verifyIpnSignature(data, signature) {
389
+ const crypto = require('crypto');
390
+ const ipnSecret = process.env.NOWPAYMENTS_IPN_SECRET;
391
+
392
+ const payload = JSON.stringify(data);
393
+ const expectedSignature = crypto
394
+ .createHmac('sha512', ipnSecret)
395
+ .update(payload)
396
+ .digest('hex');
397
+
398
+ return signature === expectedSignature;
399
+ }
400
+ ```
401
+
402
+ ## Advanced Patterns
403
+
404
+ ### Pattern 1: Subscription Payments
405
+
406
+ ```javascript
407
+ async function createSubscription(agent, plan, customerEmail) {
408
+ const monthlyPrice = plan.price;
409
+
410
+ // Create first payment
411
+ const payment = await agent.execute('nowpayments', 'create_payment', {
412
+ price: monthlyPrice,
413
+ currency: 'USD',
414
+ pay_currency: 'BTC',
415
+ order_id: `SUB-${plan.id}-${Date.now()}`,
416
+ order_description: `${plan.name} - Month 1`
417
+ });
418
+
419
+ // Schedule monthly reminders
420
+ agent.schedule('subscription_renewal', {
421
+ planId: plan.id,
422
+ customerEmail: customerEmail,
423
+ amount: monthlyPrice
424
+ }, { cron: '0 0 1 * *' }); // First of every month
425
+
426
+ return payment;
427
+ }
428
+ ```
429
+
430
+ ### Pattern 2: Batch Processing
431
+
432
+ ```javascript
433
+ async function processMonthlyPayouts(agent) {
434
+ // Get all pending payouts
435
+ const payouts = await agent.db.payouts.find({ status: 'pending' });
436
+
437
+ // Group by currency for efficiency
438
+ const grouped = groupBy(payouts, 'currency');
439
+
440
+ for (const [currency, items] of Object.entries(grouped)) {
441
+ for (const item of items) {
442
+ try {
443
+ const payout = await agent.execute('nowpayments', 'create_payout', {
444
+ amount: item.amount,
445
+ currency: currency,
446
+ address: item.address
447
+ });
448
+
449
+ await agent.db.payouts.update(
450
+ { id: item.id },
451
+ { status: 'processing', payoutId: payout.id }
452
+ );
453
+
454
+ // Rate limiting
455
+ await agent.sleep(1000);
456
+ } catch (error) {
457
+ await agent.log.error('Payout failed', {
458
+ payoutId: item.id,
459
+ error: error.message
460
+ });
461
+ }
462
+ }
463
+ }
464
+ }
465
+ ```
466
+
467
+ ### Pattern 3: Multi-Agent Coordination
468
+
469
+ ```javascript
470
+ // Payment Agent
471
+ class PaymentAgent extends OpenClawAgent {
472
+ async onPaymentRequest(data) {
473
+ const payment = await this.execute('nowpayments', 'create_payment', data);
474
+
475
+ // Notify order agent
476
+ await this.send('order-agent', 'payment_created', payment);
477
+
478
+ // Start monitoring
479
+ this.monitorPayment(payment.payment_id);
480
+ }
481
+
482
+ async onPaymentCompleted(paymentId) {
483
+ // Notify fulfillment agent
484
+ await this.send('fulfillment-agent', 'process_order', { paymentId });
485
+ }
486
+ }
487
+
488
+ // Order Agent
489
+ class OrderAgent extends OpenClawAgent {
490
+ async onMessage(from, type, data) {
491
+ if (type === 'payment_created') {
492
+ await this.db.orders.update(
493
+ { id: data.order_id },
494
+ { paymentId: data.payment_id, status: 'awaiting_payment' }
495
+ );
496
+ }
497
+ }
498
+ }
499
+
500
+ // Fulfillment Agent
501
+ class FulfillmentAgent extends OpenClawAgent {
502
+ async onMessage(from, type, data) {
503
+ if (type === 'process_order') {
504
+ const order = await this.db.orders.findOne({ paymentId: data.paymentId });
505
+ await this.fulfillOrder(order);
506
+ }
507
+ }
508
+ }
509
+ ```
510
+
511
+ ## Testing
512
+
513
+ ### Unit Tests
514
+
515
+ ```javascript
516
+ describe('NOWPayments Integration', () => {
517
+ let agent;
518
+
519
+ beforeEach(() => {
520
+ agent = new OpenClawAgent({
521
+ skills: ['nowpayments']
522
+ });
523
+ });
524
+
525
+ it('should create payment', async () => {
526
+ const payment = await agent.execute('nowpayments', 'create_payment', {
527
+ price: 100,
528
+ currency: 'USD',
529
+ pay_currency: 'BTC'
530
+ });
531
+
532
+ expect(payment.payment_id).toBeDefined();
533
+ expect(payment.pay_address).toBeDefined();
534
+ });
535
+
536
+ it('should monitor payment status', async () => {
537
+ const paymentId = 'test-payment-123';
538
+
539
+ const result = await monitorPayment(agent, paymentId);
540
+
541
+ expect(result.success).toBeDefined();
542
+ });
543
+ });
544
+ ```
545
+
546
+ ### Integration Tests
547
+
548
+ ```javascript
549
+ describe('Payment Flow', () => {
550
+ it('should complete full payment lifecycle', async () => {
551
+ // Create payment
552
+ const payment = await createPayment(agent, 100, 'USD');
553
+ expect(payment.paymentId).toBeDefined();
554
+
555
+ // Verify payment created event
556
+ const event = await agent.waitFor('payment_created');
557
+ expect(event.payment_id).toBe(payment.paymentId);
558
+
559
+ // Simulate payment completion (in sandbox)
560
+ // ... payment completion logic ...
561
+
562
+ // Verify completion event
563
+ const completedEvent = await agent.waitFor('payment_completed');
564
+ expect(completedEvent.payment_id).toBe(payment.paymentId);
565
+ });
566
+ });
567
+ ```
568
+
569
+ ## Configuration
570
+
571
+ ### Environment Variables
572
+
573
+ ```bash
574
+ # Required
575
+ NOWPAYMENTS_API_KEY=your_api_key
576
+
577
+ # Optional
578
+ NOWPAYMENTS_IPN_SECRET=your_ipn_secret
579
+ NOWPAYMENTS_SANDBOX=false
580
+ NOWPAYMENTS_DEFAULT_CURRENCY=USD
581
+ NOWPAYMENTS_DEFAULT_PAY_CURRENCY=BTC
582
+ ```
583
+
584
+ ### OpenClaw Config
585
+
586
+ ```yaml
587
+ # openclaw.config.yml
588
+ skills:
589
+ - name: nowpayments
590
+ enabled: true
591
+ config:
592
+ api_key: ${NOWPAYMENTS_API_KEY}
593
+ sandbox: false
594
+ webhook_url: https://your-domain.com/webhooks/nowpayments/ipn
595
+ default_currency: USD
596
+ supported_pay_currencies:
597
+ - BTC
598
+ - ETH
599
+ - USDT
600
+ - LTC
601
+ ```
602
+
603
+ ## Best Practices
604
+
605
+ 1. **Always use JSON output mode** for programmatic access
606
+ 2. **Implement proper error handling** for all payment operations
607
+ 3. **Use webhooks (IPN)** instead of polling when possible
608
+ 4. **Store payment IDs** in your database for tracking
609
+ 5. **Validate amounts** before creating payments
610
+ 6. **Monitor payment expiration** and notify users
611
+ 7. **Implement retry logic** for failed API calls
612
+ 8. **Use sandbox mode** for testing
613
+ 9. **Secure webhook endpoints** with signature verification
614
+ 10. **Log all payment operations** for audit trail
615
+
616
+ ## Troubleshooting
617
+
618
+ ### Common Issues
619
+
620
+ 1. **API Key Not Found**: Ensure environment variable is set or use `nowpayments auth set`
621
+ 2. **Rate Limiting**: Implement exponential backoff and respect rate limits
622
+ 3. **Webhook Not Received**: Check firewall rules and verify IPN callback URL
623
+ 4. **Payment Expired**: Monitor payments and send reminders before expiration
624
+ 5. **Currency Not Supported**: Always validate currencies before creating payments
625
+
626
+ ---
627
+
628
+ This integration guide enables seamless cryptocurrency payment processing in OpenClaw applications using the NOWPayments CLI as a foundation.