@sherwoodagent/cli 0.14.1 → 0.14.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chat-LFH2SA46.js → chat-X3IKMSNS.js} +11 -8
- package/dist/{chat-LFH2SA46.js.map → chat-X3IKMSNS.js.map} +1 -1
- package/dist/{chunk-2N7B5N7D.js → chunk-2RYZU7EP.js} +6 -4
- package/dist/chunk-2RYZU7EP.js.map +1 -0
- package/dist/chunk-4CV4JOE5.js +27 -0
- package/dist/{chunk-ADPAZUTB.js → chunk-5NA345RJ.js} +23 -10
- package/dist/chunk-5NA345RJ.js.map +1 -0
- package/dist/{chunk-IIDZ2TK5.js → chunk-BCOTZTTH.js} +39 -10
- package/dist/chunk-BCOTZTTH.js.map +1 -0
- package/dist/{chunk-7CN3TSAA.js → chunk-BGEVQQES.js} +5 -3
- package/dist/{chunk-7CN3TSAA.js.map → chunk-BGEVQQES.js.map} +1 -1
- package/dist/{chunk-FWJBUK57.js → chunk-CGSXIYYZ.js} +5 -3
- package/dist/{chunk-FWJBUK57.js.map → chunk-CGSXIYYZ.js.map} +1 -1
- package/dist/{chunk-KAZRNDZQ.js → chunk-QIOS7I7I.js} +2 -2
- package/dist/{chunk-AC4QMJKC.js → chunk-UBBR7QVJ.js} +2 -2
- package/dist/{chunk-LEQLX7XF.js → chunk-YSYX555I.js} +27 -10
- package/dist/chunk-YSYX555I.js.map +1 -0
- package/dist/{config-U74QT4SC.js → config-5C7QJMPR.js} +5 -2
- package/dist/{cron-RG46PYWA.js → cron-IKBNUL3Q.js} +3 -1
- package/dist/{cron-RG46PYWA.js.map → cron-IKBNUL3Q.js.map} +1 -1
- package/dist/{eas-XWLMRKJU.js → eas-7U7MX24T.js} +7 -6
- package/dist/index.js +74 -33
- package/dist/index.js.map +1 -1
- package/dist/ipfs-AYE4J4OX.js +13 -0
- package/dist/{network-ROF3SSAA.js → network-QU2D677V.js} +4 -3
- package/dist/research-7RI7VFPK.js +15 -0
- package/dist/research-7RI7VFPK.js.map +1 -0
- package/dist/{research-QXGYAJUL.js → research-ZDTM73C7.js} +9 -8
- package/dist/{research-QXGYAJUL.js.map → research-ZDTM73C7.js.map} +1 -1
- package/dist/{session-ECETX4MM.js → session-2VK25CSW.js} +14 -12
- package/dist/session-2VK25CSW.js.map +1 -0
- package/dist/{xmtp-EKFDS5Y3.js → xmtp-Y3LAZKOC.js} +10 -7
- package/dist/{xmtp-EKFDS5Y3.js.map → xmtp-Y3LAZKOC.js.map} +1 -1
- package/package.json +1 -1
- package/dist/chunk-2N7B5N7D.js.map +0 -1
- package/dist/chunk-ADPAZUTB.js.map +0 -1
- package/dist/chunk-IIDZ2TK5.js.map +0 -1
- package/dist/chunk-LEQLX7XF.js.map +0 -1
- package/dist/ipfs-LUJHZGKF.js +0 -11
- package/dist/research-HEZP7VPY.js +0 -14
- package/dist/session-ECETX4MM.js.map +0 -1
- /package/dist/{config-U74QT4SC.js.map → chunk-4CV4JOE5.js.map} +0 -0
- /package/dist/{chunk-KAZRNDZQ.js.map → chunk-QIOS7I7I.js.map} +0 -0
- /package/dist/{chunk-AC4QMJKC.js.map → chunk-UBBR7QVJ.js.map} +0 -0
- /package/dist/{eas-XWLMRKJU.js.map → config-5C7QJMPR.js.map} +0 -0
- /package/dist/{ipfs-LUJHZGKF.js.map → eas-7U7MX24T.js.map} +0 -0
- /package/dist/{network-ROF3SSAA.js.map → ipfs-AYE4J4OX.js.map} +0 -0
- /package/dist/{research-HEZP7VPY.js.map → network-QU2D677V.js.map} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/vault.ts","../src/lib/ens.ts"],"sourcesContent":["/**\n * SyndicateVault contract wrapper.\n *\n * The vault is the onchain identity — it holds all positions via delegatecall\n * to a shared BatchExecutorLib. No separate executor contract needed.\n */\n\nimport type { Address, Hex } from \"viem\";\nimport { formatUnits } from \"viem\";\nimport { getChain } from \"./network.js\";\nimport { getPublicClient, getWalletClient, getAccount } from \"./client.js\";\nimport { SYNDICATE_VAULT_ABI, ERC20_ABI } from \"./abis.js\";\nimport type { BatchCall } from \"./batch.js\";\nimport { getChainContracts } from \"./config.js\";\n\n// Per-command override (set by --vault flag in index.ts)\nlet _vaultOverride: Address | null = null;\n\nexport function setVaultAddress(addr: Address): void {\n _vaultOverride = addr;\n}\n\nexport function getVaultAddress(): Address {\n // 1. Per-command override (--vault flag)\n if (_vaultOverride) return _vaultOverride;\n\n // 2. Config (~/.sherwood/config.json) — default vault\n const chainId = getChain().id;\n const fromConfig = getChainContracts(chainId).vault;\n if (fromConfig) return fromConfig as Address;\n\n throw new Error(\n \"Vault address not found. Pass --vault <addr> or run 'sherwood config set --vault <addr>'.\",\n );\n}\n\n// ── Asset Helpers ──\n\n/**\n * Read the vault's underlying ERC-20 asset address.\n */\nexport async function getAssetAddress(): Promise<Address> {\n const client = getPublicClient();\n return client.readContract({\n address: getVaultAddress(),\n abi: SYNDICATE_VAULT_ABI,\n functionName: \"asset\",\n }) as Promise<Address>;\n}\n\n/**\n * Read decimals from the vault's underlying asset.\n * Works with any ERC-20 (USDC=6, WETH=18, WBTC=8, etc.).\n */\nexport async function getAssetDecimals(): Promise<number> {\n const client = getPublicClient();\n const asset = await getAssetAddress();\n return client.readContract({\n address: asset,\n abi: ERC20_ABI,\n functionName: \"decimals\",\n }) as Promise<number>;\n}\n\n// ── LP Functions ──\n\n/**\n * Deposit into the vault. Handles approval + deposit for the vault's asset.\n */\nexport async function deposit(amount: bigint): Promise<Hex> {\n const wallet = getWalletClient();\n const client = getPublicClient();\n const vaultAddress = getVaultAddress();\n const account = getAccount();\n\n // Approve vault to pull the underlying asset\n const asset = await getAssetAddress();\n const approveHash = await wallet.writeContract({\n account: getAccount(),\n chain: getChain(),\n address: asset,\n abi: ERC20_ABI,\n functionName: \"approve\",\n args: [vaultAddress, amount],\n });\n await client.waitForTransactionReceipt({ hash: approveHash });\n\n // Deposit\n return wallet.writeContract({\n account: getAccount(),\n chain: getChain(),\n address: vaultAddress,\n abi: SYNDICATE_VAULT_ABI,\n functionName: \"deposit\",\n args: [amount, account.address],\n });\n}\n\n// ── Batch Execution ──\n\n/**\n * Execute a batch of protocol calls through the vault (owner only).\n * The vault delegatecalls to the executor lib.\n * All calls execute as the vault — positions live on the vault.\n */\nexport async function executeBatch(calls: BatchCall[]): Promise<Hex> {\n const wallet = getWalletClient();\n\n return wallet.writeContract({\n account: getAccount(),\n chain: getChain(),\n address: getVaultAddress(),\n abi: SYNDICATE_VAULT_ABI,\n functionName: \"executeBatch\",\n args: [\n calls.map((c) => ({\n target: c.target,\n data: c.data,\n value: c.value,\n })),\n ],\n });\n}\n\n// ── Depositor Management ──\n\n/**\n * Approve a depositor address (owner only).\n */\nexport async function approveDepositor(depositor: Address): Promise<Hex> {\n const wallet = getWalletClient();\n return wallet.writeContract({\n account: getAccount(),\n chain: getChain(),\n address: getVaultAddress(),\n abi: SYNDICATE_VAULT_ABI,\n functionName: \"approveDepositor\",\n args: [depositor],\n });\n}\n\n/**\n * Remove a depositor from the whitelist (owner only).\n */\nexport async function removeDepositor(depositor: Address): Promise<Hex> {\n const wallet = getWalletClient();\n return wallet.writeContract({\n account: getAccount(),\n chain: getChain(),\n address: getVaultAddress(),\n abi: SYNDICATE_VAULT_ABI,\n functionName: \"removeDepositor\",\n args: [depositor],\n });\n}\n\n/**\n * Approve multiple depositors in a batch (owner only).\n */\nexport async function approveDepositors(depositors: Address[]): Promise<Hex> {\n const wallet = getWalletClient();\n return wallet.writeContract({\n account: getAccount(),\n chain: getChain(),\n address: getVaultAddress(),\n abi: SYNDICATE_VAULT_ABI,\n functionName: \"approveDepositors\",\n args: [depositors],\n });\n}\n\n/**\n * Check if an address is a registered agent on the vault.\n */\nexport async function isAgent(agentAddress: Address): Promise<boolean> {\n const client = getPublicClient();\n return client.readContract({\n address: getVaultAddress(),\n abi: SYNDICATE_VAULT_ABI,\n functionName: \"isAgent\",\n args: [agentAddress],\n }) as Promise<boolean>;\n}\n\n/**\n * Check if an address is an approved depositor.\n */\nexport async function isApprovedDepositor(depositor: Address): Promise<boolean> {\n const client = getPublicClient();\n return client.readContract({\n address: getVaultAddress(),\n abi: SYNDICATE_VAULT_ABI,\n functionName: \"isApprovedDepositor\",\n args: [depositor],\n }) as Promise<boolean>;\n}\n\n/**\n * Get LP share balance and asset value.\n */\nexport async function getBalance(address?: Address): Promise<{\n shares: bigint;\n assetsValue: string;\n percentOfVault: string;\n}> {\n const client = getPublicClient();\n const vaultAddress = getVaultAddress();\n const account = address || getAccount().address;\n\n const [shares, totalSupply] = await Promise.all([\n client.readContract({\n address: vaultAddress,\n abi: SYNDICATE_VAULT_ABI,\n functionName: \"balanceOf\",\n args: [account],\n }) as Promise<bigint>,\n client.readContract({\n address: vaultAddress,\n abi: SYNDICATE_VAULT_ABI,\n functionName: \"totalSupply\",\n }) as Promise<bigint>,\n ]);\n\n let assetsValue = 0n;\n if (shares > 0n) {\n assetsValue = (await client.readContract({\n address: vaultAddress,\n abi: SYNDICATE_VAULT_ABI,\n functionName: \"convertToAssets\",\n args: [shares],\n })) as bigint;\n }\n\n const percent =\n totalSupply > 0n ? ((Number(shares) / Number(totalSupply)) * 100).toFixed(2) : \"0.00\";\n\n const decimals = await getAssetDecimals();\n\n return {\n shares,\n assetsValue: formatUnits(assetsValue, decimals),\n percentOfVault: `${percent}%`,\n };\n}\n\n// ── Agent Management ──\n\n/**\n * Register a new agent (owner only). Requires ERC-8004 agent identity.\n */\nexport async function registerAgent(\n agentId: bigint,\n agentAddress: Address,\n): Promise<Hex> {\n const wallet = getWalletClient();\n const client = getPublicClient();\n\n const hash = await wallet.writeContract({\n account: getAccount(),\n chain: getChain(),\n address: getVaultAddress(),\n abi: SYNDICATE_VAULT_ABI,\n functionName: \"registerAgent\",\n args: [agentId, agentAddress],\n });\n\n await client.waitForTransactionReceipt({ hash });\n return hash;\n}\n\n// ── Views ──\n\nexport interface VaultInfo {\n address: Address;\n totalAssets: string;\n agentCount: bigint;\n redemptionsLocked: boolean;\n managementFeeBps: bigint;\n}\n\n/**\n * Get vault overview info.\n */\nexport async function getVaultInfo(): Promise<VaultInfo> {\n const client = getPublicClient();\n const vaultAddress = getVaultAddress();\n\n const [totalAssets, agentCount, redemptionsLocked, managementFeeBps, decimals] =\n await Promise.all([\n client.readContract({\n address: vaultAddress,\n abi: SYNDICATE_VAULT_ABI,\n functionName: \"totalAssets\",\n }) as Promise<bigint>,\n client.readContract({\n address: vaultAddress,\n abi: SYNDICATE_VAULT_ABI,\n functionName: \"getAgentCount\",\n }) as Promise<bigint>,\n client.readContract({\n address: vaultAddress,\n abi: SYNDICATE_VAULT_ABI,\n functionName: \"redemptionsLocked\",\n }) as Promise<boolean>,\n client.readContract({\n address: vaultAddress,\n abi: SYNDICATE_VAULT_ABI,\n functionName: \"managementFeeBps\",\n }) as Promise<bigint>,\n getAssetDecimals(),\n ]);\n\n return {\n address: vaultAddress,\n totalAssets: formatUnits(totalAssets, decimals),\n agentCount,\n redemptionsLocked,\n managementFeeBps,\n };\n}\n","/**\n * ENS resolution + text records via Durin L2Registry on Base.\n *\n * Two responsibilities:\n * 1. Resolve syndicate subdomain → on-chain syndicate data (via factory)\n * 2. Read/write ENS text records (via L2Registry, routed through vault's executeBatch)\n *\n * The vault owns the ENS subdomain node (registered in the factory via\n * `ensRegistrar.register(subdomain, vault)`). Only the vault can write text\n * records. We route writes through vault.executeBatch → L2Registry.setText,\n * which executes as the vault via delegatecall to the shared executor lib.\n */\n\nimport { encodeFunctionData } from \"viem\";\nimport type { Address, Hex } from \"viem\";\nimport { namehash } from \"viem/ens\";\nimport { getPublicClient, getWalletClient, getAccount } from \"./client.js\";\nimport { getChain, getNetwork } from \"./network.js\";\nimport { SYNDICATE_FACTORY_ABI, L2_REGISTRY_ABI } from \"./abis.js\";\nimport { ENS, SHERWOOD } from \"./addresses.js\";\nimport * as vaultLib from \"./vault.js\";\n\n/**\n * Wait for a transaction to be mined before proceeding.\n */\nasync function waitForTx(hash: Hex): Promise<void> {\n const client = getPublicClient();\n await client.waitForTransactionReceipt({ hash });\n}\n\nconst ENS_DOMAIN = \"sherwoodagent.eth\";\n\nfunction getFactoryAddress(): Address {\n return SHERWOOD().FACTORY;\n}\n\n// ── Syndicate Resolution (via factory) ──\n\nexport interface SyndicateResolution {\n id: bigint;\n vault: Address;\n creator: Address;\n subdomain: string;\n}\n\n/**\n * Resolve a syndicate subdomain to its on-chain data.\n * Uses factory.subdomainToSyndicate() → factory.syndicates().\n */\nexport async function resolveSyndicate(subdomain: string): Promise<SyndicateResolution> {\n const client = getPublicClient();\n const factory = getFactoryAddress();\n\n // Get syndicate ID from subdomain\n const syndicateId = (await client.readContract({\n address: factory,\n abi: SYNDICATE_FACTORY_ABI,\n functionName: \"subdomainToSyndicate\",\n args: [subdomain],\n })) as bigint;\n\n if (syndicateId === 0n) {\n throw new Error(`Syndicate \"${subdomain}\" not found`);\n }\n\n // Get full syndicate record\n const result = (await client.readContract({\n address: factory,\n abi: SYNDICATE_FACTORY_ABI,\n functionName: \"syndicates\",\n args: [syndicateId],\n })) as [bigint, Address, Address, string, bigint, boolean, string];\n\n return {\n id: result[0],\n vault: result[1],\n creator: result[2],\n subdomain: result[6],\n };\n}\n\n/**\n * Reverse lookup: vault address → syndicate info.\n * Uses factory.vaultToSyndicate() → factory.syndicates().\n */\nexport async function resolveVaultSyndicate(\n vaultAddress: Address,\n): Promise<SyndicateResolution> {\n const client = getPublicClient();\n const factory = getFactoryAddress();\n\n const syndicateId = (await client.readContract({\n address: factory,\n abi: SYNDICATE_FACTORY_ABI,\n functionName: \"vaultToSyndicate\",\n args: [vaultAddress],\n })) as bigint;\n\n if (syndicateId === 0n) {\n throw new Error(`No syndicate found for vault ${vaultAddress}`);\n }\n\n const result = (await client.readContract({\n address: factory,\n abi: SYNDICATE_FACTORY_ABI,\n functionName: \"syndicates\",\n args: [syndicateId],\n })) as [bigint, Address, Address, string, bigint, boolean, string];\n\n return {\n id: result[0],\n vault: result[1],\n creator: result[2],\n subdomain: result[6],\n };\n}\n\n// ── ENS Text Records (via L2Registry) ──\n\n/**\n * Compute the ENS node hash for a subdomain under sherwoodagent.eth.\n */\nfunction getSubdomainNode(subdomain: string): Hex {\n return namehash(`${subdomain}.${ENS_DOMAIN}`);\n}\n\n/**\n * Write a text record to the L2Registry via the vault's executeBatch.\n *\n * The vault owns the ENS node, so only the vault can call setText.\n * We route the call through vault.executeBatch (delegatecall → executor lib → L2Registry),\n * which means L2Registry sees msg.sender = vault address.\n *\n * Requires the caller to be a registered agent on the vault (creator is auto-registered).\n */\nexport async function setTextRecord(\n subdomain: string,\n key: string,\n value: string,\n vaultAddress: Address,\n): Promise<Hex> {\n const l2Registry = ENS().L2_REGISTRY;\n const node = getSubdomainNode(subdomain);\n\n vaultLib.setVaultAddress(vaultAddress);\n\n // Encode the L2Registry.setText call\n const setTextData = encodeFunctionData({\n abi: L2_REGISTRY_ABI,\n functionName: \"setText\",\n args: [node, key, value],\n });\n\n // Route through vault.executeBatch (owner only)\n return vaultLib.executeBatch(\n [{ target: l2Registry, data: setTextData, value: 0n }],\n );\n}\n\n/**\n * Read a text record from the L2Registry.\n * Used to look up xmtpGroupId when not cached locally.\n */\nexport async function getTextRecord(\n subdomain: string,\n key: string,\n): Promise<string> {\n const client = getPublicClient();\n const node = getSubdomainNode(subdomain);\n\n return client.readContract({\n address: ENS().L2_REGISTRY,\n abi: L2_REGISTRY_ABI,\n functionName: \"text\",\n args: [node, key],\n }) as Promise<string>;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/config.ts"],"sourcesContent":["/**\n * Local config management — ~/.sherwood/config.json\n *\n * Stores group ID cache, per-chain contract addresses, and wallet config.\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\n\nconst CONFIG_DIR = path.join(process.env.HOME || \"~\", \".sherwood\");\nconst CONFIG_PATH = path.join(CONFIG_DIR, \"config.json\");\n\n/** Per-chain user-specific addresses (stored by chainId). */\nexport interface ChainContracts {\n vault?: string; // user's default vault address\n}\n\nexport interface SherwoodConfig {\n dbEncryptionKey?: string; // legacy — no longer used, XMTP CLI manages its own DB\n privateKey?: string; // wallet private key (0x-prefixed)\n xmtpInboxId?: string;\n groupCache: Record<string, string>; // subdomain → XMTP group ID\n veniceApiKey?: string; // Venice AI inference API key\n agentId?: number; // ERC-8004 identity token ID\n contracts?: Record<string, ChainContracts>; // chainId → user addresses\n rpc?: Record<string, string>; // network name → custom RPC URL\n notifyTo?: string; // destination for cron summaries (Telegram chat ID, phone, etc.)\n}\n\nexport function loadConfig(): SherwoodConfig {\n if (fs.existsSync(CONFIG_PATH)) {\n return JSON.parse(fs.readFileSync(CONFIG_PATH, \"utf-8\"));\n }\n\n const config: SherwoodConfig = { groupCache: {} };\n fs.mkdirSync(CONFIG_DIR, { recursive: true });\n fs.writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2));\n return config;\n}\n\nexport function saveConfig(config: SherwoodConfig): void {\n fs.mkdirSync(CONFIG_DIR, { recursive: true });\n fs.writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2));\n}\n\nexport function cacheGroupId(subdomain: string, groupId: string): void {\n const config = loadConfig();\n config.groupCache[subdomain] = groupId;\n saveConfig(config);\n}\n\nexport function getCachedGroupId(subdomain: string): string | undefined {\n const config = loadConfig();\n return config.groupCache[subdomain];\n}\n\nexport function setVeniceApiKey(apiKey: string): void {\n const config = loadConfig();\n config.veniceApiKey = apiKey;\n saveConfig(config);\n}\n\nexport function getVeniceApiKey(): string | undefined {\n return loadConfig().veniceApiKey;\n}\n\nexport function setAgentId(agentId: number): void {\n const config = loadConfig();\n config.agentId = agentId;\n saveConfig(config);\n}\n\nexport function getAgentId(): number | undefined {\n return loadConfig().agentId;\n}\n\nexport function setPrivateKey(key: string): void {\n const config = loadConfig();\n config.privateKey = key.startsWith(\"0x\") ? key : `0x${key}`;\n saveConfig(config);\n}\n\nexport function getPrivateKey(): string | undefined {\n return loadConfig().privateKey;\n}\n\n// ── Per-network RPC URLs ──\n\nexport function getConfigRpcUrl(network: string): string | undefined {\n return loadConfig().rpc?.[network];\n}\n\nexport function setConfigRpcUrl(network: string, url: string): void {\n const config = loadConfig();\n if (!config.rpc) config.rpc = {};\n config.rpc[network] = url;\n saveConfig(config);\n}\n\n// ── Per-chain contract addresses ──\n\nexport function getChainContracts(chainId: number): ChainContracts {\n const config = loadConfig();\n return config.contracts?.[String(chainId)] ?? {};\n}\n\nexport function getNotifyTo(): string | undefined {\n return loadConfig().notifyTo;\n}\n\nexport function setNotifyTo(id: string): void {\n const config = loadConfig();\n config.notifyTo = id;\n saveConfig(config);\n}\n\nexport function setChainContract(\n chainId: number,\n key: keyof ChainContracts,\n value: string,\n): void {\n const config = loadConfig();\n if (!config.contracts) config.contracts = {};\n const cid = String(chainId);\n if (!config.contracts[cid]) config.contracts[cid] = {};\n config.contracts[cid][key] = value;\n saveConfig(config);\n}\n"],"mappings":";AAMA,OAAO,QAAQ;AACf,OAAO,UAAU;AAEjB,IAAM,aAAa,KAAK,KAAK,QAAQ,IAAI,QAAQ,KAAK,WAAW;AACjE,IAAM,cAAc,KAAK,KAAK,YAAY,aAAa;AAmBhD,SAAS,aAA6B;AAC3C,MAAI,GAAG,WAAW,WAAW,GAAG;AAC9B,WAAO,KAAK,MAAM,GAAG,aAAa,aAAa,OAAO,CAAC;AAAA,EACzD;AAEA,QAAM,SAAyB,EAAE,YAAY,CAAC,EAAE;AAChD,KAAG,UAAU,YAAY,EAAE,WAAW,KAAK,CAAC;AAC5C,KAAG,cAAc,aAAa,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAC7D,SAAO;AACT;AAEO,SAAS,WAAW,QAA8B;AACvD,KAAG,UAAU,YAAY,EAAE,WAAW,KAAK,CAAC;AAC5C,KAAG,cAAc,aAAa,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAC/D;AAEO,SAAS,aAAa,WAAmB,SAAuB;AACrE,QAAM,SAAS,WAAW;AAC1B,SAAO,WAAW,SAAS,IAAI;AAC/B,aAAW,MAAM;AACnB;AAEO,SAAS,iBAAiB,WAAuC;AACtE,QAAM,SAAS,WAAW;AAC1B,SAAO,OAAO,WAAW,SAAS;AACpC;AAEO,SAAS,gBAAgB,QAAsB;AACpD,QAAM,SAAS,WAAW;AAC1B,SAAO,eAAe;AACtB,aAAW,MAAM;AACnB;AAEO,SAAS,kBAAsC;AACpD,SAAO,WAAW,EAAE;AACtB;AAEO,SAAS,WAAW,SAAuB;AAChD,QAAM,SAAS,WAAW;AAC1B,SAAO,UAAU;AACjB,aAAW,MAAM;AACnB;AAEO,SAAS,aAAiC;AAC/C,SAAO,WAAW,EAAE;AACtB;AAEO,SAAS,cAAc,KAAmB;AAC/C,QAAM,SAAS,WAAW;AAC1B,SAAO,aAAa,IAAI,WAAW,IAAI,IAAI,MAAM,KAAK,GAAG;AACzD,aAAW,MAAM;AACnB;AAEO,SAAS,gBAAoC;AAClD,SAAO,WAAW,EAAE;AACtB;AAIO,SAAS,gBAAgB,SAAqC;AACnE,SAAO,WAAW,EAAE,MAAM,OAAO;AACnC;AAEO,SAAS,gBAAgB,SAAiB,KAAmB;AAClE,QAAM,SAAS,WAAW;AAC1B,MAAI,CAAC,OAAO,IAAK,QAAO,MAAM,CAAC;AAC/B,SAAO,IAAI,OAAO,IAAI;AACtB,aAAW,MAAM;AACnB;AAIO,SAAS,kBAAkB,SAAiC;AACjE,QAAM,SAAS,WAAW;AAC1B,SAAO,OAAO,YAAY,OAAO,OAAO,CAAC,KAAK,CAAC;AACjD;AAEO,SAAS,cAAkC;AAChD,SAAO,WAAW,EAAE;AACtB;AAEO,SAAS,YAAY,IAAkB;AAC5C,QAAM,SAAS,WAAW;AAC1B,SAAO,WAAW;AAClB,aAAW,MAAM;AACnB;AAEO,SAAS,iBACd,SACA,KACA,OACM;AACN,QAAM,SAAS,WAAW;AAC1B,MAAI,CAAC,OAAO,UAAW,QAAO,YAAY,CAAC;AAC3C,QAAM,MAAM,OAAO,OAAO;AAC1B,MAAI,CAAC,OAAO,UAAU,GAAG,EAAG,QAAO,UAAU,GAAG,IAAI,CAAC;AACrD,SAAO,UAAU,GAAG,EAAE,GAAG,IAAI;AAC7B,aAAW,MAAM;AACnB;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/ipfs.ts"],"sourcesContent":["/**\n * IPFS metadata upload/fetch via Pinata.\n *\n * Used for syndicate metadata (name, description, strategies, terms).\n * Requires PINATA_API_KEY and PINATA_GATEWAY env vars.\n */\n\nexport interface SyndicateMetadata {\n schema: string;\n name: string;\n description: string;\n logo?: string;\n chain: string;\n strategies: {\n id: string;\n name: string;\n description: string;\n protocols: string[];\n riskLevel: string;\n }[];\n terms: {\n minDeposit?: string;\n minDepositFormatted?: string;\n feeModel?: string;\n lockPeriod?: number;\n };\n links: {\n moltbook?: string;\n dashboard?: string;\n github?: string;\n };\n}\n\n// Bundled Pinata credentials — used by all CLI users for syndicate metadata.\n// Override with PINATA_API_KEY / PINATA_GATEWAY env vars if needed.\nconst BUNDLED_PINATA_JWT =\n \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mb3JtYXRpb24iOnsiaWQiOiI2NDQ0MGViOC1hYTYyLTQzY2EtOGYwNC04MDZjZmNjY2Y4YTUiLCJlbWFpbCI6ImltdGhhdGNhcmxvc0BnbWFpbC5jb20iLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwicGluX3BvbGljeSI6eyJyZWdpb25zIjpbeyJkZXNpcmVkUmVwbGljYXRpb25Db3VudCI6MSwiaWQiOiJGUkExIn1dLCJ2ZXJzaW9uIjoxfSwibWZhX2VuYWJsZWQiOmZhbHNlLCJzdGF0dXMiOiJBQ1RJVkUifSwiYXV0aGVudGljYXRpb25UeXBlIjoic2NvcGVkS2V5Iiwic2NvcGVkS2V5S2V5IjoiMWJhZWFmMzQwODM3MGQ0NGZkZWEiLCJzY29wZWRLZXlTZWNyZXQiOiIzNDcxMmU5MTkyYTgxNWFhMGRmNjUyYjYyMDQzODQ1MDJjMmU0YWE0MDhkZTJmOTU2NWYwOTk3YTNlY2U3NGU3IiwiZXhwIjoxODAxMjc2ODExfQ.7OMJiOATpqkSwe7Orrpt2b8H_-czH-W61vBm4AHtqfA\";\nconst BUNDLED_PINATA_GATEWAY = \"https://sherwood.mypinata.cloud\";\n\nfunction getPinataApiKey(): string {\n return process.env.PINATA_API_KEY || BUNDLED_PINATA_JWT;\n}\n\nfunction getPinataGateway(): string {\n return process.env.PINATA_GATEWAY || BUNDLED_PINATA_GATEWAY;\n}\n\n/**\n * Pin arbitrary JSON to IPFS via Pinata.\n * Used for research results and other generic JSON payloads.\n * Returns the IPFS URI (ipfs://Qm...).\n */\nexport async function pinJSON(content: Record<string, unknown>, name: string): Promise<string> {\n const apiKey = getPinataApiKey();\n\n const response = await fetch(\"https://api.pinata.cloud/pinning/pinJSONToIPFS\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({\n pinataContent: content,\n pinataMetadata: { name },\n }),\n });\n\n if (!response.ok) {\n const text = await response.text();\n throw new Error(`Pinata upload failed (${response.status}): ${text}`);\n }\n\n const result = (await response.json()) as { IpfsHash: string };\n return `ipfs://${result.IpfsHash}`;\n}\n\n/**\n * Upload syndicate metadata to IPFS via Pinata.\n * Returns the IPFS URI (ipfs://Qm...).\n */\nexport async function uploadMetadata(metadata: SyndicateMetadata): Promise<string> {\n const apiKey = getPinataApiKey();\n\n const response = await fetch(\"https://api.pinata.cloud/pinning/pinJSONToIPFS\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({\n pinataContent: metadata,\n pinataMetadata: {\n name: `sherwood-syndicate-${metadata.name.toLowerCase().replace(/\\s+/g, \"-\")}`,\n },\n }),\n });\n\n if (!response.ok) {\n const text = await response.text();\n throw new Error(`Pinata upload failed (${response.status}): ${text}`);\n }\n\n const result = (await response.json()) as { IpfsHash: string };\n return `ipfs://${result.IpfsHash}`;\n}\n\n/**\n * Fetch and parse metadata from an IPFS URI.\n * Supports ipfs:// protocol URIs and raw CIDs.\n */\nexport async function fetchMetadata(ipfsURI: string): Promise<SyndicateMetadata> {\n const gateway = getPinataGateway();\n let cid: string;\n\n if (ipfsURI.startsWith(\"ipfs://\")) {\n cid = ipfsURI.slice(7);\n } else if (ipfsURI.startsWith(\"Qm\") || ipfsURI.startsWith(\"bafy\")) {\n cid = ipfsURI;\n } else {\n throw new Error(`Invalid IPFS URI: ${ipfsURI}`);\n }\n\n const url = `${gateway}/ipfs/${cid}`;\n const response = await fetch(url);\n\n if (!response.ok) {\n throw new Error(`Failed to fetch metadata from ${url} (${response.status})`);\n }\n\n return (await response.json()) as SyndicateMetadata;\n}\n"],"mappings":";AAmCA,IAAM,qBACJ;AACF,IAAM,yBAAyB;AAE/B,SAAS,kBAA0B;AACjC,SAAO,QAAQ,IAAI,kBAAkB;AACvC;AAEA,SAAS,mBAA2B;AAClC,SAAO,QAAQ,IAAI,kBAAkB;AACvC;AAOA,eAAsB,QAAQ,SAAkC,MAA+B;AAC7F,QAAM,SAAS,gBAAgB;AAE/B,QAAM,WAAW,MAAM,MAAM,kDAAkD;AAAA,IAC7E,QAAQ;AAAA,IACR,SAAS;AAAA,MACP,gBAAgB;AAAA,MAChB,eAAe,UAAU,MAAM;AAAA,IACjC;AAAA,IACA,MAAM,KAAK,UAAU;AAAA,MACnB,eAAe;AAAA,MACf,gBAAgB,EAAE,KAAK;AAAA,IACzB,CAAC;AAAA,EACH,CAAC;AAED,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,OAAO,MAAM,SAAS,KAAK;AACjC,UAAM,IAAI,MAAM,yBAAyB,SAAS,MAAM,MAAM,IAAI,EAAE;AAAA,EACtE;AAEA,QAAM,SAAU,MAAM,SAAS,KAAK;AACpC,SAAO,UAAU,OAAO,QAAQ;AAClC;AAMA,eAAsB,eAAe,UAA8C;AACjF,QAAM,SAAS,gBAAgB;AAE/B,QAAM,WAAW,MAAM,MAAM,kDAAkD;AAAA,IAC7E,QAAQ;AAAA,IACR,SAAS;AAAA,MACP,gBAAgB;AAAA,MAChB,eAAe,UAAU,MAAM;AAAA,IACjC;AAAA,IACA,MAAM,KAAK,UAAU;AAAA,MACnB,eAAe;AAAA,MACf,gBAAgB;AAAA,QACd,MAAM,sBAAsB,SAAS,KAAK,YAAY,EAAE,QAAQ,QAAQ,GAAG,CAAC;AAAA,MAC9E;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AAED,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,OAAO,MAAM,SAAS,KAAK;AACjC,UAAM,IAAI,MAAM,yBAAyB,SAAS,MAAM,MAAM,IAAI,EAAE;AAAA,EACtE;AAEA,QAAM,SAAU,MAAM,SAAS,KAAK;AACpC,SAAO,UAAU,OAAO,QAAQ;AAClC;AAMA,eAAsB,cAAc,SAA6C;AAC/E,QAAM,UAAU,iBAAiB;AACjC,MAAI;AAEJ,MAAI,QAAQ,WAAW,SAAS,GAAG;AACjC,UAAM,QAAQ,MAAM,CAAC;AAAA,EACvB,WAAW,QAAQ,WAAW,IAAI,KAAK,QAAQ,WAAW,MAAM,GAAG;AACjE,UAAM;AAAA,EACR,OAAO;AACL,UAAM,IAAI,MAAM,qBAAqB,OAAO,EAAE;AAAA,EAChD;AAEA,QAAM,MAAM,GAAG,OAAO,SAAS,GAAG;AAClC,QAAM,WAAW,MAAM,MAAM,GAAG;AAEhC,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,IAAI,MAAM,iCAAiC,GAAG,KAAK,SAAS,MAAM,GAAG;AAAA,EAC7E;AAEA,SAAQ,MAAM,SAAS,KAAK;AAC9B;","names":[]}
|
package/dist/ipfs-LUJHZGKF.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
MessariProvider,
|
|
3
|
-
NansenProvider,
|
|
4
|
-
getResearchProvider
|
|
5
|
-
} from "./chunk-KAZRNDZQ.js";
|
|
6
|
-
import "./chunk-FWJBUK57.js";
|
|
7
|
-
import "./chunk-7CN3TSAA.js";
|
|
8
|
-
import "./chunk-IIDZ2TK5.js";
|
|
9
|
-
export {
|
|
10
|
-
MessariProvider,
|
|
11
|
-
NansenProvider,
|
|
12
|
-
getResearchProvider
|
|
13
|
-
};
|
|
14
|
-
//# sourceMappingURL=research-HEZP7VPY.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/session.ts","../src/lib/session.ts","../src/lib/events.ts"],"sourcesContent":["/**\n * Session commands — sherwood session check|status|reset\n *\n * Provides agent awareness: catch up on XMTP messages and on-chain events\n * since the last session. Supports one-shot polling (default) and persistent\n * streaming (--stream).\n *\n * Usage:\n * sherwood session check <name> — one-shot catch-up (JSON to stdout)\n * sherwood session check <name> --stream — persistent stream (JSON lines to stdout)\n * sherwood session status [name] — show session cursor positions\n * sherwood session reset <name> [--full] — reset session cursors\n */\n\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport type { Address } from \"viem\";\nimport { resolveSyndicate } from \"../lib/ens.js\";\nimport { SHERWOOD } from \"../lib/addresses.js\";\nimport { getPublicClient } from \"../lib/client.js\";\nimport { SYNDICATE_VAULT_ABI } from \"../lib/abis.js\";\nimport {\n getSession,\n updateSession,\n resetSession,\n getAllSessions,\n} from \"../lib/session.js\";\nimport {\n getVaultEvents,\n getGovernorEvents,\n getCurrentBlock,\n type ChainEvent,\n} from \"../lib/events.js\";\nimport type { ChatEnvelope } from \"../lib/types.js\";\n\n// Lazy-load XMTP to avoid breaking session commands when @xmtp/cli is missing\nasync function loadXmtp() {\n return import(\"../lib/xmtp.js\");\n}\n\n// ── Output types ──\n\ninterface SessionMessage {\n source: \"xmtp\";\n id: string;\n from: string;\n type: string;\n text: string;\n sentAt: string; // ISO 8601\n}\n\ninterface SessionCheckResult {\n syndicate: string;\n messages: SessionMessage[];\n events: ChainEvent[];\n meta: {\n newMessages: number;\n newEvents: number;\n blocksScanned: number;\n lastCheckAt: string; // ISO 8601\n };\n}\n\n// ── Helpers ──\n\n/** Resolve the governor address from the vault contract. */\nasync function resolveGovernor(vaultAddress: Address): Promise<Address> {\n const client = getPublicClient();\n try {\n const governor = await client.readContract({\n address: vaultAddress,\n abi: SYNDICATE_VAULT_ABI,\n functionName: \"governor\",\n });\n return governor as Address;\n } catch {\n // Vault might not have a governor set\n return SHERWOOD().GOVERNOR;\n }\n}\n\n/** Convert an XMTP message to session output format. */\nfunction toSessionMessage(msg: {\n id: string;\n senderInboxId: string;\n content: string;\n sentAt: Date;\n}): SessionMessage {\n let type = \"MESSAGE\";\n let text = msg.content;\n let from = msg.senderInboxId;\n\n try {\n const envelope: ChatEnvelope = JSON.parse(msg.content);\n type = envelope.type;\n text = envelope.text || envelope.type;\n from = envelope.from || msg.senderInboxId;\n } catch {\n // Plain text message\n }\n\n return {\n source: \"xmtp\",\n id: msg.id,\n from,\n type,\n text,\n sentAt: msg.sentAt.toISOString(),\n };\n}\n\n// ── Command handlers ──\n\nasync function handleCheck(name: string, stream: boolean): Promise<void> {\n // Resolve syndicate\n const syndicate = await resolveSyndicate(name);\n const vaultAddress = syndicate.vault;\n const governorAddress = await resolveGovernor(vaultAddress);\n\n // Load or initialize session\n const session = getSession(name);\n const currentBlock = await getCurrentBlock();\n\n // On first run: look back ~1000 blocks (~8 min on Base)\n const fromBlock = session?.lastBlockNumber\n ? BigInt(session.lastBlockNumber) + 1n\n : currentBlock > 1000n\n ? currentBlock - 1000n\n : 0n;\n\n const lastMessageTimestamp = session?.lastMessageTimestamp || 0;\n\n // ── Fetch XMTP messages ──\n let messages: SessionMessage[] = [];\n try {\n const xmtp = await loadXmtp();\n const groupId = await xmtp.getGroup(\"\", name);\n const recent = await xmtp.getRecentMessages(groupId, 100);\n\n // Filter to messages after our cursor (compare in ms for precision)\n const cursorMs = lastMessageTimestamp * 1000;\n const newMessages = recent.filter(\n (m) => m.sentAt.getTime() > cursorMs,\n );\n messages = newMessages.map(toSessionMessage);\n } catch {\n // XMTP not available or group not found — skip messages\n }\n\n // ── Fetch on-chain events ──\n let events: ChainEvent[] = [];\n if (fromBlock <= currentBlock) {\n const vaultEvents = await getVaultEvents(\n vaultAddress,\n fromBlock,\n currentBlock,\n );\n const govEvents = await getGovernorEvents(\n governorAddress,\n vaultAddress,\n fromBlock,\n currentBlock,\n );\n events = [...vaultEvents, ...govEvents].sort((a, b) => a.block - b.block);\n }\n\n // ── Output initial catch-up result ──\n const result: SessionCheckResult = {\n syndicate: name,\n messages,\n events,\n meta: {\n newMessages: messages.length,\n newEvents: events.length,\n blocksScanned: Number(currentBlock - fromBlock),\n lastCheckAt: session?.lastCheckAt\n ? new Date(session.lastCheckAt * 1000).toISOString()\n : \"never\",\n },\n };\n\n process.stdout.write(JSON.stringify(result) + \"\\n\");\n\n // ── Update session state ──\n // Find the newest message timestamp (messages may not be sorted)\n // Use ceil to ensure we don't re-fetch the same message due to sub-second precision\n let newestTimestamp = lastMessageTimestamp;\n let newestMessageId = session?.lastMessageId || \"\";\n for (const msg of messages) {\n const ts = Math.ceil(new Date(msg.sentAt).getTime() / 1000);\n if (ts > newestTimestamp) {\n newestTimestamp = ts;\n newestMessageId = msg.id;\n }\n }\n\n updateSession(name, {\n vault: vaultAddress,\n governor: governorAddress,\n lastBlockNumber: Number(currentBlock),\n lastCheckAt: Math.floor(Date.now() / 1000),\n lastMessageId: newestMessageId,\n lastMessageTimestamp: newestTimestamp,\n totalMessagesProcessed:\n (session?.totalMessagesProcessed || 0) + messages.length,\n totalEventsProcessed:\n (session?.totalEventsProcessed || 0) + events.length,\n });\n\n // ── If --stream, stay alive ──\n if (stream) {\n await startStream(name, vaultAddress, governorAddress);\n }\n}\n\nasync function startStream(\n name: string,\n vaultAddress: Address,\n governorAddress: Address,\n): Promise<void> {\n // Start XMTP message stream\n let xmtpCleanup: (() => void) | undefined;\n try {\n const xmtp = await loadXmtp();\n const groupId = await xmtp.getGroup(\"\", name);\n\n xmtpCleanup = await xmtp.streamMessages(groupId, (msg) => {\n const sessionMsg = toSessionMessage(msg);\n process.stdout.write(JSON.stringify(sessionMsg) + \"\\n\");\n\n // Update session state incrementally\n updateSession(name, {\n lastMessageId: msg.id,\n lastMessageTimestamp: Math.floor(msg.sentAt.getTime() / 1000),\n lastCheckAt: Math.floor(Date.now() / 1000),\n totalMessagesProcessed:\n (getSession(name)?.totalMessagesProcessed || 0) + 1,\n });\n });\n } catch {\n // XMTP not available — continue with event polling only\n }\n\n // Start on-chain event polling (~30s interval)\n const pollInterval = setInterval(async () => {\n try {\n const session = getSession(name);\n const fromBlock = BigInt(session?.lastBlockNumber || 0) + 1n;\n const toBlock = await getCurrentBlock();\n\n if (fromBlock > toBlock) return; // No new blocks\n\n const vaultEvents = await getVaultEvents(\n vaultAddress,\n fromBlock,\n toBlock,\n );\n const govEvents = await getGovernorEvents(\n governorAddress,\n vaultAddress,\n fromBlock,\n toBlock,\n );\n\n const events = [...vaultEvents, ...govEvents].sort(\n (a, b) => a.block - b.block,\n );\n\n for (const event of events) {\n process.stdout.write(JSON.stringify(event) + \"\\n\");\n }\n\n updateSession(name, {\n lastBlockNumber: Number(toBlock),\n lastCheckAt: Math.floor(Date.now() / 1000),\n totalEventsProcessed:\n (getSession(name)?.totalEventsProcessed || 0) + events.length,\n });\n } catch {\n // RPC error — skip this poll cycle\n }\n }, 30_000);\n\n // Clean up on exit\n const cleanup = () => {\n clearInterval(pollInterval);\n xmtpCleanup?.();\n process.exit(0);\n };\n\n process.on(\"SIGINT\", cleanup);\n process.on(\"SIGTERM\", cleanup);\n\n // Keep alive\n await new Promise(() => {});\n}\n\nasync function handleStatus(name?: string): Promise<void> {\n const sessions = getAllSessions();\n\n if (name) {\n const session = sessions[name];\n if (!session) {\n console.log(\n chalk.dim(`No session found for \"${name}\". Run \"sherwood session check ${name}\" first.`),\n );\n return;\n }\n console.log(JSON.stringify({ [name]: formatSessionStatus(session) }, null, 2));\n return;\n }\n\n // Show all sessions\n if (Object.keys(sessions).length === 0) {\n console.log(chalk.dim(\"No sessions found. Run \\\"sherwood session check <name>\\\" to start.\"));\n return;\n }\n\n const output: Record<string, ReturnType<typeof formatSessionStatus>> = {};\n for (const [subdomain, session] of Object.entries(sessions)) {\n output[subdomain] = formatSessionStatus(session);\n }\n console.log(JSON.stringify(output, null, 2));\n}\n\nfunction formatSessionStatus(session: {\n lastCheckAt: number;\n lastBlockNumber: number;\n totalMessagesProcessed: number;\n totalEventsProcessed: number;\n}) {\n return {\n lastCheckAt: session.lastCheckAt\n ? new Date(session.lastCheckAt * 1000).toISOString()\n : \"never\",\n lastBlockNumber: session.lastBlockNumber,\n totalMessagesProcessed: session.totalMessagesProcessed,\n totalEventsProcessed: session.totalEventsProcessed,\n };\n}\n\nasync function handleReset(\n name: string,\n sinceBlock?: string,\n full?: boolean,\n): Promise<void> {\n if (full || !sinceBlock) {\n resetSession(name);\n console.log(chalk.green(`Session for \"${name}\" has been reset.`));\n } else {\n const block = parseInt(sinceBlock, 10);\n if (isNaN(block)) {\n console.error(chalk.red(\"--since-block must be a number\"));\n process.exit(1);\n }\n resetSession(name, block);\n console.log(\n chalk.green(`Block cursor for \"${name}\" reset to ${block}.`),\n );\n }\n}\n\n// ── Command Registration ──\n\nexport function registerSessionCommands(program: Command): void {\n const session = program\n .command(\"session\")\n .description(\"Agent session — catch up on messages + on-chain events\");\n\n session\n .command(\"check <name>\")\n .description(\"Fetch new XMTP messages and on-chain events since last check\")\n .option(\"--stream\", \"Stay alive streaming messages and polling events\", false)\n .action(async (name: string, opts: { stream: boolean }) => {\n await handleCheck(name, opts.stream);\n });\n\n session\n .command(\"status [name]\")\n .description(\"Show session cursor positions\")\n .action(async (name?: string) => {\n await handleStatus(name);\n });\n\n session\n .command(\"reset <name>\")\n .description(\"Reset session cursors\")\n .option(\"--since-block <n>\", \"Reset block cursor to a specific block\")\n .option(\"--full\", \"Reset everything (messages + events)\", false)\n .action(\n async (\n name: string,\n opts: { sinceBlock?: string; full: boolean },\n ) => {\n await handleReset(name, opts.sinceBlock, opts.full);\n },\n );\n\n session\n .command(\"cron <name>\")\n .description(\"Manage participation crons (OpenClaw agents)\")\n .option(\"--remove\", \"Remove participation crons\", false)\n .option(\"--status\", \"Show cron status\", false)\n .action(async (name: string, opts: { remove: boolean; status: boolean }) => {\n const { isOpenClaw, registerSyndicateCrons, unregisterSyndicateCrons, getSyndicateCronStatus } =\n await import(\"../lib/cron.js\");\n const { isTestnet } = await import(\"../lib/network.js\");\n const { getNotifyTo } = await import(\"../lib/config.js\");\n\n if (!isOpenClaw()) {\n console.log(chalk.yellow(\"Not running on OpenClaw — cron commands unavailable\"));\n console.log(chalk.dim(` Set up your own scheduler: sherwood session check ${name} --stream`));\n return;\n }\n\n if (opts.status) {\n const status = getSyndicateCronStatus(name, isTestnet());\n if (status.crons.length === 0) {\n console.log(chalk.dim(\"No participation crons found for \" + name));\n return;\n }\n console.log();\n console.log(chalk.bold(`Participation Crons — ${name}`));\n console.log(chalk.dim(\"─\".repeat(50)));\n for (const cron of status.crons) {\n console.log(` ${chalk.green(cron.name)} every ${cron.every}${cron.lastRun ? ` last: ${cron.lastRun}` : \"\"}`);\n }\n console.log();\n return;\n }\n\n if (opts.remove) {\n const result = unregisterSyndicateCrons(name, isTestnet());\n if (result.removed) {\n console.log(chalk.green(\"Participation crons removed\"));\n } else {\n console.log(chalk.dim(\"No crons found to remove\"));\n }\n return;\n }\n\n // Register/update\n const result = registerSyndicateCrons(name, isTestnet(), getNotifyTo());\n if (result.registered) {\n console.log(chalk.green(\"Participation crons registered: \" + result.cronNames.join(\", \")));\n } else {\n console.log(chalk.dim(\"Crons already registered\"));\n }\n });\n}\n","/**\n * Session state management — ~/.sherwood/session.json\n *\n * Tracks per-syndicate cursors for XMTP messages and on-chain events.\n * Enables agents to catch up on what they missed between sessions.\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\n\nconst SESSION_DIR = path.join(process.env.HOME || \"~\", \".sherwood\");\nconst SESSION_PATH = path.join(SESSION_DIR, \"session.json\");\n\nexport interface SyndicateSession {\n subdomain: string;\n vault: string; // vault address for event filtering\n governor: string; // governor address for proposal events\n // XMTP cursors\n lastMessageId: string;\n lastMessageTimestamp: number; // unix seconds\n // On-chain cursors\n lastBlockNumber: number;\n // Session metadata\n lastCheckAt: number; // unix seconds\n totalMessagesProcessed: number;\n totalEventsProcessed: number;\n}\n\ninterface SessionState {\n version: 1;\n syndicates: Record<string, SyndicateSession>;\n}\n\nexport function loadSessionState(): SessionState {\n try {\n if (fs.existsSync(SESSION_PATH)) {\n return JSON.parse(fs.readFileSync(SESSION_PATH, \"utf-8\"));\n }\n } catch {\n // Corrupted file — start fresh\n }\n return { version: 1, syndicates: {} };\n}\n\nexport function saveSessionState(state: SessionState): void {\n fs.mkdirSync(SESSION_DIR, { recursive: true });\n fs.writeFileSync(SESSION_PATH, JSON.stringify(state, null, 2));\n}\n\nexport function getSession(subdomain: string): SyndicateSession | undefined {\n const state = loadSessionState();\n return state.syndicates[subdomain];\n}\n\nexport function updateSession(\n subdomain: string,\n update: Partial<SyndicateSession>,\n): void {\n const state = loadSessionState();\n const existing = state.syndicates[subdomain] || {\n subdomain,\n vault: \"\",\n governor: \"\",\n lastMessageId: \"\",\n lastMessageTimestamp: 0,\n lastBlockNumber: 0,\n lastCheckAt: 0,\n totalMessagesProcessed: 0,\n totalEventsProcessed: 0,\n };\n state.syndicates[subdomain] = { ...existing, ...update };\n saveSessionState(state);\n}\n\nexport function resetSession(\n subdomain: string,\n sinceBlock?: number,\n): void {\n const state = loadSessionState();\n if (sinceBlock !== undefined) {\n // Partial reset — just move the block cursor\n if (state.syndicates[subdomain]) {\n state.syndicates[subdomain].lastBlockNumber = sinceBlock;\n saveSessionState(state);\n }\n } else {\n // Full reset\n delete state.syndicates[subdomain];\n saveSessionState(state);\n }\n}\n\nexport function getAllSessions(): Record<string, SyndicateSession> {\n return loadSessionState().syndicates;\n}\n","/**\n * On-chain event reader — fetches vault and governor events via viem getLogs.\n *\n * Uses HTTP RPC (no WebSocket needed). Block ranges are capped at 10,000\n * per call to avoid RPC timeouts (~83 minutes on Base at 2 blocks/sec).\n */\n\nimport type { Address, Log } from \"viem\";\nimport { parseAbiItem } from \"viem\";\nimport { getPublicClient } from \"./client.js\";\n\nconst MAX_BLOCK_RANGE = 10_000n;\n\n// ── Event signatures (parseAbiItem format for getLogs) ──\n\nconst VAULT_EVENTS = [\n parseAbiItem(\"event AgentRegistered(uint256 indexed agentId, address indexed agentAddress)\"),\n parseAbiItem(\"event AgentRemoved(address indexed agentAddress)\"),\n parseAbiItem(\"event DepositorApproved(address indexed depositor)\"),\n parseAbiItem(\"event DepositorRemoved(address indexed depositor)\"),\n parseAbiItem(\"event RedemptionsLockedEvent()\"),\n parseAbiItem(\"event RedemptionsUnlockedEvent()\"),\n] as const;\n\nconst GOVERNOR_EVENTS = [\n parseAbiItem(\"event ProposalCreated(uint256 indexed proposalId, address indexed proposer, address indexed vault, uint256 performanceFeeBps, uint256 strategyDuration, uint256 executeCallCount, uint256 settlementCallCount, string metadataURI)\"),\n parseAbiItem(\"event VoteCast(uint256 indexed proposalId, address indexed voter, bool support, uint256 weight)\"),\n parseAbiItem(\"event ProposalExecuted(uint256 indexed proposalId, address indexed vault, uint256 capitalSnapshot)\"),\n parseAbiItem(\"event ProposalSettled(uint256 indexed proposalId, address indexed vault, int256 pnl, uint256 performanceFee, uint256 duration)\"),\n parseAbiItem(\"event ProposalCancelled(uint256 indexed proposalId, address indexed cancelledBy)\"),\n] as const;\n\n/** Normalized event returned by the session check. */\nexport interface ChainEvent {\n source: \"chain\";\n type: string;\n block: number;\n tx: string;\n args: Record<string, string>;\n}\n\nfunction logToChainEvent(log: Log, eventName: string): ChainEvent {\n const args: Record<string, string> = {};\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const decoded = (log as any).args;\n if (decoded) {\n for (const [key, value] of Object.entries(decoded)) {\n args[key] = String(value);\n }\n }\n\n return {\n source: \"chain\",\n type: eventName,\n block: Number(log.blockNumber),\n tx: log.transactionHash || \"\",\n args,\n };\n}\n\n/**\n * Fetch events in chunks to stay within RPC limits.\n * Returns all logs from `fromBlock` to `toBlock` inclusive.\n */\nasync function getLogsChunked(params: {\n address: Address;\n events: readonly ReturnType<typeof parseAbiItem>[];\n fromBlock: bigint;\n toBlock: bigint;\n}): Promise<Log[]> {\n const client = getPublicClient();\n const { address, events, fromBlock, toBlock } = params;\n\n const allLogs: Log[] = [];\n let cursor = fromBlock;\n\n while (cursor <= toBlock) {\n const end =\n cursor + MAX_BLOCK_RANGE - 1n > toBlock\n ? toBlock\n : cursor + MAX_BLOCK_RANGE - 1n;\n\n const logs = await client.getLogs({\n address,\n events: events as never,\n fromBlock: cursor,\n toBlock: end,\n });\n\n allLogs.push(...logs);\n cursor = end + 1n;\n }\n\n return allLogs;\n}\n\n/** Fetch vault events (AgentRegistered, Ragequit, etc.) */\nexport async function getVaultEvents(\n vaultAddress: Address,\n fromBlock: bigint,\n toBlock: bigint,\n): Promise<ChainEvent[]> {\n const logs = await getLogsChunked({\n address: vaultAddress,\n events: VAULT_EVENTS,\n fromBlock,\n toBlock,\n });\n\n return logs.map((log) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const eventName = (log as any).eventName || \"UnknownVaultEvent\";\n return logToChainEvent(log, eventName);\n });\n}\n\n/** Fetch governor events filtered to a specific vault. */\nexport async function getGovernorEvents(\n governorAddress: Address,\n vaultAddress: Address,\n fromBlock: bigint,\n toBlock: bigint,\n): Promise<ChainEvent[]> {\n if (governorAddress === \"0x0000000000000000000000000000000000000000\") {\n return []; // Governor not deployed yet\n }\n\n const logs = await getLogsChunked({\n address: governorAddress,\n events: GOVERNOR_EVENTS,\n fromBlock,\n toBlock,\n });\n\n // Filter governor events to only those involving our vault\n return logs\n .filter((log) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const args = (log as any).args;\n if (!args) return true;\n // ProposalCreated, ProposalExecuted, ProposalSettled have `vault` in args\n if (args.vault) {\n return (args.vault as string).toLowerCase() === vaultAddress.toLowerCase();\n }\n // VoteCast, ProposalCancelled don't have vault — include them\n // (agents care about all votes/cancellations on their governor)\n return true;\n })\n .map((log) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const eventName = (log as any).eventName || \"UnknownGovernorEvent\";\n return logToChainEvent(log, eventName);\n });\n}\n\n/** Get current block number from the RPC. */\nexport async function getCurrentBlock(): Promise<bigint> {\n const client = getPublicClient();\n return client.getBlockNumber();\n}\n"],"mappings":"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","names":["result"]}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|