paytaca-cli 0.6.1 → 0.7.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.
Files changed (130) hide show
  1. package/README.md +153 -37
  2. package/dist/ai/autoRefill.d.ts +27 -0
  3. package/dist/ai/autoRefill.d.ts.map +1 -0
  4. package/dist/ai/autoRefill.js +75 -0
  5. package/dist/ai/autoRefill.js.map +1 -0
  6. package/dist/ai/client.d.ts +73 -0
  7. package/dist/ai/client.d.ts.map +1 -0
  8. package/dist/ai/client.js +90 -0
  9. package/dist/ai/client.js.map +1 -0
  10. package/dist/ai/config.d.ts +7 -0
  11. package/dist/ai/config.d.ts.map +1 -0
  12. package/dist/ai/config.js +16 -0
  13. package/dist/ai/config.js.map +1 -0
  14. package/dist/ai/configure.d.ts +61 -0
  15. package/dist/ai/configure.d.ts.map +1 -0
  16. package/dist/ai/configure.js +452 -0
  17. package/dist/ai/configure.js.map +1 -0
  18. package/dist/ai/credits.d.ts +27 -0
  19. package/dist/ai/credits.d.ts.map +1 -0
  20. package/dist/ai/credits.js +99 -0
  21. package/dist/ai/credits.js.map +1 -0
  22. package/dist/ai/models.d.ts +13 -0
  23. package/dist/ai/models.d.ts.map +1 -0
  24. package/dist/ai/models.js +49 -0
  25. package/dist/ai/models.js.map +1 -0
  26. package/dist/ai/oauth.d.ts +45 -0
  27. package/dist/ai/oauth.d.ts.map +1 -0
  28. package/dist/ai/oauth.js +137 -0
  29. package/dist/ai/oauth.js.map +1 -0
  30. package/dist/ai/purchase.d.ts +30 -0
  31. package/dist/ai/purchase.d.ts.map +1 -0
  32. package/dist/ai/purchase.js +456 -0
  33. package/dist/ai/purchase.js.map +1 -0
  34. package/dist/commands/address.d.ts.map +1 -1
  35. package/dist/commands/address.js +88 -36
  36. package/dist/commands/address.js.map +1 -1
  37. package/dist/commands/ai.d.ts +9 -0
  38. package/dist/commands/ai.d.ts.map +1 -0
  39. package/dist/commands/ai.js +675 -0
  40. package/dist/commands/ai.js.map +1 -0
  41. package/dist/commands/balance.d.ts.map +1 -1
  42. package/dist/commands/balance.js +68 -129
  43. package/dist/commands/balance.js.map +1 -1
  44. package/dist/commands/history.d.ts.map +1 -1
  45. package/dist/commands/history.js +38 -78
  46. package/dist/commands/history.js.map +1 -1
  47. package/dist/commands/mcp.d.ts +14 -0
  48. package/dist/commands/mcp.d.ts.map +1 -0
  49. package/dist/commands/mcp.js +68 -0
  50. package/dist/commands/mcp.js.map +1 -0
  51. package/dist/commands/pay.js +1 -1
  52. package/dist/commands/pay.js.map +1 -1
  53. package/dist/commands/receive.d.ts +1 -8
  54. package/dist/commands/receive.d.ts.map +1 -1
  55. package/dist/commands/receive.js +51 -124
  56. package/dist/commands/receive.js.map +1 -1
  57. package/dist/commands/send.d.ts +0 -10
  58. package/dist/commands/send.d.ts.map +1 -1
  59. package/dist/commands/send.js +40 -50
  60. package/dist/commands/send.js.map +1 -1
  61. package/dist/commands/swap.js +1 -1
  62. package/dist/commands/swap.js.map +1 -1
  63. package/dist/commands/token.d.ts +1 -9
  64. package/dist/commands/token.d.ts.map +1 -1
  65. package/dist/commands/token.js +192 -289
  66. package/dist/commands/token.js.map +1 -1
  67. package/dist/core/context.d.ts +30 -0
  68. package/dist/core/context.d.ts.map +1 -0
  69. package/dist/core/context.js +45 -0
  70. package/dist/core/context.js.map +1 -0
  71. package/dist/core/wallet.d.ts +130 -0
  72. package/dist/core/wallet.d.ts.map +1 -0
  73. package/dist/core/wallet.js +276 -0
  74. package/dist/core/wallet.js.map +1 -0
  75. package/dist/index.js +4 -0
  76. package/dist/index.js.map +1 -1
  77. package/dist/mcp/server.d.ts +8 -0
  78. package/dist/mcp/server.d.ts.map +1 -0
  79. package/dist/mcp/server.js +24 -0
  80. package/dist/mcp/server.js.map +1 -0
  81. package/dist/mcp/tools.d.ts +5 -0
  82. package/dist/mcp/tools.d.ts.map +1 -0
  83. package/dist/mcp/tools.js +473 -0
  84. package/dist/mcp/tools.js.map +1 -0
  85. package/dist/utils/format.d.ts +23 -0
  86. package/dist/utils/format.d.ts.map +1 -0
  87. package/dist/utils/format.js +62 -0
  88. package/dist/utils/format.js.map +1 -0
  89. package/dist/utils/x402.js +1 -1
  90. package/dist/utils/x402.js.map +1 -1
  91. package/dist/wallet/index.d.ts +13 -0
  92. package/dist/wallet/index.d.ts.map +1 -1
  93. package/dist/wallet/index.js +18 -0
  94. package/dist/wallet/index.js.map +1 -1
  95. package/dist/wallet/keys.d.ts.map +1 -1
  96. package/dist/wallet/keys.js +2 -0
  97. package/dist/wallet/keys.js.map +1 -1
  98. package/package.json +7 -3
  99. package/dist/commands/wallet.test.d.ts +0 -2
  100. package/dist/commands/wallet.test.d.ts.map +0 -1
  101. package/dist/commands/wallet.test.js +0 -68
  102. package/dist/commands/wallet.test.js.map +0 -1
  103. package/dist/nostr/chat.test.d.ts +0 -2
  104. package/dist/nostr/chat.test.d.ts.map +0 -1
  105. package/dist/nostr/chat.test.js +0 -121
  106. package/dist/nostr/chat.test.js.map +0 -1
  107. package/dist/nostr/store.test.d.ts +0 -2
  108. package/dist/nostr/store.test.d.ts.map +0 -1
  109. package/dist/nostr/store.test.js +0 -456
  110. package/dist/nostr/store.test.js.map +0 -1
  111. package/dist/utils/prices.test.d.ts +0 -5
  112. package/dist/utils/prices.test.d.ts.map +0 -1
  113. package/dist/utils/prices.test.js +0 -62
  114. package/dist/utils/prices.test.js.map +0 -1
  115. package/dist/utils/x402.test.d.ts +0 -2
  116. package/dist/utils/x402.test.d.ts.map +0 -1
  117. package/dist/utils/x402.test.js +0 -216
  118. package/dist/utils/x402.test.js.map +0 -1
  119. package/dist/wallet/cauldron/pools.test.d.ts +0 -3
  120. package/dist/wallet/cauldron/pools.test.d.ts.map +0 -1
  121. package/dist/wallet/cauldron/pools.test.js +0 -149
  122. package/dist/wallet/cauldron/pools.test.js.map +0 -1
  123. package/dist/wallet/cauldron/swap.test.d.ts +0 -2
  124. package/dist/wallet/cauldron/swap.test.d.ts.map +0 -1
  125. package/dist/wallet/cauldron/swap.test.js +0 -179
  126. package/dist/wallet/cauldron/swap.test.js.map +0 -1
  127. package/skills/README.md +0 -68
  128. package/skills/paytaca-send/SKILL.md +0 -159
  129. package/skills/paytaca-wallet/SKILL.md +0 -164
  130. package/skills/paytaca-x402/SKILL.md +0 -130
