@sherwoodagent/cli 0.28.0 → 0.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/addresses-CQLJSZGN.js +35 -0
- package/dist/{agent-C4HZUQNI.js → agent-QIQABFLV.js} +7 -9
- package/dist/agent-QIQABFLV.js.map +1 -0
- package/dist/{chat-C7EEHQHR.js → chat-N6LSZUSC.js} +44 -12
- package/dist/chat-N6LSZUSC.js.map +1 -0
- package/dist/{chunk-KEUEO4UE.js → chunk-2H6IGGKN.js} +1 -1
- package/dist/chunk-2H6IGGKN.js.map +1 -0
- package/dist/{chunk-4OK3ZW54.js → chunk-3EMDYEAD.js} +6 -6
- package/dist/{chunk-H57TPN3L.js → chunk-I3UVF2GD.js} +7 -7
- package/dist/{chunk-Y3M66Z5O.js → chunk-IIBOFECO.js} +6 -6
- package/dist/{chunk-GCTABO5K.js → chunk-QGEIK4H5.js} +2 -2
- package/dist/chunk-T5BRUFWV.js +142 -0
- package/dist/chunk-T5BRUFWV.js.map +1 -0
- package/dist/{chunk-GJPP22NB.js → chunk-WQOTLKVP.js} +27 -2
- package/dist/{chunk-GJPP22NB.js.map → chunk-WQOTLKVP.js.map} +1 -1
- package/dist/{chunk-6Y4QZMVP.js → chunk-WRG7GAIA.js} +2 -2
- package/dist/{chunk-C6JA5EES.js → chunk-YRYPGJ66.js} +8 -8
- package/dist/{chunk-RNCK26JE.js → chunk-ZPYN5ZAI.js} +3 -3
- package/dist/chunk-ZPYN5ZAI.js.map +1 -0
- package/dist/{client-QBVND2OI.js → client-HBMSTSKK.js} +3 -3
- package/dist/{eas-CA6BXTG5.js → eas-D3KSAGWT.js} +5 -5
- package/dist/{governor-VWAPPCFS.js → governor-3MYMDBRF.js} +5 -5
- package/dist/index.js +157 -196
- package/dist/index.js.map +1 -1
- package/dist/{ipfs-22YLNQ2C.js → ipfs-IGXLLJCF.js} +2 -2
- package/dist/{network-V77NDYOW.js → network-X6GM7ROG.js} +2 -2
- package/dist/{price-YTWAYSCU.js → price-DXNFNTV6.js} +7 -7
- package/dist/{research-CGDUEDL5.js → research-H3I4LALI.js} +8 -8
- package/dist/{research-DLZNLY6X.js → research-NCESMYXK.js} +4 -4
- package/dist/research-NCESMYXK.js.map +1 -0
- package/dist/{session-6NIAZOEH.js → session-5JUUZYIL.js} +11 -11
- package/dist/{trade-VGJP6LAN.js → trade-XDE6YCNY.js} +15 -15
- package/dist/{xmtp-SF34ZC5H.js → xmtp-XTJ7HDVG.js} +5 -5
- package/package.json +1 -1
- package/dist/agent-C4HZUQNI.js.map +0 -1
- package/dist/chat-C7EEHQHR.js.map +0 -1
- package/dist/chunk-KEUEO4UE.js.map +0 -1
- package/dist/chunk-RNCK26JE.js.map +0 -1
- /package/dist/{client-QBVND2OI.js.map → addresses-CQLJSZGN.js.map} +0 -0
- /package/dist/{chunk-4OK3ZW54.js.map → chunk-3EMDYEAD.js.map} +0 -0
- /package/dist/{chunk-H57TPN3L.js.map → chunk-I3UVF2GD.js.map} +0 -0
- /package/dist/{chunk-Y3M66Z5O.js.map → chunk-IIBOFECO.js.map} +0 -0
- /package/dist/{chunk-GCTABO5K.js.map → chunk-QGEIK4H5.js.map} +0 -0
- /package/dist/{chunk-6Y4QZMVP.js.map → chunk-WRG7GAIA.js.map} +0 -0
- /package/dist/{chunk-C6JA5EES.js.map → chunk-YRYPGJ66.js.map} +0 -0
- /package/dist/{eas-CA6BXTG5.js.map → client-HBMSTSKK.js.map} +0 -0
- /package/dist/{governor-VWAPPCFS.js.map → eas-D3KSAGWT.js.map} +0 -0
- /package/dist/{ipfs-22YLNQ2C.js.map → governor-3MYMDBRF.js.map} +0 -0
- /package/dist/{network-V77NDYOW.js.map → ipfs-IGXLLJCF.js.map} +0 -0
- /package/dist/{research-DLZNLY6X.js.map → network-X6GM7ROG.js.map} +0 -0
- /package/dist/{price-YTWAYSCU.js.map → price-DXNFNTV6.js.map} +0 -0
- /package/dist/{research-CGDUEDL5.js.map → research-H3I4LALI.js.map} +0 -0
- /package/dist/{session-6NIAZOEH.js.map → session-5JUUZYIL.js.map} +0 -0
- /package/dist/{trade-VGJP6LAN.js.map → trade-XDE6YCNY.js.map} +0 -0
- /package/dist/{xmtp-SF34ZC5H.js.map → xmtp-XTJ7HDVG.js.map} +0 -0
|
@@ -1,15 +1,25 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getSyndicate,
|
|
3
|
+
updateMetadata
|
|
4
|
+
} from "./chunk-T5BRUFWV.js";
|
|
1
5
|
import {
|
|
2
6
|
getTextRecord,
|
|
3
7
|
resolveSyndicate,
|
|
4
8
|
setTextRecord
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import
|
|
9
|
+
} from "./chunk-YRYPGJ66.js";
|
|
10
|
+
import {
|
|
11
|
+
fetchMetadata,
|
|
12
|
+
uploadMetadata
|
|
13
|
+
} from "./chunk-2H6IGGKN.js";
|
|
7
14
|
import "./chunk-PQ5ZX6ZT.js";
|
|
15
|
+
import {
|
|
16
|
+
ENS
|
|
17
|
+
} from "./chunk-WQOTLKVP.js";
|
|
8
18
|
import {
|
|
9
19
|
formatContractError,
|
|
10
20
|
getAccount
|
|
11
|
-
} from "./chunk-
|
|
12
|
-
import "./chunk-
|
|
21
|
+
} from "./chunk-WRG7GAIA.js";
|
|
22
|
+
import "./chunk-ZPYN5ZAI.js";
|
|
13
23
|
import {
|
|
14
24
|
cacheGroupId,
|
|
15
25
|
getCachedGroupId
|
|
@@ -19,7 +29,7 @@ import {
|
|
|
19
29
|
import chalk from "chalk";
|
|
20
30
|
import ora from "ora";
|
|
21
31
|
async function loadXmtp() {
|
|
22
|
-
return import("./xmtp-
|
|
32
|
+
return import("./xmtp-XTJ7HDVG.js");
|
|
23
33
|
}
|
|
24
34
|
function formatTimestamp(date) {
|
|
25
35
|
return `${date.getHours().toString().padStart(2, "0")}:${date.getMinutes().toString().padStart(2, "0")}`;
|
|
@@ -293,12 +303,34 @@ async function handleInit(name, force, isPublic) {
|
|
|
293
303
|
const client = await xmtp.getXmtpClient();
|
|
294
304
|
const groupId = await xmtp.createSyndicateGroup(client, name, isPublic);
|
|
295
305
|
cacheGroupId(name, groupId);
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
306
|
+
const hasENS = ENS().L2_REGISTRY !== "0x0000000000000000000000000000000000000000";
|
|
307
|
+
if (hasENS) {
|
|
308
|
+
try {
|
|
309
|
+
spinner.text = "Writing group ID to ENS...";
|
|
310
|
+
await setTextRecord(name, "xmtpGroupId", groupId, syndicate.vault);
|
|
311
|
+
} catch (ensErr) {
|
|
312
|
+
console.warn(chalk.yellow("\n \u26A0 Could not write ENS text record"));
|
|
313
|
+
console.warn(chalk.dim(` ${ensErr instanceof Error ? ensErr.message : String(ensErr)}`));
|
|
314
|
+
}
|
|
315
|
+
} else {
|
|
316
|
+
try {
|
|
317
|
+
spinner.text = "Saving group ID to syndicate metadata...";
|
|
318
|
+
const info = await getSyndicate(syndicate.id);
|
|
319
|
+
let metadata;
|
|
320
|
+
try {
|
|
321
|
+
metadata = await fetchMetadata(info.metadataURI);
|
|
322
|
+
} catch {
|
|
323
|
+
metadata = { schema: "sherwood/syndicate/v1", name, description: "", chain: "", strategies: [], terms: {}, links: {} };
|
|
324
|
+
}
|
|
325
|
+
metadata.xmtpGroupId = groupId;
|
|
326
|
+
const newURI = await uploadMetadata(metadata);
|
|
327
|
+
await updateMetadata(syndicate.id, newURI);
|
|
328
|
+
console.log(chalk.dim(`
|
|
329
|
+
Group ID saved to metadata: ${newURI}`));
|
|
330
|
+
} catch (metaErr) {
|
|
331
|
+
console.warn(chalk.yellow("\n \u26A0 Could not persist group ID (cached locally only)"));
|
|
332
|
+
console.warn(chalk.dim(` ${metaErr instanceof Error ? metaErr.message : String(metaErr)}`));
|
|
333
|
+
}
|
|
302
334
|
}
|
|
303
335
|
spinner.succeed(`Chat group created for ${name}.sherwoodagent.eth`);
|
|
304
336
|
console.log(chalk.dim(` Group ID: ${groupId}`));
|
|
@@ -379,4 +411,4 @@ function registerChatCommands(program) {
|
|
|
379
411
|
export {
|
|
380
412
|
registerChatCommands
|
|
381
413
|
};
|
|
382
|
-
//# sourceMappingURL=chat-
|
|
414
|
+
//# sourceMappingURL=chat-N6LSZUSC.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/chat.ts"],"sourcesContent":["/**\n * Chat commands — sherwood chat <syndicate-name> [action] [args...]\n *\n * Uses XMTP for encrypted group messaging tied to syndicates.\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 */\n\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { getAccount, formatContractError } from \"../lib/client.js\";\nimport { resolveSyndicate, 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 resolveSyndicate(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\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 syndicate: 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 handlePublic(name: string, on: boolean): Promise<void> {\n const spectatorAddress = process.env.DASHBOARD_SPECTATOR_ADDRESS;\n if (!spectatorAddress) {\n console.error(chalk.red(\"DASHBOARD_SPECTATOR_ADDRESS env var is required\"));\n process.exit(1);\n }\n\n const spinner = ora(`${on ? \"Enabling\" : \"Disabling\"} public chat...`).start();\n try {\n const xmtp = await loadXmtp();\n const group = await xmtp.getGroup(\"\", name);\n\n if (on) {\n await xmtp.addMember(group, spectatorAddress);\n spinner.succeed(\"Public chat enabled — dashboard spectator added\");\n await notifySpectatorSync();\n } else {\n await xmtp.removeMember(group, spectatorAddress);\n spinner.succeed(\"Public chat disabled — dashboard spectator removed\");\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 syndicate = await resolveSyndicate(name);\n const callerAddress = getAccount().address.toLowerCase();\n if (syndicate.creator.toLowerCase() !== callerAddress) {\n spinner.fail(\"Only the syndicate 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 syndicate\");\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.createSyndicateGroup(client, name, isPublic);\n\n cacheGroupId(name, groupId);\n\n // Persist group ID: ENS on chains with L2 Registry, IPFS metadata otherwise\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, syndicate.vault);\n } catch (ensErr) {\n console.warn(chalk.yellow(\"\\n ⚠ Could not write ENS text record\"));\n console.warn(chalk.dim(` ${ensErr instanceof Error ? ensErr.message : String(ensErr)}`));\n }\n } else {\n // No ENS (e.g. HyperEVM) — persist in IPFS metadata\n try {\n spinner.text = \"Saving group ID to syndicate metadata...\";\n const info = await factoryLib.getSyndicate(syndicate.id);\n let metadata;\n try {\n metadata = await fetchMetadata(info.metadataURI);\n } catch {\n metadata = { schema: \"sherwood/syndicate/v1\", name, description: \"\", chain: \"\", strategies: [], terms: {}, links: {} };\n }\n metadata.xmtpGroupId = groupId;\n const newURI = await uploadMetadata(metadata);\n await factoryLib.updateMetadata(syndicate.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 (cached locally only)\"));\n console.warn(chalk.dim(` ${metaErr instanceof Error ? metaErr.message : String(metaErr)}`));\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(\"Syndicate chat — stream, send, log, members, add, remove, init, public\")\n .option(\"--markdown\", \"Send as rich markdown (for send)\", 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 .action(async (name: string, action: string | undefined, actionArgs: string[], opts: { markdown: boolean; limit: string; force: boolean; public: boolean }) => {\n switch (action) {\n case \"send\": {\n const message = actionArgs[0];\n if (!message) {\n console.error(chalk.red(\"Usage: sherwood chat <name> send <message> [--markdown]\"));\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 \"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":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/ipfs.ts"],"sourcesContent":["/**\n * IPFS metadata upload/fetch via Sherwood API.\n *\n * Uploads go through the server-side API at sherwood.sh/api/ipfs/upload\n * which holds the Pinata JWT. CLI and app only need the gateway URL for reads.\n */\n\nexport interface SyndicateMetadata {\n schema: string;\n name: string;\n description: string;\n logo?: string;\n chain: string;\n xmtpGroupId?: string;\n strategies: {\n id: string;\n name: string;\n description: string;\n protocols: string[];\n riskLevel: string;\n }[];\n terms: {\n minDeposit?: string;\n minDepositFormatted?: string;\n feeModel?: string;\n lockPeriod?: number;\n };\n links: {\n moltbook?: string;\n dashboard?: string;\n github?: string;\n };\n}\n\nconst DEFAULT_PINATA_GATEWAY = \"https://sherwood.mypinata.cloud\";\nconst DEFAULT_UPLOAD_API = \"https://sherwood.sh/api/ipfs/upload\";\n\nfunction getUploadApiUrl(): string {\n return process.env.SHERWOOD_API_URL\n ? `${process.env.SHERWOOD_API_URL}/api/ipfs/upload`\n : DEFAULT_UPLOAD_API;\n}\n\nfunction getPinataGateway(): string {\n return process.env.PINATA_GATEWAY || DEFAULT_PINATA_GATEWAY;\n}\n\n/**\n * Upload JSON to IPFS via the Sherwood API (server-side Pinata).\n * Returns the IPFS URI (ipfs://Qm...).\n */\nasync function uploadToIPFS(content: Record<string, unknown>, name: string): Promise<string> {\n const url = getUploadApiUrl();\n\n const response = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ content, name }),\n });\n\n if (!response.ok) {\n const text = await response.text();\n throw new Error(`IPFS upload failed (${response.status}): ${text}`);\n }\n\n const result = (await response.json()) as { ipfsHash: string };\n return `ipfs://${result.ipfsHash}`;\n}\n\n/**\n * Pin arbitrary JSON to IPFS.\n * Used for research results and other generic JSON payloads.\n * Returns the IPFS URI (ipfs://Qm...).\n */\nexport async function pinJSON(content: Record<string, unknown>, name: string): Promise<string> {\n return uploadToIPFS(content, name);\n}\n\n/**\n * Upload syndicate metadata to IPFS.\n * Returns the IPFS URI (ipfs://Qm...).\n */\nexport async function uploadMetadata(metadata: SyndicateMetadata): Promise<string> {\n const name = `sherwood-syndicate-${metadata.name.toLowerCase().replace(/\\s+/g, \"-\")}`;\n return uploadToIPFS(metadata as unknown as Record<string, unknown>, name);\n}\n\n/**\n * Fetch and parse metadata from an IPFS URI.\n * Supports ipfs:// protocol URIs and raw CIDs.\n */\nexport async function fetchMetadata(ipfsURI: string): Promise<SyndicateMetadata> {\n const gateway = getPinataGateway();\n let cid: string;\n\n if (ipfsURI.startsWith(\"ipfs://\")) {\n cid = ipfsURI.slice(7);\n } else if (ipfsURI.startsWith(\"Qm\") || ipfsURI.startsWith(\"bafy\")) {\n cid = ipfsURI;\n } else {\n throw new Error(`Invalid IPFS URI: ${ipfsURI}`);\n }\n\n const url = `${gateway}/ipfs/${cid}`;\n const response = await fetch(url);\n\n if (!response.ok) {\n throw new Error(`Failed to fetch metadata from ${url} (${response.status})`);\n }\n\n return (await response.json()) as SyndicateMetadata;\n}\n\n/**\n * Resolve a metadata URI (ipfs:// or data: base64) to name + description.\n * Returns null on any error — callers should treat enrichment as best-effort.\n */\nexport async function resolveMetadataSummary(\n uri: string,\n): Promise<{ name: string; description: string } | null> {\n try {\n if (uri.startsWith(\"data:application/json;base64,\")) {\n const b64 = uri.slice(\"data:application/json;base64,\".length);\n const json = JSON.parse(Buffer.from(b64, \"base64\").toString(\"utf-8\"));\n return { name: json.name || \"\", description: json.description || \"\" };\n }\n const meta = await fetchMetadata(uri);\n return { name: meta.name, description: meta.description };\n } catch {\n return null;\n }\n}\n"],"mappings":";AAkCA,IAAM,yBAAyB;AAC/B,IAAM,qBAAqB;AAE3B,SAAS,kBAA0B;AACjC,SAAO,QAAQ,IAAI,mBACf,GAAG,QAAQ,IAAI,gBAAgB,qBAC/B;AACN;AAEA,SAAS,mBAA2B;AAClC,SAAO,QAAQ,IAAI,kBAAkB;AACvC;AAMA,eAAe,aAAa,SAAkC,MAA+B;AAC3F,QAAM,MAAM,gBAAgB;AAE5B,QAAM,WAAW,MAAM,MAAM,KAAK;AAAA,IAChC,QAAQ;AAAA,IACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,IAC9C,MAAM,KAAK,UAAU,EAAE,SAAS,KAAK,CAAC;AAAA,EACxC,CAAC;AAED,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,OAAO,MAAM,SAAS,KAAK;AACjC,UAAM,IAAI,MAAM,uBAAuB,SAAS,MAAM,MAAM,IAAI,EAAE;AAAA,EACpE;AAEA,QAAM,SAAU,MAAM,SAAS,KAAK;AACpC,SAAO,UAAU,OAAO,QAAQ;AAClC;AAOA,eAAsB,QAAQ,SAAkC,MAA+B;AAC7F,SAAO,aAAa,SAAS,IAAI;AACnC;AAMA,eAAsB,eAAe,UAA8C;AACjF,QAAM,OAAO,sBAAsB,SAAS,KAAK,YAAY,EAAE,QAAQ,QAAQ,GAAG,CAAC;AACnF,SAAO,aAAa,UAAgD,IAAI;AAC1E;AAMA,eAAsB,cAAc,SAA6C;AAC/E,QAAM,UAAU,iBAAiB;AACjC,MAAI;AAEJ,MAAI,QAAQ,WAAW,SAAS,GAAG;AACjC,UAAM,QAAQ,MAAM,CAAC;AAAA,EACvB,WAAW,QAAQ,WAAW,IAAI,KAAK,QAAQ,WAAW,MAAM,GAAG;AACjE,UAAM;AAAA,EACR,OAAO;AACL,UAAM,IAAI,MAAM,qBAAqB,OAAO,EAAE;AAAA,EAChD;AAEA,QAAM,MAAM,GAAG,OAAO,SAAS,GAAG;AAClC,QAAM,WAAW,MAAM,MAAM,GAAG;AAEhC,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,IAAI,MAAM,iCAAiC,GAAG,KAAK,SAAS,MAAM,GAAG;AAAA,EAC7E;AAEA,SAAQ,MAAM,SAAS,KAAK;AAC9B;AAMA,eAAsB,uBACpB,KACuD;AACvD,MAAI;AACF,QAAI,IAAI,WAAW,+BAA+B,GAAG;AACnD,YAAM,MAAM,IAAI,MAAM,gCAAgC,MAAM;AAC5D,YAAM,OAAO,KAAK,MAAM,OAAO,KAAK,KAAK,QAAQ,EAAE,SAAS,OAAO,CAAC;AACpE,aAAO,EAAE,MAAM,KAAK,QAAQ,IAAI,aAAa,KAAK,eAAe,GAAG;AAAA,IACtE;AACA,UAAM,OAAO,MAAM,cAAc,GAAG;AACpC,WAAO,EAAE,MAAM,KAAK,MAAM,aAAa,KAAK,YAAY;AAAA,EAC1D,QAAQ;AACN,WAAO;AAAA,EACT;AACF;","names":[]}
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import {
|
|
2
|
-
SHERWOOD
|
|
3
|
-
} from "./chunk-GJPP22NB.js";
|
|
4
1
|
import {
|
|
5
2
|
SYNDICATE_GOVERNOR_ABI
|
|
6
3
|
} from "./chunk-PQ5ZX6ZT.js";
|
|
4
|
+
import {
|
|
5
|
+
SHERWOOD
|
|
6
|
+
} from "./chunk-WQOTLKVP.js";
|
|
7
7
|
import {
|
|
8
8
|
getAccount,
|
|
9
9
|
getPublicClient,
|
|
10
10
|
waitForReceipt,
|
|
11
11
|
writeContractWithRetry
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-WRG7GAIA.js";
|
|
13
13
|
import {
|
|
14
14
|
getChain
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-ZPYN5ZAI.js";
|
|
16
16
|
|
|
17
17
|
// src/lib/governor.ts
|
|
18
18
|
import { parseEventLogs } from "viem";
|
|
@@ -429,4 +429,4 @@ export {
|
|
|
429
429
|
vetoProposal,
|
|
430
430
|
setProtocolFeeBps
|
|
431
431
|
};
|
|
432
|
-
//# sourceMappingURL=chunk-
|
|
432
|
+
//# sourceMappingURL=chunk-3EMDYEAD.js.map
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
import {
|
|
2
|
-
EAS_CONTRACTS,
|
|
3
|
-
EAS_SCHEMAS
|
|
4
|
-
} from "./chunk-GJPP22NB.js";
|
|
5
1
|
import {
|
|
6
2
|
EAS_ABI
|
|
7
3
|
} from "./chunk-PQ5ZX6ZT.js";
|
|
4
|
+
import {
|
|
5
|
+
EAS_CONTRACTS,
|
|
6
|
+
EAS_SCHEMAS
|
|
7
|
+
} from "./chunk-WQOTLKVP.js";
|
|
8
8
|
import {
|
|
9
9
|
getAccount,
|
|
10
10
|
getPublicClient,
|
|
11
11
|
waitForReceipt,
|
|
12
12
|
writeContractWithRetry
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-WRG7GAIA.js";
|
|
14
14
|
import {
|
|
15
15
|
getChain,
|
|
16
16
|
getChainConfig,
|
|
17
17
|
getNetwork
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-ZPYN5ZAI.js";
|
|
19
19
|
|
|
20
20
|
// src/lib/eas.ts
|
|
21
21
|
import { encodeAbiParameters, parseAbiParameters, decodeAbiParameters } from "viem";
|
|
@@ -411,4 +411,4 @@ export {
|
|
|
411
411
|
queryApprovals,
|
|
412
412
|
queryJoinRequests
|
|
413
413
|
};
|
|
414
|
-
//# sourceMappingURL=chunk-
|
|
414
|
+
//# sourceMappingURL=chunk-I3UVF2GD.js.map
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import {
|
|
2
|
-
UNISWAP
|
|
3
|
-
} from "./chunk-GJPP22NB.js";
|
|
4
1
|
import {
|
|
5
2
|
UNISWAP_QUOTER_V2_ABI
|
|
6
3
|
} from "./chunk-PQ5ZX6ZT.js";
|
|
4
|
+
import {
|
|
5
|
+
UNISWAP
|
|
6
|
+
} from "./chunk-WQOTLKVP.js";
|
|
7
7
|
import {
|
|
8
8
|
getAccount,
|
|
9
9
|
getPublicClient,
|
|
10
10
|
sendTxWithRetry,
|
|
11
11
|
waitForReceipt
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-WRG7GAIA.js";
|
|
13
13
|
import {
|
|
14
14
|
getChain
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-ZPYN5ZAI.js";
|
|
16
16
|
import {
|
|
17
17
|
getUniswapApiKey,
|
|
18
18
|
getVeniceApiKey,
|
|
@@ -451,4 +451,4 @@ export {
|
|
|
451
451
|
encodeSwapPath,
|
|
452
452
|
getMultiHopQuote
|
|
453
453
|
};
|
|
454
|
-
//# sourceMappingURL=chunk-
|
|
454
|
+
//# sourceMappingURL=chunk-IIBOFECO.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getAccount
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-WRG7GAIA.js";
|
|
4
4
|
|
|
5
5
|
// src/providers/research/messari.ts
|
|
6
6
|
import { base, baseSepolia } from "viem/chains";
|
|
@@ -445,4 +445,4 @@ export {
|
|
|
445
445
|
NansenProvider,
|
|
446
446
|
getResearchProvider
|
|
447
447
|
};
|
|
448
|
-
//# sourceMappingURL=chunk-
|
|
448
|
+
//# sourceMappingURL=chunk-QGEIK4H5.js.map
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import {
|
|
2
|
+
SYNDICATE_FACTORY_ABI
|
|
3
|
+
} from "./chunk-PQ5ZX6ZT.js";
|
|
4
|
+
import {
|
|
5
|
+
SHERWOOD
|
|
6
|
+
} from "./chunk-WQOTLKVP.js";
|
|
7
|
+
import {
|
|
8
|
+
getAccount,
|
|
9
|
+
getPublicClient,
|
|
10
|
+
waitForReceipt,
|
|
11
|
+
writeContractWithRetry
|
|
12
|
+
} from "./chunk-WRG7GAIA.js";
|
|
13
|
+
import {
|
|
14
|
+
getChain
|
|
15
|
+
} from "./chunk-ZPYN5ZAI.js";
|
|
16
|
+
|
|
17
|
+
// src/lib/factory.ts
|
|
18
|
+
import { decodeEventLog } from "viem";
|
|
19
|
+
function getFactoryAddress() {
|
|
20
|
+
return SHERWOOD().FACTORY;
|
|
21
|
+
}
|
|
22
|
+
async function createSyndicate(params) {
|
|
23
|
+
const client = getPublicClient();
|
|
24
|
+
const hash = await writeContractWithRetry({
|
|
25
|
+
account: getAccount(),
|
|
26
|
+
chain: getChain(),
|
|
27
|
+
address: getFactoryAddress(),
|
|
28
|
+
abi: SYNDICATE_FACTORY_ABI,
|
|
29
|
+
functionName: "createSyndicate",
|
|
30
|
+
args: [
|
|
31
|
+
params.creatorAgentId,
|
|
32
|
+
{
|
|
33
|
+
metadataURI: params.metadataURI,
|
|
34
|
+
asset: params.asset,
|
|
35
|
+
name: params.name,
|
|
36
|
+
symbol: params.symbol,
|
|
37
|
+
openDeposits: params.openDeposits,
|
|
38
|
+
subdomain: params.subdomain
|
|
39
|
+
}
|
|
40
|
+
]
|
|
41
|
+
});
|
|
42
|
+
const receipt = await waitForReceipt(hash);
|
|
43
|
+
for (const log of receipt.logs) {
|
|
44
|
+
try {
|
|
45
|
+
const event = decodeEventLog({
|
|
46
|
+
abi: SYNDICATE_FACTORY_ABI,
|
|
47
|
+
data: log.data,
|
|
48
|
+
topics: log.topics
|
|
49
|
+
});
|
|
50
|
+
if (event.eventName === "SyndicateCreated") {
|
|
51
|
+
const args = event.args;
|
|
52
|
+
return {
|
|
53
|
+
hash,
|
|
54
|
+
syndicateId: args.id,
|
|
55
|
+
vault: args.vault
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
} catch {
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
const count = await getSyndicateCount();
|
|
62
|
+
const info = await getSyndicate(count);
|
|
63
|
+
return {
|
|
64
|
+
hash,
|
|
65
|
+
syndicateId: count,
|
|
66
|
+
vault: info.vault
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
async function subdomainExists(subdomain) {
|
|
70
|
+
const client = getPublicClient();
|
|
71
|
+
const id = await client.readContract({
|
|
72
|
+
address: getFactoryAddress(),
|
|
73
|
+
abi: SYNDICATE_FACTORY_ABI,
|
|
74
|
+
functionName: "subdomainToSyndicate",
|
|
75
|
+
args: [subdomain]
|
|
76
|
+
});
|
|
77
|
+
return id > 0n ? id : null;
|
|
78
|
+
}
|
|
79
|
+
async function getSyndicate(id) {
|
|
80
|
+
const client = getPublicClient();
|
|
81
|
+
const result = await client.readContract({
|
|
82
|
+
address: getFactoryAddress(),
|
|
83
|
+
abi: SYNDICATE_FACTORY_ABI,
|
|
84
|
+
functionName: "syndicates",
|
|
85
|
+
args: [id]
|
|
86
|
+
});
|
|
87
|
+
return {
|
|
88
|
+
id: result[0],
|
|
89
|
+
vault: result[1],
|
|
90
|
+
creator: result[2],
|
|
91
|
+
metadataURI: result[3],
|
|
92
|
+
createdAt: result[4],
|
|
93
|
+
active: result[5],
|
|
94
|
+
subdomain: result[6]
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
async function getSyndicateCount() {
|
|
98
|
+
const client = getPublicClient();
|
|
99
|
+
return client.readContract({
|
|
100
|
+
address: getFactoryAddress(),
|
|
101
|
+
abi: SYNDICATE_FACTORY_ABI,
|
|
102
|
+
functionName: "syndicateCount"
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
async function getActiveSyndicates() {
|
|
106
|
+
const client = getPublicClient();
|
|
107
|
+
const result = await client.readContract({
|
|
108
|
+
address: getFactoryAddress(),
|
|
109
|
+
abi: SYNDICATE_FACTORY_ABI,
|
|
110
|
+
functionName: "getAllActiveSyndicates"
|
|
111
|
+
});
|
|
112
|
+
return result.map((s) => ({
|
|
113
|
+
id: s.id,
|
|
114
|
+
vault: s.vault,
|
|
115
|
+
creator: s.creator,
|
|
116
|
+
metadataURI: s.metadataURI,
|
|
117
|
+
createdAt: s.createdAt,
|
|
118
|
+
active: s.active,
|
|
119
|
+
subdomain: s.subdomain
|
|
120
|
+
}));
|
|
121
|
+
}
|
|
122
|
+
async function updateMetadata(syndicateId, metadataURI) {
|
|
123
|
+
const hash = await writeContractWithRetry({
|
|
124
|
+
account: getAccount(),
|
|
125
|
+
chain: getChain(),
|
|
126
|
+
address: getFactoryAddress(),
|
|
127
|
+
abi: SYNDICATE_FACTORY_ABI,
|
|
128
|
+
functionName: "updateMetadata",
|
|
129
|
+
args: [syndicateId, metadataURI]
|
|
130
|
+
});
|
|
131
|
+
await waitForReceipt(hash);
|
|
132
|
+
return hash;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export {
|
|
136
|
+
createSyndicate,
|
|
137
|
+
subdomainExists,
|
|
138
|
+
getSyndicate,
|
|
139
|
+
getActiveSyndicates,
|
|
140
|
+
updateMetadata
|
|
141
|
+
};
|
|
142
|
+
//# sourceMappingURL=chunk-T5BRUFWV.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/factory.ts"],"sourcesContent":["/**\n * SyndicateFactory contract wrapper.\n *\n * Creates new syndicate vaults via the factory. Each syndicate = one vault proxy\n * with shared executor lib and vault implementation.\n */\n\nimport type { Address, Hex } from \"viem\";\nimport { parseUnits, formatUnits, decodeEventLog } from \"viem\";\nimport { getChain, getNetwork } from \"./network.js\";\nimport { getPublicClient, getAccount, writeContractWithRetry, waitForReceipt } from \"./client.js\";\nimport { SYNDICATE_FACTORY_ABI } from \"./abis.js\";\nimport { TOKENS, SHERWOOD } from \"./addresses.js\";\n\nexport interface SyndicateInfo {\n id: bigint;\n vault: Address;\n creator: Address;\n metadataURI: string;\n createdAt: bigint;\n active: boolean;\n subdomain: string;\n}\n\nexport interface CreateSyndicateParams {\n creatorAgentId: bigint;\n metadataURI: string;\n asset: Address;\n name: string;\n symbol: string;\n openDeposits: boolean;\n subdomain: string;\n}\n\nfunction getFactoryAddress(): Address {\n return SHERWOOD().FACTORY;\n}\n\nexport interface CreateSyndicateResult {\n hash: Hex;\n syndicateId: bigint;\n vault: Address;\n}\n\n/**\n * Create a new syndicate via the factory.\n * Deploys a UUPS vault proxy, initializes it, and registers in the factory.\n * Waits for receipt and extracts vault address from SyndicateCreated event.\n */\nexport async function createSyndicate(params: CreateSyndicateParams): Promise<CreateSyndicateResult> {\n const client = getPublicClient();\n\n const hash = await writeContractWithRetry({\n account: getAccount(),\n chain: getChain(),\n address: getFactoryAddress(),\n abi: SYNDICATE_FACTORY_ABI,\n functionName: \"createSyndicate\",\n args: [\n params.creatorAgentId,\n {\n metadataURI: params.metadataURI,\n asset: params.asset,\n name: params.name,\n symbol: params.symbol,\n openDeposits: params.openDeposits,\n subdomain: params.subdomain,\n },\n ],\n });\n\n // Wait for receipt and extract vault from SyndicateCreated event\n const receipt = await waitForReceipt(hash);\n\n // Parse SyndicateCreated event from receipt logs\n for (const log of receipt.logs) {\n try {\n const event = decodeEventLog({\n abi: SYNDICATE_FACTORY_ABI,\n data: log.data,\n topics: log.topics,\n });\n if (event.eventName === \"SyndicateCreated\") {\n const args = event.args as { id: bigint; vault: Address; creator: Address };\n return {\n hash,\n syndicateId: args.id,\n vault: args.vault,\n };\n }\n } catch {\n // Not our event, skip\n }\n }\n\n // Fallback: read from factory state (may lag on RPC replicas)\n const count = await getSyndicateCount();\n const info = await getSyndicate(count);\n\n return {\n hash,\n syndicateId: count,\n vault: info.vault,\n };\n}\n\n/**\n * Check if a subdomain is already registered. Returns the syndicate ID if found, null otherwise.\n */\nexport async function subdomainExists(subdomain: string): Promise<bigint | null> {\n const client = getPublicClient();\n const id = (await client.readContract({\n address: getFactoryAddress(),\n abi: SYNDICATE_FACTORY_ABI,\n functionName: \"subdomainToSyndicate\",\n args: [subdomain],\n })) as bigint;\n\n return id > 0n ? id : null;\n}\n\n/**\n * Get syndicate info by ID.\n */\nexport async function getSyndicate(id: bigint): Promise<SyndicateInfo> {\n const client = getPublicClient();\n const result = (await client.readContract({\n address: getFactoryAddress(),\n abi: SYNDICATE_FACTORY_ABI,\n functionName: \"syndicates\",\n args: [id],\n })) as [bigint, Address, Address, string, bigint, boolean, string];\n\n return {\n id: result[0],\n vault: result[1],\n creator: result[2],\n metadataURI: result[3],\n createdAt: result[4],\n active: result[5],\n subdomain: result[6],\n };\n}\n\n/**\n * Get the total number of syndicates created.\n */\nexport async function getSyndicateCount(): Promise<bigint> {\n const client = getPublicClient();\n return client.readContract({\n address: getFactoryAddress(),\n abi: SYNDICATE_FACTORY_ABI,\n functionName: \"syndicateCount\",\n }) as Promise<bigint>;\n}\n\n/**\n * Get all active syndicates from the factory.\n */\nexport async function getActiveSyndicates(): Promise<SyndicateInfo[]> {\n const client = getPublicClient();\n const result = (await client.readContract({\n address: getFactoryAddress(),\n abi: SYNDICATE_FACTORY_ABI,\n functionName: \"getAllActiveSyndicates\",\n })) as readonly {\n id: bigint;\n vault: Address;\n creator: Address;\n metadataURI: string;\n createdAt: bigint;\n active: boolean;\n subdomain: string;\n }[];\n\n return result.map((s) => ({\n id: s.id,\n vault: s.vault,\n creator: s.creator,\n metadataURI: s.metadataURI,\n createdAt: s.createdAt,\n active: s.active,\n subdomain: s.subdomain,\n }));\n}\n\n/**\n * Update syndicate metadata (creator only).\n */\nexport async function updateMetadata(syndicateId: bigint, metadataURI: string): Promise<Hex> {\n const hash = await writeContractWithRetry({\n account: getAccount(),\n chain: getChain(),\n address: getFactoryAddress(),\n abi: SYNDICATE_FACTORY_ABI,\n functionName: \"updateMetadata\",\n args: [syndicateId, metadataURI],\n });\n await waitForReceipt(hash);\n return hash;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getNetwork
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-ZPYN5ZAI.js";
|
|
4
4
|
|
|
5
5
|
// src/lib/addresses.ts
|
|
6
6
|
var ZERO = "0x0000000000000000000000000000000000000000";
|
|
@@ -29,6 +29,9 @@ var BASE_UNISWAP = {
|
|
|
29
29
|
QUOTER_V2: "0x3d4e44Eb1374240CE5F1B871ab261CD16335B76a",
|
|
30
30
|
SWAP_ADAPTER: "0x121AaC2B96Ec365e457fcCc1C2ED5a6142064069"
|
|
31
31
|
};
|
|
32
|
+
var BASE_INFRA = {
|
|
33
|
+
MULTICALL3: "0xcA11bde05977b3631167028862bE2a173976CA11"
|
|
34
|
+
};
|
|
32
35
|
var BASE_SEPOLIA_TOKENS = {
|
|
33
36
|
USDC: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
|
|
34
37
|
// Circle test USDC
|
|
@@ -57,6 +60,10 @@ var BASE_SEPOLIA_UNISWAP = {
|
|
|
57
60
|
// Uniswap V3 QuoterV2
|
|
58
61
|
SWAP_ADAPTER: ZERO
|
|
59
62
|
};
|
|
63
|
+
var BASE_SEPOLIA_INFRA = {
|
|
64
|
+
MULTICALL3: "0xcA11bde05977b3631167028862bE2a173976CA11"
|
|
65
|
+
// Deterministic, same everywhere
|
|
66
|
+
};
|
|
60
67
|
var ROBINHOOD_TESTNET_TOKENS = {
|
|
61
68
|
USDC: ZERO,
|
|
62
69
|
WETH: "0x7943e237c7F95DA44E0301572D358911207852Fa",
|
|
@@ -98,6 +105,10 @@ var BASE_SEPOLIA_CHAINLINK = { VERIFIER_PROXY: ZERO };
|
|
|
98
105
|
var ROBINHOOD_TESTNET_CHAINLINK = {
|
|
99
106
|
VERIFIER_PROXY: "0x72790f9eB82db492a7DDb6d2af22A270Dcc3Db64"
|
|
100
107
|
};
|
|
108
|
+
var ROBINHOOD_TESTNET_INFRA = {
|
|
109
|
+
MULTICALL3: "0xcA11bde05977b3631167028862bE2a173976CA11"
|
|
110
|
+
// Deterministic, same everywhere
|
|
111
|
+
};
|
|
101
112
|
var HYPEREVM_TOKENS = {
|
|
102
113
|
USDC: "0xb88339CB7199b77E23DB6E890353E22632Ba630f",
|
|
103
114
|
WETH: ZERO,
|
|
@@ -127,6 +138,9 @@ var HYPEREVM_MOONWELL = {
|
|
|
127
138
|
mAERO: ZERO
|
|
128
139
|
};
|
|
129
140
|
var HYPEREVM_UNISWAP = { SWAP_ROUTER: ZERO, QUOTER_V2: ZERO, SWAP_ADAPTER: ZERO };
|
|
141
|
+
var HYPEREVM_INFRA = {
|
|
142
|
+
MULTICALL3: "0xcA11bde05977b3631167028862bE2a173976CA11"
|
|
143
|
+
};
|
|
130
144
|
var BASE_ENS = {
|
|
131
145
|
L2_REGISTRAR: "0x866996c808E6244216a3d0df15464FCF5d495394",
|
|
132
146
|
L2_REGISTRY: "0x7a019ce699e27b0ad1e5b51344a58116b9f3b9b1"
|
|
@@ -301,6 +315,13 @@ var UNISWAP_REGISTRY = {
|
|
|
301
315
|
hyperevm: HYPEREVM_UNISWAP,
|
|
302
316
|
"hyperevm-testnet": HYPEREVM_UNISWAP
|
|
303
317
|
};
|
|
318
|
+
var INFRA_REGISTRY = {
|
|
319
|
+
base: BASE_INFRA,
|
|
320
|
+
"base-sepolia": BASE_SEPOLIA_INFRA,
|
|
321
|
+
"robinhood-testnet": ROBINHOOD_TESTNET_INFRA,
|
|
322
|
+
hyperevm: HYPEREVM_INFRA,
|
|
323
|
+
"hyperevm-testnet": HYPEREVM_INFRA
|
|
324
|
+
};
|
|
304
325
|
var ENS_REGISTRY = {
|
|
305
326
|
base: BASE_ENS,
|
|
306
327
|
"base-sepolia": BASE_SEPOLIA_ENS,
|
|
@@ -382,6 +403,9 @@ function MOONWELL() {
|
|
|
382
403
|
function UNISWAP() {
|
|
383
404
|
return UNISWAP_REGISTRY[getNetwork()];
|
|
384
405
|
}
|
|
406
|
+
function INFRA() {
|
|
407
|
+
return INFRA_REGISTRY[getNetwork()];
|
|
408
|
+
}
|
|
385
409
|
function ENS() {
|
|
386
410
|
return ENS_REGISTRY[getNetwork()];
|
|
387
411
|
}
|
|
@@ -417,6 +441,7 @@ export {
|
|
|
417
441
|
TOKENS,
|
|
418
442
|
MOONWELL,
|
|
419
443
|
UNISWAP,
|
|
444
|
+
INFRA,
|
|
420
445
|
ENS,
|
|
421
446
|
AGENT_REGISTRY,
|
|
422
447
|
VENICE,
|
|
@@ -428,4 +453,4 @@ export {
|
|
|
428
453
|
SYNTHRA,
|
|
429
454
|
CHAINLINK
|
|
430
455
|
};
|
|
431
|
-
//# sourceMappingURL=chunk-
|
|
456
|
+
//# sourceMappingURL=chunk-WQOTLKVP.js.map
|