@profullstack/coinpay 0.8.0 → 0.10.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 CHANGED
@@ -5,6 +5,83 @@ All notable changes to `@profullstack/coinpay` will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.10.0] - 2026-09-12
9
+
10
+ ### Added
11
+ - `coinpay finances report`: monthly, quarterly and custom-period activity
12
+ reports generated server-side from an immutable snapshot, downloadable as
13
+ PDF, HTML, CSV or JSON (`--period 2026-08`, `--period 2026-Q2`, or
14
+ `--from/--to` with an exclusive end; `--account`, `--scope`, `--timezone`,
15
+ `--format`, `--output`, `--strict`, `--wait`, `--json`). Every report
16
+ states that it was generated by CoinPay from imported account data and is
17
+ not an institution-issued statement, and carries `local_export_complete`,
18
+ `provider_coverage` and `reconciliation_status`.
19
+ - `coinpay finances backfill`, `jobs`, `coverage`: durable, resumable
20
+ calendar-period fetches in provider-safe chunks, with per-account coverage
21
+ derived from what was actually requested.
22
+ - `coinpay finances statements import|list|get|download|reconcile|delete`:
23
+ keep original bank statements (PDF, user supplied, never parsed) beside an
24
+ account and period, and check their balances against a report revision
25
+ with exact decimal arithmetic.
26
+ - `coinpay finances connect` (setup token prompted without echo or via
27
+ `--setup-token-stdin`), `disconnect`, `consent <id> on|off`.
28
+ - SDK: `finances-reports` module (`createFinanceReport`, `waitForFinanceReport`,
29
+ `downloadFinanceReport`, `createBackfillJob`, `getFinanceCoverage`,
30
+ `importFinanceStatement`, `reconcileFinanceStatement`, ...), and
31
+ `CoinPayClient.requestBinary()` / `requestForm()` for downloads and uploads.
32
+ - Exit codes for the new subcommands: 0 done or job accepted, 2 invalid
33
+ input, 3 strict/completeness rejection, 4 authentication, 5 provider or
34
+ storage failure. In `--json` mode stdout carries only the result.
35
+
36
+ ### Fixed
37
+ - `listAllFinanceTransactions` now forwards `endDate`.
38
+
39
+ ## [0.9.0] - 2026-09-05
40
+
41
+ ### Added
42
+ - `coinpay finances` (aliases `coinpay money`, `coinpay tui`): a live terminal
43
+ dashboard built on `@profullstack/hqtui`. Seven screens — Overview, Bank &
44
+ Cards, Ledger, Crypto, Cards, Invoices & Escrow, Debt & Income — showing
45
+ gross volume, commission
46
+ paid, processor fees, refunds, net earnings, bank assets and liabilities,
47
+ cashflow, credit-card balances from the SimpleFIN/Plaid feeds, the ledger,
48
+ crypto and card payment tables, invoices outstanding/overdue and escrow held.
49
+ Refreshes on a timer and subscribes to the payments SSE stream so crypto
50
+ payment events appear live. `s` syncs the bank feed on demand.
51
+ - **Debt & Income** screen (`7`), and `coinpay finances position` (aliases
52
+ `debt`, `income`) as text. Income against spending per month, credits against
53
+ debits, total owed split into revolving and instalment, months to clear each
54
+ balance at its current payment rate, debt-to-income, debt-service ratio,
55
+ months of cover, card utilisation, detected recurring bills with their next
56
+ due date, and a business-versus-personal split of all of it — so the same
57
+ feed reads for a company or a person.
58
+ Transfers and card payments are excluded from both income and spending: a
59
+ feed holding both a checking account and the card it pays counts every card
60
+ payment twice otherwise. The raw sides remain visible as gross credits and
61
+ gross debits.
62
+ Built from about six months of history rather than the dashboard window,
63
+ because a monthly charge is invisible in thirty days of rows, and averaged
64
+ over the history that exists rather than the history requested.
65
+ - `coinpay finances scope <account-id> <business|personal|clear>`, and a `Side`
66
+ column on the accounts table. Which set of books an account belongs to was a
67
+ guess from its name, which reads "Business Checking" correctly and is blind to
68
+ a personal card carrying company spend. The correction is now stored in
69
+ `finance_accounts.scope_override`, wins over the guess, and survives a re-sync
70
+ — the same contract as `kind_override`. An overridden account is marked with a
71
+ trailing `*`, so a wrong split is traceable to a guess rather than a decision.
72
+ - Plain-text `coinpay finances summary|accounts|ledger|connections|sync`
73
+ (`--json` on all of them) for scripts and for Node older than 22.6.
74
+ - SDK `finances` module, also importable as `@profullstack/coinpay/finances`:
75
+ `getFinanceSummary`, `listFinanceAccounts`, `listFinanceTransactions`,
76
+ `listFinanceConnections`, `syncFinances`, `getDashboardStats`,
77
+ `getFinanceAnalytics`, `listCryptoPayments`, `listCardTransactions`,
78
+ `listCardPayouts`, the pure `buildFinanceSnapshot()`, `collectFinanceSnapshot()`
79
+ and `subscribeToPayments()` (SSE with reconnect).
80
+
81
+ ### Changed
82
+ - New dependency `@profullstack/hqtui` (zero runtime deps of its own). The
83
+ dashboard needs Node 22.6+; every other command still runs on Node 20.
84
+
8
85
  ## [0.6.11] - 2026-03-19
