@sherwoodagent/cli 0.38.5 → 0.40.3
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/abis-TXCLIR2K.js +37 -0
- package/dist/{addresses-5BITNIGX.js → addresses-VTKWQ6GP.js} +2 -2
- package/dist/{agent-TB7VNLFH.js → agent-XBYSALOA.js} +1433 -662
- package/dist/agent-XBYSALOA.js.map +1 -0
- package/dist/{chat-CLBWW7PV.js → chat-6AOTDMSN.js} +30 -13
- package/dist/chat-6AOTDMSN.js.map +1 -0
- package/dist/{chunk-QZSKBYZ2.js → chunk-6VGC2MGU.js} +5 -5
- package/dist/{chunk-B4AH26UI.js → chunk-DNX3P5YK.js} +150 -15
- package/dist/chunk-DNX3P5YK.js.map +1 -0
- package/dist/{chunk-OPEVMNEY.js → chunk-DZSGUCUE.js} +5 -5
- package/dist/{chunk-PHU6MI3J.js → chunk-MIOZZVZJ.js} +5 -5
- package/dist/{chunk-IQNYBIFE.js → chunk-Q32OZRVA.js} +8 -8
- package/dist/{chunk-OQUGUIYM.js → chunk-W3GXAODE.js} +111 -2
- package/dist/{chunk-OQUGUIYM.js.map → chunk-W3GXAODE.js.map} +1 -1
- package/dist/{chunk-RFTJBEZI.js → chunk-X476EPJ2.js} +2 -2
- package/dist/{chunk-RFTJBEZI.js.map → chunk-X476EPJ2.js.map} +1 -1
- package/dist/{chunk-JQBGEYAK.js → chunk-ZE5ASZ7I.js} +5 -5
- package/dist/{eas-LVJEPWBY.js → eas-YOLDR2NC.js} +4 -4
- package/dist/{governor-HU3CPXMU.js → governor-QVUB5CNY.js} +4 -4
- package/dist/index.js +33 -33
- package/dist/{price-OZRLJH3X.js → price-GBLGHUMR.js} +5 -5
- package/dist/{research-662HNMOG.js → research-4UA4UB5P.js} +2 -2
- package/dist/research-4UA4UB5P.js.map +1 -0
- package/dist/{research-5WEM4WZC.js → research-6DYGOVW4.js} +4 -4
- package/dist/{session-XRTKPC4Q.js → session-GHQNP6UI.js} +11 -11
- package/dist/{trade-HN4BXDVU.js → trade-OLAZMKOH.js} +10 -10
- package/dist/{xmtp-25RHTLIA.js → xmtp-EFWFSYIQ.js} +4 -4
- package/package.json +1 -1
- package/dist/agent-TB7VNLFH.js.map +0 -1
- package/dist/chat-CLBWW7PV.js.map +0 -1
- package/dist/chunk-B4AH26UI.js.map +0 -1
- /package/dist/{addresses-5BITNIGX.js.map → abis-TXCLIR2K.js.map} +0 -0
- /package/dist/{eas-LVJEPWBY.js.map → addresses-VTKWQ6GP.js.map} +0 -0
- /package/dist/{chunk-QZSKBYZ2.js.map → chunk-6VGC2MGU.js.map} +0 -0
- /package/dist/{chunk-OPEVMNEY.js.map → chunk-DZSGUCUE.js.map} +0 -0
- /package/dist/{chunk-PHU6MI3J.js.map → chunk-MIOZZVZJ.js.map} +0 -0
- /package/dist/{chunk-IQNYBIFE.js.map → chunk-Q32OZRVA.js.map} +0 -0
- /package/dist/{chunk-JQBGEYAK.js.map → chunk-ZE5ASZ7I.js.map} +0 -0
- /package/dist/{governor-HU3CPXMU.js.map → eas-YOLDR2NC.js.map} +0 -0
- /package/dist/{research-662HNMOG.js.map → governor-QVUB5CNY.js.map} +0 -0
- /package/dist/{price-OZRLJH3X.js.map → price-GBLGHUMR.js.map} +0 -0
- /package/dist/{research-5WEM4WZC.js.map → research-6DYGOVW4.js.map} +0 -0
- /package/dist/{session-XRTKPC4Q.js.map → session-GHQNP6UI.js.map} +0 -0
- /package/dist/{trade-HN4BXDVU.js.map → trade-OLAZMKOH.js.map} +0 -0
- /package/dist/{xmtp-25RHTLIA.js.map → xmtp-EFWFSYIQ.js.map} +0 -0
|
@@ -1,20 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getSyndicate,
|
|
3
3
|
updateMetadata
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-DZSGUCUE.js";
|
|
5
5
|
import {
|
|
6
6
|
getTextRecord,
|
|
7
7
|
resolveSyndicate,
|
|
8
8
|
setTextRecord
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import {
|
|
11
|
-
fetchMetadata,
|
|
12
|
-
uploadMetadata
|
|
13
|
-
} from "./chunk-2H6IGGKN.js";
|
|
14
|
-
import "./chunk-OQUGUIYM.js";
|
|
9
|
+
} from "./chunk-Q32OZRVA.js";
|
|
15
10
|
import {
|
|
16
11
|
ENS
|
|
17
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-X476EPJ2.js";
|
|
18
13
|
import {
|
|
19
14
|
formatContractError,
|
|
20
15
|
getAccount
|
|
@@ -24,12 +19,17 @@ import {
|
|
|
24
19
|
cacheGroupId,
|
|
25
20
|
getCachedGroupId
|
|
26
21
|
} from "./chunk-WCBG44IQ.js";
|
|
22
|
+
import "./chunk-W3GXAODE.js";
|
|
23
|
+
import {
|
|
24
|
+
fetchMetadata,
|
|
25
|
+
uploadMetadata
|
|
26
|
+
} from "./chunk-2H6IGGKN.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-EFWFSYIQ.js");
|
|
33
33
|
}
|
|
34
34
|
function formatTimestamp(date) {
|
|
35
35
|
return `${date.getHours().toString().padStart(2, "0")}:${date.getMinutes().toString().padStart(2, "0")}`;
|
|
@@ -121,6 +121,13 @@ async function handleStream(name) {
|
|
|
121
121
|
process.exit(1);
|
|
122
122
|
}
|
|
123
123
|
}
|
|
124
|
+
async function readStdin() {
|
|
125
|
+
const chunks = [];
|
|
126
|
+
for await (const chunk of process.stdin) {
|
|
127
|
+
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
128
|
+
}
|
|
129
|
+
return Buffer.concat(chunks).toString("utf-8");
|
|
130
|
+
}
|
|
124
131
|
async function handleSend(name, message, markdown) {
|
|
125
132
|
const spinner = ora("Sending...").start();
|
|
126
133
|
try {
|
|
@@ -345,12 +352,22 @@ async function handleInit(name, force, isPublic) {
|
|
|
345
352
|
}
|
|
346
353
|
}
|
|
347
354
|
function registerChatCommands(program) {
|
|
348
|
-
program.command("chat <name> [action] [actionArgs...]").description("Syndicate chat \u2014 stream, send, log, members, add, remove, init, public").option("--markdown", "Send as rich markdown (for send)", 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).action(async (name, action, actionArgs, opts) => {
|
|
355
|
+
program.command("chat <name> [action] [actionArgs...]").description("Syndicate 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).action(async (name, action, actionArgs, opts) => {
|
|
349
356
|
switch (action) {
|
|
350
357
|
case "send": {
|
|
351
|
-
|
|
358
|
+
let message = actionArgs[0];
|
|
359
|
+
if (opts.stdin) {
|
|
360
|
+
if (process.stdin.isTTY) {
|
|
361
|
+
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."));
|
|
362
|
+
}
|
|
363
|
+
message = await readStdin();
|
|
364
|
+
if (!message.trim()) {
|
|
365
|
+
console.error(chalk.red("--stdin given but stdin was empty"));
|
|
366
|
+
process.exit(1);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
352
369
|
if (!message) {
|
|
353
|
-
console.error(chalk.red(
|
|
370
|
+
console.error(chalk.red('Usage: sherwood chat <name> send <message> [--markdown]\n echo "$msg" | sherwood chat <name> send --stdin'));
|
|
354
371
|
process.exit(1);
|
|
355
372
|
}
|
|
356
373
|
await handleSend(name, message, opts.markdown);
|
|
@@ -411,4 +428,4 @@ function registerChatCommands(program) {
|
|
|
411
428
|
export {
|
|
412
429
|
registerChatCommands
|
|
413
430
|
};
|
|
414
|
-
//# sourceMappingURL=chat-
|
|
431
|
+
//# sourceMappingURL=chat-6AOTDMSN.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\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 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(\"--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 .action(async (name: string, action: string | undefined, actionArgs: string[], opts: { markdown: boolean; stdin: boolean; limit: string; force: boolean; public: boolean }) => {\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 \"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,9 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
UNISWAP_QUOTER_V2_ABI
|
|
3
|
-
} from "./chunk-OQUGUIYM.js";
|
|
4
1
|
import {
|
|
5
2
|
UNISWAP
|
|
6
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-X476EPJ2.js";
|
|
7
4
|
import {
|
|
8
5
|
getAccount,
|
|
9
6
|
getPublicClient,
|
|
@@ -18,6 +15,9 @@ import {
|
|
|
18
15
|
getVeniceApiKey,
|
|
19
16
|
setVeniceApiKey
|
|
20
17
|
} from "./chunk-WCBG44IQ.js";
|
|
18
|
+
import {
|
|
19
|
+
UNISWAP_QUOTER_V2_ABI
|
|
20
|
+
} from "./chunk-W3GXAODE.js";
|
|
21
21
|
|
|
22
22
|
// src/providers/uniswap.ts
|
|
23
23
|
import { isAddress } from "viem";
|
|
@@ -451,4 +451,4 @@ export {
|
|
|
451
451
|
encodeSwapPath,
|
|
452
452
|
getMultiHopQuote
|
|
453
453
|
};
|
|
454
|
-
//# sourceMappingURL=chunk-
|
|
454
|
+
//# sourceMappingURL=chunk-6VGC2MGU.js.map
|
|
@@ -17,6 +17,45 @@ async function getX402Fetch() {
|
|
|
17
17
|
_x402Fetch = wrapFetchWithPayment(fetch, client);
|
|
18
18
|
return _x402Fetch;
|
|
19
19
|
}
|
|
20
|
+
var BASE_USDC_ADDRESS = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
|
|
21
|
+
var MIN_USDC_BALANCE = 500000n;
|
|
22
|
+
var _balanceCache = null;
|
|
23
|
+
var BALANCE_CACHE_TTL_MS = 6e4;
|
|
24
|
+
async function isX402WalletFunded() {
|
|
25
|
+
if (_balanceCache && Date.now() - _balanceCache.timestamp < BALANCE_CACHE_TTL_MS) {
|
|
26
|
+
return _balanceCache.available;
|
|
27
|
+
}
|
|
28
|
+
try {
|
|
29
|
+
const { createPublicClient, http } = await import("viem");
|
|
30
|
+
const { base: base3 } = await import("viem/chains");
|
|
31
|
+
const account = getAccount();
|
|
32
|
+
const client = createPublicClient({
|
|
33
|
+
chain: base3,
|
|
34
|
+
transport: http("https://base-rpc.publicnode.com")
|
|
35
|
+
});
|
|
36
|
+
const balance = await client.readContract({
|
|
37
|
+
address: BASE_USDC_ADDRESS,
|
|
38
|
+
abi: [
|
|
39
|
+
{
|
|
40
|
+
name: "balanceOf",
|
|
41
|
+
type: "function",
|
|
42
|
+
stateMutability: "view",
|
|
43
|
+
inputs: [{ name: "account", type: "address" }],
|
|
44
|
+
outputs: [{ name: "", type: "uint256" }]
|
|
45
|
+
}
|
|
46
|
+
],
|
|
47
|
+
functionName: "balanceOf",
|
|
48
|
+
args: [account.address]
|
|
49
|
+
});
|
|
50
|
+
const available = balance >= MIN_USDC_BALANCE;
|
|
51
|
+
_balanceCache = { available, timestamp: Date.now() };
|
|
52
|
+
return available;
|
|
53
|
+
} catch (err) {
|
|
54
|
+
console.error(`x402 balance check failed (assuming available): ${err.message}`);
|
|
55
|
+
_balanceCache = { available: true, timestamp: Date.now() };
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
20
59
|
|
|
21
60
|
// src/providers/research/messari.ts
|
|
22
61
|
var BASE_URL = "https://api.messari.io";
|
|
@@ -184,10 +223,30 @@ var MessariProvider = class {
|
|
|
184
223
|
// src/providers/research/nansen.ts
|
|
185
224
|
import { base as base2, baseSepolia as baseSepolia2 } from "viem/chains";
|
|
186
225
|
var BASE_URL2 = "https://api.nansen.ai";
|
|
226
|
+
var _nansenFetch = null;
|
|
227
|
+
var _nansenFetchKey;
|
|
228
|
+
async function getNansenFetch() {
|
|
229
|
+
const apiKey = process.env.NANSEN_API_KEY;
|
|
230
|
+
if (_nansenFetch && _nansenFetchKey === apiKey) return _nansenFetch;
|
|
231
|
+
if (apiKey) {
|
|
232
|
+
const baseFetch = globalThis.fetch;
|
|
233
|
+
_nansenFetch = ((url, init) => {
|
|
234
|
+
const headers = new Headers(init?.headers);
|
|
235
|
+
headers.set("apiKey", apiKey);
|
|
236
|
+
return baseFetch(url, { ...init, headers });
|
|
237
|
+
});
|
|
238
|
+
_nansenFetchKey = apiKey;
|
|
239
|
+
} else {
|
|
240
|
+
_nansenFetch = await getX402Fetch();
|
|
241
|
+
_nansenFetchKey = void 0;
|
|
242
|
+
}
|
|
243
|
+
return _nansenFetch;
|
|
244
|
+
}
|
|
187
245
|
var NANSEN_COST_ESTIMATE = {
|
|
188
246
|
token: "~$0.01",
|
|
189
247
|
market: "~$0.01",
|
|
190
248
|
"smart-money": "~$0.06",
|
|
249
|
+
"hl-perp-trades": "~$0.06",
|
|
191
250
|
wallet: "~$0.01"
|
|
192
251
|
};
|
|
193
252
|
var NansenProvider = class {
|
|
@@ -224,7 +283,7 @@ var NansenProvider = class {
|
|
|
224
283
|
* Cost: ~$0.01 (basic tier)
|
|
225
284
|
*/
|
|
226
285
|
async tokenScreener(target) {
|
|
227
|
-
const fetchWithPay = await
|
|
286
|
+
const fetchWithPay = await getNansenFetch();
|
|
228
287
|
const isAddr = target.startsWith("0x") && target.length === 42;
|
|
229
288
|
const filters = isAddr ? { token_address: [target] } : { token_symbol: [target.toUpperCase()] };
|
|
230
289
|
const body = {
|
|
@@ -260,7 +319,7 @@ var NansenProvider = class {
|
|
|
260
319
|
* Cost: ~$0.01 (basic tier)
|
|
261
320
|
*/
|
|
262
321
|
async marketScreener(asset) {
|
|
263
|
-
const fetchWithPay = await
|
|
322
|
+
const fetchWithPay = await getNansenFetch();
|
|
264
323
|
const isAddr = asset.startsWith("0x") && asset.length === 42;
|
|
265
324
|
const filters = isAddr ? { token_address: [asset] } : { token_symbol: [asset.toUpperCase()] };
|
|
266
325
|
const body = {
|
|
@@ -294,21 +353,54 @@ var NansenProvider = class {
|
|
|
294
353
|
/**
|
|
295
354
|
* Smart Money Net Flow — capital flow analysis from labeled wallets.
|
|
296
355
|
* Endpoint: POST /api/v1/smart-money/netflow
|
|
297
|
-
* Cost: ~$0.
|
|
356
|
+
* Cost: ~$0.06 (premium tier)
|
|
357
|
+
*
|
|
358
|
+
* Queries across all major chains (ethereum, solana, base, arbitrum, etc.)
|
|
359
|
+
* using the token's symbol for filtering. Previously hardcoded to ["base"]
|
|
360
|
+
* which returned empty flows for BTC/ETH/SOL — those tokens don't
|
|
361
|
+
* meaningfully trade on Base.
|
|
298
362
|
*
|
|
299
|
-
*
|
|
300
|
-
*
|
|
363
|
+
* Response includes net_flow_1h/24h/7d/30d in USD per token+chain,
|
|
364
|
+
* plus trader_count (active smart money wallets in 30d window).
|
|
301
365
|
*/
|
|
302
366
|
async smartMoneyNetflow(target) {
|
|
303
|
-
const fetchWithPay = await
|
|
304
|
-
const
|
|
367
|
+
const fetchWithPay = await getNansenFetch();
|
|
368
|
+
const symbolMap = {
|
|
369
|
+
bitcoin: "BTC",
|
|
370
|
+
ethereum: "ETH",
|
|
371
|
+
solana: "SOL",
|
|
372
|
+
arbitrum: "ARB",
|
|
373
|
+
aave: "AAVE",
|
|
374
|
+
uniswap: "UNI",
|
|
375
|
+
chainlink: "LINK",
|
|
376
|
+
dogecoin: "DOGE",
|
|
377
|
+
ripple: "XRP",
|
|
378
|
+
polkadot: "DOT",
|
|
379
|
+
avalanche: "AVAX",
|
|
380
|
+
near: "NEAR",
|
|
381
|
+
sui: "SUI",
|
|
382
|
+
aptos: "APT",
|
|
383
|
+
hyperliquid: "HYPE",
|
|
384
|
+
worldcoin: "WLD",
|
|
385
|
+
"worldcoin-wld": "WLD",
|
|
386
|
+
bittensor: "TAO",
|
|
387
|
+
zcash: "ZEC",
|
|
388
|
+
fartcoin: "FARTCOIN",
|
|
389
|
+
pepe: "PEPE",
|
|
390
|
+
pendle: "PENDLE",
|
|
391
|
+
jupiter: "JUP"
|
|
392
|
+
};
|
|
393
|
+
const symbol = symbolMap[target.toLowerCase()] ?? target.toUpperCase();
|
|
305
394
|
const body = {
|
|
306
|
-
chains
|
|
307
|
-
|
|
395
|
+
// Query all supported smart-money chains — the API returns per-chain
|
|
396
|
+
// rows so we get flows across ethereum, solana, base, L2s, etc.
|
|
397
|
+
chains: ["ethereum", "solana", "base", "arbitrum", "optimism", "polygon", "avalanche", "bnb"],
|
|
398
|
+
filters: {
|
|
399
|
+
token_symbol: [symbol]
|
|
400
|
+
},
|
|
401
|
+
order_by: [{ field: "net_flow_24h_usd", direction: "DESC" }],
|
|
402
|
+
pagination: { page: 1, per_page: 10 }
|
|
308
403
|
};
|
|
309
|
-
if (tokenAddress) {
|
|
310
|
-
body.filters = { token_address: [tokenAddress] };
|
|
311
|
-
}
|
|
312
404
|
const res = await fetchWithPay(`${BASE_URL2}/api/v1/smart-money/netflow`, {
|
|
313
405
|
method: "POST",
|
|
314
406
|
headers: { "Content-Type": "application/json" },
|
|
@@ -330,6 +422,48 @@ var NansenProvider = class {
|
|
|
330
422
|
timestamp: Math.floor(Date.now() / 1e3)
|
|
331
423
|
};
|
|
332
424
|
}
|
|
425
|
+
/**
|
|
426
|
+
* Hyperliquid Smart Money Perp Trades — what smart wallets are trading
|
|
427
|
+
* on Hyperliquid perps right now.
|
|
428
|
+
* Endpoint: POST /api/v1/smart-money/perp-trades
|
|
429
|
+
* Cost: ~$0.06 (premium tier, estimated)
|
|
430
|
+
*
|
|
431
|
+
* Returns granular trade data: direction (Long/Short), size, price, action
|
|
432
|
+
* (Buy - Add Long, Sell - Open Short, etc.), trader labels (Fund, Smart Trader).
|
|
433
|
+
* Directly relevant — same venue + instrument we trade.
|
|
434
|
+
*/
|
|
435
|
+
async queryHyperliquidSmartMoney(tokenSymbol) {
|
|
436
|
+
const fetchWithPay = await getNansenFetch();
|
|
437
|
+
const body = {
|
|
438
|
+
filters: {
|
|
439
|
+
include_smart_money_labels: ["Fund", "Smart Trader", "Smart HL Perps Trader"],
|
|
440
|
+
token_symbol: tokenSymbol,
|
|
441
|
+
value_usd: { min: 5e4 }
|
|
442
|
+
// only meaningful-size trades
|
|
443
|
+
},
|
|
444
|
+
only_new_positions: false,
|
|
445
|
+
pagination: { page: 1, per_page: 20 },
|
|
446
|
+
order_by: [{ field: "block_timestamp", direction: "DESC" }]
|
|
447
|
+
};
|
|
448
|
+
const res = await fetchWithPay(`${BASE_URL2}/api/v1/smart-money/perp-trades`, {
|
|
449
|
+
method: "POST",
|
|
450
|
+
headers: { "Content-Type": "application/json" },
|
|
451
|
+
body: JSON.stringify(body)
|
|
452
|
+
});
|
|
453
|
+
if (!res.ok) {
|
|
454
|
+
throw new Error(`Nansen HL perp-trades query failed: ${res.status} ${res.statusText}`);
|
|
455
|
+
}
|
|
456
|
+
const json = await res.json();
|
|
457
|
+
const costUsdc = this.extractCost(res, "smart-money");
|
|
458
|
+
return {
|
|
459
|
+
provider: "nansen",
|
|
460
|
+
queryType: "hl-perp-trades",
|
|
461
|
+
target: tokenSymbol,
|
|
462
|
+
data: { trades: json.data ?? [], count: (json.data ?? []).length },
|
|
463
|
+
costUsdc,
|
|
464
|
+
timestamp: Math.floor(Date.now() / 1e3)
|
|
465
|
+
};
|
|
466
|
+
}
|
|
333
467
|
/**
|
|
334
468
|
* Wallet Profile — PnL summary, realized/unrealized gains, token breakdown.
|
|
335
469
|
* Endpoint: POST /api/v1/profiler/address/pnl-summary
|
|
@@ -339,7 +473,7 @@ var NansenProvider = class {
|
|
|
339
473
|
* The correct x402 endpoint is /api/v1/profiler/address/pnl-summary.
|
|
340
474
|
*/
|
|
341
475
|
async walletProfile(address) {
|
|
342
|
-
const fetchWithPay = await
|
|
476
|
+
const fetchWithPay = await getNansenFetch();
|
|
343
477
|
const now = /* @__PURE__ */ new Date();
|
|
344
478
|
const thirtyDaysAgo = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1e3);
|
|
345
479
|
const body = {
|
|
@@ -380,7 +514,7 @@ var NansenProvider = class {
|
|
|
380
514
|
if (target.startsWith("0x") && target.length === 42) {
|
|
381
515
|
return target;
|
|
382
516
|
}
|
|
383
|
-
const fetchWithPay = await
|
|
517
|
+
const fetchWithPay = await getNansenFetch();
|
|
384
518
|
const body = {
|
|
385
519
|
chains: ["base"],
|
|
386
520
|
timeframe: "24h",
|
|
@@ -439,10 +573,11 @@ function getResearchProvider(name) {
|
|
|
439
573
|
}
|
|
440
574
|
|
|
441
575
|
export {
|
|
576
|
+
isX402WalletFunded,
|
|
442
577
|
MESSARI_COST_ESTIMATE,
|
|
443
578
|
MessariProvider,
|
|
444
579
|
NANSEN_COST_ESTIMATE,
|
|
445
580
|
NansenProvider,
|
|
446
581
|
getResearchProvider
|
|
447
582
|
};
|
|
448
|
-
//# sourceMappingURL=chunk-
|
|
583
|
+
//# sourceMappingURL=chunk-DNX3P5YK.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/providers/research/messari.ts","../src/lib/x402.ts","../src/providers/research/nansen.ts","../src/providers/research/index.ts"],"sourcesContent":["/**\n * Messari research provider — x402 micropayments for crypto market data.\n *\n * Docs: https://docs.messari.io\n * Payment: x402 (USDC on Base) — no API key required\n * Data: 34,000+ assets, market metrics, asset profiles\n * Pricing: $0.10/call for asset details, ROI, ATH. $0.15–$0.35 for timeseries.\n * $0.55 for news/signals. Full pricing: https://docs.messari.io/api-reference/x402-payments\n *\n * Supports:\n * token → asset details (description, category, sector, links, market snapshot)\n * market → market metrics + ATH (price, volume, market cap, ROI, ATH, cycle low)\n *\n * Not supported (use --provider nansen instead):\n * smart-money → on-chain analytics not available in Messari x402 API\n * wallet → wallet profiling not available in Messari x402 API\n */\n\nimport { base, baseSepolia } from \"viem/chains\";\nimport type { ProviderInfo } from \"../../types.js\";\nimport type { ResearchProvider, ResearchQuery, ResearchResult } from \"./index.js\";\nimport { getX402Fetch } from \"../../lib/x402.js\";\n\nconst BASE_URL = \"https://api.messari.io\";\n\n/** Known x402 cost per Messari query (approximate). */\nexport const MESSARI_COST_ESTIMATE: Record<string, string> = {\n token: \"~$0.10\",\n market: \"~$0.20\",\n};\n\nexport class MessariProvider implements ResearchProvider {\n info(): ProviderInfo {\n return {\n name: \"messari\",\n type: \"research\",\n capabilities: [\n \"research.token\",\n \"research.market\",\n ],\n supportedChains: [base, baseSepolia],\n };\n }\n\n async query(params: ResearchQuery): Promise<ResearchResult> {\n switch (params.type) {\n case \"token\":\n return this.tokenReport(params.target);\n case \"market\":\n return this.marketOverview(params.target);\n case \"smart-money\":\n throw new Error(\n \"Messari x402 API does not support on-chain analytics. Use --provider nansen for smart money data.\",\n );\n case \"wallet\":\n throw new Error(\n \"Messari does not support wallet analytics. Use --provider nansen for wallet profiling.\",\n );\n default:\n throw new Error(`Unsupported query type: ${params.type}`);\n }\n }\n\n /**\n * Resolve any user input (symbol, name, slug, address) to a Messari asset slug.\n * Uses the free /metrics/v2/assets endpoint ($0.00) to search.\n */\n private async resolveSlug(target: string): Promise<string> {\n const fetchWithPay = await getX402Fetch();\n const params = new URLSearchParams({\n search: target,\n limit: \"1\",\n });\n const url = `${BASE_URL}/metrics/v2/assets?${params}`;\n\n const res = await fetchWithPay(url, { method: \"GET\" });\n if (!res.ok) {\n throw new Error(\n `Messari asset lookup failed: ${res.status} ${res.statusText}`,\n );\n }\n\n const json = (await res.json()) as {\n data?: Array<{ slug?: string }>;\n };\n\n const slug = json.data?.[0]?.slug;\n if (!slug) {\n throw new Error(\n `No Messari asset found for \"${target}\". Try a different name, symbol, or slug.`,\n );\n }\n return slug;\n }\n\n /**\n * Get asset details: description, category, sector, links, market snapshot.\n * Endpoint: GET /metrics/v2/assets/details?assetIDs={slug} ($0.10)\n */\n private async tokenReport(target: string): Promise<ResearchResult> {\n const slug = await this.resolveSlug(target);\n const fetchWithPay = await getX402Fetch();\n const url = `${BASE_URL}/metrics/v2/assets/details?assetIDs=${encodeURIComponent(slug)}`;\n\n const res = await fetchWithPay(url, { method: \"GET\" });\n if (!res.ok) {\n throw new Error(\n `Messari token query failed: ${res.status} ${res.statusText}`,\n );\n }\n\n const json = (await res.json()) as {\n data?: Array<Record<string, unknown>>;\n };\n const costUsdc = this.extractCost(res, \"token\");\n const asset = json.data?.[0] ?? {};\n\n return {\n provider: \"messari\",\n queryType: \"token\",\n target,\n data: asset,\n costUsdc,\n timestamp: Math.floor(Date.now() / 1000),\n };\n }\n\n /**\n * Get market metrics + ATH: price, volume, market cap, ROI, all-time high, cycle low.\n * Makes two parallel calls:\n * GET /metrics/v2/assets/details?assetIDs={slug} ($0.10)\n * GET /metrics/v2/assets/ath?assetIDs={slug} ($0.10)\n * Total: ~$0.20\n */\n private async marketOverview(target: string): Promise<ResearchResult> {\n const slug = await this.resolveSlug(target);\n const fetchWithPay = await getX402Fetch();\n const assetParam = encodeURIComponent(slug);\n\n const [detailsRes, athRes] = await Promise.all([\n fetchWithPay(`${BASE_URL}/metrics/v2/assets/details?assetIDs=${assetParam}`, { method: \"GET\" }),\n fetchWithPay(`${BASE_URL}/metrics/v2/assets/ath?assetIDs=${assetParam}`, { method: \"GET\" }),\n ]);\n\n if (!detailsRes.ok) {\n throw new Error(\n `Messari market query failed: ${detailsRes.status} ${detailsRes.statusText}`,\n );\n }\n if (!athRes.ok) {\n throw new Error(\n `Messari ATH query failed: ${athRes.status} ${athRes.statusText}`,\n );\n }\n\n const detailsJson = (await detailsRes.json()) as {\n data?: Array<Record<string, unknown>>;\n };\n const athJson = (await athRes.json()) as {\n data?: Array<Record<string, unknown>>;\n };\n\n // Sum costs from both responses\n const cost1 = this.extractCostRaw(detailsRes);\n const cost2 = this.extractCostRaw(athRes);\n const totalCost = cost1 + cost2;\n const costUsdc = totalCost > 0\n ? totalCost.toFixed(4)\n : MESSARI_COST_ESTIMATE[\"market\"]?.replace(\"~$\", \"\") ?? \"unknown\";\n\n const details = detailsJson.data?.[0] ?? {};\n const ath = athJson.data?.[0] ?? {};\n\n return {\n provider: \"messari\",\n queryType: \"market\",\n target,\n data: {\n ...details,\n allTimeHigh: ath.allTimeHigh ?? null,\n },\n costUsdc,\n timestamp: Math.floor(Date.now() / 1000),\n };\n }\n\n /**\n * Extract cost from x402 response headers as a number (USDC).\n * Returns 0 if no payment info found.\n */\n private extractCostRaw(res: Response): number {\n const paymentResponse = res.headers.get(\"payment-response\");\n if (paymentResponse) {\n try {\n const parsed = JSON.parse(paymentResponse) as { amount?: string };\n if (parsed.amount) {\n return Number(parsed.amount) / 1e6;\n }\n } catch {\n // Fall through\n }\n }\n return 0;\n }\n\n /**\n * Extract cost from x402 response headers as a formatted string.\n * Falls back to the known estimate for the query type when headers are absent.\n */\n private extractCost(res: Response, queryType: string = \"token\"): string {\n const cost = this.extractCostRaw(res);\n if (cost > 0) return cost.toFixed(4);\n\n // Fall back to known estimate (strip \"~$\" prefix)\n const est = MESSARI_COST_ESTIMATE[queryType];\n if (est) return est.replace(\"~$\", \"\");\n\n return \"unknown\";\n }\n}\n","/**\n * x402 fetch wrapper — wraps native fetch with automatic USDC micropayments.\n *\n * Uses the Coinbase x402 protocol: when a server responds 402 Payment Required,\n * the wrapper automatically signs a USDC payment on Base and retries the request.\n * The agent pays from its own wallet — no vault interaction needed.\n *\n * Singleton pattern matching client.ts — cached after first creation.\n */\n\nimport { getAccount } from \"./client.js\";\n\nlet _x402Fetch: typeof fetch | null = null;\n\n/**\n * Returns a fetch function that automatically handles x402 (402 Payment Required)\n * responses by signing USDC micropayments on Base.\n *\n * Lazily initializes the x402 client on first call and caches it.\n * Uses dynamic imports so @x402 packages are only loaded when research commands run.\n */\nexport async function getX402Fetch(): Promise<typeof fetch> {\n if (_x402Fetch) return _x402Fetch;\n\n const { x402Client, wrapFetchWithPayment } = await import(\"@x402/fetch\");\n const { registerExactEvmScheme } = await import(\"@x402/evm/exact/client\");\n\n const signer = getAccount();\n const client = new x402Client();\n registerExactEvmScheme(client, { signer });\n\n _x402Fetch = wrapFetchWithPayment(fetch, client) as typeof fetch;\n return _x402Fetch;\n}\n\n/**\n * Reset cached x402 fetch. Required for tests that change accounts.\n */\nexport function resetX402Fetch(): void {\n _x402Fetch = null;\n}\n\n// ── x402 USDC balance check ──\n\n/** USDC on Base mainnet. */\nconst BASE_USDC_ADDRESS = \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\" as const;\n\n/** Minimum USDC balance (in 6-decimal units) to consider x402 available. $0.50 */\nconst MIN_USDC_BALANCE = 500_000n; // 0.50 USDC (6 decimals)\n\n/** Cache: { balance, timestamp }. Refreshed at most once per scan cycle. */\nlet _balanceCache: { available: boolean; timestamp: number } | null = null;\nconst BALANCE_CACHE_TTL_MS = 60_000; // 1 minute — covers a full scan cycle\n\n/**\n * Check whether the cron wallet has enough USDC on Base to pay for x402 requests.\n * Result is cached for 60s so we only make one RPC call per scan cycle.\n * On RPC error, returns true (assume available — don't break scoring).\n */\nexport async function isX402WalletFunded(): Promise<boolean> {\n // Return cached result if fresh\n if (_balanceCache && Date.now() - _balanceCache.timestamp < BALANCE_CACHE_TTL_MS) {\n return _balanceCache.available;\n }\n\n try {\n const { createPublicClient, http } = await import(\"viem\");\n const { base } = await import(\"viem/chains\");\n\n const account = getAccount();\n const client = createPublicClient({\n chain: base,\n transport: http(\"https://base-rpc.publicnode.com\"),\n });\n\n // ERC-20 balanceOf(address) — minimal ABI\n const balance = await client.readContract({\n address: BASE_USDC_ADDRESS,\n abi: [\n {\n name: \"balanceOf\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [{ name: \"account\", type: \"address\" }],\n outputs: [{ name: \"\", type: \"uint256\" }],\n },\n ] as const,\n functionName: \"balanceOf\",\n args: [account.address],\n });\n\n const available = (balance as bigint) >= MIN_USDC_BALANCE;\n _balanceCache = { available, timestamp: Date.now() };\n return available;\n } catch (err) {\n // RPC failure — assume funded so we don't break scoring\n console.error(`x402 balance check failed (assuming available): ${(err as Error).message}`);\n _balanceCache = { available: true, timestamp: Date.now() };\n return true;\n }\n}\n\n/** Reset balance cache — for tests. */\nexport function resetBalanceCache(): void {\n _balanceCache = null;\n}\n","/**\n * Nansen research provider — supports both API key auth (Pro subscription,\n * ~5× cheaper) and x402 micropayments (pay-per-request, no subscription).\n *\n * Auth priority:\n * 1. NANSEN_API_KEY env var → standard fetch with apiKey header (Pro plan)\n * 2. x402 fetch wrapper → automatic USDC micropayments on Base\n *\n * Docs: https://docs.nansen.ai\n * Pro pricing: 5 credits/call for Smart Money endpoints (~$0.005/call)\n * x402 pricing: ~$0.06/call for Smart Money endpoints\n *\n * Supports all query types:\n * token → token screener (on-chain metrics, holder quality)\n * market → token screener sorted by market cap / volume\n * smart-money → smart money net flow from labeled wallets\n * hl-perp-trades → Hyperliquid smart-money perp trades\n * wallet → wallet profiler (PnL, tx patterns, counterparties)\n */\n\nimport { base, baseSepolia } from \"viem/chains\";\nimport type { ProviderInfo } from \"../../types.js\";\nimport type { ResearchProvider, ResearchQuery, ResearchResult } from \"./index.js\";\nimport { getX402Fetch } from \"../../lib/x402.js\";\n\nconst BASE_URL = \"https://api.nansen.ai\";\n\n/**\n * Returns a fetch function configured for Nansen auth. Cached after first\n * creation — same pattern as getX402Fetch() to avoid allocating a new\n * closure on every call.\n *\n * If NANSEN_API_KEY is set → standard fetch with apiKey header (Pro plan).\n * Otherwise → x402 micropayment fetch.\n */\nlet _nansenFetch: typeof fetch | null = null;\nlet _nansenFetchKey: string | undefined;\n\nasync function getNansenFetch(): Promise<typeof fetch> {\n const apiKey = process.env.NANSEN_API_KEY;\n\n // Cache hit — return if key hasn't changed\n if (_nansenFetch && _nansenFetchKey === apiKey) return _nansenFetch;\n\n if (apiKey) {\n const baseFetch = globalThis.fetch;\n _nansenFetch = ((url: string | URL | Request, init?: RequestInit) => {\n const headers = new Headers(init?.headers);\n headers.set(\"apiKey\", apiKey);\n return baseFetch(url, { ...init, headers });\n }) as typeof fetch;\n _nansenFetchKey = apiKey;\n } else {\n _nansenFetch = await getX402Fetch();\n _nansenFetchKey = undefined;\n }\n\n return _nansenFetch;\n}\n\n/** Known x402 cost per Nansen query type. */\nexport const NANSEN_COST_ESTIMATE: Record<string, string> = {\n token: \"~$0.01\",\n market: \"~$0.01\",\n \"smart-money\": \"~$0.06\",\n \"hl-perp-trades\": \"~$0.06\",\n wallet: \"~$0.01\",\n};\n\nexport class NansenProvider implements ResearchProvider {\n info(): ProviderInfo {\n return {\n name: \"nansen\",\n type: \"research\",\n capabilities: [\n \"research.token\",\n \"research.market\",\n \"research.smart-money\",\n \"research.wallet\",\n ],\n supportedChains: [base, baseSepolia],\n };\n }\n\n async query(params: ResearchQuery): Promise<ResearchResult> {\n switch (params.type) {\n case \"token\":\n return this.tokenScreener(params.target);\n case \"market\":\n return this.marketScreener(params.target);\n case \"smart-money\":\n return this.smartMoneyNetflow(params.options?.token ?? params.target);\n case \"wallet\":\n return this.walletProfile(params.target);\n default:\n throw new Error(`Unsupported query type: ${params.type}`);\n }\n }\n\n /**\n * Token Screener — comprehensive token discovery with on-chain metrics.\n * Endpoint: POST /api/v1/token-screener\n * Cost: ~$0.01 (basic tier)\n */\n private async tokenScreener(target: string): Promise<ResearchResult> {\n const fetchWithPay = await getNansenFetch();\n\n // Determine if target is an address or symbol\n const isAddr = target.startsWith(\"0x\") && target.length === 42;\n const filters: Record<string, unknown> = isAddr\n ? { token_address: [target] }\n : { token_symbol: [target.toUpperCase()] };\n\n const body = {\n chains: [\"base\"],\n timeframe: \"24h\",\n filters,\n pagination: { page: 1, records_per_page: 10 },\n };\n\n const res = await fetchWithPay(`${BASE_URL}/api/v1/token-screener`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n\n if (!res.ok) {\n throw new Error(\n `Nansen token query failed: ${res.status} ${res.statusText}`,\n );\n }\n\n const json = (await res.json()) as { data?: unknown[] };\n const costUsdc = this.extractCost(res, \"token\");\n\n return {\n provider: \"nansen\",\n queryType: \"token\",\n target,\n data: { tokens: json.data ?? [], count: (json.data ?? []).length },\n costUsdc,\n timestamp: Math.floor(Date.now() / 1000),\n };\n }\n\n /**\n * Market Screener — token screener sorted by volume/market cap for market overview.\n * Endpoint: POST /api/v1/token-screener\n * Cost: ~$0.01 (basic tier)\n */\n private async marketScreener(asset: string): Promise<ResearchResult> {\n const fetchWithPay = await getNansenFetch();\n\n const isAddr = asset.startsWith(\"0x\") && asset.length === 42;\n const filters: Record<string, unknown> = isAddr\n ? { token_address: [asset] }\n : { token_symbol: [asset.toUpperCase()] };\n\n const body = {\n chains: [\"base\"],\n timeframe: \"24h\",\n filters,\n order_by: [{ field: \"buy_volume\", direction: \"desc\" }],\n pagination: { page: 1, records_per_page: 10 },\n };\n\n const res = await fetchWithPay(`${BASE_URL}/api/v1/token-screener`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n\n if (!res.ok) {\n throw new Error(\n `Nansen market query failed: ${res.status} ${res.statusText}`,\n );\n }\n\n const json = (await res.json()) as { data?: unknown[] };\n const costUsdc = this.extractCost(res, \"market\");\n\n return {\n provider: \"nansen\",\n queryType: \"market\",\n target: asset,\n data: { tokens: json.data ?? [], count: (json.data ?? []).length },\n costUsdc,\n timestamp: Math.floor(Date.now() / 1000),\n };\n }\n\n /**\n * Smart Money Net Flow — capital flow analysis from labeled wallets.\n * Endpoint: POST /api/v1/smart-money/netflow\n * Cost: ~$0.06 (premium tier)\n *\n * Queries across all major chains (ethereum, solana, base, arbitrum, etc.)\n * using the token's symbol for filtering. Previously hardcoded to [\"base\"]\n * which returned empty flows for BTC/ETH/SOL — those tokens don't\n * meaningfully trade on Base.\n *\n * Response includes net_flow_1h/24h/7d/30d in USD per token+chain,\n * plus trader_count (active smart money wallets in 30d window).\n */\n private async smartMoneyNetflow(\n target: string,\n ): Promise<ResearchResult> {\n const fetchWithPay = await getNansenFetch();\n\n // Map CoinGecko token IDs to symbols for the filter\n const symbolMap: Record<string, string> = {\n bitcoin: \"BTC\", ethereum: \"ETH\", solana: \"SOL\",\n arbitrum: \"ARB\", aave: \"AAVE\", uniswap: \"UNI\",\n chainlink: \"LINK\", dogecoin: \"DOGE\", ripple: \"XRP\",\n polkadot: \"DOT\", avalanche: \"AVAX\", near: \"NEAR\",\n sui: \"SUI\", aptos: \"APT\", hyperliquid: \"HYPE\",\n worldcoin: \"WLD\", \"worldcoin-wld\": \"WLD\",\n bittensor: \"TAO\", zcash: \"ZEC\", fartcoin: \"FARTCOIN\",\n pepe: \"PEPE\", pendle: \"PENDLE\", jupiter: \"JUP\",\n };\n const symbol = symbolMap[target.toLowerCase()] ?? target.toUpperCase();\n\n const body: Record<string, unknown> = {\n // Query all supported smart-money chains — the API returns per-chain\n // rows so we get flows across ethereum, solana, base, L2s, etc.\n chains: [\"ethereum\", \"solana\", \"base\", \"arbitrum\", \"optimism\", \"polygon\", \"avalanche\", \"bnb\"],\n filters: {\n token_symbol: [symbol],\n },\n order_by: [{ field: \"net_flow_24h_usd\", direction: \"DESC\" }],\n pagination: { page: 1, per_page: 10 },\n };\n\n const res = await fetchWithPay(`${BASE_URL}/api/v1/smart-money/netflow`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n\n if (!res.ok) {\n throw new Error(\n `Nansen smart-money query failed: ${res.status} ${res.statusText}`,\n );\n }\n\n const json = (await res.json()) as { data?: unknown[] };\n const costUsdc = this.extractCost(res, \"smart-money\");\n\n return {\n provider: \"nansen\",\n queryType: \"smart-money\",\n target,\n data: { flows: json.data ?? [], count: (json.data ?? []).length },\n costUsdc,\n timestamp: Math.floor(Date.now() / 1000),\n };\n }\n\n /**\n * Hyperliquid Smart Money Perp Trades — what smart wallets are trading\n * on Hyperliquid perps right now.\n * Endpoint: POST /api/v1/smart-money/perp-trades\n * Cost: ~$0.06 (premium tier, estimated)\n *\n * Returns granular trade data: direction (Long/Short), size, price, action\n * (Buy - Add Long, Sell - Open Short, etc.), trader labels (Fund, Smart Trader).\n * Directly relevant — same venue + instrument we trade.\n */\n async queryHyperliquidSmartMoney(\n tokenSymbol: string,\n ): Promise<ResearchResult> {\n const fetchWithPay = await getNansenFetch();\n\n const body = {\n filters: {\n include_smart_money_labels: [\"Fund\", \"Smart Trader\", \"Smart HL Perps Trader\"],\n token_symbol: tokenSymbol,\n value_usd: { min: 50000 }, // only meaningful-size trades\n },\n only_new_positions: false,\n pagination: { page: 1, per_page: 20 },\n order_by: [{ field: \"block_timestamp\", direction: \"DESC\" }],\n };\n\n const res = await fetchWithPay(`${BASE_URL}/api/v1/smart-money/perp-trades`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n\n if (!res.ok) {\n throw new Error(`Nansen HL perp-trades query failed: ${res.status} ${res.statusText}`);\n }\n\n const json = (await res.json()) as { data?: unknown[] };\n const costUsdc = this.extractCost(res, \"smart-money\");\n\n return {\n provider: \"nansen\",\n queryType: \"hl-perp-trades\",\n target: tokenSymbol,\n data: { trades: json.data ?? [], count: (json.data ?? []).length },\n costUsdc,\n timestamp: Math.floor(Date.now() / 1000),\n };\n }\n\n /**\n * Wallet Profile — PnL summary, realized/unrealized gains, token breakdown.\n * Endpoint: POST /api/v1/profiler/address/pnl-summary\n * Cost: ~$0.01 (basic tier)\n *\n * Note: /api/v1/profiler/wallet-pnl requires an API key and does not support x402.\n * The correct x402 endpoint is /api/v1/profiler/address/pnl-summary.\n */\n private async walletProfile(address: string): Promise<ResearchResult> {\n const fetchWithPay = await getNansenFetch();\n\n // pnl-summary uses `chain` (singular) + a date range, not `chains` array\n const now = new Date();\n const thirtyDaysAgo = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000);\n const body = {\n address,\n chain: \"base\",\n date: {\n from: thirtyDaysAgo.toISOString().replace(/\\.\\d{3}Z$/, \"Z\"),\n to: now.toISOString().replace(/\\.\\d{3}Z$/, \"Z\"),\n },\n };\n\n const res = await fetchWithPay(`${BASE_URL}/api/v1/profiler/address/pnl-summary`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n\n if (!res.ok) {\n throw new Error(\n `Nansen wallet query failed: ${res.status} ${res.statusText}`,\n );\n }\n\n const json = (await res.json()) as { data?: Record<string, unknown> };\n const costUsdc = this.extractCost(res, \"wallet\");\n\n return {\n provider: \"nansen\",\n queryType: \"wallet\",\n target: address,\n data: json.data ?? (json as Record<string, unknown>),\n costUsdc,\n timestamp: Math.floor(Date.now() / 1000),\n };\n }\n\n /**\n * Resolve a token symbol or name to its contract address on Base.\n * Uses the token screener endpoint ($0.01) to look up the address.\n * If the target is already an address (0x...), returns it as-is.\n */\n private async resolveTokenAddress(target: string): Promise<string | null> {\n if (target.startsWith(\"0x\") && target.length === 42) {\n return target;\n }\n\n const fetchWithPay = await getNansenFetch();\n const body = {\n chains: [\"base\"],\n timeframe: \"24h\",\n filters: { token_symbol: [target.toUpperCase()] },\n pagination: { page: 1, records_per_page: 1 },\n };\n\n const res = await fetchWithPay(`${BASE_URL}/api/v1/token-screener`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n\n if (!res.ok) return null;\n\n const json = (await res.json()) as {\n data?: Array<{ token_address?: string }>;\n };\n return json.data?.[0]?.token_address ?? null;\n }\n\n /**\n * Extract cost from x402 response headers.\n * Falls back to the known estimate for the query type when headers are absent.\n */\n private extractCost(res: Response, queryType: string): string {\n // Check Nansen-specific credit header\n const creditsUsed = res.headers.get(\"x-nansen-credits-used\");\n if (creditsUsed) {\n return creditsUsed;\n }\n\n // Fall back to x402 payment-response header\n const paymentResponse = res.headers.get(\"payment-response\");\n if (paymentResponse) {\n try {\n const parsed = JSON.parse(paymentResponse) as { amount?: string };\n if (parsed.amount) {\n const cents = Number(parsed.amount) / 1e6;\n return cents.toFixed(4);\n }\n } catch {\n // Fall through\n }\n }\n\n // Fall back to known estimate (strip \"~$\" prefix)\n const est = NANSEN_COST_ESTIMATE[queryType];\n if (est) {\n return est.replace(\"~$\", \"\");\n }\n\n return \"unknown\";\n }\n}\n","/**\n * Research providers — pluggable interface for DeFi research data via x402 micropayments.\n *\n * Same pattern as DeFi providers (Moonwell, Uniswap). Each research provider\n * implements ResearchProvider and uses x402-wrapped fetch for automatic USDC payments.\n */\n\nimport type { Provider } from \"../../types.js\";\nimport { MessariProvider } from \"./messari.js\";\nimport { NansenProvider } from \"./nansen.js\";\n\n// ── Types ──\n\nexport interface ResearchQuery {\n /** Query type determines which API endpoint is called */\n type: \"token\" | \"smart-money\" | \"market\" | \"wallet\";\n /** Token address, asset symbol, or wallet address depending on type */\n target: string;\n /** Additional query params (e.g. token symbol for smart-money queries) */\n options?: Record<string, string>;\n}\n\nexport interface ResearchResult {\n provider: string;\n queryType: string;\n target: string;\n /** Structured response data from the provider */\n data: Record<string, unknown>;\n /** Cost paid in USDC (human-readable, e.g. \"0.05\") */\n costUsdc: string;\n timestamp: number;\n}\n\nexport interface ResearchProvider extends Provider {\n /** Query the research provider. Payment is handled automatically via x402. */\n query(params: ResearchQuery): Promise<ResearchResult>;\n}\n\n// ── Factory ──\n\nexport function getResearchProvider(name: string): ResearchProvider {\n switch (name) {\n case \"messari\":\n return new MessariProvider();\n case \"nansen\":\n return new NansenProvider();\n default:\n throw new Error(\n `Unknown research provider: ${name}. Valid providers: messari, nansen`,\n );\n }\n}\n\n// ── Re-exports ──\n\nexport { MessariProvider, NansenProvider };\n"],"mappings":"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","names":["base","base","baseSepolia","BASE_URL","base","baseSepolia"]}
|
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
SYNDICATE_FACTORY_ABI
|
|
3
|
-
} from "./chunk-OQUGUIYM.js";
|
|
4
1
|
import {
|
|
5
2
|
SHERWOOD
|
|
6
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-X476EPJ2.js";
|
|
7
4
|
import {
|
|
8
5
|
getAccount,
|
|
9
6
|
getPublicClient,
|
|
@@ -13,6 +10,9 @@ import {
|
|
|
13
10
|
import {
|
|
14
11
|
getChain
|
|
15
12
|
} from "./chunk-IJG4CTOI.js";
|
|
13
|
+
import {
|
|
14
|
+
SYNDICATE_FACTORY_ABI
|
|
15
|
+
} from "./chunk-W3GXAODE.js";
|
|
16
16
|
|
|
17
17
|
// src/lib/factory.ts
|
|
18
18
|
import { decodeEventLog } from "viem";
|
|
@@ -139,4 +139,4 @@ export {
|
|
|
139
139
|
getActiveSyndicates,
|
|
140
140
|
updateMetadata
|
|
141
141
|
};
|
|
142
|
-
//# sourceMappingURL=chunk-
|
|
142
|
+
//# sourceMappingURL=chunk-DZSGUCUE.js.map
|
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
SYNDICATE_GOVERNOR_ABI
|
|
3
|
-
} from "./chunk-OQUGUIYM.js";
|
|
4
1
|
import {
|
|
5
2
|
SHERWOOD
|
|
6
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-X476EPJ2.js";
|
|
7
4
|
import {
|
|
8
5
|
getAccount,
|
|
9
6
|
getPublicClient,
|
|
@@ -13,6 +10,9 @@ import {
|
|
|
13
10
|
import {
|
|
14
11
|
getChain
|
|
15
12
|
} from "./chunk-IJG4CTOI.js";
|
|
13
|
+
import {
|
|
14
|
+
SYNDICATE_GOVERNOR_ABI
|
|
15
|
+
} from "./chunk-W3GXAODE.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-MIOZZVZJ.js.map
|
|
@@ -1,14 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ERC20_ABI,
|
|
3
|
-
L2_REGISTRY_ABI,
|
|
4
|
-
SYNDICATE_FACTORY_ABI,
|
|
5
|
-
SYNDICATE_VAULT_ABI
|
|
6
|
-
} from "./chunk-OQUGUIYM.js";
|
|
7
1
|
import {
|
|
8
2
|
ENS,
|
|
9
3
|
SHERWOOD,
|
|
10
4
|
TOKENS
|
|
11
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-X476EPJ2.js";
|
|
12
6
|
import {
|
|
13
7
|
getAccount,
|
|
14
8
|
getPublicClient,
|
|
@@ -22,6 +16,12 @@ import {
|
|
|
22
16
|
import {
|
|
23
17
|
getChainContracts
|
|
24
18
|
} from "./chunk-WCBG44IQ.js";
|
|
19
|
+
import {
|
|
20
|
+
ERC20_ABI,
|
|
21
|
+
L2_REGISTRY_ABI,
|
|
22
|
+
SYNDICATE_FACTORY_ABI,
|
|
23
|
+
SYNDICATE_VAULT_ABI
|
|
24
|
+
} from "./chunk-W3GXAODE.js";
|
|
25
25
|
|
|
26
26
|
// src/lib/vault.ts
|
|
27
27
|
import { formatUnits, parseEther } from "viem";
|
|
@@ -524,4 +524,4 @@ export {
|
|
|
524
524
|
setTextRecord,
|
|
525
525
|
getTextRecord
|
|
526
526
|
};
|
|
527
|
-
//# sourceMappingURL=chunk-
|
|
527
|
+
//# sourceMappingURL=chunk-Q32OZRVA.js.map
|