@arcdot/agent 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.
package/dist/cli.js ADDED
@@ -0,0 +1,685 @@
1
+ // src/constants.ts
2
+ var ARC_CHAIN_ID = 5042;
3
+ var ARC_RPC_URL_DEFAULT = "https://rpc.mainnet.arc.io";
4
+ var ARC_EXPLORER = "https://explorer.arc.io";
5
+ var GATEWAY_FEE_WEI_DEFAULT = 10000000000000000n;
6
+
7
+ // src/client/paymentParse.ts
8
+ function isGateway402Body(value) {
9
+ if (!value || typeof value !== "object") return false;
10
+ const v = value;
11
+ if (v.ok !== false || v.status !== 402) return false;
12
+ const err = v.error;
13
+ if (!err || typeof err !== "object") return false;
14
+ return Boolean(err.payment);
15
+ }
16
+ function parsePaymentRequired(body) {
17
+ if (!isGateway402Body(body)) return null;
18
+ const payment = body.error.payment;
19
+ if (!payment?.gateway || !payment.feeWei) return null;
20
+ return payment;
21
+ }
22
+ function parseMcpPaymentNeeded(toolResult) {
23
+ const text = extractMcpText(toolResult);
24
+ if (!text) return null;
25
+ let parsed;
26
+ try {
27
+ parsed = JSON.parse(text);
28
+ } catch {
29
+ return null;
30
+ }
31
+ if (!parsed || typeof parsed !== "object") return null;
32
+ const obj = parsed;
33
+ const err = obj.error;
34
+ if (obj.status === 402 || err?.code === "PAYMENT_REQUIRED") {
35
+ const payment = err?.payment;
36
+ if (!payment?.gateway || !payment.feeWei) return null;
37
+ const slug = err?.service?.slug || (typeof obj.service === "string" ? obj.service : "") || "";
38
+ return { payment, serviceSlug: slug, raw: parsed };
39
+ }
40
+ return null;
41
+ }
42
+ function extractMcpText(toolResult) {
43
+ if (!toolResult || typeof toolResult !== "object") return null;
44
+ const r = toolResult;
45
+ if (Array.isArray(r.content)) {
46
+ const texts = r.content.filter((c) => c?.type === "text" && typeof c.text === "string").map((c) => c.text);
47
+ if (texts.length) return texts.join("\n");
48
+ }
49
+ if (typeof toolResult.text === "string") {
50
+ return toolResult.text;
51
+ }
52
+ return null;
53
+ }
54
+ function paymentDepositArgs(payment) {
55
+ if (!payment.seller) {
56
+ throw new Error("Payment instructions missing seller address");
57
+ }
58
+ return {
59
+ feeWei: BigInt(payment.feeWei),
60
+ seller: payment.seller,
61
+ gateway: payment.gateway
62
+ };
63
+ }
64
+
65
+ // src/settle/pay.ts
66
+ import {
67
+ createPublicClient,
68
+ createWalletClient,
69
+ formatEther,
70
+ http
71
+ } from "viem";
72
+ import { privateKeyToAccount } from "viem/accounts";
73
+
74
+ // src/arc/chain.ts
75
+ import { defineChain } from "viem";
76
+ function resolveRpcUrl(override) {
77
+ return override || process.env.ARC_RPC_URL || process.env.NEXT_PUBLIC_ARC_RPC_URL || ARC_RPC_URL_DEFAULT;
78
+ }
79
+ function arcMainnet(rpcUrl) {
80
+ return defineChain({
81
+ id: ARC_CHAIN_ID,
82
+ name: "Arc",
83
+ nativeCurrency: { name: "USDC", symbol: "USDC", decimals: 18 },
84
+ rpcUrls: {
85
+ default: { http: [resolveRpcUrl(rpcUrl)] }
86
+ },
87
+ blockExplorers: {
88
+ default: { name: "Arc Explorer", url: ARC_EXPLORER }
89
+ }
90
+ });
91
+ }
92
+ var promptGatewayAbi = [
93
+ {
94
+ type: "function",
95
+ name: "depositPayment",
96
+ stateMutability: "payable",
97
+ inputs: [
98
+ { name: "paymentId", type: "bytes32" },
99
+ { name: "seller", type: "address" }
100
+ ],
101
+ outputs: []
102
+ },
103
+ {
104
+ type: "function",
105
+ name: "minFee",
106
+ stateMutability: "view",
107
+ inputs: [],
108
+ outputs: [{ name: "", type: "uint256" }]
109
+ }
110
+ ];
111
+
112
+ // src/auth/challenge.ts
113
+ import { keccak256, stringToBytes } from "viem";
114
+ function hashGatewayInput(input) {
115
+ return keccak256(stringToBytes(JSON.stringify(input ?? null)));
116
+ }
117
+ function buildAuthChallenge(msg) {
118
+ return [
119
+ "arcdot.gateway",
120
+ `chainId:${msg.chainId}`,
121
+ `gateway:${msg.gateway.toLowerCase()}`,
122
+ `txHash:${msg.txHash.toLowerCase()}`,
123
+ `feeWei:${msg.feeWei}`,
124
+ `service:${msg.service}`,
125
+ `inputHash:${msg.inputHash.toLowerCase()}`,
126
+ `issuedAt:${msg.issuedAt}`,
127
+ `expiresAt:${msg.expiresAt}`
128
+ ].join("\n");
129
+ }
130
+ function buildGatewayAuthMessage(params) {
131
+ return {
132
+ domain: "arcdot.gateway",
133
+ chainId: ARC_CHAIN_ID,
134
+ gateway: params.gateway,
135
+ txHash: params.txHash,
136
+ feeWei: params.feeWei.toString(),
137
+ service: params.service,
138
+ inputHash: hashGatewayInput(params.input),
139
+ issuedAt: params.issuedAt,
140
+ expiresAt: params.expiresAt
141
+ };
142
+ }
143
+
144
+ // src/settle/paymentId.ts
145
+ import { encodeAbiParameters, keccak256 as keccak2562 } from "viem";
146
+ function makePaymentId(params) {
147
+ return keccak2562(
148
+ encodeAbiParameters(
149
+ [
150
+ { type: "address" },
151
+ { type: "string" },
152
+ { type: "uint256" }
153
+ ],
154
+ [params.payer, params.service, BigInt(params.nonce)]
155
+ )
156
+ );
157
+ }
158
+
159
+ // src/settle/pay.ts
160
+ async function settlePayment(params) {
161
+ const account = privateKeyToAccount(params.privateKey);
162
+ const chain = arcMainnet(params.rpcUrl);
163
+ const rpcUrl = resolveRpcUrl(params.rpcUrl);
164
+ const publicClient = createPublicClient({
165
+ chain,
166
+ transport: http(rpcUrl)
167
+ });
168
+ const walletClient = createWalletClient({
169
+ account,
170
+ chain,
171
+ transport: http(rpcUrl)
172
+ });
173
+ const paymentId = makePaymentId({
174
+ payer: account.address,
175
+ service: params.service,
176
+ nonce: Date.now()
177
+ });
178
+ const txHash = await walletClient.writeContract({
179
+ address: params.gateway,
180
+ abi: promptGatewayAbi,
181
+ functionName: "depositPayment",
182
+ args: [paymentId, params.seller],
183
+ value: params.feeWei,
184
+ chain,
185
+ account
186
+ });
187
+ await publicClient.waitForTransactionReceipt({ hash: txHash });
188
+ const now = Math.floor(Date.now() / 1e3);
189
+ const authMessage = buildGatewayAuthMessage({
190
+ gateway: params.gateway,
191
+ txHash,
192
+ feeWei: params.feeWei,
193
+ service: params.service,
194
+ input: params.input,
195
+ issuedAt: now,
196
+ expiresAt: now + 120
197
+ });
198
+ const signature = await walletClient.signMessage({
199
+ account,
200
+ message: buildAuthChallenge(authMessage)
201
+ });
202
+ return {
203
+ paymentId,
204
+ feeWei: params.feeWei,
205
+ proof: {
206
+ txHash,
207
+ address: account.address,
208
+ signature,
209
+ issuedAt: now,
210
+ expiresAt: now + 120
211
+ }
212
+ };
213
+ }
214
+ async function getNativeBalance(address, rpcUrl) {
215
+ const publicClient = createPublicClient({
216
+ chain: arcMainnet(rpcUrl),
217
+ transport: http(resolveRpcUrl(rpcUrl))
218
+ });
219
+ const wei = await publicClient.getBalance({ address });
220
+ return { wei, formatted: formatEther(wei) };
221
+ }
222
+
223
+ // src/wallet/store.ts
224
+ import { mkdirSync, readFileSync, writeFileSync, existsSync, chmodSync } from "fs";
225
+ import { homedir } from "os";
226
+ import { join } from "path";
227
+ import { generatePrivateKey, privateKeyToAccount as privateKeyToAccount2 } from "viem/accounts";
228
+ function walletDir() {
229
+ return process.env.ARCDOT_HOME?.trim() || join(homedir(), ".arcdot");
230
+ }
231
+ function walletPath() {
232
+ return join(walletDir(), "wallet.json");
233
+ }
234
+ function isHexKey(key) {
235
+ return /^0x[a-fA-F0-9]{64}$/.test(key);
236
+ }
237
+ function resolvePrivateKey() {
238
+ const fromEnv = process.env.ARCDOT_PRIVATE_KEY?.trim() || process.env.AGENT_PRIVATE_KEY?.trim();
239
+ if (fromEnv) {
240
+ if (!isHexKey(fromEnv)) {
241
+ throw new Error(
242
+ "ARCDOT_PRIVATE_KEY / AGENT_PRIVATE_KEY must be a 0x-prefixed 32-byte hex key."
243
+ );
244
+ }
245
+ return fromEnv;
246
+ }
247
+ const stored = loadWallet();
248
+ if (!stored) {
249
+ throw new Error(
250
+ "No agent wallet found. Run: npx @arcdot/agent wallet create"
251
+ );
252
+ }
253
+ return stored.privateKey;
254
+ }
255
+ function loadWallet() {
256
+ const path = walletPath();
257
+ if (!existsSync(path)) return null;
258
+ const raw = JSON.parse(readFileSync(path, "utf8"));
259
+ if (!raw.address || !isHexKey(raw.privateKey)) {
260
+ throw new Error(`Corrupt wallet file at ${path}`);
261
+ }
262
+ return raw;
263
+ }
264
+ function createWallet(opts) {
265
+ const path = walletPath();
266
+ if (existsSync(path) && !opts?.force) {
267
+ throw new Error(
268
+ `Wallet already exists at ${path}. Pass --force to overwrite, or use wallet address.`
269
+ );
270
+ }
271
+ mkdirSync(walletDir(), { recursive: true });
272
+ const privateKey = generatePrivateKey();
273
+ const account = privateKeyToAccount2(privateKey);
274
+ const wallet = {
275
+ address: account.address,
276
+ privateKey,
277
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
278
+ };
279
+ writeFileSync(path, JSON.stringify(wallet, null, 2) + "\n", {
280
+ encoding: "utf8",
281
+ mode: 384
282
+ });
283
+ try {
284
+ chmodSync(path, 384);
285
+ } catch {
286
+ }
287
+ return wallet;
288
+ }
289
+ function walletAccountFromKey(privateKey) {
290
+ return privateKeyToAccount2(privateKey);
291
+ }
292
+
293
+ // src/client/gateway.ts
294
+ async function fetchService(origin, slug) {
295
+ const res = await fetch(new URL(`/api/services/${slug}`, origin));
296
+ const json = await res.json();
297
+ if (!res.ok || !json.service) {
298
+ throw new Error(json.error || `Service not found: ${slug}`);
299
+ }
300
+ const sellerRaw = json.service.seller || json.service.owner_address;
301
+ if (!sellerRaw || !/^0x[a-fA-F0-9]{40}$/.test(sellerRaw)) {
302
+ throw new Error("Service is missing a valid seller address");
303
+ }
304
+ return {
305
+ slug: json.service.slug,
306
+ price_wei: json.service.price_wei,
307
+ seller: sellerRaw,
308
+ title: json.service.title
309
+ };
310
+ }
311
+ async function resolveGateway(origin, override) {
312
+ if (override && override.length === 42) return override;
313
+ if (process.env.ARCDOT_GATEWAY?.startsWith("0x")) {
314
+ return process.env.ARCDOT_GATEWAY;
315
+ }
316
+ const res = await fetch(new URL("/api/services", origin));
317
+ const json = await res.json();
318
+ if (json.gateway && json.gateway.length === 42) {
319
+ return json.gateway;
320
+ }
321
+ throw new Error(
322
+ "Gateway address not configured on host. Set ARCDOT_GATEWAY or deploy PromptGateway."
323
+ );
324
+ }
325
+ async function postGatewayPaid(params) {
326
+ const body = {
327
+ service: params.service,
328
+ input: params.input,
329
+ clientRequestId: params.clientRequestId,
330
+ auth: {
331
+ issuedAt: params.proof.issuedAt,
332
+ expiresAt: params.proof.expiresAt
333
+ }
334
+ };
335
+ const res = await fetch(new URL("/api/gateway", params.origin), {
336
+ method: "POST",
337
+ headers: {
338
+ "Content-Type": "application/json",
339
+ "X-Arc-Tx-Hash": params.proof.txHash,
340
+ "X-Arc-Address": params.proof.address,
341
+ "X-Arc-Signature": params.proof.signature
342
+ },
343
+ body: JSON.stringify(body)
344
+ });
345
+ const json = await res.json();
346
+ if (res.status === 200 && json?.ok === true) {
347
+ return { ok: true, status: 200, body: json };
348
+ }
349
+ return { ok: false, status: res.status, body: json };
350
+ }
351
+ async function unlockWithAutoSettle(params) {
352
+ const privateKey = params.privateKey ?? resolvePrivateKey();
353
+ const origin = params.origin.replace(/\/$/, "");
354
+ const probe = await fetch(new URL("/api/gateway", origin), {
355
+ method: "POST",
356
+ headers: { "Content-Type": "application/json" },
357
+ body: JSON.stringify({
358
+ service: params.service,
359
+ input: params.input,
360
+ clientRequestId: params.clientRequestId
361
+ })
362
+ });
363
+ const probeJson = await probe.json();
364
+ if (probe.status === 200 && probeJson?.ok === true) {
365
+ return {
366
+ gateway: { ok: true, status: 200, body: probeJson },
367
+ settled: false
368
+ };
369
+ }
370
+ const payment = parsePaymentRequired(probeJson);
371
+ const service = await fetchService(origin, params.service);
372
+ const gatewayAddr = params.gateway || (payment ? payment.gateway : await resolveGateway(origin));
373
+ let feeWei = BigInt(service.price_wei);
374
+ let seller = service.seller;
375
+ if (payment) {
376
+ const args = paymentDepositArgs(payment);
377
+ feeWei = args.feeWei;
378
+ seller = args.seller;
379
+ }
380
+ if (feeWei <= 0n) feeWei = GATEWAY_FEE_WEI_DEFAULT;
381
+ const settled = await settlePayment({
382
+ privateKey,
383
+ gateway: gatewayAddr,
384
+ seller,
385
+ service: params.service,
386
+ feeWei,
387
+ input: params.input,
388
+ rpcUrl: params.rpcUrl
389
+ });
390
+ const gateway = await postGatewayPaid({
391
+ origin,
392
+ service: params.service,
393
+ input: params.input,
394
+ proof: settled.proof,
395
+ feeWei: settled.feeWei,
396
+ clientRequestId: params.clientRequestId
397
+ });
398
+ return {
399
+ gateway,
400
+ txHash: settled.proof.txHash,
401
+ paymentId: settled.paymentId,
402
+ settled: true
403
+ };
404
+ }
405
+
406
+ // src/mcp/proxy.ts
407
+ import { createInterface } from "readline";
408
+
409
+ // src/mcp/toolNames.ts
410
+ function slugFromToolName(name) {
411
+ if (!name.startsWith("arcdot_")) return null;
412
+ if (name === "arcdot_catalog" || name === "arcdot_health") return null;
413
+ return name.slice("arcdot_".length).replace(/_/g, "-");
414
+ }
415
+
416
+ // src/client/mcp.ts
417
+ async function mcpRpc(origin, method, params, id = 1) {
418
+ const endpoint = new URL("/api/mcp", origin.replace(/\/$/, ""));
419
+ const res = await fetch(endpoint, {
420
+ method: "POST",
421
+ headers: { "Content-Type": "application/json" },
422
+ body: JSON.stringify({
423
+ jsonrpc: "2.0",
424
+ id,
425
+ method,
426
+ params: params ?? {}
427
+ })
428
+ });
429
+ return await res.json();
430
+ }
431
+ async function callMcpToolWithAutoSettle(params) {
432
+ const origin = params.origin.replace(/\/$/, "");
433
+ const args = { ...params.arguments ?? {} };
434
+ const first = await mcpRpc(origin, "tools/call", {
435
+ name: params.name,
436
+ arguments: args
437
+ });
438
+ if (first.error) return first;
439
+ const needed = parseMcpPaymentNeeded(first.result);
440
+ if (!needed) return first;
441
+ const privateKey = params.privateKey ?? resolvePrivateKey();
442
+ const deposit = paymentDepositArgs(needed.payment);
443
+ const slug = needed.serviceSlug || slugFromToolName(params.name) || String(args.service ?? "");
444
+ if (!slug) {
445
+ throw new Error(
446
+ `Cannot settle: missing service slug for tool ${params.name}`
447
+ );
448
+ }
449
+ const input = {
450
+ prompt: typeof args.prompt === "string" ? args.prompt : JSON.stringify(args)
451
+ };
452
+ const gateway = params.gateway || deposit.gateway || await resolveGateway(origin);
453
+ const settled = await settlePayment({
454
+ privateKey,
455
+ gateway,
456
+ seller: deposit.seller,
457
+ service: slug,
458
+ feeWei: deposit.feeWei,
459
+ input,
460
+ rpcUrl: params.rpcUrl
461
+ });
462
+ const retryArgs = {
463
+ ...args,
464
+ payment: {
465
+ txHash: settled.proof.txHash,
466
+ address: settled.proof.address,
467
+ signature: settled.proof.signature,
468
+ issuedAt: settled.proof.issuedAt,
469
+ expiresAt: settled.proof.expiresAt
470
+ }
471
+ };
472
+ return mcpRpc(origin, "tools/call", {
473
+ name: params.name,
474
+ arguments: retryArgs
475
+ }, 2);
476
+ }
477
+
478
+ // src/mcp/proxy.ts
479
+ function write(msg) {
480
+ process.stdout.write(JSON.stringify(msg) + "\n");
481
+ }
482
+ function ok(id, result) {
483
+ write({ jsonrpc: "2.0", id: id ?? null, result });
484
+ }
485
+ function fail(id, code, message) {
486
+ write({
487
+ jsonrpc: "2.0",
488
+ id: id ?? null,
489
+ error: { code, message }
490
+ });
491
+ }
492
+ async function runMcpProxy(origin) {
493
+ const base = origin.replace(/\/$/, "");
494
+ const rl = createInterface({ input: process.stdin, crlfDelay: Infinity });
495
+ console.error(`[arcdot] MCP proxy \u2192 ${base}/api/mcp`);
496
+ for await (const line of rl) {
497
+ const trimmed = line.trim();
498
+ if (!trimmed) continue;
499
+ let msg;
500
+ try {
501
+ msg = JSON.parse(trimmed);
502
+ } catch {
503
+ fail(null, -32700, "Parse error");
504
+ continue;
505
+ }
506
+ const id = msg.id;
507
+ const method = msg.method;
508
+ if (method === "notifications/initialized" || id === void 0) {
509
+ if (method && method.startsWith("notifications/")) continue;
510
+ }
511
+ try {
512
+ if (method === "initialize") {
513
+ const remote = await mcpRpc(base, "initialize", msg.params);
514
+ if (remote.error) {
515
+ fail(id, remote.error.code, remote.error.message);
516
+ } else {
517
+ const result = remote.result;
518
+ ok(id, result ?? {
519
+ protocolVersion: "2024-11-05",
520
+ capabilities: { tools: {} },
521
+ serverInfo: { name: "arcdot-proxy", version: "0.1.0" }
522
+ });
523
+ }
524
+ continue;
525
+ }
526
+ if (method === "ping") {
527
+ ok(id, {});
528
+ continue;
529
+ }
530
+ if (method === "tools/list") {
531
+ const remote = await mcpRpc(base, "tools/list", msg.params);
532
+ if (remote.error) fail(id, remote.error.code, remote.error.message);
533
+ else ok(id, remote.result);
534
+ continue;
535
+ }
536
+ if (method === "tools/call") {
537
+ const p = msg.params;
538
+ if (!p?.name) {
539
+ fail(id, -32602, "tools/call requires params.name");
540
+ continue;
541
+ }
542
+ const remote = await callMcpToolWithAutoSettle({
543
+ origin: base,
544
+ name: p.name,
545
+ arguments: p.arguments
546
+ });
547
+ if (remote.error) fail(id, remote.error.code, remote.error.message);
548
+ else ok(id, remote.result);
549
+ continue;
550
+ }
551
+ if (method) {
552
+ const remote = await mcpRpc(base, method, msg.params);
553
+ if (remote.error) fail(id, remote.error.code, remote.error.message);
554
+ else ok(id, remote.result);
555
+ continue;
556
+ }
557
+ fail(id, -32600, "Invalid Request");
558
+ } catch (err) {
559
+ fail(
560
+ id,
561
+ -32e3,
562
+ err instanceof Error ? err.message : "Proxy error"
563
+ );
564
+ }
565
+ }
566
+ }
567
+
568
+ // src/cli.ts
569
+ function usage() {
570
+ console.log(`
571
+ arcdot \u2014 buyer agent client (keys stay on your machine)
572
+
573
+ Usage:
574
+ arcdot wallet create [--force]
575
+ arcdot wallet address
576
+ arcdot wallet balance
577
+ arcdot unlock --origin <url> --service <slug> [--prompt <text>]
578
+ arcdot mcp --origin <url>
579
+
580
+ Env:
581
+ ARCDOT_ORIGIN Default origin for unlock / mcp
582
+ ARCDOT_PRIVATE_KEY Override ~/.arcdot/wallet.json
583
+ AGENT_PRIVATE_KEY Alias for ARCDOT_PRIVATE_KEY
584
+ ARC_RPC_URL Arc RPC (default https://rpc.mainnet.arc.io)
585
+ ARCDOT_GATEWAY Override gateway address
586
+ ARCDOT_HOME Override config dir (default ~/.arcdot)
587
+ `);
588
+ }
589
+ function argValue(args, name) {
590
+ const i = args.indexOf(name);
591
+ if (i === -1) return void 0;
592
+ return args[i + 1];
593
+ }
594
+ function hasFlag(args, name) {
595
+ return args.includes(name);
596
+ }
597
+ async function main() {
598
+ const argv = process.argv.slice(2);
599
+ const cmd = argv[0];
600
+ if (!cmd || cmd === "-h" || cmd === "--help") {
601
+ usage();
602
+ process.exit(cmd ? 0 : 1);
603
+ }
604
+ if (cmd === "wallet") {
605
+ const sub = argv[1];
606
+ if (sub === "create") {
607
+ const wallet = createWallet({ force: hasFlag(argv, "--force") });
608
+ console.log(`
609
+ Created agent wallet (local only)
610
+ =================================
611
+ Address: ${wallet.address}
612
+ File: ${walletPath()}
613
+
614
+ NEXT STEPS
615
+ 1. Fund ${wallet.address} with native USDC on Arc Mainnet (chain 5042).
616
+ ${ARC_EXPLORER}/address/${wallet.address}
617
+ 2. Add MCP in Cursor with the local proxy (see Hub), or:
618
+ arcdot unlock --origin https://YOUR_HOST --service quick-brief --prompt "Hi"
619
+
620
+ Private key is stored at ${walletPath()} (mode 0600).
621
+ It was also printed once below \u2014 save it offline if you need a backup.
622
+ Do NOT put this key on the arcdot. server.
623
+
624
+ Private key: ${wallet.privateKey}
625
+ `);
626
+ return;
627
+ }
628
+ if (sub === "address") {
629
+ const w = loadWallet();
630
+ if (!w) {
631
+ const key = resolvePrivateKey();
632
+ console.log(walletAccountFromKey(key).address);
633
+ return;
634
+ }
635
+ console.log(w.address);
636
+ return;
637
+ }
638
+ if (sub === "balance") {
639
+ const key = resolvePrivateKey();
640
+ const address = walletAccountFromKey(key).address;
641
+ const { formatted, wei } = await getNativeBalance(address);
642
+ console.log(
643
+ JSON.stringify({ address, balanceUsdc: formatted, wei: wei.toString() }, null, 2)
644
+ );
645
+ return;
646
+ }
647
+ console.error("Unknown wallet command. Use create | address | balance");
648
+ process.exit(1);
649
+ }
650
+ if (cmd === "unlock") {
651
+ const origin = argValue(argv, "--origin") || process.env.ARCDOT_ORIGIN || "";
652
+ const service = argValue(argv, "--service") || "quick-brief";
653
+ const prompt = argValue(argv, "--prompt") || "Say hello in one short sentence.";
654
+ if (!origin) {
655
+ console.error("Missing --origin or ARCDOT_ORIGIN");
656
+ process.exit(1);
657
+ }
658
+ const result = await unlockWithAutoSettle({
659
+ origin,
660
+ service,
661
+ input: { prompt },
662
+ clientRequestId: `arcdot-cli-${Date.now()}`
663
+ });
664
+ console.log(JSON.stringify(result, null, 2));
665
+ if (!result.gateway.ok) process.exit(1);
666
+ return;
667
+ }
668
+ if (cmd === "mcp") {
669
+ const origin = argValue(argv, "--origin") || process.env.ARCDOT_ORIGIN || "";
670
+ if (!origin) {
671
+ console.error("Missing --origin or ARCDOT_ORIGIN");
672
+ process.exit(1);
673
+ }
674
+ await runMcpProxy(origin);
675
+ return;
676
+ }
677
+ console.error(`Unknown command: ${cmd}`);
678
+ usage();
679
+ process.exit(1);
680
+ }
681
+ main().catch((err) => {
682
+ console.error(err instanceof Error ? err.message : err);
683
+ process.exit(1);
684
+ });
685
+ //# sourceMappingURL=cli.js.map