@x402r/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.
package/SKILL.md ADDED
@@ -0,0 +1,128 @@
1
+ ---
2
+ name: x402r-dispute
3
+ description: File and track payment disputes on the x402r refundable payments protocol
4
+ version: 0.1.0
5
+ author: x402r
6
+ tags: [x402r, payments, disputes, web3, arbitration]
7
+ ---
8
+
9
+ # x402r Dispute Resolution CLI
10
+
11
+ You help users file and track payment disputes on the x402r protocol. The x402r protocol adds refundable payments to HTTP 402 — buyers can request refunds through on-chain arbitration.
12
+
13
+ ## Installation
14
+
15
+ The CLI is available via npx (no install needed):
16
+
17
+ ```bash
18
+ npx @x402r/cli <command>
19
+ ```
20
+
21
+ Or install globally:
22
+
23
+ ```bash
24
+ npm install -g @x402r/cli
25
+ ```
26
+
27
+ ## First-Time Setup
28
+
29
+ Before using any commands, configure the CLI with the user's wallet and operator:
30
+
31
+ ```bash
32
+ x402r config --key <private-key> --operator <operator-address> --arbiter-url <arbiter-server-url>
33
+ ```
34
+
35
+ - `--key`: The user's Ethereum private key (0x-prefixed). Stored in `~/.x402r/config.json`.
36
+ - `--operator`: The PaymentOperator contract address for the marketplace.
37
+ - `--arbiter-url`: URL of the arbiter server (e.g., `https://arbiter.example.com`). Defaults to `http://localhost:3000`.
38
+ - `--network`: Network ID in EIP-155 format (default: `eip155:84532` for Base Sepolia).
39
+ - `--rpc`: Custom RPC URL (optional).
40
+
41
+ To view current config: `x402r config`
42
+
43
+ ## Commands
44
+
45
+ ### File a Dispute
46
+
47
+ Creates an on-chain refund request and submits evidence in one step:
48
+
49
+ ```bash
50
+ x402r dispute "Service was not delivered as promised" --evidence "Paid for API access but received 503 errors for 3 hours"
51
+ ```
52
+
53
+ Options:
54
+ - First argument (required): The reason for the dispute
55
+ - `-e, --evidence <text>`: Additional evidence text
56
+ - `-f, --file <path>`: Path to a JSON file with structured evidence
57
+ - `-p, --payment-json <json>`: Payment info JSON (uses saved state from last payment if omitted)
58
+ - `-n, --nonce <nonce>`: Nonce for the refund request (default: 0)
59
+ - `-a, --amount <amount>`: Refund amount in token units (default: full payment amount)
60
+
61
+ The command saves dispute state to `~/.x402r/last-dispute.json` so subsequent commands can reference it.
62
+
63
+ ### Check Dispute Status
64
+
65
+ ```bash
66
+ x402r status
67
+ ```
68
+
69
+ Options:
70
+ - `--id <compositeKey>`: Look up by composite key
71
+ - `-p, --payment-json <json>`: Payment info JSON
72
+ - `-n, --nonce <nonce>`: Nonce
73
+
74
+ Tries the arbiter server first, falls back to on-chain query. Returns: Pending, Approved, Denied, or Cancelled.
75
+
76
+ ### List Disputes
77
+
78
+ ```bash
79
+ x402r list
80
+ ```
81
+
82
+ Options:
83
+ - `-r, --receiver <address>`: Filter by receiver address
84
+ - `--offset <n>`: Pagination offset (default: 0)
85
+ - `--count <n>`: Number of results (default: 20)
86
+
87
+ Lists disputes from the arbiter server with pagination.
88
+
89
+ ### View Evidence
90
+
91
+ ```bash
92
+ x402r show
93
+ ```
94
+
95
+ Shows all evidence entries (payer, merchant, arbiter) for a dispute. Each entry shows: role, submitter address, timestamp, and CID.
96
+
97
+ Options:
98
+ - `-p, --payment-json <json>`: Payment info JSON
99
+ - `-n, --nonce <nonce>`: Nonce
100
+
101
+ ### Verify Arbiter Ruling
102
+
103
+ ```bash
104
+ x402r verify
105
+ ```
106
+
107
+ Replays the arbiter's AI evaluation to verify the commitment hash matches. Shows:
108
+ - Commitment hash, prompt hash, response hash, seed
109
+ - The AI's decision, confidence, and reasoning
110
+
111
+ Options:
112
+ - `-p, --payment-json <json>`: Payment info JSON
113
+ - `-n, --nonce <nonce>`: Nonce
114
+
115
+ ## Typical Workflow
116
+
117
+ 1. User makes an HTTP 402 payment and receives poor service
118
+ 2. `x402r dispute "reason" --evidence "details"` — files the dispute
119
+ 3. `x402r status` — checks if the arbiter has ruled
120
+ 4. `x402r show` — views all evidence from both parties and the arbiter
121
+ 5. `x402r verify` — verifies the AI ruling was deterministic
122
+
123
+ ## Important Notes
124
+
125
+ - The CLI saves state between commands. After `dispute`, you can run `status`, `show`, `verify` without re-specifying payment info.
126
+ - Evidence can be stored on IPFS (if Pinata keys are configured) or inline as JSON strings.
127
+ - The `verify` command requires the arbiter server to be running — it replays the AI evaluation server-side.
128
+ - All on-chain operations require ETH for gas on the configured network.
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env tsx
2
+ /**
3
+ * x402r CLI — Agent-friendly dispute resolution tool
4
+ *
5
+ * Usage:
6
+ * x402r config --key 0x... --operator 0x...
7
+ * x402r dispute "reason" --evidence "details"
8
+ * x402r status
9
+ * x402r verify
10
+ * x402r list
11
+ * x402r show
12
+ */
13
+ export {};
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * x402r CLI — Agent-friendly dispute resolution tool
4
+ *
5
+ * Usage:
6
+ * x402r config --key 0x... --operator 0x...
7
+ * x402r dispute "reason" --evidence "details"
8
+ * x402r status
9
+ * x402r verify
10
+ * x402r list
11
+ * x402r show
12
+ */
13
+ import { Command } from "commander";
14
+ import { config as dotenvConfig } from "dotenv";
15
+ import { fileURLToPath } from "url";
16
+ import { dirname, join } from "path";
17
+ import { registerConfigCommand } from "../src/commands/config.js";
18
+ import { registerDisputeCommand } from "../src/commands/dispute.js";
19
+ import { registerStatusCommand } from "../src/commands/status.js";
20
+ import { registerVerifyCommand } from "../src/commands/verify.js";
21
+ import { registerListCommand } from "../src/commands/list.js";
22
+ import { registerShowCommand } from "../src/commands/show.js";
23
+ // Load .env from cli/ directory
24
+ const __filename = fileURLToPath(import.meta.url);
25
+ const __dirname = dirname(__filename);
26
+ dotenvConfig({ path: join(__dirname, "..", ".env") });
27
+ const program = new Command();
28
+ program
29
+ .name("x402r")
30
+ .description("Agent-friendly CLI for x402r dispute resolution")
31
+ .version("0.1.0");
32
+ registerConfigCommand(program);
33
+ registerDisputeCommand(program);
34
+ registerStatusCommand(program);
35
+ registerVerifyCommand(program);
36
+ registerListCommand(program);
37
+ registerShowCommand(program);
38
+ program.parse();
39
+ //# sourceMappingURL=x402r.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"x402r.js","sourceRoot":"","sources":["../../bin/x402r.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,MAAM,IAAI,YAAY,EAAE,MAAM,QAAQ,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAE9D,gCAAgC;AAChC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AACtC,YAAY,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;AAEtD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,OAAO,CAAC;KACb,WAAW,CAAC,iDAAiD,CAAC;KAC9D,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,qBAAqB,CAAC,OAAO,CAAC,CAAC;AAC/B,sBAAsB,CAAC,OAAO,CAAC,CAAC;AAChC,qBAAqB,CAAC,OAAO,CAAC,CAAC;AAC/B,qBAAqB,CAAC,OAAO,CAAC,CAAC;AAC/B,mBAAmB,CAAC,OAAO,CAAC,CAAC;AAC7B,mBAAmB,CAAC,OAAO,CAAC,CAAC;AAE7B,OAAO,CAAC,KAAK,EAAE,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * config command — Save/load CLI configuration
3
+ */
4
+ import type { Command } from "commander";
5
+ export declare function registerConfigCommand(program: Command): void;
@@ -0,0 +1,54 @@
1
+ /**
2
+ * config command — Save/load CLI configuration
3
+ */
4
+ import { saveConfigFile, printConfig } from "../config.js";
5
+ export function registerConfigCommand(program) {
6
+ program
7
+ .command("config")
8
+ .description("Save or view CLI configuration")
9
+ .option("-k, --key <privateKey>", "Set private key")
10
+ .option("-o, --operator <address>", "Set operator address")
11
+ .option("-a, --arbiter-url <url>", "Set arbiter server URL")
12
+ .option("-n, --network <networkId>", "Set network ID (e.g., eip155:84532)")
13
+ .option("-r, --rpc <url>", "Set RPC URL")
14
+ .option("--pinata-key <key>", "Set Pinata API key")
15
+ .option("--pinata-secret <secret>", "Set Pinata secret key")
16
+ .action((options) => {
17
+ const updates = {};
18
+ let hasUpdates = false;
19
+ if (options.key) {
20
+ updates.privateKey = options.key;
21
+ hasUpdates = true;
22
+ }
23
+ if (options.operator) {
24
+ updates.operatorAddress = options.operator;
25
+ hasUpdates = true;
26
+ }
27
+ if (options.arbiterUrl) {
28
+ updates.arbiterUrl = options.arbiterUrl;
29
+ hasUpdates = true;
30
+ }
31
+ if (options.network) {
32
+ updates.networkId = options.network;
33
+ hasUpdates = true;
34
+ }
35
+ if (options.rpc) {
36
+ updates.rpcUrl = options.rpc;
37
+ hasUpdates = true;
38
+ }
39
+ if (options.pinataKey) {
40
+ updates.pinataApiKey = options.pinataKey;
41
+ hasUpdates = true;
42
+ }
43
+ if (options.pinataSecret) {
44
+ updates.pinataSecretKey = options.pinataSecret;
45
+ hasUpdates = true;
46
+ }
47
+ if (hasUpdates) {
48
+ saveConfigFile(updates);
49
+ console.log("Config updated.");
50
+ }
51
+ printConfig();
52
+ });
53
+ }
54
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/commands/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,cAAc,EAAE,WAAW,EAAsB,MAAM,cAAc,CAAC;AAE/E,MAAM,UAAU,qBAAqB,CAAC,OAAgB;IACpD,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,gCAAgC,CAAC;SAC7C,MAAM,CAAC,wBAAwB,EAAE,iBAAiB,CAAC;SACnD,MAAM,CAAC,0BAA0B,EAAE,sBAAsB,CAAC;SAC1D,MAAM,CAAC,yBAAyB,EAAE,wBAAwB,CAAC;SAC3D,MAAM,CAAC,2BAA2B,EAAE,qCAAqC,CAAC;SAC1E,MAAM,CAAC,iBAAiB,EAAE,aAAa,CAAC;SACxC,MAAM,CAAC,oBAAoB,EAAE,oBAAoB,CAAC;SAClD,MAAM,CAAC,0BAA0B,EAAE,uBAAuB,CAAC;SAC3D,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE;QAClB,MAAM,OAAO,GAAkB,EAAE,CAAC;QAClC,IAAI,UAAU,GAAG,KAAK,CAAC;QAEvB,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;YAChB,OAAO,CAAC,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC;YACjC,UAAU,GAAG,IAAI,CAAC;QACpB,CAAC;QACD,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YACrB,OAAO,CAAC,eAAe,GAAG,OAAO,CAAC,QAAQ,CAAC;YAC3C,UAAU,GAAG,IAAI,CAAC;QACpB,CAAC;QACD,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;YACvB,OAAO,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;YACxC,UAAU,GAAG,IAAI,CAAC;QACpB,CAAC;QACD,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO,CAAC,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC;YACpC,UAAU,GAAG,IAAI,CAAC;QACpB,CAAC;QACD,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;YAChB,OAAO,CAAC,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;YAC7B,UAAU,GAAG,IAAI,CAAC;QACpB,CAAC;QACD,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;YACtB,OAAO,CAAC,YAAY,GAAG,OAAO,CAAC,SAAS,CAAC;YACzC,UAAU,GAAG,IAAI,CAAC;QACpB,CAAC;QACD,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;YACzB,OAAO,CAAC,eAAe,GAAG,OAAO,CAAC,YAAY,CAAC;YAC/C,UAAU,GAAG,IAAI,CAAC;QACpB,CAAC;QAED,IAAI,UAAU,EAAE,CAAC;YACf,cAAc,CAAC,OAAO,CAAC,CAAC;YACxB,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;QACjC,CAAC;QAED,WAAW,EAAE,CAAC;IAChB,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * dispute command — All-in-one: requestRefund + pin evidence + submitEvidence
3
+ */
4
+ import type { Command } from "commander";
5
+ export declare function registerDisputeCommand(program: Command): void;
@@ -0,0 +1,121 @@
1
+ /**
2
+ * dispute command — All-in-one: requestRefund + pin evidence + submitEvidence
3
+ */
4
+ import { X402rClient } from "@x402r/client";
5
+ import { initCli } from "../setup.js";
6
+ import { getPaymentInfo, saveDisputeState } from "../state.js";
7
+ import { pinToIpfs } from "../ipfs.js";
8
+ export function registerDisputeCommand(program) {
9
+ program
10
+ .command("dispute")
11
+ .description("Create a dispute for the last payment (requestRefund + submit evidence)")
12
+ .argument("<reason>", "Reason for the dispute")
13
+ .option("-e, --evidence <text>", "Additional evidence text")
14
+ .option("-f, --file <path>", "Path to evidence file (JSON)")
15
+ .option("-p, --payment-json <json>", "Payment info JSON (uses saved state if omitted)")
16
+ .option("-n, --nonce <nonce>", "Nonce (default: 0)", "0")
17
+ .option("-a, --amount <amount>", "Refund amount (default: full payment amount)")
18
+ .action(async (reason, options) => {
19
+ const { publicClient, walletClient, addresses, operatorAddress } = initCli();
20
+ const paymentInfo = getPaymentInfo(options);
21
+ const nonce = BigInt(options.nonce);
22
+ const amount = options.amount ? BigInt(options.amount) : paymentInfo.maxAmount;
23
+ console.log("\n=== Creating Dispute ===");
24
+ console.log(" Reason:", reason);
25
+ console.log(" Amount:", amount.toString());
26
+ console.log(" Nonce:", nonce.toString());
27
+ const client = new X402rClient({
28
+ publicClient: publicClient,
29
+ walletClient: walletClient,
30
+ operatorAddress,
31
+ refundRequestAddress: addresses.refundRequestAddress,
32
+ refundRequestEvidenceAddress: addresses.evidenceAddress,
33
+ chainId: addresses.chainId,
34
+ });
35
+ // Step 1: Request refund on-chain
36
+ console.log("\n[1/3] Requesting refund on-chain...");
37
+ let refundTxHash;
38
+ try {
39
+ const hasRequest = await client.hasRefundRequest(paymentInfo, nonce);
40
+ if (hasRequest) {
41
+ const status = await client.getRefundStatus(paymentInfo, nonce);
42
+ const statusNames = ["Pending", "Approved", "Denied", "Cancelled"];
43
+ console.log(` Refund request already exists (status: ${statusNames[status] || status})`);
44
+ }
45
+ else {
46
+ const { txHash } = await client.requestRefund(paymentInfo, amount, nonce);
47
+ refundTxHash = txHash;
48
+ console.log(" Refund requested:", txHash);
49
+ console.log(" Waiting for confirmation...");
50
+ await publicClient.waitForTransactionReceipt({ hash: txHash });
51
+ console.log(" Confirmed.");
52
+ }
53
+ }
54
+ catch (error) {
55
+ console.error(" Failed to request refund:", error instanceof Error ? error.message : error);
56
+ process.exit(1);
57
+ }
58
+ // Step 2: Build and pin evidence
59
+ console.log("\n[2/3] Building and pinning evidence...");
60
+ let fileContent;
61
+ if (options.file) {
62
+ try {
63
+ const { readFileSync } = await import("fs");
64
+ fileContent = JSON.parse(readFileSync(options.file, "utf-8"));
65
+ }
66
+ catch (error) {
67
+ console.error(" Failed to read evidence file:", error instanceof Error ? error.message : error);
68
+ process.exit(1);
69
+ }
70
+ }
71
+ const evidenceData = {
72
+ reason,
73
+ timestamp: new Date().toISOString(),
74
+ payer: paymentInfo.payer,
75
+ receiver: paymentInfo.receiver,
76
+ };
77
+ if (options.evidence) {
78
+ evidenceData.evidence = options.evidence;
79
+ }
80
+ if (fileContent) {
81
+ evidenceData.attachments = fileContent;
82
+ }
83
+ let cid;
84
+ try {
85
+ cid = await pinToIpfs(evidenceData);
86
+ }
87
+ catch (error) {
88
+ console.error(" Failed to pin evidence:", error instanceof Error ? error.message : error);
89
+ process.exit(1);
90
+ }
91
+ // Step 3: Submit evidence on-chain
92
+ console.log("\n[3/3] Submitting evidence on-chain...");
93
+ let evidenceTxHash;
94
+ try {
95
+ const { txHash } = await client.submitEvidence(paymentInfo, nonce, cid);
96
+ evidenceTxHash = txHash;
97
+ console.log(" Evidence submitted:", txHash);
98
+ }
99
+ catch (error) {
100
+ console.error(" Failed to submit evidence:", error instanceof Error ? error.message : error);
101
+ process.exit(1);
102
+ }
103
+ // Save dispute state
104
+ saveDisputeState({
105
+ nonce: nonce.toString(),
106
+ refundTxHash,
107
+ evidenceTxHash,
108
+ evidenceCid: cid,
109
+ timestamp: new Date().toISOString(),
110
+ });
111
+ console.log("\n=== Dispute Created ===");
112
+ if (refundTxHash)
113
+ console.log(" Refund Tx:", refundTxHash);
114
+ if (evidenceTxHash)
115
+ console.log(" Evidence Tx:", evidenceTxHash);
116
+ console.log(" Evidence CID:", cid);
117
+ console.log("\n State saved to ~/.x402r/last-dispute.json");
118
+ console.log(" Run 'x402r status' to check dispute status");
119
+ });
120
+ }
121
+ //# sourceMappingURL=dispute.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dispute.js","sourceRoot":"","sources":["../../../src/commands/dispute.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * list command — List disputes via arbiter server or SDK
3
+ */
4
+ import type { Command } from "commander";
5
+ export declare function registerListCommand(program: Command): void;
@@ -0,0 +1,46 @@
1
+ /**
2
+ * list command — List disputes via arbiter server or SDK
3
+ */
4
+ import { getConfig } from "../config.js";
5
+ export function registerListCommand(program) {
6
+ program
7
+ .command("list")
8
+ .description("List pending disputes")
9
+ .option("-r, --receiver <address>", "Filter by receiver address")
10
+ .option("--offset <n>", "Offset for pagination", "0")
11
+ .option("--count <n>", "Number of results", "20")
12
+ .action(async (options) => {
13
+ const config = getConfig();
14
+ const url = config.arbiterUrl;
15
+ console.log(`\nQuerying disputes from ${url}...`);
16
+ const params = new URLSearchParams();
17
+ if (options.receiver)
18
+ params.set("receiver", options.receiver);
19
+ params.set("offset", options.offset);
20
+ params.set("count", options.count);
21
+ try {
22
+ const response = await fetch(`${url}/api/disputes?${params.toString()}`);
23
+ if (!response.ok) {
24
+ const error = await response.text();
25
+ console.error(`\nArbiter returned ${response.status}:`, error);
26
+ process.exit(1);
27
+ }
28
+ const data = await response.json();
29
+ console.log(`\n=== Disputes (${data.keys.length} of ${data.total}) ===`);
30
+ if (data.keys.length === 0) {
31
+ console.log(" No pending disputes found.");
32
+ return;
33
+ }
34
+ for (let i = 0; i < data.keys.length; i++) {
35
+ console.log(` [${parseInt(data.offset) + i}] ${data.keys[i]}`);
36
+ }
37
+ console.log(`\n Showing ${data.offset}-${parseInt(data.offset) + data.keys.length} of ${data.total}`);
38
+ }
39
+ catch (error) {
40
+ console.error("\nFailed to list disputes:", error instanceof Error ? error.message : error);
41
+ console.error("Is the arbiter server running at", url, "?");
42
+ process.exit(1);
43
+ }
44
+ });
45
+ }
46
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/commands/list.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,MAAM,UAAU,mBAAmB,CAAC,OAAgB;IAClD,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,uBAAuB,CAAC;SACpC,MAAM,CAAC,0BAA0B,EAAE,4BAA4B,CAAC;SAChE,MAAM,CAAC,cAAc,EAAE,uBAAuB,EAAE,GAAG,CAAC;SACpD,MAAM,CAAC,aAAa,EAAE,mBAAmB,EAAE,IAAI,CAAC;SAChD,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;QACxB,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAG,MAAM,CAAC,UAAU,CAAC;QAE9B,OAAO,CAAC,GAAG,CAAC,4BAA4B,GAAG,KAAK,CAAC,CAAC;QAElD,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE,CAAC;QACrC,IAAI,OAAO,CAAC,QAAQ;YAAE,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC/D,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QACrC,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;QAEnC,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,GAAG,iBAAiB,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;YAEzE,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;gBACpC,OAAO,CAAC,KAAK,CAAC,sBAAsB,QAAQ,CAAC,MAAM,GAAG,EAAE,KAAK,CAAC,CAAC;gBAC/D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YAED,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAK/B,CAAC;YAEF,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,CAAC,IAAI,CAAC,MAAM,OAAO,IAAI,CAAC,KAAK,OAAO,CAAC,CAAC;YAEzE,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC3B,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;gBAC5C,OAAO;YACT,CAAC;YAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC1C,OAAO,CAAC,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAClE,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,CAAC,MAAM,IAAI,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,OAAO,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;QACzG,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,4BAA4B,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;YAC5F,OAAO,CAAC,KAAK,CAAC,kCAAkC,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;YAC5D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * show command — Show evidence for a dispute
3
+ */
4
+ import type { Command } from "commander";
5
+ export declare function registerShowCommand(program: Command): void;
@@ -0,0 +1,56 @@
1
+ /**
2
+ * show command — Show evidence for a dispute
3
+ */
4
+ import { X402rClient } from "@x402r/client";
5
+ import { SubmitterRole } from "@x402r/core";
6
+ import { initReadOnly } from "../setup.js";
7
+ import { getPaymentInfo, getNonce } from "../state.js";
8
+ function shortAddress(address) {
9
+ return `${address.slice(0, 10)}...${address.slice(-8)}`;
10
+ }
11
+ function roleName(role) {
12
+ switch (role) {
13
+ case SubmitterRole.Payer:
14
+ return "Payer";
15
+ case SubmitterRole.Receiver:
16
+ return "Receiver";
17
+ case SubmitterRole.Arbiter:
18
+ return "Arbiter";
19
+ default:
20
+ return `Unknown(${role})`;
21
+ }
22
+ }
23
+ function formatEvidence(evidence, index) {
24
+ const ts = new Date(Number(evidence.timestamp) * 1000).toISOString();
25
+ return ` [${index}] ${roleName(evidence.role)} ${shortAddress(evidence.submitter)} | ${ts} | CID: ${evidence.cid}`;
26
+ }
27
+ export function registerShowCommand(program) {
28
+ program
29
+ .command("show")
30
+ .description("Show all evidence for a dispute")
31
+ .option("-p, --payment-json <json>", "Payment info JSON (uses saved state if omitted)")
32
+ .option("-n, --nonce <nonce>", "Nonce")
33
+ .action(async (options) => {
34
+ const { publicClient, addresses, operatorAddress } = initReadOnly();
35
+ const paymentInfo = getPaymentInfo(options);
36
+ const nonce = getNonce(options);
37
+ const client = new X402rClient({
38
+ publicClient: publicClient,
39
+ operatorAddress,
40
+ refundRequestEvidenceAddress: addresses.evidenceAddress,
41
+ chainId: addresses.chainId,
42
+ });
43
+ console.log("\nFetching evidence...");
44
+ const count = await client.getEvidenceCount(paymentInfo, nonce);
45
+ console.log(`\n=== Evidence (${count} entries) ===`);
46
+ if (count === 0n) {
47
+ console.log(" No evidence submitted.");
48
+ return;
49
+ }
50
+ const entries = await client.getAllEvidence(paymentInfo, nonce);
51
+ for (let i = 0; i < entries.length; i++) {
52
+ console.log(formatEvidence(entries[i], i));
53
+ }
54
+ });
55
+ }
56
+ //# sourceMappingURL=show.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"show.js","sourceRoot":"","sources":["../../../src/commands/show.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAiB,aAAa,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvD,SAAS,YAAY,CAAC,OAAe;IACnC,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAC1D,CAAC;AAED,SAAS,QAAQ,CAAC,IAAmB;IACnC,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,aAAa,CAAC,KAAK;YACtB,OAAO,OAAO,CAAC;QACjB,KAAK,aAAa,CAAC,QAAQ;YACzB,OAAO,UAAU,CAAC;QACpB,KAAK,aAAa,CAAC,OAAO;YACxB,OAAO,SAAS,CAAC;QACnB;YACE,OAAO,WAAW,IAAI,GAAG,CAAC;IAC9B,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,QAAkB,EAAE,KAAa;IACvD,MAAM,EAAE,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;IACrE,OAAO,MAAM,KAAK,KAAK,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,YAAY,CAAC,QAAQ,CAAC,SAAS,CAAC,MAAM,EAAE,WAAW,QAAQ,CAAC,GAAG,EAAE,CAAC;AACtH,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,OAAgB;IAClD,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,iCAAiC,CAAC;SAC9C,MAAM,CAAC,2BAA2B,EAAE,iDAAiD,CAAC;SACtF,MAAM,CAAC,qBAAqB,EAAE,OAAO,CAAC;SACtC,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;QACxB,MAAM,EAAE,YAAY,EAAE,SAAS,EAAE,eAAe,EAAE,GAAG,YAAY,EAAE,CAAC;QACpE,MAAM,WAAW,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;QAC5C,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;QAEhC,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC;YAC7B,YAAY,EAAE,YAAmB;YACjC,eAAe;YACf,4BAA4B,EAAE,SAAS,CAAC,eAAe;YACvD,OAAO,EAAE,SAAS,CAAC,OAAO;SAC3B,CAAC,CAAC;QAEH,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;QAEtC,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;QAChE,OAAO,CAAC,GAAG,CAAC,mBAAmB,KAAK,eAAe,CAAC,CAAC;QAErD,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;YACjB,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;YACxC,OAAO;QACT,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;QAChE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACxC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * status command — Check dispute status via arbiter server or SDK
3
+ */
4
+ import type { Command } from "commander";
5
+ export declare function registerStatusCommand(program: Command): void;
@@ -0,0 +1,62 @@
1
+ /**
2
+ * status command — Check dispute status via arbiter server or SDK
3
+ */
4
+ import { X402rClient } from "@x402r/client";
5
+ import { initReadOnly } from "../setup.js";
6
+ import { getPaymentInfo, getNonce, getCompositeKey } from "../state.js";
7
+ import { getConfig } from "../config.js";
8
+ export function registerStatusCommand(program) {
9
+ program
10
+ .command("status")
11
+ .description("Check the status of a dispute")
12
+ .option("--id <compositeKey>", "Composite key of the dispute")
13
+ .option("-p, --payment-json <json>", "Payment info JSON (uses saved state if omitted)")
14
+ .option("-n, --nonce <nonce>", "Nonce")
15
+ .action(async (options) => {
16
+ const config = getConfig();
17
+ const compositeKey = getCompositeKey(options);
18
+ // Try arbiter server first if composite key available
19
+ if (compositeKey && config.arbiterUrl) {
20
+ try {
21
+ console.log(`\nQuerying arbiter at ${config.arbiterUrl}...`);
22
+ const response = await fetch(`${config.arbiterUrl}/api/dispute/${compositeKey}`);
23
+ if (response.ok) {
24
+ const data = await response.json();
25
+ const statusNames = { 0: "Pending", 1: "Approved", 2: "Denied", 3: "Cancelled" };
26
+ console.log("\n=== Dispute Status ===");
27
+ console.log(" Composite Key:", compositeKey);
28
+ console.log(" Status:", statusNames[data.status] || data.status);
29
+ console.log(" Amount:", data.amount);
30
+ console.log(" Nonce:", data.nonce);
31
+ console.log(" Payment Info Hash:", data.paymentInfoHash);
32
+ return;
33
+ }
34
+ console.log(" Arbiter returned", response.status, "— falling back to on-chain");
35
+ }
36
+ catch {
37
+ console.log(" Arbiter unavailable — falling back to on-chain");
38
+ }
39
+ }
40
+ // Fall back to on-chain query
41
+ const { publicClient, addresses, operatorAddress } = initReadOnly();
42
+ const paymentInfo = getPaymentInfo(options);
43
+ const nonce = getNonce(options);
44
+ const client = new X402rClient({
45
+ publicClient: publicClient,
46
+ operatorAddress,
47
+ refundRequestAddress: addresses.refundRequestAddress,
48
+ chainId: addresses.chainId,
49
+ });
50
+ const hasRequest = await client.hasRefundRequest(paymentInfo, nonce);
51
+ if (!hasRequest) {
52
+ console.log("\nNo refund request found for this payment (nonce:", nonce.toString(), ")");
53
+ return;
54
+ }
55
+ const status = await client.getRefundStatus(paymentInfo, nonce);
56
+ const statusNames = ["Pending", "Approved", "Denied", "Cancelled"];
57
+ console.log("\n=== Dispute Status (on-chain) ===");
58
+ console.log(" Status:", statusNames[status] || status);
59
+ console.log(" Nonce:", nonce.toString());
60
+ });
61
+ }
62
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../../src/commands/status.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * verify command — Replay arbiter evaluation and verify commitment hashes
3
+ */
4
+ import type { Command } from "commander";
5
+ export declare function registerVerifyCommand(program: Command): void;
@@ -0,0 +1,60 @@
1
+ /**
2
+ * verify command — Replay arbiter evaluation and verify commitment hashes
3
+ */
4
+ import { initReadOnly } from "../setup.js";
5
+ import { getPaymentInfo, getNonce } from "../state.js";
6
+ import { getConfig } from "../config.js";
7
+ export function registerVerifyCommand(program) {
8
+ program
9
+ .command("verify")
10
+ .description("Verify arbiter ruling by replaying AI evaluation")
11
+ .option("-p, --payment-json <json>", "Payment info JSON (uses saved state if omitted)")
12
+ .option("-n, --nonce <nonce>", "Nonce")
13
+ .action(async (options) => {
14
+ const config = getConfig();
15
+ const { arbiterUrl } = initReadOnly();
16
+ const paymentInfo = getPaymentInfo(options);
17
+ const nonce = getNonce(options);
18
+ const url = config.arbiterUrl || arbiterUrl;
19
+ console.log(`\nVerifying dispute via ${url}...`);
20
+ try {
21
+ const response = await fetch(`${url}/api/verify`, {
22
+ method: "POST",
23
+ headers: { "Content-Type": "application/json" },
24
+ body: JSON.stringify({
25
+ paymentInfo: JSON.parse(JSON.stringify(paymentInfo, (_, v) => (typeof v === "bigint" ? v.toString() : v))),
26
+ nonce: nonce.toString(),
27
+ }),
28
+ });
29
+ if (!response.ok) {
30
+ const error = await response.text();
31
+ console.error(`\nArbiter returned ${response.status}:`, error);
32
+ process.exit(1);
33
+ }
34
+ const data = await response.json();
35
+ console.log("\n=== Verification Result ===");
36
+ console.log("\n Commitment Hash:", data.replayCommitment.commitmentHash);
37
+ console.log(" Prompt Hash:", data.replayCommitment.promptHash);
38
+ console.log(" Response Hash:", data.replayCommitment.responseHash);
39
+ console.log(" Seed:", data.replayCommitment.seed);
40
+ // Try to parse the AI response
41
+ try {
42
+ const decision = JSON.parse(data.displayContent);
43
+ console.log("\n=== AI Decision (Replay) ===");
44
+ console.log(" Decision:", decision.decision);
45
+ console.log(" Confidence:", decision.confidence);
46
+ console.log(" Reasoning:", decision.reasoning);
47
+ }
48
+ catch {
49
+ console.log("\n Raw Response:", data.displayContent);
50
+ }
51
+ console.log("\n Note:", data.note);
52
+ }
53
+ catch (error) {
54
+ console.error("\nFailed to verify:", error instanceof Error ? error.message : error);
55
+ console.error("Is the arbiter server running at", url, "?");
56
+ process.exit(1);
57
+ }
58
+ });
59
+ }
60
+ //# sourceMappingURL=verify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify.js","sourceRoot":"","sources":["../../../src/commands/verify.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * CLI configuration — loads from ~/.x402r/config.json, .env, and env vars.
3
+ * Priority: env vars > .env > config file > defaults
4
+ */
5
+ export interface CliConfigFile {
6
+ privateKey?: string;
7
+ operatorAddress?: string;
8
+ arbiterUrl?: string;
9
+ networkId?: string;
10
+ rpcUrl?: string;
11
+ pinataApiKey?: string;
12
+ pinataSecretKey?: string;
13
+ }
14
+ /**
15
+ * Load config from ~/.x402r/config.json
16
+ */
17
+ export declare function loadConfigFile(): CliConfigFile;
18
+ /**
19
+ * Save config to ~/.x402r/config.json
20
+ */
21
+ export declare function saveConfigFile(config: CliConfigFile): void;
22
+ /**
23
+ * Get resolved config: env vars > .env > config file > defaults
24
+ */
25
+ export declare function getConfig(): Required<Pick<CliConfigFile, "networkId" | "arbiterUrl">> & CliConfigFile;
26
+ /**
27
+ * Print current config (masked key)
28
+ */
29
+ export declare function printConfig(): void;
@@ -0,0 +1,71 @@
1
+ /**
2
+ * CLI configuration — loads from ~/.x402r/config.json, .env, and env vars.
3
+ * Priority: env vars > .env > config file > defaults
4
+ */
5
+ import * as fs from "fs";
6
+ import * as path from "path";
7
+ import * as os from "os";
8
+ const CONFIG_DIR = path.join(os.homedir(), ".x402r");
9
+ const CONFIG_FILE = path.join(CONFIG_DIR, "config.json");
10
+ /**
11
+ * Load config from ~/.x402r/config.json
12
+ */
13
+ export function loadConfigFile() {
14
+ if (!fs.existsSync(CONFIG_FILE)) {
15
+ return {};
16
+ }
17
+ try {
18
+ return JSON.parse(fs.readFileSync(CONFIG_FILE, "utf-8"));
19
+ }
20
+ catch {
21
+ return {};
22
+ }
23
+ }
24
+ /**
25
+ * Save config to ~/.x402r/config.json
26
+ */
27
+ export function saveConfigFile(config) {
28
+ if (!fs.existsSync(CONFIG_DIR)) {
29
+ fs.mkdirSync(CONFIG_DIR, { recursive: true });
30
+ }
31
+ // Merge with existing config
32
+ const existing = loadConfigFile();
33
+ const merged = { ...existing, ...config };
34
+ // Remove undefined/null values
35
+ for (const key of Object.keys(merged)) {
36
+ if (merged[key] === undefined || merged[key] === null) {
37
+ delete merged[key];
38
+ }
39
+ }
40
+ fs.writeFileSync(CONFIG_FILE, JSON.stringify(merged, null, 2));
41
+ }
42
+ /**
43
+ * Get resolved config: env vars > .env > config file > defaults
44
+ */
45
+ export function getConfig() {
46
+ const file = loadConfigFile();
47
+ return {
48
+ privateKey: process.env.PRIVATE_KEY || file.privateKey,
49
+ operatorAddress: process.env.OPERATOR_ADDRESS || file.operatorAddress,
50
+ arbiterUrl: process.env.ARBITER_URL || file.arbiterUrl || "http://localhost:3000",
51
+ networkId: process.env.NETWORK_ID || file.networkId || "eip155:84532",
52
+ rpcUrl: process.env.RPC_URL || file.rpcUrl || "https://sepolia.base.org",
53
+ pinataApiKey: process.env.PINATA_API_KEY || file.pinataApiKey,
54
+ pinataSecretKey: process.env.PINATA_SECRET_KEY || file.pinataSecretKey,
55
+ };
56
+ }
57
+ /**
58
+ * Print current config (masked key)
59
+ */
60
+ export function printConfig() {
61
+ const config = getConfig();
62
+ console.log("\n=== x402r CLI Config ===");
63
+ console.log(" Private Key:", config.privateKey ? `${config.privateKey.slice(0, 6)}...${config.privateKey.slice(-4)}` : "(not set)");
64
+ console.log(" Operator:", config.operatorAddress || "(not set)");
65
+ console.log(" Arbiter URL:", config.arbiterUrl);
66
+ console.log(" Network:", config.networkId);
67
+ console.log(" RPC URL:", config.rpcUrl);
68
+ console.log(" Pinata API Key:", config.pinataApiKey ? `${config.pinataApiKey.slice(0, 8)}...` : "(not set)");
69
+ console.log(`\n Config file: ${CONFIG_FILE}`);
70
+ }
71
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * IPFS pinning via Pinata API.
3
+ * Falls back to inline string if no Pinata key configured.
4
+ */
5
+ /**
6
+ * Pin JSON to IPFS via Pinata.
7
+ * Returns IPFS CID if Pinata configured, otherwise returns JSON string directly.
8
+ */
9
+ export declare function pinToIpfs(data: Record<string, unknown>): Promise<string>;
@@ -0,0 +1,41 @@
1
+ /**
2
+ * IPFS pinning via Pinata API.
3
+ * Falls back to inline string if no Pinata key configured.
4
+ */
5
+ import { getConfig } from "./config.js";
6
+ /**
7
+ * Pin JSON to IPFS via Pinata.
8
+ * Returns IPFS CID if Pinata configured, otherwise returns JSON string directly.
9
+ */
10
+ export async function pinToIpfs(data) {
11
+ const config = getConfig();
12
+ if (!config.pinataApiKey || !config.pinataSecretKey) {
13
+ console.log(" (No Pinata key — storing evidence as inline string)");
14
+ return JSON.stringify(data);
15
+ }
16
+ console.log(" Pinning to IPFS via Pinata...");
17
+ const response = await fetch("https://api.pinata.cloud/pinning/pinJSONToIPFS", {
18
+ method: "POST",
19
+ headers: {
20
+ "Content-Type": "application/json",
21
+ pinata_api_key: config.pinataApiKey,
22
+ pinata_secret_api_key: config.pinataSecretKey,
23
+ },
24
+ body: JSON.stringify({
25
+ pinataContent: data,
26
+ pinataMetadata: {
27
+ name: `x402r-evidence-${Date.now()}`,
28
+ },
29
+ }),
30
+ });
31
+ if (!response.ok) {
32
+ const text = await response.text();
33
+ console.warn(` Pinata failed (${response.status}): ${text}`);
34
+ console.log(" Falling back to inline string");
35
+ return JSON.stringify(data);
36
+ }
37
+ const result = (await response.json());
38
+ console.log(` Pinned: ${result.IpfsHash}`);
39
+ return result.IpfsHash;
40
+ }
41
+ //# sourceMappingURL=ipfs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ipfs.js","sourceRoot":"","sources":["../../src/ipfs.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAQxC;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,IAA6B;IAC3D,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAE3B,IAAI,CAAC,MAAM,CAAC,YAAY,IAAI,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC;QACpD,OAAO,CAAC,GAAG,CAAC,uDAAuD,CAAC,CAAC;QACrE,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;IAE/C,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,gDAAgD,EAAE;QAC7E,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,cAAc,EAAE,kBAAkB;YAClC,cAAc,EAAE,MAAM,CAAC,YAAY;YACnC,qBAAqB,EAAE,MAAM,CAAC,eAAe;SAC9C;QACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YACnB,aAAa,EAAE,IAAI;YACnB,cAAc,EAAE;gBACd,IAAI,EAAE,kBAAkB,IAAI,CAAC,GAAG,EAAE,EAAE;aACrC;SACF,CAAC;KACH,CAAC,CAAC;IAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnC,OAAO,CAAC,IAAI,CAAC,oBAAoB,QAAQ,CAAC,MAAM,MAAM,IAAI,EAAE,CAAC,CAAC;QAC9D,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;QAC/C,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;IAED,MAAM,MAAM,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAmB,CAAC;IACzD,OAAO,CAAC,GAAG,CAAC,aAAa,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC5C,OAAO,MAAM,CAAC,QAAQ,CAAC;AACzB,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * CLI setup — creates viem clients from resolved config.
3
+ * Ported from x402r-sdk/examples/dev-tools/shared/cli-setup.ts with config file support.
4
+ */
5
+ import { type PublicClient, type WalletClient } from "viem";
6
+ import { type PrivateKeyAccount } from "viem/accounts";
7
+ import { type ResolvedAddresses } from "@x402r/core";
8
+ export interface CliSetup {
9
+ account: PrivateKeyAccount;
10
+ publicClient: PublicClient;
11
+ walletClient: WalletClient;
12
+ networkId: string;
13
+ addresses: ResolvedAddresses;
14
+ operatorAddress: `0x${string}`;
15
+ arbiterUrl: string;
16
+ }
17
+ /**
18
+ * Initialize CLI: validates config, creates viem clients.
19
+ */
20
+ export declare function initCli(): CliSetup;
21
+ /**
22
+ * Read-only setup — no private key required.
23
+ */
24
+ export declare function initReadOnly(): Pick<CliSetup, "publicClient" | "networkId" | "addresses" | "arbiterUrl" | "operatorAddress">;
@@ -0,0 +1,72 @@
1
+ /**
2
+ * CLI setup — creates viem clients from resolved config.
3
+ * Ported from x402r-sdk/examples/dev-tools/shared/cli-setup.ts with config file support.
4
+ */
5
+ import { createPublicClient, createWalletClient, http, } from "viem";
6
+ import { baseSepolia, base, sepolia } from "viem/chains";
7
+ import { privateKeyToAccount } from "viem/accounts";
8
+ import { resolveAddresses } from "@x402r/core";
9
+ import { getConfig } from "./config.js";
10
+ const CHAINS = {
11
+ 84532: baseSepolia,
12
+ 8453: base,
13
+ 11155111: sepolia,
14
+ };
15
+ /**
16
+ * Initialize CLI: validates config, creates viem clients.
17
+ */
18
+ export function initCli() {
19
+ const config = getConfig();
20
+ if (!config.privateKey) {
21
+ console.error("Error: Private key not configured.");
22
+ console.error("Run: x402r config --key 0x...");
23
+ process.exit(1);
24
+ }
25
+ if (!config.operatorAddress) {
26
+ console.error("Error: Operator address not configured.");
27
+ console.error("Run: x402r config --operator 0x...");
28
+ process.exit(1);
29
+ }
30
+ const account = privateKeyToAccount(config.privateKey);
31
+ const addresses = resolveAddresses(config.networkId);
32
+ const chainId = addresses.chainId;
33
+ const chain = CHAINS[chainId];
34
+ if (!chain) {
35
+ console.error(`Unsupported chain ID: ${chainId} (network: ${config.networkId})`);
36
+ process.exit(1);
37
+ }
38
+ const transport = http(config.rpcUrl);
39
+ const publicClient = createPublicClient({ chain, transport });
40
+ const walletClient = createWalletClient({ account, chain, transport });
41
+ return {
42
+ account,
43
+ publicClient,
44
+ walletClient,
45
+ networkId: config.networkId,
46
+ addresses,
47
+ operatorAddress: config.operatorAddress,
48
+ arbiterUrl: config.arbiterUrl,
49
+ };
50
+ }
51
+ /**
52
+ * Read-only setup — no private key required.
53
+ */
54
+ export function initReadOnly() {
55
+ const config = getConfig();
56
+ const addresses = resolveAddresses(config.networkId);
57
+ const chainId = addresses.chainId;
58
+ const chain = CHAINS[chainId];
59
+ if (!chain) {
60
+ console.error(`Unsupported chain ID: ${chainId}`);
61
+ process.exit(1);
62
+ }
63
+ const publicClient = createPublicClient({ chain, transport: http(config.rpcUrl) });
64
+ return {
65
+ publicClient,
66
+ networkId: config.networkId,
67
+ addresses,
68
+ arbiterUrl: config.arbiterUrl,
69
+ operatorAddress: (config.operatorAddress || "0x0000000000000000000000000000000000000000"),
70
+ };
71
+ }
72
+ //# sourceMappingURL=setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/setup.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * State persistence — saves payment and dispute state to ~/.x402r/
3
+ * Ported from x402r-sdk/examples/dev-tools/shared/state.ts with dispute state added.
4
+ */
5
+ import type { PaymentInfo } from "@x402r/core";
6
+ export interface PaymentState {
7
+ paymentInfo: PaymentInfo;
8
+ operatorAddress: string;
9
+ paymentHash: string;
10
+ timestamp: string;
11
+ networkId: string;
12
+ }
13
+ export declare function savePaymentState(state: PaymentState): void;
14
+ export declare function loadPaymentState(): PaymentState | null;
15
+ /**
16
+ * Get PaymentInfo from CLI options or state file.
17
+ */
18
+ export declare function getPaymentInfo(options: {
19
+ paymentJson?: string;
20
+ }): PaymentInfo;
21
+ export interface DisputeState {
22
+ nonce: string;
23
+ compositeKey?: string;
24
+ refundTxHash?: string;
25
+ evidenceTxHash?: string;
26
+ evidenceCid?: string;
27
+ arbiterResponse?: Record<string, unknown>;
28
+ timestamp: string;
29
+ }
30
+ export declare function saveDisputeState(state: DisputeState): void;
31
+ export declare function loadDisputeState(): DisputeState | null;
32
+ /**
33
+ * Get nonce from CLI options or dispute state.
34
+ */
35
+ export declare function getNonce(options: {
36
+ nonce?: string;
37
+ id?: string;
38
+ }): bigint;
39
+ /**
40
+ * Get composite key from CLI options or dispute state.
41
+ */
42
+ export declare function getCompositeKey(options: {
43
+ id?: string;
44
+ }): string | undefined;
@@ -0,0 +1,113 @@
1
+ /**
2
+ * State persistence — saves payment and dispute state to ~/.x402r/
3
+ * Ported from x402r-sdk/examples/dev-tools/shared/state.ts with dispute state added.
4
+ */
5
+ import * as fs from "fs";
6
+ import * as path from "path";
7
+ import * as os from "os";
8
+ import { parsePaymentInfo as coreParsePaymentInfo } from "@x402r/core";
9
+ const STATE_DIR = path.join(os.homedir(), ".x402r");
10
+ const PAYMENT_STATE_FILE = path.join(STATE_DIR, "last-payment.json");
11
+ const DISPUTE_STATE_FILE = path.join(STATE_DIR, "last-dispute.json");
12
+ function ensureDir() {
13
+ if (!fs.existsSync(STATE_DIR)) {
14
+ fs.mkdirSync(STATE_DIR, { recursive: true });
15
+ }
16
+ }
17
+ export function savePaymentState(state) {
18
+ ensureDir();
19
+ const serializable = {
20
+ ...state,
21
+ paymentInfo: {
22
+ ...state.paymentInfo,
23
+ maxAmount: state.paymentInfo.maxAmount.toString(),
24
+ preApprovalExpiry: state.paymentInfo.preApprovalExpiry.toString(),
25
+ authorizationExpiry: state.paymentInfo.authorizationExpiry.toString(),
26
+ refundExpiry: state.paymentInfo.refundExpiry.toString(),
27
+ salt: state.paymentInfo.salt.toString(),
28
+ },
29
+ };
30
+ fs.writeFileSync(PAYMENT_STATE_FILE, JSON.stringify(serializable, null, 2));
31
+ }
32
+ export function loadPaymentState() {
33
+ if (!fs.existsSync(PAYMENT_STATE_FILE)) {
34
+ return null;
35
+ }
36
+ try {
37
+ const raw = JSON.parse(fs.readFileSync(PAYMENT_STATE_FILE, "utf-8"));
38
+ return {
39
+ ...raw,
40
+ paymentInfo: {
41
+ ...raw.paymentInfo,
42
+ maxAmount: BigInt(raw.paymentInfo.maxAmount),
43
+ preApprovalExpiry: BigInt(raw.paymentInfo.preApprovalExpiry),
44
+ authorizationExpiry: BigInt(raw.paymentInfo.authorizationExpiry),
45
+ refundExpiry: BigInt(raw.paymentInfo.refundExpiry),
46
+ salt: BigInt(raw.paymentInfo.salt),
47
+ },
48
+ };
49
+ }
50
+ catch {
51
+ return null;
52
+ }
53
+ }
54
+ /**
55
+ * Get PaymentInfo from CLI options or state file.
56
+ */
57
+ export function getPaymentInfo(options) {
58
+ if (options.paymentJson) {
59
+ try {
60
+ return coreParsePaymentInfo(options.paymentJson);
61
+ }
62
+ catch {
63
+ console.error("Error: Invalid payment JSON");
64
+ process.exit(1);
65
+ }
66
+ }
67
+ const state = loadPaymentState();
68
+ if (state) {
69
+ console.log(` (Using saved payment from ${state.timestamp})`);
70
+ return state.paymentInfo;
71
+ }
72
+ console.error("Error: No payment state found. Make a payment first or provide --payment-json.");
73
+ process.exit(1);
74
+ }
75
+ export function saveDisputeState(state) {
76
+ ensureDir();
77
+ fs.writeFileSync(DISPUTE_STATE_FILE, JSON.stringify(state, null, 2));
78
+ }
79
+ export function loadDisputeState() {
80
+ if (!fs.existsSync(DISPUTE_STATE_FILE)) {
81
+ return null;
82
+ }
83
+ try {
84
+ return JSON.parse(fs.readFileSync(DISPUTE_STATE_FILE, "utf-8"));
85
+ }
86
+ catch {
87
+ return null;
88
+ }
89
+ }
90
+ /**
91
+ * Get nonce from CLI options or dispute state.
92
+ */
93
+ export function getNonce(options) {
94
+ if (options.nonce !== undefined) {
95
+ return BigInt(options.nonce);
96
+ }
97
+ const state = loadDisputeState();
98
+ if (state) {
99
+ console.log(` (Using saved dispute nonce: ${state.nonce})`);
100
+ return BigInt(state.nonce);
101
+ }
102
+ return 0n;
103
+ }
104
+ /**
105
+ * Get composite key from CLI options or dispute state.
106
+ */
107
+ export function getCompositeKey(options) {
108
+ if (options.id)
109
+ return options.id;
110
+ const state = loadDisputeState();
111
+ return state?.compositeKey;
112
+ }
113
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/state.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@x402r/cli",
3
+ "version": "0.1.0",
4
+ "description": "Agent-friendly CLI for x402r dispute resolution",
5
+ "type": "module",
6
+ "bin": {
7
+ "x402r": "./dist/bin/x402r.js"
8
+ },
9
+ "scripts": {
10
+ "start": "tsx bin/x402r.ts",
11
+ "dev": "tsx bin/x402r.ts",
12
+ "build": "tsc && sed -i '' '1s|#!/usr/bin/env tsx|#!/usr/bin/env node|' dist/bin/x402r.js && chmod +x dist/bin/x402r.js",
13
+ "prepublishOnly": "npm run build"
14
+ },
15
+ "dependencies": {
16
+ "@x402r/client": "^0.0.2",
17
+ "@x402r/core": "^0.0.2",
18
+ "commander": "^12.1.0",
19
+ "dotenv": "^16.4.0",
20
+ "viem": "^2.21.0"
21
+ },
22
+ "devDependencies": {
23
+ "@types/node": "^20.11.0",
24
+ "tsx": "^4.7.0",
25
+ "typescript": "^5.7.0"
26
+ },
27
+ "files": [
28
+ "dist/",
29
+ "SKILL.md"
30
+ ],
31
+ "keywords": [
32
+ "x402r",
33
+ "dispute",
34
+ "arbiter",
35
+ "payments",
36
+ "web3",
37
+ "openclaw"
38
+ ],
39
+ "license": "MIT"
40
+ }