@xona-labs/xpay 0.1.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 (143) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +226 -0
  3. package/dist/cli/accounts.d.ts +13 -0
  4. package/dist/cli/accounts.d.ts.map +1 -0
  5. package/dist/cli/accounts.js +66 -0
  6. package/dist/cli/accounts.js.map +1 -0
  7. package/dist/cli/balance.d.ts +14 -0
  8. package/dist/cli/balance.d.ts.map +1 -0
  9. package/dist/cli/balance.js +60 -0
  10. package/dist/cli/balance.js.map +1 -0
  11. package/dist/cli/common.d.ts +20 -0
  12. package/dist/cli/common.d.ts.map +1 -0
  13. package/dist/cli/common.js +58 -0
  14. package/dist/cli/common.js.map +1 -0
  15. package/dist/cli/discover.d.ts +12 -0
  16. package/dist/cli/discover.d.ts.map +1 -0
  17. package/dist/cli/discover.js +69 -0
  18. package/dist/cli/discover.js.map +1 -0
  19. package/dist/cli/guardrail.d.ts +16 -0
  20. package/dist/cli/guardrail.d.ts.map +1 -0
  21. package/dist/cli/guardrail.js +71 -0
  22. package/dist/cli/guardrail.js.map +1 -0
  23. package/dist/cli/history.d.ts +16 -0
  24. package/dist/cli/history.d.ts.map +1 -0
  25. package/dist/cli/history.js +59 -0
  26. package/dist/cli/history.js.map +1 -0
  27. package/dist/cli/index.d.ts +17 -0
  28. package/dist/cli/index.d.ts.map +1 -0
  29. package/dist/cli/index.js +165 -0
  30. package/dist/cli/index.js.map +1 -0
  31. package/dist/cli/init.d.ts +23 -0
  32. package/dist/cli/init.d.ts.map +1 -0
  33. package/dist/cli/init.js +114 -0
  34. package/dist/cli/init.js.map +1 -0
  35. package/dist/cli/mcp-server.d.ts +26 -0
  36. package/dist/cli/mcp-server.d.ts.map +1 -0
  37. package/dist/cli/mcp-server.js +112 -0
  38. package/dist/cli/mcp-server.js.map +1 -0
  39. package/dist/cli/pay.d.ts +15 -0
  40. package/dist/cli/pay.d.ts.map +1 -0
  41. package/dist/cli/pay.js +76 -0
  42. package/dist/cli/pay.js.map +1 -0
  43. package/dist/cli/transfer.d.ts +19 -0
  44. package/dist/cli/transfer.d.ts.map +1 -0
  45. package/dist/cli/transfer.js +66 -0
  46. package/dist/cli/transfer.js.map +1 -0
  47. package/dist/discover/cache.d.ts +24 -0
  48. package/dist/discover/cache.d.ts.map +1 -0
  49. package/dist/discover/cache.js +94 -0
  50. package/dist/discover/cache.js.map +1 -0
  51. package/dist/discover/index.d.ts +21 -0
  52. package/dist/discover/index.d.ts.map +1 -0
  53. package/dist/discover/index.js +88 -0
  54. package/dist/discover/index.js.map +1 -0
  55. package/dist/discover/payai.d.ts +18 -0
  56. package/dist/discover/payai.d.ts.map +1 -0
  57. package/dist/discover/payai.js +56 -0
  58. package/dist/discover/payai.js.map +1 -0
  59. package/dist/do/index.d.ts +17 -0
  60. package/dist/do/index.d.ts.map +1 -0
  61. package/dist/do/index.js +32 -0
  62. package/dist/do/index.js.map +1 -0
  63. package/dist/guardrail/index.d.ts +47 -0
  64. package/dist/guardrail/index.d.ts.map +1 -0
  65. package/dist/guardrail/index.js +99 -0
  66. package/dist/guardrail/index.js.map +1 -0
  67. package/dist/history/evm.d.ts +21 -0
  68. package/dist/history/evm.d.ts.map +1 -0
  69. package/dist/history/evm.js +118 -0
  70. package/dist/history/evm.js.map +1 -0
  71. package/dist/history/index.d.ts +19 -0
  72. package/dist/history/index.d.ts.map +1 -0
  73. package/dist/history/index.js +45 -0
  74. package/dist/history/index.js.map +1 -0
  75. package/dist/history/solana.d.ts +20 -0
  76. package/dist/history/solana.d.ts.map +1 -0
  77. package/dist/history/solana.js +97 -0
  78. package/dist/history/solana.js.map +1 -0
  79. package/dist/history/types.d.ts +26 -0
  80. package/dist/history/types.d.ts.map +1 -0
  81. package/dist/history/types.js +10 -0
  82. package/dist/history/types.js.map +1 -0
  83. package/dist/index.d.ts +94 -0
  84. package/dist/index.d.ts.map +1 -0
  85. package/dist/index.js +74 -0
  86. package/dist/index.js.map +1 -0
  87. package/dist/profile/derive.d.ts +28 -0
  88. package/dist/profile/derive.d.ts.map +1 -0
  89. package/dist/profile/derive.js +75 -0
  90. package/dist/profile/derive.js.map +1 -0
  91. package/dist/profile/index.d.ts +74 -0
  92. package/dist/profile/index.d.ts.map +1 -0
  93. package/dist/profile/index.js +115 -0
  94. package/dist/profile/index.js.map +1 -0
  95. package/dist/profile/storage.d.ts +35 -0
  96. package/dist/profile/storage.d.ts.map +1 -0
  97. package/dist/profile/storage.js +162 -0
  98. package/dist/profile/storage.js.map +1 -0
  99. package/dist/profile/types.d.ts +69 -0
  100. package/dist/profile/types.d.ts.map +1 -0
  101. package/dist/profile/types.js +9 -0
  102. package/dist/profile/types.js.map +1 -0
  103. package/dist/signers/index.d.ts +5 -0
  104. package/dist/signers/index.d.ts.map +1 -0
  105. package/dist/signers/index.js +5 -0
  106. package/dist/signers/index.js.map +1 -0
  107. package/dist/signers/phantom.d.ts +14 -0
  108. package/dist/signers/phantom.d.ts.map +1 -0
  109. package/dist/signers/phantom.js +12 -0
  110. package/dist/signers/phantom.js.map +1 -0
  111. package/dist/signers/privy.d.ts +20 -0
  112. package/dist/signers/privy.d.ts.map +1 -0
  113. package/dist/signers/privy.js +15 -0
  114. package/dist/signers/privy.js.map +1 -0
  115. package/dist/signers/raw-evm.d.ts +15 -0
  116. package/dist/signers/raw-evm.d.ts.map +1 -0
  117. package/dist/signers/raw-evm.js +70 -0
  118. package/dist/signers/raw-evm.js.map +1 -0
  119. package/dist/signers/raw-solana.d.ts +15 -0
  120. package/dist/signers/raw-solana.d.ts.map +1 -0
  121. package/dist/signers/raw-solana.js +88 -0
  122. package/dist/signers/raw-solana.js.map +1 -0
  123. package/dist/tools/index.d.ts +48 -0
  124. package/dist/tools/index.d.ts.map +1 -0
  125. package/dist/tools/index.js +164 -0
  126. package/dist/tools/index.js.map +1 -0
  127. package/dist/transfer/index.d.ts +30 -0
  128. package/dist/transfer/index.d.ts.map +1 -0
  129. package/dist/transfer/index.js +86 -0
  130. package/dist/transfer/index.js.map +1 -0
  131. package/dist/types.d.ts +203 -0
  132. package/dist/types.d.ts.map +1 -0
  133. package/dist/types.js +56 -0
  134. package/dist/types.js.map +1 -0
  135. package/dist/use/index.d.ts +38 -0
  136. package/dist/use/index.d.ts.map +1 -0
  137. package/dist/use/index.js +173 -0
  138. package/dist/use/index.js.map +1 -0
  139. package/dist/wallet/index.d.ts +31 -0
  140. package/dist/wallet/index.d.ts.map +1 -0
  141. package/dist/wallet/index.js +56 -0
  142. package/dist/wallet/index.js.map +1 -0
  143. package/package.json +70 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 xona-labs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,226 @@
