@sherwoodagent/cli 0.25.3 → 0.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/dist/addresses-CQLJSZGN.js +35 -0
  2. package/dist/agent-QIQABFLV.js +7087 -0
  3. package/dist/agent-QIQABFLV.js.map +1 -0
  4. package/dist/{chat-DRKUZCOY.js → chat-N6LSZUSC.js} +45 -12
  5. package/dist/chat-N6LSZUSC.js.map +1 -0
  6. package/dist/{chunk-KEUEO4UE.js → chunk-2H6IGGKN.js} +1 -1
  7. package/dist/chunk-2H6IGGKN.js.map +1 -0
  8. package/dist/{chunk-H55III3L.js → chunk-3EMDYEAD.js} +7 -5
  9. package/dist/{chunk-H55III3L.js.map → chunk-3EMDYEAD.js.map} +1 -1
  10. package/dist/{chunk-6DWQIKGN.js → chunk-I3UVF2GD.js} +7 -5
  11. package/dist/{chunk-6DWQIKGN.js.map → chunk-I3UVF2GD.js.map} +1 -1
  12. package/dist/{chunk-4WG64CRK.js → chunk-IIBOFECO.js} +7 -5
  13. package/dist/{chunk-4WG64CRK.js.map → chunk-IIBOFECO.js.map} +1 -1
  14. package/dist/{chunk-ICUQY7TY.js → chunk-PQ5ZX6ZT.js} +39 -343
  15. package/dist/chunk-PQ5ZX6ZT.js.map +1 -0
  16. package/dist/{chunk-66VFSLPS.js → chunk-QGEIK4H5.js} +2 -2
  17. package/dist/chunk-T5BRUFWV.js +142 -0
  18. package/dist/chunk-T5BRUFWV.js.map +1 -0
  19. package/dist/chunk-WQOTLKVP.js +456 -0
  20. package/dist/chunk-WQOTLKVP.js.map +1 -0
  21. package/dist/{chunk-SBVHGUQJ.js → chunk-WRG7GAIA.js} +2 -2
  22. package/dist/{chunk-Y7LUFGIS.js → chunk-YRYPGJ66.js} +9 -7
  23. package/dist/{chunk-Y7LUFGIS.js.map → chunk-YRYPGJ66.js.map} +1 -1
  24. package/dist/{chunk-GWIW6DDG.js → chunk-ZPYN5ZAI.js} +53 -1
  25. package/dist/chunk-ZPYN5ZAI.js.map +1 -0
  26. package/dist/{client-CWQFYZ5Z.js → client-HBMSTSKK.js} +3 -3
  27. package/dist/{eas-652I6ULB.js → eas-D3KSAGWT.js} +6 -5
  28. package/dist/{governor-CY3GXU44.js → governor-3MYMDBRF.js} +6 -5
  29. package/dist/index.js +267 -220
  30. package/dist/index.js.map +1 -1
  31. package/dist/{ipfs-22YLNQ2C.js → ipfs-IGXLLJCF.js} +2 -2
  32. package/dist/{network-QEMP3DSP.js → network-X6GM7ROG.js} +6 -2
  33. package/dist/{price-FOCSYKGJ.js → price-DXNFNTV6.js} +8 -6
  34. package/dist/{price-FOCSYKGJ.js.map → price-DXNFNTV6.js.map} +1 -1
  35. package/dist/{research-LJKYDBCL.js → research-H3I4LALI.js} +8 -8
  36. package/dist/{research-ZX7T2ZIJ.js → research-NCESMYXK.js} +4 -4
  37. package/dist/research-NCESMYXK.js.map +1 -0
  38. package/dist/{session-7HKFQ7JZ.js → session-5JUUZYIL.js} +12 -10
  39. package/dist/{session-7HKFQ7JZ.js.map → session-5JUUZYIL.js.map} +1 -1
  40. package/dist/{trade-4SOHHD5R.js → trade-XDE6YCNY.js} +16 -14
  41. package/dist/{trade-4SOHHD5R.js.map → trade-XDE6YCNY.js.map} +1 -1
  42. package/dist/{xmtp-K555NJPU.js → xmtp-XTJ7HDVG.js} +6 -5
  43. package/dist/{xmtp-K555NJPU.js.map → xmtp-XTJ7HDVG.js.map} +1 -1
  44. package/package.json +1 -1
  45. package/dist/chat-DRKUZCOY.js.map +0 -1
  46. package/dist/chunk-GWIW6DDG.js.map +0 -1
  47. package/dist/chunk-ICUQY7TY.js.map +0 -1
  48. package/dist/chunk-KEUEO4UE.js.map +0 -1
  49. /package/dist/{client-CWQFYZ5Z.js.map → addresses-CQLJSZGN.js.map} +0 -0
  50. /package/dist/{chunk-66VFSLPS.js.map → chunk-QGEIK4H5.js.map} +0 -0
  51. /package/dist/{chunk-SBVHGUQJ.js.map → chunk-WRG7GAIA.js.map} +0 -0
  52. /package/dist/{eas-652I6ULB.js.map → client-HBMSTSKK.js.map} +0 -0
  53. /package/dist/{governor-CY3GXU44.js.map → eas-D3KSAGWT.js.map} +0 -0
  54. /package/dist/{ipfs-22YLNQ2C.js.map → governor-3MYMDBRF.js.map} +0 -0
  55. /package/dist/{network-QEMP3DSP.js.map → ipfs-IGXLLJCF.js.map} +0 -0
  56. /package/dist/{research-ZX7T2ZIJ.js.map → network-X6GM7ROG.js.map} +0 -0
  57. /package/dist/{research-LJKYDBCL.js.map → research-H3I4LALI.js.map} +0 -0
@@ -3,11 +3,11 @@ import {
3
3
  pinJSON,
4
4
  resolveMetadataSummary,
5
5
  uploadMetadata
6
- } from "./chunk-KEUEO4UE.js";
6
+ } from "./chunk-2H6IGGKN.js";
7
7
  export {
8
8
  fetchMetadata,
9
9
  pinJSON,
10
10
  resolveMetadataSummary,
11
11
  uploadMetadata
12
12
  };
