@sherwoodagent/cli 0.85.0 → 0.86.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.
Files changed (29) hide show
  1. package/dist/{chat-DNWTI4CZ.js → chat-PRYOT3ZV.js} +9 -9
  2. package/dist/chat-PRYOT3ZV.js.map +1 -0
  3. package/dist/{chunk-TWT56FTL.js → chunk-5NFAEOFG.js} +2 -2
  4. package/dist/{chunk-65G5BFYR.js → chunk-HODME7UJ.js} +2 -2
  5. package/dist/{chunk-ILHOW6IA.js → chunk-LRUSZUEU.js} +197 -65
  6. package/dist/chunk-LRUSZUEU.js.map +1 -0
  7. package/dist/{chunk-VR4VHX4D.js → chunk-YMB4RJOR.js} +2 -2
  8. package/dist/{chunk-VR4VHX4D.js.map → chunk-YMB4RJOR.js.map} +1 -1
  9. package/dist/{identity-RMEPBFOL.js → identity-XOAYQFUW.js} +2 -2
  10. package/dist/index.js +148 -123
  11. package/dist/index.js.map +1 -1
  12. package/dist/{ipfs-EJ7IHXCU.js → ipfs-M56BLMCW.js} +2 -2
  13. package/dist/{research-GZNVG3SP.js → research-NKGP3M4J.js} +12 -12
  14. package/dist/research-NKGP3M4J.js.map +1 -0
  15. package/dist/{session-M5QB25PK.js → session-LJT3SAED.js} +3 -3
  16. package/dist/{trade-TCQ5NUNA.js → trade-OTZ7UHDK.js} +5 -5
  17. package/dist/trade-OTZ7UHDK.js.map +1 -0
  18. package/dist/{vault-K2R4VHVI.js → vault-7O4N6WZG.js} +4 -4
  19. package/package.json +2 -2
  20. package/dist/chat-DNWTI4CZ.js.map +0 -1
  21. package/dist/chunk-ILHOW6IA.js.map +0 -1
  22. package/dist/research-GZNVG3SP.js.map +0 -1
  23. package/dist/trade-TCQ5NUNA.js.map +0 -1
  24. /package/dist/{chunk-TWT56FTL.js.map → chunk-5NFAEOFG.js.map} +0 -0
  25. /package/dist/{chunk-65G5BFYR.js.map → chunk-HODME7UJ.js.map} +0 -0
  26. /package/dist/{identity-RMEPBFOL.js.map → identity-XOAYQFUW.js.map} +0 -0
  27. /package/dist/{ipfs-EJ7IHXCU.js.map → ipfs-M56BLMCW.js.map} +0 -0
  28. /package/dist/{session-M5QB25PK.js.map → session-LJT3SAED.js.map} +0 -0
  29. /package/dist/{vault-K2R4VHVI.js.map → vault-7O4N6WZG.js.map} +0 -0
@@ -23,7 +23,7 @@ import "./chunk-F3MDCUGO.js";
23
23
  import {
24
24
  fetchMetadata,
25
25
  uploadMetadata
26
- } from "./chunk-VR4VHX4D.js";
26
+ } from "./chunk-YMB4RJOR.js";
27
27
 
28
28
  // src/commands/chat.ts
29
29
  import chalk from "chalk";
@@ -291,12 +291,12 @@ async function handleRename(name, newName, newDescription) {
291
291
  }
292
292
  }