1
+ # @xona-labs/xpay
2
+
3
+ > **Agentic-commerce wallet.** Multi-network USDC wallet, x402 payments, and discovery across 20,000+ services — as a CLI, an SDK, and an MCP server.
4
+
5
+ ```bash
6
+ npm install -g @xona-labs/xpay
7
+ xpay init # creates Solana + EVM keys, encrypted
8
+ xpay discover "research API" # 21k catalog, ranked
9
+ xpay pay https://api.example.com/x402 # x402 one-liner
10
+ xpay transfer 5 USDC 7G73PL...gC # direct USDC transfer
11
+ xpay balance # unified across networks
12
+ xpay history # recent activity, on-chain
13
+ ```
14
+
15
+ ```ts
16
+ // SDK — same primitives, programmatic
17
+ import { loadProfile, createXPay } from "@xona-labs/xpay";
18
+ const xpay = createXPay({ profile: await loadProfile({ passphrase }) });
19
+ const result = await xpay.do("translate this PDF to Japanese", { body: { file } });
20
+ ```
21
+
22
+ xPay is the **wallet** and **rail** layer for agentic commerce. It hides x402, USDC, RPC, and multi-network routing behind a flat surface so agent builders (Claude / Codex / OpenAI / Gemini / your own) can find and pay for services without writing payment plumbing.
23
+
24
+ ---
25
+
26
+ ## Install
27
+
28
+ ```bash
29
+ npm install -g @xona-labs/xpay # CLI + MCP server, system-wide
30
+ npm install @xona-labs/xpay # programmatic SDK in a project
31
+ ```
32
+
33
+ ## Quickstart
34
+
35
+ ```bash
36
+ xpay init
37
+ # ✔ Profile "default" created at /Users/you/.xpay/default
38
+ # Solana 7RB7frdxPc9vZtuyq6YfNoWTJcDZsE2AcXXV6qkpf5ph
39
+ # EVM 0xA5D93CDB2bD16b2d1d3d19D45dad3FaBb1023dfa
40
+ # ⚠ RECOVERY PHRASE — write this down NOW. We cannot recover it for you.
41
+ # 1. depend 2. guess 3. mercy 4. online
42
+ # ... (24 words)
43
+ ```
44
+
45
+ Fund the addresses with a few dollars of USDC on Solana mainnet, Base, or both. Then:
46
+
47
+ ```bash
48
+ xpay balance
49
+ xpay discover "image generation"
50
+ xpay pay https://orbisapi.com/proxy/image-alt-text-generator-api-1c9472
51
+ ```
52
+
53
+ ## CLI commands
54
+
55
+ | Command | What it does |
56
+ |---|---|
57
+ | `xpay init [name]` | Create a profile (Solana + EVM keys from one BIP-39 seed). `--import` to restore from a phrase, `--no-encrypt` for dev wallets, `--workspace` to store locally. |
58
+ | `xpay accounts list \| show \| use` | List profiles, inspect one, or set the active profile. |
59
+ | `xpay balance` | USDC balance per network for the active profile. |
60
+ | `xpay discover [query]` | Search 21k+ x402 services from PayAI (cached on disk). `--network`, `--limit`, `--json`. |
61
+ | `xpay pay <url>` | Pay an x402 endpoint. Works on catalog URLs and any URL that returns 402. `--max-usd`, `--body`, `-y`. |
62
+ | `xpay transfer <amount> USDC <to>` | Direct USDC transfer, subject to the guardrail. `--network`, `-y`. |
63
+ | `xpay history` | Recent on-chain USDC activity across all networks. `--network`, `--limit`, `--evm-window`. |
64
+ | `xpay guardrail show \| set \| clear` | Inspect or edit spending caps and allowed hosts. |
65
+ | `xpay mcp` | Start the MCP server on stdio (for Claude Desktop / Cursor / Codex). |
66
+
67
+ All commands run from a single profile. Switch with `xpay accounts use <name>`.
68
+
69
+ ## SDK
70
+
71
+ The CLI is a thin shell over the SDK — every command has a direct programmatic equivalent.
72
+
73
+ ```ts
74
+ import {
75
+ createXPay,
76
+ initProfile,
77
+ loadProfile,
78
+ setProfileGuardrail,
79
+ } from "@xona-labs/xpay";
80
+
81
+ // One-time setup
82
+ const created = await initProfile({
83
+ name: "default",
84
+ passphrase: process.env.XPAY_PASSPHRASE!,
85
+ });
86
+ console.log(created.addresses); // { solana, evm }
87
+ console.log(created.mnemonic); // back this up; not persisted in plaintext
88
+
89
+ // Configure spending caps
90
+ setProfileGuardrail("default", {
91
+ maxPerTx: 0.5,
92
+ maxPerDay: 5,
93
+ allowedHosts: ["api.payai.network", "*.xona.xyz"],
94
+ });
95
+
96
+ // Use
97
+ const profile = await loadProfile({ name: "default", passphrase: process.env.XPAY_PASSPHRASE });
98
+ const xpay = createXPay({ profile });
99
+
100
+ await xpay.discover({ query: "weather" });
101
+ await xpay.useByUrl("https://...");
102
+ await xpay.do("translate this PDF to Japanese");
103
+ await xpay.transfer({ amount: 1, to: "7G73PL...", token: "USDC" });
104
+ await xpay.history({ limit: 10 });
105
+ await xpay.wallet.balance("solana");
106
+ ```
107
+
108
+ ### Agent runtimes
109
+
110
+ xPay ships tool definitions for the three major LLM SDKs. Same handlers, different schema shapes.
111
+
112
+ ```ts
113
+ import Anthropic from "@anthropic-ai/sdk";
114
+ import { createXPay, forClaude, loadProfile } from "@xona-labs/xpay";
115
+
116
+ const xpay = createXPay({ profile: await loadProfile({ passphrase }) });
117
+ const { tools, handlers } = forClaude(xpay);
118
+
119
+ const response = await new Anthropic().messages.create({
120
+ model: "claude-sonnet-4-5",
121
+ tools,
122
+ messages: [{ role: "user", content: "find a cheap weather API and call it" }],
123
+ });
124
+
125
+ for (const block of response.content) {
126
+ if (block.type === "tool_use") {
127
+ const result = await handlers[block.name]!(block.input as Record<string, unknown>);
128
+ // ... feed result back to Claude
129
+ }
130
+ }
131
+ ```
132
+
133
+ `forOpenAI(xpay)` and `forGemini(xpay)` return the same handlers wrapped in vendor-specific schemas. See [`examples/claude-agent.ts`](./examples/claude-agent.ts) for the full tool-use loop.
134
+
135
+ ## MCP server (Claude Desktop / Cursor / Codex)
136
+
137
+ Drop xPay into any MCP host's config — no code changes on the agent side.
138
+
139
+ ```jsonc
140
+ // ~/Library/Application Support/Claude/claude_desktop_config.json
141
+ {
142
+ "mcpServers": {
143
+ "xpay": {
144
+ "command": "npx",
145
+ "args": ["-y", "@xona-labs/xpay", "mcp"],
146
+ "env": {
147
+ "XPAY_PASSPHRASE": "<your-passphrase>"
148
+ }
149
+ }
150
+ }
151
+ }
152
+ ```
153
+
154
+ The host then sees seven tools: `xpay_discover`, `xpay_use`, `xpay_do`, `xpay_transfer`, `xpay_balance`, `xpay_history`, `xpay_guardrail`. The server reads the same `~/.xpay/<profile>/` you created with `xpay init`.
155
+
156
+ ## Profiles
157
+
158
+ Each profile is a directory under `~/.xpay/` with:
159
+
160
+ ```
161
+ ~/.xpay/
162
+ ├── default/ (or any name)
163
+ │ ├── wallet.json BIP-39 seed, AES-256-GCM encrypted by default
164
+ │ └── config.json networks, guardrail, RPC overrides, link
165
+ └── cache/ disk cache of catalogs (auto-managed)
166
+ ```
167
+
168
+ Override with `XPAY_HOME=/some/path` or `xpay init --workspace` for project-local profiles.
169
+
170
+ ## Guardrail
171
+
172
+ The guardrail runs **before** any signer is touched, so a misbehaving agent (or compromised LLM) cannot bypass it.
173
+
174
+ ```bash
175
+ xpay guardrail set \
176
+ --max-per-tx 0.5 \
177
+ --max-per-day 5 \
178
+ --require-approval-above 1 \
179
+ --allowed-hosts 'api.payai.network,*.xona.xyz'
180
+ ```
181
+
182
+ - **`maxPerTx` / `maxPerDay`** — apply to every paid call *and* direct transfers.
183
+ - **`allowedHosts`** — apply only to x402 calls (transfers go to addresses, not hosts).
184
+ - **`requireApprovalAbove`** — calls ≥ threshold call your `onApprovalRequired` hook (SDK only — wire to a push notification, biometric prompt, or webhook).
185
+
186
+ ## Multi-network
187
+
188
+ `init` configures Solana and Base by default. Add or change via `~/.xpay/<name>/config.json`:
189
+
190
+ ```json
191
+ {
192
+ "version": 1,
193
+ "networks": ["solana", "base", "arbitrum"],
194
+ "defaultNetwork": "solana",
195
+ "rpcs": {
196
+ "solana": "https://your-helius-endpoint",
197
+ "base": "https://your-alchemy-endpoint"
198
+ }
199
+ }
200
+ ```
201
+
202
+ Public RPCs work for development but rate-limit hard. Production deployments should configure dedicated RPC endpoints.
203
+
204
+ ## How it works
205
+
206
+ - **Keys** — One BIP-39 mnemonic per profile derives Solana (`m/44'/501'/0'/0'`, Phantom-compatible) and EVM (`m/44'/60'/0'/0/0`, MetaMask-compatible) keypairs. Encrypted at rest with scrypt + AES-256-GCM.
207
+ - **Discovery** — PayAI's `/discovery/resources` is the primary catalog (21k+ x402 endpoints). The fetcher walks the offset-pagination, validates each entry against a Zod schema, and persists to `~/.xpay/cache/` for 10 min so CLI invocations don't pay the ~30s cold-fetch tax repeatedly.
208
+ - **Pay** — `use()` and `useByUrl()` both go: guardrail check → signer.pay(USDC) on the right network → `X-Payment` header → retry. The signer abstraction means the same code path works for Solana SPL transfers and EVM ERC-20 transfers.
209
+ - **History** — Solana via `getSignaturesForAddress` + `getParsedTransaction` on the USDC ATA. EVM via chunked `eth_getLogs` for ERC-20 `Transfer` events. No indexer required.
210
+
211
+ ## Project status
212
+
213
+ **v0.1 (current):**
214
+ - ✅ CLI: init, accounts, balance, discover, pay, transfer, history, guardrail, mcp
215
+ - ✅ SDK: full parity with CLI; tool exporters for Claude / OpenAI / Gemini
216
+ - ✅ MCP server on stdio with 7 tools
217
+ - ✅ Solana + Base mainnet with disk caching
218
+
219
+ **v0.2 planned:**
220
+ - `bridge` — USDC EVM ↔ SVM via CCTP (Circle's native burn/mint)
221
+ - `link / unlink` — opt-in cloud sync (audit log, dashboard)
222
+ - Pay catalog + xona-labs catalog as additional discovery sources
223
+
224
+ ## License
225
+
226
+ MIT — see [LICENSE](./LICENSE).
@@ -0,0 +1,13 @@
1
+ /**
2
+ * `xpay accounts` — multi-profile management.
3
+ *
4
+ * xpay accounts list list known profiles
5
+ * xpay accounts show [name] show addresses for a profile
6
+ * xpay accounts use <name> set the default profile (via ~/.xpay/active)
7
+ */
8
+ export declare function getActiveProfile(): string;
9
+ export declare function setActiveProfile(name: string): void;
10
+ export declare function runAccountsList(): void;
11
+ export declare function runAccountsShow(name?: string): void;
12
+ export declare function runAccountsUse(name: string): void;
13
+ //# sourceMappingURL=accounts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accounts.d.ts","sourceRoot":"","sources":["../../src/cli/accounts.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAeH,wBAAgB,gBAAgB,IAAI,MAAM,CAIzC;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAKnD;AAED,wBAAgB,eAAe,IAAI,IAAI,CAetC;AAED,wBAAgB,eAAe,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAanD;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAQjD"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * `xpay accounts` — multi-profile management.
3
+ *
4
+ * xpay accounts list list known profiles
5
+ * xpay accounts show [name] show addresses for a profile
6
+ * xpay accounts use <name> set the default profile (via ~/.xpay/active)
7
+ */
8
+ import chalk from "chalk";
9
+ import { existsSync, readFileSync, writeFileSync } from "node:fs";
10
+ import { join } from "node:path";
11
+ import { listProfiles, profilePath, profileExists, xpayHome, } from "../profile/storage.js";
12
+ import { readWalletFile } from "../profile/storage.js";
13
+ const ACTIVE_FILE = "active";
14
+ export function getActiveProfile() {
15
+ const file = join(xpayHome(), ACTIVE_FILE);
16
+ if (existsSync(file))
17
+ return readFileSync(file, "utf8").trim() || "default";
18
+ return "default";
19
+ }
20
+ export function setActiveProfile(name) {
21
+ if (!profileExists(name)) {
22
+ throw new Error(`Profile "${name}" does not exist.`);
23
+ }
24
+ writeFileSync(join(xpayHome(), ACTIVE_FILE), name);
25
+ }
26
+ export function runAccountsList() {
27
+ const profiles = listProfiles();
28
+ if (profiles.length === 0) {
29
+ console.log(chalk.yellow("No profiles yet. Run `xpay init` to create one."));
30
+ return;
31
+ }
32
+ const active = getActiveProfile();
33
+ for (const name of profiles) {
34
+ const marker = name === active ? chalk.green("●") : chalk.dim("○");
35
+ const wallet = readWalletFile(profilePath(name));
36
+ const encrypted = wallet.encrypted ? chalk.dim("(encrypted)") : chalk.red.dim("(unencrypted)");
37
+ console.log(` ${marker} ${chalk.bold(name)} ${encrypted}`);
38
+ console.log(` Solana ${chalk.cyan(wallet.addresses.solana)}`);
39
+ console.log(` EVM ${chalk.cyan(wallet.addresses.evm)}`);
40
+ }
41
+ }
42
+ export function runAccountsShow(name) {
43
+ const target = name ?? getActiveProfile();
44
+ if (!profileExists(target)) {
45
+ console.error(chalk.red(`✗ Profile "${target}" not found.`));
46
+ process.exit(1);
47
+ }
48
+ const wallet = readWalletFile(profilePath(target));
49
+ console.log(chalk.bold(`Profile "${target}"`));
50
+ console.log(` Path: ${profilePath(target)}`);
51
+ console.log(` Encrypted: ${wallet.encrypted ? "yes" : chalk.red("no")}`);
52
+ console.log(` Created: ${wallet.createdAt}`);
53
+ console.log(` Solana: ${chalk.cyan(wallet.addresses.solana)}`);
54
+ console.log(` EVM: ${chalk.cyan(wallet.addresses.evm)}`);
55
+ }
56
+ export function runAccountsUse(name) {
57
+ try {
58
+ setActiveProfile(name);
59
+ console.log(chalk.green(`✔ Active profile set to "${name}"`));
60
+ }
61
+ catch (err) {
62
+ console.error(chalk.red(`✗ ${err.message}`));
63
+ process.exit(1);
64
+ }
65
+ }
66
+ //# sourceMappingURL=accounts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accounts.js","sourceRoot":"","sources":["../../src/cli/accounts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * `xpay balance` — show USDC balance per network for the active profile.
3
+ *
4
+ * Unlocks the active profile (prompts for passphrase if encrypted, unless
5
+ * $XPAY_PASSPHRASE is set for non-interactive use), then queries each
6
+ * configured network's USDC balance.
7
+ */
8
+ export interface BalanceCmdOptions {
9
+ profile?: string;
10
+ network?: string;
11
+ passphrase?: string;
12
+ }
13
+ export declare function runBalance(opts: BalanceCmdOptions): Promise<void>;
14
+ //# sourceMappingURL=balance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"balance.d.ts","sourceRoot":"","sources":["../../src/cli/balance.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAUH,MAAM,WAAW,iBAAiB;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAqDvE"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * `xpay balance` — show USDC balance per network for the active profile.
3
+ *
4
+ * Unlocks the active profile (prompts for passphrase if encrypted, unless
5
+ * $XPAY_PASSPHRASE is set for non-interactive use), then queries each
6
+ * configured network's USDC balance.
7
+ */
8
+ import chalk from "chalk";
9
+ import inquirer from "inquirer";
10
+ import { loadProfile, signersFromProfile } from "../profile/index.js";
11
+ import { profileExists } from "../profile/storage.js";
12
+ import { readWalletFile } from "../profile/storage.js";
13
+ import { profilePath } from "../profile/storage.js";
14
+ import { getActiveProfile } from "./accounts.js";
15
+ export async function runBalance(opts) {
16
+ const name = opts.profile ?? getActiveProfile();
17
+ if (!profileExists(name)) {
18
+ console.error(chalk.red(`✗ Profile "${name}" not found. Run \`xpay init\` first.`));
19
+ process.exit(1);
20
+ }
21
+ const wallet = readWalletFile(profilePath(name));
22
+ let passphrase = opts.passphrase ?? process.env.XPAY_PASSPHRASE;
23
+ if (wallet.encrypted && !passphrase) {
24
+ const a = await inquirer.prompt([
25
+ { type: "password", name: "p", message: `Passphrase for "${name}":`, mask: "*" },
26
+ ]);
27
+ passphrase = a.p;
28
+ }
29
+ let profile;
30
+ try {
31
+ profile = await loadProfile({ name, passphrase });
32
+ }
33
+ catch (err) {
34
+ console.error(chalk.red(`✗ ${err.message}`));
35
+ process.exit(1);
36
+ }
37
+ const signers = signersFromProfile(profile);
38
+ const networks = opts.network ? [opts.network] : profile.config.networks;
39
+ console.log("");
40
+ console.log(chalk.bold(`Profile "${name}"`));
41
+ console.log("");
42
+ let total = 0;
43
+ const rows = [];
44
+ for (const net of networks) {
45
+ const signer = signers[net];
46
+ if (!signer) {
47
+ rows.push({ network: net, address: chalk.dim("(no signer)"), balance: 0 });
48
+ continue;
49
+ }
50
+ const bal = signer.balance ? await signer.balance().catch(() => 0) : 0;
51
+ total += bal;
52
+ rows.push({ network: net, address: signer.address, balance: bal });
53
+ }
54
+ for (const r of rows) {
55
+ console.log(` ${chalk.bold(r.network.padEnd(10))} ${chalk.cyan(r.address)} ${chalk.green(`$${r.balance.toFixed(4)}`)} ${chalk.dim("USDC")}`);
56
+ }
57
+ console.log("");
58
+ console.log(` ${" ".repeat(10)} ${" ".repeat(44)} ${chalk.bold(`$${total.toFixed(4)} total`)}`);
59
+ }
60
+ //# sourceMappingURL=balance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"balance.js","sourceRoot":"","sources":["../../src/cli/balance.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Shared CLI helpers: unlock the active profile, format addresses + amounts.
3
+ */
4
+ import type { LoadedProfile } from "../profile/index.js";
5
+ export interface UnlockOptions {
6
+ profile?: string;
7
+ passphrase?: string;
8
+ }
9
+ /**
10
+ * Resolve + unlock the active profile, prompting for passphrase if needed.
11
+ * Falls back to $XPAY_PASSPHRASE so non-interactive use stays simple.
12
+ */
13
+ export declare function unlockActive(opts?: UnlockOptions): Promise<LoadedProfile>;
14
+ /** Compact display for long addresses: `7RB7...f5ph`. */
15
+ export declare function shortAddress(addr: string, head?: number, tail?: number): string;
16
+ /** "$0.0123 USDC", consistent width. */
17
+ export declare function formatUsd(amount: number): string;
18
+ /** "2m ago" / "3h ago" / "5d ago". */
19
+ export declare function timeAgo(ts: number | null): string;
20
+ //# sourceMappingURL=common.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../src/cli/common.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAAC,IAAI,GAAE,aAAkB,GAAG,OAAO,CAAC,aAAa,CAAC,CAuBnF;AAED,yDAAyD;AACzD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,SAAI,EAAE,IAAI,SAAI,GAAG,MAAM,CAGrE;AAED,wCAAwC;AACxC,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED,sCAAsC;AACtC,wBAAgB,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAOjD"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Shared CLI helpers: unlock the active profile, format addresses + amounts.
3
+ */
4
+ import chalk from "chalk";
5
+ import inquirer from "inquirer";
6
+ import { loadProfile } from "../profile/index.js";
7
+ import { profileExists, readWalletFile, profilePath } from "../profile/storage.js";
8
+ import { getActiveProfile } from "./accounts.js";
9
+ /**
10
+ * Resolve + unlock the active profile, prompting for passphrase if needed.
11
+ * Falls back to $XPAY_PASSPHRASE so non-interactive use stays simple.
12
+ */
13
+ export async function unlockActive(opts = {}) {
14
+ const name = opts.profile ?? getActiveProfile();
15
+ if (!profileExists(name)) {
16
+ console.error(chalk.red(`✗ Profile "${name}" not found. Run \`xpay init\` first.`));
17
+ process.exit(1);
18
+ }
19
+ const wallet = readWalletFile(profilePath(name));
20
+ let passphrase = opts.passphrase ?? process.env.XPAY_PASSPHRASE;
21
+ if (wallet.encrypted && !passphrase) {
22
+ const a = await inquirer.prompt([
23
+ { type: "password", name: "p", message: `Passphrase for "${name}":`, mask: "*" },
24
+ ]);
25
+ passphrase = a.p;
26
+ }
27
+ try {
28
+ return await loadProfile({ name, passphrase });
29
+ }
30
+ catch (err) {
31
+ console.error(chalk.red(`✗ ${err.message}`));
32
+ process.exit(1);
33
+ }
34
+ }
35
+ /** Compact display for long addresses: `7RB7...f5ph`. */
36
+ export function shortAddress(addr, head = 4, tail = 4) {
37
+ if (!addr || addr.length <= head + tail + 3)
38
+ return addr;
39
+ return `${addr.slice(0, head)}…${addr.slice(-tail)}`;
40
+ }
41
+ /** "$0.0123 USDC", consistent width. */
42
+ export function formatUsd(amount) {
43
+ return chalk.green(`$${amount.toFixed(4)}`);
44
+ }
45
+ /** "2m ago" / "3h ago" / "5d ago". */
46
+ export function timeAgo(ts) {
47
+ if (!ts)
48
+ return chalk.dim("—");
49
+ const s = (Date.now() - ts) / 1000;
50
+ if (s < 60)
51
+ return `${Math.floor(s)}s ago`;
52
+ if (s < 3600)
53
+ return `${Math.floor(s / 60)}m ago`;
54
+ if (s < 86400)
55
+ return `${Math.floor(s / 3600)}h ago`;
56
+ return `${Math.floor(s / 86400)}d ago`;
57
+ }
58
+ //# sourceMappingURL=common.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"common.js","sourceRoot":"","sources":["../../src/cli/common.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * `xpay discover <query>` — search the agentic-commerce catalog.
3
+ *
4
+ * Read-only — does not load a profile or touch keys.
5
+ */
6
+ export interface DiscoverCmdOptions {
7
+ limit?: string;
8
+ network?: string;
9
+ json?: boolean;
10
+ }
11
+ export declare function runDiscover(query: string | undefined, opts: DiscoverCmdOptions): Promise<void>;
12
+ //# sourceMappingURL=discover.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discover.d.ts","sourceRoot":"","sources":["../../src/cli/discover.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAsB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAkCpG"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * `xpay discover <query>` — search the agentic-commerce catalog.
3
+ *
4
+ * Read-only — does not load a profile or touch keys.
5
+ */
6
+ import chalk from "chalk";
7
+ import { discover } from "../discover/index.js";
8
+ import { formatUsd, shortAddress } from "./common.js";
9
+ export async function runDiscover(query, opts) {
10
+ const limit = opts.limit ? Number(opts.limit) : 10;
11
+ const networks = opts.network ? [opts.network] : undefined;
12
+ const t0 = Date.now();
13
+ const results = await discover({ query, limit, networks });
14
+ const elapsed = Date.now() - t0;
15
+ if (opts.json) {
16
+ process.stdout.write(JSON.stringify(results, null, 2) + "\n");
17
+ return;
18
+ }
19
+ if (results.length === 0) {
20
+ console.log(chalk.yellow(`No services found${query ? ` for "${query}"` : ""}.`));
21
+ console.log(chalk.dim(`Tip: try broader terms, or omit --network.`));
22
+ return;
23
+ }
24
+ console.log("");
25
+ console.log(chalk.dim(`${results.length} result${results.length === 1 ? "" : "s"}` +
26
+ (query ? ` for "${query}"` : "") +
27
+ ` (${elapsed}ms)`));
28
+ console.log("");
29
+ for (let i = 0; i < results.length; i++) {
30
+ printResource(results[i], i + 1);
31
+ }
32
+ console.log("");
33
+ console.log(chalk.dim(`Use \`xpay pay <url>\` to call one.`));
34
+ }
35
+ function printResource(r, index) {
36
+ const opt = r.accepts[0];
37
+ const price = opt?.amount ? formatUsd(Number(opt.amount) / 1_000_000) : chalk.dim("?");
38
+ const net = chalk.cyan(normalizeNetwork(opt?.network).padEnd(9));
39
+ const method = chalk.dim(r.method.padEnd(6));
40
+ const host = safeHost(r.resource);
41
+ console.log(` ${chalk.bold(String(index).padStart(2) + ".")} ${price} ${net} ${method} ${chalk.white(host)}`);
42
+ console.log(` ${chalk.dim(r.resource)}`);
43
+ if (opt?.payTo) {
44
+ console.log(` ${chalk.dim("→ pay")} ${chalk.dim(shortAddress(opt.payTo, 6, 6))} ${chalk.dim(`(${opt.asset.slice(0, 12)}…)`)}`);
45
+ }
46
+ console.log("");
47
+ }
48
+ function safeHost(url) {
49
+ try {
50
+ return new URL(url).host;
51
+ }
52
+ catch {
53
+ return url;
54
+ }
55
+ }
56
+ function normalizeNetwork(raw) {
57
+ if (!raw)
58
+ return "?";
59
+ if (raw === "eip155:8453")
60
+ return "base";
61
+ if (raw === "eip155:1")
62
+ return "ethereum";
63
+ if (raw === "eip155:42161")
64
+ return "arbitrum";
65
+ if (raw.startsWith("solana"))
66
+ return "solana";
67
+ return raw;
68
+ }
69
+ //# sourceMappingURL=discover.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discover.js","sourceRoot":"","sources":["../../src/cli/discover.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * `xpay guardrail show|set|clear` — view and edit the active profile's
3
+ * spending guardrail. Persisted to config.json; loaded by every command that
4
+ * builds a runtime client.
5
+ */
6
+ export interface GuardrailSetOptions {
7
+ profile?: string;
8
+ maxPerTx?: string;
9
+ maxPerDay?: string;
10
+ allowedHosts?: string;
11
+ requireApprovalAbove?: string;
12
+ }
13
+ export declare function runGuardrailShow(profileName?: string): void;
14
+ export declare function runGuardrailSet(opts: GuardrailSetOptions): void;
15
+ export declare function runGuardrailClear(profileName?: string): void;
16
+ //# sourceMappingURL=guardrail.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guardrail.d.ts","sourceRoot":"","sources":["../../src/cli/guardrail.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAUH,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,wBAAgB,gBAAgB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAuB3D;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,mBAAmB,GAAG,IAAI,CAuB/D;AAED,wBAAgB,iBAAiB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAI5D"}