paytaca-cli 0.8.0 → 0.8.1

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/README.md CHANGED
@@ -4,7 +4,7 @@ A command-line interface for the Paytaca [Bitcoin Cash](https://bitcoincash.org)
4
4
 
5
5
  Bitcoin Cash is peer-to-peer electronic cash, enabling fast, low-fee transactions for everyday use. Paytaca CLI brings the full capabilities of the Paytaca wallet to the terminal — create wallets, derive addresses, send and receive BCH, manage CashTokens (fungible tokens and NFTs), swap tokens on the Cauldron DEX, pay x402 HTTP APIs, chat over Nostr, and view transaction history, all from the command line.
6
6
 
7
- Designed to be AI agent-friendly and useful for automation by power users. It ships an MCP server and a one-step installer for the Paytaca AI provider.
7
+ Designed to be AI agent-friendly and useful for automation by power users. It ships an MCP server, a one-step installer for the Paytaca AI provider, and a local web UI (`paytaca web`).
8
8
 
9
9
  ## Requirements
10
10
 
@@ -36,11 +36,15 @@ Most commands accept `--json` for machine-readable output and `--chipnet` to tar
36
36
  ```bash
37
37
  paytaca wallet create # Generate a new 12-word seed phrase
38
38
  paytaca wallet create --chipnet # Create on chipnet (testnet)
39
- paytaca wallet import # Import an existing seed phrase
39
+ paytaca wallet import # Import a seed phrase (12/15/18/21/24 words)
40
40
  paytaca wallet info # Show wallet hash, address, and balance
41
41
  paytaca wallet export # Display the stored seed phrase (interactive terminal + biometrics)
42
42
  ```
43
43
 
44
+ > `wallet import` accepts 12/15/18/21/24-word phrases separated by spaces or
45
+ > commas. Unknown words are rejected with the closest BIP39 suggestion, and the
46
+ > checksum is validated before the wallet is stored.
47
+
44
48
  > `wallet export` requires an interactive terminal and prompts for biometric
45
49
  > authentication (Touch ID, fingerprint, or Windows Hello) when available. It
46
50
  > cannot be used from scripts, pipes, or other non-interactive processes.
@@ -185,7 +189,7 @@ paytaca ai auto-refill --status # Inspect; also --disable, --delete
185
189
 
186
190
  `ai configure` accepts `--backend`, `--path`, `--api-key`, `--chipnet`, and `-y/--yes`. `ai purchase` and `ai auto-refill` accept `--lift` to pay with LIFT tokens at a discount. Add `--json` to any `ai` subcommand for machine-readable output.
187
191
 
188
- Armed auto-refill state lives at `~/.paytaca/auto-refill.json`. It runs inline — arming performs one immediate check (buying right away if the armed model has no credits), the `get_credits` MCP tool refills on demand, and the `paytaca mcp` server keeps a background backstop while a session is running. Each execution is appended to `~/.paytaca/auto-refill-events.jsonl` and the latest is reported as `lastEvent`. It disarms when the budget is spent, funds are short, or the plan is no longer offered. Use `--disable` to pause and `--delete` to remove the configuration (history is kept).
192
+ Armed auto-refill state lives at `~/.paytaca/auto-refill.json`. Arming performs one immediate check (buying right away if the armed model has no credits), and the `paytaca mcp` server keeps a background backstop (every 60s) while a session is running. The `get_credits` MCP tool is read-only and never triggers a purchase. Each execution is appended to `~/.paytaca/auto-refill-events.jsonl` and the latest is reported as `lastEvent`. It disarms when the budget is spent, funds are short, or the plan is no longer offered. Use `--disable` to pause and `--delete` to remove the configuration (history is kept).
189
193
 
190
194
  ### Image Generation
191
195
 
@@ -232,7 +236,7 @@ paytaca ai configure opencode --api-key sk-pytc-… # read-only wallet
232
236
 
233
237
  Read-only wallets report credits from the shared wallet hash but can't buy plans — fund credits from the full wallet.
234
238
 
235
- **MCP tools:** wallet reads (`get_balance`, `get_transactions`, `get_receiving_address`, `get_tokens`, `send`) plus Paytaca AI (`get_models`, `get_plans`, `get_credits`, `buy_plan`, `auto_refill`, `get_help`, `generate_image`, `get_image_status`, `get_image_models`, `get_image_history`).
239
+ **MCP tools:** wallet (`get_balance`, `get_transactions`, `get_receiving_address`, `get_tokens`, `send`) plus Paytaca AI (`get_models`, `get_plans`, `get_credits`, `buy_plan`, `auto_refill`, `get_help`, `generate_image`, `get_image_status`, `get_image_models`, `get_image_history`).
236
240
 
237
241
  Spending tools (`send`, `buy_plan`, `auto_refill`, `generate_image`) require host-level approval. By default MCP operates on your **main wallet** and can spend real funds.
238
242
 
@@ -271,6 +275,27 @@ paytaca chat remove-display-name # Remove published name
271
275
  paytaca chat remove-bch-address # Remove published address
272
276
  ```
273
277
 
278
+ ### Web UI
279
+
280
+ Launch a local browser UI for the wallet, Cauldron swaps, and Paytaca AI:
281
+
282
+ ```bash
283
+ paytaca web # Serve on http://127.0.0.1:7474 and open the browser
284
+ paytaca web --port 8080 # Use a custom port
285
+ paytaca web --chipnet # Mainnet by default; --chipnet targets testnet
286
+ paytaca web --backend <url> # Override the Paytaca AI backend URL
287
+ paytaca web --no-open # Do not auto-open the browser
288
+ ```
289
+
290
+ The server binds to `127.0.0.1` only. Access is gated by a random per-session token sent in the `X-Paytaca-Token` header; the browser is auto-opened with a session link that carries the token, and the page strips it from the address bar after loading. With `--no-open`, use the printed URL alongside the session link to open it manually.
291
+
292
+ The UI is organized into two tabs:
293
+
294
+ - **Wallet** — send and receive BCH, send CashTokens, swap on the Cauldron DEX, and review transaction history (date, type, counterparty, amount, USD value, fee, and explorer links), with token-category selection in the send and swap forms.
295
+ - **AI** — buy plans (BCH or a live LIFT quote), manage auto-refill (enable / pause / delete, with budget-cap validation), and browse generated images (gallery with lightbox, order history, and delete).
296
+
297
+ Incoming transactions are streamed live over a Watchtower WebSocket and surface as in-page notifications; a light/dark theme toggle is persisted in the browser.
298
+
274
299
  ## Network
275
300
 
276
301
  All commands default to **mainnet**. Pass `--chipnet` for testnet:
@@ -293,6 +318,8 @@ Powered by [@napi-rs/keyring](https://github.com/Brooooooklyn/keyring-node) (pre
293
318
 
294
319
  Nostr chat keys are **not** persisted — they are re-derived from the wallet mnemonic at runtime via HD path `m/44'/1237'/0'/0/0` and held only in memory for the duration of a session. Non-secret chat metadata (contacts, rooms, messages) is written to `~/.paytaca/chat-state.json` with mode `0600`; no key material is ever written there.
295
320
 
321
+ The `paytaca web` server listens on `127.0.0.1` only and requires a random per-session token in the `X-Paytaca-Token` header; requests whose `Host` header is not `127.0.0.1`/`localhost` are rejected, request bodies are capped at 1 MB, and internal error details are logged to stderr rather than returned to the client.
322
+
296
323
  ## Architecture
297
324
 
298
325
  ```
@@ -310,6 +337,7 @@ src/
310
337
  check.ts Check if URL requires x402 payment
311
338
  ai.ts Paytaca AI (configure, api-key, models, plans, credits, purchase, auto-refill, image)
312
339
  chat.ts Nostr chat (contacts, conversations, identity, listen)
340
+ web.ts `paytaca web` — local browser UI launcher
313
341
  mcp.ts `paytaca mcp` stdio entry + per-harness config templates
314
342
  update.ts Self-update from npm registry
315
343
  core/
@@ -318,6 +346,10 @@ src/
318
346
  mcp/
319
347
  server.ts MCP server construction and stdio lifecycle
320
348
  tools.ts MCP tool registration (wallet reads, send, Paytaca AI)
349
+ web/
350
+ server.ts Local HTTP server (token auth, JSON API routes)
351
+ page.ts Self-contained Alpine.js UI (wallet, swap, AI tabs)
352
+ assets.ts Inline asset loading (vendored Alpine.js, styles)
321
353
  wallet/
322
354
  index.ts Wallet class, mnemonic gen/import/load
323
355
  bch.ts BchWallet (balance, send, history, CashTokens)
@@ -364,6 +396,7 @@ src/
364
396
  | `@cashlab/cauldron` | Cauldron DEX swap building |
365
397
  | `@napi-rs/keyring` | OS-native keychain storage |
366
398
  | `@modelcontextprotocol/sdk` | MCP server (stdio) |
399
+ | `alpinejs` | Reactive web UI (`paytaca web`), vendored inline |
367
400
  | `bip39` | Mnemonic generation and validation |
368
401
  | `nostr-tools` | Nostr chat events, keys, and relay transport |
369
402
  | `js-sha256` | Hashing for key derivation and payment headers |
@@ -1 +1 @@
1
- {"version":3,"file":"page.d.ts","sourceRoot":"","sources":["../../src/web/page.ts"],"names":[],"mappings":"AAWA,wBAAgB,UAAU,IAAI,MAAM,CAqnBnC"}
1
+ {"version":3,"file":"page.d.ts","sourceRoot":"","sources":["../../src/web/page.ts"],"names":[],"mappings":"AAWA,wBAAgB,UAAU,IAAI,MAAM,CAsnBnC"}
package/dist/web/page.js CHANGED
@@ -586,8 +586,9 @@ refillModel:'',refillMinutes:'30',refillMax:'',refillPayMethod:'bch',refillEditi
586
586
  imgPrompt:'',imgModel:'bytedance-seed/seedream-5-0-pro',imgAspect:'1:1',imgQuality:'auto',
587
587
  toastVisible:false,toastMsg:'',toastOk:true,
588
588
  ws:null,wsStatus:'connecting',wsAddress:null,wsSeen:{},wsReconnectTimer:null,wsPingTimer:null,wsRefreshTimer:null,wsLateTimer:null,notify:null,_ntid:0,
589
- async init(){document.documentElement.setAttribute('data-theme',this.theme);try{this.state=await this.api('GET','/api/wallet/state');this.loadHistory(1);await this.onRcvChange();this.connectWatch()}catch(e){this.toast(e.message,true)}var self=this;document.addEventListener('visibilitychange',function(){if(document.visibilityState==='visible'&&self.state){if(!self.ws||self.ws.readyState!==1){if(self.wsReconnectTimer)clearTimeout(self.wsReconnectTimer);self.connectWatch()}}});window.addEventListener('online',function(){if(self.state){if(self.wsReconnectTimer)clearTimeout(self.wsReconnectTimer);self.connectWatch()}})},
590
- async load(){try{this.state=await this.api('GET','/api/wallet/state');this.onRcvChange();this.loadHistory(this.histPage);(this.state.imageHistory||[]).forEach(h=>{if(h.status==='completed'&&h.filepath)this.loadImage(h.id)})}catch(e){this.toast(e.message,true)}},
589
+ async init(){document.documentElement.setAttribute('data-theme',this.theme);try{this.state=await this.api('GET','/api/wallet/state');this.loadHistory(1);this.loadImages();await this.onRcvChange();this.connectWatch()}catch(e){this.toast(e.message,true)}var self=this;document.addEventListener('visibilitychange',function(){if(document.visibilityState==='visible'&&self.state){if(!self.ws||self.ws.readyState!==1){if(self.wsReconnectTimer)clearTimeout(self.wsReconnectTimer);self.connectWatch()}}});window.addEventListener('online',function(){if(self.state){if(self.wsReconnectTimer)clearTimeout(self.wsReconnectTimer);self.connectWatch()}})},
590
+ async load(){try{this.state=await this.api('GET','/api/wallet/state');this.onRcvChange();this.loadHistory(this.histPage);this.loadImages()}catch(e){this.toast(e.message,true)}},
591
+ loadImages(){var s=this;(this.state&&this.state.imageHistory||[]).forEach(function(h){if(h.status==='completed'&&h.filepath)s.loadImage(h.id)})},
591
592
  async loadImage(id){if(!id||this.imgUrls[id])return;try{var res=await fetch('/api/ai/images/'+id+'/file',{headers:{'X-Paytaca-Token':this.token}});if(!res.ok)return;var blob=await res.blob();this.imgUrls[id]=URL.createObjectURL(blob)}catch(e){}},
592
593
  async api(method,apipath,body){var opts={method:method,headers:{'X-Paytaca-Token':this.token,'Accept':'application/json'}};if(body!==undefined){opts.headers['Content-Type']='application/json';opts.body=JSON.stringify(body)}var res=await fetch(apipath,opts);if(!res.ok){var msg='Request failed ('+res.status+')';try{var j=await res.json();if(j.error)msg=j.error}catch(ex){}throw new Error(msg)}return res.json()},
593
594
  fmtDuration(s){if(!s||s<=0)return '0m';var h=Math.floor(s/3600),m=Math.floor((s%3600)/60);return h?h+'h '+m+'m':m+'m'},
@@ -1 +1 @@
1
- {"version":3,"file":"page.js","sourceRoot":"","sources":["../../src/web/page.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAE3D,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAA;AACjE,MAAM,SAAS,GAAG,EAAE,CAAC,YAAY,CAC/B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,uBAAuB,CAAC,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,EACvF,MAAM,CACP,CAAA;AAED,MAAM,UAAU,UAAU;IACxB,OAAO;;;;;;0CAMiC,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qCAsQjB,YAAY;;;;;;wGAMuD,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sCAuHjF,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gBAwOrC,SAAS;;QAEjB,CAAC;AACT,CAAC"}
1
+ {"version":3,"file":"page.js","sourceRoot":"","sources":["../../src/web/page.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAE3D,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAA;AACjE,MAAM,SAAS,GAAG,EAAE,CAAC,YAAY,CAC/B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,uBAAuB,CAAC,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,EACvF,MAAM,CACP,CAAA;AAED,MAAM,UAAU,UAAU;IACxB,OAAO;;;;;;0CAMiC,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qCAsQjB,YAAY;;;;;;wGAMuD,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sCAuHjF,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gBAyOrC,SAAS;;QAEjB,CAAC;AACT,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "paytaca-cli",
3
- "version": "0.8.0",
3
+ "version": "0.8.1",
4
4
  "description": "Command-line interface for the Paytaca Bitcoin Cash wallet",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",