9
86
 
10
87
  ### Added
package/README.md CHANGED
@@ -596,9 +596,9 @@ coinpay payment qr pay_abc123
596
596
  ### Invoices
597
597
 
598
598
  Invoice creation is draft-only. It does not send the invoice or move funds.
599
- The create command prints the public `/now/{invoiceId}` payment link so it can be
600
- copied into chat. The payment page becomes available after the invoice is sent.
601
- Create's JSON output includes the same link as `shareUrl`.
599
+ Drafts do not have a public payment link. Publish the draft to create payment
600
+ details for manual sharing, or send it to create payment details and email the
601
+ client.
602
602
  When using a business-scoped API key, --business-id may be omitted.
603
603
 
604
604
  ```bash
@@ -618,6 +618,29 @@ coinpay invoice create --amount 250 --merchant-wallet-address 0xabc123
618
618
  # Get invoice details
619
619
  coinpay invoice get inv_abc123
620
620
 
621
+ # Update editable fields on a draft. Use --notes= to clear existing notes.
622
+ coinpay invoice update inv_abc123 \
623
+ --amount 275 \
624
+ --due-date 2026-09-15 \
625
+ --notes "Updated scope"
626
+
627
+ # Publish creates real payment details without emailing the client. It asks for
628
+ # confirmation and prints a live /now/{invoiceId} link for manual chat sharing.
629
+ coinpay invoice publish inv_abc123
630
+
631
+ # Non-interactive publish requires explicit confirmation.
632
+ coinpay invoice publish inv_abc123 --yes --json
633
+
634
+ # Send creates real payment details and emails the client. The command asks for
635
+ # confirmation and prints the same /now/{invoiceId} link for manual chat sharing.
636
+ coinpay invoice send inv_abc123
637
+
638
+ # Non-interactive send requires explicit confirmation. JSON stays on stdout.
639
+ coinpay invoice send inv_abc123 --yes --json
640
+
641
+ # Permanently delete a draft invoice (also asks for confirmation).
642
+ coinpay invoice delete inv_abc123
643
+
621
644
  # List invoices. Date filters apply to created_at and --date-to includes that day.
622
645
  coinpay invoice list \
623
646
  --business-id biz_123 \
@@ -630,6 +653,20 @@ coinpay invoice list \
630
653
  coinpay invoice list --status paid --json
631
654
  ```
632
655
 
656
+ Only draft invoices can be updated or deleted. Draft and overdue invoices can
657
+ be sent; sending an overdue invoice issues new payment details and emails the
658
+ client again. Only drafts can be published. `--yes` skips the confirmation for
659
+ publish/send/delete, and is required when any of those commands runs without a
660
+ terminal or with `--json`.
661
+
662
+ `--wallet-id` updates the invoice's stored wallet reference. To change the
663
+ actual settlement destination, use `--merchant-wallet-address` (or change the
664
+ crypto currency and let the server resolve the configured payee).
665
+
666
+ The CLI does not post invoice links to `/chat` automatically. Copy the printed
667
+ share link into chat manually. Treat `COINPAY_API_KEY` and `~/.coinpay.json` as
668
+ sensitive: either credential can authorize invoice updates, sends, and deletes.
669
+
633
670
  ### Businesses
634
671
 
635
672
  ```bash
@@ -653,6 +690,67 @@ coinpay webhook logs biz_123
653
690
  coinpay webhook test biz_123 --event payment.completed
654
691
  ```
655
692
 
