@hpp-io/x402-mcp-bridge 0.0.1 → 0.0.3
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/README.md +125 -77
- package/bin/hpp-x402.js +5 -0
- package/bin/x402-mcp-bridge.js +0 -0
- package/dist/a2a.d.ts +70 -0
- package/dist/a2a.js +210 -0
- package/dist/a2a.js.map +1 -0
- package/dist/autoTopup.d.ts +2 -1
- package/dist/autoTopup.js.map +1 -1
- package/dist/cli/channel.d.ts +1 -0
- package/dist/cli/channel.js +323 -0
- package/dist/cli/channel.js.map +1 -0
- package/dist/cli/hpp-x402.d.ts +2 -0
- package/dist/cli/hpp-x402.js +375 -0
- package/dist/cli/hpp-x402.js.map +1 -0
- package/dist/cli/install-claude-code.d.ts +24 -0
- package/dist/cli/install-claude-code.js +50 -0
- package/dist/cli/install-claude-code.js.map +1 -0
- package/dist/cli/install-claude.d.ts +2 -20
- package/dist/cli/install-claude.js +12 -63
- package/dist/cli/install-claude.js.map +1 -1
- package/dist/cli/install-cursor.d.ts +7 -0
- package/dist/cli/install-cursor.js +26 -0
- package/dist/cli/install-cursor.js.map +1 -0
- package/dist/cli/install-mcp-host.d.ts +35 -0
- package/dist/cli/install-mcp-host.js +82 -0
- package/dist/cli/install-mcp-host.js.map +1 -0
- package/dist/cli/install-openclaw.d.ts +7 -0
- package/dist/cli/install-openclaw.js +28 -0
- package/dist/cli/install-openclaw.js.map +1 -0
- package/dist/cli/install-windsurf.d.ts +7 -0
- package/dist/cli/install-windsurf.js +37 -0
- package/dist/cli/install-windsurf.js.map +1 -0
- package/dist/cli/policy.d.ts +1 -0
- package/dist/cli/policy.js +212 -0
- package/dist/cli/policy.js.map +1 -0
- package/dist/cli/revoke.d.ts +1 -1
- package/dist/cli/revoke.js +1 -5
- package/dist/cli/revoke.js.map +1 -1
- package/dist/cli/safe.d.ts +4172 -9580
- package/dist/cli/setup.d.ts +1 -1
- package/dist/cli/setup.js +24 -6
- package/dist/cli/setup.js.map +1 -1
- package/dist/client.d.ts +25 -10
- package/dist/client.js +139 -2
- package/dist/client.js.map +1 -1
- package/dist/config.d.ts +50 -11
- package/dist/config.js +50 -10
- package/dist/config.js.map +1 -1
- package/dist/discovery.d.ts +43 -0
- package/dist/discovery.js +62 -0
- package/dist/discovery.js.map +1 -0
- package/dist/discoveryTools.d.ts +75 -0
- package/dist/discoveryTools.js +101 -0
- package/dist/discoveryTools.js.map +1 -0
- package/dist/funds/direct-balance.d.ts +27 -0
- package/dist/funds/direct-balance.js +58 -0
- package/dist/funds/direct-balance.js.map +1 -0
- package/dist/funds.d.ts +26 -0
- package/dist/funds.js +2 -0
- package/dist/funds.js.map +1 -0
- package/dist/httpX402.d.ts +45 -0
- package/dist/httpX402.js +214 -0
- package/dist/httpX402.js.map +1 -0
- package/dist/index.js +66 -20
- package/dist/index.js.map +1 -1
- package/dist/keychain.d.ts +23 -0
- package/dist/keychain.js +111 -0
- package/dist/keychain.js.map +1 -0
- package/dist/policy.d.ts +73 -0
- package/dist/policy.js +249 -0
- package/dist/policy.js.map +1 -0
- package/dist/server.d.ts +18 -1
- package/dist/server.js +120 -10
- package/dist/server.js.map +1 -1
- package/docs/policy.md +101 -0
- package/package.json +11 -8
- package/bin/hpp-x402-safe-revoke.js +0 -5
- package/bin/hpp-x402-safe-setup.js +0 -5
package/README.md
CHANGED
|
@@ -1,128 +1,176 @@
|
|
|
1
1
|
# @hpp-io/x402-mcp-bridge
|
|
2
2
|
|
|
3
|
-
>
|
|
4
|
-
>
|
|
5
|
-
>
|
|
6
|
-
>
|
|
3
|
+
> The agent payment rail for HPP. A stdio MCP bridge + a unified `hpp-x402`
|
|
4
|
+
> CLI that let Claude Desktop / Claude Code / Cursor / Windsurf / OpenClaw make
|
|
5
|
+
> autonomous **HPP USDC.e** payments over [x402](https://x402.org) — discover
|
|
6
|
+
> paid services, pay per call, all within a spend cap. No API keys, no manual
|
|
7
|
+
> signing.
|
|
7
8
|
|
|
8
9
|
## What it is
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
spawns, exposes itself as an MCP server to the host, and internally:
|
|
11
|
+
MCP hosts (Claude Desktop, Cursor, …) can't sign x402 payments. This package is
|
|
12
|
+
two things:
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
- Retries the call.
|
|
14
|
+
- **The bridge** (`x402-mcp-bridge`) — a stdio MCP server the host spawns. It
|
|
15
|
+
proxies a paid upstream MCP server, and adds local tools to **discover** and
|
|
16
|
+
**call** any x402 service on HPP. When a service returns `402`, the bridge
|
|
17
|
+
pays with your wallet and retries. The host just sees tools that work.
|
|
18
|
+
- **The CLI** (`hpp-x402`) — one command to create a wallet, register the bridge
|
|
19
|
+
into your host, fund it, and browse/call services from the terminal.
|
|
21
20
|
|
|
22
|
-
|
|
21
|
+
Two wallet modes:
|
|
23
22
|
|
|
24
|
-
|
|
23
|
+
| Mode | Cap | Gas | For |
|
|
24
|
+
|------|-----|-----|-----|
|
|
25
|
+
| **light** (default) | fund small = your cap | none (settlement is gasless) | quick start, low value |
|
|
26
|
+
| **Safe** (governance) | on-chain daily cap (AllowanceModule) | delegate pays top-up gas | treasury, teams |
|
|
27
|
+
|
|
28
|
+
## Quick start (light mode, ~2 min)
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
# 1. Create a wallet + register the bridge into your host in one shot
|
|
32
|
+
npx -y -p @hpp-io/x402-mcp-bridge hpp-x402 setup --install claude
|
|
33
|
+
# → prints your delegate address + a paste-ready config
|
|
34
|
+
|
|
35
|
+
# 2. Fund it — send USDC.e to that address on HPP (no native gas needed)
|
|
36
|
+
npx -y -p @hpp-io/x402-mcp-bridge hpp-x402 fund
|
|
37
|
+
|
|
38
|
+
# 3. Restart your host. Ask the agent to discover + call a paid service.
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
`--install` accepts `claude | claude-code | cursor | windsurf | openclaw`.
|
|
42
|
+
|
|
43
|
+
## The `hpp-x402` CLI
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
hpp-x402 setup one-command onboarding (+ optional --install <host>)
|
|
47
|
+
hpp-x402 wallet <sub> address | balance | generate | import <key> | remove
|
|
48
|
+
hpp-x402 install <host> register the bridge into an MCP host
|
|
49
|
+
hpp-x402 fund show the deposit address + on-chain balance
|
|
50
|
+
hpp-x402 discover [query] browse/search curated HPP x402 services
|
|
51
|
+
hpp-x402 call <resourceId> pay + invoke a discovered service (--body '{...}')
|
|
52
|
+
hpp-x402 status network + wallet + balance + server reachability
|
|
53
|
+
hpp-x402 policy <sub> host policy for x402_http_call (show/set/list/...)
|
|
54
|
+
hpp-x402 channel <sub> batch-settlement channels (ls/status/refund)
|
|
55
|
+
hpp-x402 safe <setup|revoke> Safe (governance) wallet + AllowanceModule
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Common flags: `-a, --account <name>` (keychain slot, default `delegate-default`),
|
|
59
|
+
`-n, --network <caip2>` (`eip155:181228` Sepolia / `eip155:190415` Mainnet).
|
|
60
|
+
|
|
61
|
+
Keys are stored in the OS keychain (macOS Keychain / Windows Credential Vault /
|
|
62
|
+
Linux libsecret) and referenced as `keychain://hpp-x402/<account>` — never
|
|
63
|
+
plaintext on disk. Use `--print-key` on `setup` for a raw key (dev only).
|
|
64
|
+
|
|
65
|
+
## Discover → pay, from the terminal
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
hpp-x402 discover "image generation" -n eip155:190415
|
|
69
|
+
# → lists services with resourceId, price (USDC.e), network, scheme
|
|
70
|
+
|
|
71
|
+
hpp-x402 call <resourceId> --body '{"prompt":"a red bicycle"}'
|
|
72
|
+
# → pays with your wallet (within the spend cap) and returns the result
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
The same capability is exposed to agents as MCP tools (below), so an agent can
|
|
76
|
+
discover and pay on its own.
|
|
77
|
+
|
|
78
|
+
## Tools the host sees
|
|
79
|
+
|
|
80
|
+
Registered by the bridge on top of any proxied upstream tools:
|
|
81
|
+
|
|
82
|
+
| Tool | What it does |
|
|
83
|
+
|------|--------------|
|
|
84
|
+
| `hpp_discover` | list/search the curated HPP discovery directory (read-only) |
|
|
85
|
+
| `hpp_call` | call a discovered service by `resourceId`; pays via your wallet |
|
|
86
|
+
| `x402_http_call` | call any allow-listed x402 HTTP endpoint (auth headers from local policy) |
|
|
87
|
+
| `pay_a2a_agent` | pay + message another A2A agent |
|
|
88
|
+
|
|
89
|
+
Discovery is **curated** (facilitator-indexed HPP services) — that's the trust
|
|
90
|
+
boundary — and every paid call is still bounded by the daily spend cap.
|
|
91
|
+
Non-custodial throughout: discovery never holds funds or sees your keys.
|
|
92
|
+
|
|
93
|
+
## Configuration (env)
|
|
94
|
+
|
|
95
|
+
The host config's `env` block drives the bridge. Light mode omits the Safe vars:
|
|
25
96
|
|
|
26
97
|
```jsonc
|
|
27
|
-
// claude_desktop_config.json
|
|
98
|
+
// claude_desktop_config.json (generated by `hpp-x402 setup`)
|
|
28
99
|
{
|
|
29
100
|
"mcpServers": {
|
|
30
101
|
"hpp-x402": {
|
|
31
102
|
"command": "npx",
|
|
32
103
|
"args": ["-y", "@hpp-io/x402-mcp-bridge"],
|
|
33
104
|
"env": {
|
|
34
|
-
"DELEGATE_PRIVATE_KEY": "
|
|
35
|
-
"
|
|
36
|
-
"ALLOWANCE_MODULE_ADDRESS": "0x...",
|
|
37
|
-
"USDCE_ADDRESS": "0x...",
|
|
38
|
-
"RESOURCE_SERVER_URL": "https://your-x402-server/mcp/sse",
|
|
105
|
+
"DELEGATE_PRIVATE_KEY": "keychain://hpp-x402/delegate-default",
|
|
106
|
+
"USDCE_ADDRESS": "0x401eCb1D350407f13ba348573E5630B83638E30D",
|
|
39
107
|
"HPP_RPC_URL": "https://sepolia.hpp.io",
|
|
40
|
-
"HPP_NETWORK": "eip155:181228"
|
|
108
|
+
"HPP_NETWORK": "eip155:181228",
|
|
109
|
+
"RESOURCE_SERVER_URL": "https://your-x402-server/mcp/sse" // optional
|
|
41
110
|
}
|
|
42
111
|
}
|
|
43
112
|
}
|
|
44
113
|
}
|
|
45
114
|
```
|
|
46
115
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
116
|
+
| Var | Notes |
|
|
117
|
+
|-----|-------|
|
|
118
|
+
| `DELEGATE_PRIVATE_KEY` | `keychain://hpp-x402/<account>` (recommended) or `0x<64 hex>` |
|
|
119
|
+
| `USDCE_ADDRESS` | USDC.e token on HPP |
|
|
120
|
+
| `HPP_RPC_URL` / `HPP_NETWORK` | chain RPC + CAIP-2 id |
|
|
121
|
+
| `RESOURCE_SERVER_URL` | optional upstream MCP server to proxy (omit = local tools only) |
|
|
122
|
+
| `SAFE_ADDRESS` + `ALLOWANCE_MODULE_ADDRESS` | set both = Safe mode; omit both = light mode |
|
|
123
|
+
| `HPP_X402_DISCOVERY` | `on` (default) / `off` — registers `hpp_discover` / `hpp_call` |
|
|
124
|
+
| `HPP_X402_DISCOVERY_URL` | discovery base URL (default `https://x402-discovery.hpp.io`) |
|
|
51
125
|
|
|
52
|
-
##
|
|
126
|
+
## Safe mode (governance)
|
|
53
127
|
|
|
54
|
-
|
|
55
|
-
|
|
128
|
+
For an on-chain daily cap and treasury separation, use a Safe + AllowanceModule
|
|
129
|
+
instead of the light EOA:
|
|
56
130
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
`setAllowance(<delegate>, USDC.e, <daily cap>, 1440 minutes, 0)` —
|
|
62
|
-
one Safe transaction each (or batched via Safe's MultiSend).
|
|
63
|
-
5. Send a small amount of native ETH to the delegate EOA (it pays gas
|
|
64
|
-
for `executeAllowanceTransfer`).
|
|
131
|
+
```bash
|
|
132
|
+
hpp-x402 safe setup --owner-pk 0x... --allowance <atomic> # deploy + enable + delegate
|
|
133
|
+
hpp-x402 safe revoke --owner-pk 0x... --delegate 0x... # emergency: deleteAllowance
|
|
134
|
+
```
|
|
65
135
|
|
|
66
|
-
|
|
67
|
-
|
|
136
|
+
Then set `SAFE_ADDRESS` + `ALLOWANCE_MODULE_ADDRESS` in the host config; the
|
|
137
|
+
bridge auto-tops up the delegate from the Safe within the chain-enforced cap
|
|
138
|
+
(`AllowanceModule.executeAllowanceTransfer`) before each payment.
|
|
68
139
|
|
|
69
140
|
## Architecture
|
|
70
141
|
|
|
71
|
-
See [DESIGN.md in the parent task](../noosphere-evm/.claude/tasks/x402-mcp-wallet/design/DESIGN.md).
|
|
72
|
-
|
|
73
|
-
In short:
|
|
74
|
-
|
|
75
142
|
```
|
|
76
|
-
host (Claude Desktop)
|
|
143
|
+
host (Claude Desktop / Cursor / …)
|
|
77
144
|
│ stdio (MCP)
|
|
78
145
|
▼
|
|
79
146
|
[ this bridge ]
|
|
80
147
|
─ Signer (delegate EOA)
|
|
81
|
-
─
|
|
82
|
-
─
|
|
148
|
+
─ Funds (light DirectBalance | Safe AutoTopup within cap)
|
|
149
|
+
─ discovery client (curated HPP services)
|
|
150
|
+
─ upstream MCP client (@x402/mcp wrapped) ─ optional
|
|
83
151
|
│
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
remote x402 MCP server
|
|
152
|
+
▼ SSE / StreamableHTTP (MCP + x402) discovery REST
|
|
153
|
+
paid x402 services on HPP
|
|
87
154
|
```
|
|
88
155
|
|
|
89
156
|
## Releasing to npm
|
|
90
157
|
|
|
91
|
-
|
|
158
|
+
Tag-driven via the GitHub Actions Publish workflow:
|
|
92
159
|
|
|
93
160
|
```
|
|
94
|
-
# (1) Recommended: tag-driven release
|
|
95
161
|
git checkout main && git pull
|
|
96
162
|
npm version patch # or minor / major
|
|
97
|
-
git push --follow-tags # → workflow
|
|
98
|
-
|
|
99
|
-
# (2) Ad-hoc: workflow_dispatch from GitHub UI
|
|
100
|
-
# Actions tab → "Publish to npm" → Run workflow
|
|
101
|
-
# Optional `dry_run` toggle for verification
|
|
163
|
+
git push --follow-tags # → workflow publishes to npm
|
|
102
164
|
```
|
|
103
165
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
The `prepublishOnly` script in package.json runs `typecheck && build`
|
|
108
|
-
locally too, so manual `npm publish` from a developer's machine still
|
|
109
|
-
guards against shipping broken builds.
|
|
110
|
-
|
|
111
|
-
## Status
|
|
112
|
-
|
|
113
|
-
**v0.0.1 — PoC.** Working end-to-end against HPP Sepolia (smoke proves
|
|
114
|
-
both the "delegate has balance" and "delegate empty → autoTopup → pay"
|
|
115
|
-
paths). Not yet published to npm; install via local path or git clone.
|
|
166
|
+
`prepublishOnly` runs `typecheck && build`, so a broken build never ships.
|
|
167
|
+
Required repo secret: `NPM_TOKEN` (npmjs "Automation" token scoped to `@hpp-io`).
|
|
116
168
|
|
|
117
|
-
|
|
169
|
+
## Related
|
|
118
170
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
-
|
|
122
|
-
API, ERC-4337 session keys).
|
|
123
|
-
- v0.3: structured guardrail layer (allowlist of `RESOURCE_SERVER_URL`,
|
|
124
|
-
per-call max payment cap) — mirrors Coinbase AgentKit's
|
|
125
|
-
`X402ActionProvider`.
|
|
171
|
+
Building an **agent / SDK** integration instead (LangChain, OpenAI
|
|
172
|
+
function-calling, AgentKit, A2A)? See the runnable gallery:
|
|
173
|
+
→ [hpp-io/hpp-x402-agent-sample](https://github.com/hpp-io/hpp-x402-agent-sample)
|
|
126
174
|
|
|
127
175
|
## License
|
|
128
176
|
|
package/bin/hpp-x402.js
ADDED
package/bin/x402-mcp-bridge.js
CHANGED
|
File without changes
|
package/dist/a2a.d.ts
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { Network } from "@x402/core/types";
|
|
2
|
+
import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
|
|
3
|
+
import type { Funds } from "./funds.js";
|
|
4
|
+
import type { RawEoaSigner } from "./signers/raw-eoa.js";
|
|
5
|
+
export interface A2aPayerDeps {
|
|
6
|
+
signer: RawEoaSigner;
|
|
7
|
+
network: Network;
|
|
8
|
+
/** Optional: ensure the delegate holds enough USDC.e before paying. */
|
|
9
|
+
funds?: Funds;
|
|
10
|
+
/**
|
|
11
|
+
* Per-request timeout for the gate + paid `message/send` JSON-RPC calls.
|
|
12
|
+
* Defaults to {@link DEFAULT_A2A_RPC_TIMEOUT_MS} (60s). Override via env
|
|
13
|
+
* `HPP_X402_A2A_RPC_TIMEOUT_MS` at startup.
|
|
14
|
+
*/
|
|
15
|
+
rpcTimeoutMs?: number;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Pick the single `accept` entry the bridge will actually pay against:
|
|
19
|
+
* scheme === "exact" AND network === `deps.network`. The server may
|
|
20
|
+
* advertise multiple schemes (batch-settlement first, exact second is
|
|
21
|
+
* the noosphere-x402-server default); the SDK's
|
|
22
|
+
* `createPaymentPayload(required)` would internally re-select based on
|
|
23
|
+
* registered schemes — but our spend-cap topup happens *before* that
|
|
24
|
+
* call, so they must operate on the *same* accept or `accept.amount`
|
|
25
|
+
* (topup) and the signed amount can diverge silently. We narrow to one
|
|
26
|
+
* accept here and pass it to both the topup gate AND the SDK, so the
|
|
27
|
+
* choice is auditable + consistent.
|
|
28
|
+
*/
|
|
29
|
+
export declare function pickExactAccept(required: {
|
|
30
|
+
accepts?: ReadonlyArray<Record<string, unknown>>;
|
|
31
|
+
}, network: Network): Record<string, unknown> | null;
|
|
32
|
+
export declare const PAY_A2A_TOOL: {
|
|
33
|
+
readonly name: "pay_a2a_agent";
|
|
34
|
+
readonly description: string;
|
|
35
|
+
readonly inputSchema: {
|
|
36
|
+
readonly type: "object";
|
|
37
|
+
readonly properties: {
|
|
38
|
+
readonly agentUrl: {
|
|
39
|
+
readonly type: "string";
|
|
40
|
+
readonly description: "The A2A agent's JSON-RPC endpoint URL (e.g. http://host:4021/a2a)";
|
|
41
|
+
};
|
|
42
|
+
readonly skill: {
|
|
43
|
+
readonly type: "string";
|
|
44
|
+
readonly description: "The skill id to invoke. Operator-supplied — this MVP does not auto-discover the AgentCard.";
|
|
45
|
+
};
|
|
46
|
+
readonly message: {
|
|
47
|
+
readonly type: "string";
|
|
48
|
+
readonly description: "Text input / prompt for the skill";
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
readonly required: readonly ["agentUrl", "skill", "message"];
|
|
52
|
+
readonly additionalProperties: false;
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Per-request timeout for A2A JSON-RPC calls. Without this the bridge's
|
|
57
|
+
* tool call hangs as long as the external agent does — the MCP host's
|
|
58
|
+
* own timeout (~5min) is the only fallback, and it surfaces a generic
|
|
59
|
+
* error that doesn't identify A2A as the slow leg. 60s covers any
|
|
60
|
+
* realistic gate / paid-message-send wallclock for synchronous A2A
|
|
61
|
+
* skills; long-running compute is meant to use the agent's own pending /
|
|
62
|
+
* polling protocol, not a single message/send.
|
|
63
|
+
*/
|
|
64
|
+
export declare const DEFAULT_A2A_RPC_TIMEOUT_MS = 60000;
|
|
65
|
+
export interface PayA2aArgs {
|
|
66
|
+
agentUrl: string;
|
|
67
|
+
skill: string;
|
|
68
|
+
message: string;
|
|
69
|
+
}
|
|
70
|
+
export declare function payA2aAgent(deps: A2aPayerDeps, args: PayA2aArgs): Promise<CallToolResult>;
|
package/dist/a2a.js
ADDED
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent2Agent (A2A) buyer tool for the bridge.
|
|
3
|
+
*
|
|
4
|
+
* The bridge's host (Claude Desktop / OpenClaw) speaks MCP, not A2A. This
|
|
5
|
+
* tool lets the host pay an *external A2A agent*: the operator passes the
|
|
6
|
+
* agent's `/a2a` endpoint URL + skill id (no AgentCard discovery — that
|
|
7
|
+
* is post-MVP, see TODO below), the bridge drives the `message/send`
|
|
8
|
+
* gate-then-pay flow, and signs the x402 `exact` payment with the
|
|
9
|
+
* bridge's existing delegate EOA — the same signer + AllowanceModule
|
|
10
|
+
* spend-cap that gate the MCP/HTTP path.
|
|
11
|
+
*
|
|
12
|
+
* The payment travels inside A2A message metadata (the a2a-x402 extension),
|
|
13
|
+
* not an HTTP header — but the signed payload is produced by the same
|
|
14
|
+
* @x402/core client + @x402/evm exact scheme used everywhere else.
|
|
15
|
+
*
|
|
16
|
+
* TODO (post-MVP): GET `/.well-known/agent-card.json`, validate `skill`
|
|
17
|
+
* against the published skill list, surface card metadata in errors.
|
|
18
|
+
*/
|
|
19
|
+
import { x402Client } from "@x402/core/client";
|
|
20
|
+
import { ExactEvmScheme } from "@x402/evm/exact/client";
|
|
21
|
+
import { log } from "./log.js";
|
|
22
|
+
/**
|
|
23
|
+
* Pick the single `accept` entry the bridge will actually pay against:
|
|
24
|
+
* scheme === "exact" AND network === `deps.network`. The server may
|
|
25
|
+
* advertise multiple schemes (batch-settlement first, exact second is
|
|
26
|
+
* the noosphere-x402-server default); the SDK's
|
|
27
|
+
* `createPaymentPayload(required)` would internally re-select based on
|
|
28
|
+
* registered schemes — but our spend-cap topup happens *before* that
|
|
29
|
+
* call, so they must operate on the *same* accept or `accept.amount`
|
|
30
|
+
* (topup) and the signed amount can diverge silently. We narrow to one
|
|
31
|
+
* accept here and pass it to both the topup gate AND the SDK, so the
|
|
32
|
+
* choice is auditable + consistent.
|
|
33
|
+
*/
|
|
34
|
+
export function pickExactAccept(required, network) {
|
|
35
|
+
const accepts = required.accepts ?? [];
|
|
36
|
+
for (const a of accepts) {
|
|
37
|
+
if (a.scheme === "exact" && a.network === network)
|
|
38
|
+
return a;
|
|
39
|
+
}
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
export const PAY_A2A_TOOL = {
|
|
43
|
+
name: "pay_a2a_agent",
|
|
44
|
+
description: "Pay an external Agent2Agent (A2A) agent for one of its skills using x402 " +
|
|
45
|
+
"(exact scheme, USDC.e) and return the result. The operator supplies the " +
|
|
46
|
+
"agent's A2A endpoint URL (e.g. http://host:4021/a2a) and the skill id " +
|
|
47
|
+
"directly — this MVP does not yet fetch the AgentCard. The bridge gates " +
|
|
48
|
+
"(unpaid message/send), signs the x402 payment with its delegate wallet " +
|
|
49
|
+
"(subject to the daily spend cap), and re-sends with the payment in A2A " +
|
|
50
|
+
"metadata, returning the agent's output on success.",
|
|
51
|
+
inputSchema: {
|
|
52
|
+
type: "object",
|
|
53
|
+
properties: {
|
|
54
|
+
agentUrl: {
|
|
55
|
+
type: "string",
|
|
56
|
+
description: "The A2A agent's JSON-RPC endpoint URL (e.g. http://host:4021/a2a)",
|
|
57
|
+
},
|
|
58
|
+
skill: {
|
|
59
|
+
type: "string",
|
|
60
|
+
description: "The skill id to invoke. Operator-supplied — this MVP does not auto-discover the AgentCard.",
|
|
61
|
+
},
|
|
62
|
+
message: {
|
|
63
|
+
type: "string",
|
|
64
|
+
description: "Text input / prompt for the skill",
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
required: ["agentUrl", "skill", "message"],
|
|
68
|
+
additionalProperties: false,
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
const REQUIRED_KEY = "x402.payment.required";
|
|
72
|
+
const PAYLOAD_KEY = "x402.payment.payload";
|
|
73
|
+
const STATUS_KEY = "x402.payment.status";
|
|
74
|
+
/**
|
|
75
|
+
* Per-request timeout for A2A JSON-RPC calls. Without this the bridge's
|
|
76
|
+
* tool call hangs as long as the external agent does — the MCP host's
|
|
77
|
+
* own timeout (~5min) is the only fallback, and it surfaces a generic
|
|
78
|
+
* error that doesn't identify A2A as the slow leg. 60s covers any
|
|
79
|
+
* realistic gate / paid-message-send wallclock for synchronous A2A
|
|
80
|
+
* skills; long-running compute is meant to use the agent's own pending /
|
|
81
|
+
* polling protocol, not a single message/send.
|
|
82
|
+
*/
|
|
83
|
+
export const DEFAULT_A2A_RPC_TIMEOUT_MS = 60_000;
|
|
84
|
+
let rpcId = 0;
|
|
85
|
+
async function a2aRpc(url, method, params, timeoutMs) {
|
|
86
|
+
let res;
|
|
87
|
+
try {
|
|
88
|
+
res = await fetch(url, {
|
|
89
|
+
method: "POST",
|
|
90
|
+
headers: { "content-type": "application/json" },
|
|
91
|
+
body: JSON.stringify({ jsonrpc: "2.0", id: ++rpcId, method, params }),
|
|
92
|
+
signal: AbortSignal.timeout(timeoutMs),
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
catch (err) {
|
|
96
|
+
if (err instanceof DOMException && err.name === "TimeoutError") {
|
|
97
|
+
throw new Error(`A2A ${method} timed out after ${Math.round(timeoutMs / 1000)}s (${url})`);
|
|
98
|
+
}
|
|
99
|
+
throw err;
|
|
100
|
+
}
|
|
101
|
+
const json = (await res.json());
|
|
102
|
+
if (json.error) {
|
|
103
|
+
throw new Error(`A2A JSON-RPC error: ${JSON.stringify(json.error)}`);
|
|
104
|
+
}
|
|
105
|
+
return json.result;
|
|
106
|
+
}
|
|
107
|
+
function userMessage(text, metadata) {
|
|
108
|
+
return {
|
|
109
|
+
message: {
|
|
110
|
+
kind: "message",
|
|
111
|
+
messageId: `bridge-a2a-${++rpcId}`,
|
|
112
|
+
role: "user",
|
|
113
|
+
parts: [{ kind: "text", text }],
|
|
114
|
+
metadata,
|
|
115
|
+
},
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
function errorResult(text) {
|
|
119
|
+
return { content: [{ type: "text", text }], isError: true };
|
|
120
|
+
}
|
|
121
|
+
export async function payA2aAgent(deps, args) {
|
|
122
|
+
const a2aUrl = args.agentUrl.replace(/\/+$/, "");
|
|
123
|
+
const timeoutMs = deps.rpcTimeoutMs ?? DEFAULT_A2A_RPC_TIMEOUT_MS;
|
|
124
|
+
// 1. Gate: send the request unpaid → expect input-required + requirements.
|
|
125
|
+
let gate;
|
|
126
|
+
try {
|
|
127
|
+
gate = await a2aRpc(a2aUrl, "message/send", userMessage(args.message, { skillId: args.skill }), timeoutMs);
|
|
128
|
+
}
|
|
129
|
+
catch (err) {
|
|
130
|
+
return errorResult(`A2A gate request failed: ${err.message}`);
|
|
131
|
+
}
|
|
132
|
+
const state = gate?.status?.state;
|
|
133
|
+
// Free agent (no payment needed) — return the result as-is.
|
|
134
|
+
if (state === "completed") {
|
|
135
|
+
return { content: [{ type: "text", text: JSON.stringify(extractResult(gate)) }] };
|
|
136
|
+
}
|
|
137
|
+
if (state !== "input-required") {
|
|
138
|
+
return errorResult(`unexpected A2A task state "${state}" (expected input-required)`);
|
|
139
|
+
}
|
|
140
|
+
const required = gate.metadata?.[REQUIRED_KEY];
|
|
141
|
+
if (!required?.accepts?.length) {
|
|
142
|
+
return errorResult("A2A agent did not return x402 payment requirements");
|
|
143
|
+
}
|
|
144
|
+
// Narrow to the (scheme=exact, network=deps.network) entry — the SDK
|
|
145
|
+
// would otherwise re-pick based on registered schemes and the topup
|
|
146
|
+
// amount could end up funding a different `accepts[i].amount` than the
|
|
147
|
+
// one actually signed. See pickExactAccept docstring.
|
|
148
|
+
const accept = pickExactAccept(required, deps.network);
|
|
149
|
+
if (!accept) {
|
|
150
|
+
return errorResult(`A2A agent advertised no "exact" accept for network ${deps.network} ` +
|
|
151
|
+
`(scheme/networks: ${JSON.stringify(required.accepts.map((a) => ({ scheme: a.scheme, network: a.network })))})`);
|
|
152
|
+
}
|
|
153
|
+
// Reconstruct a single-accept PaymentRequired for the SDK so its
|
|
154
|
+
// internal selection cannot diverge from what we just chose.
|
|
155
|
+
const narrowedRequired = { ...required, accepts: [accept] };
|
|
156
|
+
// 2. Spend-cap: ensure the delegate holds enough USDC.e (same gate as the
|
|
157
|
+
// MCP/HTTP path). Skipped when no funds source is wired.
|
|
158
|
+
if (deps.funds) {
|
|
159
|
+
try {
|
|
160
|
+
const requiredAtomic = BigInt(accept.amount ?? "0");
|
|
161
|
+
await deps.funds.ensure(requiredAtomic);
|
|
162
|
+
}
|
|
163
|
+
catch (err) {
|
|
164
|
+
return errorResult(`funds check failed (spend cap / insufficient balance?): ${err.message}`);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
// 3. Sign the exact payload with the bridge's delegate EOA against
|
|
168
|
+
// the *narrowed* PaymentRequired (single-accept) so the SDK's
|
|
169
|
+
// internal scheme/network selection cannot pick a different entry.
|
|
170
|
+
let payload;
|
|
171
|
+
try {
|
|
172
|
+
const client = new x402Client().register(deps.network, new ExactEvmScheme(deps.signer.viemAccount));
|
|
173
|
+
payload = await client.createPaymentPayload(narrowedRequired);
|
|
174
|
+
}
|
|
175
|
+
catch (err) {
|
|
176
|
+
return errorResult(`failed to sign x402 payment: ${err.message}`);
|
|
177
|
+
}
|
|
178
|
+
// 4. Re-send with the payload in A2A metadata → expect completed.
|
|
179
|
+
let task;
|
|
180
|
+
try {
|
|
181
|
+
task = await a2aRpc(a2aUrl, "message/send", userMessage(args.message, { skillId: args.skill, [PAYLOAD_KEY]: payload }), timeoutMs);
|
|
182
|
+
}
|
|
183
|
+
catch (err) {
|
|
184
|
+
return errorResult(`A2A paid request failed: ${err.message}`);
|
|
185
|
+
}
|
|
186
|
+
const finalState = task?.status?.state;
|
|
187
|
+
const payStatus = task?.metadata?.[STATUS_KEY];
|
|
188
|
+
log.info("a2a.paid", { agent: a2aUrl, skill: args.skill, state: finalState, payment: payStatus });
|
|
189
|
+
if (finalState !== "completed") {
|
|
190
|
+
return errorResult(`A2A payment did not complete (state="${finalState}", payment="${payStatus}"): ` +
|
|
191
|
+
JSON.stringify(task?.status?.message ?? task?.metadata ?? {}).slice(0, 300));
|
|
192
|
+
}
|
|
193
|
+
return {
|
|
194
|
+
content: [{ type: "text", text: JSON.stringify({ payment: payStatus, ...extractResult(task) }) }],
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
function extractResult(task) {
|
|
198
|
+
const artifact = (task?.artifacts ?? [])[0];
|
|
199
|
+
const part = artifact?.parts?.[0];
|
|
200
|
+
if (part?.kind === "text" && typeof part.text === "string") {
|
|
201
|
+
try {
|
|
202
|
+
return JSON.parse(part.text);
|
|
203
|
+
}
|
|
204
|
+
catch {
|
|
205
|
+
return { output: part.text };
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return { taskId: task?.id, state: task?.status?.state };
|
|
209
|
+
}
|
|
210
|
+
//# sourceMappingURL=a2a.js.map
|
package/dist/a2a.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"a2a.js","sourceRoot":"","sources":["../src/a2a.ts"],"names":[],"mappings":"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"}
|
package/dist/autoTopup.d.ts
CHANGED
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
*/
|
|
17
17
|
import { type Address, type Hex } from "viem";
|
|
18
18
|
import type { Signer } from "./signer.js";
|
|
19
|
+
import type { Funds } from "./funds.js";
|
|
19
20
|
export interface AutoTopupOptions {
|
|
20
21
|
/** PoC-only: explicit pull amount (atomic). If unset, a dynamic value
|
|
21
22
|
* based on `requiredAtomic` × headroom is used. */
|
|
@@ -23,7 +24,7 @@ export interface AutoTopupOptions {
|
|
|
23
24
|
/** Headroom multiplier for dynamic topup. Default 10. */
|
|
24
25
|
headroomX?: bigint;
|
|
25
26
|
}
|
|
26
|
-
export declare class AutoTopup {
|
|
27
|
+
export declare class AutoTopup implements Funds {
|
|
27
28
|
private readonly signer;
|
|
28
29
|
private readonly safe;
|
|
29
30
|
private readonly allowanceModule;
|
package/dist/autoTopup.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"autoTopup.js","sourceRoot":"","sources":["../src/autoTopup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,IAAI,EACJ,WAAW,GAKZ,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"autoTopup.js","sourceRoot":"","sources":["../src/autoTopup.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function run(): Promise<void>;
|