@sherwoodagent/cli 0.19.2 → 0.22.8
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-WKOSUZXO.js → chat-JYAJMP4D.js} +42 -16
- package/dist/chat-JYAJMP4D.js.map +1 -0
- package/dist/{chunk-WWH4GD3N.js → chunk-4Y6Y4SVH.js} +37 -27
- package/dist/chunk-4Y6Y4SVH.js.map +1 -0
- package/dist/{chunk-XR2ZUO4R.js → chunk-4YIE7GHL.js} +16 -7
- package/dist/chunk-4YIE7GHL.js.map +1 -0
- package/dist/chunk-ASJTFFZH.js +485 -0
- package/dist/chunk-ASJTFFZH.js.map +1 -0
- package/dist/{chunk-SZ5QQJGA.js → chunk-B42ZCCZ7.js} +54 -2
- package/dist/chunk-B42ZCCZ7.js.map +1 -0
- package/dist/{chunk-QT7BUKWR.js → chunk-G7JQRLQE.js} +141 -37
- package/dist/chunk-G7JQRLQE.js.map +1 -0
- package/dist/{chunk-LHDWONBI.js → chunk-JR5K5WVR.js} +45 -6
- package/dist/chunk-JR5K5WVR.js.map +1 -0
- package/dist/{chunk-TAAEMX3L.js → chunk-LVPBJ7MI.js} +2 -2
- package/dist/{chunk-P4J6FKAP.js → chunk-VO6DCRWV.js} +36 -64
- package/dist/chunk-VO6DCRWV.js.map +1 -0
- package/dist/chunk-W2ZUPR3W.js +64 -0
- package/dist/chunk-W2ZUPR3W.js.map +1 -0
- package/dist/{chunk-YJAMY25R.js → chunk-Y7LS6DEF.js} +26 -39
- package/dist/chunk-Y7LS6DEF.js.map +1 -0
- package/dist/{client-3AAXAX4C.js → client-SCIY6SUP.js} +12 -4
- package/dist/{config-IDAHD7S3.js → config-BGS5MX4D.js} +10 -2
- package/dist/{cron-SKYKVZ6K.js → cron-EOULYO3R.js} +8 -3
- package/dist/cron-EOULYO3R.js.map +1 -0
- package/dist/{eas-MPDYDPJK.js → eas-X5UIEM6D.js} +14 -8
- package/dist/{governor-J3W67NXA.js → governor-ZKRSAHG4.js} +6 -6
- package/dist/index.js +1594 -391
- package/dist/index.js.map +1 -1
- package/dist/{network-DBUZ7GRF.js → network-UTSOP7EF.js} +3 -3
- package/dist/{research-LOSOHKOJ.js → research-EWH43HFN.js} +17 -16
- package/dist/research-EWH43HFN.js.map +1 -0
- package/dist/research-W3M3VZBD.js +14 -0
- package/dist/session-XAW5UIXP.js +17 -0
- package/dist/session-XAW5UIXP.js.map +1 -0
- package/dist/{session-Q2WRYXYF.js → session-XZNKLK3I.js} +17 -66
- package/dist/session-XZNKLK3I.js.map +1 -0
- package/dist/{trade-JLQPIA5W.js → trade-VKSXEHWW.js} +133 -70
- package/dist/trade-VKSXEHWW.js.map +1 -0
- package/dist/xmtp-XKHXATPQ.js +278 -0
- package/dist/xmtp-XKHXATPQ.js.map +1 -0
- package/package.json +7 -2
- package/dist/chat-WKOSUZXO.js.map +0 -1
- package/dist/chunk-I7CKBBOG.js +0 -129
- package/dist/chunk-I7CKBBOG.js.map +0 -1
- package/dist/chunk-LHDWONBI.js.map +0 -1
- package/dist/chunk-P4J6FKAP.js.map +0 -1
- package/dist/chunk-QT7BUKWR.js.map +0 -1
- package/dist/chunk-SZ5QQJGA.js.map +0 -1
- package/dist/chunk-WWH4GD3N.js.map +0 -1
- package/dist/chunk-XR2ZUO4R.js.map +0 -1
- package/dist/chunk-YJAMY25R.js.map +0 -1
- package/dist/cron-SKYKVZ6K.js.map +0 -1
- package/dist/research-DZINC4N4.js +0 -14
- package/dist/research-LOSOHKOJ.js.map +0 -1
- package/dist/session-Q2WRYXYF.js.map +0 -1
- package/dist/trade-JLQPIA5W.js.map +0 -1
- package/dist/xmtp-7DF7UG66.js +0 -367
- package/dist/xmtp-7DF7UG66.js.map +0 -1
- /package/dist/{chunk-TAAEMX3L.js.map → chunk-LVPBJ7MI.js.map} +0 -0
- /package/dist/{client-3AAXAX4C.js.map → client-SCIY6SUP.js.map} +0 -0
- /package/dist/{config-IDAHD7S3.js.map → config-BGS5MX4D.js.map} +0 -0
- /package/dist/{eas-MPDYDPJK.js.map → eas-X5UIEM6D.js.map} +0 -0
- /package/dist/{governor-J3W67NXA.js.map → governor-ZKRSAHG4.js.map} +0 -0
- /package/dist/{network-DBUZ7GRF.js.map → network-UTSOP7EF.js.map} +0 -0
- /package/dist/{research-DZINC4N4.js.map → research-W3M3VZBD.js.map} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/addresses.ts","../src/lib/abis.ts"],"sourcesContent":["/**\n * Contract addresses by network.\n *\n * All exports are functions — they resolve at call time based on the\n * current network set via setNetwork(). This ensures --chain works\n * even when modules are imported before the flag is parsed.\n *\n * Zero addresses = protocol not deployed on that chain. Strategies that\n * need them will fail at execution time with a clear allowlist error.\n */\n\nimport type { Address } from \"viem\";\nimport { type Network, getNetwork } from \"./network.js\";\n\nconst ZERO: Address = \"0x0000000000000000000000000000000000000000\";\nconst ZERO_BYTES32 =\n \"0x0000000000000000000000000000000000000000000000000000000000000000\" as `0x${string}`;\n\n// ── Base Mainnet ──\n\nconst BASE_TOKENS = {\n USDC: \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\" as Address,\n WETH: \"0x4200000000000000000000000000000000000006\" as Address,\n cbETH: \"0x2Ae3F1Ec7F1F5012CFEab0185bfc7aa3cf0DEc22\" as Address,\n wstETH: \"0xc1CBa3fCea344f92D9239c08C0568f6F2F0ee452\" as Address,\n cbBTC: \"0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf\" as Address,\n DAI: \"0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb\" as Address,\n AERO: \"0x940181a94A35A4569E4529A3CDfB74e38FD98631\" as Address,\n} as const;\n\nconst BASE_MOONWELL = {\n COMPTROLLER: \"0xfBb21d0380beE3312B33c4353c8936a0F13EF26C\" as Address,\n mUSDC: \"0xEdc817A28E8B93B03976FBd4a3dDBc9f7D176c22\" as Address,\n mWETH: \"0x628ff693426583D9a7FB391E54366292F509D457\" as Address,\n mCbETH: \"0x3bf93770f2d4a794c3d9EBEfBAeBAE2a8f09A5E5\" as Address,\n mWstETH: \"0x627Fe393Bc6EdDA28e99AE648fD6fF362514304b\" as Address,\n mCbBTC: \"0xF877ACaFA28c19b96727966690b2f44d35aD5976\" as Address,\n mDAI: \"0x73b06D8d18De422E269645eaCe15400DE7462417\" as Address,\n mAERO: \"0x73902f619CEB9B31FD8EFecf435CbDf89E369Ba6\" as Address,\n} as const;\n\nconst BASE_UNISWAP = {\n SWAP_ROUTER: \"0x2626664c2603336E57B271c5C0b26F421741e481\" as Address,\n QUOTER_V2: \"0x3d4e44Eb1374240CE5F1B871ab261CD16335B76a\" as Address,\n} as const;\n\nconst BASE_INFRA = {\n MULTICALL3: \"0xcA11bde05977b3631167028862bE2a173976CA11\" as Address,\n} as const;\n\n// ── Base Sepolia ──\n\nconst BASE_SEPOLIA_TOKENS = {\n USDC: \"0x036CbD53842c5426634e7929541eC2318f3dCF7e\" as Address, // Circle test USDC\n WETH: \"0x4200000000000000000000000000000000000006\" as Address, // Canonical bridged WETH\n cbETH: ZERO,\n wstETH: ZERO,\n cbBTC: ZERO,\n DAI: ZERO,\n AERO: ZERO,\n} as const;\n\nconst BASE_SEPOLIA_MOONWELL = {\n COMPTROLLER: ZERO,\n mUSDC: ZERO,\n mWETH: ZERO,\n mCbETH: ZERO,\n mWstETH: ZERO,\n mCbBTC: ZERO,\n mDAI: ZERO,\n mAERO: ZERO,\n} as const;\n\nconst BASE_SEPOLIA_UNISWAP = {\n SWAP_ROUTER: \"0x94cC0AaC535CCDB3C01d6787D6413C739ae12bc4\" as Address, // Uniswap V3 SwapRouter02\n QUOTER_V2: \"0xC5290058841028F1614F3A6F0F5816cAd0df5E27\" as Address, // Uniswap V3 QuoterV2\n} as const;\n\nconst BASE_SEPOLIA_INFRA = {\n MULTICALL3: \"0xcA11bde05977b3631167028862bE2a173976CA11\" as Address, // Deterministic, same everywhere\n} as const;\n\n// ── Robinhood L2 Testnet (Arbitrum Orbit, chain 46630) ──\n// No Moonwell, no Uniswap, no Venice, no ENS/Durin, no ERC-8004, no EAS.\n// USDC: Circle testnet, WETH: canonical bridged.\n\nconst ROBINHOOD_TESTNET_TOKENS = {\n USDC: ZERO, // no Circle USDC on Robinhood L2\n WETH: \"0x7943e237c7F95DA44E0301572D358911207852Fa\" as Address,\n cbETH: ZERO,\n wstETH: ZERO,\n cbBTC: ZERO,\n DAI: ZERO,\n AERO: ZERO,\n} as const;\n\nconst ROBINHOOD_TESTNET_MOONWELL = {\n COMPTROLLER: ZERO,\n mUSDC: ZERO,\n mWETH: ZERO,\n mCbETH: ZERO,\n mWstETH: ZERO,\n mCbBTC: ZERO,\n mDAI: ZERO,\n mAERO: ZERO,\n} as const;\n\nconst ROBINHOOD_TESTNET_UNISWAP = {\n SWAP_ROUTER: ZERO,\n QUOTER_V2: ZERO,\n} as const;\n\nconst ROBINHOOD_TESTNET_INFRA = {\n MULTICALL3: \"0xcA11bde05977b3631167028862bE2a173976CA11\" as Address, // Deterministic, same everywhere\n} as const;\n\n// ── ENS / Durin ──\n\nconst BASE_ENS = {\n L2_REGISTRAR: \"0x866996c808E6244216a3d0df15464FCF5d495394\" as Address,\n L2_REGISTRY: \"0x7a019ce699e27b0ad1e5b51344a58116b9f3b9b1\" as Address,\n} as const;\n\nconst BASE_SEPOLIA_ENS = {\n L2_REGISTRAR: \"0x1fCbe9dFC25e3fa3F7C55b26c7992684A4758b47\" as Address,\n L2_REGISTRY: \"0x06eb7b85b59bc3e50fe4837be776cdd26de602cf\" as Address,\n} as const;\n\nconst ROBINHOOD_TESTNET_ENS = {\n L2_REGISTRAR: ZERO,\n L2_REGISTRY: ZERO,\n} as const;\n\n// ── ERC-8004 Agent Identity ──\n\nconst BASE_AGENT_REGISTRY = {\n IDENTITY_REGISTRY: \"0x8004A169FB4a3325136EB29fA0ceB6D2e539a432\" as Address,\n REPUTATION_REGISTRY:\n \"0x8004BAa17C55a88189AE136b182e5fdA19dE9b63\" as Address,\n} as const;\n\nconst BASE_SEPOLIA_AGENT_REGISTRY = {\n IDENTITY_REGISTRY: \"0x8004A818BFB912233c491871b3d84c89A494BD9e\" as Address,\n REPUTATION_REGISTRY:\n \"0x8004B663056A597Dffe9eCcC1965A193B7388713\" as Address,\n} as const;\n\nconst ROBINHOOD_TESTNET_AGENT_REGISTRY = {\n IDENTITY_REGISTRY: ZERO,\n REPUTATION_REGISTRY: ZERO,\n} as const;\n\n// ── Sherwood Protocol (our deployed contracts) ──\n\nconst BASE_SHERWOOD = {\n FACTORY: \"0xd5C4eE2E4c5B606b9401E69A3B3FeE169037C284\" as Address,\n GOVERNOR: \"0x358AD8B492BcC710BE0D7c902D8702164c35DC34\" as Address,\n} as const;\n\nconst BASE_SEPOLIA_SHERWOOD = {\n FACTORY: \"0x121AaC2B96Ec365e457fcCc1C2ED5a6142064069\" as Address,\n GOVERNOR: \"0xE5ecf2B06E3f3e298B632C0cf6575f9d9422F55E\" as Address,\n} as const;\n\nconst ROBINHOOD_TESTNET_SHERWOOD = {\n FACTORY: \"0xd5C4eE2E4c5B606b9401E69A3B3FeE169037C284\" as Address,\n GOVERNOR: \"0x358AD8B492BcC710BE0D7c902D8702164c35DC34\" as Address,\n} as const;\n\n// ── Venice (VVV governance + sVVV staking + DIEM compute) ──\n\nconst BASE_VENICE = {\n VVV: \"0xacfe6019ed1a7dc6f7b508c02d1b04ec88cc21bf\" as Address,\n STAKING: \"0x321b7ff75154472b18edb199033ff4d116f340ff\" as Address, // also the sVVV ERC-20\n DIEM: \"0xF4d97F2da56e8c3098f3a8D538DB630A2606a024\" as Address,\n} as const;\n\nconst BASE_SEPOLIA_VENICE = {\n VVV: ZERO,\n STAKING: ZERO,\n DIEM: ZERO,\n} as const;\n\nconst ROBINHOOD_TESTNET_VENICE = {\n VVV: ZERO,\n STAKING: ZERO,\n DIEM: ZERO,\n} as const;\n\n// ── Aerodrome (Base ve(3,3) DEX) ──\n\nconst BASE_AERODROME = {\n ROUTER: \"0xcF77a3Ba9A5CA399B7c97c74d54e5b1Beb874E43\" as Address,\n FACTORY: \"0x420DD381b31aEf6683db6B902084cB0FFECe40Da\" as Address,\n} as const;\n\nconst BASE_SEPOLIA_AERODROME = {\n ROUTER: ZERO,\n FACTORY: ZERO,\n} as const;\n\nconst ROBINHOOD_TESTNET_AERODROME = {\n ROUTER: ZERO,\n FACTORY: ZERO,\n} as const;\n\n// ── Strategy Templates (ERC-1167 clonable singletons) ──\n// Populated after running script/DeployTemplates.s.sol\n\nconst BASE_STRATEGY_TEMPLATES = {\n MOONWELL_SUPPLY: \"0x25E33fAeE061E752fDFe851911ccC4C6D9FBA346\" as Address,\n AERODROME_LP: \"0x1c61c740702690B86b874ab929A6F04A4Ec56C1c\" as Address,\n VENICE_INFERENCE: \"0xd882056ba6b0aEd8908c541884B327121E2f2C9C\" as Address,\n WSTETH_MOONWELL: \"0x6d026e2f5Ff0C34A01690EC46Cb601B8fF391985\" as Address,\n} as const;\n\nconst BASE_SEPOLIA_STRATEGY_TEMPLATES = {\n MOONWELL_SUPPLY: ZERO as Address,\n AERODROME_LP: ZERO as Address,\n VENICE_INFERENCE: ZERO as Address,\n WSTETH_MOONWELL: ZERO as Address,\n} as const;\n\nconst ROBINHOOD_TESTNET_STRATEGY_TEMPLATES = {\n MOONWELL_SUPPLY: ZERO as Address,\n AERODROME_LP: ZERO as Address,\n VENICE_INFERENCE: ZERO as Address,\n WSTETH_MOONWELL: ZERO as Address,\n} as const;\n\n// ── EAS (Ethereum Attestation Service) — Base predeploys ──\n\nconst BASE_EAS = {\n EAS: \"0x4200000000000000000000000000000000000021\" as Address,\n SCHEMA_REGISTRY: \"0x4200000000000000000000000000000000000020\" as Address,\n} as const;\n\nconst BASE_SEPOLIA_EAS = {\n EAS: \"0x4200000000000000000000000000000000000021\" as Address,\n SCHEMA_REGISTRY: \"0x4200000000000000000000000000000000000020\" as Address,\n} as const;\n\nconst ROBINHOOD_TESTNET_EAS = {\n EAS: ZERO,\n SCHEMA_REGISTRY: ZERO,\n} as const;\n\n// ── EAS Schema UIDs (populated after running scripts/register-eas-schemas.ts) ──\n\nconst BASE_EAS_SCHEMAS = {\n SYNDICATE_JOIN_REQUEST:\n \"0x1e7ce17b16233977ba913b156033e98f52029f4bee273a4abefe6c15ce11d5ef\" as `0x${string}`,\n AGENT_APPROVED:\n \"0x1013f7b38f433b2a93fc5ac162482813081c64edd67cea9b5a90698531ddb607\" as `0x${string}`,\n X402_RESEARCH:\n \"0x86c67f0a59acb3093ecbeb6c4d1d4352e4a48143672e92ef9dd2fdfc8a9ca708\" as `0x${string}`,\n VENICE_PROVISION:\n \"0x76d4d6baa72307826cd2fd4ce069bb42ee54cdda6ed6ab208c8d233c893fb7f1\" as `0x${string}`,\n VENICE_INFERENCE:\n \"0xf9b4e530f3016c19439b67372a1c213c9339857627fb817032614b97433a2a14\" as `0x${string}`,\n TRADE_EXECUTED:\n \"0x06bb488363a468f7f857ddc8cfffe918d048b8746a0d59eca9cd7f58dbdb4af6\" as `0x${string}`,\n} as const;\n\nconst BASE_SEPOLIA_EAS_SCHEMAS = {\n SYNDICATE_JOIN_REQUEST:\n \"0x1e7ce17b16233977ba913b156033e98f52029f4bee273a4abefe6c15ce11d5ef\" as `0x${string}`,\n AGENT_APPROVED:\n \"0x1013f7b38f433b2a93fc5ac162482813081c64edd67cea9b5a90698531ddb607\" as `0x${string}`,\n X402_RESEARCH:\n \"0x86c67f0a59acb3093ecbeb6c4d1d4352e4a48143672e92ef9dd2fdfc8a9ca708\" as `0x${string}`,\n VENICE_PROVISION:\n \"0x76d4d6baa72307826cd2fd4ce069bb42ee54cdda6ed6ab208c8d233c893fb7f1\" as `0x${string}`,\n VENICE_INFERENCE:\n \"0xf9b4e530f3016c19439b67372a1c213c9339857627fb817032614b97433a2a14\" as `0x${string}`,\n TRADE_EXECUTED:\n \"0x06bb488363a468f7f857ddc8cfffe918d048b8746a0d59eca9cd7f58dbdb4af6\" as `0x${string}`,\n} as const;\n\nconst ROBINHOOD_TESTNET_EAS_SCHEMAS = {\n SYNDICATE_JOIN_REQUEST: ZERO_BYTES32,\n AGENT_APPROVED: ZERO_BYTES32,\n X402_RESEARCH: ZERO_BYTES32,\n VENICE_PROVISION: ZERO_BYTES32,\n VENICE_INFERENCE: ZERO_BYTES32,\n TRADE_EXECUTED: ZERO_BYTES32,\n} as const;\n\n// ── Registries (map-based lookup) ──\n\nconst TOKEN_REGISTRY: Record<Network, typeof BASE_TOKENS> = {\n base: BASE_TOKENS,\n \"base-sepolia\": BASE_SEPOLIA_TOKENS,\n \"robinhood-testnet\": ROBINHOOD_TESTNET_TOKENS,\n};\n\nconst MOONWELL_REGISTRY: Record<Network, typeof BASE_MOONWELL> = {\n base: BASE_MOONWELL,\n \"base-sepolia\": BASE_SEPOLIA_MOONWELL,\n \"robinhood-testnet\": ROBINHOOD_TESTNET_MOONWELL,\n};\n\nconst UNISWAP_REGISTRY: Record<Network, typeof BASE_UNISWAP> = {\n base: BASE_UNISWAP,\n \"base-sepolia\": BASE_SEPOLIA_UNISWAP,\n \"robinhood-testnet\": ROBINHOOD_TESTNET_UNISWAP,\n};\n\nconst INFRA_REGISTRY: Record<Network, typeof BASE_INFRA> = {\n base: BASE_INFRA,\n \"base-sepolia\": BASE_SEPOLIA_INFRA,\n \"robinhood-testnet\": ROBINHOOD_TESTNET_INFRA,\n};\n\nconst ENS_REGISTRY: Record<Network, typeof BASE_ENS> = {\n base: BASE_ENS,\n \"base-sepolia\": BASE_SEPOLIA_ENS,\n \"robinhood-testnet\": ROBINHOOD_TESTNET_ENS,\n};\n\nconst AGENT_REGISTRY_MAP: Record<Network, typeof BASE_AGENT_REGISTRY> = {\n base: BASE_AGENT_REGISTRY,\n \"base-sepolia\": BASE_SEPOLIA_AGENT_REGISTRY,\n \"robinhood-testnet\": ROBINHOOD_TESTNET_AGENT_REGISTRY,\n};\n\nconst SHERWOOD_REGISTRY: Record<Network, typeof BASE_SHERWOOD> = {\n base: BASE_SHERWOOD,\n \"base-sepolia\": BASE_SEPOLIA_SHERWOOD,\n \"robinhood-testnet\": ROBINHOOD_TESTNET_SHERWOOD,\n};\n\nconst VENICE_REGISTRY: Record<Network, typeof BASE_VENICE> = {\n base: BASE_VENICE,\n \"base-sepolia\": BASE_SEPOLIA_VENICE,\n \"robinhood-testnet\": ROBINHOOD_TESTNET_VENICE,\n};\n\nconst AERODROME_REGISTRY: Record<Network, typeof BASE_AERODROME> = {\n base: BASE_AERODROME,\n \"base-sepolia\": BASE_SEPOLIA_AERODROME,\n \"robinhood-testnet\": ROBINHOOD_TESTNET_AERODROME,\n};\n\nconst STRATEGY_TEMPLATE_REGISTRY: Record<Network, typeof BASE_STRATEGY_TEMPLATES> = {\n base: BASE_STRATEGY_TEMPLATES,\n \"base-sepolia\": BASE_SEPOLIA_STRATEGY_TEMPLATES,\n \"robinhood-testnet\": ROBINHOOD_TESTNET_STRATEGY_TEMPLATES,\n};\n\nconst EAS_CONTRACT_REGISTRY: Record<Network, typeof BASE_EAS> = {\n base: BASE_EAS,\n \"base-sepolia\": BASE_SEPOLIA_EAS,\n \"robinhood-testnet\": ROBINHOOD_TESTNET_EAS,\n};\n\nconst EAS_SCHEMA_REGISTRY: Record<Network, typeof BASE_EAS_SCHEMAS> = {\n base: BASE_EAS_SCHEMAS,\n \"base-sepolia\": BASE_SEPOLIA_EAS_SCHEMAS,\n \"robinhood-testnet\": ROBINHOOD_TESTNET_EAS_SCHEMAS,\n};\n\n// ── Exports (functions, resolved at call time) ──\n\nexport function TOKENS() {\n return TOKEN_REGISTRY[getNetwork()];\n}\n\nexport function MOONWELL() {\n return MOONWELL_REGISTRY[getNetwork()];\n}\n\nexport function UNISWAP() {\n return UNISWAP_REGISTRY[getNetwork()];\n}\n\nexport function INFRA() {\n return INFRA_REGISTRY[getNetwork()];\n}\n\nexport function ENS() {\n return ENS_REGISTRY[getNetwork()];\n}\n\nexport function AGENT_REGISTRY() {\n return AGENT_REGISTRY_MAP[getNetwork()];\n}\n\nexport function VENICE() {\n return VENICE_REGISTRY[getNetwork()];\n}\n\nexport function SHERWOOD() {\n return SHERWOOD_REGISTRY[getNetwork()];\n}\n\nexport function AERODROME() {\n return AERODROME_REGISTRY[getNetwork()];\n}\n\nexport function STRATEGY_TEMPLATES() {\n return STRATEGY_TEMPLATE_REGISTRY[getNetwork()];\n}\n\nexport function EAS_CONTRACTS() {\n return EAS_CONTRACT_REGISTRY[getNetwork()];\n}\n\nexport function EAS_SCHEMAS() {\n return EAS_SCHEMA_REGISTRY[getNetwork()];\n}\n","/**\n * Minimal contract ABIs for viem type inference.\n * Extracted from contracts/src/ — keep in sync if contracts change.\n */\n\n// ── SyndicateVault (ERC-4626 + ERC20Votes + governor integration) ──\n\nexport const SYNDICATE_VAULT_ABI = [\n // ERC-4626\n {\n name: \"deposit\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"assets\", type: \"uint256\" },\n { name: \"receiver\", type: \"address\" },\n ],\n outputs: [{ name: \"shares\", type: \"uint256\" }],\n },\n {\n name: \"totalAssets\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [],\n outputs: [{ name: \"\", type: \"uint256\" }],\n },\n {\n name: \"asset\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [],\n outputs: [{ name: \"\", type: \"address\" }],\n },\n // ERC-20\n {\n name: \"balanceOf\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [{ name: \"account\", type: \"address\" }],\n outputs: [{ name: \"\", type: \"uint256\" }],\n },\n // Batch execution (owner-only, via delegatecall to shared executor lib)\n {\n name: \"executeBatch\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [\n {\n name: \"calls\",\n type: \"tuple[]\",\n components: [\n { name: \"target\", type: \"address\" },\n { name: \"data\", type: \"bytes\" },\n { name: \"value\", type: \"uint256\" },\n ],\n },\n ],\n outputs: [],\n },\n // Agent management\n {\n name: \"registerAgent\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"agentId\", type: \"uint256\" },\n { name: \"agentAddress\", type: \"address\" },\n ],\n outputs: [],\n },\n {\n name: \"removeAgent\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [{ name: \"agentAddress\", type: \"address\" }],\n outputs: [],\n },\n // Views\n {\n name: \"getAgentConfig\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [{ name: \"agentAddress\", type: \"address\" }],\n outputs: [\n {\n name: \"\",\n type: \"tuple\",\n components: [\n { name: \"agentId\", type: \"uint256\" },\n { name: \"agentAddress\", type: \"address\" },\n { name: \"active\", type: \"bool\" },\n ],\n },\n ],\n },\n {\n name: \"getAgentCount\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [],\n outputs: [{ name: \"\", type: \"uint256\" }],\n },\n {\n name: \"isAgent\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [{ name: \"agentAddress\", type: \"address\" }],\n outputs: [{ name: \"\", type: \"bool\" }],\n },\n {\n name: \"getExecutorImpl\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [],\n outputs: [{ name: \"\", type: \"address\" }],\n },\n {\n name: \"totalDeposited\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [],\n outputs: [{ name: \"\", type: \"uint256\" }],\n },\n {\n name: \"getAgentAddresses\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [],\n outputs: [{ name: \"\", type: \"address[]\" }],\n },\n {\n name: \"pause\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [],\n outputs: [],\n },\n {\n name: \"unpause\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [],\n outputs: [],\n },\n // Depositor whitelist\n {\n name: \"approveDepositor\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [{ name: \"depositor\", type: \"address\" }],\n outputs: [],\n },\n {\n name: \"removeDepositor\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [{ name: \"depositor\", type: \"address\" }],\n outputs: [],\n },\n {\n name: \"approveDepositors\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [{ name: \"depositors\", type: \"address[]\" }],\n outputs: [],\n },\n {\n name: \"isApprovedDepositor\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [{ name: \"depositor\", type: \"address\" }],\n outputs: [{ name: \"\", type: \"bool\" }],\n },\n {\n name: \"getApprovedDepositors\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [],\n outputs: [{ name: \"\", type: \"address[]\" }],\n },\n {\n name: \"setOpenDeposits\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [{ name: \"open\", type: \"bool\" }],\n outputs: [],\n },\n {\n name: \"openDeposits\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [],\n outputs: [{ name: \"\", type: \"bool\" }],\n },\n // ERC-4626 views for LP balance\n {\n name: \"convertToAssets\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [{ name: \"shares\", type: \"uint256\" }],\n outputs: [{ name: \"assets\", type: \"uint256\" }],\n },\n {\n name: \"totalSupply\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [],\n outputs: [{ name: \"\", type: \"uint256\" }],\n },\n // ── Events ──\n {\n name: \"AgentRegistered\",\n type: \"event\",\n inputs: [\n { name: \"agentId\", type: \"uint256\", indexed: true },\n { name: \"agentAddress\", type: \"address\", indexed: true },\n ],\n },\n {\n name: \"AgentRemoved\",\n type: \"event\",\n inputs: [{ name: \"agentAddress\", type: \"address\", indexed: true }],\n },\n {\n name: \"DepositorApproved\",\n type: \"event\",\n inputs: [{ name: \"depositor\", type: \"address\", indexed: true }],\n },\n {\n name: \"DepositorRemoved\",\n type: \"event\",\n inputs: [{ name: \"depositor\", type: \"address\", indexed: true }],\n },\n // Governor integration\n {\n name: \"governor\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [],\n outputs: [{ name: \"\", type: \"address\" }],\n },\n {\n name: \"redemptionsLocked\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [],\n outputs: [{ name: \"\", type: \"bool\" }],\n },\n {\n name: \"managementFeeBps\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [],\n outputs: [{ name: \"\", type: \"uint256\" }],\n },\n] as const;\n\n// ── Uniswap Quoter V2 ──\n\nexport const UNISWAP_QUOTER_V2_ABI = [\n {\n name: \"quoteExactInputSingle\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [\n {\n name: \"params\",\n type: \"tuple\",\n components: [\n { name: \"tokenIn\", type: \"address\" },\n { name: \"tokenOut\", type: \"address\" },\n { name: \"amountIn\", type: \"uint256\" },\n { name: \"fee\", type: \"uint24\" },\n { name: \"sqrtPriceLimitX96\", type: \"uint160\" },\n ],\n },\n ],\n outputs: [\n { name: \"amountOut\", type: \"uint256\" },\n { name: \"sqrtPriceX96After\", type: \"uint160\" },\n { name: \"initializedTicksCrossed\", type: \"uint32\" },\n { name: \"gasEstimate\", type: \"uint256\" },\n ],\n },\n {\n name: \"quoteExactInput\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"path\", type: \"bytes\" },\n { name: \"amountIn\", type: \"uint256\" },\n ],\n outputs: [\n { name: \"amountOut\", type: \"uint256\" },\n { name: \"sqrtPriceX96AfterList\", type: \"uint160[]\" },\n { name: \"initializedTicksCrossedList\", type: \"uint32[]\" },\n { name: \"gasEstimate\", type: \"uint256\" },\n ],\n },\n] as const;\n\n// ── Uniswap SwapRouter (multi-hop) ──\n\nexport const SWAP_ROUTER_ABI = [\n {\n name: \"exactInput\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [\n {\n name: \"params\",\n type: \"tuple\",\n components: [\n { name: \"path\", type: \"bytes\" },\n { name: \"recipient\", type: \"address\" },\n { name: \"amountIn\", type: \"uint256\" },\n { name: \"amountOutMinimum\", type: \"uint256\" },\n ],\n },\n ],\n outputs: [{ name: \"amountOut\", type: \"uint256\" }],\n },\n] as const;\n\n// ── Uniswap SwapRouter (single-hop) ──\n\nexport const SWAP_ROUTER_EXACT_INPUT_SINGLE_ABI = [\n {\n name: \"exactInputSingle\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [\n {\n name: \"params\",\n type: \"tuple\",\n components: [\n { name: \"tokenIn\", type: \"address\" },\n { name: \"tokenOut\", type: \"address\" },\n { name: \"fee\", type: \"uint24\" },\n { name: \"recipient\", type: \"address\" },\n { name: \"amountIn\", type: \"uint256\" },\n { name: \"amountOutMinimum\", type: \"uint256\" },\n { name: \"sqrtPriceLimitX96\", type: \"uint160\" },\n ],\n },\n ],\n outputs: [{ name: \"amountOut\", type: \"uint256\" }],\n },\n] as const;\n\n// ── ERC20 ──\n\nexport const ERC20_ABI = [\n {\n name: \"approve\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"spender\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n ],\n outputs: [{ name: \"\", type: \"bool\" }],\n },\n {\n name: \"balanceOf\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [{ name: \"account\", type: \"address\" }],\n outputs: [{ name: \"\", type: \"uint256\" }],\n },\n {\n name: \"allowance\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [\n { name: \"owner\", type: \"address\" },\n { name: \"spender\", type: \"address\" },\n ],\n outputs: [{ name: \"\", type: \"uint256\" }],\n },\n {\n name: \"decimals\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [],\n outputs: [{ name: \"\", type: \"uint8\" }],\n },\n {\n name: \"symbol\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [],\n outputs: [{ name: \"\", type: \"string\" }],\n },\n {\n name: \"transfer\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"to\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n ],\n outputs: [{ name: \"\", type: \"bool\" }],\n },\n] as const;\n\n// ── SyndicateFactory ──\n\nexport const SYNDICATE_FACTORY_ABI = [\n {\n name: \"createSyndicate\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"creatorAgentId\", type: \"uint256\" },\n {\n name: \"config\",\n type: \"tuple\",\n components: [\n { name: \"metadataURI\", type: \"string\" },\n { name: \"asset\", type: \"address\" },\n { name: \"name\", type: \"string\" },\n { name: \"symbol\", type: \"string\" },\n { name: \"openDeposits\", type: \"bool\" },\n { name: \"subdomain\", type: \"string\" },\n ],\n },\n ],\n outputs: [\n { name: \"syndicateId\", type: \"uint256\" },\n { name: \"vault\", type: \"address\" },\n ],\n },\n {\n name: \"syndicates\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [{ name: \"\", type: \"uint256\" }],\n outputs: [\n { name: \"id\", type: \"uint256\" },\n { name: \"vault\", type: \"address\" },\n { name: \"creator\", type: \"address\" },\n { name: \"metadataURI\", type: \"string\" },\n { name: \"createdAt\", type: \"uint256\" },\n { name: \"active\", type: \"bool\" },\n { name: \"subdomain\", type: \"string\" },\n ],\n },\n {\n name: \"getAllActiveSyndicates\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [],\n outputs: [\n {\n name: \"\",\n type: \"tuple[]\",\n components: [\n { name: \"id\", type: \"uint256\" },\n { name: \"vault\", type: \"address\" },\n { name: \"creator\", type: \"address\" },\n { name: \"metadataURI\", type: \"string\" },\n { name: \"createdAt\", type: \"uint256\" },\n { name: \"active\", type: \"bool\" },\n { name: \"subdomain\", type: \"string\" },\n ],\n },\n ],\n },\n {\n name: \"syndicateCount\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [],\n outputs: [{ name: \"\", type: \"uint256\" }],\n },\n {\n name: \"vaultToSyndicate\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [{ name: \"\", type: \"address\" }],\n outputs: [{ name: \"\", type: \"uint256\" }],\n },\n {\n name: \"updateMetadata\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"syndicateId\", type: \"uint256\" },\n { name: \"metadataURI\", type: \"string\" },\n ],\n outputs: [],\n },\n {\n name: \"deactivate\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [{ name: \"syndicateId\", type: \"uint256\" }],\n outputs: [],\n },\n {\n name: \"executorImpl\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [],\n outputs: [{ name: \"\", type: \"address\" }],\n },\n {\n name: \"vaultImpl\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [],\n outputs: [{ name: \"\", type: \"address\" }],\n },\n {\n name: \"subdomainToSyndicate\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [{ name: \"subdomain\", type: \"string\" }],\n outputs: [{ name: \"\", type: \"uint256\" }],\n },\n {\n name: \"isSubdomainAvailable\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [{ name: \"subdomain\", type: \"string\" }],\n outputs: [{ name: \"\", type: \"bool\" }],\n },\n {\n name: \"SyndicateCreated\",\n type: \"event\",\n inputs: [\n { name: \"id\", type: \"uint256\", indexed: true },\n { name: \"vault\", type: \"address\", indexed: true },\n { name: \"creator\", type: \"address\", indexed: true },\n { name: \"metadataURI\", type: \"string\", indexed: false },\n { name: \"subdomain\", type: \"string\", indexed: false },\n ],\n },\n] as const;\n\n// ── L2 Registry (Durin ENS — text records) ──\n\nexport const L2_REGISTRY_ABI = [\n {\n name: \"setText\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"node\", type: \"bytes32\" },\n { name: \"key\", type: \"string\" },\n { name: \"value\", type: \"string\" },\n ],\n outputs: [],\n },\n {\n name: \"text\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [\n { name: \"node\", type: \"bytes32\" },\n { name: \"key\", type: \"string\" },\n ],\n outputs: [{ name: \"\", type: \"string\" }],\n },\n] as const;\n\n// ── StrategyRegistry ──\n\nexport const STRATEGY_REGISTRY_ABI = [\n {\n name: \"registerStrategy\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"implementation\", type: \"address\" },\n { name: \"strategyTypeId\", type: \"uint256\" },\n { name: \"name\", type: \"string\" },\n { name: \"metadataURI\", type: \"string\" },\n ],\n outputs: [{ name: \"strategyId\", type: \"uint256\" }],\n },\n {\n name: \"getStrategy\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [{ name: \"strategyId\", type: \"uint256\" }],\n outputs: [\n {\n name: \"\",\n type: \"tuple\",\n components: [\n { name: \"implementation\", type: \"address\" },\n { name: \"creator\", type: \"address\" },\n { name: \"strategyTypeId\", type: \"uint256\" },\n { name: \"active\", type: \"bool\" },\n { name: \"name\", type: \"string\" },\n { name: \"metadataURI\", type: \"string\" },\n ],\n },\n ],\n },\n {\n name: \"getStrategiesByType\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [{ name: \"strategyTypeId\", type: \"uint256\" }],\n outputs: [{ name: \"\", type: \"uint256[]\" }],\n },\n {\n name: \"getStrategiesByCreator\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [{ name: \"creator\", type: \"address\" }],\n outputs: [{ name: \"\", type: \"uint256[]\" }],\n },\n {\n name: \"strategyCount\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [],\n outputs: [{ name: \"\", type: \"uint256\" }],\n },\n {\n name: \"isStrategyActive\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [{ name: \"strategyId\", type: \"uint256\" }],\n outputs: [{ name: \"\", type: \"bool\" }],\n },\n {\n name: \"deactivateStrategy\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [{ name: \"strategyId\", type: \"uint256\" }],\n outputs: [],\n },\n] as const;\n\n// ── Venice Staking (sVVV = staking contract ERC-20) ──\n\nexport const VENICE_STAKING_ABI = [\n {\n name: \"stake\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"recipient\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n ],\n outputs: [],\n },\n {\n name: \"initiateUnstake\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [{ name: \"amount\", type: \"uint256\" }],\n outputs: [],\n },\n {\n name: \"finalizeUnstake\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [],\n outputs: [],\n },\n {\n name: \"mintDiem\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"sVVVAmountToLock\", type: \"uint256\" },\n { name: \"minDiemAmountOut\", type: \"uint256\" },\n ],\n outputs: [],\n },\n {\n name: \"balanceOf\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [{ name: \"account\", type: \"address\" }],\n outputs: [{ name: \"\", type: \"uint256\" }],\n },\n {\n name: \"pendingRewards\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [{ name: \"_user\", type: \"address\" }],\n outputs: [{ name: \"\", type: \"uint256\" }],\n },\n {\n name: \"cooldownDuration\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [],\n outputs: [{ name: \"\", type: \"uint256\" }],\n },\n {\n name: \"getDiemAmountOut\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [{ name: \"sVVVAmountToLock\", type: \"uint256\" }],\n outputs: [{ name: \"\", type: \"uint256\" }],\n },\n {\n name: \"claim\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [],\n outputs: [],\n },\n] as const;\n\n// ── EAS (Ethereum Attestation Service) ──\n\nexport const EAS_ABI = [\n {\n name: \"attest\",\n type: \"function\",\n stateMutability: \"payable\",\n inputs: [\n {\n name: \"request\",\n type: \"tuple\",\n components: [\n { name: \"schema\", type: \"bytes32\" },\n {\n name: \"data\",\n type: \"tuple\",\n components: [\n { name: \"recipient\", type: \"address\" },\n { name: \"expirationTime\", type: \"uint64\" },\n { name: \"revocable\", type: \"bool\" },\n { name: \"refUID\", type: \"bytes32\" },\n { name: \"data\", type: \"bytes\" },\n { name: \"value\", type: \"uint256\" },\n ],\n },\n ],\n },\n ],\n outputs: [{ name: \"\", type: \"bytes32\" }],\n },\n {\n name: \"revoke\",\n type: \"function\",\n stateMutability: \"payable\",\n inputs: [\n {\n name: \"request\",\n type: \"tuple\",\n components: [\n { name: \"schema\", type: \"bytes32\" },\n {\n name: \"data\",\n type: \"tuple\",\n components: [\n { name: \"uid\", type: \"bytes32\" },\n { name: \"value\", type: \"uint256\" },\n ],\n },\n ],\n },\n ],\n outputs: [],\n },\n {\n name: \"getAttestation\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [{ name: \"uid\", type: \"bytes32\" }],\n outputs: [\n {\n name: \"\",\n type: \"tuple\",\n components: [\n { name: \"uid\", type: \"bytes32\" },\n { name: \"schema\", type: \"bytes32\" },\n { name: \"time\", type: \"uint64\" },\n { name: \"expirationTime\", type: \"uint64\" },\n { name: \"revocationTime\", type: \"uint64\" },\n { name: \"refUID\", type: \"bytes32\" },\n { name: \"recipient\", type: \"address\" },\n { name: \"attester\", type: \"address\" },\n { name: \"revocable\", type: \"bool\" },\n { name: \"data\", type: \"bytes\" },\n ],\n },\n ],\n },\n] as const;\n\n// ── SyndicateGovernor ──\n\nexport const SYNDICATE_GOVERNOR_ABI = [\n // Proposal lifecycle\n {\n name: \"propose\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"vault\", type: \"address\" },\n { name: \"metadataURI\", type: \"string\" },\n { name: \"performanceFeeBps\", type: \"uint256\" },\n { name: \"strategyDuration\", type: \"uint256\" },\n {\n name: \"executeCalls\",\n type: \"tuple[]\",\n components: [\n { name: \"target\", type: \"address\" },\n { name: \"data\", type: \"bytes\" },\n { name: \"value\", type: \"uint256\" },\n ],\n },\n {\n name: \"settlementCalls\",\n type: \"tuple[]\",\n components: [\n { name: \"target\", type: \"address\" },\n { name: \"data\", type: \"bytes\" },\n { name: \"value\", type: \"uint256\" },\n ],\n },\n {\n name: \"coProposers\",\n type: \"tuple[]\",\n components: [\n { name: \"agent\", type: \"address\" },\n { name: \"splitBps\", type: \"uint256\" },\n ],\n },\n ],\n outputs: [{ name: \"proposalId\", type: \"uint256\" }],\n },\n {\n name: \"vote\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"proposalId\", type: \"uint256\" },\n { name: \"support\", type: \"uint8\" },\n ],\n outputs: [],\n },\n {\n name: \"executeProposal\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [{ name: \"proposalId\", type: \"uint256\" }],\n outputs: [],\n },\n {\n name: \"settleProposal\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [{ name: \"proposalId\", type: \"uint256\" }],\n outputs: [],\n },\n {\n name: \"emergencySettle\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"proposalId\", type: \"uint256\" },\n {\n name: \"calls\",\n type: \"tuple[]\",\n components: [\n { name: \"target\", type: \"address\" },\n { name: \"data\", type: \"bytes\" },\n { name: \"value\", type: \"uint256\" },\n ],\n },\n ],\n outputs: [],\n },\n {\n name: \"cancelProposal\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [{ name: \"proposalId\", type: \"uint256\" }],\n outputs: [],\n },\n {\n name: \"emergencyCancel\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [{ name: \"proposalId\", type: \"uint256\" }],\n outputs: [],\n },\n // Views\n {\n name: \"getProposal\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [{ name: \"proposalId\", type: \"uint256\" }],\n outputs: [\n {\n name: \"\",\n type: \"tuple\",\n components: [\n { name: \"id\", type: \"uint256\" },\n { name: \"proposer\", type: \"address\" },\n { name: \"vault\", type: \"address\" },\n { name: \"metadataURI\", type: \"string\" },\n { name: \"performanceFeeBps\", type: \"uint256\" },\n { name: \"strategyDuration\", type: \"uint256\" },\n { name: \"votesFor\", type: \"uint256\" },\n { name: \"votesAgainst\", type: \"uint256\" },\n { name: \"votesAbstain\", type: \"uint256\" },\n { name: \"snapshotTimestamp\", type: \"uint256\" },\n { name: \"voteEnd\", type: \"uint256\" },\n { name: \"executeBy\", type: \"uint256\" },\n { name: \"executedAt\", type: \"uint256\" },\n { name: \"state\", type: \"uint8\" },\n ],\n },\n ],\n },\n {\n name: \"getProposalState\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [{ name: \"proposalId\", type: \"uint256\" }],\n outputs: [{ name: \"\", type: \"uint8\" }],\n },\n {\n name: \"getProposalCalls\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [{ name: \"proposalId\", type: \"uint256\" }],\n outputs: [\n {\n name: \"\",\n type: \"tuple[]\",\n components: [\n { name: \"target\", type: \"address\" },\n { name: \"data\", type: \"bytes\" },\n { name: \"value\", type: \"uint256\" },\n ],\n },\n ],\n },\n {\n name: \"getVoteWeight\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [\n { name: \"proposalId\", type: \"uint256\" },\n { name: \"voter\", type: \"address\" },\n ],\n outputs: [{ name: \"\", type: \"uint256\" }],\n },\n {\n name: \"hasVoted\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [\n { name: \"proposalId\", type: \"uint256\" },\n { name: \"voter\", type: \"address\" },\n ],\n outputs: [{ name: \"\", type: \"bool\" }],\n },\n {\n name: \"proposalCount\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [],\n outputs: [{ name: \"\", type: \"uint256\" }],\n },\n {\n name: \"getGovernorParams\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [],\n outputs: [\n {\n name: \"\",\n type: \"tuple\",\n components: [\n { name: \"votingPeriod\", type: \"uint256\" },\n { name: \"executionWindow\", type: \"uint256\" },\n { name: \"vetoThresholdBps\", type: \"uint256\" },\n { name: \"maxPerformanceFeeBps\", type: \"uint256\" },\n { name: \"cooldownPeriod\", type: \"uint256\" },\n { name: \"collaborationWindow\", type: \"uint256\" },\n { name: \"maxCoProposers\", type: \"uint256\" },\n { name: \"minStrategyDuration\", type: \"uint256\" },\n { name: \"maxStrategyDuration\", type: \"uint256\" },\n ],\n },\n ],\n },\n {\n name: \"getRegisteredVaults\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [],\n outputs: [{ name: \"\", type: \"address[]\" }],\n },\n {\n name: \"getActiveProposal\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [{ name: \"vault\", type: \"address\" }],\n outputs: [{ name: \"\", type: \"uint256\" }],\n },\n {\n name: \"getCooldownEnd\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [{ name: \"vault\", type: \"address\" }],\n outputs: [{ name: \"\", type: \"uint256\" }],\n },\n {\n name: \"getCapitalSnapshot\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [{ name: \"proposalId\", type: \"uint256\" }],\n outputs: [{ name: \"\", type: \"uint256\" }],\n },\n {\n name: \"isRegisteredVault\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [{ name: \"vault\", type: \"address\" }],\n outputs: [{ name: \"\", type: \"bool\" }],\n },\n // Vault management\n {\n name: \"addVault\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [{ name: \"vault\", type: \"address\" }],\n outputs: [],\n },\n {\n name: \"removeVault\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [{ name: \"vault\", type: \"address\" }],\n outputs: [],\n },\n // ── Events ──\n {\n name: \"ProposalCreated\",\n type: \"event\",\n inputs: [\n { name: \"proposalId\", type: \"uint256\", indexed: true },\n { name: \"proposer\", type: \"address\", indexed: true },\n { name: \"vault\", type: \"address\", indexed: true },\n { name: \"performanceFeeBps\", type: \"uint256\", indexed: false },\n { name: \"strategyDuration\", type: \"uint256\", indexed: false },\n { name: \"executeCallCount\", type: \"uint256\", indexed: false },\n { name: \"settlementCallCount\", type: \"uint256\", indexed: false },\n { name: \"metadataURI\", type: \"string\", indexed: false },\n ],\n },\n {\n name: \"VoteCast\",\n type: \"event\",\n inputs: [\n { name: \"proposalId\", type: \"uint256\", indexed: true },\n { name: \"voter\", type: \"address\", indexed: true },\n { name: \"support\", type: \"uint8\", indexed: false },\n { name: \"weight\", type: \"uint256\", indexed: false },\n ],\n },\n {\n name: \"ProposalExecuted\",\n type: \"event\",\n inputs: [\n { name: \"proposalId\", type: \"uint256\", indexed: true },\n { name: \"vault\", type: \"address\", indexed: true },\n { name: \"capitalSnapshot\", type: \"uint256\", indexed: false },\n ],\n },\n {\n name: \"ProposalSettled\",\n type: \"event\",\n inputs: [\n { name: \"proposalId\", type: \"uint256\", indexed: true },\n { name: \"vault\", type: \"address\", indexed: true },\n { name: \"pnl\", type: \"int256\", indexed: false },\n { name: \"performanceFee\", type: \"uint256\", indexed: false },\n { name: \"duration\", type: \"uint256\", indexed: false },\n ],\n },\n {\n name: \"ProposalCancelled\",\n type: \"event\",\n inputs: [\n { name: \"proposalId\", type: \"uint256\", indexed: true },\n { name: \"cancelledBy\", type: \"address\", indexed: true },\n ],\n },\n // Parameter setters (owner-only)\n {\n name: \"setVotingPeriod\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [{ name: \"newVotingPeriod\", type: \"uint256\" }],\n outputs: [],\n },\n {\n name: \"setExecutionWindow\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [{ name: \"newExecutionWindow\", type: \"uint256\" }],\n outputs: [],\n },\n {\n name: \"setVetoThresholdBps\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [{ name: \"newVetoThresholdBps\", type: \"uint256\" }],\n outputs: [],\n },\n {\n name: \"setMaxPerformanceFeeBps\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [{ name: \"newMaxPerformanceFeeBps\", type: \"uint256\" }],\n outputs: [],\n },\n {\n name: \"setMaxStrategyDuration\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [{ name: \"newMaxStrategyDuration\", type: \"uint256\" }],\n outputs: [],\n },\n {\n name: \"setCooldownPeriod\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [{ name: \"newCooldownPeriod\", type: \"uint256\" }],\n outputs: [],\n },\n {\n name: \"vetoProposal\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [{ name: \"proposalId\", type: \"uint256\" }],\n outputs: [],\n },\n {\n name: \"setProtocolFeeBps\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [{ name: \"newProtocolFeeBps\", type: \"uint256\" }],\n outputs: [],\n },\n {\n name: \"getExecuteCalls\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [{ name: \"proposalId\", type: \"uint256\" }],\n outputs: [\n {\n name: \"\",\n type: \"tuple[]\",\n components: [\n { name: \"target\", type: \"address\" },\n { name: \"data\", type: \"bytes\" },\n { name: \"value\", type: \"uint256\" },\n ],\n },\n ],\n },\n {\n name: \"getSettlementCalls\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [{ name: \"proposalId\", type: \"uint256\" }],\n outputs: [\n {\n name: \"\",\n type: \"tuple[]\",\n components: [\n { name: \"target\", type: \"address\" },\n { name: \"data\", type: \"bytes\" },\n { name: \"value\", type: \"uint256\" },\n ],\n },\n ],\n },\n] as const;\n\n// ── EAS Schema Registry ──\n\nexport const SCHEMA_REGISTRY_ABI = [\n {\n name: \"register\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"schema\", type: \"string\" },\n { name: \"resolver\", type: \"address\" },\n { name: \"revocable\", type: \"bool\" },\n ],\n outputs: [{ name: \"\", type: \"bytes32\" }],\n },\n {\n name: \"Registered\",\n type: \"event\",\n inputs: [\n { name: \"uid\", type: \"bytes32\", indexed: true },\n { name: \"registerer\", type: \"address\", indexed: true },\n ],\n },\n] as const;\n\n// ── BaseStrategy (IStrategy + lifecycle views) ──\n\nexport const BASE_STRATEGY_ABI = [\n {\n name: \"initialize\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"vault\", type: \"address\" },\n { name: \"proposer\", type: \"address\" },\n { name: \"data\", type: \"bytes\" },\n ],\n outputs: [],\n },\n {\n name: \"execute\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [],\n outputs: [],\n },\n {\n name: \"settle\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [],\n outputs: [],\n },\n {\n name: \"updateParams\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [{ name: \"data\", type: \"bytes\" }],\n outputs: [],\n },\n {\n name: \"name\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [],\n outputs: [{ name: \"\", type: \"string\" }],\n },\n {\n name: \"vault\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [],\n outputs: [{ name: \"\", type: \"address\" }],\n },\n {\n name: \"proposer\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [],\n outputs: [{ name: \"\", type: \"address\" }],\n },\n {\n name: \"executed\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [],\n outputs: [{ name: \"\", type: \"bool\" }],\n },\n {\n name: \"state\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [],\n outputs: [{ name: \"\", type: \"uint8\" }],\n },\n] as const;\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/governor.ts"],"sourcesContent":["/**\n * Governor contract wrapper — reads/writes to SyndicateGovernor.\n *\n * Provides typed helpers for the proposal lifecycle, voting,\n * settlement, and parameter management.\n */\n\nimport type { Address, Hex, Log } from \"viem\";\nimport { parseEventLogs } from \"viem\";\nimport { getPublicClient, getWalletClient, getAccount } from \"./client.js\";\nimport { getChain } from \"./network.js\";\nimport { SHERWOOD } from \"./addresses.js\";\nimport { SYNDICATE_GOVERNOR_ABI } from \"./abis.js\";\n\n// ── Types ──\n\nexport interface GovernorParams {\n votingPeriod: bigint;\n executionWindow: bigint;\n vetoThresholdBps: bigint;\n maxPerformanceFeeBps: bigint;\n cooldownPeriod: bigint;\n collaborationWindow: bigint;\n maxCoProposers: bigint;\n minStrategyDuration: bigint;\n maxStrategyDuration: bigint;\n}\n\nexport interface StrategyProposal {\n id: bigint;\n proposer: Address;\n vault: Address;\n metadataURI: string;\n performanceFeeBps: bigint;\n strategyDuration: bigint;\n votesFor: bigint;\n votesAgainst: bigint;\n votesAbstain: bigint;\n snapshotTimestamp: bigint;\n voteEnd: bigint;\n executeBy: bigint;\n executedAt: bigint;\n state: number;\n}\n\nexport interface CoProposer {\n agent: Address;\n splitBps: bigint;\n}\n\nexport interface BatchCall {\n target: Address;\n data: Hex;\n value: bigint;\n}\n\nexport const PROPOSAL_STATES = [\n \"Draft\",\n \"Pending\",\n \"Approved\",\n \"Rejected\",\n \"Expired\",\n \"Executed\",\n \"Settled\",\n \"Cancelled\",\n] as const;\n\nexport const PROPOSAL_STATE = {\n Draft: 0,\n Pending: 1,\n Approved: 2,\n Rejected: 3,\n Expired: 4,\n Executed: 5,\n Settled: 6,\n Cancelled: 7,\n} as const;\n\nexport const VOTE_TYPE = {\n For: 0,\n Against: 1,\n Abstain: 2,\n} as const;\n\n// ── Duration parser ──\n\nexport function parseDuration(input: string): bigint {\n const match = input.match(/^(\\d+)(d|h|m|s)?$/);\n if (!match) throw new Error(`Invalid duration: ${input}`);\n const value = BigInt(match[1]);\n switch (match[2]) {\n case \"d\":\n return value * 86400n;\n case \"h\":\n return value * 3600n;\n case \"m\":\n return value * 60n;\n case \"s\":\n case undefined:\n return value;\n default:\n throw new Error(`Unknown duration unit: ${match[2]}`);\n }\n}\n\n// ── Address helper ──\n\nexport function getGovernorAddress(): Address {\n return SHERWOOD().GOVERNOR;\n}\n\n// ── Read helpers ──\n\nexport async function getGovernorParams(): Promise<GovernorParams> {\n const client = getPublicClient();\n const result = await client.readContract({\n address: getGovernorAddress(),\n abi: SYNDICATE_GOVERNOR_ABI,\n functionName: \"getGovernorParams\",\n }) as {\n votingPeriod: bigint;\n executionWindow: bigint;\n vetoThresholdBps: bigint;\n maxPerformanceFeeBps: bigint;\n cooldownPeriod: bigint;\n collaborationWindow: bigint;\n maxCoProposers: bigint;\n minStrategyDuration: bigint;\n maxStrategyDuration: bigint;\n };\n return result;\n}\n\nexport async function getProposal(id: bigint): Promise<StrategyProposal> {\n const client = getPublicClient();\n const result = await client.readContract({\n address: getGovernorAddress(),\n abi: SYNDICATE_GOVERNOR_ABI,\n functionName: \"getProposal\",\n args: [id],\n }) as {\n id: bigint;\n proposer: Address;\n vault: Address;\n metadataURI: string;\n performanceFeeBps: bigint;\n strategyDuration: bigint;\n votesFor: bigint;\n votesAgainst: bigint;\n votesAbstain: bigint;\n snapshotTimestamp: bigint;\n voteEnd: bigint;\n executeBy: bigint;\n executedAt: bigint;\n state: number;\n };\n return result;\n}\n\nexport async function getProposalState(id: bigint): Promise<number> {\n const client = getPublicClient();\n return client.readContract({\n address: getGovernorAddress(),\n abi: SYNDICATE_GOVERNOR_ABI,\n functionName: \"getProposalState\",\n args: [id],\n }) as Promise<number>;\n}\n\nexport async function proposalCount(): Promise<bigint> {\n const client = getPublicClient();\n return client.readContract({\n address: getGovernorAddress(),\n abi: SYNDICATE_GOVERNOR_ABI,\n functionName: \"proposalCount\",\n }) as Promise<bigint>;\n}\n\nexport async function getVoteWeight(proposalId: bigint, voter: Address): Promise<bigint> {\n const client = getPublicClient();\n return client.readContract({\n address: getGovernorAddress(),\n abi: SYNDICATE_GOVERNOR_ABI,\n functionName: \"getVoteWeight\",\n args: [proposalId, voter],\n }) as Promise<bigint>;\n}\n\nexport async function hasVoted(proposalId: bigint, voter: Address): Promise<boolean> {\n const client = getPublicClient();\n return client.readContract({\n address: getGovernorAddress(),\n abi: SYNDICATE_GOVERNOR_ABI,\n functionName: \"hasVoted\",\n args: [proposalId, voter],\n }) as Promise<boolean>;\n}\n\nexport async function getProposalCalls(proposalId: bigint): Promise<BatchCall[]> {\n const client = getPublicClient();\n const result = await client.readContract({\n address: getGovernorAddress(),\n abi: SYNDICATE_GOVERNOR_ABI,\n functionName: \"getProposalCalls\",\n args: [proposalId],\n }) as { target: Address; data: Hex; value: bigint }[];\n return result.map((c) => ({ target: c.target, data: c.data, value: c.value }));\n}\n\nexport async function getExecuteCalls(proposalId: bigint): Promise<BatchCall[]> {\n const client = getPublicClient();\n const result = await client.readContract({\n address: getGovernorAddress(),\n abi: SYNDICATE_GOVERNOR_ABI,\n functionName: \"getExecuteCalls\",\n args: [proposalId],\n }) as { target: Address; data: Hex; value: bigint }[];\n return result.map((c) => ({ target: c.target, data: c.data, value: c.value }));\n}\n\nexport async function getSettlementCalls(proposalId: bigint): Promise<BatchCall[]> {\n const client = getPublicClient();\n const result = await client.readContract({\n address: getGovernorAddress(),\n abi: SYNDICATE_GOVERNOR_ABI,\n functionName: \"getSettlementCalls\",\n args: [proposalId],\n }) as { target: Address; data: Hex; value: bigint }[];\n return result.map((c) => ({ target: c.target, data: c.data, value: c.value }));\n}\n\nexport async function getRegisteredVaults(): Promise<Address[]> {\n const client = getPublicClient();\n return client.readContract({\n address: getGovernorAddress(),\n abi: SYNDICATE_GOVERNOR_ABI,\n functionName: \"getRegisteredVaults\",\n }) as Promise<Address[]>;\n}\n\nexport async function getActiveProposal(vault: Address): Promise<bigint> {\n const client = getPublicClient();\n return client.readContract({\n address: getGovernorAddress(),\n abi: SYNDICATE_GOVERNOR_ABI,\n functionName: \"getActiveProposal\",\n args: [vault],\n }) as Promise<bigint>;\n}\n\nexport async function getCooldownEnd(vault: Address): Promise<bigint> {\n const client = getPublicClient();\n return client.readContract({\n address: getGovernorAddress(),\n abi: SYNDICATE_GOVERNOR_ABI,\n functionName: \"getCooldownEnd\",\n args: [vault],\n }) as Promise<bigint>;\n}\n\nexport async function getCapitalSnapshot(proposalId: bigint): Promise<bigint> {\n const client = getPublicClient();\n return client.readContract({\n address: getGovernorAddress(),\n abi: SYNDICATE_GOVERNOR_ABI,\n functionName: \"getCapitalSnapshot\",\n args: [proposalId],\n }) as Promise<bigint>;\n}\n\nexport async function isRegisteredVault(vault: Address): Promise<boolean> {\n const client = getPublicClient();\n return client.readContract({\n address: getGovernorAddress(),\n abi: SYNDICATE_GOVERNOR_ABI,\n functionName: \"isRegisteredVault\",\n args: [vault],\n }) as Promise<boolean>;\n}\n\n/**\n * Extract proposalId from ProposalCreated event logs.\n * Returns undefined if the event is not found or parsing fails.\n */\nexport function parseProposalIdFromLogs(logs: Log[]): bigint | undefined {\n try {\n const parsed = parseEventLogs({\n abi: SYNDICATE_GOVERNOR_ABI,\n logs,\n eventName: \"ProposalCreated\",\n });\n return parsed[0]?.args.proposalId;\n } catch {\n return undefined;\n }\n}\n\n// ── Write helpers ──\n\nexport async function propose(\n vault: Address,\n metadataURI: string,\n performanceFeeBps: bigint,\n strategyDuration: bigint,\n executeCalls: BatchCall[],\n settlementCalls: BatchCall[],\n coProposers: CoProposer[] = [],\n): Promise<{ hash: Hex; proposalId: bigint }> {\n const wallet = getWalletClient();\n const client = getPublicClient();\n\n const hash = await wallet.writeContract({\n account: getAccount(),\n chain: getChain(),\n address: getGovernorAddress(),\n abi: SYNDICATE_GOVERNOR_ABI,\n functionName: \"propose\",\n args: [vault, metadataURI, performanceFeeBps, strategyDuration, executeCalls, settlementCalls, coProposers],\n });\n\n const receipt = await client.waitForTransactionReceipt({ hash });\n\n // Parse proposalId from the ProposalCreated event in the receipt logs.\n // Falls back to proposalCount() if event parsing fails.\n let proposalId = parseProposalIdFromLogs(receipt.logs);\n if (proposalId === undefined) {\n try {\n proposalId = await proposalCount();\n } catch {\n proposalId = 0n;\n }\n }\n\n return { hash: receipt.transactionHash, proposalId };\n}\n\nexport async function vote(proposalId: bigint, support: number): 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: getGovernorAddress(),\n abi: SYNDICATE_GOVERNOR_ABI,\n functionName: \"vote\",\n args: [proposalId, support],\n });\n\n const receipt = await client.waitForTransactionReceipt({ hash });\n return receipt.transactionHash;\n}\n\nexport async function executeProposal(proposalId: bigint): 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: getGovernorAddress(),\n abi: SYNDICATE_GOVERNOR_ABI,\n functionName: \"executeProposal\",\n args: [proposalId],\n });\n\n const receipt = await client.waitForTransactionReceipt({ hash });\n return receipt.transactionHash;\n}\n\nexport async function settleProposal(proposalId: bigint): 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: getGovernorAddress(),\n abi: SYNDICATE_GOVERNOR_ABI,\n functionName: \"settleProposal\",\n args: [proposalId],\n });\n\n const receipt = await client.waitForTransactionReceipt({ hash });\n return receipt.transactionHash;\n}\n\nexport async function emergencySettle(proposalId: bigint, calls: BatchCall[]): 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: getGovernorAddress(),\n abi: SYNDICATE_GOVERNOR_ABI,\n functionName: \"emergencySettle\",\n args: [proposalId, calls],\n });\n\n const receipt = await client.waitForTransactionReceipt({ hash });\n return receipt.transactionHash;\n}\n\nexport async function cancelProposal(proposalId: bigint): 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: getGovernorAddress(),\n abi: SYNDICATE_GOVERNOR_ABI,\n functionName: \"cancelProposal\",\n args: [proposalId],\n });\n\n const receipt = await client.waitForTransactionReceipt({ hash });\n return receipt.transactionHash;\n}\n\nexport async function emergencyCancel(proposalId: bigint): 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: getGovernorAddress(),\n abi: SYNDICATE_GOVERNOR_ABI,\n functionName: \"emergencyCancel\",\n args: [proposalId],\n });\n\n const receipt = await client.waitForTransactionReceipt({ hash });\n return receipt.transactionHash;\n}\n\n// ── Parameter setters (owner-only) ──\n\nexport async function setVotingPeriod(seconds: bigint): Promise<Hex> {\n const wallet = getWalletClient();\n const client = getPublicClient();\n const hash = await wallet.writeContract({\n account: getAccount(),\n chain: getChain(),\n address: getGovernorAddress(),\n abi: SYNDICATE_GOVERNOR_ABI,\n functionName: \"setVotingPeriod\",\n args: [seconds],\n });\n const receipt = await client.waitForTransactionReceipt({ hash });\n return receipt.transactionHash;\n}\n\nexport async function setExecutionWindow(seconds: bigint): Promise<Hex> {\n const wallet = getWalletClient();\n const client = getPublicClient();\n const hash = await wallet.writeContract({\n account: getAccount(),\n chain: getChain(),\n address: getGovernorAddress(),\n abi: SYNDICATE_GOVERNOR_ABI,\n functionName: \"setExecutionWindow\",\n args: [seconds],\n });\n const receipt = await client.waitForTransactionReceipt({ hash });\n return receipt.transactionHash;\n}\n\nexport async function setVetoThresholdBps(bps: bigint): Promise<Hex> {\n const wallet = getWalletClient();\n const client = getPublicClient();\n const hash = await wallet.writeContract({\n account: getAccount(),\n chain: getChain(),\n address: getGovernorAddress(),\n abi: SYNDICATE_GOVERNOR_ABI,\n functionName: \"setVetoThresholdBps\",\n args: [bps],\n });\n const receipt = await client.waitForTransactionReceipt({ hash });\n return receipt.transactionHash;\n}\n\nexport async function setMaxPerformanceFeeBps(bps: bigint): Promise<Hex> {\n const wallet = getWalletClient();\n const client = getPublicClient();\n const hash = await wallet.writeContract({\n account: getAccount(),\n chain: getChain(),\n address: getGovernorAddress(),\n abi: SYNDICATE_GOVERNOR_ABI,\n functionName: \"setMaxPerformanceFeeBps\",\n args: [bps],\n });\n const receipt = await client.waitForTransactionReceipt({ hash });\n return receipt.transactionHash;\n}\n\nexport async function setMaxStrategyDuration(seconds: bigint): Promise<Hex> {\n const wallet = getWalletClient();\n const client = getPublicClient();\n const hash = await wallet.writeContract({\n account: getAccount(),\n chain: getChain(),\n address: getGovernorAddress(),\n abi: SYNDICATE_GOVERNOR_ABI,\n functionName: \"setMaxStrategyDuration\",\n args: [seconds],\n });\n const receipt = await client.waitForTransactionReceipt({ hash });\n return receipt.transactionHash;\n}\n\nexport async function setCooldownPeriod(seconds: bigint): Promise<Hex> {\n const wallet = getWalletClient();\n const client = getPublicClient();\n const hash = await wallet.writeContract({\n account: getAccount(),\n chain: getChain(),\n address: getGovernorAddress(),\n abi: SYNDICATE_GOVERNOR_ABI,\n functionName: \"setCooldownPeriod\",\n args: [seconds],\n });\n const receipt = await client.waitForTransactionReceipt({ hash });\n return receipt.transactionHash;\n}\n\nexport async function vetoProposal(proposalId: bigint): Promise<Hex> {\n const wallet = getWalletClient();\n const client = getPublicClient();\n const hash = await wallet.writeContract({\n account: getAccount(),\n chain: getChain(),\n address: getGovernorAddress(),\n abi: SYNDICATE_GOVERNOR_ABI,\n functionName: \"vetoProposal\",\n args: [proposalId],\n });\n const receipt = await client.waitForTransactionReceipt({ hash });\n return receipt.transactionHash;\n}\n\nexport async function setProtocolFeeBps(bps: bigint): Promise<Hex> {\n const wallet = getWalletClient();\n const client = getPublicClient();\n const hash = await wallet.writeContract({\n account: getAccount(),\n chain: getChain(),\n address: getGovernorAddress(),\n abi: SYNDICATE_GOVERNOR_ABI,\n functionName: \"setProtocolFeeBps\",\n args: [bps],\n });\n const receipt = await client.waitForTransactionReceipt({ hash });\n return receipt.transactionHash;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -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 {\n getPublicClient,\n getWalletClient,\n getAccount,\n estimateFeesWithBuffer,\n} 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 const asset = await getAssetAddress();\n const fees = await estimateFeesWithBuffer();\n\n // Check existing allowance — skip approve if sufficient\n const currentAllowance = (await client.readContract({\n address: asset,\n abi: ERC20_ABI,\n functionName: \"allowance\",\n args: [account.address, vaultAddress],\n })) as bigint;\n\n if (currentAllowance < amount) {\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 ...fees,\n });\n await client.waitForTransactionReceipt({ hash: approveHash });\n }\n\n // Deposit\n const depositHash = await 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 ...fees,\n });\n await client.waitForTransactionReceipt({ hash: depositHash });\n return depositHash;\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 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: \"executeBatch\",\n args: [\n calls.map((c) => ({\n target: c.target,\n data: c.data,\n value: c.value,\n })),\n ],\n });\n await client.waitForTransactionReceipt({ hash });\n return hash;\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 const client = getPublicClient();\n const hash = await wallet.writeContract({\n account: getAccount(),\n chain: getChain(),\n address: getVaultAddress(),\n abi: SYNDICATE_VAULT_ABI,\n functionName: \"approveDepositor\",\n args: [depositor],\n });\n await client.waitForTransactionReceipt({ hash });\n return hash;\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 const client = getPublicClient();\n const hash = await wallet.writeContract({\n account: getAccount(),\n chain: getChain(),\n address: getVaultAddress(),\n abi: SYNDICATE_VAULT_ABI,\n functionName: \"removeDepositor\",\n args: [depositor],\n });\n await client.waitForTransactionReceipt({ hash });\n return hash;\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 const client = getPublicClient();\n const hash = await wallet.writeContract({\n account: getAccount(),\n chain: getChain(),\n address: getVaultAddress(),\n abi: SYNDICATE_VAULT_ABI,\n functionName: \"approveDepositors\",\n args: [depositors],\n });\n await client.waitForTransactionReceipt({ hash });\n return hash;\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":";;;;;;;;;;;;;;;;;;;;;;AAQA,SAAS,mBAAmB;AAa5B,IAAI,iBAAiC;AAE9B,SAAS,gBAAgB,MAAqB;AACnD,mBAAiB;AACnB;AAEO,SAAS,kBAA2B;AAEzC,MAAI,eAAgB,QAAO;AAG3B,QAAM,UAAU,SAAS,EAAE;AAC3B,QAAM,aAAa,kBAAkB,OAAO,EAAE;AAC9C,MAAI,WAAY,QAAO;AAEvB,QAAM,IAAI;AAAA,IACR;AAAA,EACF;AACF;AAOA,eAAsB,kBAAoC;AACxD,QAAM,SAAS,gBAAgB;AAC/B,SAAO,OAAO,aAAa;AAAA,IACzB,SAAS,gBAAgB;AAAA,IACzB,KAAK;AAAA,IACL,cAAc;AAAA,EAChB,CAAC;AACH;AAMA,eAAsB,mBAAoC;AACxD,QAAM,SAAS,gBAAgB;AAC/B,QAAM,QAAQ,MAAM,gBAAgB;AACpC,SAAO,OAAO,aAAa;AAAA,IACzB,SAAS;AAAA,IACT,KAAK;AAAA,IACL,cAAc;AAAA,EAChB,CAAC;AACH;AAOA,eAAsB,QAAQ,QAA8B;AAC1D,QAAM,SAAS,gBAAgB;AAC/B,QAAM,SAAS,gBAAgB;AAC/B,QAAM,eAAe,gBAAgB;AACrC,QAAM,UAAU,WAAW;AAC3B,QAAM,QAAQ,MAAM,gBAAgB;AACpC,QAAM,OAAO,MAAM,uBAAuB;AAG1C,QAAM,mBAAoB,MAAM,OAAO,aAAa;AAAA,IAClD,SAAS;AAAA,IACT,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC,QAAQ,SAAS,YAAY;AAAA,EACtC,CAAC;AAED,MAAI,mBAAmB,QAAQ;AAC7B,UAAM,cAAc,MAAM,OAAO,cAAc;AAAA,MAC7C,SAAS,WAAW;AAAA,MACpB,OAAO,SAAS;AAAA,MAChB,SAAS;AAAA,MACT,KAAK;AAAA,MACL,cAAc;AAAA,MACd,MAAM,CAAC,cAAc,MAAM;AAAA,MAC3B,GAAG;AAAA,IACL,CAAC;AACD,UAAM,OAAO,0BAA0B,EAAE,MAAM,YAAY,CAAC;AAAA,EAC9D;AAGA,QAAM,cAAc,MAAM,OAAO,cAAc;AAAA,IAC7C,SAAS,WAAW;AAAA,IACpB,OAAO,SAAS;AAAA,IAChB,SAAS;AAAA,IACT,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC,QAAQ,QAAQ,OAAO;AAAA,IAC9B,GAAG;AAAA,EACL,CAAC;AACD,QAAM,OAAO,0BAA0B,EAAE,MAAM,YAAY,CAAC;AAC5D,SAAO;AACT;AASA,eAAsB,aAAa,OAAkC;AACnE,QAAM,SAAS,gBAAgB;AAC/B,QAAM,SAAS,gBAAgB;AAE/B,QAAM,OAAO,MAAM,OAAO,cAAc;AAAA,IACtC,SAAS,WAAW;AAAA,IACpB,OAAO,SAAS;AAAA,IAChB,SAAS,gBAAgB;AAAA,IACzB,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM;AAAA,MACJ,MAAM,IAAI,CAAC,OAAO;AAAA,QAChB,QAAQ,EAAE;AAAA,QACV,MAAM,EAAE;AAAA,QACR,OAAO,EAAE;AAAA,MACX,EAAE;AAAA,IACJ;AAAA,EACF,CAAC;AACD,QAAM,OAAO,0BAA0B,EAAE,KAAK,CAAC;AAC/C,SAAO;AACT;AAOA,eAAsB,iBAAiB,WAAkC;AACvE,QAAM,SAAS,gBAAgB;AAC/B,QAAM,SAAS,gBAAgB;AAC/B,QAAM,OAAO,MAAM,OAAO,cAAc;AAAA,IACtC,SAAS,WAAW;AAAA,IACpB,OAAO,SAAS;AAAA,IAChB,SAAS,gBAAgB;AAAA,IACzB,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC,SAAS;AAAA,EAClB,CAAC;AACD,QAAM,OAAO,0BAA0B,EAAE,KAAK,CAAC;AAC/C,SAAO;AACT;AAKA,eAAsB,gBAAgB,WAAkC;AACtE,QAAM,SAAS,gBAAgB;AAC/B,QAAM,SAAS,gBAAgB;AAC/B,QAAM,OAAO,MAAM,OAAO,cAAc;AAAA,IACtC,SAAS,WAAW;AAAA,IACpB,OAAO,SAAS;AAAA,IAChB,SAAS,gBAAgB;AAAA,IACzB,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC,SAAS;AAAA,EAClB,CAAC;AACD,QAAM,OAAO,0BAA0B,EAAE,KAAK,CAAC;AAC/C,SAAO;AACT;AAuBA,eAAsB,QAAQ,cAAyC;AACrE,QAAM,SAAS,gBAAgB;AAC/B,SAAO,OAAO,aAAa;AAAA,IACzB,SAAS,gBAAgB;AAAA,IACzB,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC,YAAY;AAAA,EACrB,CAAC;AACH;AAkBA,eAAsB,WAAW,SAI9B;AACD,QAAM,SAAS,gBAAgB;AAC/B,QAAM,eAAe,gBAAgB;AACrC,QAAM,UAAU,WAAW,WAAW,EAAE;AAExC,QAAM,CAAC,QAAQ,WAAW,IAAI,MAAM,QAAQ,IAAI;AAAA,IAC9C,OAAO,aAAa;AAAA,MAClB,SAAS;AAAA,MACT,KAAK;AAAA,MACL,cAAc;AAAA,MACd,MAAM,CAAC,OAAO;AAAA,IAChB,CAAC;AAAA,IACD,OAAO,aAAa;AAAA,MAClB,SAAS;AAAA,MACT,KAAK;AAAA,MACL,cAAc;AAAA,IAChB,CAAC;AAAA,EACH,CAAC;AAED,MAAI,cAAc;AAClB,MAAI,SAAS,IAAI;AACf,kBAAe,MAAM,OAAO,aAAa;AAAA,MACvC,SAAS;AAAA,MACT,KAAK;AAAA,MACL,cAAc;AAAA,MACd,MAAM,CAAC,MAAM;AAAA,IACf,CAAC;AAAA,EACH;AAEA,QAAM,UACJ,cAAc,MAAO,OAAO,MAAM,IAAI,OAAO,WAAW,IAAK,KAAK,QAAQ,CAAC,IAAI;AAEjF,QAAM,WAAW,MAAM,iBAAiB;AAExC,SAAO;AAAA,IACL;AAAA,IACA,aAAa,YAAY,aAAa,QAAQ;AAAA,IAC9C,gBAAgB,GAAG,OAAO;AAAA,EAC5B;AACF;AAOA,eAAsB,cACpB,SACA,cACc;AACd,QAAM,SAAS,gBAAgB;AAC/B,QAAM,SAAS,gBAAgB;AAE/B,QAAM,OAAO,MAAM,OAAO,cAAc;AAAA,IACtC,SAAS,WAAW;AAAA,IACpB,OAAO,SAAS;AAAA,IAChB,SAAS,gBAAgB;AAAA,IACzB,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC,SAAS,YAAY;AAAA,EAC9B,CAAC;AAED,QAAM,OAAO,0BAA0B,EAAE,KAAK,CAAC;AAC/C,SAAO;AACT;AAeA,eAAsB,eAAmC;AACvD,QAAM,SAAS,gBAAgB;AAC/B,QAAM,eAAe,gBAAgB;AAErC,QAAM,CAAC,aAAa,YAAY,mBAAmB,kBAAkB,QAAQ,IAC3E,MAAM,QAAQ,IAAI;AAAA,IAChB,OAAO,aAAa;AAAA,MAClB,SAAS;AAAA,MACT,KAAK;AAAA,MACL,cAAc;AAAA,IAChB,CAAC;AAAA,IACD,OAAO,aAAa;AAAA,MAClB,SAAS;AAAA,MACT,KAAK;AAAA,MACL,cAAc;AAAA,IAChB,CAAC;AAAA,IACD,OAAO,aAAa;AAAA,MAClB,SAAS;AAAA,MACT,KAAK;AAAA,MACL,cAAc;AAAA,IAChB,CAAC;AAAA,IACD,OAAO,aAAa;AAAA,MAClB,SAAS;AAAA,MACT,KAAK;AAAA,MACL,cAAc;AAAA,IAChB,CAAC;AAAA,IACD,iBAAiB;AAAA,EACnB,CAAC;AAEH,SAAO;AAAA,IACL,SAAS;AAAA,IACT,aAAa,YAAY,aAAa,QAAQ;AAAA,IAC9C;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;ACjVA,SAAS,0BAA0B;AAEnC,SAAS,gBAAgB;AAezB,IAAM,aAAa;AAEnB,SAAS,oBAA6B;AACpC,SAAO,SAAS,EAAE;AACpB;AAeA,eAAsB,iBAAiB,WAAiD;AACtF,QAAM,SAAS,gBAAgB;AAC/B,QAAM,UAAU,kBAAkB;AAGlC,QAAM,cAAe,MAAM,OAAO,aAAa;AAAA,IAC7C,SAAS;AAAA,IACT,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC,SAAS;AAAA,EAClB,CAAC;AAED,MAAI,gBAAgB,IAAI;AACtB,UAAM,IAAI,MAAM,cAAc,SAAS,aAAa;AAAA,EACtD;AAGA,QAAM,SAAU,MAAM,OAAO,aAAa;AAAA,IACxC,SAAS;AAAA,IACT,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC,WAAW;AAAA,EACpB,CAAC;AAED,SAAO;AAAA,IACL,IAAI,OAAO,CAAC;AAAA,IACZ,OAAO,OAAO,CAAC;AAAA,IACf,SAAS,OAAO,CAAC;AAAA,IACjB,WAAW,OAAO,CAAC;AAAA,EACrB;AACF;AAMA,eAAsB,sBACpB,cAC8B;AAC9B,QAAM,SAAS,gBAAgB;AAC/B,QAAM,UAAU,kBAAkB;AAElC,QAAM,cAAe,MAAM,OAAO,aAAa;AAAA,IAC7C,SAAS;AAAA,IACT,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC,YAAY;AAAA,EACrB,CAAC;AAED,MAAI,gBAAgB,IAAI;AACtB,UAAM,IAAI,MAAM,gCAAgC,YAAY,EAAE;AAAA,EAChE;AAEA,QAAM,SAAU,MAAM,OAAO,aAAa;AAAA,IACxC,SAAS;AAAA,IACT,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC,WAAW;AAAA,EACpB,CAAC;AAED,SAAO;AAAA,IACL,IAAI,OAAO,CAAC;AAAA,IACZ,OAAO,OAAO,CAAC;AAAA,IACf,SAAS,OAAO,CAAC;AAAA,IACjB,WAAW,OAAO,CAAC;AAAA,EACrB;AACF;AAOA,SAAS,iBAAiB,WAAwB;AAChD,SAAO,SAAS,GAAG,SAAS,IAAI,UAAU,EAAE;AAC9C;AAWA,eAAsB,cACpB,WACA,KACA,OACA,cACc;AACd,QAAM,aAAa,IAAI,EAAE;AACzB,QAAM,OAAO,iBAAiB,SAAS;AAEvC,EAAS,gBAAgB,YAAY;AAGrC,QAAM,cAAc,mBAAmB;AAAA,IACrC,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC,MAAM,KAAK,KAAK;AAAA,EACzB,CAAC;AAGD,SAAgB;AAAA,IACd,CAAC,EAAE,QAAQ,YAAY,MAAM,aAAa,OAAO,GAAG,CAAC;AAAA,EACvD;AACF;AAMA,eAAsB,cACpB,WACA,KACiB;AACjB,QAAM,SAAS,gBAAgB;AAC/B,QAAM,OAAO,iBAAiB,SAAS;AAEvC,SAAO,OAAO,aAAa;AAAA,IACzB,SAAS,IAAI,EAAE;AAAA,IACf,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC,MAAM,GAAG;AAAA,EAClB,CAAC;AACH;","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 os from \"node:os\";\nimport path from \"node:path\";\n\nconst CONFIG_DIR = path.join(os.homedir(), \".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 uniswapApiKey?: string; // Uniswap Trading API key (from developers.uniswap.org)\n positions?: unknown[]; // open trade positions (typed in positions.ts)\n closedPositions?: unknown[]; // historical closed positions\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 return { groupCache: {} };\n}\n\nexport function saveConfig(config: SherwoodConfig): void {\n fs.mkdirSync(CONFIG_DIR, { recursive: true, mode: 0o700 });\n fs.writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2), { mode: 0o600 });\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 ?? process.env.VENICE_API_KEY;\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// ── Uniswap Trading API Key ──\n\nexport function setUniswapApiKey(apiKey: string): void {\n const config = loadConfig();\n config.uniswapApiKey = apiKey;\n saveConfig(config);\n}\n\nexport function getUniswapApiKey(): string | undefined {\n return loadConfig().uniswapApiKey ?? process.env.UNISWAP_API_KEY;\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,QAAQ;AACf,OAAO,UAAU;AAEjB,IAAM,aAAa,KAAK,KAAK,GAAG,QAAQ,GAAG,WAAW;AACtD,IAAM,cAAc,KAAK,KAAK,YAAY,aAAa;AAsBhD,SAAS,aAA6B;AAC3C,MAAI,GAAG,WAAW,WAAW,GAAG;AAC9B,WAAO,KAAK,MAAM,GAAG,aAAa,aAAa,OAAO,CAAC;AAAA,EACzD;AAEA,SAAO,EAAE,YAAY,CAAC,EAAE;AAC1B;AAEO,SAAS,WAAW,QAA8B;AACvD,KAAG,UAAU,YAAY,EAAE,WAAW,MAAM,MAAM,IAAM,CAAC;AACzD,KAAG,cAAc,aAAa,KAAK,UAAU,QAAQ,MAAM,CAAC,GAAG,EAAE,MAAM,IAAM,CAAC;AAChF;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,gBAAgB,QAAQ,IAAI;AAClD;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,iBAAiB,QAAsB;AACrD,QAAM,SAAS,WAAW;AAC1B,SAAO,gBAAgB;AACvB,aAAW,MAAM;AACnB;AAEO,SAAS,mBAAuC;AACrD,SAAO,WAAW,EAAE,iBAAiB,QAAQ,IAAI;AACnD;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/eas.ts"],"sourcesContent":["/**\n * EAS (Ethereum Attestation Service) wrapper for syndicate join requests and approvals.\n *\n * Uses viem for on-chain writes and the EAS GraphQL API for queries.\n * No ethers dependency — attestation data is encoded with viem's encodeAbiParameters.\n */\n\nimport type { Address, Hex } from \"viem\";\nimport { encodeAbiParameters, parseAbiParameters, decodeAbiParameters } from \"viem\";\nimport { getPublicClient, getWalletClient, getAccount } from \"./client.js\";\nimport { getChain, getNetwork, getChainConfig } from \"./network.js\";\nimport { EAS_CONTRACTS, EAS_SCHEMAS } from \"./addresses.js\";\nimport { EAS_ABI } from \"./abis.js\";\n\n// ── Schema definitions ──\n\nconst ZERO_BYTES32 = \"0x0000000000000000000000000000000000000000000000000000000000000000\" as Hex;\n\n// keccak256(\"Attested(address,address,bytes32,bytes32)\")\nconst ATTESTED_TOPIC = \"0x8bf46bf4cfd674fa735a3d63ec1c9ad4153f033c290341f3a588b75685141b35\" as Hex;\n\nconst JOIN_REQUEST_PARAMS = parseAbiParameters(\"uint256, uint256, address, string\");\nconst AGENT_APPROVED_PARAMS = parseAbiParameters(\"uint256, uint256, address\");\nconst X402_RESEARCH_PARAMS = parseAbiParameters(\"string, string, string, string, string\");\nconst VENICE_PROVISION_PARAMS = parseAbiParameters(\"address, string\");\nconst VENICE_INFERENCE_PARAMS = parseAbiParameters(\"string, uint256, uint256, string\");\nconst TRADE_EXECUTED_PARAMS = parseAbiParameters(\"address, address, uint256, string, string, string\");\n\nfunction assertSchemasRegistered() {\n const schemas = EAS_SCHEMAS();\n if (schemas.SYNDICATE_JOIN_REQUEST === ZERO_BYTES32 || schemas.AGENT_APPROVED === ZERO_BYTES32) {\n throw new Error(\n \"EAS schemas not registered. Run: npx tsx scripts/register-eas-schemas.ts --testnet\",\n );\n }\n}\n\n// ── GraphQL ──\n\nfunction getEasGraphqlUrl(): string {\n const url = getChainConfig().easGraphqlUrl;\n if (!url) {\n throw new Error(\n `EAS is not available on ${getNetwork()}. Attestation operations require a chain with EAS (e.g. base, base-sepolia).`,\n );\n }\n return url;\n}\n\nexport function getEasScanUrl(uid: Hex): string {\n const host = getChainConfig().easScanHost;\n if (!host) {\n throw new Error(`EAS scan is not available on ${getNetwork()}.`);\n }\n return `https://${host}/attestation/view/${uid}`;\n}\n\n// ── Attestation Creation ──\n\n/**\n * Extract the attestation UID from a transaction receipt.\n * The EAS contract emits: event Attested(address indexed recipient, address indexed attester, bytes32 uid, bytes32 indexed schemaUID)\n * uid is a non-indexed parameter in the event data.\n */\nfunction extractAttestationUid(receipt: { logs: readonly { topics: readonly Hex[]; data: Hex }[] }): Hex {\n for (const log of receipt.logs) {\n // Match the Attested event signature to avoid false positives from other events\n if (log.topics[0] !== ATTESTED_TOPIC) continue;\n // Attested event has 4 topics (sig + 3 indexed) and data contains the uid (bytes32)\n if (log.topics.length === 4 && log.data.length >= 66) {\n return (\"0x\" + log.data.slice(2, 66)) as Hex;\n }\n }\n throw new Error(\"Could not extract attestation UID from transaction receipt\");\n}\n\n/**\n * Create a SYNDICATE_JOIN_REQUEST attestation.\n * Attester: the calling agent. Recipient: the syndicate creator.\n */\nexport async function createJoinRequest(\n syndicateId: bigint,\n agentId: bigint,\n vault: Address,\n creatorAddress: Address,\n message: string,\n): Promise<{ uid: Hex; hash: Hex }> {\n assertSchemasRegistered();\n const wallet = getWalletClient();\n const client = getPublicClient();\n\n const data = encodeAbiParameters(JOIN_REQUEST_PARAMS, [\n syndicateId, agentId, vault, message,\n ]);\n\n const hash = await wallet.writeContract({\n account: getAccount(),\n chain: getChain(),\n address: EAS_CONTRACTS().EAS,\n abi: EAS_ABI,\n functionName: \"attest\",\n args: [{\n schema: EAS_SCHEMAS().SYNDICATE_JOIN_REQUEST,\n data: {\n recipient: creatorAddress,\n expirationTime: 0n,\n revocable: true,\n refUID: ZERO_BYTES32,\n data,\n value: 0n,\n },\n }],\n value: 0n,\n });\n\n const receipt = await client.waitForTransactionReceipt({ hash });\n const uid = extractAttestationUid(receipt);\n\n return { uid, hash };\n}\n\n/**\n * Create an AGENT_APPROVED attestation.\n * Attester: the syndicate creator. Recipient: the agent wallet.\n */\nexport async function createApproval(\n syndicateId: bigint,\n agentId: bigint,\n vault: Address,\n agentAddress: Address,\n): Promise<{ uid: Hex; hash: Hex }> {\n assertSchemasRegistered();\n const wallet = getWalletClient();\n const client = getPublicClient();\n\n const data = encodeAbiParameters(AGENT_APPROVED_PARAMS, [\n syndicateId, agentId, vault,\n ]);\n\n const hash = await wallet.writeContract({\n account: getAccount(),\n chain: getChain(),\n address: EAS_CONTRACTS().EAS,\n abi: EAS_ABI,\n functionName: \"attest\",\n args: [{\n schema: EAS_SCHEMAS().AGENT_APPROVED,\n data: {\n recipient: agentAddress,\n expirationTime: 0n,\n revocable: true,\n refUID: ZERO_BYTES32,\n data,\n value: 0n,\n },\n }],\n value: 0n,\n });\n\n const receipt = await client.waitForTransactionReceipt({ hash });\n const uid = extractAttestationUid(receipt);\n\n return { uid, hash };\n}\n\n/**\n * Revoke an attestation. Only the original attester can revoke.\n */\nexport async function revokeAttestation(\n schemaUid: Hex,\n attestationUid: Hex,\n): Promise<Hex> {\n const wallet = getWalletClient();\n\n return wallet.writeContract({\n account: getAccount(),\n chain: getChain(),\n address: EAS_CONTRACTS().EAS,\n abi: EAS_ABI,\n functionName: \"revoke\",\n args: [{\n schema: schemaUid,\n data: {\n uid: attestationUid,\n value: 0n,\n },\n }],\n value: 0n,\n });\n}\n\n/**\n * Create an X402_RESEARCH attestation — records a research query on-chain.\n * Attester: the agent. Recipient: vault address (links to syndicate) or agent itself.\n * Schema: \"string provider, string queryType, string prompt, string costUsdc, string resultUri\"\n */\nexport async function createResearchAttestation(\n provider: string,\n queryType: string,\n prompt: string,\n costUsdc: string,\n resultUri: string,\n recipient?: Address,\n): Promise<{ uid: Hex; hash: Hex }> {\n const schemas = EAS_SCHEMAS();\n if (schemas.X402_RESEARCH === ZERO_BYTES32) {\n throw new Error(\n \"X402_RESEARCH schema not registered. Run: npx tsx scripts/register-eas-schemas.ts --testnet\",\n );\n }\n\n const wallet = getWalletClient();\n const client = getPublicClient();\n const account = getAccount();\n\n const data = encodeAbiParameters(X402_RESEARCH_PARAMS, [\n provider, queryType, prompt, costUsdc, resultUri,\n ]);\n\n const hash = await wallet.writeContract({\n account,\n chain: getChain(),\n address: EAS_CONTRACTS().EAS,\n abi: EAS_ABI,\n functionName: \"attest\",\n args: [{\n schema: schemas.X402_RESEARCH,\n data: {\n recipient: recipient ?? account.address,\n expirationTime: 0n,\n revocable: false,\n refUID: ZERO_BYTES32,\n data,\n value: 0n,\n },\n }],\n value: 0n,\n });\n\n const receipt = await client.waitForTransactionReceipt({ hash });\n const uid = extractAttestationUid(receipt);\n\n return { uid, hash };\n}\n\n/**\n * Create a VENICE_PROVISION attestation — records that an agent provisioned a Venice API key.\n * Schema: \"address agent, string status\"\n */\nexport async function createVeniceProvisionAttestation(\n agent: Address,\n): Promise<{ uid: Hex; hash: Hex }> {\n const schemas = EAS_SCHEMAS();\n if (schemas.VENICE_PROVISION === ZERO_BYTES32) return skipAttestation(\"VENICE_PROVISION\");\n\n const wallet = getWalletClient();\n const client = getPublicClient();\n const account = getAccount();\n\n const data = encodeAbiParameters(VENICE_PROVISION_PARAMS, [agent, \"provisioned\"]);\n\n const hash = await wallet.writeContract({\n account,\n chain: getChain(),\n address: EAS_CONTRACTS().EAS,\n abi: EAS_ABI,\n functionName: \"attest\",\n args: [{\n schema: schemas.VENICE_PROVISION,\n data: {\n recipient: agent,\n expirationTime: 0n,\n revocable: false,\n refUID: ZERO_BYTES32,\n data,\n value: 0n,\n },\n }],\n value: 0n,\n });\n\n const receipt = await client.waitForTransactionReceipt({ hash });\n const uid = extractAttestationUid(receipt);\n return { uid, hash };\n}\n\n/**\n * Create a VENICE_INFERENCE attestation — records an inference call.\n * Attester: the agent. Recipient: vault address (links to syndicate) or agent itself.\n * Schema: \"string model, uint256 promptTokens, uint256 completionTokens, string promptHash\"\n */\nexport async function createVeniceInferenceAttestation(\n model: string,\n promptTokens: number,\n completionTokens: number,\n promptHash: string,\n recipient?: Address,\n): Promise<{ uid: Hex; hash: Hex }> {\n const schemas = EAS_SCHEMAS();\n if (schemas.VENICE_INFERENCE === ZERO_BYTES32) return skipAttestation(\"VENICE_INFERENCE\");\n\n const wallet = getWalletClient();\n const client = getPublicClient();\n const account = getAccount();\n\n const data = encodeAbiParameters(VENICE_INFERENCE_PARAMS, [\n model,\n BigInt(promptTokens),\n BigInt(completionTokens),\n promptHash,\n ]);\n\n const hash = await wallet.writeContract({\n account,\n chain: getChain(),\n address: EAS_CONTRACTS().EAS,\n abi: EAS_ABI,\n functionName: \"attest\",\n args: [{\n schema: schemas.VENICE_INFERENCE,\n data: {\n recipient: recipient ?? account.address,\n expirationTime: 0n,\n revocable: false,\n refUID: ZERO_BYTES32,\n data,\n value: 0n,\n },\n }],\n value: 0n,\n });\n\n const receipt = await client.waitForTransactionReceipt({ hash });\n const uid = extractAttestationUid(receipt);\n return { uid, hash };\n}\n\n/**\n * Create a TRADE_EXECUTED attestation — records a swap on-chain.\n * Attester: the agent. Recipient: vault address (links to syndicate) or agent itself.\n * Schema: \"address tokenIn, address tokenOut, uint256 amountIn, string amountOut, string txHash, string routing\"\n */\nexport async function createTradeAttestation(\n tokenIn: Address,\n tokenOut: Address,\n amountIn: bigint,\n amountOut: string,\n txHash: string,\n routing: string,\n recipient?: Address,\n): Promise<{ uid: Hex; hash: Hex }> {\n const schemas = EAS_SCHEMAS();\n if (schemas.TRADE_EXECUTED === ZERO_BYTES32) return skipAttestation(\"TRADE_EXECUTED\");\n\n const wallet = getWalletClient();\n const client = getPublicClient();\n const account = getAccount();\n\n const data = encodeAbiParameters(TRADE_EXECUTED_PARAMS, [\n tokenIn, tokenOut, amountIn, amountOut, txHash, routing,\n ]);\n\n const hash = await wallet.writeContract({\n account,\n chain: getChain(),\n address: EAS_CONTRACTS().EAS,\n abi: EAS_ABI,\n functionName: \"attest\",\n args: [{\n schema: schemas.TRADE_EXECUTED,\n data: {\n recipient: recipient ?? account.address,\n expirationTime: 0n,\n revocable: false,\n refUID: ZERO_BYTES32,\n data,\n value: 0n,\n },\n }],\n value: 0n,\n });\n\n const receipt = await client.waitForTransactionReceipt({ hash });\n const uid = extractAttestationUid(receipt);\n return { uid, hash };\n}\n\n/** Skip attestation gracefully when schema isn't registered on this chain. */\nfunction skipAttestation(name: string): { uid: Hex; hash: Hex } {\n return { uid: ZERO_BYTES32, hash: ZERO_BYTES32 };\n}\n\n// ── Attestation Queries ──\n\nexport interface JoinRequestAttestation {\n uid: Hex;\n attester: Address;\n recipient: Address;\n time: number;\n decoded: {\n syndicateId: bigint;\n agentId: bigint;\n vault: Address;\n message: string;\n };\n}\n\n/**\n * Query pending (non-revoked) join requests for a given recipient (creator address).\n * Uses the EAS GraphQL API.\n */\nexport interface ApprovalAttestation {\n uid: Hex;\n attester: Address;\n recipient: Address;\n time: number;\n decoded: {\n syndicateId: bigint;\n agentId: bigint;\n vault: Address;\n };\n}\n\n/**\n * Query existing (non-revoked) AGENT_APPROVED attestations created by a given attester (creator).\n * Used to check for duplicates before creating a new approval and to filter already-approved agents from requests.\n */\nexport async function queryApprovals(\n attester: Address,\n): Promise<ApprovalAttestation[]> {\n assertSchemasRegistered();\n const schemaUid = EAS_SCHEMAS().AGENT_APPROVED;\n const url = getEasGraphqlUrl();\n\n const query = `\n query Approvals($schemaId: String!, $attester: String!) {\n attestations(\n where: {\n schemaId: { equals: $schemaId }\n attester: { equals: $attester }\n revoked: { equals: false }\n }\n orderBy: [{ time: desc }]\n ) {\n id\n attester\n recipient\n time\n data\n }\n }\n `;\n\n const response = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n query,\n variables: { schemaId: schemaUid, attester },\n }),\n });\n\n if (!response.ok) {\n throw new Error(`EAS GraphQL query failed: ${response.statusText}`);\n }\n\n const json = await response.json() as {\n data?: {\n attestations: Array<{\n id: string;\n attester: string;\n recipient: string;\n time: number;\n data: string;\n }>;\n };\n };\n\n if (!json.data?.attestations) return [];\n\n return json.data.attestations.map((a) => {\n const decoded = decodeAbiParameters(AGENT_APPROVED_PARAMS, a.data as Hex);\n return {\n uid: a.id as Hex,\n attester: a.attester as Address,\n recipient: a.recipient as Address,\n time: a.time,\n decoded: {\n syndicateId: decoded[0],\n agentId: decoded[1],\n vault: decoded[2],\n },\n };\n });\n}\n\nexport async function queryJoinRequests(\n recipient: Address,\n): Promise<JoinRequestAttestation[]> {\n assertSchemasRegistered();\n const schemaUid = EAS_SCHEMAS().SYNDICATE_JOIN_REQUEST;\n const url = getEasGraphqlUrl();\n\n const query = `\n query JoinRequests($schemaId: String!, $recipient: String!) {\n attestations(\n where: {\n schemaId: { equals: $schemaId }\n recipient: { equals: $recipient }\n revoked: { equals: false }\n }\n orderBy: [{ time: desc }]\n ) {\n id\n attester\n recipient\n time\n data\n }\n }\n `;\n\n const response = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n query,\n variables: { schemaId: schemaUid, recipient },\n }),\n });\n\n if (!response.ok) {\n throw new Error(`EAS GraphQL query failed: ${response.statusText}`);\n }\n\n const json = await response.json() as {\n data?: {\n attestations: Array<{\n id: string;\n attester: string;\n recipient: string;\n time: number;\n data: string;\n }>;\n };\n };\n\n if (!json.data?.attestations) return [];\n\n return json.data.attestations.map((a) => {\n const decoded = decodeAbiParameters(JOIN_REQUEST_PARAMS, a.data as Hex);\n return {\n uid: a.id as Hex,\n attester: a.attester as Address,\n recipient: a.recipient as Address,\n time: a.time,\n decoded: {\n syndicateId: decoded[0],\n agentId: decoded[1],\n vault: decoded[2],\n message: decoded[3],\n },\n };\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAQA,SAAS,qBAAqB,oBAAoB,2BAA2B;AAQ7E,IAAM,eAAe;AAGrB,IAAM,iBAAiB;AAEvB,IAAM,sBAAsB,mBAAmB,mCAAmC;AAClF,IAAM,wBAAwB,mBAAmB,2BAA2B;AAC5E,IAAM,uBAAuB,mBAAmB,wCAAwC;AACxF,IAAM,0BAA0B,mBAAmB,iBAAiB;AACpE,IAAM,0BAA0B,mBAAmB,kCAAkC;AACrF,IAAM,wBAAwB,mBAAmB,mDAAmD;AAEpG,SAAS,0BAA0B;AACjC,QAAM,UAAU,YAAY;AAC5B,MAAI,QAAQ,2BAA2B,gBAAgB,QAAQ,mBAAmB,cAAc;AAC9F,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACF;AAIA,SAAS,mBAA2B;AAClC,QAAM,MAAM,eAAe,EAAE;AAC7B,MAAI,CAAC,KAAK;AACR,UAAM,IAAI;AAAA,MACR,2BAA2B,WAAW,CAAC;AAAA,IACzC;AAAA,EACF;AACA,SAAO;AACT;AAEO,SAAS,cAAc,KAAkB;AAC9C,QAAM,OAAO,eAAe,EAAE;AAC9B,MAAI,CAAC,MAAM;AACT,UAAM,IAAI,MAAM,gCAAgC,WAAW,CAAC,GAAG;AAAA,EACjE;AACA,SAAO,WAAW,IAAI,qBAAqB,GAAG;AAChD;AASA,SAAS,sBAAsB,SAA0E;AACvG,aAAW,OAAO,QAAQ,MAAM;AAE9B,QAAI,IAAI,OAAO,CAAC,MAAM,eAAgB;AAEtC,QAAI,IAAI,OAAO,WAAW,KAAK,IAAI,KAAK,UAAU,IAAI;AACpD,aAAQ,OAAO,IAAI,KAAK,MAAM,GAAG,EAAE;AAAA,IACrC;AAAA,EACF;AACA,QAAM,IAAI,MAAM,4DAA4D;AAC9E;AAMA,eAAsB,kBACpB,aACA,SACA,OACA,gBACA,SACkC;AAClC,0BAAwB;AACxB,QAAM,SAAS,gBAAgB;AAC/B,QAAM,SAAS,gBAAgB;AAE/B,QAAM,OAAO,oBAAoB,qBAAqB;AAAA,IACpD;AAAA,IAAa;AAAA,IAAS;AAAA,IAAO;AAAA,EAC/B,CAAC;AAED,QAAM,OAAO,MAAM,OAAO,cAAc;AAAA,IACtC,SAAS,WAAW;AAAA,IACpB,OAAO,SAAS;AAAA,IAChB,SAAS,cAAc,EAAE;AAAA,IACzB,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC;AAAA,MACL,QAAQ,YAAY,EAAE;AAAA,MACtB,MAAM;AAAA,QACJ,WAAW;AAAA,QACX,gBAAgB;AAAA,QAChB,WAAW;AAAA,QACX,QAAQ;AAAA,QACR;AAAA,QACA,OAAO;AAAA,MACT;AAAA,IACF,CAAC;AAAA,IACD,OAAO;AAAA,EACT,CAAC;AAED,QAAM,UAAU,MAAM,OAAO,0BAA0B,EAAE,KAAK,CAAC;AAC/D,QAAM,MAAM,sBAAsB,OAAO;AAEzC,SAAO,EAAE,KAAK,KAAK;AACrB;AAMA,eAAsB,eACpB,aACA,SACA,OACA,cACkC;AAClC,0BAAwB;AACxB,QAAM,SAAS,gBAAgB;AAC/B,QAAM,SAAS,gBAAgB;AAE/B,QAAM,OAAO,oBAAoB,uBAAuB;AAAA,IACtD;AAAA,IAAa;AAAA,IAAS;AAAA,EACxB,CAAC;AAED,QAAM,OAAO,MAAM,OAAO,cAAc;AAAA,IACtC,SAAS,WAAW;AAAA,IACpB,OAAO,SAAS;AAAA,IAChB,SAAS,cAAc,EAAE;AAAA,IACzB,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC;AAAA,MACL,QAAQ,YAAY,EAAE;AAAA,MACtB,MAAM;AAAA,QACJ,WAAW;AAAA,QACX,gBAAgB;AAAA,QAChB,WAAW;AAAA,QACX,QAAQ;AAAA,QACR;AAAA,QACA,OAAO;AAAA,MACT;AAAA,IACF,CAAC;AAAA,IACD,OAAO;AAAA,EACT,CAAC;AAED,QAAM,UAAU,MAAM,OAAO,0BAA0B,EAAE,KAAK,CAAC;AAC/D,QAAM,MAAM,sBAAsB,OAAO;AAEzC,SAAO,EAAE,KAAK,KAAK;AACrB;AAKA,eAAsB,kBACpB,WACA,gBACc;AACd,QAAM,SAAS,gBAAgB;AAE/B,SAAO,OAAO,cAAc;AAAA,IAC1B,SAAS,WAAW;AAAA,IACpB,OAAO,SAAS;AAAA,IAChB,SAAS,cAAc,EAAE;AAAA,IACzB,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC;AAAA,MACL,QAAQ;AAAA,MACR,MAAM;AAAA,QACJ,KAAK;AAAA,QACL,OAAO;AAAA,MACT;AAAA,IACF,CAAC;AAAA,IACD,OAAO;AAAA,EACT,CAAC;AACH;AAOA,eAAsB,0BACpB,UACA,WACA,QACA,UACA,WACA,WACkC;AAClC,QAAM,UAAU,YAAY;AAC5B,MAAI,QAAQ,kBAAkB,cAAc;AAC1C,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAS,gBAAgB;AAC/B,QAAM,SAAS,gBAAgB;AAC/B,QAAM,UAAU,WAAW;AAE3B,QAAM,OAAO,oBAAoB,sBAAsB;AAAA,IACrD;AAAA,IAAU;AAAA,IAAW;AAAA,IAAQ;AAAA,IAAU;AAAA,EACzC,CAAC;AAED,QAAM,OAAO,MAAM,OAAO,cAAc;AAAA,IACtC;AAAA,IACA,OAAO,SAAS;AAAA,IAChB,SAAS,cAAc,EAAE;AAAA,IACzB,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC;AAAA,MACL,QAAQ,QAAQ;AAAA,MAChB,MAAM;AAAA,QACJ,WAAW,aAAa,QAAQ;AAAA,QAChC,gBAAgB;AAAA,QAChB,WAAW;AAAA,QACX,QAAQ;AAAA,QACR;AAAA,QACA,OAAO;AAAA,MACT;AAAA,IACF,CAAC;AAAA,IACD,OAAO;AAAA,EACT,CAAC;AAED,QAAM,UAAU,MAAM,OAAO,0BAA0B,EAAE,KAAK,CAAC;AAC/D,QAAM,MAAM,sBAAsB,OAAO;AAEzC,SAAO,EAAE,KAAK,KAAK;AACrB;AAMA,eAAsB,iCACpB,OACkC;AAClC,QAAM,UAAU,YAAY;AAC5B,MAAI,QAAQ,qBAAqB,aAAc,QAAO,gBAAgB,kBAAkB;AAExF,QAAM,SAAS,gBAAgB;AAC/B,QAAM,SAAS,gBAAgB;AAC/B,QAAM,UAAU,WAAW;AAE3B,QAAM,OAAO,oBAAoB,yBAAyB,CAAC,OAAO,aAAa,CAAC;AAEhF,QAAM,OAAO,MAAM,OAAO,cAAc;AAAA,IACtC;AAAA,IACA,OAAO,SAAS;AAAA,IAChB,SAAS,cAAc,EAAE;AAAA,IACzB,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC;AAAA,MACL,QAAQ,QAAQ;AAAA,MAChB,MAAM;AAAA,QACJ,WAAW;AAAA,QACX,gBAAgB;AAAA,QAChB,WAAW;AAAA,QACX,QAAQ;AAAA,QACR;AAAA,QACA,OAAO;AAAA,MACT;AAAA,IACF,CAAC;AAAA,IACD,OAAO;AAAA,EACT,CAAC;AAED,QAAM,UAAU,MAAM,OAAO,0BAA0B,EAAE,KAAK,CAAC;AAC/D,QAAM,MAAM,sBAAsB,OAAO;AACzC,SAAO,EAAE,KAAK,KAAK;AACrB;AAOA,eAAsB,iCACpB,OACA,cACA,kBACA,YACA,WACkC;AAClC,QAAM,UAAU,YAAY;AAC5B,MAAI,QAAQ,qBAAqB,aAAc,QAAO,gBAAgB,kBAAkB;AAExF,QAAM,SAAS,gBAAgB;AAC/B,QAAM,SAAS,gBAAgB;AAC/B,QAAM,UAAU,WAAW;AAE3B,QAAM,OAAO,oBAAoB,yBAAyB;AAAA,IACxD;AAAA,IACA,OAAO,YAAY;AAAA,IACnB,OAAO,gBAAgB;AAAA,IACvB;AAAA,EACF,CAAC;AAED,QAAM,OAAO,MAAM,OAAO,cAAc;AAAA,IACtC;AAAA,IACA,OAAO,SAAS;AAAA,IAChB,SAAS,cAAc,EAAE;AAAA,IACzB,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC;AAAA,MACL,QAAQ,QAAQ;AAAA,MAChB,MAAM;AAAA,QACJ,WAAW,aAAa,QAAQ;AAAA,QAChC,gBAAgB;AAAA,QAChB,WAAW;AAAA,QACX,QAAQ;AAAA,QACR;AAAA,QACA,OAAO;AAAA,MACT;AAAA,IACF,CAAC;AAAA,IACD,OAAO;AAAA,EACT,CAAC;AAED,QAAM,UAAU,MAAM,OAAO,0BAA0B,EAAE,KAAK,CAAC;AAC/D,QAAM,MAAM,sBAAsB,OAAO;AACzC,SAAO,EAAE,KAAK,KAAK;AACrB;AAOA,eAAsB,uBACpB,SACA,UACA,UACA,WACA,QACA,SACA,WACkC;AAClC,QAAM,UAAU,YAAY;AAC5B,MAAI,QAAQ,mBAAmB,aAAc,QAAO,gBAAgB,gBAAgB;AAEpF,QAAM,SAAS,gBAAgB;AAC/B,QAAM,SAAS,gBAAgB;AAC/B,QAAM,UAAU,WAAW;AAE3B,QAAM,OAAO,oBAAoB,uBAAuB;AAAA,IACtD;AAAA,IAAS;AAAA,IAAU;AAAA,IAAU;AAAA,IAAW;AAAA,IAAQ;AAAA,EAClD,CAAC;AAED,QAAM,OAAO,MAAM,OAAO,cAAc;AAAA,IACtC;AAAA,IACA,OAAO,SAAS;AAAA,IAChB,SAAS,cAAc,EAAE;AAAA,IACzB,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC;AAAA,MACL,QAAQ,QAAQ;AAAA,MAChB,MAAM;AAAA,QACJ,WAAW,aAAa,QAAQ;AAAA,QAChC,gBAAgB;AAAA,QAChB,WAAW;AAAA,QACX,QAAQ;AAAA,QACR;AAAA,QACA,OAAO;AAAA,MACT;AAAA,IACF,CAAC;AAAA,IACD,OAAO;AAAA,EACT,CAAC;AAED,QAAM,UAAU,MAAM,OAAO,0BAA0B,EAAE,KAAK,CAAC;AAC/D,QAAM,MAAM,sBAAsB,OAAO;AACzC,SAAO,EAAE,KAAK,KAAK;AACrB;AAGA,SAAS,gBAAgB,MAAuC;AAC9D,SAAO,EAAE,KAAK,cAAc,MAAM,aAAa;AACjD;AAqCA,eAAsB,eACpB,UACgC;AAChC,0BAAwB;AACxB,QAAM,YAAY,YAAY,EAAE;AAChC,QAAM,MAAM,iBAAiB;AAE7B,QAAM,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAmBd,QAAM,WAAW,MAAM,MAAM,KAAK;AAAA,IAChC,QAAQ;AAAA,IACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,IAC9C,MAAM,KAAK,UAAU;AAAA,MACnB;AAAA,MACA,WAAW,EAAE,UAAU,WAAW,SAAS;AAAA,IAC7C,CAAC;AAAA,EACH,CAAC;AAED,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,IAAI,MAAM,6BAA6B,SAAS,UAAU,EAAE;AAAA,EACpE;AAEA,QAAM,OAAO,MAAM,SAAS,KAAK;AAYjC,MAAI,CAAC,KAAK,MAAM,aAAc,QAAO,CAAC;AAEtC,SAAO,KAAK,KAAK,aAAa,IAAI,CAAC,MAAM;AACvC,UAAM,UAAU,oBAAoB,uBAAuB,EAAE,IAAW;AACxE,WAAO;AAAA,MACL,KAAK,EAAE;AAAA,MACP,UAAU,EAAE;AAAA,MACZ,WAAW,EAAE;AAAA,MACb,MAAM,EAAE;AAAA,MACR,SAAS;AAAA,QACP,aAAa,QAAQ,CAAC;AAAA,QACtB,SAAS,QAAQ,CAAC;AAAA,QAClB,OAAO,QAAQ,CAAC;AAAA,MAClB;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAEA,eAAsB,kBACpB,WACmC;AACnC,0BAAwB;AACxB,QAAM,YAAY,YAAY,EAAE;AAChC,QAAM,MAAM,iBAAiB;AAE7B,QAAM,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAmBd,QAAM,WAAW,MAAM,MAAM,KAAK;AAAA,IAChC,QAAQ;AAAA,IACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,IAC9C,MAAM,KAAK,UAAU;AAAA,MACnB;AAAA,MACA,WAAW,EAAE,UAAU,WAAW,UAAU;AAAA,IAC9C,CAAC;AAAA,EACH,CAAC;AAED,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,IAAI,MAAM,6BAA6B,SAAS,UAAU,EAAE;AAAA,EACpE;AAEA,QAAM,OAAO,MAAM,SAAS,KAAK;AAYjC,MAAI,CAAC,KAAK,MAAM,aAAc,QAAO,CAAC;AAEtC,SAAO,KAAK,KAAK,aAAa,IAAI,CAAC,MAAM;AACvC,UAAM,UAAU,oBAAoB,qBAAqB,EAAE,IAAW;AACtE,WAAO;AAAA,MACL,KAAK,EAAE;AAAA,MACP,UAAU,EAAE;AAAA,MACZ,WAAW,EAAE;AAAA,MACb,MAAM,EAAE;AAAA,MACR,SAAS;AAAA,QACP,aAAa,QAAQ,CAAC;AAAA,QACtB,SAAS,QAAQ,CAAC;AAAA,QAClB,OAAO,QAAQ,CAAC;AAAA,QAChB,SAAS,QAAQ,CAAC;AAAA,MACpB;AAAA,IACF;AAAA,EACF,CAAC;AACH;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/providers/research/messari.ts","../src/lib/x402.ts","../src/providers/research/nansen.ts","../src/providers/research/index.ts"],"sourcesContent":["/**\n * Messari research provider — x402 micropayments for crypto market data.\n *\n * Docs: https://docs.messari.io\n * Payment: x402 (USDC on Base) — no API key required\n * Data: 34,000+ assets, market metrics, asset profiles\n * Pricing: $0.10/call for asset details, ROI, ATH. $0.15–$0.35 for timeseries.\n * $0.55 for news/signals. Full pricing: https://docs.messari.io/api-reference/x402-payments\n *\n * Supports:\n * token → asset details (description, category, sector, links, market snapshot)\n * market → market metrics + ATH (price, volume, market cap, ROI, ATH, cycle low)\n *\n * Not supported (use --provider nansen instead):\n * smart-money → on-chain analytics not available in Messari x402 API\n * wallet → wallet profiling not available in Messari x402 API\n */\n\nimport { base, baseSepolia } from \"viem/chains\";\nimport type { ProviderInfo } from \"../../types.js\";\nimport type { ResearchProvider, ResearchQuery, ResearchResult } from \"./index.js\";\nimport { getX402Fetch } from \"../../lib/x402.js\";\n\nconst BASE_URL = \"https://api.messari.io\";\n\n/** Known x402 cost per Messari query (approximate). */\nexport const MESSARI_COST_ESTIMATE: Record<string, string> = {\n token: \"~$0.10\",\n market: \"~$0.20\",\n};\n\nexport class MessariProvider implements ResearchProvider {\n info(): ProviderInfo {\n return {\n name: \"messari\",\n type: \"research\",\n capabilities: [\n \"research.token\",\n \"research.market\",\n ],\n supportedChains: [base, baseSepolia],\n };\n }\n\n async query(params: ResearchQuery): Promise<ResearchResult> {\n switch (params.type) {\n case \"token\":\n return this.tokenReport(params.target);\n case \"market\":\n return this.marketOverview(params.target);\n case \"smart-money\":\n throw new Error(\n \"Messari x402 API does not support on-chain analytics. Use --provider nansen for smart money data.\",\n );\n case \"wallet\":\n throw new Error(\n \"Messari does not support wallet analytics. Use --provider nansen for wallet profiling.\",\n );\n default:\n throw new Error(`Unsupported query type: ${params.type}`);\n }\n }\n\n /**\n * Resolve any user input (symbol, name, slug, address) to a Messari asset slug.\n * Uses the free /metrics/v2/assets endpoint ($0.00) to search.\n */\n private async resolveSlug(target: string): Promise<string> {\n const fetchWithPay = await getX402Fetch();\n const params = new URLSearchParams({\n search: target,\n limit: \"1\",\n });\n const url = `${BASE_URL}/metrics/v2/assets?${params}`;\n\n const res = await fetchWithPay(url, { method: \"GET\" });\n if (!res.ok) {\n throw new Error(\n `Messari asset lookup failed: ${res.status} ${res.statusText}`,\n );\n }\n\n const json = (await res.json()) as {\n data?: Array<{ slug?: string }>;\n };\n\n const slug = json.data?.[0]?.slug;\n if (!slug) {\n throw new Error(\n `No Messari asset found for \"${target}\". Try a different name, symbol, or slug.`,\n );\n }\n return slug;\n }\n\n /**\n * Get asset details: description, category, sector, links, market snapshot.\n * Endpoint: GET /metrics/v2/assets/details?assetIDs={slug} ($0.10)\n */\n private async tokenReport(target: string): Promise<ResearchResult> {\n const slug = await this.resolveSlug(target);\n const fetchWithPay = await getX402Fetch();\n const url = `${BASE_URL}/metrics/v2/assets/details?assetIDs=${encodeURIComponent(slug)}`;\n\n const res = await fetchWithPay(url, { method: \"GET\" });\n if (!res.ok) {\n throw new Error(\n `Messari token query failed: ${res.status} ${res.statusText}`,\n );\n }\n\n const json = (await res.json()) as {\n data?: Array<Record<string, unknown>>;\n };\n const costUsdc = this.extractCost(res, \"token\");\n const asset = json.data?.[0] ?? {};\n\n return {\n provider: \"messari\",\n queryType: \"token\",\n target,\n data: asset,\n costUsdc,\n timestamp: Math.floor(Date.now() / 1000),\n };\n }\n\n /**\n * Get market metrics + ATH: price, volume, market cap, ROI, all-time high, cycle low.\n * Makes two parallel calls:\n * GET /metrics/v2/assets/details?assetIDs={slug} ($0.10)\n * GET /metrics/v2/assets/ath?assetIDs={slug} ($0.10)\n * Total: ~$0.20\n */\n private async marketOverview(target: string): Promise<ResearchResult> {\n const slug = await this.resolveSlug(target);\n const fetchWithPay = await getX402Fetch();\n const assetParam = encodeURIComponent(slug);\n\n const [detailsRes, athRes] = await Promise.all([\n fetchWithPay(`${BASE_URL}/metrics/v2/assets/details?assetIDs=${assetParam}`, { method: \"GET\" }),\n fetchWithPay(`${BASE_URL}/metrics/v2/assets/ath?assetIDs=${assetParam}`, { method: \"GET\" }),\n ]);\n\n if (!detailsRes.ok) {\n throw new Error(\n `Messari market query failed: ${detailsRes.status} ${detailsRes.statusText}`,\n );\n }\n if (!athRes.ok) {\n throw new Error(\n `Messari ATH query failed: ${athRes.status} ${athRes.statusText}`,\n );\n }\n\n const detailsJson = (await detailsRes.json()) as {\n data?: Array<Record<string, unknown>>;\n };\n const athJson = (await athRes.json()) as {\n data?: Array<Record<string, unknown>>;\n };\n\n // Sum costs from both responses\n const cost1 = this.extractCostRaw(detailsRes);\n const cost2 = this.extractCostRaw(athRes);\n const totalCost = cost1 + cost2;\n const costUsdc = totalCost > 0\n ? totalCost.toFixed(4)\n : MESSARI_COST_ESTIMATE[\"market\"]?.replace(\"~$\", \"\") ?? \"unknown\";\n\n const details = detailsJson.data?.[0] ?? {};\n const ath = athJson.data?.[0] ?? {};\n\n return {\n provider: \"messari\",\n queryType: \"market\",\n target,\n data: {\n ...details,\n allTimeHigh: ath.allTimeHigh ?? null,\n },\n costUsdc,\n timestamp: Math.floor(Date.now() / 1000),\n };\n }\n\n /**\n * Extract cost from x402 response headers as a number (USDC).\n * Returns 0 if no payment info found.\n */\n private extractCostRaw(res: Response): number {\n const paymentResponse = res.headers.get(\"payment-response\");\n if (paymentResponse) {\n try {\n const parsed = JSON.parse(paymentResponse) as { amount?: string };\n if (parsed.amount) {\n return Number(parsed.amount) / 1e6;\n }\n } catch {\n // Fall through\n }\n }\n return 0;\n }\n\n /**\n * Extract cost from x402 response headers as a formatted string.\n * Falls back to the known estimate for the query type when headers are absent.\n */\n private extractCost(res: Response, queryType: string = \"token\"): string {\n const cost = this.extractCostRaw(res);\n if (cost > 0) return cost.toFixed(4);\n\n // Fall back to known estimate (strip \"~$\" prefix)\n const est = MESSARI_COST_ESTIMATE[queryType];\n if (est) return est.replace(\"~$\", \"\");\n\n return \"unknown\";\n }\n}\n","/**\n * x402 fetch wrapper — wraps native fetch with automatic USDC micropayments.\n *\n * Uses the Coinbase x402 protocol: when a server responds 402 Payment Required,\n * the wrapper automatically signs a USDC payment on Base and retries the request.\n * The agent pays from its own wallet — no vault interaction needed.\n *\n * Singleton pattern matching client.ts — cached after first creation.\n */\n\nimport { getAccount } from \"./client.js\";\n\nlet _x402Fetch: typeof fetch | null = null;\n\n/**\n * Returns a fetch function that automatically handles x402 (402 Payment Required)\n * responses by signing USDC micropayments on Base.\n *\n * Lazily initializes the x402 client on first call and caches it.\n * Uses dynamic imports so @x402 packages are only loaded when research commands run.\n */\nexport async function getX402Fetch(): Promise<typeof fetch> {\n if (_x402Fetch) return _x402Fetch;\n\n const { x402Client, wrapFetchWithPayment } = await import(\"@x402/fetch\");\n const { registerExactEvmScheme } = await import(\"@x402/evm/exact/client\");\n\n const signer = getAccount();\n const client = new x402Client();\n registerExactEvmScheme(client, { signer });\n\n _x402Fetch = wrapFetchWithPayment(fetch, client) as typeof fetch;\n return _x402Fetch;\n}\n\n/**\n * Reset cached x402 fetch. Required for tests that change accounts.\n */\nexport function resetX402Fetch(): void {\n _x402Fetch = null;\n}\n","/**\n * Nansen research provider — x402 micropayments for on-chain analytics.\n *\n * Docs: https://docs.nansen.ai\n * Payment: x402 (USDC on Base) — no API key required\n * Pricing: Basic $0.01/call (Token Screener, Wallet Balances, PnL, DEX Trades)\n * Premium $0.05/call (Smart Money Net Flow, Holdings, PnL Leaderboard)\n *\n * Supports all query types:\n * token → token screener (on-chain metrics, holder quality)\n * market → token screener sorted by market cap / volume\n * smart-money → smart money net flow from labeled wallets\n * wallet → wallet profiler (PnL, tx patterns, counterparties)\n */\n\nimport { base, baseSepolia } from \"viem/chains\";\nimport type { ProviderInfo } from \"../../types.js\";\nimport type { ResearchProvider, ResearchQuery, ResearchResult } from \"./index.js\";\nimport { getX402Fetch } from \"../../lib/x402.js\";\n\nconst BASE_URL = \"https://api.nansen.ai\";\n\n/** Known x402 cost per Nansen query type. */\nexport const NANSEN_COST_ESTIMATE: Record<string, string> = {\n token: \"~$0.01\",\n market: \"~$0.01\",\n \"smart-money\": \"~$0.06\",\n wallet: \"~$0.01\",\n};\n\nexport class NansenProvider implements ResearchProvider {\n info(): ProviderInfo {\n return {\n name: \"nansen\",\n type: \"research\",\n capabilities: [\n \"research.token\",\n \"research.market\",\n \"research.smart-money\",\n \"research.wallet\",\n ],\n supportedChains: [base, baseSepolia],\n };\n }\n\n async query(params: ResearchQuery): Promise<ResearchResult> {\n switch (params.type) {\n case \"token\":\n return this.tokenScreener(params.target);\n case \"market\":\n return this.marketScreener(params.target);\n case \"smart-money\":\n return this.smartMoneyNetflow(params.options?.token ?? params.target);\n case \"wallet\":\n return this.walletProfile(params.target);\n default:\n throw new Error(`Unsupported query type: ${params.type}`);\n }\n }\n\n /**\n * Token Screener — comprehensive token discovery with on-chain metrics.\n * Endpoint: POST /api/v1/token-screener\n * Cost: ~$0.01 (basic tier)\n */\n private async tokenScreener(target: string): Promise<ResearchResult> {\n const fetchWithPay = await getX402Fetch();\n\n // Determine if target is an address or symbol\n const isAddr = target.startsWith(\"0x\") && target.length === 42;\n const filters: Record<string, unknown> = isAddr\n ? { token_address: [target] }\n : { token_symbol: [target.toUpperCase()] };\n\n const body = {\n chains: [\"base\"],\n timeframe: \"24h\",\n filters,\n pagination: { page: 1, records_per_page: 10 },\n };\n\n const res = await fetchWithPay(`${BASE_URL}/api/v1/token-screener`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n\n if (!res.ok) {\n throw new Error(\n `Nansen token query failed: ${res.status} ${res.statusText}`,\n );\n }\n\n const json = (await res.json()) as { data?: unknown[] };\n const costUsdc = this.extractCost(res, \"token\");\n\n return {\n provider: \"nansen\",\n queryType: \"token\",\n target,\n data: { tokens: json.data ?? [], count: (json.data ?? []).length },\n costUsdc,\n timestamp: Math.floor(Date.now() / 1000),\n };\n }\n\n /**\n * Market Screener — token screener sorted by volume/market cap for market overview.\n * Endpoint: POST /api/v1/token-screener\n * Cost: ~$0.01 (basic tier)\n */\n private async marketScreener(asset: string): Promise<ResearchResult> {\n const fetchWithPay = await getX402Fetch();\n\n const isAddr = asset.startsWith(\"0x\") && asset.length === 42;\n const filters: Record<string, unknown> = isAddr\n ? { token_address: [asset] }\n : { token_symbol: [asset.toUpperCase()] };\n\n const body = {\n chains: [\"base\"],\n timeframe: \"24h\",\n filters,\n order_by: [{ field: \"buy_volume\", direction: \"desc\" }],\n pagination: { page: 1, records_per_page: 10 },\n };\n\n const res = await fetchWithPay(`${BASE_URL}/api/v1/token-screener`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n\n if (!res.ok) {\n throw new Error(\n `Nansen market query failed: ${res.status} ${res.statusText}`,\n );\n }\n\n const json = (await res.json()) as { data?: unknown[] };\n const costUsdc = this.extractCost(res, \"market\");\n\n return {\n provider: \"nansen\",\n queryType: \"market\",\n target: asset,\n data: { tokens: json.data ?? [], count: (json.data ?? []).length },\n costUsdc,\n timestamp: Math.floor(Date.now() / 1000),\n };\n }\n\n /**\n * Smart Money Net Flow — capital flow analysis from labeled wallets.\n * Endpoint: POST /api/v1/smart-money/netflow\n * Cost: ~$0.05 (premium tier)\n *\n * The netflow endpoint only accepts `token_address` filters (not `token_symbol`).\n * If the target is a symbol, we resolve it to an address via the token screener first.\n */\n private async smartMoneyNetflow(\n target: string,\n ): Promise<ResearchResult> {\n const fetchWithPay = await getX402Fetch();\n\n // Resolve symbol → address if needed (token screener is $0.01)\n const tokenAddress = await this.resolveTokenAddress(target);\n\n const body: Record<string, unknown> = {\n chains: [\"base\"],\n pagination: { page: 1, records_per_page: 10 },\n };\n\n if (tokenAddress) {\n body.filters = { token_address: [tokenAddress] };\n }\n\n const res = await fetchWithPay(`${BASE_URL}/api/v1/smart-money/netflow`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n\n if (!res.ok) {\n throw new Error(\n `Nansen smart-money query failed: ${res.status} ${res.statusText}`,\n );\n }\n\n const json = (await res.json()) as { data?: unknown[] };\n const costUsdc = this.extractCost(res, \"smart-money\");\n\n return {\n provider: \"nansen\",\n queryType: \"smart-money\",\n target,\n data: { flows: json.data ?? [], count: (json.data ?? []).length },\n costUsdc,\n timestamp: Math.floor(Date.now() / 1000),\n };\n }\n\n /**\n * Wallet Profile — PnL history, transaction patterns, counterparties.\n * Endpoint: POST /api/v1/profiler/wallet-pnl\n * Cost: ~$0.01 (basic tier)\n */\n private async walletProfile(address: string): Promise<ResearchResult> {\n const fetchWithPay = await getX402Fetch();\n\n const body = {\n chains: [\"base\"],\n address,\n };\n\n const res = await fetchWithPay(`${BASE_URL}/api/v1/profiler/wallet-pnl`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n\n if (!res.ok) {\n throw new Error(\n `Nansen wallet query failed: ${res.status} ${res.statusText}`,\n );\n }\n\n const json = (await res.json()) as { data?: Record<string, unknown> };\n const costUsdc = this.extractCost(res, \"wallet\");\n\n return {\n provider: \"nansen\",\n queryType: \"wallet\",\n target: address,\n data: json.data ?? (json as Record<string, unknown>),\n costUsdc,\n timestamp: Math.floor(Date.now() / 1000),\n };\n }\n\n /**\n * Resolve a token symbol or name to its contract address on Base.\n * Uses the token screener endpoint ($0.01) to look up the address.\n * If the target is already an address (0x...), returns it as-is.\n */\n private async resolveTokenAddress(target: string): Promise<string | null> {\n if (target.startsWith(\"0x\") && target.length === 42) {\n return target;\n }\n\n const fetchWithPay = await getX402Fetch();\n const body = {\n chains: [\"base\"],\n timeframe: \"24h\",\n filters: { token_symbol: [target.toUpperCase()] },\n pagination: { page: 1, records_per_page: 1 },\n };\n\n const res = await fetchWithPay(`${BASE_URL}/api/v1/token-screener`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n\n if (!res.ok) return null;\n\n const json = (await res.json()) as {\n data?: Array<{ token_address?: string }>;\n };\n return json.data?.[0]?.token_address ?? null;\n }\n\n /**\n * Extract cost from x402 response headers.\n * Falls back to the known estimate for the query type when headers are absent.\n */\n private extractCost(res: Response, queryType: string): string {\n // Check Nansen-specific credit header\n const creditsUsed = res.headers.get(\"x-nansen-credits-used\");\n if (creditsUsed) {\n return creditsUsed;\n }\n\n // Fall back to x402 payment-response header\n const paymentResponse = res.headers.get(\"payment-response\");\n if (paymentResponse) {\n try {\n const parsed = JSON.parse(paymentResponse) as { amount?: string };\n if (parsed.amount) {\n const cents = Number(parsed.amount) / 1e6;\n return cents.toFixed(4);\n }\n } catch {\n // Fall through\n }\n }\n\n // Fall back to known estimate (strip \"~$\" prefix)\n const est = NANSEN_COST_ESTIMATE[queryType];\n if (est) {\n return est.replace(\"~$\", \"\");\n }\n\n return \"unknown\";\n }\n}\n","/**\n * Research providers — pluggable interface for DeFi research data via x402 micropayments.\n *\n * Same pattern as DeFi providers (Moonwell, Uniswap). Each research provider\n * implements ResearchProvider and uses x402-wrapped fetch for automatic USDC payments.\n */\n\nimport type { Provider } from \"../../types.js\";\nimport { MessariProvider } from \"./messari.js\";\nimport { NansenProvider } from \"./nansen.js\";\n\n// ── Types ──\n\nexport interface ResearchQuery {\n /** Query type determines which API endpoint is called */\n type: \"token\" | \"smart-money\" | \"market\" | \"wallet\";\n /** Token address, asset symbol, or wallet address depending on type */\n target: string;\n /** Additional query params (e.g. token symbol for smart-money queries) */\n options?: Record<string, string>;\n}\n\nexport interface ResearchResult {\n provider: string;\n queryType: string;\n target: string;\n /** Structured response data from the provider */\n data: Record<string, unknown>;\n /** Cost paid in USDC (human-readable, e.g. \"0.05\") */\n costUsdc: string;\n timestamp: number;\n}\n\nexport interface ResearchProvider extends Provider {\n /** Query the research provider. Payment is handled automatically via x402. */\n query(params: ResearchQuery): Promise<ResearchResult>;\n}\n\n// ── Factory ──\n\nexport function getResearchProvider(name: string): ResearchProvider {\n switch (name) {\n case \"messari\":\n return new MessariProvider();\n case \"nansen\":\n return new NansenProvider();\n default:\n throw new Error(\n `Unknown research provider: ${name}. Valid providers: messari, nansen`,\n );\n }\n}\n\n// ── Re-exports ──\n\nexport { MessariProvider, NansenProvider };\n"],"mappings":"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","names":["base","baseSepolia","BASE_URL","base","baseSepolia"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/providers/uniswap.ts","../src/lib/venice.ts","../src/lib/quote.ts"],"sourcesContent":["/**\n * Uniswap Trading API provider — swaps on Base via the hosted API.\n *\n * Uses the 3-step flow:\n * 1. POST /check_approval → check/submit token approval\n * 2. POST /quote → get optimal route + executable quote\n * 3. POST /swap → get transaction calldata to sign\n *\n * API key required — set via `sherwood config set --uniswap-api-key <key>`\n * or UNISWAP_API_KEY env var.\n *\n * Docs: https://docs.uniswap.org/api/trading-api\n * Key: https://developers.uniswap.org/\n */\n\nimport type { Address, Hex } from \"viem\";\nimport { isAddress, isHex, formatUnits } from \"viem\";\nimport { base, baseSepolia } from \"viem/chains\";\nimport type { TradingProvider, ProviderInfo, SwapParams, SwapQuoteParams, TxResult, SwapQuote } from \"../types.js\";\nimport { getPublicClient, getAccount, writeContractWithRetry } from \"../lib/client.js\";\nimport { getChain } from \"../lib/network.js\";\nimport { getUniswapApiKey } from \"../lib/config.js\";\nimport { ERC20_ABI } from \"../lib/abis.js\";\n\nconst API_BASE = \"https://trade-api.gateway.uniswap.org/v1\";\n\n// ── API Types ──\n\ninterface ApprovalResponse {\n approval: {\n to: Address;\n from: Address;\n data: Hex;\n value: string;\n chainId: number;\n } | null;\n}\n\n// CLASSIC route quote\ninterface ClassicQuote {\n routing: \"CLASSIC\" | \"WRAP\" | \"UNWRAP\";\n quote: {\n input: { token: string; amount: string };\n output: { token: string; amount: string };\n slippage: number;\n route: unknown[];\n gasFee: string;\n gasFeeUSD: string;\n gasUseEstimate: string;\n };\n permitData: Record<string, unknown> | null;\n}\n\n// UniswapX route quote (PRIORITY on Base)\ninterface UniswapXQuote {\n routing: \"DUTCH_V2\" | \"DUTCH_V3\" | \"PRIORITY\";\n quote: {\n orderInfo: {\n outputs: Array<{\n token: string;\n startAmount: string;\n endAmount: string;\n recipient: string;\n }>;\n input: { token: string; startAmount: string; endAmount: string };\n deadline: number;\n nonce: string;\n };\n encodedOrder: string;\n orderHash: string;\n };\n permitData: Record<string, unknown> | null;\n}\n\ntype QuoteResponse = ClassicQuote | UniswapXQuote;\n\ninterface SwapResponse {\n swap: {\n to: Address;\n from: Address;\n data: Hex;\n value: string;\n chainId: number;\n gasLimit?: string;\n };\n}\n\n// ── Helpers ──\n\nfunction getApiKey(): string {\n const key = getUniswapApiKey();\n if (!key) {\n throw new Error(\n \"Uniswap API key not configured. Run 'sherwood config set --uniswap-api-key <key>' \" +\n \"or set UNISWAP_API_KEY env var.\\n\" +\n \"Get your key at https://developers.uniswap.org/\",\n );\n }\n return key;\n}\n\nfunction apiHeaders(): Record<string, string> {\n return {\n \"Content-Type\": \"application/json\",\n \"x-api-key\": getApiKey(),\n \"x-universal-router-version\": \"2.0\",\n };\n}\n\nfunction isUniswapXRouting(routing: string): boolean {\n return routing === \"DUTCH_V2\" || routing === \"DUTCH_V3\" || routing === \"PRIORITY\";\n}\n\nfunction getOutputAmount(q: QuoteResponse): string {\n if (isUniswapXRouting(q.routing)) {\n const ux = q as UniswapXQuote;\n const firstOutput = ux.quote.orderInfo.outputs[0];\n if (!firstOutput) throw new Error(\"UniswapX quote has no outputs\");\n return firstOutput.startAmount; // best-case fill\n }\n return (q as ClassicQuote).quote.output.amount;\n}\n\nasync function fetchWithRetry(\n url: string,\n init: RequestInit,\n maxRetries = 3,\n): Promise<Response> {\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n const response = await fetch(url, {\n ...init,\n signal: AbortSignal.timeout(30_000),\n });\n if (response.status !== 429 && response.status < 500) return response;\n if (attempt === maxRetries) return response;\n\n const delay = Math.min(200 * Math.pow(2, attempt) + Math.random() * 100, 10000);\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n throw new Error(\"Unreachable\");\n}\n\n// ── Provider ──\n\nexport class UniswapProvider implements TradingProvider {\n info(): ProviderInfo {\n return {\n name: \"uniswap\",\n type: \"trading\",\n capabilities: [\n \"swap.exact-input\",\n \"swap.quote\",\n \"swap.check-approval\",\n ],\n supportedChains: [base, baseSepolia],\n };\n }\n\n /**\n * Get a quote from the Uniswap Trading API.\n * Returns the optimal route (CLASSIC, PRIORITY, or UniswapX).\n */\n async quote(params: SwapQuoteParams): Promise<SwapQuote> {\n const account = getAccount();\n const chainId = getChain().id;\n\n const body = {\n swapper: account.address,\n tokenIn: params.tokenIn,\n tokenOut: params.tokenOut,\n tokenInChainId: String(chainId),\n tokenOutChainId: String(chainId),\n amount: params.amountIn.toString(),\n type: \"EXACT_INPUT\",\n slippageTolerance: 0.5,\n routingPreference: \"BEST_PRICE\",\n };\n\n const res = await fetchWithRetry(`${API_BASE}/quote`, {\n method: \"POST\",\n headers: apiHeaders(),\n body: JSON.stringify(body),\n });\n\n if (!res.ok) {\n const err = await res.text();\n throw new Error(`Uniswap quote failed (${res.status}): ${err}`);\n }\n\n const data = (await res.json()) as QuoteResponse;\n const amountOut = BigInt(getOutputAmount(data));\n\n return {\n amountOut,\n priceImpact: 0,\n route: `${data.routing}: ${params.tokenIn.slice(0, 8)}→${params.tokenOut.slice(0, 8)}`,\n };\n }\n\n /**\n * Get a full quote response (preserving the raw API response for swap execution).\n */\n async fullQuote(params: {\n tokenIn: Address;\n tokenOut: Address;\n amountIn: bigint;\n slippageTolerance?: number;\n }): Promise<{ quoteResponse: QuoteResponse; amountOut: bigint; routing: string }> {\n const account = getAccount();\n const chainId = getChain().id;\n\n const body = {\n swapper: account.address,\n tokenIn: params.tokenIn,\n tokenOut: params.tokenOut,\n tokenInChainId: String(chainId),\n tokenOutChainId: String(chainId),\n amount: params.amountIn.toString(),\n type: \"EXACT_INPUT\",\n slippageTolerance: params.slippageTolerance ?? 0.5,\n routingPreference: \"BEST_PRICE\",\n };\n\n const res = await fetchWithRetry(`${API_BASE}/quote`, {\n method: \"POST\",\n headers: apiHeaders(),\n body: JSON.stringify(body),\n });\n\n if (!res.ok) {\n const err = await res.text();\n throw new Error(`Uniswap quote failed (${res.status}): ${err}`);\n }\n\n const quoteResponse = (await res.json()) as QuoteResponse;\n const amountOut = BigInt(getOutputAmount(quoteResponse));\n return { quoteResponse, amountOut, routing: quoteResponse.routing };\n }\n\n /**\n * Check and handle token approval for Uniswap.\n * Uses the Trading API's /check_approval endpoint.\n */\n async checkApproval(params: {\n token: Address;\n amount: bigint;\n }): Promise<void> {\n const account = getAccount();\n const chainId = getChain().id;\n const client = getPublicClient();\n\n const res = await fetchWithRetry(`${API_BASE}/check_approval`, {\n method: \"POST\",\n headers: apiHeaders(),\n body: JSON.stringify({\n walletAddress: account.address,\n token: params.token,\n amount: params.amount.toString(),\n chainId,\n }),\n });\n\n if (!res.ok) {\n const err = await res.text();\n throw new Error(`Approval check failed (${res.status}): ${err}`);\n }\n\n const data = (await res.json()) as ApprovalResponse;\n\n if (data.approval) {\n // Submit the approval transaction\n const hash = await writeContractWithRetry({\n address: data.approval.to,\n abi: ERC20_ABI,\n functionName: \"approve\",\n // Decode the approval data — the API returns the full calldata\n // but we need to send the raw transaction\n args: [], // unused — we send raw data\n account,\n chain: getChain(),\n });\n\n // Actually, the API returns a ready-to-send transaction, so use sendTransaction\n // Let's use the wallet client directly\n const { getWalletClient } = await import(\"../lib/client.js\");\n const wallet = getWalletClient();\n const approvalHash = await wallet.sendTransaction({\n to: data.approval.to,\n data: data.approval.data,\n value: BigInt(data.approval.value || \"0\"),\n account,\n chain: getChain(),\n });\n await client.waitForTransactionReceipt({ hash: approvalHash });\n }\n }\n\n /**\n * Execute a swap via the Uniswap Trading API.\n *\n * Full flow: check_approval → quote → swap → sign & broadcast.\n */\n async swap(params: SwapParams): Promise<TxResult> {\n const account = getAccount();\n const client = getPublicClient();\n\n // 1. Check approval (skip for native ETH)\n const ETH_ADDRESS = \"0x0000000000000000000000000000000000000000\" as Address;\n if (params.tokenIn !== ETH_ADDRESS) {\n await this.checkApproval({\n token: params.tokenIn,\n amount: params.amountIn,\n });\n }\n\n // 2. Get quote\n const slippageBps = params.fee; // repurpose fee field for slippage in API mode\n const { quoteResponse } = await this.fullQuote({\n tokenIn: params.tokenIn,\n tokenOut: params.tokenOut,\n amountIn: params.amountIn,\n slippageTolerance: 0.5, // 0.5%\n });\n\n // 3. Prepare swap request — routing-aware permitData handling\n const quoteRaw = quoteResponse as unknown as Record<string, unknown>;\n const { permitData, ...cleanQuote } = quoteRaw;\n const swapRequest: Record<string, unknown> = { ...cleanQuote };\n\n // UniswapX routes: permitData is for local signing only, must NOT be sent to /swap\n // For CLASSIC routes without Permit2: omit both signature and permitData\n // (We use direct approval via /check_approval, not Permit2)\n if (isUniswapXRouting(quoteResponse.routing)) {\n // UniswapX: sign the order with permitData locally\n if (permitData && typeof permitData === \"object\") {\n const typedData = permitData as {\n domain: Record<string, unknown>;\n types: Record<string, unknown>;\n values: Record<string, unknown>;\n };\n const signature = await account.signTypedData({\n domain: typedData.domain as Record<string, unknown>,\n types: typedData.types as Record<string, Array<{ name: string; type: string }>>,\n primaryType: Object.keys(typedData.types).find((k) => k !== \"EIP712Domain\") ?? \"PermitWitnessTransferFrom\",\n message: typedData.values,\n });\n swapRequest.signature = signature;\n }\n }\n // For CLASSIC: no signature/permitData needed (we use /check_approval)\n\n // 4. Get swap transaction\n const swapRes = await fetchWithRetry(`${API_BASE}/swap`, {\n method: \"POST\",\n headers: apiHeaders(),\n body: JSON.stringify(swapRequest),\n });\n\n if (!swapRes.ok) {\n const err = await swapRes.text();\n throw new Error(`Uniswap swap failed (${swapRes.status}): ${err}`);\n }\n\n const swapData = (await swapRes.json()) as SwapResponse;\n\n // 5. Validate before broadcasting\n if (!swapData.swap?.data || swapData.swap.data === (\"\" as Hex) || swapData.swap.data === \"0x\") {\n throw new Error(\"Empty swap data — quote may have expired. Try again.\");\n }\n if (!isAddress(swapData.swap.to) || !isAddress(swapData.swap.from)) {\n throw new Error(\"Invalid address in swap response\");\n }\n\n // 6. Sign and broadcast\n const { getWalletClient } = await import(\"../lib/client.js\");\n const wallet = getWalletClient();\n const hash = await wallet.sendTransaction({\n to: swapData.swap.to,\n data: swapData.swap.data,\n value: BigInt(swapData.swap.value || \"0\"),\n account,\n chain: getChain(),\n });\n\n const receipt = await client.waitForTransactionReceipt({ hash });\n return {\n hash,\n success: receipt.status === \"success\",\n gasUsed: receipt.gasUsed,\n };\n }\n}\n","/**\n * Venice AI API integration — web3 key generation, validation, and inference.\n *\n * Key provisioning flow:\n * 1. GET /api_keys/generate_web3_key → validation token\n * 2. Sign token with agent wallet (EIP-191)\n * 3. POST /api_keys/generate_web3_key → API key\n *\n * Inference:\n * POST /chat/completions with Bearer auth → chat completion response\n *\n * The API key is stored in ~/.sherwood/config.json.\n * Venice requires the signing wallet to hold staked VVV (sVVV).\n */\n\nimport { getAccount } from \"./client.js\";\nimport { setVeniceApiKey, getVeniceApiKey } from \"./config.js\";\n\nconst VENICE_API_BASE = \"https://api.venice.ai/api/v1\";\n\n/**\n * Provision a Venice API key via web3 wallet signature.\n * The wallet must hold sVVV for this to succeed.\n */\nexport async function provisionApiKey(): Promise<string> {\n const account = getAccount();\n\n // 1. Get validation token (requires admin API key)\n const adminKey = process.env.VENICE_ADMIN_KEY;\n if (!adminKey) {\n throw new Error(\n \"VENICE_ADMIN_KEY env var required for autonomous provisioning.\\n\" +\n \" Get an admin key from https://venice.ai/settings/api-keys\\n\" +\n \" Or set a key manually: sherwood config set --venice-api-key <key>\",\n );\n }\n const tokenRes = await fetch(`${VENICE_API_BASE}/api_keys/generate_web3_key`, {\n headers: { Authorization: `Bearer ${adminKey}` },\n signal: AbortSignal.timeout(15_000),\n });\n if (!tokenRes.ok) {\n throw new Error(`Failed to get validation token: ${tokenRes.status} ${tokenRes.statusText}`);\n }\n const tokenData = await tokenRes.json();\n const token = tokenData?.data?.token;\n if (!token) {\n throw new Error(\"Venice API returned no validation token\");\n }\n\n // 2. Sign token with wallet (EIP-191)\n const signature = await account.signMessage({ message: token });\n\n // 3. Generate API key\n const keyRes = await fetch(`${VENICE_API_BASE}/api_keys/generate_web3_key`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${token}`,\n },\n signal: AbortSignal.timeout(15_000),\n body: JSON.stringify({\n address: account.address,\n signature,\n token,\n apiKeyType: \"INFERENCE\",\n description: \"Sherwood syndicate agent\",\n }),\n });\n\n if (!keyRes.ok) {\n const body = await keyRes.text();\n throw new Error(`Failed to generate API key: ${keyRes.status} ${body}`);\n }\n\n const keyData = await keyRes.json();\n const apiKey = keyData?.data?.apiKey;\n if (!apiKey) {\n throw new Error(\"Venice API returned no API key\");\n }\n\n // Store in config\n setVeniceApiKey(apiKey);\n\n return apiKey;\n}\n\n/**\n * Check if the stored Venice API key is still valid.\n */\nexport async function checkApiKeyValid(): Promise<boolean> {\n const apiKey = getVeniceApiKey();\n if (!apiKey) return false;\n\n try {\n const res = await fetch(`${VENICE_API_BASE}/models`, {\n headers: { Authorization: `Bearer ${apiKey}` },\n signal: AbortSignal.timeout(15_000),\n });\n return res.ok;\n } catch {\n return false;\n }\n}\n\n// ── Inference ──\n\nexport interface ChatCompletionMessage {\n role: \"system\" | \"user\" | \"assistant\";\n content: string;\n}\n\nexport interface ChatCompletionOptions {\n model: string;\n messages: ChatCompletionMessage[];\n temperature?: number;\n maxTokens?: number;\n enableWebSearch?: boolean;\n disableThinking?: boolean;\n}\n\nexport interface ChatCompletionResult {\n content: string;\n model: string;\n usage: {\n promptTokens: number;\n completionTokens: number;\n totalTokens: number;\n };\n}\n\n/**\n * Call Venice chat completions API for private inference.\n * Requires a provisioned API key (run `sherwood venice provision` first).\n */\nexport async function chatCompletion(opts: ChatCompletionOptions): Promise<ChatCompletionResult> {\n const apiKey = getVeniceApiKey();\n if (!apiKey) {\n throw new Error(\"No Venice API key configured. Run 'sherwood venice provision' first.\");\n }\n\n const body: Record<string, unknown> = {\n model: opts.model,\n messages: opts.messages,\n };\n if (opts.temperature !== undefined) body.temperature = opts.temperature;\n if (opts.maxTokens !== undefined) body.max_tokens = opts.maxTokens;\n\n const veniceParams: Record<string, unknown> = {};\n if (opts.enableWebSearch) veniceParams.enable_web_search = \"on\";\n if (opts.disableThinking) veniceParams.disable_thinking = true;\n if (Object.keys(veniceParams).length > 0) body.venice_parameters = veniceParams;\n\n const res = await fetch(`${VENICE_API_BASE}/chat/completions`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n signal: AbortSignal.timeout(120_000), // inference can be slow\n body: JSON.stringify(body),\n });\n\n if (!res.ok) {\n const errBody = await res.text();\n throw new Error(`Venice inference failed: ${res.status} ${errBody}`);\n }\n\n const data = await res.json();\n const choice = data.choices?.[0];\n if (!choice) {\n throw new Error(\"Venice returned no choices\");\n }\n\n return {\n content: choice.message?.content ?? \"\",\n model: data.model ?? opts.model,\n usage: {\n promptTokens: data.usage?.prompt_tokens ?? 0,\n completionTokens: data.usage?.completion_tokens ?? 0,\n totalTokens: data.usage?.total_tokens ?? 0,\n },\n };\n}\n\n/**\n * List available Venice models.\n * Requires a provisioned API key.\n */\nexport async function listModels(): Promise<string[]> {\n const apiKey = getVeniceApiKey();\n if (!apiKey) {\n throw new Error(\"No Venice API key configured. Run 'sherwood venice provision' first.\");\n }\n\n const res = await fetch(`${VENICE_API_BASE}/models`, {\n headers: { Authorization: `Bearer ${apiKey}` },\n signal: AbortSignal.timeout(15_000),\n });\n\n if (!res.ok) {\n throw new Error(`Failed to list Venice models: ${res.status} ${res.statusText}`);\n }\n\n const data = await res.json();\n return (data.data ?? []).map((m: { id: string }) => m.id);\n}\n","/**\n * Uniswap V3 Quoter V2 integration for swap quotes.\n *\n * quoteExactInputSingle is NOT a view function — it reverts internally\n * after computing the quote. Must use eth_call to get the return data.\n */\n\nimport type { Address, Hex } from \"viem\";\nimport { encodeFunctionData, decodeFunctionResult, concat, pad, numberToHex } from \"viem\";\nimport { getPublicClient } from \"./client.js\";\nimport { UNISWAP_QUOTER_V2_ABI } from \"./abis.js\";\nimport { UNISWAP } from \"./addresses.js\";\n\nexport interface QuoteResult {\n amountOut: bigint;\n sqrtPriceX96After: bigint;\n gasEstimate: bigint;\n}\n\n/**\n * Get a swap quote from Uniswap Quoter V2.\n */\nexport async function getQuote(params: {\n tokenIn: Address;\n tokenOut: Address;\n amountIn: bigint;\n fee: number;\n}): Promise<QuoteResult> {\n const client = getPublicClient();\n\n const calldata = encodeFunctionData({\n abi: UNISWAP_QUOTER_V2_ABI,\n functionName: \"quoteExactInputSingle\",\n args: [\n {\n tokenIn: params.tokenIn,\n tokenOut: params.tokenOut,\n amountIn: params.amountIn,\n fee: params.fee,\n sqrtPriceLimitX96: 0n,\n },\n ],\n });\n\n const { data } = await client.call({\n to: UNISWAP().QUOTER_V2,\n data: calldata,\n });\n\n if (!data) {\n throw new Error(\"Quoter returned no data — pool may not exist for this pair/fee\");\n }\n\n const [amountOut, sqrtPriceX96After, , gasEstimate] = decodeFunctionResult({\n abi: UNISWAP_QUOTER_V2_ABI,\n functionName: \"quoteExactInputSingle\",\n data,\n }) as [bigint, bigint, number, bigint];\n\n return { amountOut, sqrtPriceX96After, gasEstimate };\n}\n\n/**\n * Apply slippage tolerance to a quote amount.\n * Returns the minimum acceptable output amount.\n */\nexport function applySlippage(amountOut: bigint, slippageBps: number): bigint {\n return (amountOut * BigInt(10000 - slippageBps)) / 10000n;\n}\n\n/**\n * Encode a Uniswap V3 multi-hop swap path.\n * Format: abi.encodePacked(address, uint24, address, uint24, address, ...)\n */\nexport function encodeSwapPath(tokens: Address[], fees: number[]): Hex {\n if (tokens.length < 2 || fees.length !== tokens.length - 1) {\n throw new Error(\"Invalid path: need at least 2 tokens and (tokens-1) fees\");\n }\n\n const parts: Hex[] = [];\n for (let i = 0; i < tokens.length; i++) {\n // Address: 20 bytes (no padding)\n parts.push(tokens[i].toLowerCase() as Hex);\n if (i < fees.length) {\n // Fee: 3 bytes (uint24), left-padded to 3 bytes\n parts.push(pad(numberToHex(fees[i]), { size: 3 }) as Hex);\n }\n }\n return concat(parts);\n}\n\n/**\n * Get a multi-hop swap quote from Uniswap Quoter V2.\n */\nexport async function getMultiHopQuote(params: {\n path: Hex;\n amountIn: bigint;\n}): Promise<QuoteResult> {\n const client = getPublicClient();\n\n const calldata = encodeFunctionData({\n abi: UNISWAP_QUOTER_V2_ABI,\n functionName: \"quoteExactInput\",\n args: [params.path, params.amountIn],\n });\n\n const { data } = await client.call({\n to: UNISWAP().QUOTER_V2,\n data: calldata,\n });\n\n if (!data) {\n throw new Error(\"Quoter returned no data — pool may not exist for this path\");\n }\n\n const [amountOut, , , gasEstimate] = decodeFunctionResult({\n abi: UNISWAP_QUOTER_V2_ABI,\n functionName: \"quoteExactInput\",\n data,\n }) as [bigint, bigint[], number[], bigint];\n\n return { amountOut, sqrtPriceX96After: 0n, gasEstimate };\n}\n\n/** Token decimals for display purposes. */\nexport const TOKEN_DECIMALS: Record<string, number> = {\n USDC: 6,\n WETH: 18,\n cbETH: 18,\n wstETH: 18,\n cbBTC: 8,\n DAI: 18,\n AERO: 18,\n};\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/cron.ts"],"sourcesContent":["/**\n * OpenClaw cron integration — auto-register participation crons for syndicate agents.\n *\n * When an agent creates or joins a syndicate, the CLI registers two cron jobs:\n * 1. Silent check (every 15m) — processes messages/events, responds autonomously\n * 2. Human summary (every 1h) — brief activity report delivered to the human's channel\n *\n * Non-OpenClaw agents skip silently — the caller prints guidance instead.\n */\n\nimport { execFileSync } from \"node:child_process\";\n\n// ── OpenClaw detection (cached per process) ──\n\nlet _isOpenClaw: boolean | null = null;\n\nexport function isOpenClaw(): boolean {\n if (_isOpenClaw !== null) return _isOpenClaw;\n try {\n execFileSync(\"openclaw\", [\"cron\", \"list\"], {\n encoding: \"utf8\",\n timeout: 10_000,\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n _isOpenClaw = true;\n } catch {\n _isOpenClaw = false;\n }\n return _isOpenClaw;\n}\n\n// ── Types ──\n\nexport interface CronResult {\n registered: boolean;\n isOpenClaw: boolean;\n cronNames: string[];\n}\n\nexport interface CronStatus {\n isOpenClaw: boolean;\n crons: { name: string; every: string; lastRun?: string }[];\n}\n\n// ── Cron naming ──\n\nfunction cronName(subdomain: string, testnet: boolean): string {\n return `sherwood-${subdomain}${testnet ? \"-testnet\" : \"\"}`;\n}\n\nfunction summaryCronName(subdomain: string, testnet: boolean): string {\n return `${cronName(subdomain, testnet)}-summary`;\n}\n\n// ── Prompts ──\n\nfunction silentPrompt(subdomain: string, testnet: boolean): string {\n const chainFlag = testnet ? \" --chain base-sepolia\" : \"\";\n const envPrefix = testnet ? \"ENABLE_TESTNET=true \" : \"\";\n return [\n `You are a sherwood syndicate member. Your syndicate: ${subdomain}.sherwoodagent.eth`,\n \"\",\n `Step 1: Run \\`${envPrefix}sherwood session check ${subdomain}${chainFlag}\\``,\n \"Step 2: Parse the JSON output.\",\n \" - If the output shows 0 messages and 0 events, you may still be pending approval.\",\n \" Check: `\" + envPrefix + \"sherwood vault info\" + chainFlag + \"`\",\n \" If your wallet is not listed as a registered agent, you are still pending. Reply HEARTBEAT_OK.\",\n \" If you ARE registered but this is your first time seeing it, alert your human that you've been approved and are now active.\",\n \" - If there are new messages from OTHER agents, respond thoughtfully via:\",\n ` \\`${envPrefix}sherwood chat ${subdomain} send \"<response>\"${chainFlag}\\``,\n \"Step 3: If you responded to anything, summarize what you did (for your own session log).\",\n \" If nothing happened, reply HEARTBEAT_OK\",\n \"\",\n \"Rules:\",\n \"- Be a real syndicate member — discuss strategies, share opinions, ask questions\",\n \"- Keep responses concise and on-topic\",\n \"- Do NOT alert your human unless something requires their approval (or you were just approved)\",\n `- You can use \\`sherwood research\\` commands if you need data to back up your response`,\n ].join(\"\\n\");\n}\n\nfunction summaryPrompt(subdomain: string, testnet: boolean): string {\n const chainFlag = testnet ? \" --chain base-sepolia\" : \"\";\n const envPrefix = testnet ? \"ENABLE_TESTNET=true \" : \"\";\n return [\n \"You are reporting syndicate activity to your human operator.\",\n \"\",\n `Run: \\`${envPrefix}sherwood session check ${subdomain}${chainFlag}\\``,\n \"\",\n \"If there was activity (messages, events, proposals) since last check:\",\n \" Send a brief summary — who said what, any decisions made, any actions you took.\",\n \" Keep it to 3-5 lines max.\",\n \"\",\n \"If there was no activity:\",\n \" Reply HEARTBEAT_OK\",\n \"\",\n \"Only escalate (flag as urgent) if:\",\n \"- A proposal needs human sign-off\",\n \"- An agent left the syndicate\",\n \"- Risk alert or health factor warning\",\n \"- Human was directly asked for input\",\n ].join(\"\\n\");\n}\n\n// ── Helpers ──\n\n/** Parse `openclaw cron list --json` and return job names. */\nfunction listCronNames(): string[] {\n try {\n const raw = execFileSync(\"openclaw\", [\"cron\", \"list\", \"--json\"], {\n encoding: \"utf8\",\n timeout: 10_000,\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n const parsed = JSON.parse(raw);\n const jobs: { name: string }[] = parsed.jobs || parsed || [];\n return jobs.map((j) => j.name);\n } catch {\n return [];\n }\n}\n\n/** Parse `openclaw cron list --json` with full details for status display. */\nfunction listCronDetails(): { name: string; every: string; lastRun?: string }[] {\n try {\n const raw = execFileSync(\"openclaw\", [\"cron\", \"list\", \"--json\"], {\n encoding: \"utf8\",\n timeout: 10_000,\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n const parsed = JSON.parse(raw);\n const jobs: { name: string; every?: string; interval?: string; lastRun?: string }[] =\n parsed.jobs || parsed || [];\n return jobs.map((j) => ({\n name: j.name,\n every: j.every || j.interval || \"unknown\",\n lastRun: j.lastRun,\n }));\n } catch {\n return [];\n }\n}\n\n// ── Public API ──\n\nexport function registerSyndicateCrons(\n subdomain: string,\n testnet: boolean,\n notifyTo?: string,\n): CronResult {\n if (!isOpenClaw()) {\n return { registered: false, isOpenClaw: false, cronNames: [] };\n }\n\n const checkName = cronName(subdomain, testnet);\n const summaryName = summaryCronName(subdomain, testnet);\n const existing = listCronNames();\n const created: string[] = [];\n\n // Cron 1: Silent participation check (every 15m)\n if (!existing.includes(checkName)) {\n try {\n execFileSync(\"openclaw\", [\n \"cron\", \"create\",\n \"--name\", checkName,\n \"--every\", \"15m\",\n \"--session\", \"isolated\",\n \"--timeout-seconds\", \"120\",\n \"--no-deliver\",\n \"--message\", silentPrompt(subdomain, testnet),\n ], {\n encoding: \"utf8\",\n timeout: 30_000,\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n created.push(checkName);\n } catch (err) {\n console.warn(`Could not create silent cron: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n\n // Cron 2: Human summary (every 1h)\n if (!existing.includes(summaryName)) {\n try {\n const args = [\n \"cron\", \"create\",\n \"--name\", summaryName,\n \"--every\", \"1h\",\n \"--session\", \"isolated\",\n \"--timeout-seconds\", \"90\",\n \"--announce\",\n ];\n\n // Use explicit destination if configured, otherwise auto-route via --channel last\n if (notifyTo) {\n args.push(\"--to\", notifyTo);\n } else {\n args.push(\"--channel\", \"last\");\n }\n\n args.push(\"--message\", summaryPrompt(subdomain, testnet));\n\n execFileSync(\"openclaw\", args, {\n encoding: \"utf8\",\n timeout: 30_000,\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n created.push(summaryName);\n } catch (err) {\n console.warn(`Could not create summary cron: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n\n return {\n registered: created.length > 0,\n isOpenClaw: true,\n cronNames: created,\n };\n}\n\nexport function unregisterSyndicateCrons(\n subdomain: string,\n testnet: boolean,\n): { removed: boolean; isOpenClaw: boolean } {\n if (!isOpenClaw()) {\n return { removed: false, isOpenClaw: false };\n }\n\n const names = [cronName(subdomain, testnet), summaryCronName(subdomain, testnet)];\n let removed = false;\n\n for (const name of names) {\n try {\n execFileSync(\"openclaw\", [\"cron\", \"remove\", \"--name\", name], {\n encoding: \"utf8\",\n timeout: 10_000,\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n removed = true;\n } catch {\n // Cron may not exist — that's fine\n }\n }\n\n return { removed, isOpenClaw: true };\n}\n\nexport function getSyndicateCronStatus(\n subdomain: string,\n testnet: boolean,\n): CronStatus {\n if (!isOpenClaw()) {\n return { isOpenClaw: false, crons: [] };\n }\n\n const prefix = cronName(subdomain, testnet);\n const all = listCronDetails();\n const matching = all.filter((c) => c.name.startsWith(prefix));\n\n return { isOpenClaw: true, crons: matching };\n}\n"],"mappings":"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","names":[]}
|