@hpp-io/x402-mcp-bridge 0.0.1 → 0.0.2
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 +54 -4
- package/bin/hpp-x402-channel.js +5 -0
- package/bin/hpp-x402-keychain.js +5 -0
- package/bin/hpp-x402-policy.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/autoSettlePickup.d.ts +69 -0
- package/dist/autoSettlePickup.js +150 -0
- package/dist/autoSettlePickup.js.map +1 -0
- package/dist/cli/channel.d.ts +1 -0
- package/dist/cli/channel.js +330 -0
- package/dist/cli/channel.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-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/keychain.d.ts +1 -0
- package/dist/cli/keychain.js +147 -0
- package/dist/cli/keychain.js.map +1 -0
- package/dist/cli/policy.d.ts +1 -0
- package/dist/cli/policy.js +219 -0
- package/dist/cli/policy.js.map +1 -0
- package/dist/cli/safe.d.ts +4111 -9519
- package/dist/cli/setup.js +23 -1
- package/dist/cli/setup.js.map +1 -1
- package/dist/client.d.ts +19 -8
- package/dist/client.js +118 -0
- package/dist/client.js.map +1 -1
- package/dist/config.d.ts +4 -4
- package/dist/config.js +11 -5
- package/dist/config.js.map +1 -1
- package/dist/httpX402.d.ts +39 -0
- package/dist/httpX402.js +208 -0
- package/dist/httpX402.js.map +1 -0
- package/dist/index.js +43 -14
- 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 +15 -1
- package/dist/server.js +154 -10
- package/dist/server.js.map +1 -1
- package/docs/policy.md +101 -0
- package/package.json +12 -5
|
@@ -0,0 +1,147 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keychain.js","sourceRoot":"","sources":["../../src/cli/keychain.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* hpp-x402-policy — manage the host policy file (`~/.hpp-x402/policy.json`)
|
|
3
|
+
* that the `x402_http_call` tool reads for per-host auth-header injection and
|
|
4
|
+
* spend guardrails. Editing the JSON by hand works too; this is a convenience
|
|
5
|
+
* wrapper (mirrors hpp-x402-keychain).
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* hpp-x402-policy path print the policy file path
|
|
9
|
+
* hpp-x402-policy show print the full policy JSON
|
|
10
|
+
* hpp-x402-policy list summarize configured hosts
|
|
11
|
+
* hpp-x402-policy set <host> [flags] add/update a host entry
|
|
12
|
+
* --header NAME=SOURCE (repeatable) e.g. X-Api-Key=file:~/.hpphub/config.json#api_key
|
|
13
|
+
* --max-per-call <usdc> e.g. 5 (stored atomic, 6 dec)
|
|
14
|
+
* --cooldown-ms <n> min ms between paid calls
|
|
15
|
+
* --https <true|false> require https (default true)
|
|
16
|
+
* hpp-x402-policy unset <host> remove a host entry
|
|
17
|
+
* hpp-x402-policy unset <host> --header NAME remove a single header
|
|
18
|
+
* hpp-x402-policy defaults [flags] set _defaults
|
|
19
|
+
* --allow-unlisted <true|false> allow non-listed hosts (default false)
|
|
20
|
+
* --max-per-call <usdc> / --https <bool> default limits
|
|
21
|
+
*
|
|
22
|
+
* value-source for headers: file:<path>#<field> | env:<VAR> |
|
|
23
|
+
* keychain://<svc>/<acct> | literal:<value>
|
|
24
|
+
*/
|
|
25
|
+
import { loadPolicy, savePolicy, policyFilePath, } from "../policy.js";
|
|
26
|
+
const USDC_DECIMALS = 6; // USDC.e
|
|
27
|
+
const SOURCE_PREFIXES = ["file:", "env:", "keychain://", "literal:"];
|
|
28
|
+
function usage() {
|
|
29
|
+
process.stderr.write([
|
|
30
|
+
"hpp-x402-policy — manage ~/.hpp-x402/policy.json (host auth + spend guardrails)",
|
|
31
|
+
"",
|
|
32
|
+
"Usage:",
|
|
33
|
+
" hpp-x402-policy path",
|
|
34
|
+
" hpp-x402-policy show",
|
|
35
|
+
" hpp-x402-policy list",
|
|
36
|
+
" hpp-x402-policy set <host> [--header NAME=SOURCE]... [--max-per-call <usdc>]",
|
|
37
|
+
" [--cooldown-ms <n>] [--https <true|false>]",
|
|
38
|
+
" hpp-x402-policy unset <host> [--header NAME]",
|
|
39
|
+
" hpp-x402-policy defaults [--allow-unlisted <true|false>] [--max-per-call <usdc>] [--https <true|false>]",
|
|
40
|
+
"",
|
|
41
|
+
"value-source: file:<path>#<field> | env:<VAR> | keychain://<svc>/<acct> | literal:<value>",
|
|
42
|
+
"example: hpp-x402-policy set hub-stage.hpp.io \\",
|
|
43
|
+
" --header X-Api-Key=file:~/.hpphub/config.json#api_key --max-per-call 5 --cooldown-ms 300000",
|
|
44
|
+
"",
|
|
45
|
+
].join("\n"));
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
function parseArgs(argv) {
|
|
49
|
+
const args = argv.slice(2);
|
|
50
|
+
const cmd = args[0] ?? "help";
|
|
51
|
+
const out = { cmd, headers: [] };
|
|
52
|
+
const rest = args.slice(1);
|
|
53
|
+
const positional = [];
|
|
54
|
+
for (let i = 0; i < rest.length; i++) {
|
|
55
|
+
const a = rest[i];
|
|
56
|
+
if (!a.startsWith("--")) {
|
|
57
|
+
positional.push(a);
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
const key = a.slice(2);
|
|
61
|
+
const val = rest[i + 1];
|
|
62
|
+
const takeVal = () => {
|
|
63
|
+
if (val === undefined || val.startsWith("--"))
|
|
64
|
+
throw new Error(`--${key} needs a value`);
|
|
65
|
+
i++;
|
|
66
|
+
return val;
|
|
67
|
+
};
|
|
68
|
+
switch (key) {
|
|
69
|
+
case "header": {
|
|
70
|
+
const v = takeVal();
|
|
71
|
+
if (out.cmd === "unset") {
|
|
72
|
+
out.removeHeader = v; // unset --header NAME
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
const eq = v.indexOf("=");
|
|
76
|
+
if (eq === -1)
|
|
77
|
+
throw new Error(`--header expects NAME=SOURCE, got "${v}"`);
|
|
78
|
+
out.headers.push({ name: v.slice(0, eq), source: v.slice(eq + 1) });
|
|
79
|
+
}
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
case "max-per-call":
|
|
83
|
+
out.maxPerCall = takeVal();
|
|
84
|
+
break;
|
|
85
|
+
case "cooldown-ms":
|
|
86
|
+
out.cooldownMs = takeVal();
|
|
87
|
+
break;
|
|
88
|
+
case "https":
|
|
89
|
+
out.https = takeVal();
|
|
90
|
+
break;
|
|
91
|
+
case "allow-unlisted":
|
|
92
|
+
out.allowUnlisted = takeVal();
|
|
93
|
+
break;
|
|
94
|
+
default: throw new Error(`unknown flag --${key}`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
out.host = positional[0];
|
|
98
|
+
return out;
|
|
99
|
+
}
|
|
100
|
+
function usdcToAtomic(usdc) {
|
|
101
|
+
const n = Number(usdc);
|
|
102
|
+
if (!Number.isFinite(n) || n < 0)
|
|
103
|
+
throw new Error(`invalid amount: ${usdc}`);
|
|
104
|
+
return String(Math.round(n * 10 ** USDC_DECIMALS));
|
|
105
|
+
}
|
|
106
|
+
function atomicToUsdc(a) {
|
|
107
|
+
return a == null ? "-" : String(Number(a) / 10 ** USDC_DECIMALS);
|
|
108
|
+
}
|
|
109
|
+
function parseBool(s) {
|
|
110
|
+
if (s === "true")
|
|
111
|
+
return true;
|
|
112
|
+
if (s === "false")
|
|
113
|
+
return false;
|
|
114
|
+
throw new Error(`expected true|false, got "${s}"`);
|
|
115
|
+
}
|
|
116
|
+
function buildLimits(base, a) {
|
|
117
|
+
const limits = { ...(base ?? {}) };
|
|
118
|
+
if (a.maxPerCall !== undefined)
|
|
119
|
+
limits.maxPerCallAtomic = usdcToAtomic(a.maxPerCall);
|
|
120
|
+
if (a.cooldownMs !== undefined)
|
|
121
|
+
limits.cooldownMs = Number(a.cooldownMs);
|
|
122
|
+
if (a.https !== undefined)
|
|
123
|
+
limits.requireHttps = parseBool(a.https);
|
|
124
|
+
return limits;
|
|
125
|
+
}
|
|
126
|
+
function main() {
|
|
127
|
+
const a = parseArgs(process.argv);
|
|
128
|
+
if (a.cmd === "help")
|
|
129
|
+
usage();
|
|
130
|
+
if (a.cmd === "path") {
|
|
131
|
+
process.stdout.write(policyFilePath() + "\n");
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
const policy = loadPolicy();
|
|
135
|
+
if (a.cmd === "show") {
|
|
136
|
+
process.stdout.write(JSON.stringify(policy, null, 2) + "\n");
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
if (a.cmd === "list") {
|
|
140
|
+
const hosts = Object.keys(policy).filter((k) => k !== "_defaults");
|
|
141
|
+
if (hosts.length === 0) {
|
|
142
|
+
process.stdout.write("(no hosts configured)\n");
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
const d = policy._defaults;
|
|
146
|
+
if (d)
|
|
147
|
+
process.stdout.write(`_defaults: allowUnlisted=${d.allowUnlisted ?? false} maxPerCall=${atomicToUsdc(d.limits?.maxPerCallAtomic)} https=${d.limits?.requireHttps ?? true}\n`);
|
|
148
|
+
for (const h of hosts) {
|
|
149
|
+
const hp = policy[h];
|
|
150
|
+
const hdrs = Object.keys(hp.headers ?? {}).join(", ") || "(none)";
|
|
151
|
+
const l = hp.limits ?? {};
|
|
152
|
+
process.stdout.write(`${h}\n headers: ${hdrs}\n maxPerCall: ${atomicToUsdc(l.maxPerCallAtomic)} cooldownMs: ${l.cooldownMs ?? "-"} https: ${l.requireHttps ?? true}\n`);
|
|
153
|
+
}
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
if (a.cmd === "set") {
|
|
157
|
+
if (!a.host)
|
|
158
|
+
throw new Error("set requires <host>");
|
|
159
|
+
if (a.headers.some((h) => !SOURCE_PREFIXES.some((p) => h.source.startsWith(p)))) {
|
|
160
|
+
throw new Error(`header source must start with one of: ${SOURCE_PREFIXES.join(", ")}`);
|
|
161
|
+
}
|
|
162
|
+
const existing = policy[a.host] ?? {};
|
|
163
|
+
const headers = { ...(existing.headers ?? {}) };
|
|
164
|
+
for (const h of a.headers)
|
|
165
|
+
headers[h.name] = h.source;
|
|
166
|
+
const next = { ...existing };
|
|
167
|
+
if (Object.keys(headers).length)
|
|
168
|
+
next.headers = headers;
|
|
169
|
+
const limits = buildLimits(existing.limits, a);
|
|
170
|
+
if (Object.keys(limits).length)
|
|
171
|
+
next.limits = limits;
|
|
172
|
+
policy[a.host] = next;
|
|
173
|
+
savePolicy(policy);
|
|
174
|
+
process.stdout.write(`✓ set ${a.host}\n headers: ${Object.keys(next.headers ?? {}).join(", ") || "(none)"}\n maxPerCall: ${atomicToUsdc(next.limits?.maxPerCallAtomic)} cooldownMs: ${next.limits?.cooldownMs ?? "-"} https: ${next.limits?.requireHttps ?? true}\n`);
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
if (a.cmd === "unset") {
|
|
178
|
+
if (!a.host)
|
|
179
|
+
throw new Error("unset requires <host>");
|
|
180
|
+
const hp = policy[a.host];
|
|
181
|
+
if (!hp) {
|
|
182
|
+
process.stdout.write(`(no entry: ${a.host})\n`);
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
if (a.removeHeader) {
|
|
186
|
+
if (hp.headers)
|
|
187
|
+
delete hp.headers[a.removeHeader];
|
|
188
|
+
savePolicy(policy);
|
|
189
|
+
process.stdout.write(`✓ removed header ${a.removeHeader} from ${a.host}\n`);
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
delete policy[a.host];
|
|
193
|
+
savePolicy(policy);
|
|
194
|
+
process.stdout.write(`✓ removed host ${a.host}\n`);
|
|
195
|
+
}
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
if (a.cmd === "defaults") {
|
|
199
|
+
const d = { ...(policy._defaults ?? {}) };
|
|
200
|
+
if (a.allowUnlisted !== undefined)
|
|
201
|
+
d.allowUnlisted = parseBool(a.allowUnlisted);
|
|
202
|
+
const limits = buildLimits(d.limits, a);
|
|
203
|
+
if (Object.keys(limits).length)
|
|
204
|
+
d.limits = limits;
|
|
205
|
+
policy._defaults = d;
|
|
206
|
+
savePolicy(policy);
|
|
207
|
+
process.stdout.write(`✓ defaults: allowUnlisted=${d.allowUnlisted ?? false} maxPerCall=${atomicToUsdc(d.limits?.maxPerCallAtomic)} https=${d.limits?.requireHttps ?? true}\n`);
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
usage();
|
|
211
|
+
}
|
|
212
|
+
try {
|
|
213
|
+
main();
|
|
214
|
+
}
|
|
215
|
+
catch (err) {
|
|
216
|
+
process.stderr.write(`hpp-x402-policy: ${err.message}\n`);
|
|
217
|
+
process.exit(1);
|
|
218
|
+
}
|
|
219
|
+
//# sourceMappingURL=policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy.js","sourceRoot":"","sources":["../../src/cli/policy.ts"],"names":[],"mappings":"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"}
|