@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.
Files changed (45) hide show
  1. package/dist/abis-TXCLIR2K.js +37 -0
  2. package/dist/{addresses-5BITNIGX.js → addresses-VTKWQ6GP.js} +2 -2
  3. package/dist/{agent-TB7VNLFH.js → agent-XBYSALOA.js} +1433 -662
  4. package/dist/agent-XBYSALOA.js.map +1 -0
  5. package/dist/{chat-CLBWW7PV.js → chat-6AOTDMSN.js} +30 -13
  6. package/dist/chat-6AOTDMSN.js.map +1 -0
  7. package/dist/{chunk-QZSKBYZ2.js → chunk-6VGC2MGU.js} +5 -5
  8. package/dist/{chunk-B4AH26UI.js → chunk-DNX3P5YK.js} +150 -15
  9. package/dist/chunk-DNX3P5YK.js.map +1 -0
  10. package/dist/{chunk-OPEVMNEY.js → chunk-DZSGUCUE.js} +5 -5
  11. package/dist/{chunk-PHU6MI3J.js → chunk-MIOZZVZJ.js} +5 -5
  12. package/dist/{chunk-IQNYBIFE.js → chunk-Q32OZRVA.js} +8 -8
  13. package/dist/{chunk-OQUGUIYM.js → chunk-W3GXAODE.js} +111 -2
  14. package/dist/{chunk-OQUGUIYM.js.map → chunk-W3GXAODE.js.map} +1 -1
  15. package/dist/{chunk-RFTJBEZI.js → chunk-X476EPJ2.js} +2 -2
  16. package/dist/{chunk-RFTJBEZI.js.map → chunk-X476EPJ2.js.map} +1 -1
  17. package/dist/{chunk-JQBGEYAK.js → chunk-ZE5ASZ7I.js} +5 -5
  18. package/dist/{eas-LVJEPWBY.js → eas-YOLDR2NC.js} +4 -4
  19. package/dist/{governor-HU3CPXMU.js → governor-QVUB5CNY.js} +4 -4
  20. package/dist/index.js +33 -33
  21. package/dist/{price-OZRLJH3X.js → price-GBLGHUMR.js} +5 -5
  22. package/dist/{research-662HNMOG.js → research-4UA4UB5P.js} +2 -2
  23. package/dist/research-4UA4UB5P.js.map +1 -0
  24. package/dist/{research-5WEM4WZC.js → research-6DYGOVW4.js} +4 -4
  25. package/dist/{session-XRTKPC4Q.js → session-GHQNP6UI.js} +11 -11
  26. package/dist/{trade-HN4BXDVU.js → trade-OLAZMKOH.js} +10 -10
  27. package/dist/{xmtp-25RHTLIA.js → xmtp-EFWFSYIQ.js} +4 -4
  28. package/package.json +1 -1
  29. package/dist/agent-TB7VNLFH.js.map +0 -1
  30. package/dist/chat-CLBWW7PV.js.map +0 -1
  31. package/dist/chunk-B4AH26UI.js.map +0 -1
  32. /package/dist/{addresses-5BITNIGX.js.map → abis-TXCLIR2K.js.map} +0 -0
  33. /package/dist/{eas-LVJEPWBY.js.map → addresses-VTKWQ6GP.js.map} +0 -0
  34. /package/dist/{chunk-QZSKBYZ2.js.map → chunk-6VGC2MGU.js.map} +0 -0
  35. /package/dist/{chunk-OPEVMNEY.js.map → chunk-DZSGUCUE.js.map} +0 -0
  36. /package/dist/{chunk-PHU6MI3J.js.map → chunk-MIOZZVZJ.js.map} +0 -0
  37. /package/dist/{chunk-IQNYBIFE.js.map → chunk-Q32OZRVA.js.map} +0 -0
  38. /package/dist/{chunk-JQBGEYAK.js.map → chunk-ZE5ASZ7I.js.map} +0 -0
  39. /package/dist/{governor-HU3CPXMU.js.map → eas-YOLDR2NC.js.map} +0 -0
  40. /package/dist/{research-662HNMOG.js.map → governor-QVUB5CNY.js.map} +0 -0
  41. /package/dist/{price-OZRLJH3X.js.map → price-GBLGHUMR.js.map} +0 -0
  42. /package/dist/{research-5WEM4WZC.js.map → research-6DYGOVW4.js.map} +0 -0
  43. /package/dist/{session-XRTKPC4Q.js.map → session-GHQNP6UI.js.map} +0 -0
  44. /package/dist/{trade-HN4BXDVU.js.map → trade-OLAZMKOH.js.map} +0 -0
  45. /package/dist/{xmtp-25RHTLIA.js.map → xmtp-EFWFSYIQ.js.map} +0 -0