13
- //# sourceMappingURL=ipfs-22YLNQ2C.js.map
13
+ //# sourceMappingURL=ipfs-IGXLLJCF.js.map
@@ -6,10 +6,12 @@ import {
6
6
  getExplorerUrl,
7
7
  getNetwork,
8
8
  getRpcUrl,
9
+ hyperevm,
10
+ hyperevmTestnet,
9
11
  isTestnet,
10
12
  robinhoodTestnet,
11
13
  setNetwork
12
- } from "./chunk-GWIW6DDG.js";
14
+ } from "./chunk-ZPYN5ZAI.js";
13
15
  import "./chunk-RGOTBJIN.js";
14
16
  export {
15
17
  CHAIN_REGISTRY,
@@ -19,8 +21,10 @@ export {
19
21
  getExplorerUrl,
20
22
  getNetwork,
21
23
  getRpcUrl,
24
+ hyperevm,
25
+ hyperevmTestnet,
22
26
  isTestnet,
23
27
  robinhoodTestnet,
24
28
  setNetwork
25
29
  };
26
- //# sourceMappingURL=network-QEMP3DSP.js.map
30
+ //# sourceMappingURL=network-X6GM7ROG.js.map
@@ -1,14 +1,16 @@
1
1
  import {
2
- SYNTHRA,
3
- UNISWAP,
4
2
  UNISWAP_QUOTER_V2_ABI
5
- } from "./chunk-ICUQY7TY.js";
3
+ } from "./chunk-PQ5ZX6ZT.js";
4
+ import {
5
+ SYNTHRA,
6
+ UNISWAP
7
+ } from "./chunk-WQOTLKVP.js";
6
8
  import {
7
9
  getPublicClient
8
- } from "./chunk-SBVHGUQJ.js";
10
+ } from "./chunk-WRG7GAIA.js";
9
11
  import {
10
12
  getNetwork
11
- } from "./chunk-GWIW6DDG.js";
13
+ } from "./chunk-ZPYN5ZAI.js";
12
14
  import "./chunk-RGOTBJIN.js";
13
15
 
14
16
  // src/lib/price.ts
@@ -153,4 +155,4 @@ export {
153
155
  getTokenPriceInAsset,
154
156
  getTokenPricesInAsset
155
157
  };