293
293
  async function handlePublishMetadata(name, groupIdOpt) {
294
- const spinner = ora("Updating fund metadata...").start();
294
+ const spinner = ora("Updating vault metadata...").start();
295
295
  try {
296
296
  const fund = await resolveFund(name);
297
297
  const callerAddress = getAccount().address.toLowerCase();
298
298
  if (fund.creator.toLowerCase() !== callerAddress) {
299
- spinner.fail("Only the fund creator can update metadata");
299
+ spinner.fail("Only the vault creator can update metadata");
300
300
  process.exit(1);
301
301
  }
302
302
  const xmtp = await loadXmtp();
@@ -353,7 +353,7 @@ async function handlePublishEns(name, groupIdOpt) {
353
353
  const fund = await resolveFund(name);
354
354
  const callerAddress = getAccount().address.toLowerCase();
355
355
  if (fund.creator.toLowerCase() !== callerAddress) {
356
- spinner.fail("Only the fund creator can write ENS records");
356
+ spinner.fail("Only the vault creator can write ENS records");
357
357
  process.exit(1);
358
358
  }
359
359
  const xmtp = await loadXmtp();
@@ -410,13 +410,13 @@ async function handleInit(name, force, isPublic) {
410
410
  const fund = await resolveFund(name);
411
411
  const callerAddress = getAccount().address.toLowerCase();
412
412
  if (fund.creator.toLowerCase() !== callerAddress) {
413
- spinner.fail("Only the fund creator can initialize the chat group");
413
+ spinner.fail("Only the vault creator can initialize the chat group");
414
414
  process.exit(1);
415
415
  }
416
416
  if (!force) {
417
417
  const existingId = getCachedGroupId(name) || await getTextRecord(name, "xmtpGroupId");
418
418
  if (existingId) {
419
- spinner.succeed("XMTP group already exists for this fund");
419
+ spinner.succeed("XMTP group already exists for this vault");
420
420
  console.log(chalk.dim(` Group ID: ${existingId}`));
421
421
  return;
422
422
  }
@@ -426,7 +426,7 @@ async function handleInit(name, force, isPublic) {
426
426
  const client = await xmtp.getXmtpClient();
427
427
  const groupId = await xmtp.createFundGroup(client, name, isPublic);
428
428
  cacheGroupId(name, groupId);
429
- spinner.text = "Saving group ID to fund metadata...";
429
+ spinner.text = "Saving group ID to vault metadata...";
430
430
  try {
431
431
  const info = await getFund(fund.id);
432
432
  let metadata;
@@ -476,7 +476,7 @@ async function handleInit(name, force, isPublic) {
476
476
  }
477
477
  }
478
478
  function registerChatCommands(program) {
479
- program.command("chat <name> [action] [actionArgs...]").description("Fund chat \u2014 stream, send, log, members, add, remove, init, public").option("--markdown", "Send as rich markdown (for send)", false).option("--stdin", "Read send message from stdin instead of CLI arg (avoids shell quoting issues with $ chars and quotes)", false).option("--limit <n>", "Number of messages to show (for log)", "20").option("--force", "Recreate group even if one exists (for init)", false).option("--public", "Enable public chat \u2014 adds dashboard spectator (for init)", false).option("--description <text>", "New description (for rename)").option("--group-id <id>", "Explicit XMTP group ID (for publish-ens)").action(async (name, action, actionArgs, opts) => {
479
+ program.command("chat <name> [action] [actionArgs...]").description("Vault chat \u2014 stream, send, log, members, add, remove, init, public").option("--markdown", "Send as rich markdown (for send)", false).option("--stdin", "Read send message from stdin instead of CLI arg (avoids shell quoting issues with $ chars and quotes)", false).option("--limit <n>", "Number of messages to show (for log)", "20").option("--force", "Recreate group even if one exists (for init)", false).option("--public", "Enable public chat \u2014 adds dashboard spectator (for init)", false).option("--description <text>", "New description (for rename)").option("--group-id <id>", "Explicit XMTP group ID (for publish-ens)").action(async (name, action, actionArgs, opts) => {
480
480
  switch (action) {
481
481
  case "send": {
482
482
  let message = actionArgs[0];
@@ -563,4 +563,4 @@ function registerChatCommands(program) {
563
563
  export {
564
564
  registerChatCommands
565
565
  };
566
- //# sourceMappingURL=chat-DNWTI4CZ.js.map
566
+ //# sourceMappingURL=chat-PRYOT3ZV.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/chat.ts"],"sourcesContent":["/**\n * Chat commands — sherwood chat <fund-name> [action] [args...]\n *\n * Uses XMTP for encrypted group messaging tied to funds.\n * Shells out to the @xmtp/cli binary for all XMTP operations.\n *\n * Commander can't dispatch subcommands when the parent has a positional <name> arg\n * (it always runs the parent action). So we use manual dispatch: a single .action()\n * that routes based on the [action] argument.\n *\n * Usage:\n * sherwood chat <name> — stream messages (default)\n * sherwood chat <name> send \"hello\" — send a text message\n * sherwood chat <name> send \"hello\" --markdown — send formatted markdown\n * sherwood chat <name> react <id> <emoji> — react to a message\n * sherwood chat <name> log [--limit 50] — show recent messages\n * sherwood chat <name> members — list group members\n * sherwood chat <name> add <address> — add member (creator only)\n * sherwood chat <name> init [--force] [--public] — create XMTP group + write ENS record\n * sherwood chat <name> public on/off — toggle dashboard spectator access\n * sherwood chat <name> rename <new-name> [--description \"...\"] — update group metadata (admin only)\n * sherwood chat <name> publish-ens [--group-id <id>] — write xmtpGroupId ENS text record (creator only, recovery for failed init)\n * sherwood chat <name> publish-metadata [--group-id <id>] — backfill xmtpGroupId into IPFS metadata (creator only; use when ENS write reverts)\n */\n\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { getAccount, formatContractError } from \"../lib/client.js\";\nimport { resolveFund, setTextRecord, getTextRecord } from \"../lib/ens.js\";\nimport { cacheGroupId, getCachedGroupId } from \"../lib/config.js\";\nimport { fetchMetadata, uploadMetadata } from \"../lib/ipfs.js\";\nimport * as factoryLib from \"../lib/factory.js\";\nimport { ENS } from \"../lib/addresses.js\";\nimport type { ChatEnvelope, MessageType } from \"../lib/types.js\";\nimport type { XmtpMessage } from \"../lib/xmtp.js\";\n\n// Lazy-load XMTP to avoid breaking non-chat commands when @xmtp/cli is missing\nasync function loadXmtp() {\n return import(\"../lib/xmtp.js\");\n}\n\n// ── Formatting ──\n\nfunction formatTimestamp(date: Date): string {\n return `${date.getHours().toString().padStart(2, \"0\")}:${date.getMinutes().toString().padStart(2, \"0\")}`;\n}\n\nfunction truncateAddress(addr: string): string {\n return `${addr.slice(0, 6)}...${addr.slice(-4)}`;\n}\n\nfunction colorByType(type: MessageType): (text: string) => string {\n switch (type) {\n case \"TRADE_EXECUTED\":\n return chalk.green;\n case \"RISK_ALERT\":\n return chalk.red;\n case \"TRADE_SIGNAL\":\n return chalk.yellow;\n case \"POSITION_UPDATE\":\n return chalk.cyan;\n case \"LP_REPORT\":\n return chalk.magenta;\n case \"X402_RESEARCH\":\n return chalk.cyan;\n case \"AGENT_REGISTERED\":\n case \"MEMBER_JOIN\":\n return chalk.blue;\n case \"RAGEQUIT_NOTICE\":\n return chalk.red;\n default:\n return chalk.white;\n }\n}\n\nfunction formatMessage(msg: XmtpMessage): string {\n const time = chalk.dim(`[${formatTimestamp(msg.sentAt)}]`);\n const sender = chalk.dim(truncateAddress(msg.senderInboxId));\n\n const text = msg.content;\n try {\n const envelope: ChatEnvelope = JSON.parse(text);\n const color = colorByType(envelope.type);\n const from = envelope.from ? truncateAddress(envelope.from) : sender;\n\n if (envelope.type === \"REACTION\") {\n const data = envelope.data as { reference?: string; emoji?: string } | undefined;\n return `${time} ${sender} reacted ${data?.emoji || \"?\"} to ${truncateAddress(data?.reference || \"?\")}`;\n }\n\n if (envelope.type === \"MESSAGE\") {\n if ((envelope.data as Record<string, unknown>)?.format === \"markdown\") {\n return `${time} ${chalk.dim(from)}\\n${envelope.text || \"\"}`;\n }\n return `${time} ${chalk.dim(from)}: ${envelope.text || \"\"}`;\n }\n\n if (envelope.type === \"AGENT_REGISTERED\") {\n return `${time} ${color(`[${envelope.type}]`)} Agent ${truncateAddress(envelope.agent?.address || \"?\")} registered`;\n }\n\n if (envelope.type === \"MEMBER_JOIN\") {\n return `${time} ${color(`[${envelope.type}]`)} ${truncateAddress(envelope.from || \"?\")} joined`;\n }\n\n if (envelope.type === \"X402_RESEARCH\") {\n const d = envelope.data as { provider?: string; queryType?: string; costUsdc?: string; attestationUid?: string } | undefined;\n const label = `${d?.provider || \"?\"} ${d?.queryType || \"?\"}`;\n return `${time} ${color(`[RESEARCH]`)} ${chalk.dim(from)}: ${label} ($${d?.costUsdc || \"?\"} USDC)`;\n }\n\n const summary = envelope.text || envelope.type;\n return `${time} ${color(`[${envelope.type}]`)} ${chalk.dim(from)}: ${summary}`;\n } catch {\n return `${time} ${sender}: ${text}`;\n }\n}\n\n// ── Action handlers ──\n\nasync function handleStream(name: string): Promise<void> {\n const spinner = ora(\"Connecting to chat...\").start();\n try {\n await resolveFund(name);\n const xmtp = await loadXmtp();\n const client = await xmtp.getXmtpClient();\n const group = await xmtp.getGroup(client, name);\n spinner.succeed(`Connected to ${name}.sherwoodagent.eth`);\n console.log(chalk.dim(\"Streaming messages... (Ctrl+C to exit)\\n\"));\n\n const cleanup = await xmtp.streamMessages(group, (msg) => {\n console.log(formatMessage(msg));\n });\n\n process.on(\"SIGINT\", async () => {\n console.log(chalk.dim(\"\\nDisconnecting...\"));\n cleanup();\n process.exit(0);\n });\n\n await new Promise(() => {});\n } catch (err) {\n spinner.fail(\"Failed to connect to chat\");\n console.error(chalk.red(formatContractError(err)));\n process.exit(1);\n }\n}\n\n/** Drain stdin into a single string. Used by `chat send --stdin` to bypass\n * shell expansion on dynamic messages (e.g. amounts containing `$`). */\nasync function readStdin(): Promise<string> {\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n }\n return Buffer.concat(chunks).toString('utf-8');\n}\n\nasync function handleSend(name: string, message: string, markdown: boolean): Promise<void> {\n const spinner = ora(\"Sending...\").start();\n try {\n const xmtp = await loadXmtp();\n const group = await xmtp.getGroup(\"\", name);\n\n if (markdown) {\n await xmtp.sendMarkdown(group, message);\n } else {\n const envelope: ChatEnvelope = {\n type: \"MESSAGE\",\n from: getAccount().address,\n text: message,\n timestamp: Math.floor(Date.now() / 1000),\n };\n await xmtp.sendEnvelope(group, envelope);\n }\n\n spinner.succeed(\"Message sent\");\n } catch (err) {\n spinner.fail(\"Failed to send message\");\n console.error(chalk.red(formatContractError(err)));\n process.exit(1);\n }\n}\n\nasync function handleReact(name: string, messageId: string, emoji: string): Promise<void> {\n const spinner = ora(\"Reacting...\").start();\n try {\n const xmtp = await loadXmtp();\n const group = await xmtp.getGroup(\"\", name);\n await xmtp.sendReaction(group, messageId, emoji);\n spinner.succeed(`Reacted ${emoji}`);\n } catch (err) {\n spinner.fail(\"Failed to send reaction\");\n console.error(chalk.red(formatContractError(err)));\n process.exit(1);\n }\n}\n\nasync function handleLog(name: string, limit: number): Promise<void> {\n const spinner = ora(\"Loading messages...\").start();\n try {\n const xmtp = await loadXmtp();\n const group = await xmtp.getGroup(\"\", name);\n const messages = await xmtp.getRecentMessages(group, limit);\n\n spinner.stop();\n console.log();\n console.log(chalk.bold(`Chat log: ${name}.sherwoodagent.eth`));\n console.log(chalk.dim(\"─\".repeat(50)));\n\n if (messages.length === 0) {\n console.log(chalk.dim(\" No messages yet\"));\n } else {\n for (const msg of messages.reverse()) {\n console.log(formatMessage(msg));\n }\n }\n console.log();\n } catch (err) {\n spinner.fail(\"Failed to load messages\");\n console.error(chalk.red(formatContractError(err)));\n process.exit(1);\n }\n}\n\nasync function handleMembers(name: string): Promise<void> {\n const spinner = ora(\"Loading members...\").start();\n try {\n const xmtp = await loadXmtp();\n const group = await xmtp.getGroup(\"\", name);\n const members = await xmtp.getMembers(group);\n\n spinner.stop();\n console.log();\n console.log(chalk.bold(`Members: ${name}.sherwoodagent.eth`));\n console.log(chalk.dim(\"─\".repeat(50)));\n\n for (const member of members) {\n const role = member.permissionLevel === \"super_admin\"\n ? chalk.yellow(\" (super admin)\")\n : member.permissionLevel === \"admin\"\n ? chalk.blue(\" (admin)\")\n : \"\";\n console.log(` ${member.inboxId}${role}`);\n }\n\n console.log(chalk.dim(`\\n Total: ${members.length} members`));\n console.log();\n } catch (err) {\n spinner.fail(\"Failed to load members\");\n console.error(chalk.red(formatContractError(err)));\n process.exit(1);\n }\n}\n\nasync function handleAdd(name: string, address: string): Promise<void> {\n const spinner = ora(\"Adding member...\").start();\n try {\n const xmtp = await loadXmtp();\n const group = await xmtp.getGroup(\"\", name);\n await xmtp.addMember(group, address);\n\n await xmtp.sendEnvelope(group, {\n type: \"MEMBER_JOIN\",\n from: address,\n fund: name,\n timestamp: Math.floor(Date.now() / 1000),\n });\n\n spinner.succeed(`Member added: ${address}`);\n } catch (err) {\n spinner.fail(\"Failed to add member\");\n console.error(chalk.red(formatContractError(err)));\n process.exit(1);\n }\n}\n\nasync function handleRemove(name: string, address: string): Promise<void> {\n const spinner = ora(\"Removing member...\").start();\n try {\n const xmtp = await loadXmtp();\n const group = await xmtp.getGroup(\"\", name);\n await xmtp.removeMember(group, address);\n spinner.succeed(`Member removed: ${address}`);\n } catch (err) {\n spinner.fail(\"Failed to remove member\");\n console.error(chalk.red(formatContractError(err)));\n process.exit(1);\n }\n}\n\n/**\n * Notify the spectator service to sync new groups.\n * Called after adding the spectator wallet to an XMTP group so the service\n * invalidates its cache, calls syncAll(), and discovers the new group.\n */\nasync function notifySpectatorSync(): Promise<void> {\n const spectatorUrl =\n process.env.SPECTATOR_URL || \"https://spectator.sherwood.sh\";\n try {\n const res = await fetch(`${spectatorUrl}/sync`, {\n method: \"POST\",\n signal: AbortSignal.timeout(8_000),\n });\n if (res.ok) {\n const data = (await res.json()) as { groups?: number };\n console.log(\n chalk.dim(\n ` Spectator synced — ${data.groups ?? \"?\"} groups discovered`,\n ),\n );\n }\n } catch {\n // Non-fatal — spectator will self-sync within 60 s via cache TTL\n console.log(\n chalk.dim(\" (Spectator sync skipped — will auto-discover within 60 s)\"),\n );\n }\n}\n\nasync function handleRename(\n name: string,\n newName?: string,\n newDescription?: string,\n): Promise<void> {\n if (newName === undefined && newDescription === undefined) {\n console.error(\n chalk.red(\n \"Usage: sherwood chat <name> rename [new-name] [--description \\\"...\\\"]\",\n ),\n );\n process.exit(1);\n }\n const spinner = ora(\"Updating group metadata...\").start();\n try {\n const xmtp = await loadXmtp();\n const group = await xmtp.getGroup(\"\", name);\n await xmtp.renameGroup(group, newName, newDescription);\n spinner.succeed(\n `Updated ${[\n newName !== undefined ? `name → \"${newName}\"` : null,\n newDescription !== undefined\n ? `description → \"${newDescription}\"`\n : null,\n ]\n .filter(Boolean)\n .join(\", \")}`,\n );\n } catch (err) {\n spinner.fail(\"Failed to update group metadata\");\n console.error(chalk.red(formatContractError(err)));\n process.exit(1);\n }\n}\n\nasync function handlePublishMetadata(\n name: string,\n groupIdOpt?: string,\n): Promise<void> {\n const spinner = ora(\"Updating vault metadata...\").start();\n try {\n const fund = await resolveFund(name);\n const callerAddress = getAccount().address.toLowerCase();\n if (fund.creator.toLowerCase() !== callerAddress) {\n spinner.fail(\"Only the vault creator can update metadata\");\n process.exit(1);\n }\n\n const xmtp = await loadXmtp();\n let groupId = groupIdOpt || getCachedGroupId(name);\n if (!groupId) {\n try {\n groupId = await xmtp.getGroup(\"\", name);\n } catch {\n // ignore\n }\n }\n if (!groupId) {\n spinner.fail(\n \"Could not determine group ID — pass --group-id <id> or run from a machine that has the group cached\",\n );\n process.exit(1);\n }\n\n spinner.text = \"Fetching current metadata...\";\n const info = await factoryLib.getFund(fund.id);\n let metadata;\n try {\n metadata = await fetchMetadata(info.metadataURI);\n } catch {\n metadata = {\n schema: \"sherwood/fund/v1\",\n name,\n description: \"\",\n chain: \"\",\n strategies: [],\n terms: {},\n links: {},\n };\n }\n metadata.xmtpGroupId = groupId;\n\n spinner.text = \"Pinning updated metadata to IPFS...\";\n const newURI = await uploadMetadata(metadata);\n\n spinner.text = \"Calling factory.updateMetadata...\";\n await factoryLib.updateMetadata(fund.id, newURI);\n\n spinner.succeed(`Metadata updated — xmtpGroupId = ${groupId}`);\n console.log(chalk.dim(` New URI: ${newURI}`));\n console.log(\n chalk.dim(\n \" Dashboard will resolve the group via metadata fallback on next page load.\",\n ),\n );\n } catch (err) {\n spinner.fail(\"Failed to update metadata\");\n console.error(chalk.red(formatContractError(err)));\n process.exit(1);\n }\n}\n\nasync function handlePublishEns(name: string, groupIdOpt?: string): Promise<void> {\n const spinner = ora(\"Publishing group ID to ENS...\").start();\n try {\n const fund = await resolveFund(name);\n const callerAddress = getAccount().address.toLowerCase();\n if (fund.creator.toLowerCase() !== callerAddress) {\n spinner.fail(\"Only the vault creator can write ENS records\");\n process.exit(1);\n }\n\n // Resolve group ID: explicit arg → local cache → existing ENS record (no-op)\n const xmtp = await loadXmtp();\n let groupId = groupIdOpt || getCachedGroupId(name);\n if (!groupId) {\n try {\n groupId = await xmtp.getGroup(\"\", name); // syncs DB + name-search fallback\n } catch {\n // ignore\n }\n }\n if (!groupId) {\n spinner.fail(\n \"Could not determine group ID — pass --group-id <id> or run from a machine that has the group cached\",\n );\n process.exit(1);\n }\n\n await setTextRecord(name, \"xmtpGroupId\", groupId, fund.vault);\n spinner.succeed(`Published xmtpGroupId → ${groupId} on ENS`);\n console.log(chalk.dim(\" Dashboard will pick up the group on next page load.\"));\n } catch (err) {\n spinner.fail(\"Failed to publish ENS record\");\n console.error(chalk.red(formatContractError(err)));\n process.exit(1);\n }\n}\n\nasync function handlePublic(name: string, on: boolean): Promise<void> {\n const xmtp = await loadXmtp();\n // Default to the canonical production spectator; `DASHBOARD_SPECTATOR_ADDRESS`\n // is an override hook for testing or future rotation. Earlier versions\n // of this command required the env var with no default — when callers\n // (cron, manual one-liners) set it to the wrong wallet, the agent's\n // own wallet got added \"as the spectator\" and the dashboard stayed\n // OFFLINE because the real spectator service was never in the group.\n // Single source of truth lives in xmtp.ts: resolveSpectatorAddress().\n const spectatorAddress = xmtp.resolveSpectatorAddress();\n const usingDefault =\n spectatorAddress === xmtp.DEFAULT_DASHBOARD_SPECTATOR_ADDRESS;\n\n const spinner = ora(`${on ? \"Enabling\" : \"Disabling\"} public chat...`).start();\n try {\n const group = await xmtp.getGroup(\"\", name);\n\n if (on) {\n await xmtp.addMember(group, spectatorAddress);\n spinner.succeed(\n `Public chat enabled — dashboard spectator added (${spectatorAddress}${usingDefault ? \", canonical\" : \", overridden via env\"})`,\n );\n await notifySpectatorSync();\n } else {\n await xmtp.removeMember(group, spectatorAddress);\n spinner.succeed(\n `Public chat disabled — dashboard spectator removed (${spectatorAddress})`,\n );\n }\n } catch (err) {\n spinner.fail(\"Failed to toggle public chat\");\n console.error(chalk.red(formatContractError(err)));\n process.exit(1);\n }\n}\n\nasync function handleInit(name: string, force: boolean, isPublic: boolean): Promise<void> {\n const spinner = ora(\"Initializing chat group...\").start();\n try {\n const fund = await resolveFund(name);\n const callerAddress = getAccount().address.toLowerCase();\n if (fund.creator.toLowerCase() !== callerAddress) {\n spinner.fail(\"Only the vault creator can initialize the chat group\");\n process.exit(1);\n }\n\n // Idempotency check\n if (!force) {\n const existingId = getCachedGroupId(name) || await getTextRecord(name, \"xmtpGroupId\");\n if (existingId) {\n spinner.succeed(\"XMTP group already exists for this vault\");\n console.log(chalk.dim(` Group ID: ${existingId}`));\n return;\n }\n }\n\n // Create the group\n spinner.text = \"Creating XMTP group...\";\n const xmtp = await loadXmtp();\n const client = await xmtp.getXmtpClient();\n const groupId = await xmtp.createFundGroup(client, name, isPublic);\n\n cacheGroupId(name, groupId);\n\n // Persist group ID. Strategy:\n // 1. ALWAYS write to IPFS metadata — canonical source on every chain.\n // The dashboard's resolver chain is `ENS text → metadata → null`, so\n // metadata being populated guarantees the dashboard works regardless\n // of ENS state. Necessary because the V1.5 vault has no `executeBatch`\n // (V-C3 removal), so the ENS `setText` call below currently reverts on\n // Base mainnet — without metadata, the dashboard would show OFFLINE.\n // 2. ADDITIONALLY try the ENS text record (best-effort). Fast resolution\n // path for chains where the vault has a writable executeBatch path\n // (HyperEVM today, or a future vault setEnsText helper). On failure,\n // we log a debug line and keep going — metadata fallback covers it.\n spinner.text = \"Saving group ID to vault metadata...\";\n try {\n const info = await factoryLib.getFund(fund.id);\n let metadata;\n try {\n metadata = await fetchMetadata(info.metadataURI);\n } catch {\n metadata = {\n schema: \"sherwood/fund/v1\",\n name,\n description: \"\",\n chain: \"\",\n strategies: [],\n terms: {},\n links: {},\n };\n }\n metadata.xmtpGroupId = groupId;\n const newURI = await uploadMetadata(metadata);\n await factoryLib.updateMetadata(fund.id, newURI);\n console.log(chalk.dim(`\\n Group ID saved to metadata: ${newURI}`));\n } catch (metaErr) {\n console.warn(chalk.yellow(\"\\n ⚠ Could not persist group ID to IPFS metadata\"));\n console.warn(chalk.dim(` ${metaErr instanceof Error ? metaErr.message : String(metaErr)}`));\n console.warn(chalk.dim(\" Dashboard may show OFFLINE until backfilled with `chat <name> publish-metadata`.\"));\n }\n\n // Best-effort ENS text record write. Currently reverts on Base mainnet\n // because the V1.5 vault has no owner-direct executeBatch path; metadata\n // above is the operative resolution source. Will succeed once a vault\n // setEnsText helper lands or on chains where the existing path works.\n const hasENS = ENS().L2_REGISTRY !== \"0x0000000000000000000000000000000000000000\";\n if (hasENS) {\n try {\n spinner.text = \"Writing group ID to ENS...\";\n await setTextRecord(name, \"xmtpGroupId\", groupId, fund.vault);\n console.log(chalk.dim(\" ENS text record written: xmtpGroupId\"));\n } catch {\n console.log(chalk.dim(\" ENS text record skipped (metadata fallback active)\"));\n }\n }\n\n spinner.succeed(`Chat group created for ${name}.sherwoodagent.eth`);\n console.log(chalk.dim(` Group ID: ${groupId}`));\n console.log(chalk.dim(` Stream: sherwood chat ${name}`));\n\n // Notify spectator to sync and discover the new public group\n if (isPublic) {\n await notifySpectatorSync();\n }\n } catch (err) {\n spinner.fail(\"Failed to initialize chat group\");\n console.error(chalk.red(formatContractError(err)));\n process.exit(1);\n }\n}\n\n// ── Command Registration ──\n\nexport function registerChatCommands(program: Command): void {\n program\n .command(\"chat <name> [action] [actionArgs...]\")\n .description(\"Vault chat — stream, send, log, members, add, remove, init, public\")\n .option(\"--markdown\", \"Send as rich markdown (for send)\", false)\n .option(\"--stdin\", \"Read send message from stdin instead of CLI arg (avoids shell quoting issues with $ chars and quotes)\", false)\n .option(\"--limit <n>\", \"Number of messages to show (for log)\", \"20\")\n .option(\"--force\", \"Recreate group even if one exists (for init)\", false)\n .option(\"--public\", \"Enable public chat — adds dashboard spectator (for init)\", false)\n .option(\"--description <text>\", \"New description (for rename)\")\n .option(\"--group-id <id>\", \"Explicit XMTP group ID (for publish-ens)\")\n .action(async (name: string, action: string | undefined, actionArgs: string[], opts: { markdown: boolean; stdin: boolean; limit: string; force: boolean; public: boolean; description?: string; groupId?: string }) => {\n switch (action) {\n case \"send\": {\n let message = actionArgs[0];\n if (opts.stdin) {\n // If stdin is a terminal, the user forgot to pipe — readStdin\n // would block forever waiting for EOF (Ctrl+D). Warn explicitly.\n if (process.stdin.isTTY) {\n console.error(chalk.yellow(\"--stdin specified but stdin is a terminal. Either pipe the message in or omit --stdin and pass it as an argument. Press Ctrl+D to send what you've typed, Ctrl+C to abort.\"));\n }\n // Read entire stdin into the message — sidesteps bash $-expansion\n // when callers (cron jobs, scripts) construct dynamic message text.\n message = await readStdin();\n if (!message.trim()) {\n console.error(chalk.red(\"--stdin given but stdin was empty\"));\n process.exit(1);\n }\n }\n if (!message) {\n console.error(chalk.red(\"Usage: sherwood chat <name> send <message> [--markdown]\\n echo \\\"$msg\\\" | sherwood chat <name> send --stdin\"));\n process.exit(1);\n }\n await handleSend(name, message, opts.markdown);\n break;\n }\n\n case \"react\": {\n const [messageId, emoji] = actionArgs;\n if (!messageId || !emoji) {\n console.error(chalk.red(\"Usage: sherwood chat <name> react <messageId> <emoji>\"));\n process.exit(1);\n }\n await handleReact(name, messageId, emoji);\n break;\n }\n\n case \"log\":\n await handleLog(name, parseInt(opts.limit, 10));\n break;\n\n case \"members\":\n await handleMembers(name);\n break;\n\n case \"add\": {\n const address = actionArgs[0];\n if (!address) {\n console.error(chalk.red(\"Usage: sherwood chat <name> add <address>\"));\n process.exit(1);\n }\n await handleAdd(name, address);\n break;\n }\n\n case \"remove\": {\n const removeAddr = actionArgs[0];\n if (!removeAddr) {\n console.error(chalk.red(\"Usage: sherwood chat <name> remove <address>\"));\n process.exit(1);\n }\n await handleRemove(name, removeAddr);\n break;\n }\n\n case \"init\":\n await handleInit(name, opts.force, opts.public);\n break;\n\n case \"rename\": {\n const newName = actionArgs[0]; // optional positional\n await handleRename(name, newName, opts.description);\n break;\n }\n\n case \"publish-ens\":\n await handlePublishEns(name, opts.groupId);\n break;\n\n case \"publish-metadata\":\n await handlePublishMetadata(name, opts.groupId);\n break;\n\n case \"public\": {\n const flag = actionArgs[0];\n if (flag !== \"on\" && flag !== \"off\") {\n console.error(chalk.red(\"Usage: sherwood chat <name> public on/off\"));\n process.exit(1);\n }\n await handlePublic(name, flag === \"on\");\n break;\n }\n\n case undefined:\n default:\n await handleStream(name);\n break;\n }\n });\n}\n"],"mappings":"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","names":[]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getLogsChunked
3
- } from "./chunk-65G5BFYR.js";
3
+ } from "./chunk-HODME7UJ.js";
4
4
  import {
5
5
  TOKENS
6
6
  } from "./chunk-AM6MI2JF.js";
@@ -557,4 +557,4 @@ export {
557
557
  registerAgent,
558
558
  getVaultInfo
559
559
  };
560
- //# sourceMappingURL=chunk-TWT56FTL.js.map
560
+ //# sourceMappingURL=chunk-5NFAEOFG.js.map
@@ -7,7 +7,7 @@ import {
7
7
  } from "./chunk-QRMZRAMG.js";
8
8
  import {
9
9
  resolveMetadataSummary
10
- } from "./chunk-VR4VHX4D.js";
10
+ } from "./chunk-YMB4RJOR.js";
11
11
 
12
12
  // src/lib/events.ts
13
13
  import { parseAbiItem } from "viem";
@@ -221,4 +221,4 @@ export {
221
221
  getCurrentBlock,
222
222
  enrichProposalEvents
223
223
  };
224
- //# sourceMappingURL=chunk-65G5BFYR.js.map
224
+ //# sourceMappingURL=chunk-HODME7UJ.js.map
@@ -321,6 +321,25 @@ var SYNDICATE_VAULT_ABI = [
321
321
  ],
322
322
  outputs: [{ name: "requestId", type: "uint256" }]
323
323
  },
324
+ // Lane B deposit escrow. Assets are held OFF-vault by the queue so they
325
+ // neither inflate totalAssets nor get swept into the strategy.
326
+ {
327
+ name: "requestDeposit",
328
+ type: "function",
329
+ stateMutability: "nonpayable",
330
+ inputs: [
331
+ { name: "assets", type: "uint256" },
332
+ { name: "receiver", type: "address" }
333
+ ],
334
+ outputs: [{ name: "requestId", type: "uint256" }]
335
+ },
336
+ {
337
+ name: "withdrawalQueue",
338
+ type: "function",
339
+ stateMutability: "view",
340
+ inputs: [],
341
+ outputs: [{ name: "", type: "address" }]
342
+ },
324
343
  // Reads
325
344
  {
326
345
  name: "asset",
@@ -441,12 +460,15 @@ var SYNDICATE_VAULT_ABI = [
441
460
  outputs: []
442
461
  },
443
462
  {
463
+ // ARGUMENT ORDER IS (agentId, agentAddress), NOT the reverse. The flipped
464
+ // tuple is a DIFFERENT function (0x3543ad58) that no deployed vault has —
465
+ // it reverts with empty returndata, giving the caller no signal (SHE-185).
444
466
  name: "registerAgent",
445
467
  type: "function",
446
468
  stateMutability: "nonpayable",
447
469
  inputs: [
448
- { name: "agentAddress", type: "address" },
449
- { name: "agentId", type: "uint256" }
470
+ { name: "agentId", type: "uint256" },
471
+ { name: "agentAddress", type: "address" }
450
472
  ],
451
473
  outputs: []
452
474
  },
@@ -812,13 +834,8 @@ var SYNDICATE_GOVERNOR_ABI = [
812
834
  }
813
835
  ]
814
836
  },
815
- {
816
- name: "protocolFeeRecipient",
817
- type: "function",
818
- stateMutability: "view",
819
- inputs: [],
820
- outputs: [{ name: "", type: "address" }]
821
- },
837
+ // protocolFeeRecipient() is NOT on the governor — fees moved to
838
+ // ProtocolConfig (#421). Read it off PROTOCOL_CONFIG_ABI instead (SHE-185).
822
839
  {
823
840
  name: "FeeClamped",
824
841
  type: "event",
@@ -958,7 +975,43 @@ var PROTOCOL_CONFIG_ABI = [
958
975
  }
959
976
  ];
960
977
  var GUARDIAN_REGISTRY_ABI = [
961
- // Guardian stake
978
+ // Guardian staking, unstaking and stake reads are NOT on this contract —
979
+ // the sWOOD split moved them to StakedWood, which is the sole WOOD
980
+ // custodian. They lived here until SHE-185; sending stakeAsGuardian /
981
+ // requestUnstakeGuardian / cancelUnstakeGuardian / claimUnstakeGuardian /
982
+ // guardianStake / isActiveGuardian to the registry reverts with empty
983
+ // returndata. Use STAKED_WOOD_ABI against `sherwood.stakedWood`.
984
+ // Guardian review vote — 3 args, no slashBps. Selector 0x3ad95b6d.
985
+ // GuardianVoteType: None=0, Approve=1, Block=2 (uint8).
986
+ {
987
+ name: "voteOnProposal",
988
+ type: "function",
989
+ stateMutability: "nonpayable",
990
+ inputs: [
991
+ { name: "governor", type: "address" },
992
+ { name: "proposalId", type: "uint256" },
993
+ { name: "support", type: "uint8" }
994
+ ],
995
+ outputs: []
996
+ },
997
+ // Cached review flags. Returns THREE bools (opened, resolved, blocked).
998
+ // A fourth output is the SHE-88 arity break: viem refuses the 96-byte returndata.
999
+ {
1000
+ name: "getReviewState",
1001
+ type: "function",
1002
+ stateMutability: "view",
1003
+ inputs: [
1004
+ { name: "governor", type: "address" },
1005
+ { name: "proposalId", type: "uint256" }
1006
+ ],
1007
+ outputs: [
1008
+ { name: "opened", type: "bool" },
1009
+ { name: "resolved", type: "bool" },
1010
+ { name: "blocked", type: "bool" }
1011
+ ]
1012
+ }
1013
+ ];
1014
+ var STAKED_WOOD_ABI = [
962
1015
  {
963
1016
  name: "stakeAsGuardian",
964
1017
  type: "function",
@@ -969,6 +1022,8 @@ var GUARDIAN_REGISTRY_ABI = [
969
1022
  ],
970
1023
  outputs: []
971
1024
  },
1025
+ // Self-stake unstake flow. Moved off GUARDIAN_REGISTRY_ABI in SHE-185 —
1026
+ // the registry holds zero WOOD and implements none of these.
972
1027
  {
973
1028
  name: "requestUnstakeGuardian",
974
1029
  type: "function",
@@ -990,9 +1045,6 @@ var GUARDIAN_REGISTRY_ABI = [
990
1045
  inputs: [],
991
1046
  outputs: []
992
1047
  },
993
- // Delegation and commission fragments removed (SHE-86): delegateStake,
994
- // requestUnstakeDelegation, cancelUnstakeDelegation, claimUnstakeDelegation
995
- // and setCommission do not exist on the post-audit contracts.
996
1048
  // Reads
997
1049
  {
998
1050
  name: "guardianStake",
@@ -1007,47 +1059,6 @@ var GUARDIAN_REGISTRY_ABI = [
1007
1059
  stateMutability: "view",
1008
1060
  inputs: [{ name: "guardian", type: "address" }],
1009
1061
  outputs: [{ name: "", type: "bool" }]
1010
- },
1011
- // Guardian review vote — 3 args, no slashBps. Selector 0x3ad95b6d.
1012
- // GuardianVoteType: None=0, Approve=1, Block=2 (uint8).
1013
- {
1014
- name: "voteOnProposal",
1015
- type: "function",
1016
- stateMutability: "nonpayable",
1017
- inputs: [
1018
- { name: "governor", type: "address" },
1019
- { name: "proposalId", type: "uint256" },
1020
- { name: "support", type: "uint8" }
1021
- ],
1022
- outputs: []
1023
- },
1024
- // Cached review flags. Returns THREE bools (opened, resolved, blocked).
1025
- // A fourth output is the SHE-88 arity break: viem refuses the 96-byte returndata.
1026
- {
1027
- name: "getReviewState",
1028
- type: "function",
1029
- stateMutability: "view",
1030
- inputs: [
1031
- { name: "governor", type: "address" },
1032
- { name: "proposalId", type: "uint256" }
1033
- ],
1034
- outputs: [
1035
- { name: "opened", type: "bool" },
1036
- { name: "resolved", type: "bool" },
1037
- { name: "blocked", type: "bool" }
1038
- ]
1039
- }
1040
- ];
1041
- var STAKED_WOOD_ABI = [
1042
- {
1043
- name: "stakeAsGuardian",
1044
- type: "function",
1045
- stateMutability: "nonpayable",
1046
- inputs: [
1047
- { name: "amount", type: "uint256" },
1048
- { name: "agentId", type: "uint256" }
1049
- ],
1050
- outputs: []
1051
1062
  }
1052
1063
  ];
1053
1064
  var ERC20_ABI = [
@@ -1176,6 +1187,126 @@ var STRATEGY_FACTORY_ABI = [
1176
1187
  }
1177
1188
  ];
1178
1189
 
1190
+ // ../sdk/dist/protocol-selectors.js
1191
+ var PROTOCOL_SELECTORS = {
1192
+ propose: {
1193
+ iface: "ISyndicateGovernor",
1194
+ signature: "propose(address,address,string,uint256,(uint256,uint16),(address,bytes,uint256)[],uint256[],(address,bytes,uint256)[],uint256[],(address,uint256)[])",
1195
+ selector: "0x784ea274"
1196
+ },
1197
+ proposeWithSandbox: {
1198
+ iface: "ISyndicateGovernor",
1199
+ signature: "proposeWithSandbox((uint256,(address,bytes)[],address[]),address,address,string,uint256,(uint256,uint16),(address,bytes,uint256)[],uint256[],(address,bytes,uint256)[],uint256[],(address,uint256)[])",
1200
+ selector: "0x16c0fa9c"
1201
+ },
1202
+ voteOnProposal: {
1203
+ iface: "IGuardianRegistry",
1204
+ signature: "voteOnProposal(address,uint256,uint8)",
1205
+ selector: "0x3ad95b6d"
1206
+ },
1207
+ getReviewState: {
1208
+ iface: "IGuardianRegistry",
1209
+ signature: "getReviewState(address,uint256)",
1210
+ selector: "0x043bd8b9"
1211
+ },
1212
+ runSandbox: {
1213
+ iface: "ISyndicateVault",
1214
+ signature: "runSandbox(uint256,(address,bytes)[],address[],uint256)",
1215
+ selector: "0xb0f4c59d"
1216
+ },
1217
+ sweep: {
1218
+ iface: "ICallSandbox",
1219
+ signature: "sweep()",
1220
+ selector: "0x35faa416"
1221
+ }
1222
+ };
1223
+ var API_CALLDATA_SELECTORS = {
1224
+ deposit: [
1225
+ { target: "erc20", selector: "0x095ea7b3", signature: "approve(address,uint256)", external: true },
1226
+ { target: "vault", selector: "0x6e553f65", signature: "deposit(uint256,address)" }
1227
+ ],
1228
+ redeem: [
1229
+ { target: "vault", selector: "0xba087652", signature: "redeem(uint256,address,address)" }
1230
+ ],
1231
+ "request-redeem": [
1232
+ { target: "vault", selector: "0x107703ab", signature: "requestRedeem(uint256,address)" }
1233
+ ],
1234
+ "request-deposit": [
1235
+ { target: "erc20", selector: "0x095ea7b3", signature: "approve(address,uint256)", external: true },
1236
+ { target: "vault", selector: "0x29344f08", signature: "requestDeposit(uint256,address)" }
1237
+ ],
1238
+ "queue-claim": [
1239
+ { target: "queue", selector: "0x379607f5", signature: "claim(uint256)" }
1240
+ ],
1241
+ "queue-cancel": [
1242
+ { target: "queue", selector: "0x40e58ee5", signature: "cancel(uint256)" }
1243
+ ],
1244
+ "strategy-deploy": [
1245
+ { target: "strategyFactory", selector: "0x26ab0cd4", signature: "cloneAndInitDeterministic(address,address,address,bytes,bytes32)" }
1246
+ ],
1247
+ propose: [
1248
+ { target: "governor", selector: "0x784ea274", signature: PROTOCOL_SELECTORS.propose.signature }
1249
+ ],
1250
+ "propose-with-sandbox": [
1251
+ { target: "governor", selector: "0x16c0fa9c", signature: PROTOCOL_SELECTORS.proposeWithSandbox.signature }
1252
+ ],
1253
+ vote: [
1254
+ { target: "governor", selector: "0x943e8216", signature: "vote(uint256,uint8)" }
1255
+ ],
1256
+ "vote-on-proposal": [
1257
+ { target: "guardianRegistry", selector: "0x3ad95b6d", signature: PROTOCOL_SELECTORS.voteOnProposal.signature }
1258
+ ],
1259
+ execute: [
1260
+ { target: "governor", selector: "0x0d61b519", signature: "executeProposal(uint256)" }
1261
+ ],
1262
+ settle: [
1263
+ { target: "governor", selector: "0x2473ad34", signature: "settleProposal(uint256)" }
1264
+ ],
1265
+ cancel: [
1266
+ { target: "governor", selector: "0xe0a8f6f5", signature: "cancelProposal(uint256)" }
1267
+ ],
1268
+ veto: [
1269
+ { target: "governor", selector: "0x6f65108c", signature: "vetoProposal(uint256)" }
1270
+ ],
1271
+ unstick: [
1272
+ { target: "governor", selector: "0x83170f05", signature: "unstick(uint256)" }
1273
+ ],
1274
+ "emergency-settle": [
1275
+ { target: "governor", selector: "0xf1f21adc", signature: "emergencySettleWithCalls(uint256,(address,bytes,uint256)[])" }
1276
+ ],
1277
+ "governor-set": [
1278
+ { target: "governor", selector: "0xea0217cf", signature: "setVotingPeriod(uint256)" }
1279
+ ],
1280
+ "create-fund": [
1281
+ { target: "factory", selector: "0xd902f450", signature: "createSyndicate(uint256,(string,address,string,string,bool,string))" }
1282
+ ],
1283
+ "approve-depositor": [
1284
+ { target: "vault", selector: "0x8e6a1bb3", signature: "approveDepositor(address)" }
1285
+ ],
1286
+ // (agentId, agentAddress). The flipped tuple is
1287
+ // KNOWN_BREAKAGE_SELECTORS.registerAgentFlipped and exists on no deployed vault.
1288
+ "register-agent": [
1289
+ { target: "vault", selector: "0x047d4c27", signature: "registerAgent(uint256,address)" }
1290
+ ],
1291
+ "approve-agent": [
1292
+ { target: "vault", selector: "0x047d4c27", signature: "registerAgent(uint256,address)" },
1293
+ { target: "eas", selector: "0xf17325e7", signature: "attest((bytes32,(address,uint64,bool,bytes32,bytes,uint256)))", external: true }
1294
+ ],
1295
+ join: [
1296
+ { target: "eas", selector: "0xf17325e7", signature: "attest((bytes32,(address,uint64,bool,bytes32,bytes,uint256)))", external: true }
1297
+ ],
1298
+ "identity-mint": [
1299
+ { target: "identityRegistry", selector: "0x8ea42286", signature: "register(string,(string,bytes)[])", external: true }
1300
+ ],
1301
+ // sWOOD, not the registry — see the note above.
1302
+ "guardian-stake": [
1303
+ { target: "stakedWood", selector: "0xfc1d6c63", signature: "stakeAsGuardian(uint256,uint256)" }
1304
+ ],
1305
+ "guardian-unstake": [
1306
+ { target: "stakedWood", selector: "0xf4714817", signature: "requestUnstakeGuardian()" }
1307
+ ]
1308
+ };
1309
+
1179
1310
  // ../sdk/dist/addresses.js
1180
1311
  var ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
1181
1312
  var ZERO_BYTES32 = "0x0000000000000000000000000000000000000000000000000000000000000000";
@@ -1584,7 +1715,8 @@ function encodeRegisterAgent(args, chainId) {
1584
1715
  data: encodeFunctionData({
1585
1716
  abi: SYNDICATE_VAULT_ABI,
1586
1717
  functionName: "registerAgent",
1587
- args: [agentAddress, id]
1718
+ // (agentId, agentAddress) — the protocol's order. See abis.ts.
1719
+ args: [id, agentAddress]
1588
1720
  }),
1589
1721
  value: ZERO_VALUE,
1590
1722
  chainId
@@ -2404,15 +2536,15 @@ function encodeGuardianUnstake(args, chainId) {
2404
2536
  throw usage(`\`action\` must be one of: ${Object.keys(GUARDIAN_UNSTAKE_FN).join(", ")}`);
2405
2537
  }
2406
2538
  const data = encodeFunctionData7({
2407
- abi: GUARDIAN_REGISTRY_ABI,
2539
+ abi: STAKED_WOOD_ABI,
2408
2540
  functionName: fn,
2409
2541
  args: []
2410
2542
  });
2411
2543
  return {
2412
- txs: [registryTx(chainId, data)],
2544
+ txs: [swoodTx(chainId, data)],
2413
2545
  preconditions: [],
2414
2546
  description: `Guardian unstake ${args.action}.`,
2415
- note: args.action === "request" ? "Starts a 7-day cooldown. After it elapses, call again with action=claim to withdraw." : args.action === "claim" ? "Withdraws the unstake amount once the 7-day cooldown has elapsed." : "Cancels a pending unstake request and re-activates the guardian."
2547
+ note: args.action === "request" ? "Targets sWOOD (StakedWood), not the guardian registry. Starts a 7-day cooldown. After it elapses, call again with action=claim to withdraw." : args.action === "claim" ? "Withdraws the unstake amount once the 7-day cooldown has elapsed." : "Cancels a pending unstake request and re-activates the guardian."
2416
2548
  };
2417
2549
  }
2418
2550
  function encodeVoteOnProposal(args, chainId) {
@@ -2516,7 +2648,7 @@ async function lookupAgentIdByWallet(wallet) {
2516
2648
  }
2517
2649
  function registerIdentityCommands(program) {
2518
2650
  const identity = program.command("identity").description("Manage ERC-8004 agent identity (via Agent0 SDK)");
2519
- identity.command("mint").description("Register a new ERC-8004 agent identity (required before creating/joining funds)").requiredOption("--name <name>", "Agent name (e.g. 'Alpha Seeker Agent')").option("--description <desc>", "Agent description", "Sherwood fund agent").option("--image <uri>", "Agent image URI (IPFS recommended)").action(async (opts) => {
2651
+ identity.command("mint").description("Register a new ERC-8004 agent identity (required before creating/joining vaults)").requiredOption("--name <name>", "Agent name (e.g. 'Alpha Seeker Agent')").option("--description <desc>", "Agent description", "Sherwood vault agent").option("--image <uri>", "Agent image URI (IPFS recommended)").action(async (opts) => {
2520
2652
  if (isCalldataOnly()) {
2521
2653
  emitCalldata(
2522
2654
  encodeIdentityMint(
@@ -2544,7 +2676,7 @@ function registerIdentityCommands(program) {
2544
2676
  const balance = await client.getBalance({ address: account.address });
2545
2677
  if (balance === 0n) {
2546
2678
  throw new Error(
2547
- `No ETH on Robinhood mainnet (chain 4663) for ${account.address}. Identity is minted on the coordination chain regardless of your fund's chain; a mint costs well under 0.0001 ETH.`
2679
+ `No ETH on Robinhood mainnet (chain 4663) for ${account.address}. Identity is minted on the coordination chain regardless of your vault's chain; a mint costs well under 0.0001 ETH.`
2548
2680
  );
2549
2681
  }
2550
2682
  const action = encodeIdentityMint(
@@ -2574,8 +2706,8 @@ function registerIdentityCommands(program) {
2574
2706
  console.log(chalk.dim(` Owner: ${account.address}`));
2575
2707
  console.log(chalk.dim(` Saved to ~/.sherwood/config.json`));
2576
2708
  console.log();
2577
- console.log(chalk.green("You can now create funds:"));
2578
- console.log(chalk.dim(` sherwood fund create --agent-id ${tokenId} --subdomain <name> --name <name>`));
2709
+ console.log(chalk.green("You can now create vaults:"));
2710
+ console.log(chalk.dim(` sherwood vault create --agent-id ${tokenId} --subdomain <name> --name <name>`));
2579
2711
  } catch (err) {
2580
2712
  spinner.fail("Failed to register identity");
2581
2713
  console.error(chalk.red(formatContractError(err)));
@@ -2734,8 +2866,8 @@ function registerIdentityCommands(program) {
2734
2866
  console.log(chalk.dim(` Sherwood wallet: ${account.address}${self ? " (same as economyOS wallet \u2014 no binding needed)" : " (bound via signature)"}`));
2735
2867
  console.log(chalk.dim(` Saved to ~/.sherwood/config.json`));
2736
2868
  console.log();
2737
- console.log(chalk.green("You can now create or join funds with this identity:"));
2738
- console.log(chalk.dim(` sherwood fund create --agent-id ${tokenId} --subdomain <name> --name <name>`));
2869
+ console.log(chalk.green("You can now create or join vaults with this identity:"));
2870
+ console.log(chalk.dim(` sherwood vault create --agent-id ${tokenId} --subdomain <name> --name <name>`));
2739
2871
  } catch (err) {
2740
2872
  spinner.fail("Failed to link Virtuals identity");
2741
2873
  console.error(chalk.red(formatContractError(err)));
@@ -2968,4 +3100,4 @@ export {
2968
3100
  lookupAgentIdByWallet,
2969
3101
  registerIdentityCommands
2970
3102
  };
2971
- //# sourceMappingURL=chunk-ILHOW6IA.js.map
3103
+ //# sourceMappingURL=chunk-LRUSZUEU.js.map