@caypo/canton-cli 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.
@@ -0,0 +1,14 @@
1
+
2
+ > @caypo/canton-cli@0.1.0 build /Users/anil/Desktop/caypo/packages/cli
3
+ > tsup
4
+
5
+ CLI Building entry: src/index.ts
6
+ CLI Using tsconfig: tsconfig.json
7
+ CLI tsup v8.5.1
8
+ CLI Using tsup config: /Users/anil/Desktop/caypo/packages/cli/tsup.config.ts
9
+ CLI Target: es2022
10
+ CLI Cleaning output folder
11
+ ESM Build start
12
+ ESM dist/index.js 16.09 KB
13
+ ESM dist/index.js.map 32.52 KB
14
+ ESM ⚡️ Build success in 11ms
@@ -0,0 +1,12 @@
1
+
2
+ > @caypo/canton-cli@0.1.0 test /Users/anil/Desktop/caypo/packages/cli
3
+ > vitest run
4
+
5
+
6
+ RUN v3.2.4 /Users/anil/Desktop/caypo/packages/cli
7
+
8
+ No test files found, exiting with code 0
9
+
10
+ include: **/*.{test,spec}.?(c|m)[jt]s?(x)
11
+ exclude: **/node_modules/**, **/dist/**, **/cypress/**, **/.{idea,git,cache,output,temp}/**, **/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build,eslint,prettier}.config.*
12
+
package/README.md ADDED
@@ -0,0 +1,101 @@
1
+ # @caypo/canton-cli
2
+
3
+ **CLI for AI agent banking on [Canton Network](https://canton.network)**
4
+
5
+ Manage your USDCx wallet, send payments, pay for APIs, and configure MCP server — all from the terminal.
6
+
7
+ [![License](https://img.shields.io/badge/license-Apache--2.0%20%2F%20MIT-blue)](../../LICENSE-APACHE)
8
+
9
+ ## Install
10
+
11
+ ```bash
12
+ npm install -g @caypo/canton-cli
13
+ ```
14
+
15
+ ## Commands
16
+
17
+ ```
18
+ SETUP
19
+ caypo init Set up wallet (PIN, ledger URL, JWT, party)
20
+ caypo address Show your Canton party ID
21
+ caypo balance Show USDCx balance and holdings
22
+
23
+ PAYMENTS
24
+ caypo send <amount> to <recipient> Send USDCx to a party
25
+ caypo pay <url> [--max-price N] Pay for API (auto 402 flow)
26
+
27
+ SAFEGUARDS
28
+ caypo safeguards View spending limits
29
+ caypo safeguards set-tx-limit <amt> Set per-transaction limit
30
+ caypo safeguards set-daily-limit <amt> Set daily spending limit
31
+ caypo safeguards lock Lock wallet
32
+ caypo safeguards unlock Unlock wallet
33
+
34
+ TRAFFIC
35
+ caypo traffic Validator traffic balance
36
+
37
+ MCP
38
+ caypo mcp install Install for Claude/Cursor/Windsurf
39
+ ```
40
+
41
+ ## Examples
42
+
43
+ ### Set up a new wallet
44
+
45
+ ```
46
+ $ caypo init
47
+
48
+ CAYPO — A bank account for AI agents on Canton Network
49
+
50
+ ? Choose a PIN for your wallet: ****
51
+ ? Confirm PIN: ****
52
+ ? Canton Ledger URL: http://localhost:7575
53
+ ? JWT bearer token: ****
54
+ ? Agent display name: MyAgent
55
+
56
+ [OK] Party allocated
57
+ [OK] Keystore created
58
+
59
+ Party ID: MyAgent::1220abcdef...
60
+ Config: ~/.caypo/config.json
61
+ ```
62
+
63
+ ### Check balance
64
+
65
+ ```
66
+ $ caypo balance
67
+
68
+ Checking Account
69
+
70
+ Balance: 50.00 USDCx
71
+ Holdings: 3 UTXOs
72
+ Address: MyAgent::1220abcdef...
73
+ Network: testnet
74
+ ```
75
+
76
+ ### Pay for an API call
77
+
78
+ ```
79
+ $ caypo pay https://mpp.cayvox.io/openai/v1/chat/completions --max-price 0.05
80
+
81
+ [OK] Paid 0.01 USDCx for API access
82
+ Update ID: upd-abc123
83
+ Status: 200
84
+ ```
85
+
86
+ ### Install MCP server
87
+
88
+ ```
89
+ $ caypo mcp install
90
+
91
+ [OK] Claude Desktop
92
+ [OK] Cursor
93
+ [OK] Windsurf
94
+
95
+ MCP server installed for 3 tools.
96
+ Restart your AI tool to activate.
97
+ ```
98
+
99
+ ## License
100
+
101
+ Apache-2.0 OR MIT
package/SPEC.md ADDED
@@ -0,0 +1,41 @@
1
+ # @cayvox/canton-cli — CLI Specification (Production)
2
+
3
+ Binary: `canton-agent` (alias: `ca`)
4
+
5
+ ## Commands
6
+
7
+ ```
8
+ SETUP
9
+ init Interactive: PIN, ledger URL, JWT, party allocation, MCP
10
+ address Party ID (e.g., Agent::1220abcd...)
11
+ balance All account balances
12
+ config Show/edit configuration
13
+ mcp install Install MCP server for Claude/Cursor/Windsurf
14
+ export-key Export private key (requires PIN)
15
+
16
+ CHECKING
17
+ send <amount> to <recipient> Send USDCx (party ID or ANS name)
18
+ history [--limit N] Transaction history
19
+
20
+ MPP PAYMENTS
21
+ pay <url> [--data json] [--method POST] [--max-price amount]
22
+
23
+ SAFEGUARDS
24
+ safeguards Show settings
25
+ safeguards set-tx-limit <amount>
26
+ safeguards set-daily-limit <amount>
27
+ safeguards lock / unlock
28
+
29
+ TRAFFIC
30
+ traffic Validator traffic balance
31
+ traffic purchase <cc-amount> Buy traffic with CC
32
+
33
+ PHASE 3+ (stubs in v1)
34
+ save, withdraw, rebalance, earnings
35
+ borrow, repay, health
36
+ exchange, rates
37
+ invest buy/sell/earn/strategy/auto/portfolio
38
+ claim-rewards
39
+ ```
40
+
41
+ ## Technology: commander + chalk + ora + inquirer
package/dist/index.js ADDED
@@ -0,0 +1,468 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/index.ts
4
+ import { Command as Command9 } from "commander";
5
+
6
+ // src/commands/init.ts
7
+ import { Command } from "commander";
8
+ import inquirer from "inquirer";
9
+ import ora from "ora";
10
+ import chalk2 from "chalk";
11
+ import {
12
+ CantonClient,
13
+ Keystore,
14
+ saveConfig,
15
+ DEFAULT_CONFIG,
16
+ SafeguardManager
17
+ } from "@caypo/canton-sdk";
18
+
19
+ // src/helpers/format.ts
20
+ import chalk from "chalk";
21
+ var label = (text) => chalk.gray(text);
22
+ var value = (text) => chalk.white.bold(text);
23
+ var success = (text) => chalk.green(text);
24
+ var warn = (text) => chalk.yellow(text);
25
+ var fail = (text) => chalk.red(text);
26
+ var accent = (text) => chalk.cyan(text);
27
+ var dim = (text) => chalk.dim(text);
28
+ function banner() {
29
+ console.log(chalk.cyan.bold("\n CAYPO") + chalk.gray(" \u2014 A bank account for AI agents on Canton Network\n"));
30
+ }
31
+ function keyValue(key, val) {
32
+ console.log(` ${label(key + ":")} ${value(val)}`);
33
+ }
34
+ function errorMessage(msg) {
35
+ console.log(`
36
+ ${fail("\u2717")} ${msg}
37
+ `);
38
+ }
39
+ function successMessage(msg) {
40
+ console.log(`
41
+ ${success("\u2713")} ${msg}
42
+ `);
43
+ }
44
+
45
+ // src/commands/init.ts
46
+ var initCommand = new Command("init").description("Interactive wallet setup \u2014 create keystore, allocate party").action(async () => {
47
+ banner();
48
+ console.log(chalk2.gray(" Setting up your Canton agent wallet...\n"));
49
+ try {
50
+ const { pin } = await inquirer.prompt([
51
+ {
52
+ type: "password",
53
+ name: "pin",
54
+ message: "Choose a PIN for your wallet:",
55
+ mask: "*",
56
+ validate: (v) => v.length >= 4 || "PIN must be at least 4 characters"
57
+ }
58
+ ]);
59
+ const { confirmPin } = await inquirer.prompt([
60
+ {
61
+ type: "password",
62
+ name: "confirmPin",
63
+ message: "Confirm PIN:",
64
+ mask: "*",
65
+ validate: (v) => v === pin || "PINs do not match"
66
+ }
67
+ ]);
68
+ const { ledgerUrl } = await inquirer.prompt([
69
+ {
70
+ type: "input",
71
+ name: "ledgerUrl",
72
+ message: "Canton Ledger URL:",
73
+ default: "http://localhost:7575"
74
+ }
75
+ ]);
76
+ const { jwt } = await inquirer.prompt([
77
+ {
78
+ type: "password",
79
+ name: "jwt",
80
+ message: "JWT bearer token:",
81
+ mask: "*",
82
+ validate: (v) => v.length > 0 || "JWT is required"
83
+ }
84
+ ]);
85
+ const { userId } = await inquirer.prompt([
86
+ {
87
+ type: "input",
88
+ name: "userId",
89
+ message: "Ledger API user ID:",
90
+ default: "ledger-api-user"
91
+ }
92
+ ]);
93
+ const { displayName } = await inquirer.prompt([
94
+ {
95
+ type: "input",
96
+ name: "displayName",
97
+ message: "Agent display name:",
98
+ default: "Agent"
99
+ }
100
+ ]);
101
+ const spinner = ora("Allocating party on Canton ledger...").start();
102
+ const client = new CantonClient({ ledgerUrl, token: jwt, userId });
103
+ let partyId;
104
+ try {
105
+ const party = await client.allocateParty(displayName);
106
+ partyId = party.party;
107
+ spinner.succeed("Party allocated");
108
+ } catch (err) {
109
+ spinner.fail("Failed to allocate party");
110
+ errorMessage(err.message);
111
+ process.exit(1);
112
+ }
113
+ const keystoreSpinner = ora("Creating encrypted keystore...").start();
114
+ await Keystore.create(pin, { partyId, jwt, userId });
115
+ keystoreSpinner.succeed("Keystore created");
116
+ const config = {
117
+ ...DEFAULT_CONFIG,
118
+ ledgerUrl,
119
+ partyId,
120
+ userId
121
+ };
122
+ await saveConfig(config);
123
+ const safeguards = new SafeguardManager();
124
+ safeguards.setTxLimit(DEFAULT_CONFIG.safeguards.txLimit);
125
+ safeguards.setDailyLimit(DEFAULT_CONFIG.safeguards.dailyLimit);
126
+ console.log("");
127
+ successMessage("Canton agent wallet created successfully!");
128
+ console.log("");
129
+ keyValue("Party ID", accent(partyId));
130
+ keyValue("Ledger URL", ledgerUrl);
131
+ keyValue("Config", "~/.caypo/config.json");
132
+ keyValue("Keystore", "~/.caypo/wallet.key");
133
+ console.log("");
134
+ console.log(chalk2.gray(" Next steps:"));
135
+ console.log(chalk2.gray(" caypo balance \u2014 Check your balance"));
136
+ console.log(chalk2.gray(" caypo mcp install \u2014 Install MCP server for AI tools"));
137
+ console.log(chalk2.gray(" caypo send 1 to <party> \u2014 Send USDCx"));
138
+ console.log("");
139
+ } catch (err) {
140
+ errorMessage(`Setup failed: ${err.message}`);
141
+ process.exit(1);
142
+ }
143
+ });
144
+
145
+ // src/commands/balance.ts
146
+ import { Command as Command2 } from "commander";
147
+ import chalk3 from "chalk";
148
+ import ora2 from "ora";
149
+
150
+ // src/helpers/load-agent.ts
151
+ import { CantonAgent, loadConfig } from "@caypo/canton-sdk";
152
+ async function loadAgent() {
153
+ try {
154
+ const config = await loadConfig();
155
+ if (!config.partyId) {
156
+ errorMessage("No wallet configured. Run 'caypo init' first.");
157
+ process.exit(1);
158
+ }
159
+ return CantonAgent.create({
160
+ ledgerUrl: config.ledgerUrl,
161
+ partyId: config.partyId,
162
+ userId: config.userId,
163
+ network: config.network,
164
+ token: process.env.CANTON_JWT ?? ""
165
+ });
166
+ } catch (err) {
167
+ errorMessage(`Failed to load agent: ${err.message}`);
168
+ process.exit(1);
169
+ }
170
+ }
171
+
172
+ // src/commands/balance.ts
173
+ var balanceCommand = new Command2("balance").description("Show USDCx checking balance").action(async () => {
174
+ banner();
175
+ const spinner = ora2("Fetching balance...").start();
176
+ try {
177
+ const agent = await loadAgent();
178
+ const bal = await agent.checking.balance();
179
+ spinner.stop();
180
+ console.log(chalk3.gray(" Checking Account\n"));
181
+ keyValue("Balance", accent(`${bal.available} USDCx`));
182
+ keyValue("Holdings", `${bal.holdingCount} UTXO${bal.holdingCount !== 1 ? "s" : ""}`);
183
+ keyValue("Address", agent.wallet.address);
184
+ keyValue("Network", agent.wallet.network);
185
+ console.log("");
186
+ } catch (err) {
187
+ spinner.fail(`Failed to fetch balance: ${err.message}`);
188
+ process.exit(1);
189
+ }
190
+ });
191
+
192
+ // src/commands/send.ts
193
+ import { Command as Command3 } from "commander";
194
+ import ora3 from "ora";
195
+ var sendCommand = new Command3("send").description("Send USDCx to a recipient").argument("<amount>", "Amount of USDCx to send").argument("to", "Literal 'to' keyword").argument("<recipient>", "Recipient party ID").option("--memo <memo>", "Optional memo").action(async (amount, _to, recipient, opts) => {
196
+ banner();
197
+ const spinner = ora3(`Sending ${amount} USDCx to ${recipient}...`).start();
198
+ try {
199
+ const agent = await loadAgent();
200
+ const result = await agent.checking.send(recipient, amount, { memo: opts.memo });
201
+ spinner.stop();
202
+ successMessage(`Sent ${accent(amount + " USDCx")} successfully!`);
203
+ keyValue("Recipient", recipient);
204
+ keyValue("Update ID", result.updateId);
205
+ keyValue("Offset", String(result.completionOffset));
206
+ keyValue("Command ID", result.commandId);
207
+ console.log("");
208
+ } catch (err) {
209
+ spinner.fail("Transfer failed");
210
+ errorMessage(err.message);
211
+ process.exit(1);
212
+ }
213
+ });
214
+
215
+ // src/commands/pay.ts
216
+ import { Command as Command4 } from "commander";
217
+ import ora4 from "ora";
218
+ var payCommand = new Command4("pay").description("Pay for an API call via MPP (402 auto-pay)").argument("<url>", "URL to fetch").option("-d, --data <json>", "Request body (JSON)").option("-X, --method <method>", "HTTP method", "GET").option("--max-price <amount>", "Maximum price to pay").action(async (url, opts) => {
219
+ banner();
220
+ const spinner = ora4(`Fetching ${url}...`).start();
221
+ try {
222
+ const agent = await loadAgent();
223
+ const result = await agent.mpp.pay(url, {
224
+ method: opts.method,
225
+ body: opts.data,
226
+ maxPrice: opts.maxPrice,
227
+ headers: opts.data ? { "Content-Type": "application/json" } : void 0
228
+ });
229
+ spinner.stop();
230
+ if (result.paid) {
231
+ successMessage(`Paid ${accent(result.receipt.amount + " USDCx")} for API access`);
232
+ keyValue("Update ID", result.receipt.updateId);
233
+ keyValue("Command ID", result.receipt.commandId);
234
+ } else {
235
+ console.log(dim(" No payment required (non-402 response)"));
236
+ }
237
+ keyValue("Status", String(result.response.status));
238
+ const body = await result.response.text();
239
+ if (body) {
240
+ console.log(dim("\n Response:"));
241
+ console.log(dim(" " + body.slice(0, 500)));
242
+ if (body.length > 500) console.log(dim(" ... (truncated)"));
243
+ }
244
+ console.log("");
245
+ } catch (err) {
246
+ spinner.fail("Payment failed");
247
+ errorMessage(err.message);
248
+ process.exit(1);
249
+ }
250
+ });
251
+
252
+ // src/commands/address.ts
253
+ import { Command as Command5 } from "commander";
254
+ var addressCommand = new Command5("address").description("Show your Canton party ID (address)").action(async () => {
255
+ banner();
256
+ try {
257
+ const agent = await loadAgent();
258
+ keyValue("Party ID", agent.wallet.address);
259
+ keyValue("Network", agent.wallet.network);
260
+ console.log("");
261
+ } catch (err) {
262
+ console.error(err.message);
263
+ process.exit(1);
264
+ }
265
+ });
266
+
267
+ // src/commands/safeguards.ts
268
+ import { Command as Command6 } from "commander";
269
+ import inquirer2 from "inquirer";
270
+ import chalk4 from "chalk";
271
+ import { SafeguardManager as SafeguardManager2 } from "@caypo/canton-sdk";
272
+ var safeguardsCommand = new Command6("safeguards").description("View and manage safeguard settings").action(async () => {
273
+ banner();
274
+ try {
275
+ const mgr = await SafeguardManager2.load();
276
+ const s = mgr.settings();
277
+ console.log(chalk4.gray(" Safeguard Settings\n"));
278
+ keyValue("Per-tx limit", accent(s.txLimit + " USDCx"));
279
+ keyValue("Daily limit", accent(s.dailyLimit + " USDCx"));
280
+ keyValue("Daily spent", s.dailySpent + " USDCx");
281
+ keyValue("Locked", s.locked ? warn("YES") : "no");
282
+ keyValue("Last reset", s.lastResetDate);
283
+ console.log("");
284
+ } catch (err) {
285
+ errorMessage(err.message);
286
+ process.exit(1);
287
+ }
288
+ });
289
+ safeguardsCommand.command("set-tx-limit").argument("<amount>", "Per-transaction limit in USDCx").description("Set per-transaction spending limit").action(async (amount) => {
290
+ try {
291
+ const mgr = await SafeguardManager2.load();
292
+ mgr.setTxLimit(amount);
293
+ successMessage(`Per-transaction limit set to ${accent(amount + " USDCx")}`);
294
+ } catch (err) {
295
+ errorMessage(err.message);
296
+ process.exit(1);
297
+ }
298
+ });
299
+ safeguardsCommand.command("set-daily-limit").argument("<amount>", "Daily spending limit in USDCx").description("Set daily spending limit").action(async (amount) => {
300
+ try {
301
+ const mgr = await SafeguardManager2.load();
302
+ mgr.setDailyLimit(amount);
303
+ successMessage(`Daily limit set to ${accent(amount + " USDCx")}`);
304
+ } catch (err) {
305
+ errorMessage(err.message);
306
+ process.exit(1);
307
+ }
308
+ });
309
+ safeguardsCommand.command("lock").description("Lock wallet \u2014 all transactions will be rejected").action(async () => {
310
+ try {
311
+ const { pin } = await inquirer2.prompt([
312
+ {
313
+ type: "password",
314
+ name: "pin",
315
+ message: "Set lock PIN:",
316
+ mask: "*"
317
+ }
318
+ ]);
319
+ const mgr = await SafeguardManager2.load();
320
+ mgr.lock(pin);
321
+ successMessage("Wallet locked");
322
+ } catch (err) {
323
+ errorMessage(err.message);
324
+ process.exit(1);
325
+ }
326
+ });
327
+ safeguardsCommand.command("unlock").description("Unlock wallet").action(async () => {
328
+ try {
329
+ const { pin } = await inquirer2.prompt([
330
+ {
331
+ type: "password",
332
+ name: "pin",
333
+ message: "Enter lock PIN:",
334
+ mask: "*"
335
+ }
336
+ ]);
337
+ const mgr = await SafeguardManager2.load();
338
+ mgr.unlock(pin);
339
+ successMessage("Wallet unlocked");
340
+ } catch (err) {
341
+ errorMessage(err.message);
342
+ process.exit(1);
343
+ }
344
+ });
345
+
346
+ // src/commands/traffic.ts
347
+ import { Command as Command7 } from "commander";
348
+ import ora5 from "ora";
349
+ import chalk5 from "chalk";
350
+ var trafficCommand = new Command7("traffic").description("Show validator traffic balance").action(async () => {
351
+ banner();
352
+ const spinner = ora5("Checking traffic balance...").start();
353
+ try {
354
+ const agent = await loadAgent();
355
+ const balance = await agent.traffic.trafficBalance();
356
+ const sufficient = balance.remaining > 1e3;
357
+ spinner.stop();
358
+ console.log(chalk5.gray(" Validator Traffic\n"));
359
+ keyValue("Total purchased", accent(String(balance.totalPurchased)));
360
+ keyValue("Consumed", String(balance.consumed));
361
+ keyValue("Remaining", sufficient ? accent(String(balance.remaining)) : warn(String(balance.remaining)));
362
+ keyValue("Status", sufficient ? "Sufficient" : warn("Low \u2014 consider purchasing more"));
363
+ console.log("");
364
+ } catch (err) {
365
+ spinner.fail(`Failed: ${err.message}`);
366
+ process.exit(1);
367
+ }
368
+ });
369
+ trafficCommand.command("purchase").argument("<cc-amount>", "Canton Coin amount to burn for traffic").description("Purchase additional traffic by burning CC").action(async (ccAmount) => {
370
+ const spinner = ora5(`Purchasing traffic with ${ccAmount} CC...`).start();
371
+ try {
372
+ const agent = await loadAgent();
373
+ await agent.traffic.purchaseTraffic(ccAmount);
374
+ spinner.succeed("Traffic purchased");
375
+ } catch (err) {
376
+ spinner.fail(`Purchase failed: ${err.message}`);
377
+ process.exit(1);
378
+ }
379
+ });
380
+
381
+ // src/commands/mcp.ts
382
+ import { Command as Command8 } from "commander";
383
+ import { mkdir, readFile, writeFile } from "fs/promises";
384
+ import { join } from "path";
385
+ import { homedir, platform } from "os";
386
+ import chalk6 from "chalk";
387
+ var MCP_ENTRY = {
388
+ command: "npx",
389
+ args: ["@caypo/canton-mcp"],
390
+ env: { CANTON_AGENT_CONFIG: join(homedir(), ".caypo", "config.json") }
391
+ };
392
+ function getConfigPaths() {
393
+ const home = homedir();
394
+ const os = platform();
395
+ const paths = [];
396
+ if (os === "darwin") {
397
+ paths.push(
398
+ { name: "Claude Desktop", path: join(home, "Library", "Application Support", "Claude", "claude_desktop_config.json") },
399
+ { name: "Cursor", path: join(home, ".cursor", "mcp.json") },
400
+ { name: "Windsurf", path: join(home, ".windsurf", "mcp.json") }
401
+ );
402
+ } else if (os === "linux") {
403
+ paths.push(
404
+ { name: "Claude Desktop", path: join(home, ".config", "Claude", "claude_desktop_config.json") },
405
+ { name: "Cursor", path: join(home, ".cursor", "mcp.json") },
406
+ { name: "Windsurf", path: join(home, ".windsurf", "mcp.json") }
407
+ );
408
+ } else {
409
+ const appData = process.env.APPDATA ?? join(home, "AppData", "Roaming");
410
+ paths.push(
411
+ { name: "Claude Desktop", path: join(appData, "Claude", "claude_desktop_config.json") },
412
+ { name: "Cursor", path: join(home, ".cursor", "mcp.json") },
413
+ { name: "Windsurf", path: join(home, ".windsurf", "mcp.json") }
414
+ );
415
+ }
416
+ return paths;
417
+ }
418
+ async function installToConfig(configPath) {
419
+ let config;
420
+ try {
421
+ const raw = await readFile(configPath, "utf8");
422
+ config = JSON.parse(raw);
423
+ } catch {
424
+ config = { mcpServers: {} };
425
+ }
426
+ if (!config.mcpServers) {
427
+ config.mcpServers = {};
428
+ }
429
+ config.mcpServers["caypo"] = MCP_ENTRY;
430
+ await mkdir(join(configPath, ".."), { recursive: true });
431
+ await writeFile(configPath, JSON.stringify(config, null, 2), "utf8");
432
+ return true;
433
+ }
434
+ var mcpCommand = new Command8("mcp").description("MCP server management");
435
+ mcpCommand.command("install").description("Install MCP server config for Claude Desktop, Cursor, Windsurf").action(async () => {
436
+ console.log(chalk6.gray("\n Installing CAYPO MCP server configuration...\n"));
437
+ const configs = getConfigPaths();
438
+ let installed = 0;
439
+ for (const { name, path } of configs) {
440
+ try {
441
+ await installToConfig(path);
442
+ console.log(` ${chalk6.green("\u2713")} ${name} ${dim(path)}`);
443
+ installed++;
444
+ } catch (err) {
445
+ console.log(` ${chalk6.yellow("\u26A0")} ${name} \u2014 ${dim(err.message)}`);
446
+ }
447
+ }
448
+ if (installed > 0) {
449
+ successMessage(`MCP server installed for ${installed} tool${installed > 1 ? "s" : ""}`);
450
+ console.log(chalk6.gray(" Restart your AI tool to activate the MCP server."));
451
+ console.log(chalk6.gray(" The server provides 33 tools and 20 prompts for Canton banking.\n"));
452
+ } else {
453
+ errorMessage("No AI tool configs found. Install manually.");
454
+ console.log(chalk6.gray(" Add this to your MCP config:\n"));
455
+ console.log(chalk6.gray(" " + JSON.stringify({ caypo: MCP_ENTRY }, null, 2).replace(/\n/g, "\n ")));
456
+ console.log("");
457
+ }
458
+ });
459
+
460
+ // src/index.ts
461
+ var CANTON_CLI_VERSION = "0.1.0";
462
+ var program = new Command9();
463
+ program.name("caypo").description("CAYPO \u2014 A bank account for AI agents on Canton Network").version(CANTON_CLI_VERSION, "-v, --version").addCommand(initCommand).addCommand(balanceCommand).addCommand(sendCommand).addCommand(payCommand).addCommand(addressCommand).addCommand(safeguardsCommand).addCommand(trafficCommand).addCommand(mcpCommand);
464
+ program.parse(process.argv);
465
+ export {
466
+ CANTON_CLI_VERSION
467
+ };
468
+ //# sourceMappingURL=index.js.map