156
- //# sourceMappingURL=price-FOCSYKGJ.js.map
158
+ //# sourceMappingURL=price-DXNFNTV6.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/lib/price.ts"],"sourcesContent":["/**\n * Network-aware price quoting for portfolio valuation.\n *\n * Dispatches to the right DEX quoter based on network:\n * - Base / Base Sepolia → Uniswap QuoterV2 (struct params, 4-tuple return)\n * - Robinhood testnet → Direct pool slot0 (Synthra QuoterV2 can't resolve\n * proxy-deployed pools via CREATE2, so we read sqrtPriceX96 from the pool)\n *\n * Uniswap quoter uses eth_call (not view — it reverts internally).\n */\n\nimport type { Address } from \"viem\";\nimport { encodeFunctionData, decodeFunctionResult, parseUnits, formatUnits } from \"viem\";\nimport { getPublicClient } from \"./client.js\";\nimport { getNetwork } from \"./network.js\";\nimport { UNISWAP, SYNTHRA } from \"./addresses.js\";\nimport { UNISWAP_QUOTER_V2_ABI } from \"./abis.js\";\n\nexport interface TokenPrice {\n price: number; // 1 token = X asset units (human-readable)\n amountOut: bigint; // raw quoter output\n source: \"uniswap\" | \"synthra\";\n}\n\nconst ZERO: Address = \"0x0000000000000000000000000000000000000000\";\n\n/**\n * Get the price of one token denominated in the strategy's asset.\n * Uses the appropriate DEX quoter for the current network.\n */\nexport async function getTokenPriceInAsset(params: {\n token: Address;\n tokenDecimals: number;\n asset: Address;\n assetDecimals: number;\n feeTier: number;\n}): Promise<TokenPrice> {\n const { token, tokenDecimals, asset, assetDecimals, feeTier } = params;\n\n // Short-circuit: token IS the asset\n if (token.toLowerCase() === asset.toLowerCase()) {\n return { price: 1.0, amountOut: parseUnits(\"1\", assetDecimals), source: \"uniswap\" };\n }\n\n const network = getNetwork();\n const client = getPublicClient();\n\n if (network === \"robinhood-testnet\") {\n return quoteSynthra(client, token, tokenDecimals, asset, assetDecimals, feeTier);\n }\n\n return quoteUniswap(client, token, tokenDecimals, asset, assetDecimals, feeTier);\n}\n\n/**\n * Batch price lookup — parallel, graceful failure (null per failed quote).\n */\nexport async function getTokenPricesInAsset(params: {\n tokens: { token: Address; tokenDecimals: number; feeTier: number }[];\n asset: Address;\n assetDecimals: number;\n}): Promise<(TokenPrice | null)[]> {\n const { tokens, asset, assetDecimals } = params;\n\n const results = await Promise.allSettled(\n tokens.map((t) =>\n getTokenPriceInAsset({\n token: t.token,\n tokenDecimals: t.tokenDecimals,\n asset,\n assetDecimals,\n feeTier: t.feeTier,\n }),\n ),\n );\n\n return results.map((r) => (r.status === \"fulfilled\" ? r.value : null));\n}\n\n// ── Synthra direct pool pricing (Robinhood testnet) ──\n//\n// The Synthra QuoterV2 can't resolve proxy-deployed pools via CREATE2 (same\n// issue that led to SynthraDirectAdapter). Instead we look up the pool via\n// factory.getPool(), read slot0.sqrtPriceX96, and derive the spot price.\n\nconst POOL_SLOT0_ABI = [\n {\n type: \"function\" as const,\n name: \"slot0\",\n inputs: [],\n outputs: [\n { name: \"sqrtPriceX96\", type: \"uint160\" as const },\n { name: \"tick\", type: \"int24\" as const },\n { name: \"observationIndex\", type: \"uint16\" as const },\n { name: \"observationCardinality\", type: \"uint16\" as const },\n { name: \"observationCardinalityNext\", type: \"uint16\" as const },\n { name: \"feeProtocol\", type: \"uint8\" as const },\n { name: \"unlocked\", type: \"bool\" as const },\n ],\n stateMutability: \"view\" as const,\n },\n] as const;\n\nconst POOL_TOKEN0_ABI = [\n {\n type: \"function\" as const,\n name: \"token0\",\n inputs: [],\n outputs: [{ name: \"\", type: \"address\" as const }],\n stateMutability: \"view\" as const,\n },\n] as const;\n\nconst FACTORY_GET_POOL_ABI = [\n {\n type: \"function\" as const,\n name: \"getPool\",\n inputs: [\n { name: \"tokenA\", type: \"address\" as const },\n { name: \"tokenB\", type: \"address\" as const },\n { name: \"fee\", type: \"uint24\" as const },\n ],\n outputs: [{ name: \"\", type: \"address\" as const }],\n stateMutability: \"view\" as const,\n },\n] as const;\n\n/**\n * Derive a spot price from a Uniswap V3 / Synthra V3 pool's sqrtPriceX96.\n *\n * sqrtPriceX96 = sqrt(token1/token0) × 2^96\n * price (token1 per token0) = (sqrtPriceX96 / 2^96)^2\n *\n * Returns the price of `tokenIn` denominated in `tokenOut`.\n */\nfunction priceFromSqrtPriceX96(\n sqrtPriceX96: bigint,\n token0Decimals: number,\n token1Decimals: number,\n tokenInIsToken0: boolean,\n): number {\n const Q96 = 2 ** 96;\n const ratio = Number(sqrtPriceX96) / Q96;\n // raw price = token1 per token0 (adjusted for same-decimal tokens only)\n const rawPrice = ratio * ratio;\n // decimal adjustment: token0Decimals - token1Decimals\n const decimalAdjust = 10 ** (token0Decimals - token1Decimals);\n const token1PerToken0 = rawPrice * decimalAdjust;\n\n // If tokenIn is token0, price = how many token1 per token0 → token1PerToken0\n // If tokenIn is token1, price = how many token0 per token1 → 1/token1PerToken0\n return tokenInIsToken0 ? token1PerToken0 : 1 / token1PerToken0;\n}\n\nasync function quoteSynthra(\n client: ReturnType<typeof getPublicClient>,\n tokenIn: Address,\n tokenInDecimals: number,\n tokenOut: Address,\n tokenOutDecimals: number,\n fee: number,\n): Promise<TokenPrice> {\n const factoryAddr = SYNTHRA().FACTORY;\n if (factoryAddr === ZERO) {\n throw new Error(\"Synthra Factory not deployed on this network\");\n }\n\n // 1. Resolve pool via factory.getPool()\n const pool = await client.readContract({\n address: factoryAddr,\n abi: FACTORY_GET_POOL_ABI,\n functionName: \"getPool\",\n args: [tokenIn, tokenOut, fee],\n });\n\n if (!pool || pool === ZERO) {\n throw new Error(`No Synthra pool for ${tokenIn}↔${tokenOut} fee=${fee}`);\n }\n\n // 2. Read slot0 and token0 from the pool\n const [slot0, token0] = await Promise.all([\n client.readContract({ address: pool, abi: POOL_SLOT0_ABI, functionName: \"slot0\" }),\n client.readContract({ address: pool, abi: POOL_TOKEN0_ABI, functionName: \"token0\" }),\n ]);\n\n const sqrtPriceX96 = slot0[0];\n if (sqrtPriceX96 === 0n) {\n throw new Error(`Pool ${pool} not initialized (sqrtPriceX96 = 0)`);\n }\n\n // 3. Determine token ordering\n const tokenInIsToken0 = tokenIn.toLowerCase() === token0.toLowerCase();\n const t0Decimals = tokenInIsToken0 ? tokenInDecimals : tokenOutDecimals;\n const t1Decimals = tokenInIsToken0 ? tokenOutDecimals : tokenInDecimals;\n\n const price = priceFromSqrtPriceX96(sqrtPriceX96, t0Decimals, t1Decimals, tokenInIsToken0);\n\n // Compute amountOut for 1 tokenIn\n const oneToken = parseUnits(\"1\", tokenInDecimals);\n const amountOut = BigInt(Math.round(price * Number(parseUnits(\"1\", tokenOutDecimals))));\n\n return { price, amountOut, source: \"synthra\" };\n}\n\n// ── Uniswap QuoterV2 (Base / Base Sepolia) ──\n\nasync function quoteUniswap(\n client: ReturnType<typeof getPublicClient>,\n tokenIn: Address,\n tokenInDecimals: number,\n tokenOut: Address,\n tokenOutDecimals: number,\n fee: number,\n): Promise<TokenPrice> {\n const quoterAddr = UNISWAP().QUOTER_V2;\n if (quoterAddr === ZERO) {\n throw new Error(\"Uniswap QuoterV2 not deployed on this network\");\n }\n\n const oneToken = parseUnits(\"1\", tokenInDecimals);\n\n const calldata = encodeFunctionData({\n abi: UNISWAP_QUOTER_V2_ABI,\n functionName: \"quoteExactInputSingle\",\n args: [\n {\n tokenIn,\n tokenOut,\n amountIn: oneToken,\n fee,\n sqrtPriceLimitX96: 0n,\n },\n ],\n });\n\n const { data } = await client.call({ to: quoterAddr, data: calldata });\n\n if (!data) {\n throw new Error(`Uniswap quoter returned no data for ${tokenIn}→${tokenOut} fee=${fee}`);\n }\n\n const [amountOut] = decodeFunctionResult({\n abi: UNISWAP_QUOTER_V2_ABI,\n functionName: \"quoteExactInputSingle\",\n data,\n }) as [bigint, bigint, number, bigint];\n\n const price = Number(formatUnits(amountOut, tokenOutDecimals));\n return { price, amountOut, source: \"uniswap\" };\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/lib/price.ts"],"sourcesContent":["/**\n * Network-aware price quoting for portfolio valuation.\n *\n * Dispatches to the right DEX quoter based on network:\n * - Base / Base Sepolia → Uniswap QuoterV2 (struct params, 4-tuple return)\n * - Robinhood testnet → Direct pool slot0 (Synthra QuoterV2 can't resolve\n * proxy-deployed pools via CREATE2, so we read sqrtPriceX96 from the pool)\n *\n * Uniswap quoter uses eth_call (not view — it reverts internally).\n */\n\nimport type { Address } from \"viem\";\nimport { encodeFunctionData, decodeFunctionResult, parseUnits, formatUnits } from \"viem\";\nimport { getPublicClient } from \"./client.js\";\nimport { getNetwork } from \"./network.js\";\nimport { UNISWAP, SYNTHRA } from \"./addresses.js\";\nimport { UNISWAP_QUOTER_V2_ABI } from \"./abis.js\";\n\nexport interface TokenPrice {\n price: number; // 1 token = X asset units (human-readable)\n amountOut: bigint; // raw quoter output\n source: \"uniswap\" | \"synthra\";\n}\n\nconst ZERO: Address = \"0x0000000000000000000000000000000000000000\";\n\n/**\n * Get the price of one token denominated in the strategy's asset.\n * Uses the appropriate DEX quoter for the current network.\n */\nexport async function getTokenPriceInAsset(params: {\n token: Address;\n tokenDecimals: number;\n asset: Address;\n assetDecimals: number;\n feeTier: number;\n}): Promise<TokenPrice> {\n const { token, tokenDecimals, asset, assetDecimals, feeTier } = params;\n\n // Short-circuit: token IS the asset\n if (token.toLowerCase() === asset.toLowerCase()) {\n return { price: 1.0, amountOut: parseUnits(\"1\", assetDecimals), source: \"uniswap\" };\n }\n\n const network = getNetwork();\n const client = getPublicClient();\n\n if (network === \"robinhood-testnet\") {\n return quoteSynthra(client, token, tokenDecimals, asset, assetDecimals, feeTier);\n }\n\n return quoteUniswap(client, token, tokenDecimals, asset, assetDecimals, feeTier);\n}\n\n/**\n * Batch price lookup — parallel, graceful failure (null per failed quote).\n */\nexport async function getTokenPricesInAsset(params: {\n tokens: { token: Address; tokenDecimals: number; feeTier: number }[];\n asset: Address;\n assetDecimals: number;\n}): Promise<(TokenPrice | null)[]> {\n const { tokens, asset, assetDecimals } = params;\n\n const results = await Promise.allSettled(\n tokens.map((t) =>\n getTokenPriceInAsset({\n token: t.token,\n tokenDecimals: t.tokenDecimals,\n asset,\n assetDecimals,\n feeTier: t.feeTier,\n }),\n ),\n );\n\n return results.map((r) => (r.status === \"fulfilled\" ? r.value : null));\n}\n\n// ── Synthra direct pool pricing (Robinhood testnet) ──\n//\n// The Synthra QuoterV2 can't resolve proxy-deployed pools via CREATE2 (same\n// issue that led to SynthraDirectAdapter). Instead we look up the pool via\n// factory.getPool(), read slot0.sqrtPriceX96, and derive the spot price.\n\nconst POOL_SLOT0_ABI = [\n {\n type: \"function\" as const,\n name: \"slot0\",\n inputs: [],\n outputs: [\n { name: \"sqrtPriceX96\", type: \"uint160\" as const },\n { name: \"tick\", type: \"int24\" as const },\n { name: \"observationIndex\", type: \"uint16\" as const },\n { name: \"observationCardinality\", type: \"uint16\" as const },\n { name: \"observationCardinalityNext\", type: \"uint16\" as const },\n { name: \"feeProtocol\", type: \"uint8\" as const },\n { name: \"unlocked\", type: \"bool\" as const },\n ],\n stateMutability: \"view\" as const,\n },\n] as const;\n\nconst POOL_TOKEN0_ABI = [\n {\n type: \"function\" as const,\n name: \"token0\",\n inputs: [],\n outputs: [{ name: \"\", type: \"address\" as const }],\n stateMutability: \"view\" as const,\n },\n] as const;\n\nconst FACTORY_GET_POOL_ABI = [\n {\n type: \"function\" as const,\n name: \"getPool\",\n inputs: [\n { name: \"tokenA\", type: \"address\" as const },\n { name: \"tokenB\", type: \"address\" as const },\n { name: \"fee\", type: \"uint24\" as const },\n ],\n outputs: [{ name: \"\", type: \"address\" as const }],\n stateMutability: \"view\" as const,\n },\n] as const;\n\n/**\n * Derive a spot price from a Uniswap V3 / Synthra V3 pool's sqrtPriceX96.\n *\n * sqrtPriceX96 = sqrt(token1/token0) × 2^96\n * price (token1 per token0) = (sqrtPriceX96 / 2^96)^2\n *\n * Returns the price of `tokenIn` denominated in `tokenOut`.\n */\nfunction priceFromSqrtPriceX96(\n sqrtPriceX96: bigint,\n token0Decimals: number,\n token1Decimals: number,\n tokenInIsToken0: boolean,\n): number {\n const Q96 = 2 ** 96;\n const ratio = Number(sqrtPriceX96) / Q96;\n // raw price = token1 per token0 (adjusted for same-decimal tokens only)\n const rawPrice = ratio * ratio;\n // decimal adjustment: token0Decimals - token1Decimals\n const decimalAdjust = 10 ** (token0Decimals - token1Decimals);\n const token1PerToken0 = rawPrice * decimalAdjust;\n\n // If tokenIn is token0, price = how many token1 per token0 → token1PerToken0\n // If tokenIn is token1, price = how many token0 per token1 → 1/token1PerToken0\n return tokenInIsToken0 ? token1PerToken0 : 1 / token1PerToken0;\n}\n\nasync function quoteSynthra(\n client: ReturnType<typeof getPublicClient>,\n tokenIn: Address,\n tokenInDecimals: number,\n tokenOut: Address,\n tokenOutDecimals: number,\n fee: number,\n): Promise<TokenPrice> {\n const factoryAddr = SYNTHRA().FACTORY;\n if (factoryAddr === ZERO) {\n throw new Error(\"Synthra Factory not deployed on this network\");\n }\n\n // 1. Resolve pool via factory.getPool()\n const pool = await client.readContract({\n address: factoryAddr,\n abi: FACTORY_GET_POOL_ABI,\n functionName: \"getPool\",\n args: [tokenIn, tokenOut, fee],\n });\n\n if (!pool || pool === ZERO) {\n throw new Error(`No Synthra pool for ${tokenIn}↔${tokenOut} fee=${fee}`);\n }\n\n // 2. Read slot0 and token0 from the pool\n const [slot0, token0] = await Promise.all([\n client.readContract({ address: pool, abi: POOL_SLOT0_ABI, functionName: \"slot0\" }),\n client.readContract({ address: pool, abi: POOL_TOKEN0_ABI, functionName: \"token0\" }),\n ]);\n\n const sqrtPriceX96 = slot0[0];\n if (sqrtPriceX96 === 0n) {\n throw new Error(`Pool ${pool} not initialized (sqrtPriceX96 = 0)`);\n }\n\n // 3. Determine token ordering\n const tokenInIsToken0 = tokenIn.toLowerCase() === token0.toLowerCase();\n const t0Decimals = tokenInIsToken0 ? tokenInDecimals : tokenOutDecimals;\n const t1Decimals = tokenInIsToken0 ? tokenOutDecimals : tokenInDecimals;\n\n const price = priceFromSqrtPriceX96(sqrtPriceX96, t0Decimals, t1Decimals, tokenInIsToken0);\n\n // Compute amountOut for 1 tokenIn\n const oneToken = parseUnits(\"1\", tokenInDecimals);\n const amountOut = BigInt(Math.round(price * Number(parseUnits(\"1\", tokenOutDecimals))));\n\n return { price, amountOut, source: \"synthra\" };\n}\n\n// ── Uniswap QuoterV2 (Base / Base Sepolia) ──\n\nasync function quoteUniswap(\n client: ReturnType<typeof getPublicClient>,\n tokenIn: Address,\n tokenInDecimals: number,\n tokenOut: Address,\n tokenOutDecimals: number,\n fee: number,\n): Promise<TokenPrice> {\n const quoterAddr = UNISWAP().QUOTER_V2;\n if (quoterAddr === ZERO) {\n throw new Error(\"Uniswap QuoterV2 not deployed on this network\");\n }\n\n const oneToken = parseUnits(\"1\", tokenInDecimals);\n\n const calldata = encodeFunctionData({\n abi: UNISWAP_QUOTER_V2_ABI,\n functionName: \"quoteExactInputSingle\",\n args: [\n {\n tokenIn,\n tokenOut,\n amountIn: oneToken,\n fee,\n sqrtPriceLimitX96: 0n,\n },\n ],\n });\n\n const { data } = await client.call({ to: quoterAddr, data: calldata });\n\n if (!data) {\n throw new Error(`Uniswap quoter returned no data for ${tokenIn}→${tokenOut} fee=${fee}`);\n }\n\n const [amountOut] = decodeFunctionResult({\n abi: UNISWAP_QUOTER_V2_ABI,\n functionName: \"quoteExactInputSingle\",\n data,\n }) as [bigint, bigint, number, bigint];\n\n const price = Number(formatUnits(amountOut, tokenOutDecimals));\n return { price, amountOut, source: \"uniswap\" };\n}\n"],"mappings":"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","names":[]}
@@ -2,12 +2,12 @@ import {
2
2
  MESSARI_COST_ESTIMATE,
3
3
  NANSEN_COST_ESTIMATE,
4
4
  getResearchProvider
5
- } from "./chunk-66VFSLPS.js";
5
+ } from "./chunk-QGEIK4H5.js";
6
6
  import {
7
7
  formatContractError,
8
8
  getAccount
9
- } from "./chunk-SBVHGUQJ.js";
10
- import "./chunk-GWIW6DDG.js";
9
+ } from "./chunk-WRG7GAIA.js";
10
+ import "./chunk-ZPYN5ZAI.js";
11
11
  import "./chunk-RGOTBJIN.js";
