agent402-client 0.3.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +25 -2
  2. package/index.js +61 -0
  3. package/package.json +40 -11
package/README.md CHANGED
@@ -67,7 +67,7 @@ const { messages } = await a.getWorkflowPrompt("security-audit", { domain: "stri
67
67
 
68
68
  Want to see who's actually getting paid on x402 right now — not just what tools
69
69
  this service exposes? `topSellers()` returns the live leaderboard of sellers
70
- settling USDC on Base in the last ~24h, derived from on-chain transfers. Free
70
+ settling USDC (primarily on Base) in the last ~24h, derived from on-chain transfers. Free
71
71
  to call (no payment, no proof-of-work):
72
72
 
73
73
  ```js
@@ -86,7 +86,7 @@ await a.topSellers({ sort: "calls", include: "all" });
86
86
  | `await a.find(task, { k = 5 })` | Resolve a plain-language task to the best-matching tools (route, price, schema, example) |
87
87
  | `await a.findWorkflows(task, { k = 2 })` | Resolve a task to matching multi-tool workflow templates (skill packs) |
88
88
  | `await a.getWorkflowPrompt(slug, args)` | Fetch the rendered prompt messages for a skill pack with arguments substituted in |
89
- | `await a.topSellers({ limit?, sort?, include? })` | Live x402 leaderboard: which sellers are settling the most USDC on Base in the last ~24h (free, no payment) |
89
+ | `await a.topSellers({ limit?, sort?, include? })` | Live x402 leaderboard: which sellers are settling the most USDC (primarily on Base) in the last ~24h (free, no payment) |
90
90
  | `await a.call(slug, params, { idempotencyKey?, cache? })` | Call a tool; auto-pays (PoW for free tools, x402 for wallet-only); returns the JSON result |
91
91
  | `Agent402.solvePow(pow)` | Solve a proof-of-work challenge object → an `X-Pow-Solution` value |
92
92
  | `a.clearCache()` | Drop the in-memory result cache |
@@ -94,3 +94,26 @@ await a.topSellers({ sort: "calls", include: "all" });
94
94
  - **Zero dependencies** for the free/proof-of-work path (uses `node:crypto`).
95
95
  - **Non-custodial:** paid settlement is your `@x402/fetch` + wallet; this client never sees your key.
96
96
  - MIT licensed. Part of [Agent402](https://github.com/MikeyPetrillo/Agent402).
97
+
98
+ ## Pick the settlement chain (`withNetworkPreference`)
99
+
100
+ Multi-chain sellers list Base first, so an unmodified x402 client effectively
101
+ always settles there. To pin a chain — e.g. **USDG on Robinhood Chain** —
102
+ wrap your client before building the fetch:
103
+
104
+ ```js
105
+ import { withNetworkPreference } from "agent402-client";
106
+ import { x402Client } from "@x402/core/client";
107
+ import { registerExactEvmScheme } from "@x402/evm/exact/client";
108
+ import { wrapFetchWithPayment } from "@x402/fetch";
109
+
110
+ const client = new x402Client();
111
+ registerExactEvmScheme(client, { signer });
112
+ withNetworkPreference(client, ["robinhood"]); // or ["base","solana"], or ["eip155:4663"]
113
+ const payFetch = wrapFetchWithPayment(fetch, client);
114
+ ```
115
+
116
+ Short names map to CAIP-2 (`base`, `solana`, `polygon`, `arbitrum`,
117
+ `robinhood`); unknown entries pass through verbatim so future chains work
118
+ without a package update. If the preference matches none of a seller's
119
+ payment options it throws **before** any payment is signed.
package/index.js CHANGED
@@ -110,6 +110,26 @@ export class Agent402 {
110
110
  };
111
111
  }
112
112
 
113
+ /**
114
+ * Register a wallet address for Base builder code attribution. Idempotent:
115
+ * the same wallet always returns the same code. No authentication required.
116
+ *
117
+ * @param {string} walletAddress the caller's wallet address (e.g. "0x…")
118
+ * @param {object} [opts]
119
+ * @param {typeof fetch} [opts.fetchImpl] plain fetch (defaults to global fetch)
120
+ * @returns {Promise<{builderCode:string, walletAddress:string}>}
121
+ */
122
+ static async registerBuilderCode(walletAddress, { fetchImpl = globalThis.fetch } = {}) {
123
+ if (!walletAddress || typeof walletAddress !== "string") throw new Error("walletAddress is required");
124
+ const r = await fetchImpl("https://api.base.dev/v1/agents/builder-codes", {
125
+ method: "POST",
126
+ headers: { "Content-Type": "application/json" },
127
+ body: JSON.stringify({ walletAddress }),
128
+ });
129
+ if (!r.ok) throw new Error(`builder code registration failed: HTTP ${r.status}`);
130
+ return r.json();
131
+ }
132
+
113
133
  /** Solve a proof-of-work challenge object (from a 402 body) into an X-Pow-Solution value. */
114
134
  static solvePow(pow) {
115
135
  let n = 0;
@@ -178,4 +198,45 @@ export class Agent402 {
178
198
  clearCache() { this._cache?.clear(); }
179
199
  }
180
200
 
201
+ /**
202
+ * Restrict + order which chains an @x402 client will pay on (duck-typed — any
203
+ * client version with createPaymentPayload works, zero new dependencies).
204
+ * Multi-chain sellers list Base first, so an unmodified client effectively
205
+ * always settles there; this makes rails like USDG on Robinhood Chain
206
+ * (eip155:4663) reachable:
207
+ *
208
+ * import { withNetworkPreference } from "agent402-client";
209
+ * withNetworkPreference(x402client, ["robinhood"]); // or ["eip155:4663"]
210
+ * const payFetch = wrapFetchWithPayment(fetch, x402client);
211
+ *
212
+ * Short names map to CAIP-2; unknown entries pass through verbatim so future
213
+ * chains work without a package update. Throws (before paying) when the
214
+ * preference matches none of a seller's payment options.
215
+ */
216
+ export const NETWORK_CAIP2 = {
217
+ base: "eip155:8453",
218
+ polygon: "eip155:137",
219
+ arbitrum: "eip155:42161",
220
+ "base-sepolia": "eip155:84532",
221
+ robinhood: "eip155:4663",
222
+ solana: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
223
+ "solana-devnet": "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",
224
+ };
225
+
226
+ export function withNetworkPreference(client, networks) {
227
+ const prefs = (networks || []).map((n) => NETWORK_CAIP2[String(n).trim().toLowerCase()] || String(n).trim());
228
+ if (!prefs.length) return client;
229
+ const orig = client.createPaymentPayload.bind(client);
230
+ client.createPaymentPayload = (paymentRequired) => {
231
+ const list = Array.isArray(paymentRequired?.accepts) ? paymentRequired.accepts : [];
232
+ const picked = prefs.flatMap((caip2) => list.filter((a) => String(a?.network || "").toLowerCase() === caip2.toLowerCase()));
233
+ if (!picked.length) {
234
+ const offered = [...new Set(list.map((a) => a?.network).filter(Boolean))];
235
+ throw new Error(`network preference [${prefs.join(", ")}] matched none of the seller's payment options [${offered.join(", ")}]`);
236
+ }
237
+ return orig({ ...paymentRequired, accepts: picked });
238
+ };
239
+ return client;
240
+ }
241
+
181
242
  export default Agent402;
