@hpp-io/x402-mcp-bridge 0.0.2 → 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/README.md +146 -123
- package/bin/hpp-x402.js +5 -0
- package/dist/a2a.d.ts +2 -2
- package/dist/a2a.js +14 -6
- package/dist/a2a.js.map +1 -1
- package/dist/autoTopup.d.ts +4 -1
- package/dist/autoTopup.js +4 -0
- package/dist/autoTopup.js.map +1 -1
- package/dist/cli/channel.d.ts +1 -1
- package/dist/cli/channel.js +1 -8
- package/dist/cli/channel.js.map +1 -1
- package/dist/cli/hpp-x402.d.ts +2 -0
- package/dist/cli/hpp-x402.js +377 -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-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 +2 -2
- package/dist/cli/install-mcp-host.js.map +1 -1
- 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 -1
- package/dist/cli/policy.js +1 -8
- package/dist/cli/policy.js.map +1 -1
- 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 +62 -62
- package/dist/cli/serve.d.ts +1 -0
- package/dist/cli/serve.js +128 -0
- package/dist/cli/serve.js.map +1 -0
- package/dist/cli/setup.d.ts +1 -1
- package/dist/cli/setup.js +1 -5
- package/dist/cli/setup.js.map +1 -1
- package/dist/client.d.ts +6 -2
- package/dist/client.js +34 -15
- package/dist/client.js.map +1 -1
- package/dist/config.d.ts +71 -15
- package/dist/config.js +66 -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 +28 -0
- package/dist/funds/direct-balance.js +61 -0
- package/dist/funds/direct-balance.js.map +1 -0
- package/dist/funds.d.ts +32 -0
- package/dist/funds.js +2 -0
- package/dist/funds.js.map +1 -0
- package/dist/httpX402.d.ts +8 -2
- package/dist/httpX402.js +26 -13
- package/dist/httpX402.js.map +1 -1
- package/dist/index.js +66 -11
- package/dist/index.js.map +1 -1
- package/dist/sellerTools.d.ts +247 -0
- package/dist/sellerTools.js +202 -0
- package/dist/sellerTools.js.map +1 -0
- package/dist/server.d.ts +8 -2
- package/dist/server.js +165 -64
- package/dist/server.js.map +1 -1
- package/dist/spendGuard.d.ts +24 -0
- package/dist/spendGuard.js +124 -0
- package/dist/spendGuard.js.map +1 -0
- package/package.json +13 -12
- package/bin/hpp-x402-channel.js +0 -5
- package/bin/hpp-x402-keychain.js +0 -5
- package/bin/hpp-x402-policy.js +0 -5
- package/bin/hpp-x402-safe-revoke.js +0 -5
- package/bin/hpp-x402-safe-setup.js +0 -5
- package/dist/autoSettlePickup.d.ts +0 -69
- package/dist/autoSettlePickup.js +0 -150
- package/dist/autoSettlePickup.js.map +0 -1
- package/dist/cli/keychain.d.ts +0 -1
- package/dist/cli/keychain.js +0 -147
- package/dist/cli/keychain.js.map +0 -1
package/dist/autoSettlePickup.js
DELETED
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
import { log } from "./log.js";
|
|
2
|
-
/** Default poll interval — design/03 §H.1. */
|
|
3
|
-
const POLL_INTERVAL_MS = (() => {
|
|
4
|
-
const raw = process.env.HPP_X402_POLL_INTERVAL_MS;
|
|
5
|
-
const n = raw ? Number(raw) : NaN;
|
|
6
|
-
return Number.isFinite(n) && n >= 1000 ? n : 30_000;
|
|
7
|
-
})();
|
|
8
|
-
/**
|
|
9
|
-
* Default cap of 2880 = 24h at 30s, matching the server-side TTL
|
|
10
|
-
* (design/02 §C, design/03 §H.3). Picking the same horizon means the
|
|
11
|
-
* client gives up exactly when the server discards the pending voucher.
|
|
12
|
-
*/
|
|
13
|
-
const POLL_MAX_ATTEMPTS = (() => {
|
|
14
|
-
const raw = process.env.HPP_X402_POLL_MAX_ATTEMPTS;
|
|
15
|
-
const n = raw ? Number(raw) : NaN;
|
|
16
|
-
return Number.isFinite(n) && n >= 1 ? n : 2880;
|
|
17
|
-
})();
|
|
18
|
-
/**
|
|
19
|
-
* MCP payment-response meta key. Matches `@x402/mcp`'s
|
|
20
|
-
* `MCP_PAYMENT_RESPONSE_META_KEY`; we duplicate the string literal
|
|
21
|
-
* instead of importing the symbol so this module stays usable from
|
|
22
|
-
* non-MCP callers (e.g. an A2A entry point that picks up settle from a
|
|
23
|
-
* different transport).
|
|
24
|
-
*/
|
|
25
|
-
const MCP_PAYMENT_RESPONSE_META_KEY = "x402/payment-response";
|
|
26
|
-
/** Returns true unless the env explicitly opts out. */
|
|
27
|
-
export function isAutoPollEnabled() {
|
|
28
|
-
const v = process.env.HPP_X402_AUTO_POLL?.toLowerCase().trim();
|
|
29
|
-
return !["false", "0", "no", "off"].includes(v ?? "");
|
|
30
|
-
}
|
|
31
|
-
export function parseComputeResultText(text) {
|
|
32
|
-
try {
|
|
33
|
-
const parsed = JSON.parse(text);
|
|
34
|
-
if (parsed && typeof parsed === "object")
|
|
35
|
-
return parsed;
|
|
36
|
-
}
|
|
37
|
-
catch {
|
|
38
|
-
// not JSON — some compute responses are plain strings ("hello world ...")
|
|
39
|
-
}
|
|
40
|
-
return null;
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* Pulls a `SettleResponse` out of an MCP tool result's `_meta`, if
|
|
44
|
-
* present. Returns `undefined` when the server didn't attach one
|
|
45
|
-
* (the result is still pending, or this is a non-batch path).
|
|
46
|
-
*/
|
|
47
|
-
export function extractSettleResponse(meta) {
|
|
48
|
-
if (!meta || typeof meta !== "object")
|
|
49
|
-
return undefined;
|
|
50
|
-
const candidate = meta[MCP_PAYMENT_RESPONSE_META_KEY];
|
|
51
|
-
if (!candidate || typeof candidate !== "object")
|
|
52
|
-
return undefined;
|
|
53
|
-
return candidate;
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* Fire-and-forget background poller. Polls until terminal then either
|
|
57
|
-
* applies the settle pickup or just exits on failure. Errors inside
|
|
58
|
-
* the poller never propagate — they're logged and the task ends.
|
|
59
|
-
*/
|
|
60
|
-
export function startAutoSettlePoller(deps, ctx) {
|
|
61
|
-
if (!isAutoPollEnabled()) {
|
|
62
|
-
log.info("autoSettle.disabled_by_env", { jobId: ctx.jobId });
|
|
63
|
-
return;
|
|
64
|
-
}
|
|
65
|
-
log.info("autoSettle.poller.start", {
|
|
66
|
-
jobId: ctx.jobId,
|
|
67
|
-
channelId: ctx.channelId,
|
|
68
|
-
pollIntervalMs: POLL_INTERVAL_MS,
|
|
69
|
-
maxAttempts: POLL_MAX_ATTEMPTS,
|
|
70
|
-
});
|
|
71
|
-
let attempt = 0;
|
|
72
|
-
const tick = async () => {
|
|
73
|
-
attempt += 1;
|
|
74
|
-
try {
|
|
75
|
-
const res = await deps.base.callTool({
|
|
76
|
-
name: "get_compute_result",
|
|
77
|
-
arguments: { jobId: ctx.jobId },
|
|
78
|
-
});
|
|
79
|
-
const content = res.content;
|
|
80
|
-
const text = content?.[0]?.type === "text" ? content[0]?.text : undefined;
|
|
81
|
-
const parsed = text ? parseComputeResultText(text) : null;
|
|
82
|
-
// Settle pickup first — once the server has attached a
|
|
83
|
-
// PAYMENT-RESPONSE we should apply it whatever the status reads.
|
|
84
|
-
const settleResponse = extractSettleResponse(res._meta);
|
|
85
|
-
if (parsed?.status === "succeeded" || settleResponse) {
|
|
86
|
-
if (settleResponse) {
|
|
87
|
-
try {
|
|
88
|
-
await deps.batchScheme.processSettleResponse(settleResponse);
|
|
89
|
-
log.info("autoSettle.settle_applied", {
|
|
90
|
-
jobId: ctx.jobId,
|
|
91
|
-
channelId: ctx.channelId,
|
|
92
|
-
attempts: attempt,
|
|
93
|
-
tool: ctx.toolName,
|
|
94
|
-
tx: settleResponse.transaction,
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
catch (err) {
|
|
98
|
-
// processSettleResponse shouldn't throw in steady state,
|
|
99
|
-
// but if it does (corrupted channel state, etc.) we log
|
|
100
|
-
// and abandon — a subsequent paid call will trigger a
|
|
101
|
-
// corrective 402 and resync.
|
|
102
|
-
log.error("autoSettle.settle_apply_failed", {
|
|
103
|
-
jobId: ctx.jobId,
|
|
104
|
-
channelId: ctx.channelId,
|
|
105
|
-
err: err.message,
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
else {
|
|
110
|
-
log.info("autoSettle.succeeded_without_payment_response", {
|
|
111
|
-
jobId: ctx.jobId,
|
|
112
|
-
attempts: attempt,
|
|
113
|
-
note: "server didn't attach PAYMENT-RESPONSE; nothing to apply",
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
|
-
return;
|
|
117
|
-
}
|
|
118
|
-
if (parsed?.status === "failed") {
|
|
119
|
-
// Deferred-settle model: the server never charged for a job that
|
|
120
|
-
// failed, so there's nothing to refund. Just exit.
|
|
121
|
-
log.info("autoSettle.poller.terminal_failed", {
|
|
122
|
-
jobId: ctx.jobId,
|
|
123
|
-
attempts: attempt,
|
|
124
|
-
serverError: parsed.error,
|
|
125
|
-
});
|
|
126
|
-
return;
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
catch (err) {
|
|
130
|
-
// Polling failure isn't fatal — server might be momentarily
|
|
131
|
-
// unreachable. Keep trying until the attempt cap.
|
|
132
|
-
log.debug("autoSettle.poller.probe_failed", {
|
|
133
|
-
jobId: ctx.jobId,
|
|
134
|
-
attempt,
|
|
135
|
-
err: err.message,
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
|
-
if (attempt >= POLL_MAX_ATTEMPTS) {
|
|
139
|
-
log.info("autoSettle.poller.timeout", {
|
|
140
|
-
jobId: ctx.jobId,
|
|
141
|
-
attempts: attempt,
|
|
142
|
-
elapsedMs: POLL_INTERVAL_MS * attempt,
|
|
143
|
-
});
|
|
144
|
-
return;
|
|
145
|
-
}
|
|
146
|
-
setTimeout(tick, POLL_INTERVAL_MS).unref();
|
|
147
|
-
};
|
|
148
|
-
setTimeout(tick, POLL_INTERVAL_MS).unref();
|
|
149
|
-
}
|
|
150
|
-
//# sourceMappingURL=autoSettlePickup.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"autoSettlePickup.js","sourceRoot":"","sources":["../src/autoSettlePickup.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/keychain.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/dist/cli/keychain.js
DELETED
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* hpp-x402-keychain — store the delegate private key in the OS keychain.
|
|
3
|
-
*
|
|
4
|
-
* Replaces `DELEGATE_PRIVATE_KEY=0x...` in the host config (Claude Desktop
|
|
5
|
-
* / OpenClaw / .env.local) with `keychain://hpp-x402/<account>`. The
|
|
6
|
-
* bridge resolves the URI at startup via @napi-rs/keyring (macOS Keychain,
|
|
7
|
-
* Windows Credential Vault, Linux libsecret).
|
|
8
|
-
*
|
|
9
|
-
* Usage:
|
|
10
|
-
* hpp-x402-keychain set [account] prompts for hex (no echo)
|
|
11
|
-
* hpp-x402-keychain set [account] --stdin reads hex from stdin (for piping)
|
|
12
|
-
* hpp-x402-keychain generate [account] creates a fresh delegate key
|
|
13
|
-
* hpp-x402-keychain delete [account]
|
|
14
|
-
* hpp-x402-keychain show [account] prints address (never the key)
|
|
15
|
-
* hpp-x402-keychain uri [account] prints keychain://hpp-x402/<account>
|
|
16
|
-
*
|
|
17
|
-
* `account` defaults to `delegate-default`.
|
|
18
|
-
*
|
|
19
|
-
* Note: `setup` (hpp-x402-safe-setup) prints a copy-pasteable env block.
|
|
20
|
-
* After running `keychain set`, replace that env line in your host config
|
|
21
|
-
* with the printed `keychain://...` URI.
|
|
22
|
-
*/
|
|
23
|
-
import { generatePrivateKey, privateKeyToAccount } from "viem/accounts";
|
|
24
|
-
import * as readline from "node:readline";
|
|
25
|
-
import { buildKeychainURI, deleteKeychain, isHexKey, resolveKeychain, setKeychain, KEYCHAIN_SERVICE, } from "../keychain.js";
|
|
26
|
-
const DEFAULT_ACCOUNT = "delegate-default";
|
|
27
|
-
function usage() {
|
|
28
|
-
process.stderr.write([
|
|
29
|
-
"hpp-x402-keychain — manage delegate keys in the OS keychain",
|
|
30
|
-
"",
|
|
31
|
-
"Usage:",
|
|
32
|
-
" hpp-x402-keychain set [account] prompt for hex (no echo)",
|
|
33
|
-
" hpp-x402-keychain set [account] --stdin read hex from stdin",
|
|
34
|
-
" hpp-x402-keychain generate [account] create + store fresh key",
|
|
35
|
-
" hpp-x402-keychain show [account] print address only",
|
|
36
|
-
" hpp-x402-keychain uri [account] print keychain:// URI",
|
|
37
|
-
" hpp-x402-keychain delete [account]",
|
|
38
|
-
"",
|
|
39
|
-
`Default account: ${DEFAULT_ACCOUNT}`,
|
|
40
|
-
`Service (fixed): ${KEYCHAIN_SERVICE}`,
|
|
41
|
-
"",
|
|
42
|
-
].join("\n"));
|
|
43
|
-
process.exit(1);
|
|
44
|
-
}
|
|
45
|
-
function parseCmd(argv) {
|
|
46
|
-
const args = argv.slice(2);
|
|
47
|
-
const cmd = (args[0] ?? "help");
|
|
48
|
-
const positional = [];
|
|
49
|
-
const flags = new Set();
|
|
50
|
-
for (const a of args.slice(1)) {
|
|
51
|
-
if (a.startsWith("--"))
|
|
52
|
-
flags.add(a.slice(2));
|
|
53
|
-
else
|
|
54
|
-
positional.push(a);
|
|
55
|
-
}
|
|
56
|
-
if (!["set", "generate", "delete", "show", "uri", "help"].includes(cmd)) {
|
|
57
|
-
usage();
|
|
58
|
-
}
|
|
59
|
-
const account = positional[0] ?? DEFAULT_ACCOUNT;
|
|
60
|
-
return { cmd, account, flags };
|
|
61
|
-
}
|
|
62
|
-
async function readHexFromTTY() {
|
|
63
|
-
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
64
|
-
const muted = rl;
|
|
65
|
-
const origWrite = muted._writeToOutput;
|
|
66
|
-
muted._writeToOutput = (s) => {
|
|
67
|
-
if (s.startsWith("Delegate private key"))
|
|
68
|
-
origWrite.call(muted, s);
|
|
69
|
-
};
|
|
70
|
-
const answer = await new Promise((resolve) => rl.question("Delegate private key (0x + 64 hex, hidden): ", (a) => {
|
|
71
|
-
process.stdout.write("\n");
|
|
72
|
-
rl.close();
|
|
73
|
-
resolve(a.trim());
|
|
74
|
-
}));
|
|
75
|
-
if (!isHexKey(answer))
|
|
76
|
-
throw new Error("expected 0x + 64 hex chars");
|
|
77
|
-
return answer;
|
|
78
|
-
}
|
|
79
|
-
async function readHexFromStdin() {
|
|
80
|
-
const chunks = [];
|
|
81
|
-
for await (const c of process.stdin)
|
|
82
|
-
chunks.push(c);
|
|
83
|
-
const raw = Buffer.concat(chunks).toString("utf8").trim();
|
|
84
|
-
if (!isHexKey(raw))
|
|
85
|
-
throw new Error("stdin did not contain a 0x + 64 hex key");
|
|
86
|
-
return raw;
|
|
87
|
-
}
|
|
88
|
-
async function main() {
|
|
89
|
-
const { cmd, account, flags } = parseCmd(process.argv);
|
|
90
|
-
if (cmd === "help")
|
|
91
|
-
usage();
|
|
92
|
-
if (cmd === "set") {
|
|
93
|
-
const hex = flags.has("stdin") ? await readHexFromStdin() : await readHexFromTTY();
|
|
94
|
-
setKeychain(account, hex);
|
|
95
|
-
const addr = privateKeyToAccount(hex).address;
|
|
96
|
-
process.stdout.write([
|
|
97
|
-
"✓ stored",
|
|
98
|
-
` uri : ${buildKeychainURI(account)}`,
|
|
99
|
-
` address : ${addr}`,
|
|
100
|
-
"",
|
|
101
|
-
"Replace DELEGATE_PRIVATE_KEY in your host config with the URI above.",
|
|
102
|
-
"",
|
|
103
|
-
].join("\n"));
|
|
104
|
-
return;
|
|
105
|
-
}
|
|
106
|
-
if (cmd === "generate") {
|
|
107
|
-
const hex = generatePrivateKey();
|
|
108
|
-
setKeychain(account, hex);
|
|
109
|
-
const addr = privateKeyToAccount(hex).address;
|
|
110
|
-
process.stdout.write([
|
|
111
|
-
"✓ generated + stored fresh delegate key",
|
|
112
|
-
` uri : ${buildKeychainURI(account)}`,
|
|
113
|
-
` address : ${addr}`,
|
|
114
|
-
"",
|
|
115
|
-
"Fund this address with ~0.001 native HPP for gas, then add it as a",
|
|
116
|
-
"delegate on your Safe (allowanceModule.addDelegate + setAllowance).",
|
|
117
|
-
"Or re-run hpp-x402-safe-setup with --delegate-pk pre-set:",
|
|
118
|
-
" - the bridge does NOT print the private key; rotate via the keychain CLI.",
|
|
119
|
-
"",
|
|
120
|
-
].join("\n"));
|
|
121
|
-
return;
|
|
122
|
-
}
|
|
123
|
-
if (cmd === "show") {
|
|
124
|
-
const hex = resolveKeychain(buildKeychainURI(account));
|
|
125
|
-
const addr = privateKeyToAccount(hex).address;
|
|
126
|
-
process.stdout.write([
|
|
127
|
-
` uri : ${buildKeychainURI(account)}`,
|
|
128
|
-
` address : ${addr}`,
|
|
129
|
-
"",
|
|
130
|
-
].join("\n"));
|
|
131
|
-
return;
|
|
132
|
-
}
|
|
133
|
-
if (cmd === "uri") {
|
|
134
|
-
process.stdout.write(buildKeychainURI(account) + "\n");
|
|
135
|
-
return;
|
|
136
|
-
}
|
|
137
|
-
if (cmd === "delete") {
|
|
138
|
-
const ok = deleteKeychain(account);
|
|
139
|
-
process.stdout.write(ok ? `✓ deleted ${buildKeychainURI(account)}\n` : `(no entry: ${buildKeychainURI(account)})\n`);
|
|
140
|
-
return;
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
main().catch((err) => {
|
|
144
|
-
process.stderr.write(`hpp-x402-keychain: ${err.message}\n`);
|
|
145
|
-
process.exit(1);
|
|
146
|
-
});
|
|
147
|
-
//# sourceMappingURL=keychain.js.map
|
package/dist/cli/keychain.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"keychain.js","sourceRoot":"","sources":["../../src/cli/keychain.ts"],"names":[],"mappings":"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"}
|