12
12
 
13
13
  // src/commands/research.ts
@@ -16,7 +16,7 @@ import ora from "ora";
16
16
  import { confirm } from "@inquirer/prompts";
17
17
  import { isAddress } from "viem";
18
18
  async function loadXmtp() {
19
- return import("./xmtp-K555NJPU.js");
19
+ return import("./xmtp-XTJ7HDVG.js");
20
20
  }
21
21
  var COST_ESTIMATES = {
22
22
  messari: MESSARI_COST_ESTIMATE,
@@ -82,8 +82,8 @@ function formatValue(value) {
82
82
  return String(value);
83
83
  }
84
84
  async function postResearch(syndicateName, result, prompt) {
85
- const { pinJSON } = await import("./ipfs-22YLNQ2C.js");
86
- const { createResearchAttestation, getEasScanUrl } = await import("./eas-652I6ULB.js");
85
+ const { pinJSON } = await import("./ipfs-IGXLLJCF.js");
86
+ const { createResearchAttestation, getEasScanUrl } = await import("./eas-D3KSAGWT.js");
87
87
  const xmtp = await loadXmtp();
88
88
  const pinSpinner = ora("Pinning research result to IPFS...").start();
89
89
  let resultUri;
@@ -113,7 +113,7 @@ async function postResearch(syndicateName, result, prompt) {
113
113
  let attestationUid;
114
114
  try {
115
115
  const { getChainContracts } = await import("./config-YXZKPSZB.js");
116
- const { getChain } = await import("./network-QEMP3DSP.js");
116
+ const { getChain } = await import("./network-X6GM7ROG.js");
117
117
  const vaultRecipient = getChainContracts(getChain().id).vault;
118
118
  const { uid } = await createResearchAttestation(
119
119
  result.provider,
@@ -312,4 +312,4 @@ function registerResearchCommands(program) {
312
312
  export {
313
313
  registerResearchCommands
314
314
  };
315
- //# sourceMappingURL=research-LJKYDBCL.js.map
315
+ //# sourceMappingURL=research-H3I4LALI.js.map
@@ -2,13 +2,13 @@ import {
2
2
  MessariProvider,
3
3
  NansenProvider,
4
4
  getResearchProvider
5
- } from "./chunk-66VFSLPS.js";
6
- import "./chunk-SBVHGUQJ.js";
7
- import "./chunk-GWIW6DDG.js";
5
+ } from "./chunk-QGEIK4H5.js";
6
+ import "./chunk-WRG7GAIA.js";
7
+ import "./chunk-ZPYN5ZAI.js";
8
8
  import "./chunk-RGOTBJIN.js";
9
9
  export {
10
10
  MessariProvider,
11
11
  NansenProvider,
12
12
  getResearchProvider
13
13
  };
14
- //# sourceMappingURL=research-ZX7T2ZIJ.js.map
14
+ //# sourceMappingURL=research-NCESMYXK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -6,22 +6,24 @@ import {
6
6
  } from "./chunk-W2ZUPR3W.js";
7
7
  import {
8
8
  resolveSyndicate
9
- } from "./chunk-Y7LUFGIS.js";
9
+ } from "./chunk-YRYPGJ66.js";
10
10
  import {
11
11
  PROPOSAL_STATES,
12
12
  getProposal
13
- } from "./chunk-H55III3L.js";
13
+ } from "./chunk-3EMDYEAD.js";
14
14
  import {
15
15
  resolveMetadataSummary
16
- } from "./chunk-KEUEO4UE.js";
16
+ } from "./chunk-2H6IGGKN.js";
17
17
  import {
18
- SHERWOOD,
19
18
  SYNDICATE_VAULT_ABI
20
- } from "./chunk-ICUQY7TY.js";
19
+ } from "./chunk-PQ5ZX6ZT.js";
20
+ import {
21
+ SHERWOOD
22
+ } from "./chunk-WQOTLKVP.js";
21
23
  import {
22
24
  getPublicClient
23
- } from "./chunk-SBVHGUQJ.js";
24
- import "./chunk-GWIW6DDG.js";
25
+ } from "./chunk-WRG7GAIA.js";
26
+ import "./chunk-ZPYN5ZAI.js";
25
27
  import {
26
28
  loadConfig
27
29
  } from "./chunk-RGOTBJIN.js";
