Skip to content

Commit a1d29fc

Browse files
ralyodioclaude
andcommitted
Pay x402 gateways when the HTTP node meets one (@profullstack/x402-client)
The HTTP call node fetches through a paidFetch: with X402_PRIVATE_KEY set on the orchestrator, a 402 carrying an x402 offer is signed with the shared crawler wallet, the pass is filed by origin and presented on every later call to that site. Without the key it is the global fetch, unchanged. Capped at five dollars a payment. The client is listed in minimumReleaseAgeExclude because it was published today and pnpm 11 refuses packages younger than a day. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NSGS7Sy3QmEgTNZDg4eq7g
1 parent 38d7eb6 commit a1d29fc

5 files changed

Lines changed: 74 additions & 17 deletions

File tree

‎package.json‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,17 @@
2424
"security:patch": "SOCKET_API_TOKEN=${SOCKET_API_TOKEN} node scripts/socket-patch.mjs"
2525
},
2626
"devDependencies": {
27+
"chai": "^5.1.2",
2728
"dotenv": "^17.2.3",
2829
"inquirer": "^12.9.6",
2930
"prettier": "^3.3.3",
30-
"vitest": "^3.2.4",
31-
"chai": "^5.1.2"
31+
"vitest": "^3.2.4"
3232
},
3333
"dependencies": {
34+
"@meshhook/shared": "workspace:*",
35+
"@profullstack/x402-client": "0.2.0",
3436
"fast-xml-parser": "^5.3.0",
3537
"jmespath": "^0.16.0",
36-
"openai": "^6.3.0",
37-
"@meshhook/shared": "workspace:*"
38+
"openai": "^6.3.0"
3839
}
3940
}

‎pnpm-lock.yaml‎

Lines changed: 42 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎pnpm-workspace.yaml‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,8 @@ packages:
1111
# esbuild links the platform binary Vite uses to bundle the SvelteKit app.
1212
allowBuilds:
1313
esbuild: true
14+
15+
# The x402 client was published today; pnpm 11 refuses packages younger than a day
16+
# unless they are listed here.
17+
minimumReleaseAgeExclude:
18+
- '@profullstack/x402-client@0.2.0'

‎src/lib/paid-fetch.js‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/**
2+
* The fetch the HTTP node calls out with — paying when asked.
3+
*
4+
* A URL behind an x402 gateway answers with 402 and an offer. With
5+
* `X402_PRIVATE_KEY` set on the orchestrator, the client signs the offer with
6+
* the shared crawler wallet, buys the pass, files it by origin and presents
7+
* it on every later call to that site. Without the key this is the global
8+
* fetch, unchanged. Capped at five dollars a payment.
9+
*/
10+
11+
import { createClient } from '@profullstack/x402-client';
12+
13+
const key = globalThis.process?.env?.X402_PRIVATE_KEY;
14+
15+
/** The paying client, or null when no key is configured. */
16+
export const x402 = key ? createClient({ key, maxUsd: 5 }) : null;
17+
18+
/** @type {typeof fetch} */
19+
export const paidFetch = x402 ? (input, init) => x402.fetch(input, init) : (input, init) => globalThis.fetch(input, init);

‎src/nodes/http-call.js‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
* const result = await node.execute({ userId: 123, token: 'abc', name: 'John', email: 'john@example.com' });
3535
*/
3636

37+
import { paidFetch } from '../lib/paid-fetch.js';
38+
3739
/**
3840
* Custom error class for HTTP call errors
3941
*/
@@ -176,7 +178,7 @@ export class HttpCallNode {
176178
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
177179

178180
try {
179-
const response = await fetch(url, {
181+
const response = await paidFetch(url, {
180182
...options,
181183
signal: controller.signal,
182184
});

0 commit comments

Comments
 (0)