@keeperhub/wallet 0.1.8 → 0.1.9
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 +9 -0
- package/dist/cli.cjs +69 -13
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +69 -13
- package/dist/cli.js.map +1 -1
- package/dist/hook-entrypoint.cjs +23 -0
- package/dist/hook-entrypoint.cjs.map +1 -1
- package/dist/hook-entrypoint.js +23 -0
- package/dist/hook-entrypoint.js.map +1 -1
- package/dist/index.cjs +94 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +27 -2
- package/dist/index.d.ts +27 -2
- package/dist/index.js +93 -13
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -43,6 +43,7 @@ __export(index_exports, {
|
|
|
43
43
|
paymentSigner: () => paymentSigner,
|
|
44
44
|
readWalletConfig: () => readWalletConfig,
|
|
45
45
|
registerClaudeCodeHook: () => registerClaudeCodeHook,
|
|
46
|
+
resolveHookCommand: () => resolveHookCommand,
|
|
46
47
|
runCli: () => runCli,
|
|
47
48
|
runHookCli: () => runHookCli,
|
|
48
49
|
selectProtocol: () => selectProtocol,
|
|
@@ -196,15 +197,69 @@ function fund(walletAddress) {
|
|
|
196
197
|
}
|
|
197
198
|
|
|
198
199
|
// src/skill-install.ts
|
|
200
|
+
var import_node_child_process = require("child_process");
|
|
199
201
|
var import_promises = require("fs/promises");
|
|
202
|
+
var import_node_fs2 = require("fs");
|
|
200
203
|
var import_node_path2 = require("path");
|
|
201
204
|
var import_node_url = require("url");
|
|
202
|
-
var
|
|
203
|
-
var
|
|
204
|
-
|
|
205
|
+
var HOOK_BIN = "keeperhub-wallet-hook";
|
|
206
|
+
var HOOK_COMMAND_BARE = HOOK_BIN;
|
|
207
|
+
var PACKAGE_NAME = "@keeperhub/wallet";
|
|
208
|
+
function readPackageVersion() {
|
|
209
|
+
try {
|
|
210
|
+
const here = (0, import_node_path2.dirname)((0, import_node_url.fileURLToPath)(__filename));
|
|
211
|
+
const pkgPath = (0, import_node_path2.join)(here, "..", "package.json");
|
|
212
|
+
const raw = (0, import_node_fs2.readFileSync)(pkgPath, "utf-8");
|
|
213
|
+
const parsed = JSON.parse(raw);
|
|
214
|
+
if (typeof parsed.version === "string" && parsed.version.length > 0) {
|
|
215
|
+
return parsed.version;
|
|
216
|
+
}
|
|
217
|
+
} catch {
|
|
218
|
+
}
|
|
219
|
+
return "latest";
|
|
220
|
+
}
|
|
221
|
+
function buildNpxCommand(version) {
|
|
222
|
+
return `npx -y -p ${PACKAGE_NAME}@${version} ${HOOK_BIN}`;
|
|
223
|
+
}
|
|
224
|
+
var KEEPERHUB_HOOK_MARKER = HOOK_BIN;
|
|
225
|
+
function filterKeeperhubHooksFromEntry(entry) {
|
|
226
|
+
if (typeof entry !== "object" || entry === null) {
|
|
227
|
+
return entry;
|
|
228
|
+
}
|
|
229
|
+
const candidate = entry;
|
|
230
|
+
if (!Array.isArray(candidate.hooks)) {
|
|
231
|
+
return entry;
|
|
232
|
+
}
|
|
233
|
+
const survivors = candidate.hooks.filter((h) => {
|
|
234
|
+
const cmd = h?.command;
|
|
235
|
+
return !(typeof cmd === "string" && cmd.includes(KEEPERHUB_HOOK_MARKER));
|
|
236
|
+
});
|
|
237
|
+
if (survivors.length === candidate.hooks.length) {
|
|
238
|
+
return entry;
|
|
239
|
+
}
|
|
240
|
+
if (survivors.length === 0) {
|
|
241
|
+
return null;
|
|
242
|
+
}
|
|
243
|
+
return { ...candidate, hooks: survivors };
|
|
244
|
+
}
|
|
245
|
+
function resolveHookCommand() {
|
|
246
|
+
const envOverride = process.env.KEEPERHUB_WALLET_HOOK_COMMAND;
|
|
247
|
+
if (envOverride && envOverride.length > 0) {
|
|
248
|
+
return envOverride;
|
|
249
|
+
}
|
|
250
|
+
try {
|
|
251
|
+
(0, import_node_child_process.execFileSync)("/bin/sh", ["-c", `command -v ${HOOK_BIN}`], {
|
|
252
|
+
stdio: "ignore"
|
|
253
|
+
});
|
|
254
|
+
return HOOK_COMMAND_BARE;
|
|
255
|
+
} catch {
|
|
256
|
+
return buildNpxCommand(readPackageVersion());
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
function buildKeeperhubEntry(command) {
|
|
205
260
|
return {
|
|
206
261
|
matcher: "*",
|
|
207
|
-
hooks: [{ type: "command", command
|
|
262
|
+
hooks: [{ type: "command", command }]
|
|
208
263
|
};
|
|
209
264
|
}
|
|
210
265
|
function resolveDefaultSkillSource() {
|
|
@@ -215,7 +270,8 @@ function defaultNotice(msg) {
|
|
|
215
270
|
process.stderr.write(`${msg}
|
|
216
271
|
`);
|
|
217
272
|
}
|
|
218
|
-
async function registerClaudeCodeHook(settingsPath) {
|
|
273
|
+
async function registerClaudeCodeHook(settingsPath, options = {}) {
|
|
274
|
+
const command = options.hookCommand ?? resolveHookCommand();
|
|
219
275
|
let raw = null;
|
|
220
276
|
try {
|
|
221
277
|
raw = await (0, import_promises.readFile)(settingsPath, "utf-8");
|
|
@@ -238,12 +294,12 @@ async function registerClaudeCodeHook(settingsPath) {
|
|
|
238
294
|
const existingPreToolUse = Array.isArray(hooks.PreToolUse) ? hooks.PreToolUse : [];
|
|
239
295
|
const filtered = [];
|
|
240
296
|
for (const entry of existingPreToolUse) {
|
|
241
|
-
const
|
|
242
|
-
if (
|
|
243
|
-
filtered.push(
|
|
297
|
+
const survivor = filterKeeperhubHooksFromEntry(entry);
|
|
298
|
+
if (survivor !== null) {
|
|
299
|
+
filtered.push(survivor);
|
|
244
300
|
}
|
|
245
301
|
}
|
|
246
|
-
filtered.push(buildKeeperhubEntry());
|
|
302
|
+
filtered.push(buildKeeperhubEntry(command));
|
|
247
303
|
hooks.PreToolUse = filtered;
|
|
248
304
|
config.hooks = hooks;
|
|
249
305
|
await (0, import_promises.mkdir)((0, import_node_path2.dirname)(settingsPath), { recursive: true, mode: 448 });
|
|
@@ -259,26 +315,27 @@ async function writeSkillToAgent(agent, skillSource) {
|
|
|
259
315
|
await (0, import_promises.chmod)(target, 420);
|
|
260
316
|
return { agent: agent.agent, path: target, status: "written" };
|
|
261
317
|
}
|
|
262
|
-
function buildNoticeMessage(agent) {
|
|
263
|
-
return `${agent.agent} does not support auto-registered PreToolUse hooks; run \`${
|
|
318
|
+
function buildNoticeMessage(agent, command) {
|
|
319
|
+
return `${agent.agent} does not support auto-registered PreToolUse hooks; run \`${command}\` on every tool use via ${agent.agent}'s settings file at ${agent.settingsFile}`;
|
|
264
320
|
}
|
|
265
321
|
async function installSkill(options = {}) {
|
|
266
322
|
const agents = detectAgents(options.homeOverride);
|
|
267
323
|
const skillSource = options.skillSourcePath ?? resolveDefaultSkillSource();
|
|
268
324
|
const onNotice = options.onNotice ?? defaultNotice;
|
|
325
|
+
const hookCommand = options.hookCommand ?? resolveHookCommand();
|
|
269
326
|
const skillWrites = [];
|
|
270
327
|
const hookRegistrations = [];
|
|
271
328
|
for (const agent of agents) {
|
|
272
329
|
const write = await writeSkillToAgent(agent, skillSource);
|
|
273
330
|
skillWrites.push(write);
|
|
274
331
|
if (agent.hookSupport === "claude-code") {
|
|
275
|
-
await registerClaudeCodeHook(agent.settingsFile);
|
|
332
|
+
await registerClaudeCodeHook(agent.settingsFile, { hookCommand });
|
|
276
333
|
hookRegistrations.push({
|
|
277
334
|
agent: agent.agent,
|
|
278
335
|
status: "registered"
|
|
279
336
|
});
|
|
280
337
|
} else {
|
|
281
|
-
const message = buildNoticeMessage(agent);
|
|
338
|
+
const message = buildNoticeMessage(agent, hookCommand);
|
|
282
339
|
hookRegistrations.push({
|
|
283
340
|
agent: agent.agent,
|
|
284
341
|
status: "notice",
|
|
@@ -686,6 +743,26 @@ var DEFAULT_TOOL_RE = /keeperhub|wallet|sign/i;
|
|
|
686
743
|
function defaultToolMatcher(name) {
|
|
687
744
|
return DEFAULT_TOOL_RE.test(name);
|
|
688
745
|
}
|
|
746
|
+
function hasPaymentShape(input) {
|
|
747
|
+
const ti = input.tool_input ?? {};
|
|
748
|
+
const challenge = ti.paymentChallenge;
|
|
749
|
+
if (challenge !== void 0 && challenge !== null) {
|
|
750
|
+
return true;
|
|
751
|
+
}
|
|
752
|
+
if (ti.amount !== void 0 && ti.amount !== null) {
|
|
753
|
+
return true;
|
|
754
|
+
}
|
|
755
|
+
if (ti.unit !== void 0 && ti.unit !== null) {
|
|
756
|
+
return true;
|
|
757
|
+
}
|
|
758
|
+
for (const field of ["to", "contract", "assetAddress"]) {
|
|
759
|
+
const v = ti[field];
|
|
760
|
+
if (typeof v === "string" && ADDRESS_RE.test(v)) {
|
|
761
|
+
return true;
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
return false;
|
|
765
|
+
}
|
|
689
766
|
function extractAmountMicroUsdc(input) {
|
|
690
767
|
const ti = input.tool_input ?? {};
|
|
691
768
|
const challenge = ti.paymentChallenge ?? {};
|
|
@@ -735,6 +812,9 @@ async function createPreToolUseHook(options = {}) {
|
|
|
735
812
|
if (!(typeof hookInput.tool_name === "string" && toolMatcher(hookInput.tool_name))) {
|
|
736
813
|
return { decision: "allow" };
|
|
737
814
|
}
|
|
815
|
+
if (!hasPaymentShape(hookInput)) {
|
|
816
|
+
return { decision: "allow" };
|
|
817
|
+
}
|
|
738
818
|
const contractAddr = extractContractAddress(hookInput);
|
|
739
819
|
const amountMicro = extractAmountMicroUsdc(hookInput);
|
|
740
820
|
if (contractAddr && !safety.allowlisted_contracts.includes(contractAddr)) {
|
|
@@ -1084,6 +1164,7 @@ var paymentSigner = createPaymentSigner();
|
|
|
1084
1164
|
paymentSigner,
|
|
1085
1165
|
readWalletConfig,
|
|
1086
1166
|
registerClaudeCodeHook,
|
|
1167
|
+
resolveHookCommand,
|
|
1087
1168
|
runCli,
|
|
1088
1169
|
runHookCli,
|
|
1089
1170
|
selectProtocol,
|