package/package.json CHANGED
@@ -1,19 +1,48 @@
1
1
  {
2
2
  "name": "agent402-client",
3
- "version": "0.3.0",
4
- "description": "Tiny buyer-side client for Agent402 (x402): resolve a task to a tool and call it with payment handled for you — free tools settle via built-in proof-of-work (no wallet), wallet-only tools via your x402 fetch. Caching + idempotent retries.",
3
+ "version": "0.4.1",
4
+ "description": "Buyer-side SDK for Agent402.Tools (x402): resolve a task to a tool across 1,346 pay-per-call endpoints and call it with payment handled for you — free tools settle via built-in proof-of-work (no wallet), wallet-only tools via your x402 fetch — with a withNetworkPreference helper to pick the settlement chain (USDC on Base/Solana/Polygon/Arbitrum or USDG on Robinhood Chain). Caching, idempotent retries, cross-seller Smart Order Router.",
5
5
  "type": "module",
6
6
  "main": "index.js",
7
- "exports": { ".": "./index.js" },
8
- "files": ["index.js", "README.md"],
9
- "engines": { "node": ">=18" },
10
- "scripts": { "test": "node test.js" },
7
+ "exports": {
8
+ ".": "./index.js"
9
+ },
10
+ "files": [
11
+ "index.js",
12
+ "README.md"
13
+ ],
14
+ "engines": {
15
+ "node": ">=18"
16
+ },
17
+ "scripts": {
18
+ "test": "node test.js"
19
+ },
11
20
  "keywords": [
12
- "x402", "ai-agents", "agent-tools", "llm-tools", "usdc", "base",
13
- "proof-of-work", "http-402", "micropayments", "mcp", "client", "sdk"
21
+ "x402",
22
+ "ai-agents",
23
+ "agent-tools",
24
+ "llm-tools",
25
+ "usdc",
26
+ "base",
27
+ "proof-of-work",
28
+ "http-402",
29
+ "micropayments",
30
+ "mcp",
31
+ "client",
32
+ "sdk",
33
+ "agent402",
34
+ "tool-discovery",
35
+ "smart-order-router",
36
+ "robinhood-chain",
37
+ "usdg",
38
+ "multi-chain"
14
39
  ],
15
- "author": "Mikey Petrillo (https://github.com/MikeyPetrillo)",
40
+ "author": "Mike Petrillo <mike@agent402.tools> (https://github.com/MikeyPetrillo)",
16
41
  "license": "MIT",
17
- "repository": { "type": "git", "url": "https://github.com/MikeyPetrillo/Agent402.git", "directory": "client" },
18
- "homepage": "https://github.com/MikeyPetrillo/Agent402/tree/main/client"
42
+ "repository": {
43
+ "type": "git",
44
+ "url": "https://github.com/MikeyPetrillo/Agent402.git",
45
+ "directory": "client"
46
+ },
47
+ "homepage": "https://agent402.tools"
19
48
  }