693
+ ### Finances — your money in one place
694
+
695
+ ```bash
696
+ coinpay finances # live dashboard (needs `coinpay login`)
697
+ coinpay finances --days 90 # window for earnings / cashflow: 7, 30, 90, 365
698
+ coinpay finances summary # plain text, --json for machines
699
+ coinpay finances position # debt vs income, credits vs debits (also: debt)
700
+ coinpay finances scope <id> business # put an account on the company's books
701
+ coinpay finances accounts # linked bank & credit-card accounts (SimpleFIN / Plaid)
702
+ coinpay finances ledger --search anthropic --limit 20
703
+ coinpay finances connections # institutions and their last sync
704
+ coinpay finances sync # pull fresh balances (rate-limited by the bank bridge)
705
+ ```
706
+
707
+ The dashboard has seven screens (`1`–`7`, `Tab`): **Overview** (gross volume, crypto vs
708
+ cards, commission paid, processor fees, refunds, net earnings, bank position, cashflow,
709
+ invoices, escrow, payouts, a volume-vs-commission graph and a live feed), **Bank &
710
+ Cards**, **Ledger**, **Crypto**, **Cards**, **Invoices & Escrow**, **Debt & Income**.
711
+ `r` refreshes, `s`
712
+ syncs the bank feed, `w` cycles the window, `p` pauses, `?` shows help, `q` quits. It
713
+ refreshes every 30 seconds (`--interval`) and listens to the payments event stream, so
714
+ a crypto payment shows up the moment it is detected.
715
+
716
+ **Debt & Income** is the basic-accounting view, and it reads the same for a company or
717
+ a person: income against spending per month, total owed split into revolving and
718
+ instalment, months to clear each balance at its current payment rate, debt-to-income,
719
+ debt-service ratio, months of cover, card utilisation, the recurring bills it found with
720
+ their next due date, and a business-versus-personal split of all of it.
721
+
722
+ The business/personal split starts as a guess from the account name, which gets
723
+ "Business Checking (4672)" right and cannot see a personal card carrying company
724
+ spend. Correct it with `coinpay finances scope <account-id> business|personal`,
725
+ or `clear` to hand it back to the guess. The correction is stored separately from
726
+ the derived value, so a re-sync cannot clobber it, and corrected accounts carry a
727
+ trailing `*` in the `Side` column.
728
+
729
+ Two things about those numbers. Transfers and card payments are excluded from both
730
+ income and spending — a feed holding both a checking account and the card it pays
731
+ contains every card payment twice, so counting raw credits as income inflates both
732
+ sides by the whole card-payment volume. The untouched totals stay on screen as gross
733
+ credits and gross debits, so the netting is auditable. And the figures come from about
734
+ six months of history rather than the dashboard window (`w` does not move them), because
735
+ a monthly charge cannot be seen in thirty days of rows; the per-month averages divide by
736
+ the history that actually exists, which for a recently linked feed is much less than six
737
+ months.
738
+
739
+ It is built on [@profullstack/hqtui](https://hqtui.com) and needs Node 22.6+; the
740
+ plain-text subcommands work on Node 20. Bank data needs the merchant session from
741
+ `coinpay login` (business API keys are refused on purpose).
742
+
743
+ From the SDK:
744
+
745
+ ```js
746
+ import { CoinPayClient } from '@profullstack/coinpay';
747
+ import { collectFinanceSnapshot } from '@profullstack/coinpay/finances';
748
+
749
+ const client = new CoinPayClient({ apiKey: sessionToken });
750
+ const snapshot = await collectFinanceSnapshot(client, { days: 30 });
751
+ console.log(snapshot.earnings.netUsd, snapshot.bank.liabilities, snapshot.invoices.totals.overdue);
752
+ ```
753
+
656
754
  ---
657
755
 
658
756
  ## Webhook Integration
@@ -977,6 +1075,41 @@ Tests use [Vitest](https://vitest.dev/) with mocked `fetch` — no API key neede
977
1075
 
978
1076
  ---
979
1077
 
1078
+
1079
+ ## TaskMarket delegation (x402 v2)
1080
+
1081
+ `@profullstack/coinpay/taskmarket` lets an agent or user create and fund a
1082
+ [TaskMarket](https://taskmarket.dev) task from inside a CoinPay-powered app,
1083
+ using the standard x402 v2 transfer-authorization flow this SDK already speaks.
1084
+
1085
+ ```js
1086
+ import { createTask, discoverTasks, getTask, listSubmissions } from '@profullstack/coinpay/taskmarket';
1087
+
1088
+ // Browse open work (public endpoint)
1089
+ const open = await discoverTasks({ status: 'open', limit: 25, mode: 'bounty' });
1090
+
1091
+ // Create + fund a task. The wallet signs the EIP-712 transfer authorization
1092
+ // itself; this module never sees a private key.
1093
+ const { taskId } = await createTask(
1094
+ { title: 'Fix my parser bug', description: 'Repro + expected output attached in the linked issue.', reward: 2500000 },
1095
+ {
1096
+ signer: myWalletSigner, // { address, signTypedData({domain, types, primaryType, message}) }
1097
+ capabilities: ['eip155:8453'],
1098
+ spendingLimitUsd: 10, // hard cap; refuses anything above
1099
+ authorize: async (d) => confirm(`Send ${d.amount} ${d.asset} to ${d.payTo}?`),
1100
+ }
1101
+ );
1102
+
1103
+ // Track it and present submissions for human review (never auto-accept)
1104
+ const live = await getTask(taskId);
1105
+ const submissions = await listSubmissions(taskId);
1106
+ ```
1107
+
1108
+ Safety: no keys ever enter the module; every payment needs fresh `authorize()`
1109
+ consent; `spendingLimitUsd` is enforced against the quoted amount in base
1110
+ units; after a payment with unknown settlement the caller is told to verify
1111
+ with `getTask` instead of retrying blindly.
1112
+
980
1113
  ## License
981
1114
 
982
1115
  [MIT](./LICENSE) © Profullstack, Inc.