@profullstack/coinpay 0.8.0 → 0.9.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/CHANGELOG.md +39 -0
- package/README.md +128 -3
- package/bin/coinpay.js +919 -30
- package/package.json +24 -9
- package/src/card-payments.js +23 -14
- package/src/client.js +40 -2
- package/src/finances-tui.js +1005 -0
- package/src/finances.d.ts +333 -0
- package/src/finances.js +445 -0
- package/src/index.d.ts +3 -0
- package/src/index.js +35 -0
- package/src/invoices.d.ts +1 -0
- package/src/invoices.js +14 -1
- package/src/lightning.js +8 -3
- package/src/swap.js +36 -5
- package/src/taskmarket.js +329 -0
- package/src/wallet.js +54 -24
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@profullstack/coinpay",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "CoinPay SDK & CLI
|
|
3
|
+
"version": "0.9.0",
|
|
4
|
+
"description": "CoinPay SDK & CLI \u2014 Accept cryptocurrency and card payments (BTC, ETH, SOL, POL, BCH, USDC) with wallet, swap and a live finances dashboard",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.js",
|
|
7
7
|
"types": "./src/index.d.ts",
|
|
@@ -48,6 +48,16 @@
|
|
|
48
48
|
},
|
|
49
49
|
"./x402-pay-server": {
|
|
50
50
|
"import": "./src/x402-pay-server.js"
|
|
51
|
+
},
|
|
52
|
+
"./taskmarket": {
|
|
53
|
+
"import": "./src/taskmarket.js"
|
|
54
|
+
},
|
|
55
|
+
"./finances": {
|
|
56
|
+
"import": "./src/finances.js",
|
|
57
|
+
"types": "./src/finances.d.ts"
|
|
58
|
+
},
|
|
59
|
+
"./finances-tui": {
|
|
60
|
+
"import": "./src/finances-tui.js"
|
|
51
61
|
}
|
|
52
62
|
},
|
|
53
63
|
"files": [
|
|
@@ -86,7 +96,12 @@
|
|
|
86
96
|
"payment-gateway",
|
|
87
97
|
"merchant",
|
|
88
98
|
"bip39",
|
|
89
|
-
"mnemonic"
|
|
99
|
+
"mnemonic",
|
|
100
|
+
"finances",
|
|
101
|
+
"tui",
|
|
102
|
+
"dashboard",
|
|
103
|
+
"plaid",
|
|
104
|
+
"simplefin"
|
|
90
105
|
],
|
|
91
106
|
"author": "Profullstack, Inc.",
|
|
92
107
|
"license": "MIT",
|
|
@@ -103,16 +118,16 @@
|
|
|
103
118
|
"node": ">=20.0.0"
|
|
104
119
|
},
|
|
105
120
|
"devDependencies": {
|
|
106
|
-
"vitest": "^4.1.0",
|
|
107
121
|
"eslint": "^8.57.0",
|
|
108
|
-
"prettier": "^3.4.1"
|
|
122
|
+
"prettier": "^3.4.1",
|
|
123
|
+
"vitest": "^4.1.0"
|
|
109
124
|
},
|
|
110
|
-
"peerDependencies": {},
|
|
111
125
|
"dependencies": {
|
|
112
|
-
"@
|
|
113
|
-
"@scure/bip32": "^1.5.0",
|
|
126
|
+
"@inquirer/prompts": "^8.3.0",
|
|
114
127
|
"@noble/curves": "^1.6.0",
|
|
115
128
|
"@noble/hashes": "^1.5.0",
|
|
116
|
-
"@
|
|
129
|
+
"@profullstack/hqtui": "^0.1.11",
|
|
130
|
+
"@scure/bip32": "^1.5.0",
|
|
131
|
+
"@scure/bip39": "^1.4.0"
|
|
117
132
|
}
|
|
118
133
|
}
|
package/src/card-payments.js
CHANGED
|
@@ -309,13 +309,21 @@ export async function createCardEscrow(client, businessId, amountUSD, descriptio
|
|
|
309
309
|
// Convert USD to cents
|
|
310
310
|
const amountCents = Math.round(amountUSD * 100);
|
|
311
311
|
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
312
|
+
// `CoinPayClient.request(endpoint, options)` takes TWO arguments. Every call
|
|
313
|
+
// in this file passed three, in the shape `request(method, path, body)` — so
|
|
314
|
+
// `endpoint` received 'POST', the URL became `baseUrl + 'POST'`, and `options`
|
|
315
|
+
// received the path as a string. These calls failed 100% of the time, which
|
|
316
|
+
// made releasing or refunding a card escrow unreachable through the SDK.
|
|
317
|
+
return client.request('/api/stripe/payments/create', {
|
|
318
|
+
method: 'POST',
|
|
319
|
+
body: JSON.stringify({
|
|
320
|
+
businessId,
|
|
321
|
+
amount: amountCents,
|
|
322
|
+
currency: 'usd',
|
|
323
|
+
description,
|
|
324
|
+
metadata,
|
|
325
|
+
escrowMode: true,
|
|
326
|
+
}),
|
|
319
327
|
});
|
|
320
328
|
}
|
|
321
329
|
|
|
@@ -346,7 +354,7 @@ export async function listCardEscrows(client, options = {}) {
|
|
|
346
354
|
const queryString = queryParams.toString();
|
|
347
355
|
const url = `/api/stripe/escrows${queryString ? `?${queryString}` : ''}`;
|
|
348
356
|
|
|
349
|
-
return client.request('GET'
|
|
357
|
+
return client.request(url, { method: 'GET' });
|
|
350
358
|
}
|
|
351
359
|
|
|
352
360
|
/**
|
|
@@ -360,8 +368,9 @@ export async function listCardEscrows(client, options = {}) {
|
|
|
360
368
|
* const result = await releaseCardEscrow(client, 'escrow-123');
|
|
361
369
|
*/
|
|
362
370
|
export async function releaseCardEscrow(client, escrowId) {
|
|
363
|
-
return client.request('
|
|
364
|
-
|
|
371
|
+
return client.request('/api/stripe/escrow/release', {
|
|
372
|
+
method: 'POST',
|
|
373
|
+
body: JSON.stringify({ escrowId }),
|
|
365
374
|
});
|
|
366
375
|
}
|
|
367
376
|
|
|
@@ -386,9 +395,9 @@ export async function releaseCardEscrow(client, escrowId) {
|
|
|
386
395
|
* });
|
|
387
396
|
*/
|
|
388
397
|
export async function refundCardEscrow(client, escrowId, options = {}) {
|
|
389
|
-
return client.request('
|
|
390
|
-
|
|
391
|
-
...options,
|
|
398
|
+
return client.request('/api/stripe/escrow/refund', {
|
|
399
|
+
method: 'POST',
|
|
400
|
+
body: JSON.stringify({ escrowId, ...options }),
|
|
392
401
|
});
|
|
393
402
|
}
|
|
394
403
|
|
|
@@ -404,7 +413,7 @@ export async function refundCardEscrow(client, escrowId, options = {}) {
|
|
|
404
413
|
* console.log(status.escrow_status); // 'pending', 'released', 'refunded'
|
|
405
414
|
*/
|
|
406
415
|
export async function getCardEscrowStatus(client, escrowId) {
|
|
407
|
-
return client.request(
|
|
416
|
+
return client.request(`/api/stripe/transactions/${escrowId}`, { method: 'GET' });
|
|
408
417
|
}
|
|
409
418
|
|
|
410
419
|
/**
|
package/src/client.js
CHANGED
|
@@ -454,23 +454,61 @@ export class CoinPayClient {
|
|
|
454
454
|
|
|
455
455
|
/**
|
|
456
456
|
* Create a new business
|
|
457
|
+
*
|
|
458
|
+
* Field names are snake_case because that is what the API reads. This used to
|
|
459
|
+
* send `webhookUrl`, which POST /api/businesses does not look at -- it reads
|
|
460
|
+
* `input.webhook_url` -- so every business created through the SDK came back
|
|
461
|
+
* with a null webhook_url and no webhook secret, silently. The value was
|
|
462
|
+
* accepted, echoed nowhere, and dropped.
|
|
463
|
+
*
|
|
464
|
+
* `category` is required by the API and was not sent at all, so
|
|
465
|
+
* `coinpay business create` failed outright with "Select a valid business
|
|
466
|
+
* category" and there was no flag to supply one. Valid slugs live in
|
|
467
|
+
* src/lib/business/taxonomy.ts.
|
|
468
|
+
*
|
|
457
469
|
* @param {Object} params - Business parameters
|
|
458
470
|
* @param {string} params.name - Business name
|
|
471
|
+
* @param {string} params.category - Taxonomy slug; required by the API
|
|
472
|
+
* @param {string} [params.description]
|
|
459
473
|
* @param {string} [params.webhookUrl] - Webhook URL
|
|
474
|
+
* @param {string} [params.webhookSecret] - Supply one, or the API generates it
|
|
460
475
|
* @param {Object} [params.walletAddresses] - Wallet addresses by chain
|
|
461
476
|
* @returns {Promise<Object>} Created business
|
|
462
477
|
*/
|
|
463
|
-
async createBusiness({
|
|
478
|
+
async createBusiness({
|
|
479
|
+
name,
|
|
480
|
+
category,
|
|
481
|
+
description,
|
|
482
|
+
webhookUrl,
|
|
483
|
+
webhookSecret,
|
|
484
|
+
walletAddresses,
|
|
485
|
+
}) {
|
|
464
486
|
return this.request('/businesses', {
|
|
465
487
|
method: 'POST',
|
|
466
488
|
body: JSON.stringify({
|
|
467
489
|
name,
|
|
468
|
-
|
|
490
|
+
category,
|
|
491
|
+
description,
|
|
492
|
+
webhook_url: webhookUrl,
|
|
493
|
+
webhook_secret: webhookSecret,
|
|
469
494
|
walletAddresses,
|
|
470
495
|
}),
|
|
471
496
|
});
|
|
472
497
|
}
|
|
473
498
|
|
|
499
|
+
/**
|
|
500
|
+
* The taxonomy a business may be created with.
|
|
501
|
+
*
|
|
502
|
+
* Fetched rather than bundled: a copy inside the SDK goes stale the moment a
|
|
503
|
+
* category is added, and a stale copy is how "Select a valid business category"
|
|
504
|
+
* happens a second time.
|
|
505
|
+
*
|
|
506
|
+
* @returns {Promise<Object>} { success, categories: [{ slug, label, group, baseRisk }] }
|
|
507
|
+
*/
|
|
508
|
+
async listBusinessCategories() {
|
|
509
|
+
return this.request('/businesses/categories', { method: 'GET' });
|
|
510
|
+
}
|
|
511
|
+
|
|
474
512
|
/**
|
|
475
513
|
* Update business
|
|
476
514
|
* @param {string} businessId - Business ID
|