@sherwoodagent/cli 0.85.1 → 0.86.1
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/dist/{chat-DNWTI4CZ.js → chat-ETZSKQDI.js} +13 -13
- package/dist/chat-ETZSKQDI.js.map +1 -0
- package/dist/{chunk-ARSQ5UQA.js → chunk-3IAZQMAW.js} +2 -2
- package/dist/{chunk-FPB23SDH.js → chunk-6QBGTX2Q.js} +93 -19
- package/dist/chunk-6QBGTX2Q.js.map +1 -0
- package/dist/{chunk-65G5BFYR.js → chunk-EA65CDQH.js} +3 -3
- package/dist/{chunk-53W6CYYV.js → chunk-EVUKJ7CJ.js} +2 -2
- package/dist/{chunk-AM6MI2JF.js → chunk-IAM4VIU2.js} +146 -23
- package/dist/chunk-IAM4VIU2.js.map +1 -0
- package/dist/{chunk-M4GX5PL2.js → chunk-OUYMZ5ZC.js} +2 -2
- package/dist/{chunk-TWT56FTL.js → chunk-XPVXNG2K.js} +3 -3
- package/dist/{chunk-6N7EVSAZ.js → chunk-YAS52NEF.js} +19 -6
- package/dist/{chunk-6N7EVSAZ.js.map → chunk-YAS52NEF.js.map} +1 -1
- package/dist/{chunk-VR4VHX4D.js → chunk-YMB4RJOR.js} +2 -2
- package/dist/{chunk-VR4VHX4D.js.map → chunk-YMB4RJOR.js.map} +1 -1
- package/dist/{chunk-I2BBOJNC.js → chunk-ZN2MHIB7.js} +2 -2
- package/dist/{eas-D3BVHBJH.js → eas-KMDAMLXW.js} +3 -3
- package/dist/{governor-35IXAEDJ.js → governor-JNSWPJVQ.js} +7 -5
- package/dist/{identity-3A2D7DGS.js → identity-ATWV2O7Y.js} +4 -4
- package/dist/index.js +239 -148
- package/dist/index.js.map +1 -1
- package/dist/{ipfs-EJ7IHXCU.js → ipfs-M56BLMCW.js} +2 -2
- package/dist/{price-I5T77X7Y.js → price-YNPYE2EO.js} +3 -3
- package/dist/{research-GZNVG3SP.js → research-W74PNYPO.js} +14 -14
- package/dist/research-W74PNYPO.js.map +1 -0
- package/dist/{session-M5QB25PK.js → session-HVRZ6AJM.js} +7 -7
- package/dist/{trade-TCQ5NUNA.js → trade-EOQY72L7.js} +10 -10
- package/dist/trade-EOQY72L7.js.map +1 -0
- package/dist/{vault-K2R4VHVI.js → vault-HWJQJW5U.js} +6 -6
- package/dist/{xmtp-R25Q5GWY.js → xmtp-KW73BGVO.js} +3 -3
- package/package.json +2 -2
- package/dist/chat-DNWTI4CZ.js.map +0 -1
- package/dist/chunk-AM6MI2JF.js.map +0 -1
- package/dist/chunk-FPB23SDH.js.map +0 -1
- package/dist/research-GZNVG3SP.js.map +0 -1
- package/dist/trade-TCQ5NUNA.js.map +0 -1
- /package/dist/{chunk-ARSQ5UQA.js.map → chunk-3IAZQMAW.js.map} +0 -0
- /package/dist/{chunk-65G5BFYR.js.map → chunk-EA65CDQH.js.map} +0 -0
- /package/dist/{chunk-53W6CYYV.js.map → chunk-EVUKJ7CJ.js.map} +0 -0
- /package/dist/{chunk-M4GX5PL2.js.map → chunk-OUYMZ5ZC.js.map} +0 -0
- /package/dist/{chunk-TWT56FTL.js.map → chunk-XPVXNG2K.js.map} +0 -0
- /package/dist/{chunk-I2BBOJNC.js.map → chunk-ZN2MHIB7.js.map} +0 -0
- /package/dist/{eas-D3BVHBJH.js.map → eas-KMDAMLXW.js.map} +0 -0
- /package/dist/{governor-35IXAEDJ.js.map → governor-JNSWPJVQ.js.map} +0 -0
- /package/dist/{identity-3A2D7DGS.js.map → identity-ATWV2O7Y.js.map} +0 -0
- /package/dist/{ipfs-EJ7IHXCU.js.map → ipfs-M56BLMCW.js.map} +0 -0
- /package/dist/{price-I5T77X7Y.js.map → price-YNPYE2EO.js.map} +0 -0
- /package/dist/{session-M5QB25PK.js.map → session-HVRZ6AJM.js.map} +0 -0
- /package/dist/{vault-K2R4VHVI.js.map → vault-HWJQJW5U.js.map} +0 -0
- /package/dist/{xmtp-R25Q5GWY.js.map → xmtp-KW73BGVO.js.map} +0 -0
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getFund,
|
|
3
3
|
updateMetadata
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-EVUKJ7CJ.js";
|
|
5
5
|
import {
|
|
6
6
|
getTextRecord,
|
|
7
7
|
resolveFund,
|
|
8
8
|
setTextRecord
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-ZN2MHIB7.js";
|
|
10
10
|
import {
|
|
11
11
|
ENS
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-IAM4VIU2.js";
|
|
13
13
|
import {
|
|
14
14
|
formatContractError,
|
|
15
15
|
getAccount
|
|
@@ -23,13 +23,13 @@ import "./chunk-F3MDCUGO.js";
|
|
|
23
23
|
import {
|
|
24
24
|
fetchMetadata,
|
|
25
25
|
uploadMetadata
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-YMB4RJOR.js";
|
|
27
27
|
|
|
28
28
|
// src/commands/chat.ts
|
|
29
29
|
import chalk from "chalk";
|
|
30
30
|
import ora from "ora";
|
|
31
31
|
async function loadXmtp() {
|
|
32
|
-
return import("./xmtp-
|
|
32
|
+
return import("./xmtp-KW73BGVO.js");
|
|
33
33
|
}
|
|
34
34
|
function formatTimestamp(date) {
|
|
35
35
|
return `${date.getHours().toString().padStart(2, "0")}:${date.getMinutes().toString().padStart(2, "0")}`;
|
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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("
|
|
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-
|
|
566
|
+
//# sourceMappingURL=chat-ETZSKQDI.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":[]}
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
UNISWAP,
|
|
9
9
|
VENICE,
|
|
10
10
|
robinhoodEquityMaxAge
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-IAM4VIU2.js";
|
|
12
12
|
import {
|
|
13
13
|
getPublicClient
|
|
14
14
|
} from "./chunk-QRMZRAMG.js";
|
|
@@ -1667,4 +1667,4 @@ export {
|
|
|
1667
1667
|
applySlippage,
|
|
1668
1668
|
encodeSwapPath
|
|
1669
1669
|
};
|
|
1670
|
-
//# sourceMappingURL=chunk-
|
|
1670
|
+
//# sourceMappingURL=chunk-3IAZQMAW.js.map
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
COORDINATION_NETWORK
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-OUYMZ5ZC.js";
|
|
4
4
|
import {
|
|
5
5
|
AGENT_REGISTRY
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-IAM4VIU2.js";
|
|
7
7
|
import {
|
|
8
8
|
formatContractError,
|
|
9
9
|
getAccount,
|
|
@@ -965,12 +965,43 @@ var PROTOCOL_CONFIG_ABI = [
|
|
|
965
965
|
inputs: [],
|
|
966
966
|
outputs: [{ name: "", type: "address" }]
|
|
967
967
|
},
|
|
968
|
-
// Protocol-owner
|
|
968
|
+
// Protocol-owner setters — post-audit ProtocolConfig has no per-rate
|
|
969
|
+
// protocol fee; the two-number model exposes the SPLITS instead. (The old
|
|
970
|
+
// `setProtocolFeeBps` entry described a function the contract no longer
|
|
971
|
+
// has; every call through it reverted.)
|
|
969
972
|
{
|
|
970
|
-
name: "
|
|
973
|
+
name: "setMgmtSplit",
|
|
971
974
|
type: "function",
|
|
972
975
|
stateMutability: "nonpayable",
|
|
973
|
-
inputs: [
|
|
976
|
+
inputs: [
|
|
977
|
+
{
|
|
978
|
+
name: "s",
|
|
979
|
+
type: "tuple",
|
|
980
|
+
components: [
|
|
981
|
+
{ name: "agentBps", type: "uint16" },
|
|
982
|
+
{ name: "protocolBps", type: "uint16" },
|
|
983
|
+
{ name: "guardianBps", type: "uint16" }
|
|
984
|
+
]
|
|
985
|
+
}
|
|
986
|
+
],
|
|
987
|
+
outputs: []
|
|
988
|
+
},
|
|
989
|
+
{
|
|
990
|
+
name: "setPerfSplit",
|
|
991
|
+
type: "function",
|
|
992
|
+
stateMutability: "nonpayable",
|
|
993
|
+
inputs: [
|
|
994
|
+
{
|
|
995
|
+
name: "s",
|
|
996
|
+
type: "tuple",
|
|
997
|
+
components: [
|
|
998
|
+
{ name: "agentBps", type: "uint16" },
|
|
999
|
+
{ name: "protocolBps", type: "uint16" },
|
|
1000
|
+
{ name: "guardianBps", type: "uint16" },
|
|
1001
|
+
{ name: "ownerBps", type: "uint16" }
|
|
1002
|
+
]
|
|
1003
|
+
}
|
|
1004
|
+
],
|
|
974
1005
|
outputs: []
|
|
975
1006
|
}
|
|
976
1007
|
];
|
|
@@ -2172,22 +2203,64 @@ function encodeGovernorParam(args, chainId) {
|
|
|
2172
2203
|
note: "Vault-owner only. V1.5 has no on-chain parameter timelock \u2014 the change applies immediately on this call. Bounds are validated on-chain; out-of-range values revert."
|
|
2173
2204
|
};
|
|
2174
2205
|
}
|
|
2175
|
-
function
|
|
2206
|
+
function parseSplitBps(value, label) {
|
|
2207
|
+
const v = Number(parseUintArg(value, label));
|
|
2208
|
+
if (v > 1e4)
|
|
2209
|
+
throw usage(`\`${label}\` must be <= 10000 bps, got ${v}`);
|
|
2210
|
+
return v;
|
|
2211
|
+
}
|
|
2212
|
+
function requireSplitSum(legs) {
|
|
2213
|
+
const sum = Object.values(legs).reduce((a, b) => a + b, 0);
|
|
2214
|
+
if (sum !== 1e4) {
|
|
2215
|
+
const parts = Object.entries(legs).map(([k, v]) => `${k}=${v}`).join(", ");
|
|
2216
|
+
throw usage(`split legs must sum to 10000 bps, got ${sum} (${parts})`);
|
|
2217
|
+
}
|
|
2218
|
+
}
|
|
2219
|
+
function encodeMgmtSplit(args, chainId) {
|
|
2176
2220
|
if (!isAddress2(args.protocolConfig)) {
|
|
2177
2221
|
throw usage(`\`protocolConfig\` must be a valid address, got "${args.protocolConfig}"`);
|
|
2178
2222
|
}
|
|
2179
2223
|
const protocolConfig = getAddress2(args.protocolConfig);
|
|
2180
|
-
const
|
|
2224
|
+
const s = {
|
|
2225
|
+
agentBps: parseSplitBps(args.agentBps, "agentBps"),
|
|
2226
|
+
protocolBps: parseSplitBps(args.protocolBps, "protocolBps"),
|
|
2227
|
+
guardianBps: parseSplitBps(args.guardianBps, "guardianBps")
|
|
2228
|
+
};
|
|
2229
|
+
requireSplitSum(s);
|
|
2181
2230
|
const data = encodeFunctionData2({
|
|
2182
2231
|
abi: PROTOCOL_CONFIG_ABI,
|
|
2183
|
-
functionName: "
|
|
2184
|
-
args: [
|
|
2232
|
+
functionName: "setMgmtSplit",
|
|
2233
|
+
args: [s]
|
|
2234
|
+
});
|
|
2235
|
+
return {
|
|
2236
|
+
txs: [governorTx(protocolConfig, chainId, data)],
|
|
2237
|
+
preconditions: [],
|
|
2238
|
+
description: `Set ProtocolConfig mgmtSplit = agent ${s.agentBps} / protocol ${s.protocolBps} / guardian ${s.guardianBps} bps.`,
|
|
2239
|
+
note: "Protocol-owner only (the protocol multisig), NOT the vault owner. Targets the protocol-wide ProtocolConfig contract; in-flight proposals keep the split snapshotted at propose time."
|
|
2240
|
+
};
|
|
2241
|
+
}
|
|
2242
|
+
function encodePerfSplit(args, chainId) {
|
|
2243
|
+
if (!isAddress2(args.protocolConfig)) {
|
|
2244
|
+
throw usage(`\`protocolConfig\` must be a valid address, got "${args.protocolConfig}"`);
|
|
2245
|
+
}
|
|
2246
|
+
const protocolConfig = getAddress2(args.protocolConfig);
|
|
2247
|
+
const s = {
|
|
2248
|
+
agentBps: parseSplitBps(args.agentBps, "agentBps"),
|
|
2249
|
+
protocolBps: parseSplitBps(args.protocolBps, "protocolBps"),
|
|
2250
|
+
guardianBps: parseSplitBps(args.guardianBps, "guardianBps"),
|
|
2251
|
+
ownerBps: parseSplitBps(args.ownerBps, "ownerBps")
|
|
2252
|
+
};
|
|
2253
|
+
requireSplitSum(s);
|
|
2254
|
+
const data = encodeFunctionData2({
|
|
2255
|
+
abi: PROTOCOL_CONFIG_ABI,
|
|
2256
|
+
functionName: "setPerfSplit",
|
|
2257
|
+
args: [s]
|
|
2185
2258
|
});
|
|
2186
2259
|
return {
|
|
2187
2260
|
txs: [governorTx(protocolConfig, chainId, data)],
|
|
2188
2261
|
preconditions: [],
|
|
2189
|
-
description: `Set ProtocolConfig
|
|
2190
|
-
note: "Protocol-owner only (the protocol multisig), NOT the vault owner. Targets the protocol-wide ProtocolConfig contract
|
|
2262
|
+
description: `Set ProtocolConfig perfSplit = agent ${s.agentBps} / protocol ${s.protocolBps} / guardian ${s.guardianBps} / owner ${s.ownerBps} bps.`,
|
|
2263
|
+
note: "Protocol-owner only (the protocol multisig), NOT the vault owner. Targets the protocol-wide ProtocolConfig contract; in-flight proposals keep the split snapshotted at propose time."
|
|
2191
2264
|
};
|
|
2192
2265
|
}
|
|
2193
2266
|
|
|
@@ -2648,7 +2721,7 @@ async function lookupAgentIdByWallet(wallet) {
|
|
|
2648
2721
|
}
|
|
2649
2722
|
function registerIdentityCommands(program) {
|
|
2650
2723
|
const identity = program.command("identity").description("Manage ERC-8004 agent identity (via Agent0 SDK)");
|
|
2651
|
-
identity.command("mint").description("Register a new ERC-8004 agent identity (required before creating/joining
|
|
2724
|
+
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) => {
|
|
2652
2725
|
if (isCalldataOnly()) {
|
|
2653
2726
|
emitCalldata(
|
|
2654
2727
|
encodeIdentityMint(
|
|
@@ -2676,7 +2749,7 @@ function registerIdentityCommands(program) {
|
|
|
2676
2749
|
const balance = await client.getBalance({ address: account.address });
|
|
2677
2750
|
if (balance === 0n) {
|
|
2678
2751
|
throw new Error(
|
|
2679
|
-
`No ETH on Robinhood mainnet (chain 4663) for ${account.address}. Identity is minted on the coordination chain regardless of your
|
|
2752
|
+
`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.`
|
|
2680
2753
|
);
|
|
2681
2754
|
}
|
|
2682
2755
|
const action = encodeIdentityMint(
|
|
@@ -2706,8 +2779,8 @@ function registerIdentityCommands(program) {
|
|
|
2706
2779
|
console.log(chalk.dim(` Owner: ${account.address}`));
|
|
2707
2780
|
console.log(chalk.dim(` Saved to ~/.sherwood/config.json`));
|
|
2708
2781
|
console.log();
|
|
2709
|
-
console.log(chalk.green("You can now create
|
|
2710
|
-
console.log(chalk.dim(` sherwood
|
|
2782
|
+
console.log(chalk.green("You can now create vaults:"));
|
|
2783
|
+
console.log(chalk.dim(` sherwood vault create --agent-id ${tokenId} --subdomain <name> --name <name>`));
|
|
2711
2784
|
} catch (err) {
|
|
2712
2785
|
spinner.fail("Failed to register identity");
|
|
2713
2786
|
console.error(chalk.red(formatContractError(err)));
|
|
@@ -2866,8 +2939,8 @@ function registerIdentityCommands(program) {
|
|
|
2866
2939
|
console.log(chalk.dim(` Sherwood wallet: ${account.address}${self ? " (same as economyOS wallet \u2014 no binding needed)" : " (bound via signature)"}`));
|
|
2867
2940
|
console.log(chalk.dim(` Saved to ~/.sherwood/config.json`));
|
|
2868
2941
|
console.log();
|
|
2869
|
-
console.log(chalk.green("You can now create or join
|
|
2870
|
-
console.log(chalk.dim(` sherwood
|
|
2942
|
+
console.log(chalk.green("You can now create or join vaults with this identity:"));
|
|
2943
|
+
console.log(chalk.dim(` sherwood vault create --agent-id ${tokenId} --subdomain <name> --name <name>`));
|
|
2871
2944
|
} catch (err) {
|
|
2872
2945
|
spinner.fail("Failed to link Virtuals identity");
|
|
2873
2946
|
console.error(chalk.red(formatContractError(err)));
|
|
@@ -3083,7 +3156,8 @@ export {
|
|
|
3083
3156
|
encodeUnstick,
|
|
3084
3157
|
encodeEmergencySettle,
|
|
3085
3158
|
encodeGovernorParam,
|
|
3086
|
-
|
|
3159
|
+
encodeMgmtSplit,
|
|
3160
|
+
encodePerfSplit,
|
|
3087
3161
|
encodeCreateFund,
|
|
3088
3162
|
encodeStrategyDeploy,
|
|
3089
3163
|
encodeJoinRequest,
|
|
@@ -3100,4 +3174,4 @@ export {
|
|
|
3100
3174
|
lookupAgentIdByWallet,
|
|
3101
3175
|
registerIdentityCommands
|
|
3102
3176
|
};
|
|
3103
|
-
//# sourceMappingURL=chunk-
|
|
3177
|
+
//# sourceMappingURL=chunk-6QBGTX2Q.js.map
|