package/README.md CHANGED
@@ -2,9 +2,9 @@
2
2
 
3
3
  A command-line interface for the Paytaca [Bitcoin Cash](https://bitcoincash.org) (BCH) wallet. Built with the same core logic as the [Paytaca mobile app](https://github.com/paytaca/paytaca-app), using [watchtower-cash-js](https://github.com/paytaca/watchtower-cash-js) for transaction operations and [libauth](https://github.com/bitauth/libauth) for HD key derivation.
4
4
 
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), and view transaction history, all from the command line.
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.
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.
8
8
 
9
9
  ## Requirements
10
10
 
@@ -29,6 +29,8 @@ After installing, the `paytaca` command is available globally.
29
29
 
30
30
  ## Commands
31
31
 
32
+ Most commands accept `--json` for machine-readable output and `--chipnet` to target testnet (see [Network](#network)). Run `paytaca <command> --help` for the full option list.
33
+
32
34
  ### Wallet
33
35
 
34
36
  ```bash
@@ -111,8 +113,11 @@ paytaca token info <category> # Token metadata, balance,
111
113
  paytaca token price <category> [amount] # USD price of a token and value of an amount (default: balance)
112
114
  paytaca token send <address> <amount> --token <cat> # Send fungible tokens
113
115
  paytaca token send-nft <address> --token <cat> --commitment <hex> # Send an NFT
116
+ paytaca token send-nft <address> --token <cat> --commitment '' --capability minting
114
117
  ```
115
118
 
119
+ `token send-nft` also accepts `--capability <none|minting|mutable>` (default `none`), and `--txid` / `--vout` to pin a specific NFT UTXO (auto-detected otherwise).
120
+
116
121
  ### Swap (Cauldron DEX)
117
122
 
118
123
  ```bash
@@ -122,58 +127,118 @@ paytaca swap <tokenId> <amount> --raw # Amount is in raw base units
122
127
  paytaca swap <tokenId> <amount> --yes # Skip the confirmation prompt
123
128
  ```
124
129
 
125
- The `--action` option is `sell` (token→BCH) or `buy` (BCH→token). Swaps run on mainnet only.
130
+ The `--action` option is `sell` (token→BCH) or `buy` (BCH→token). Swaps run on mainnet only; `--chipnet` is accepted but exits with an error.
126
131
 
127
132
  ### x402 Payments
128
133
 
129
- The x402 protocol enables HTTP payments via BCH. Some APIs (like nanogpt) require payment to access.
134
+ The x402 protocol enables HTTP payments via BCH. Some APIs require payment to access.
130
135
 
131
136
  ```bash
132
- paytaca check <url> # Check if URL requires payment, shows estimated cost
133
- paytaca pay <url> # Make a paid HTTP request (handles 402 automatically)
134
- paytaca pay <url> --json # JSON output (recommended for AI agents)
135
- paytaca pay <url> --dry-run # Preview payment without executing
136
- paytaca pay <url> --method POST # POST request with body
137
- paytaca pay <url> --body '{"prompt":"hello"}'
137
+ paytaca check <url> # Check if URL requires payment, shows estimated cost
138
+ paytaca check <url> -X POST -d '{}' # Check a POST endpoint (-X/--method, -H/--header, -d/--body)
139
+ paytaca pay <url> # Make a paid HTTP request (handles 402 automatically)
140
+ paytaca pay <url> --json # JSON output (recommended for AI agents)
141
+ paytaca pay <url> --dry-run # Preview payment without executing
142
+ paytaca pay <url> -X POST -d '{"prompt":"hello"}'
143
+ paytaca pay <url> --max-amount 500 # Cap payment in sats (overrides server max)
144
+ paytaca pay <url> --change-address <addr> # Custom change address
145
+ paytaca pay <url> --payer <value> # Payer identifier (defaults to wallet index 0)
146
+ paytaca pay <url> --confirmed # Skip the confirmation prompt
138
147
  ```
139
148
 
140
149
  **Example workflow:**
141
150
  ```bash
142
- paytaca check https://api.nanogpt.com/v1/complete --json
151
+ paytaca check https://api.example.com/v1/complete --json
143
152
  # → {"paymentRequired": true, "estimatedCostSats": "100"}
144
153
 
145
- paytaca pay https://api.nanogpt.com/v1/complete --method POST --body '{"prompt":"hello"}'
154
+ paytaca pay https://api.example.com/v1/complete --method POST --body '{"prompt":"hello"}'
146
155
  # → Handles 402 → pays → returns response
147
156
  ```
148
157
 
149
- ### AI Agent Integration
158
+ ### Paytaca AI
159
+
160
+ Paytaca AI is a pay-as-you-go model gateway paid with BCH or LIFT via x402. Manage it from the CLI:
161
+
162
+ ```bash
163
+ paytaca ai configure [harness] # Install MCP + AI provider (opencode is the default)
164
+ paytaca ai api-key create # Create a wallet-bound API key (shown once)
165
+ paytaca ai models # List available models
166
+ paytaca ai plans [model] # Plan pricing, optionally for a single model
167
+ paytaca ai credits [--model <id>] # Remaining time credits per model
168
+ paytaca ai usage # Per-session usage
169
+ paytaca ai balance # BCH + LIFT funds available for purchases
170
+ paytaca ai purchase --model <id> --minutes <n> # Buy a plan
171
+ paytaca ai purchase --model <id> --minutes 60 --lift # Pay with LIFT (discount)
172
+ paytaca ai auto-refill --enable --model <id> --minutes <n> --max-minutes <n>
173
+ paytaca ai auto-refill --status # Inspect; also --disable
174
+ ```
175
+
176
+ `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.
150
177
 
151
- Paytaca CLI provides AI agent skills for wallet operations. Install from GitHub (supports 45+ AI frameworks):
178
+ ### MCP Server
179
+
180
+ Configure an AI harness in one step. This installs the Paytaca MCP server and, for opencode, also the Paytaca AI provider (model catalogue + API key) so the Paytaca AI models are usable immediately:
152
181
 
153
182
  ```bash
154
- # Install specific skill
155
- npx skills add paytaca/paytaca-cli --skill <skill-name> -a <agent> -g
183
+ paytaca ai configure opencode # opencode | pi | omp
184
+ ```
156
185
 
157
- # Install all skills
158
- npx skills add paytaca/paytaca-cli --all
186
+ The command creates a wallet-bound API key against the Paytaca AI backend, writes the provider (base URL, models, key) and MCP server into the harness config, then checks your AI credits and offers to buy a plan when none are active.
159
187
 
160
- # Examples
161
- npx skills add paytaca/paytaca-cli --skill paytaca-x402 -a opencode -g
162
- npx skills add paytaca/paytaca-cli --skill paytaca-wallet -a claude-code -g
163
- npx skills add paytaca/paytaca-cli --skill paytaca-send -a openclaw -g
188
+ Re-running is idempotent: an existing provider API key is reused. Then run the server over stdio:
189
+
190
+ ```bash
191
+ paytaca mcp # mainnet
192
+ paytaca mcp --chipnet # default MCP tools to chipnet (testnet)
164
193
  ```
165
194
 
166
- **Available Skills:**
195
+ **Read-only wallets:** if the active wallet cannot sign (no seed phrase in the keychain), `ai configure` asks for an API key instead of creating one. Generate it from your full wallet and hand it over:
196
+
197
+ ```bash
198
+ paytaca ai api-key create # full wallet: prints sk-pytc-… once
199
+ paytaca ai configure opencode --api-key sk-pytc-… # read-only wallet
200
+ ```
167
201
 
168
- | Skill | Purpose | Approval Needed |
169
- |-------|---------|------------------|
170
- | `paytaca-x402` | HTTP 402 payment handling | Yes (before payment) |
171
- | `paytaca-wallet` | Balance, addresses, history, token info | No (read-only) |
172
- | `paytaca-send` | Send BCH and CashTokens | Yes (before sending) |
202
+ Read-only wallets report credits from the shared wallet hash but can't buy plans — fund credits from the full wallet.
173
203
 
174
- **Supported frameworks:** OpenCode, Claude Code, OpenClaw, Cursor, Cline, Windsurf, Roo, Gemini CLI, Codex, GitHub Copilot, Goose, Trae, Kiro CLI, and 30+ more.
204
+ **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`).
175
205
 
176
- See [skills/README.md](skills/README.md) for detailed skill documentation.
206
+ Spending tools (`send`, `buy_plan`, `auto_refill`) require host-level approval. By default MCP operates on your **main wallet** and can spend real funds.
207
+
208
+ When `get_credits` finds a model with no active session (e.g. after a `402` from the Paytaca AI provider), the result includes a `purchaseHint`. Relay `purchaseHint.message` as-is — it carries the exact copy-paste top-up command (no upsell or follow-up questions needed):
209
+
210
+ ```json
211
+ {
212
+ "modelId": "deepseek/deepseek-v4.1-flash",
213
+ "active": false,
214
+ "purchaseHint": {
215
+ "model": "deepseek/deepseek-v4.1-flash",
216
+ "minutes": 15,
217
+ "command": "paytaca ai purchase --model deepseek/deepseek-v4.1-flash --minutes 15",
218
+ "message": "To keep using DeepSeek V4.1 Flash, top up by running this in a terminal:\n\n paytaca ai purchase --model deepseek/deepseek-v4.1-flash --minutes 15\n\n(Switch models with `paytaca ai plans`.)"
219
+ }
220
+ }
221
+ ```
222
+
223
+ ### Nostr Chat
224
+
225
+ End-to-end encrypted Nostr chat keyed from the wallet mnemonic (HD path `m/44'/1237'/0'/0/0`; keys are derived in memory and never stored). Conversation metadata (contacts, rooms, messages) is persisted at `~/.paytaca/chat-state.json`.
226
+
227
+ ```bash
228
+ paytaca chat identity # Show your npub and pubkey
229
+ paytaca chat profile # Show display name and published BCH address
230
+ paytaca chat contacts # List saved contacts
231
+ paytaca chat add-contact <npub> [name] # Add a contact
232
+ paytaca chat start <npub> # Start a 1:1 conversation
233
+ paytaca chat list # List conversations
234
+ paytaca chat open <room-id> --tail 20 # Show recent messages (--tail, --json)
235
+ paytaca chat send <room-id> <text> # Send a message
236
+ paytaca chat listen [--contact <npub|name>] # Subscribe to new messages (long-running)
237
+ paytaca chat set-display-name <name> # Publish profile name to relays (NIP-78)
238
+ paytaca chat set-bch-address <address> # Publish a BCH address to relays (NIP-78)
239
+ paytaca chat remove-display-name # Remove published name
240
+ paytaca chat remove-bch-address # Remove published address
241
+ ```
177
242
 
178
243
  ## Network
179
244
 
@@ -195,6 +260,8 @@ Seed phrases are stored in the OS native keychain:
195
260
 
196
261
  Powered by [@napi-rs/keyring](https://github.com/Brooooooklyn/keyring-node) (prebuilt Rust binaries, no node-gyp required).
197
262
 
263
+ 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.
264
+
198
265
  ## Architecture
199
266
 
200
267
  ```
@@ -210,20 +277,49 @@ src/
210
277
  swap.ts Cauldron DEX swaps (sell/buy with --action)
211
278
  pay.ts x402 BCH payment handler for HTTP requests
212
279
  check.ts Check if URL requires x402 payment
280
+ ai.ts Paytaca AI (configure, api-key, models, plans, credits, purchase, auto-refill)
281
+ chat.ts Nostr chat (contacts, conversations, identity, listen)
282
+ mcp.ts `paytaca mcp` stdio entry + per-harness config templates
283
+ core/
284
+ context.ts Wallet context resolution (keychain + network), embed-safe
285
+ wallet.ts Render-agnostic wallet ops shared by CLI and MCP tools
286
+ mcp/
287
+ server.ts MCP server construction and stdio lifecycle
288
+ tools.ts MCP tool registration (wallet reads, send, Paytaca AI)
213
289
  wallet/
214
290
  index.ts Wallet class, mnemonic gen/import/load
215
291
  bch.ts BchWallet (balance, send, history, CashTokens)
216
292
  keys.ts LibauthHDWallet (HD key derivation, token addresses)
217
293
  x402.ts X402Payer (BCH payment signing and verification)
294
+ cauldron/
295
+ api.ts Cauldron (riften indexer) REST client
296
+ pools.ts Pool conversions and helpers
297
+ swap.ts Swap orchestration: quote estimation and execution
298
+ transact.ts Cauldron trade transaction building
218
299
  storage/
219
300
  keychain.ts OS keychain wrapper (@napi-rs/keyring)
220
301
  utils/
221
302
  crypto.ts pubkey -> CashAddress pipeline
303
+ format.ts Shared display/formatting helpers
222
304
  network.ts Watchtower URLs, derivation paths
223
305
  prices.ts Watchtower asset-prices client (USD per token/BCH)
224
306
  x402.ts x402 header parsing, payment requirement selection
225
307
  types/
226
308
  x402.ts x402 payment types (PaymentRequired, PaymentPayload, etc.)
309
+ ai/
310
+ client.ts Paytaca AI backend client (config, wallet status)
311
+ config.ts Backend URL, LIFT token id, ~/.paytaca paths
312
+ oauth.ts BCH OAuth challenge -> access token -> API key
313
+ models.ts Model catalogue, plan tiers, price/duration helpers
314
+ credits.ts Credit session lookup and summaries
315
+ purchase.ts Plan purchase via x402 (BCH or LIFT)
316
+ autoRefill.ts Auto-refill state and orchestration
317
+ configure.ts Harness setup (MCP + Paytaca AI provider + credits offer)
318
+ nostr/
319
+ keys.ts Nostr key derivation from wallet mnemonic (in memory)
320
+ chat.ts DM event building/signing (NIP-17 style)
321
+ relay.ts Relay connection/subscription service
322
+ store.ts Contact/room/message JSON store (~/.paytaca)
227
323
  ```
228
324
 
229
325
  ## Key Dependencies
@@ -232,35 +328,55 @@ src/
232
328
  |---------|---------|
233
329
  | `watchtower-cash-js` | UTXO fetching, tx building/signing/broadcasting |
234
330
  | `@bitauth/libauth` | HD key derivation (pinned to 2.0.0-alpha.8) |
331
+ | `@cashlab/cauldron` | Cauldron DEX swap building |
235
332
  | `@napi-rs/keyring` | OS-native keychain storage |
333
+ | `@modelcontextprotocol/sdk` | MCP server (stdio) |
236
334
  | `bip39` | Mnemonic generation and validation |
335
+ | `nostr-tools` | Nostr chat events, keys, and relay transport |
336
+ | `js-sha256` | Hashing for key derivation and payment headers |
237
337
  | `commander` | CLI framework |
238
338
  | `chalk` | Terminal colors |
239
339
  | `qrcode-terminal` | Terminal QR code rendering |
340
+ | `zod` | MCP tool input schemas |
240
341
 
241
342
  ## Development
242
343
 
243
344
  ```bash
244
345
  npm run dev # Watch mode (recompile on change)
245
- npm run build # One-time build
346
+ npm run build # One-time build (also type-checks)
347
+ npm test # Run the Vitest suite
246
348
  npm run clean # Remove dist/
247
349
  ```
248
350
 
351
+ There is no lint script; `npm run build` is the type-check. Tests live next to sources as `*.test.ts`.
352
+
249
353
  ## x402 Server
250
354
 
251
- A reference x402 server implementation is included for testing:
355
+ A reference x402 server accepting BCH (the `utxo` scheme) is included for testing:
252
356
 
253
357
  ```bash
254
358
  cd x402-server
255
359
  npm install
256
- npm run dev # Start dev server on port 3001
360
+ npm run dev # Start dev server on port 3000 (npm start to run once)
257
361
  ```
258
362
 
259
- The server implements the x402-bch v2.2 specification and provides:
260
- - `GET /api/quote` — Returns a quote (requires payment)
261
- - `POST /api/generate` Text generation endpoint (requires payment)
363
+ Configuration via environment variables:
364
+
365
+ | Variable | Description | Default |
366
+ |----------|-------------|---------|
367
+ | `PORT` | Server port | `3000` |
368
+ | `BCH_NETWORK` | `mainnet` or `chipnet` | `mainnet` |
369
+ | `RECEIVE_ADDRESS` | BCH address to receive payments | required for real payments |
370
+
371
+ The server exposes:
372
+
373
+ | Endpoint | Cost | Description |
374
+ |----------|------|-------------|
375
+ | `GET /api/quote` | 100 sats | Random inspirational quote |
376
+ | `GET /api/weather` | 50 sats | Fake weather data |
377
+ | `GET /api/status` | 1 sat | Server status |
262
378
 
263
- Useful for testing the `paytaca pay` workflow locally.
379
+ Useful for testing the `paytaca check` / `paytaca pay` workflow locally (see `x402-server/README.md` for the header-level protocol details).
264
380
 
265
381
  ## License
266
382
 
@@ -0,0 +1,27 @@
1
+ export type PaymentMethod = 'bch' | 'lift';
2
+ export interface AutoRefillState {
3
+ enabled: boolean;
4
+ model?: string;
5
+ minutes?: number;
6
+ maxMinutes?: number;
7
+ spentMinutes?: number;
8
+ paymentMethod?: PaymentMethod;
9
+ startedAt?: string;
10
+ lastRefillAt?: string;
11
+ }
12
+ export declare function readAutoRefillState(): AutoRefillState | null;
13
+ export declare function writeAutoRefillState(state: AutoRefillState): void;
14
+ export interface ArmAutoRefillOptions {
15
+ model?: string;
16
+ minutes?: number;
17
+ maxMinutes?: number;
18
+ paymentMethod?: PaymentMethod;
19
+ }
20
+ export declare function armAutoRefill(opts: ArmAutoRefillOptions): AutoRefillState;
21
+ export declare function disarmAutoRefill(): AutoRefillState;
22
+ export declare function remainingBudget(state: AutoRefillState | null): number | null;
23
+ export declare function autoRefillCanBuy(state: AutoRefillState | null, model: string, minutes: number): {
24
+ canBuy: boolean;
25
+ reason?: string;
26
+ };
27
+ //# sourceMappingURL=autoRefill.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"autoRefill.d.ts","sourceRoot":"","sources":["../../src/ai/autoRefill.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,MAAM,CAAA;AAE1C,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,aAAa,CAAC,EAAE,aAAa,CAAA;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,wBAAgB,mBAAmB,IAAI,eAAe,GAAG,IAAI,CAS5D;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAKjE;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,aAAa,CAAC,EAAE,aAAa,CAAA;CAC9B;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,oBAAoB,GAAG,eAAe,CAczE;AAED,wBAAgB,gBAAgB,IAAI,eAAe,CAQlD;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAG5E;AAED,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,eAAe,GAAG,IAAI,EAC7B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,GACd;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAwBtC"}
@@ -0,0 +1,75 @@
1
+ import fs from 'fs';
2
+ import { PAYTACA_DIR, AUTO_REFILL_FILE } from './config.js';
3
+ export function readAutoRefillState() {
4
+ try {
5
+ const raw = fs.readFileSync(AUTO_REFILL_FILE, 'utf8');
6
+ const parsed = JSON.parse(raw);
7
+ if (!parsed || typeof parsed !== 'object')
8
+ return null;
9
+ return parsed;
10
+ }
11
+ catch {
12
+ return null;
13
+ }
14
+ }
15
+ export function writeAutoRefillState(state) {
16
+ fs.mkdirSync(PAYTACA_DIR, { recursive: true, mode: 0o700 });
17
+ fs.writeFileSync(AUTO_REFILL_FILE, JSON.stringify(state, null, 2), {
18
+ mode: 0o600,
19
+ });
20
+ }
21
+ export function armAutoRefill(opts) {
22
+ const existing = readAutoRefillState();
23
+ const state = {
24
+ enabled: true,
25
+ model: opts.model ?? existing?.model,
26
+ minutes: opts.minutes ?? existing?.minutes,
27
+ maxMinutes: opts.maxMinutes ?? existing?.maxMinutes,
28
+ spentMinutes: existing?.spentMinutes ?? 0,
29
+ paymentMethod: opts.paymentMethod ?? existing?.paymentMethod ?? 'bch',
30
+ startedAt: new Date().toISOString(),
31
+ lastRefillAt: existing?.lastRefillAt,
32
+ };
33
+ writeAutoRefillState(state);
34
+ return state;
35
+ }
36
+ export function disarmAutoRefill() {
37
+ const existing = readAutoRefillState();
38
+ const state = {
39
+ ...(existing || {}),
40
+ enabled: false,
41
+ };
42
+ writeAutoRefillState(state);
43
+ return state;
44
+ }
45
+ export function remainingBudget(state) {
46
+ if (!state || state.maxMinutes === undefined)
47
+ return null;
48
+ return Math.max(0, state.maxMinutes - (state.spentMinutes ?? 0));
49
+ }
50
+ export function autoRefillCanBuy(state, model, minutes) {
51
+ if (!state || !state.enabled) {
52
+ return { canBuy: false, reason: 'Auto-refill is not enabled.' };
53
+ }
54
+ if (state.model && state.model !== model) {
55
+ return {
56
+ canBuy: false,
57
+ reason: `Auto-refill is armed for ${state.model}, not ${model}.`,
58
+ };
59
+ }
60
+ if (state.minutes && state.minutes !== minutes) {
61
+ return {
62
+ canBuy: false,
63
+ reason: `Auto-refill is armed for ${state.minutes}-minute plans, not ${minutes}.`,
64
+ };
65
+ }
66
+ const budget = remainingBudget(state);
67
+ if (budget !== null && budget < minutes) {
68
+ return {
69
+ canBuy: false,
70
+ reason: `Auto-refill budget exhausted (${budget} min left).`,
71
+ };
72
+ }
73
+ return { canBuy: true };
74
+ }
75
+ //# sourceMappingURL=autoRefill.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"autoRefill.js","sourceRoot":"","sources":["../../src/ai/autoRefill.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAA;AACnB,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAe3D,MAAM,UAAU,mBAAmB;IACjC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAA;QACrD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QAC9B,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAA;QACtD,OAAO,MAAyB,CAAA;IAClC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,KAAsB;IACzD,EAAE,CAAC,SAAS,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;IAC3D,EAAE,CAAC,aAAa,CAAC,gBAAgB,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;QACjE,IAAI,EAAE,KAAK;KACZ,CAAC,CAAA;AACJ,CAAC;AASD,MAAM,UAAU,aAAa,CAAC,IAA0B;IACtD,MAAM,QAAQ,GAAG,mBAAmB,EAAE,CAAA;IACtC,MAAM,KAAK,GAAoB;QAC7B,OAAO,EAAE,IAAI;QACb,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,QAAQ,EAAE,KAAK;QACpC,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,QAAQ,EAAE,OAAO;QAC1C,UAAU,EAAE,IAAI,CAAC,UAAU,IAAI,QAAQ,EAAE,UAAU;QACnD,YAAY,EAAE,QAAQ,EAAE,YAAY,IAAI,CAAC;QACzC,aAAa,EAAE,IAAI,CAAC,aAAa,IAAI,QAAQ,EAAE,aAAa,IAAI,KAAK;QACrE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,YAAY,EAAE,QAAQ,EAAE,YAAY;KACrC,CAAA;IACD,oBAAoB,CAAC,KAAK,CAAC,CAAA;IAC3B,OAAO,KAAK,CAAA;AACd,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC9B,MAAM,QAAQ,GAAG,mBAAmB,EAAE,CAAA;IACtC,MAAM,KAAK,GAAoB;QAC7B,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC;QACnB,OAAO,EAAE,KAAK;KACf,CAAA;IACD,oBAAoB,CAAC,KAAK,CAAC,CAAA;IAC3B,OAAO,KAAK,CAAA;AACd,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAA6B;IAC3D,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,UAAU,KAAK,SAAS;QAAE,OAAO,IAAI,CAAA;IACzD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,GAAG,CAAC,KAAK,CAAC,YAAY,IAAI,CAAC,CAAC,CAAC,CAAA;AAClE,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,KAA6B,EAC7B,KAAa,EACb,OAAe;IAEf,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;QAC7B,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,6BAA6B,EAAE,CAAA;IACjE,CAAC;IACD,IAAI,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,KAAK,KAAK,EAAE,CAAC;QACzC,OAAO;YACL,MAAM,EAAE,KAAK;YACb,MAAM,EAAE,4BAA4B,KAAK,CAAC,KAAK,SAAS,KAAK,GAAG;SACjE,CAAA;IACH,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,KAAK,OAAO,EAAE,CAAC;QAC/C,OAAO;YACL,MAAM,EAAE,KAAK;YACb,MAAM,EAAE,4BAA4B,KAAK,CAAC,OAAO,sBAAsB,OAAO,GAAG;SAClF,CAAA;IACH,CAAC;IACD,MAAM,MAAM,GAAG,eAAe,CAAC,KAAK,CAAC,CAAA;IACrC,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,GAAG,OAAO,EAAE,CAAC;QACxC,OAAO;YACL,MAAM,EAAE,KAAK;YACb,MAAM,EAAE,iCAAiC,MAAM,aAAa;SAC7D,CAAA;IACH,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAA;AACzB,CAAC"}
@@ -0,0 +1,73 @@
1
+ export interface PriceTier {
2
+ minutes: number;
3
+ price_usd?: number;
4
+ price_php?: number;
5
+ price_sats: number;
6
+ }
7
+ export interface AiModelConfig {
8
+ id: string;
9
+ display_name: string;
10
+ price_tiers: PriceTier[];
11
+ }
12
+ export interface AiConfig {
13
+ models: AiModelConfig[];
14
+ default_model?: string;
15
+ default_duration_minutes?: number;
16
+ context_retention_hours?: number;
17
+ lift_payment_discount_percent?: number;
18
+ proxy_url?: string;
19
+ image_models?: unknown[];
20
+ }
21
+ export interface WalletSession {
22
+ model_id?: string;
23
+ ai_model?: string;
24
+ display_name?: string;
25
+ model_active?: boolean;
26
+ session_active?: boolean;
27
+ time_credits_seconds?: number;
28
+ time_used_seconds?: number;
29
+ time_remaining_seconds?: number;
30
+ token_limit?: number;
31
+ }
32
+ export interface WalletStatus extends WalletSession {
33
+ sessions?: WalletSession[];
34
+ }
35
+ export interface ChatMessage {
36
+ role: 'system' | 'user' | 'assistant' | 'tool';
37
+ content: string;
38
+ }
39
+ export interface ChatResult {
40
+ ok: boolean;
41
+ status: number;
42
+ statusText: string;
43
+ headers: Record<string, string>;
44
+ data: any;
45
+ }
46
+ export declare class AiApiError extends Error {
47
+ status?: number;
48
+ body?: unknown;
49
+ constructor(message: string, status?: number, body?: unknown);
50
+ }
51
+ export interface RequestOptions {
52
+ backendUrl?: string;
53
+ headers?: Record<string, string>;
54
+ timeoutMs?: number;
55
+ signal?: AbortSignal;
56
+ }
57
+ export declare function getConfig(opts?: RequestOptions): Promise<AiConfig>;
58
+ export declare function getWalletStatus(walletHash: string, opts?: RequestOptions & {
59
+ modelId?: string;
60
+ }): Promise<WalletStatus>;
61
+ export interface ChatRequestOptions extends RequestOptions {
62
+ walletHash: string;
63
+ body: {
64
+ model?: string;
65
+ messages: ChatMessage[];
66
+ stream?: boolean;
67
+ temperature?: number;
68
+ max_tokens?: number;
69
+ [key: string]: unknown;
70
+ };
71
+ }
72
+ export declare function chatCompletions(opts: ChatRequestOptions): Promise<ChatResult>;
73
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/ai/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,90 @@
1
+ import { resolveBackendUrl, apiUrl } from './config.js';
2
+ export class AiApiError extends Error {
3
+ status;
4
+ body;
5
+ constructor(message, status, body) {
6
+ super(message);
7
+ this.name = 'AiApiError';
8
+ this.status = status;
9
+ this.body = body;
10
+ }
11
+ }
12
+ async function doFetch(url, init, timeoutMs) {
13
+ const signal = timeoutMs ? AbortSignal.timeout(timeoutMs) : undefined;
14
+ return fetch(url, { ...init, signal });
15
+ }
16
+ async function parseBody(response) {
17
+ const text = await response.text();
18
+ if (!text)
19
+ return null;
20
+ try {
21
+ return JSON.parse(text);
22
+ }
23
+ catch {
24
+ return text;
25
+ }
26
+ }
27
+ function headersToObject(headers) {
28
+ const out = {};
29
+ headers.forEach((value, key) => {
30
+ out[key] = value;
31
+ });
32
+ return out;
33
+ }
34
+ export async function getConfig(opts = {}) {
35
+ const base = resolveBackendUrl(opts.backendUrl);
36
+ let response;
37
+ try {
38
+ response = await doFetch(apiUrl(base, '/v1/config'), { method: 'GET', headers: opts.headers }, opts.timeoutMs ?? 15000);
39
+ }
40
+ catch (err) {
41
+ throw new AiApiError(`Backend unreachable: ${err?.message || err}`);
42
+ }
43
+ const body = await parseBody(response);
44
+ if (!response.ok) {
45
+ throw new AiApiError(`GET /v1/config failed (${response.status} ${response.statusText})`, response.status, body);
46
+ }
47
+ return body;
48
+ }
49
+ export async function getWalletStatus(walletHash, opts = {}) {
50
+ const base = resolveBackendUrl(opts.backendUrl);
51
+ const url = new URL(apiUrl(base, '/v1/wallet/status'));
52
+ if (opts.modelId)
53
+ url.searchParams.set('model_id', opts.modelId);
54
+ let response;
55
+ try {
56
+ response = await doFetch(url.toString(), {
57
+ method: 'GET',
58
+ headers: { 'X-Wallet-Hash': walletHash, ...(opts.headers || {}) },
59
+ }, opts.timeoutMs ?? 15000);
60
+ }
61
+ catch (err) {
62
+ throw new AiApiError(`Backend unreachable: ${err?.message || err}`);
63
+ }
64
+ const body = await parseBody(response);
65
+ if (!response.ok) {
66
+ throw new AiApiError(`GET /v1/wallet/status failed (${response.status} ${response.statusText})`, response.status, body);
67
+ }
68
+ return body;
69
+ }
70
+ export async function chatCompletions(opts) {
71
+ const base = resolveBackendUrl(opts.backendUrl);
72
+ const headers = {
73
+ 'Content-Type': 'application/json',
74
+ 'X-Wallet-Hash': opts.walletHash,
75
+ ...(opts.headers || {}),
76
+ };
77
+ const response = await doFetch(apiUrl(base, '/v1/chat/completions'), {
78
+ method: 'POST',
79
+ headers,
80
+ body: JSON.stringify({ stream: false, ...opts.body }),
81
+ }, opts.timeoutMs ?? 240000);
82
+ return {
83
+ ok: response.ok,
84
+ status: response.status,
85
+ statusText: response.statusText,
86
+ headers: headersToObject(response.headers),
87
+ data: await parseBody(response),
88
+ };
89
+ }
90
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/ai/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export declare const DEFAULT_BACKEND_URL = "https://api.paytaca.ai";
2
+ export declare const LIFT_TOKEN_ID = "5932b2fd4915d6a75d3ec53282cd49118149a2176ee67ed68b1111ff0786f7fc";
3
+ export declare const PAYTACA_DIR: string;
4
+ export declare const AUTO_REFILL_FILE: string;
5
+ export declare function resolveBackendUrl(explicit?: string): string;
6
+ export declare function apiUrl(baseUrl: string, apiPath: string): string;
7
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/ai/config.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,mBAAmB,2BAA2B,CAAA;AAE3D,eAAO,MAAM,aAAa,qEAC0C,CAAA;AAEpE,eAAO,MAAM,WAAW,QAAsC,CAAA;AAC9D,eAAO,MAAM,gBAAgB,QAA6C,CAAA;AAE1E,wBAAgB,iBAAiB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAG3D;AAED,wBAAgB,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAI/D"}
@@ -0,0 +1,16 @@
1
+ import os from 'os';
2
+ import path from 'path';
3
+ export const DEFAULT_BACKEND_URL = 'https://api.paytaca.ai';
4
+ export const LIFT_TOKEN_ID = '5932b2fd4915d6a75d3ec53282cd49118149a2176ee67ed68b1111ff0786f7fc';
5
+ export const PAYTACA_DIR = path.join(os.homedir(), '.paytaca');
6
+ export const AUTO_REFILL_FILE = path.join(PAYTACA_DIR, 'auto-refill.json');
7
+ export function resolveBackendUrl(explicit) {
8
+ const url = explicit || process.env.PAYTACA_BACKEND_URL || DEFAULT_BACKEND_URL;
9
+ return url.replace(/\/+$/, '');
10
+ }
11
+ export function apiUrl(baseUrl, apiPath) {
12
+ const normalized = baseUrl.replace(/\/+$/, '');
13
+ const suffix = apiPath.startsWith('/') ? apiPath : `/${apiPath}`;
14
+ return `${normalized}${suffix}`;
15
+ }
16
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/ai/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAA;AACnB,OAAO,IAAI,MAAM,MAAM,CAAA;AAEvB,MAAM,CAAC,MAAM,mBAAmB,GAAG,wBAAwB,CAAA;AAE3D,MAAM,CAAC,MAAM,aAAa,GACxB,kEAAkE,CAAA;AAEpE,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,UAAU,CAAC,CAAA;AAC9D,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,kBAAkB,CAAC,CAAA;AAE1E,MAAM,UAAU,iBAAiB,CAAC,QAAiB;IACjD,MAAM,GAAG,GAAG,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,mBAAmB,CAAA;IAC9E,OAAO,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;AAChC,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,OAAe,EAAE,OAAe;IACrD,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;IAC9C,MAAM,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,OAAO,EAAE,CAAA;IAChE,OAAO,GAAG,UAAU,GAAG,MAAM,EAAE,CAAA;AACjC,CAAC"}