@@ -185,7 +187,7 @@ async function enrichProposalEvents(events, metadataCache) {
185
187
 
186
188
  // src/commands/session.ts
187
189
  async function loadXmtp() {
188
- return import("./xmtp-K555NJPU.js");
190
+ return import("./xmtp-XTJ7HDVG.js");
189
191
  }
190
192
  async function resolveGovernor(vaultAddress) {
191
193
  const client = getPublicClient();
@@ -422,7 +424,7 @@ function registerSessionCommands(program) {
422
424
  );
423
425
  session.command("cron <name>").description("Manage participation crons (OpenClaw agents)").option("--remove", "Remove participation crons", false).option("--status", "Show cron status", false).action(async (name, opts) => {
424
426
  const { isOpenClaw, registerSyndicateCrons, unregisterSyndicateCrons, getSyndicateCronStatus } = await import("./cron-EOULYO3R.js");
425
- const { isTestnet } = await import("./network-QEMP3DSP.js");
427
+ const { isTestnet } = await import("./network-X6GM7ROG.js");
426
428
  const { getNotifyTo } = await import("./config-YXZKPSZB.js");
427
429
  if (!isOpenClaw()) {
428
430
  console.log(chalk.yellow("Not running on OpenClaw \u2014 cron commands unavailable"));
@@ -464,4 +466,4 @@ function registerSessionCommands(program) {
464
466
  export {
465
467
  registerSessionCommands
466
468
  };
467
- //# sourceMappingURL=session-7HKFQ7JZ.js.map
469
+ //# sourceMappingURL=session-5JUUZYIL.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/commands/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 enrichProposalEvents,\n type ChainEvent,\n} from \"../lib/events.js\";\nimport type { ChatEnvelope } from \"../lib/types.js\";\nimport { loadConfig } from \"../lib/config.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, excluding our own messages\n const cursorMs = lastMessageTimestamp * 1000;\n const ownInboxId = loadConfig().xmtpInboxId;\n const newMessages = recent.filter(\n (m) =>\n m.sentAt.getTime() > cursorMs &&\n (!ownInboxId || m.senderInboxId !== ownInboxId),\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 // Enrich proposal events with IPFS metadata (name, description, state)\n try {\n events = await enrichProposalEvents(events);\n } catch {\n // IPFS/RPC unreachable — continue with raw events\n }\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 // Cache for proposal metadata — immutable once pinned, safe to reuse across polls\n const metadataCache = new Map<string, { name: string; description: string }>();\n\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 const streamOwnInboxId = loadConfig().xmtpInboxId;\n xmtpCleanup = await xmtp.streamMessages(groupId, (msg) => {\n // Skip own messages to prevent self-replies\n if (streamOwnInboxId && msg.senderInboxId === streamOwnInboxId) return;\n\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 let events = [...vaultEvents, ...govEvents].sort(\n (a, b) => a.block - b.block,\n );\n\n // Enrich proposal events with IPFS metadata (reuse cache across polls)\n try {\n events = await enrichProposalEvents(events, metadataCache);\n } catch {\n // IPFS/RPC unreachable — continue with raw events\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 * 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\";\nimport { getProposal, PROPOSAL_STATES } from \"./governor.js\";\nimport { resolveMetadataSummary } from \"./ipfs.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, uint8 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\n// ── Proposal event enrichment ──\n\nconst PROPOSAL_EVENT_TYPES = new Set([\n \"ProposalCreated\",\n \"VoteCast\",\n \"ProposalExecuted\",\n \"ProposalSettled\",\n \"ProposalCancelled\",\n]);\n\n/**\n * Enrich proposal-related events with IPFS metadata (name, description)\n * and current on-chain state. Best-effort — events are returned un-enriched\n * if RPC or IPFS calls fail.\n *\n * An optional metadataCache avoids redundant IPFS fetches across poll cycles\n * in streaming mode (proposal metadata is immutable once pinned).\n */\nexport async function enrichProposalEvents(\n events: ChainEvent[],\n metadataCache?: Map<string, { name: string; description: string }>,\n): Promise<ChainEvent[]> {\n const cache = metadataCache ?? new Map<string, { name: string; description: string }>();\n\n const proposalEvents = events.filter((e) => PROPOSAL_EVENT_TYPES.has(e.type));\n if (proposalEvents.length === 0) return events;\n\n // Collect unique proposalIds and their metadata sources\n const idsNeedingLookup = new Set<string>();\n const createdURIs = new Map<string, string>(); // proposalId → metadataURI from event args\n\n for (const event of proposalEvents) {\n const pid = event.args.proposalId;\n if (!pid) continue;\n\n if (event.type === \"ProposalCreated\" && event.args.metadataURI) {\n createdURIs.set(pid, event.args.metadataURI);\n } else if (!cache.has(pid)) {\n idsNeedingLookup.add(pid);\n }\n }\n\n // Fetch on-chain proposal data for non-Created events (parallel, deduplicated)\n const proposalData = new Map<string, { metadataURI: string; state: number }>();\n\n await Promise.all(\n Array.from(idsNeedingLookup).map(async (pid) => {\n try {\n const p = await getProposal(BigInt(pid));\n proposalData.set(pid, { metadataURI: p.metadataURI, state: p.state });\n } catch {\n // RPC failure — skip enrichment for this proposalId\n }\n }),\n );\n\n // Resolve IPFS metadata (parallel, deduplicated, uses cache)\n const allURIs = new Map<string, string>();\n for (const [pid, uri] of createdURIs) allURIs.set(pid, uri);\n for (const [pid, data] of proposalData) {\n if (!allURIs.has(pid)) allURIs.set(pid, data.metadataURI);\n }\n\n await Promise.all(\n Array.from(allURIs.entries()).map(async ([pid, uri]) => {\n if (cache.has(pid) || !uri) return;\n const summary = await resolveMetadataSummary(uri);\n if (summary) cache.set(pid, summary);\n }),\n );\n\n // Inject enrichment fields into event args\n return events.map((event) => {\n if (!PROPOSAL_EVENT_TYPES.has(event.type)) return event;\n const pid = event.args.proposalId;\n if (!pid) return event;\n\n const meta = cache.get(pid);\n const pData = proposalData.get(pid);\n const enrichedArgs = { ...event.args };\n\n if (meta) {\n enrichedArgs.proposalName = meta.name;\n enrichedArgs.proposalDescription = meta.description;\n }\n\n if (event.type === \"ProposalCreated\") {\n enrichedArgs.proposalState = \"Pending\";\n } else if (pData) {\n enrichedArgs.proposalState = PROPOSAL_STATES[pData.state] || \"Unknown\";\n }\n\n return { ...event, args: enrichedArgs };\n });\n}\n"],"mappings":"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","names":["result"]}
1
+ {"version":3,"sources":["../src/commands/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 enrichProposalEvents,\n type ChainEvent,\n} from \"../lib/events.js\";\nimport type { ChatEnvelope } from \"../lib/types.js\";\nimport { loadConfig } from \"../lib/config.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, excluding our own messages\n const cursorMs = lastMessageTimestamp * 1000;\n const ownInboxId = loadConfig().xmtpInboxId;\n const newMessages = recent.filter(\n (m) =>\n m.sentAt.getTime() > cursorMs &&\n (!ownInboxId || m.senderInboxId !== ownInboxId),\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 // Enrich proposal events with IPFS metadata (name, description, state)\n try {\n events = await enrichProposalEvents(events);\n } catch {\n // IPFS/RPC unreachable — continue with raw events\n }\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 // Cache for proposal metadata — immutable once pinned, safe to reuse across polls\n const metadataCache = new Map<string, { name: string; description: string }>();\n\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 const streamOwnInboxId = loadConfig().xmtpInboxId;\n xmtpCleanup = await xmtp.streamMessages(groupId, (msg) => {\n // Skip own messages to prevent self-replies\n if (streamOwnInboxId && msg.senderInboxId === streamOwnInboxId) return;\n\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 let events = [...vaultEvents, ...govEvents].sort(\n (a, b) => a.block - b.block,\n );\n\n // Enrich proposal events with IPFS metadata (reuse cache across polls)\n try {\n events = await enrichProposalEvents(events, metadataCache);\n } catch {\n // IPFS/RPC unreachable — continue with raw events\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 * 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\";\nimport { getProposal, PROPOSAL_STATES } from \"./governor.js\";\nimport { resolveMetadataSummary } from \"./ipfs.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, uint8 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\n// ── Proposal event enrichment ──\n\nconst PROPOSAL_EVENT_TYPES = new Set([\n \"ProposalCreated\",\n \"VoteCast\",\n \"ProposalExecuted\",\n \"ProposalSettled\",\n \"ProposalCancelled\",\n]);\n\n/**\n * Enrich proposal-related events with IPFS metadata (name, description)\n * and current on-chain state. Best-effort — events are returned un-enriched\n * if RPC or IPFS calls fail.\n *\n * An optional metadataCache avoids redundant IPFS fetches across poll cycles\n * in streaming mode (proposal metadata is immutable once pinned).\n */\nexport async function enrichProposalEvents(\n events: ChainEvent[],\n metadataCache?: Map<string, { name: string; description: string }>,\n): Promise<ChainEvent[]> {\n const cache = metadataCache ?? new Map<string, { name: string; description: string }>();\n\n const proposalEvents = events.filter((e) => PROPOSAL_EVENT_TYPES.has(e.type));\n if (proposalEvents.length === 0) return events;\n\n // Collect unique proposalIds and their metadata sources\n const idsNeedingLookup = new Set<string>();\n const createdURIs = new Map<string, string>(); // proposalId → metadataURI from event args\n\n for (const event of proposalEvents) {\n const pid = event.args.proposalId;\n if (!pid) continue;\n\n if (event.type === \"ProposalCreated\" && event.args.metadataURI) {\n createdURIs.set(pid, event.args.metadataURI);\n } else if (!cache.has(pid)) {\n idsNeedingLookup.add(pid);\n }\n }\n\n // Fetch on-chain proposal data for non-Created events (parallel, deduplicated)\n const proposalData = new Map<string, { metadataURI: string; state: number }>();\n\n await Promise.all(\n Array.from(idsNeedingLookup).map(async (pid) => {\n try {\n const p = await getProposal(BigInt(pid));\n proposalData.set(pid, { metadataURI: p.metadataURI, state: p.state });\n } catch {\n // RPC failure — skip enrichment for this proposalId\n }\n }),\n );\n\n // Resolve IPFS metadata (parallel, deduplicated, uses cache)\n const allURIs = new Map<string, string>();\n for (const [pid, uri] of createdURIs) allURIs.set(pid, uri);\n for (const [pid, data] of proposalData) {\n if (!allURIs.has(pid)) allURIs.set(pid, data.metadataURI);\n }\n\n await Promise.all(\n Array.from(allURIs.entries()).map(async ([pid, uri]) => {\n if (cache.has(pid) || !uri) return;\n const summary = await resolveMetadataSummary(uri);\n if (summary) cache.set(pid, summary);\n }),\n );\n\n // Inject enrichment fields into event args\n return events.map((event) => {\n if (!PROPOSAL_EVENT_TYPES.has(event.type)) return event;\n const pid = event.args.proposalId;\n if (!pid) return event;\n\n const meta = cache.get(pid);\n const pData = proposalData.get(pid);\n const enrichedArgs = { ...event.args };\n\n if (meta) {\n enrichedArgs.proposalName = meta.name;\n enrichedArgs.proposalDescription = meta.description;\n }\n\n if (event.type === \"ProposalCreated\") {\n enrichedArgs.proposalState = \"Pending\";\n } else if (pData) {\n enrichedArgs.proposalState = PROPOSAL_STATES[pData.state] || \"Unknown\";\n }\n\n return { ...event, args: enrichedArgs };\n });\n}\n"],"mappings":"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","names":["result"]}
@@ -1,23 +1,25 @@
1
1
  import {
2
2
  getResearchProvider
3
- } from "./chunk-66VFSLPS.js";
3
+ } from "./chunk-QGEIK4H5.js";
4
4
  import {
5
5
  UniswapProvider,
6
6
  chatCompletion,
7
7
  getQuote
8
- } from "./chunk-4WG64CRK.js";
8
+ } from "./chunk-IIBOFECO.js";
9
+ import {
10
+ ERC20_ABI
11
+ } from "./chunk-PQ5ZX6ZT.js";
9
12
  import {
10
- ERC20_ABI,
11
13
  TOKENS
12
- } from "./chunk-ICUQY7TY.js";
14
+ } from "./chunk-WQOTLKVP.js";
13
15
  import {
14
16
  formatContractError,
15
17
  getAccount,
16
18
  getPublicClient
17
- } from "./chunk-SBVHGUQJ.js";
19
+ } from "./chunk-WRG7GAIA.js";
18
20
  import {
19
21
  getExplorerUrl
20
- } from "./chunk-GWIW6DDG.js";
22
+ } from "./chunk-ZPYN5ZAI.js";
21
23
  import {
22
24
  loadConfig,
23
25
  saveConfig
@@ -330,7 +332,7 @@ async function getCurrentPrice(tokenAddress, tokenDecimals, feeTier) {
330
332
  // src/commands/trade.ts
331
333
  var uniswap = new UniswapProvider();
332
334
  async function loadXmtp() {
333
- return import("./xmtp-K555NJPU.js");
335
+ return import("./xmtp-XTJ7HDVG.js");
334
336
  }
335
337
  var ETH_ADDRESS = "0x0000000000000000000000000000000000000000";
336
338
  var KNOWN_MEMECOINS = {
@@ -514,7 +516,7 @@ function registerTradeCommands(program) {
514
516
  }
515
517
  const wrapSpinner = ora("Wrapping ETH \u2192 WETH...").start();
516
518
  try {
517
- const { writeContractWithRetry, waitForReceipt: waitForReceiptFn } = await import("./client-CWQFYZ5Z.js");
519
+ const { writeContractWithRetry, waitForReceipt: waitForReceiptFn } = await import("./client-HBMSTSKK.js");
518
520
  const wethAddr = TOKENS().WETH;
519
521
  const wrapHash = await writeContractWithRetry({
520
522
  address: wethAddr,
@@ -523,7 +525,7 @@ function registerTradeCommands(program) {
523
525
  args: [],
524
526
  value: inputAmount,
525
527
  account,
526
- chain: (await import("./network-QEMP3DSP.js")).getChain()
528
+ chain: (await import("./network-X6GM7ROG.js")).getChain()
527
529
  });
528
530
  await waitForReceiptFn(wrapHash);
529
531
  wrapSpinner.succeed(`Wrapped ${opts.amount} ETH \u2192 WETH`);
@@ -637,9 +639,9 @@ function registerTradeCommands(program) {
637
639
  }
638
640
  console.log(` Tx: ${chalk.dim(getExplorerUrl(txHash))}`);
639
641
  try {
640
- const { createTradeAttestation, getEasScanUrl } = await import("./eas-652I6ULB.js");
642
+ const { createTradeAttestation, getEasScanUrl } = await import("./eas-D3KSAGWT.js");
641
643
  const { getChainContracts } = await import("./config-YXZKPSZB.js");
642
- const { getChain: getActiveChain } = await import("./network-QEMP3DSP.js");
644
+ const { getChain: getActiveChain } = await import("./network-X6GM7ROG.js");
643
645
  const vaultRecipient = getChainContracts(getActiveChain().id).vault;
644
646
  const { uid } = await createTradeAttestation(
645
647
  inputAddr,
@@ -765,9 +767,9 @@ function registerTradeCommands(program) {
765
767
  }
766
768
  console.log(` Tx: ${chalk.dim(getExplorerUrl(txHash))}`);
767
769
  try {
768
- const { createTradeAttestation, getEasScanUrl } = await import("./eas-652I6ULB.js");
770
+ const { createTradeAttestation, getEasScanUrl } = await import("./eas-D3KSAGWT.js");
769
771
  const { getChainContracts } = await import("./config-YXZKPSZB.js");
770
- const { getChain: getActiveChain } = await import("./network-QEMP3DSP.js");
772
+ const { getChain: getActiveChain } = await import("./network-X6GM7ROG.js");
771
773
  const vaultRecipient = getChainContracts(getActiveChain().id).vault;
772
774
  const { uid } = await createTradeAttestation(
773
775
  tokenAddr,
@@ -942,4 +944,4 @@ function sleep(ms) {
942
944
  export {
943
945
  registerTradeCommands
944
946
  };
945
- //# sourceMappingURL=trade-4SOHHD5R.js.map
947
+ //# sourceMappingURL=trade-XDE6YCNY.js.map