@@ -1 +0,0 @@
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":[]}
@@ -1 +0,0 @@
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 * Nansen research provider — x402 micropayments for on-chain analytics.\n *\n * Docs: https://docs.nansen.ai\n * Payment: x402 (USDC on Base) — no API key required\n * Pricing: Basic $0.01/call (Token Screener, Wallet Balances, PnL, Transactions)\n * Smart Money $0.05/call (SM Net Flow, SM Holdings, SM DEX Trades)\n * Premium $0.05/call (Counterparties, Holders, PnL Leaderboard)\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 * 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/** 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 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 getX402Fetch();\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 getX402Fetch();\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.05 (premium tier)\n *\n * The netflow endpoint only accepts `token_address` filters (not `token_symbol`).\n * If the target is a symbol, we resolve it to an address via the token screener first.\n */\n private async smartMoneyNetflow(\n target: string,\n ): Promise<ResearchResult> {\n const fetchWithPay = await getX402Fetch();\n\n // Resolve symbol → address if needed (token screener is $0.01)\n const tokenAddress = await this.resolveTokenAddress(target);\n\n const body: Record<string, unknown> = {\n chains: [\"base\"],\n pagination: { page: 1, records_per_page: 10 },\n };\n\n if (tokenAddress) {\n body.filters = { token_address: [tokenAddress] };\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 * 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 getX402Fetch();\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 getX402Fetch();\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":";;;;;AAkBA,SAAS,MAAM,mBAAmB;;;ACNlC,IAAI,aAAkC;AAStC,eAAsB,eAAsC;AAC1D,MAAI,WAAY,QAAO;AAEvB,QAAM,EAAE,YAAY,qBAAqB,IAAI,MAAM,OAAO,aAAa;AACvE,QAAM,EAAE,uBAAuB,IAAI,MAAM,OAAO,wBAAwB;AAExE,QAAM,SAAS,WAAW;AAC1B,QAAM,SAAS,IAAI,WAAW;AAC9B,yBAAuB,QAAQ,EAAE,OAAO,CAAC;AAEzC,eAAa,qBAAqB,OAAO,MAAM;AAC/C,SAAO;AACT;;;ADVA,IAAM,WAAW;AAGV,IAAM,wBAAgD;AAAA,EAC3D,OAAO;AAAA,EACP,QAAQ;AACV;AAEO,IAAM,kBAAN,MAAkD;AAAA,EACvD,OAAqB;AACnB,WAAO;AAAA,MACL,MAAM;AAAA,MACN,MAAM;AAAA,MACN,cAAc;AAAA,QACZ;AAAA,QACA;AAAA,MACF;AAAA,MACA,iBAAiB,CAAC,MAAM,WAAW;AAAA,IACrC;AAAA,EACF;AAAA,EAEA,MAAM,MAAM,QAAgD;AAC1D,YAAQ,OAAO,MAAM;AAAA,MACnB,KAAK;AACH,eAAO,KAAK,YAAY,OAAO,MAAM;AAAA,MACvC,KAAK;AACH,eAAO,KAAK,eAAe,OAAO,MAAM;AAAA,MAC1C,KAAK;AACH,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AAAA,MACF,KAAK;AACH,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AAAA,MACF;AACE,cAAM,IAAI,MAAM,2BAA2B,OAAO,IAAI,EAAE;AAAA,IAC5D;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,YAAY,QAAiC;AACzD,UAAM,eAAe,MAAM,aAAa;AACxC,UAAM,SAAS,IAAI,gBAAgB;AAAA,MACjC,QAAQ;AAAA,MACR,OAAO;AAAA,IACT,CAAC;AACD,UAAM,MAAM,GAAG,QAAQ,sBAAsB,MAAM;AAEnD,UAAM,MAAM,MAAM,aAAa,KAAK,EAAE,QAAQ,MAAM,CAAC;AACrD,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,IAAI;AAAA,QACR,gCAAgC,IAAI,MAAM,IAAI,IAAI,UAAU;AAAA,MAC9D;AAAA,IACF;AAEA,UAAM,OAAQ,MAAM,IAAI,KAAK;AAI7B,UAAM,OAAO,KAAK,OAAO,CAAC,GAAG;AAC7B,QAAI,CAAC,MAAM;AACT,YAAM,IAAI;AAAA,QACR,+BAA+B,MAAM;AAAA,MACvC;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,YAAY,QAAyC;AACjE,UAAM,OAAO,MAAM,KAAK,YAAY,MAAM;AAC1C,UAAM,eAAe,MAAM,aAAa;AACxC,UAAM,MAAM,GAAG,QAAQ,uCAAuC,mBAAmB,IAAI,CAAC;AAEtF,UAAM,MAAM,MAAM,aAAa,KAAK,EAAE,QAAQ,MAAM,CAAC;AACrD,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,IAAI;AAAA,QACR,+BAA+B,IAAI,MAAM,IAAI,IAAI,UAAU;AAAA,MAC7D;AAAA,IACF;AAEA,UAAM,OAAQ,MAAM,IAAI,KAAK;AAG7B,UAAM,WAAW,KAAK,YAAY,KAAK,OAAO;AAC9C,UAAM,QAAQ,KAAK,OAAO,CAAC,KAAK,CAAC;AAEjC,WAAO;AAAA,MACL,UAAU;AAAA,MACV,WAAW;AAAA,MACX;AAAA,MACA,MAAM;AAAA,MACN;AAAA,MACA,WAAW,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AAAA,IACzC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAc,eAAe,QAAyC;AACpE,UAAM,OAAO,MAAM,KAAK,YAAY,MAAM;AAC1C,UAAM,eAAe,MAAM,aAAa;AACxC,UAAM,aAAa,mBAAmB,IAAI;AAE1C,UAAM,CAAC,YAAY,MAAM,IAAI,MAAM,QAAQ,IAAI;AAAA,MAC7C,aAAa,GAAG,QAAQ,uCAAuC,UAAU,IAAI,EAAE,QAAQ,MAAM,CAAC;AAAA,MAC9F,aAAa,GAAG,QAAQ,mCAAmC,UAAU,IAAI,EAAE,QAAQ,MAAM,CAAC;AAAA,IAC5F,CAAC;AAED,QAAI,CAAC,WAAW,IAAI;AAClB,YAAM,IAAI;AAAA,QACR,gCAAgC,WAAW,MAAM,IAAI,WAAW,UAAU;AAAA,MAC5E;AAAA,IACF;AACA,QAAI,CAAC,OAAO,IAAI;AACd,YAAM,IAAI;AAAA,QACR,6BAA6B,OAAO,MAAM,IAAI,OAAO,UAAU;AAAA,MACjE;AAAA,IACF;AAEA,UAAM,cAAe,MAAM,WAAW,KAAK;AAG3C,UAAM,UAAW,MAAM,OAAO,KAAK;AAKnC,UAAM,QAAQ,KAAK,eAAe,UAAU;AAC5C,UAAM,QAAQ,KAAK,eAAe,MAAM;AACxC,UAAM,YAAY,QAAQ;AAC1B,UAAM,WAAW,YAAY,IACzB,UAAU,QAAQ,CAAC,IACnB,sBAAsB,QAAQ,GAAG,QAAQ,MAAM,EAAE,KAAK;AAE1D,UAAM,UAAU,YAAY,OAAO,CAAC,KAAK,CAAC;AAC1C,UAAM,MAAM,QAAQ,OAAO,CAAC,KAAK,CAAC;AAElC,WAAO;AAAA,MACL,UAAU;AAAA,MACV,WAAW;AAAA,MACX;AAAA,MACA,MAAM;AAAA,QACJ,GAAG;AAAA,QACH,aAAa,IAAI,eAAe;AAAA,MAClC;AAAA,MACA;AAAA,MACA,WAAW,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AAAA,IACzC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,eAAe,KAAuB;AAC5C,UAAM,kBAAkB,IAAI,QAAQ,IAAI,kBAAkB;AAC1D,QAAI,iBAAiB;AACnB,UAAI;AACF,cAAM,SAAS,KAAK,MAAM,eAAe;AACzC,YAAI,OAAO,QAAQ;AACjB,iBAAO,OAAO,OAAO,MAAM,IAAI;AAAA,QACjC;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,YAAY,KAAe,YAAoB,SAAiB;AACtE,UAAM,OAAO,KAAK,eAAe,GAAG;AACpC,QAAI,OAAO,EAAG,QAAO,KAAK,QAAQ,CAAC;AAGnC,UAAM,MAAM,sBAAsB,SAAS;AAC3C,QAAI,IAAK,QAAO,IAAI,QAAQ,MAAM,EAAE;AAEpC,WAAO;AAAA,EACT;AACF;;;AE3MA,SAAS,QAAAA,OAAM,eAAAC,oBAAmB;AAKlC,IAAMC,YAAW;AAGV,IAAM,uBAA+C;AAAA,EAC1D,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,eAAe;AAAA,EACf,QAAQ;AACV;AAEO,IAAM,iBAAN,MAAiD;AAAA,EACtD,OAAqB;AACnB,WAAO;AAAA,MACL,MAAM;AAAA,MACN,MAAM;AAAA,MACN,cAAc;AAAA,QACZ;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,iBAAiB,CAACC,OAAMC,YAAW;AAAA,IACrC;AAAA,EACF;AAAA,EAEA,MAAM,MAAM,QAAgD;AAC1D,YAAQ,OAAO,MAAM;AAAA,MACnB,KAAK;AACH,eAAO,KAAK,cAAc,OAAO,MAAM;AAAA,MACzC,KAAK;AACH,eAAO,KAAK,eAAe,OAAO,MAAM;AAAA,MAC1C,KAAK;AACH,eAAO,KAAK,kBAAkB,OAAO,SAAS,SAAS,OAAO,MAAM;AAAA,MACtE,KAAK;AACH,eAAO,KAAK,cAAc,OAAO,MAAM;AAAA,MACzC;AACE,cAAM,IAAI,MAAM,2BAA2B,OAAO,IAAI,EAAE;AAAA,IAC5D;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAc,cAAc,QAAyC;AACnE,UAAM,eAAe,MAAM,aAAa;AAGxC,UAAM,SAAS,OAAO,WAAW,IAAI,KAAK,OAAO,WAAW;AAC5D,UAAM,UAAmC,SACrC,EAAE,eAAe,CAAC,MAAM,EAAE,IAC1B,EAAE,cAAc,CAAC,OAAO,YAAY,CAAC,EAAE;AAE3C,UAAM,OAAO;AAAA,MACX,QAAQ,CAAC,MAAM;AAAA,MACf,WAAW;AAAA,MACX;AAAA,MACA,YAAY,EAAE,MAAM,GAAG,kBAAkB,GAAG;AAAA,IAC9C;AAEA,UAAM,MAAM,MAAM,aAAa,GAAGF,SAAQ,0BAA0B;AAAA,MAClE,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAC9C,MAAM,KAAK,UAAU,IAAI;AAAA,IAC3B,CAAC;AAED,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,IAAI;AAAA,QACR,8BAA8B,IAAI,MAAM,IAAI,IAAI,UAAU;AAAA,MAC5D;AAAA,IACF;AAEA,UAAM,OAAQ,MAAM,IAAI,KAAK;AAC7B,UAAM,WAAW,KAAK,YAAY,KAAK,OAAO;AAE9C,WAAO;AAAA,MACL,UAAU;AAAA,MACV,WAAW;AAAA,MACX;AAAA,MACA,MAAM,EAAE,QAAQ,KAAK,QAAQ,CAAC,GAAG,QAAQ,KAAK,QAAQ,CAAC,GAAG,OAAO;AAAA,MACjE;AAAA,MACA,WAAW,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AAAA,IACzC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAc,eAAe,OAAwC;AACnE,UAAM,eAAe,MAAM,aAAa;AAExC,UAAM,SAAS,MAAM,WAAW,IAAI,KAAK,MAAM,WAAW;AAC1D,UAAM,UAAmC,SACrC,EAAE,eAAe,CAAC,KAAK,EAAE,IACzB,EAAE,cAAc,CAAC,MAAM,YAAY,CAAC,EAAE;AAE1C,UAAM,OAAO;AAAA,MACX,QAAQ,CAAC,MAAM;AAAA,MACf,WAAW;AAAA,MACX;AAAA,MACA,UAAU,CAAC,EAAE,OAAO,cAAc,WAAW,OAAO,CAAC;AAAA,MACrD,YAAY,EAAE,MAAM,GAAG,kBAAkB,GAAG;AAAA,IAC9C;AAEA,UAAM,MAAM,MAAM,aAAa,GAAGA,SAAQ,0BAA0B;AAAA,MAClE,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAC9C,MAAM,KAAK,UAAU,IAAI;AAAA,IAC3B,CAAC;AAED,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,IAAI;AAAA,QACR,+BAA+B,IAAI,MAAM,IAAI,IAAI,UAAU;AAAA,MAC7D;AAAA,IACF;AAEA,UAAM,OAAQ,MAAM,IAAI,KAAK;AAC7B,UAAM,WAAW,KAAK,YAAY,KAAK,QAAQ;AAE/C,WAAO;AAAA,MACL,UAAU;AAAA,MACV,WAAW;AAAA,MACX,QAAQ;AAAA,MACR,MAAM,EAAE,QAAQ,KAAK,QAAQ,CAAC,GAAG,QAAQ,KAAK,QAAQ,CAAC,GAAG,OAAO;AAAA,MACjE;AAAA,MACA,WAAW,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AAAA,IACzC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAc,kBACZ,QACyB;AACzB,UAAM,eAAe,MAAM,aAAa;AAGxC,UAAM,eAAe,MAAM,KAAK,oBAAoB,MAAM;AAE1D,UAAM,OAAgC;AAAA,MACpC,QAAQ,CAAC,MAAM;AAAA,MACf,YAAY,EAAE,MAAM,GAAG,kBAAkB,GAAG;AAAA,IAC9C;AAEA,QAAI,cAAc;AAChB,WAAK,UAAU,EAAE,eAAe,CAAC,YAAY,EAAE;AAAA,IACjD;AAEA,UAAM,MAAM,MAAM,aAAa,GAAGA,SAAQ,+BAA+B;AAAA,MACvE,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAC9C,MAAM,KAAK,UAAU,IAAI;AAAA,IAC3B,CAAC;AAED,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,IAAI;AAAA,QACR,oCAAoC,IAAI,MAAM,IAAI,IAAI,UAAU;AAAA,MAClE;AAAA,IACF;AAEA,UAAM,OAAQ,MAAM,IAAI,KAAK;AAC7B,UAAM,WAAW,KAAK,YAAY,KAAK,aAAa;AAEpD,WAAO;AAAA,MACL,UAAU;AAAA,MACV,WAAW;AAAA,MACX;AAAA,MACA,MAAM,EAAE,OAAO,KAAK,QAAQ,CAAC,GAAG,QAAQ,KAAK,QAAQ,CAAC,GAAG,OAAO;AAAA,MAChE;AAAA,MACA,WAAW,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AAAA,IACzC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAc,cAAc,SAA0C;AACpE,UAAM,eAAe,MAAM,aAAa;AAGxC,UAAM,MAAM,oBAAI,KAAK;AACrB,UAAM,gBAAgB,IAAI,KAAK,IAAI,QAAQ,IAAI,KAAK,KAAK,KAAK,KAAK,GAAI;AACvE,UAAM,OAAO;AAAA,MACX;AAAA,MACA,OAAO;AAAA,MACP,MAAM;AAAA,QACJ,MAAM,cAAc,YAAY,EAAE,QAAQ,aAAa,GAAG;AAAA,QAC1D,IAAI,IAAI,YAAY,EAAE,QAAQ,aAAa,GAAG;AAAA,MAChD;AAAA,IACF;AAEA,UAAM,MAAM,MAAM,aAAa,GAAGA,SAAQ,wCAAwC;AAAA,MAChF,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAC9C,MAAM,KAAK,UAAU,IAAI;AAAA,IAC3B,CAAC;AAED,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,IAAI;AAAA,QACR,+BAA+B,IAAI,MAAM,IAAI,IAAI,UAAU;AAAA,MAC7D;AAAA,IACF;AAEA,UAAM,OAAQ,MAAM,IAAI,KAAK;AAC7B,UAAM,WAAW,KAAK,YAAY,KAAK,QAAQ;AAE/C,WAAO;AAAA,MACL,UAAU;AAAA,MACV,WAAW;AAAA,MACX,QAAQ;AAAA,MACR,MAAM,KAAK,QAAS;AAAA,MACpB;AAAA,MACA,WAAW,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AAAA,IACzC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAc,oBAAoB,QAAwC;AACxE,QAAI,OAAO,WAAW,IAAI,KAAK,OAAO,WAAW,IAAI;AACnD,aAAO;AAAA,IACT;AAEA,UAAM,eAAe,MAAM,aAAa;AACxC,UAAM,OAAO;AAAA,MACX,QAAQ,CAAC,MAAM;AAAA,MACf,WAAW;AAAA,MACX,SAAS,EAAE,cAAc,CAAC,OAAO,YAAY,CAAC,EAAE;AAAA,MAChD,YAAY,EAAE,MAAM,GAAG,kBAAkB,EAAE;AAAA,IAC7C;AAEA,UAAM,MAAM,MAAM,aAAa,GAAGA,SAAQ,0BAA0B;AAAA,MAClE,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAC9C,MAAM,KAAK,UAAU,IAAI;AAAA,IAC3B,CAAC;AAED,QAAI,CAAC,IAAI,GAAI,QAAO;AAEpB,UAAM,OAAQ,MAAM,IAAI,KAAK;AAG7B,WAAO,KAAK,OAAO,CAAC,GAAG,iBAAiB;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,YAAY,KAAe,WAA2B;AAE5D,UAAM,cAAc,IAAI,QAAQ,IAAI,uBAAuB;AAC3D,QAAI,aAAa;AACf,aAAO;AAAA,IACT;AAGA,UAAM,kBAAkB,IAAI,QAAQ,IAAI,kBAAkB;AAC1D,QAAI,iBAAiB;AACnB,UAAI;AACF,cAAM,SAAS,KAAK,MAAM,eAAe;AACzC,YAAI,OAAO,QAAQ;AACjB,gBAAM,QAAQ,OAAO,OAAO,MAAM,IAAI;AACtC,iBAAO,MAAM,QAAQ,CAAC;AAAA,QACxB;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AAGA,UAAM,MAAM,qBAAqB,SAAS;AAC1C,QAAI,KAAK;AACP,aAAO,IAAI,QAAQ,MAAM,EAAE;AAAA,IAC7B;AAEA,WAAO;AAAA,EACT;AACF;;;ACpRO,SAAS,oBAAoB,MAAgC;AAClE,UAAQ,MAAM;AAAA,IACZ,KAAK;AACH,aAAO,IAAI,gBAAgB;AAAA,IAC7B,KAAK;AACH,aAAO,IAAI,eAAe;AAAA,IAC5B;AACE,YAAM,IAAI;AAAA,QACR,8BAA8B,IAAI;AAAA,MACpC;AAAA,EACJ;AACF;","names":["base","baseSepolia","BASE_URL","base","baseSepolia"]}