@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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@profullstack/coinpay",
3
- "version": "0.8.0",
4
- "description": "CoinPay SDK & CLI — Accept cryptocurrency payments (BTC, ETH, SOL, POL, BCH, USDC) with wallet and swap support",
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
- "@scure/bip39": "^1.4.0",
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
- "@inquirer/prompts": "^8.3.0"
129
+ "@profullstack/hqtui": "^0.1.11",
130
+ "@scure/bip32": "^1.5.0",
131
+ "@scure/bip39": "^1.4.0"
117
132
  }
118
133
  }
@@ -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
- return client.request('POST', '/api/stripe/payments/create', {
313
- businessId,
314
- amount: amountCents,
315
- currency: 'usd',
316
- description,
317
- metadata,
318
- escrowMode: true,
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', url);
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('POST', '/api/stripe/escrow/release', {
364
- escrowId,
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('POST', '/api/stripe/escrow/refund', {
390
- escrowId,
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('GET', `/api/stripe/transactions/${escrowId}`);
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({ name, webhookUrl, walletAddresses }) {
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
- webhookUrl,
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