@sherwoodagent/cli 0.86.0 → 0.87.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{abis-WVW2EBI3.js → abis-WJQ6IVYV.js} +2 -2
- package/dist/{agent-TBLC3WNJ.js → agent-A2JEYGQS.js} +7 -7
- package/dist/{chat-PRYOT3ZV.js → chat-OZAAN5LT.js} +8 -8
- package/dist/{chunk-I2BBOJNC.js → chunk-37GT3TJX.js} +5 -5
- package/dist/{chunk-45FELUWY.js → chunk-3UYGXGMF.js} +2 -2
- package/dist/{chunk-6N7EVSAZ.js → chunk-CU42ZD4K.js} +22 -9
- package/dist/chunk-CU42ZD4K.js.map +1 -0
- package/dist/{chunk-PVTZMRC6.js → chunk-G3FUEM5N.js} +2 -2
- package/dist/chunk-G3FUEM5N.js.map +1 -0
- package/dist/{chunk-5NFAEOFG.js → chunk-GR3GSU3I.js} +6 -6
- package/dist/{chunk-KVB5P2OE.js → chunk-IINWI3LD.js} +2 -2
- package/dist/{chunk-F3MDCUGO.js → chunk-J2IZWAEW.js} +75 -227
- package/dist/chunk-J2IZWAEW.js.map +1 -0
- package/dist/{chunk-ARSQ5UQA.js → chunk-JGD6A2Q4.js} +29 -82
- package/dist/chunk-JGD6A2Q4.js.map +1 -0
- package/dist/{chunk-QRMZRAMG.js → chunk-MIAMGVZ4.js} +8 -8
- package/dist/chunk-MIAMGVZ4.js.map +1 -0
- package/dist/{chunk-HODME7UJ.js → chunk-R6F57QQF.js} +14 -23
- package/dist/chunk-R6F57QQF.js.map +1 -0
- package/dist/{chunk-53W6CYYV.js → chunk-TTF5TDRV.js} +5 -5
- package/dist/{chunk-AM6MI2JF.js → chunk-UOIAY6ZG.js} +148 -58
- package/dist/chunk-UOIAY6ZG.js.map +1 -0
- package/dist/{chunk-LRUSZUEU.js → chunk-V7TNYHIK.js} +337 -490
- package/dist/chunk-V7TNYHIK.js.map +1 -0
- package/dist/{chunk-M4GX5PL2.js → chunk-W3XWRWML.js} +5 -5
- package/dist/{client-3SE632Q2.js → client-C6N2ASTH.js} +3 -3
- package/dist/{eas-D3BVHBJH.js → eas-VFTWEI4K.js} +6 -6
- package/dist/{governor-35IXAEDJ.js → governor-HVBSI6Z2.js} +10 -8
- package/dist/identity-OLD25QEP.js +18 -0
- package/dist/index.js +168 -316
- package/dist/index.js.map +1 -1
- package/dist/{network-FEHRFDPJ.js → network-7445KSCF.js} +2 -2
- package/dist/{price-I5T77X7Y.js → price-O3THX2HL.js} +6 -6
- package/dist/{providers-BMOHHVUN.js → providers-KZNCCUKT.js} +4 -4
- package/dist/{research-NKGP3M4J.js → research-ARFBFXIT.js} +7 -7
- package/dist/{session-LJT3SAED.js → session-A7CYZSSA.js} +14 -12
- package/dist/session-A7CYZSSA.js.map +1 -0
- package/dist/{trade-OTZ7UHDK.js → trade-ZCK332E4.js} +15 -15
- package/dist/{vault-7O4N6WZG.js → vault-CDI7BELZ.js} +8 -8
- package/dist/{xmtp-R25Q5GWY.js → xmtp-7LAWDKJT.js} +6 -6
- package/package.json +1 -1
- package/dist/chunk-6N7EVSAZ.js.map +0 -1
- package/dist/chunk-AM6MI2JF.js.map +0 -1
- package/dist/chunk-ARSQ5UQA.js.map +0 -1
- package/dist/chunk-F3MDCUGO.js.map +0 -1
- package/dist/chunk-HODME7UJ.js.map +0 -1
- package/dist/chunk-LRUSZUEU.js.map +0 -1
- package/dist/chunk-PVTZMRC6.js.map +0 -1
- package/dist/chunk-QRMZRAMG.js.map +0 -1
- package/dist/identity-XOAYQFUW.js +0 -15
- package/dist/session-LJT3SAED.js.map +0 -1
- /package/dist/{abis-WVW2EBI3.js.map → abis-WJQ6IVYV.js.map} +0 -0
- /package/dist/{agent-TBLC3WNJ.js.map → agent-A2JEYGQS.js.map} +0 -0
- /package/dist/{chat-PRYOT3ZV.js.map → chat-OZAAN5LT.js.map} +0 -0
- /package/dist/{chunk-I2BBOJNC.js.map → chunk-37GT3TJX.js.map} +0 -0
- /package/dist/{chunk-45FELUWY.js.map → chunk-3UYGXGMF.js.map} +0 -0
- /package/dist/{chunk-5NFAEOFG.js.map → chunk-GR3GSU3I.js.map} +0 -0
- /package/dist/{chunk-KVB5P2OE.js.map → chunk-IINWI3LD.js.map} +0 -0
- /package/dist/{chunk-53W6CYYV.js.map → chunk-TTF5TDRV.js.map} +0 -0
- /package/dist/{chunk-M4GX5PL2.js.map → chunk-W3XWRWML.js.map} +0 -0
- /package/dist/{client-3SE632Q2.js.map → client-C6N2ASTH.js.map} +0 -0
- /package/dist/{eas-D3BVHBJH.js.map → eas-VFTWEI4K.js.map} +0 -0
- /package/dist/{governor-35IXAEDJ.js.map → governor-HVBSI6Z2.js.map} +0 -0
- /package/dist/{identity-XOAYQFUW.js.map → identity-OLD25QEP.js.map} +0 -0
- /package/dist/{network-FEHRFDPJ.js.map → network-7445KSCF.js.map} +0 -0
- /package/dist/{price-I5T77X7Y.js.map → price-O3THX2HL.js.map} +0 -0
- /package/dist/{providers-BMOHHVUN.js.map → providers-KZNCCUKT.js.map} +0 -0
- /package/dist/{research-NKGP3M4J.js.map → research-ARFBFXIT.js.map} +0 -0
- /package/dist/{trade-OTZ7UHDK.js.map → trade-ZCK332E4.js.map} +0 -0
- /package/dist/{vault-7O4N6WZG.js.map → vault-CDI7BELZ.js.map} +0 -0
- /package/dist/{xmtp-R25Q5GWY.js.map → xmtp-7LAWDKJT.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/client.ts","../src/lib/errors.ts"],"sourcesContent":["/**\n * viem client factory — resolves chain and RPC from the network module.\n * Private key is read from ~/.sherwood/config.json (set via `sherwood config set --private-key`),\n * with PRIVATE_KEY env var as fallback.\n */\n\n// dotenv loaded at entrypoint\nimport type { Hex, TransactionReceipt } from \"viem\";\nimport { createPublicClient, createWalletClient, fallback, http } from \"viem\";\nimport { privateKeyToAccount } from \"viem/accounts\";\nimport { getChain, getRpcUrls, getMinGasReserve } from \"./network.js\";\nimport { requirePrivateKey } from \"./config.js\";\nimport { formatContractError } from \"./errors.js\";\nexport { formatContractError } from \"./errors.js\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nlet _publicClient: any = null;\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nlet _walletClient: any = null;\n\n/**\n * Build a viem fallback transport over the chain's RPC URL list.\n * Transparently advances to the next URL on rate-limit / network errors\n * (issue #182). `retryCount: 0` on the inner `http` avoids wasting 10+s\n * spinning on a dead RPC before the fallback layer advances.\n */\nfunction buildTransport() {\n const urls = getRpcUrls();\n return fallback(\n urls.map((url) => http(url, { retryCount: 0, timeout: 8_000 })),\n { rank: false, retryCount: 0 },\n );\n}\n\nexport function getPublicClient() {\n const chain = getChain();\n // Auto-invalidate if network changed since last creation\n if (_publicClient && _publicClient.chain?.id !== chain.id) {\n _publicClient = null;\n }\n if (!_publicClient) {\n _publicClient = createPublicClient({\n chain,\n transport: buildTransport(),\n });\n }\n return _publicClient as ReturnType<typeof createPublicClient>;\n}\n\nexport function getWalletClient() {\n const chain = getChain();\n // Auto-invalidate if network changed since last creation\n if (_walletClient && _walletClient.chain?.id !== chain.id) {\n _walletClient = null;\n }\n if (!_walletClient) {\n const account = privateKeyToAccount(requirePrivateKey());\n _walletClient = createWalletClient({\n account,\n chain,\n transport: buildTransport(),\n });\n }\n return _walletClient as ReturnType<typeof createWalletClient>;\n}\n\n/**\n * Reset cached clients. Required for tests that call setNetwork()\n * after a client was already created.\n */\nexport function resetClients() {\n _publicClient = null;\n _walletClient = null;\n}\n\nexport function getAccount() {\n return privateKeyToAccount(requirePrivateKey());\n}\n\n/**\n * Estimate EIP-1559 fees with a 20% buffer to avoid stuck txs on Base gas spikes.\n */\nexport async function estimateFeesWithBuffer() {\n const client = getPublicClient();\n const { maxFeePerGas, maxPriorityFeePerGas } =\n await client.estimateFeesPerGas();\n let fee = (maxFeePerGas * 120n) / 100n;\n let tip = (maxPriorityFeePerGas * 120n) / 100n;\n // #462: some RPCs (Robinhood testnet after activity bursts) suggest fees\n // orders of magnitude above the live base fee; viem's worst-case prefund\n // check (gas × maxFeePerGas) then rejects large txs from small wallets even\n // though real cost is negligible. Clamp to 10× live base, but ONLY when the\n // suggestion exceeds 1000× base (never true on healthy chains — Base gas\n // spikes stay untouched). Best-effort: a failed getBlock skips the clamp.\n let base: bigint | null | undefined;\n try {\n base = (await client.getBlock()).baseFeePerGas;\n } catch {\n base = undefined;\n }\n if (base !== null && base !== undefined && base > 0n && fee > base * 1000n) {\n fee = base * 10n;\n if (tip > fee) tip = fee;\n }\n return { maxFeePerGas: fee, maxPriorityFeePerGas: tip };\n}\n\n/**\n * Conservative per-op gas-unit budgets for the native-ETH-wrap deposit/redeem\n * sequences. Multiplied by the live buffered `maxFeePerGas` (× a safety factor)\n * to derive the ETH gas cushion — replacing the old hardcoded 0.0005-ETH,\n * Base-calibrated constant that rejected valid deposits on low-fee chains\n * (Robinhood testnet, ~14-wei base fee). Deliberately generous; the realized\n * cost is a fraction of these on any chain.\n */\nexport const GAS_UNITS = {\n wrap: 55_000n,\n approve: 60_000n,\n deposit: 250_000n,\n redeem: 250_000n,\n} as const;\n\n/**\n * Derive the ETH gas cushion from live chain gas instead of a fixed constant:\n *\n * cushion = gasUnits × bufferedMaxFeePerGas × safetyFactor, floored at the\n * active chain's `minGasReserve`.\n *\n * `gasUnits` is the summed budget for the tx sequence (e.g. wrap+approve+deposit\n * via `GAS_UNITS`). Falls back to the per-chain floor when the live fee estimate\n * is unavailable (RPC error). On a ~14-wei-base-fee chain the derived term is\n * negligible, so the tiny per-chain floor dominates; on Base the live term\n * scales with the gas market and the Base-scale floor is the lower bound.\n */\nexport async function estimateGasCushion(\n gasUnits: bigint,\n safetyFactor = 2n,\n): Promise<bigint> {\n const floor = getMinGasReserve();\n try {\n const { maxFeePerGas } = await estimateFeesWithBuffer();\n const derived = gasUnits * maxFeePerGas * safetyFactor;\n return derived > floor ? derived : floor;\n } catch {\n return floor;\n }\n}\n\n// ── Nonce management + retry helpers ──\n//\n// Handles: nonce collisions, underpriced replacements, stuck pending txs.\n// Gas bump ceiling: base * 1.2 (buffer) * 1.1^3 (max retries) ≈ 1.6x base fee.\n\nconst MAX_RETRIES = 3;\nconst RETRY_DELAY_MS = 1500; // backoff between retries\nconst STUCK_NONCE_CONFIRM_DELAY_MS = 2500; // staleness check delay\nconst GAS_BUMP_NUMERATOR = 110n;\nconst GAS_BUMP_DENOMINATOR = 100n;\n\nfunction isUnderpricedError(msg: string): boolean {\n return msg.includes(\"replacement transaction underpriced\");\n}\n\nfunction isNonceStaleError(msg: string): boolean {\n return msg.includes(\"nonce too low\") || msg.includes(\"NONCE_EXPIRED\");\n}\n\nfunction isRetryableError(err: unknown): boolean {\n const msg = err instanceof Error ? err.message : String(err);\n return isUnderpricedError(msg) || isNonceStaleError(msg);\n}\n\nfunction bumpFees(fees: { maxFeePerGas: bigint; maxPriorityFeePerGas: bigint }) {\n return {\n maxFeePerGas: (fees.maxFeePerGas * GAS_BUMP_NUMERATOR) / GAS_BUMP_DENOMINATOR,\n maxPriorityFeePerGas: (fees.maxPriorityFeePerGas * GAS_BUMP_NUMERATOR) / GAS_BUMP_DENOMINATOR,\n };\n}\n\n// ── Stuck nonce detection ──\n\n/**\n * Check if the wallet has a stuck nonce (pending tx count > confirmed tx count).\n * Returns the stuck nonce number, or null if the wallet is clean.\n *\n * Includes a staleness guard: if pending > confirmed, waits ~2.5s and re-checks\n * to avoid false positives from propagation delays.\n */\nexport async function detectStuckNonce(): Promise<number | null> {\n const client = getPublicClient();\n const address = getAccount().address;\n const [confirmed, pending] = await Promise.all([\n client.getTransactionCount({ address, blockTag: \"latest\" }),\n client.getTransactionCount({ address, blockTag: \"pending\" }),\n ]);\n if (pending <= confirmed) return null;\n\n // Staleness guard: re-check after a short delay to avoid false positives\n await new Promise((r) => setTimeout(r, STUCK_NONCE_CONFIRM_DELAY_MS));\n const [confirmed2, pending2] = await Promise.all([\n client.getTransactionCount({ address, blockTag: \"latest\" }),\n client.getTransactionCount({ address, blockTag: \"pending\" }),\n ]);\n return pending2 > confirmed2 ? confirmed2 : null;\n}\n\n/**\n * Clear a single stuck nonce by sending a 0-value self-transfer with aggressively bumped gas.\n * Uses 5x the buffered fee estimate to guarantee replacement even if the original tx\n * was sent during a gas spike (EIP-1559 requires >= 110% of original maxPriorityFeePerGas).\n */\nasync function unstickWalletSingle(): Promise<Hex> {\n const stuckNonce = await detectStuckNonce();\n if (stuckNonce === null) {\n throw new Error(\"No stuck nonce detected — wallet is clean.\");\n }\n\n console.warn(` Unsticking wallet: replacing stuck tx at nonce ${stuckNonce}...`);\n const wallet = getWalletClient();\n const account = getAccount();\n\n // Use 5x gas buffer to guarantee replacement even for txs sent during gas spikes\n const { maxFeePerGas, maxPriorityFeePerGas } = await estimateFeesWithBuffer();\n const hash = await wallet.sendTransaction({\n account,\n chain: wallet.chain,\n to: account.address,\n value: 0n,\n nonce: stuckNonce,\n maxFeePerGas: maxFeePerGas * 5n,\n maxPriorityFeePerGas: maxPriorityFeePerGas * 5n,\n });\n\n const client = getPublicClient();\n await client.waitForTransactionReceipt({ hash });\n console.warn(` Wallet unstuck (nonce ${stuckNonce} replaced).`);\n return hash;\n}\n\n/**\n * Unstick a wallet by clearing ALL stuck nonces, not just the first one.\n * Loops until pending == confirmed nonce count.\n */\nexport async function unstickWallet(): Promise<Hex[]> {\n const hashes: Hex[] = [];\n while ((await detectStuckNonce()) !== null) {\n hashes.push(await unstickWalletSingle());\n }\n if (hashes.length === 0) {\n throw new Error(\"No stuck nonce detected — wallet is clean.\");\n }\n return hashes;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype TxSender = (params: any) => Promise<Hex>;\n\n/**\n * Shared retry loop: explicit nonce + EIP-1559 fee buffer + gas-bump on underpriced errors.\n * On \"nonce too low\" / \"NONCE_EXPIRED\", re-fetches nonce from pending state before retrying.\n * Also detects stuck nonces before sending and auto-unsticks the wallet.\n */\nasync function withRetry(send: TxSender, txParams: Record<string, unknown>): Promise<Hex> {\n const client = getPublicClient();\n const account = getAccount();\n let fees = await estimateFeesWithBuffer();\n\n // Auto-detect and clear ALL stuck nonces before attempting the tx\n while ((await detectStuckNonce()) !== null) {\n await unstickWalletSingle();\n }\n\n let nonce = await client.getTransactionCount({ address: account.address, blockTag: \"pending\" });\n\n for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {\n try {\n return await send({ ...txParams, ...fees, nonce });\n } catch (err) {\n if (attempt >= MAX_RETRIES || !isRetryableError(err)) {\n // Decode contract revert into a human-readable message before throwing\n throw new Error(formatContractError(err));\n }\n\n const msg = err instanceof Error ? err.message : String(err);\n console.warn(` Retry ${attempt + 1}/${MAX_RETRIES}: ${isNonceStaleError(msg) ? \"refreshing nonce\" : \"bumping gas\"}...`);\n\n // Backoff between retries to let mempool settle\n await new Promise((r) => setTimeout(r, RETRY_DELAY_MS));\n\n if (isNonceStaleError(msg)) {\n // Fresh nonce = fresh tx, no replacement needed — only bump fees for underpriced errors\n nonce = await client.getTransactionCount({ address: account.address, blockTag: \"pending\" });\n } else {\n fees = bumpFees(fees);\n }\n }\n }\n throw new Error(\"withRetry: exhausted retries\");\n}\n\n/**\n * Send a raw transaction with automatic gas-bump retry on nonce/underpriced errors.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport async function sendTxWithRetry(txParams: Record<string, any>): Promise<Hex> {\n const wallet = getWalletClient();\n return withRetry((p) => wallet.sendTransaction(p), txParams);\n}\n\n/**\n * Call writeContract with automatic gas-bump retry on nonce/underpriced errors.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport async function writeContractWithRetry(txParams: Record<string, any>): Promise<Hex> {\n const wallet = getWalletClient();\n return withRetry((p) => wallet.writeContract(p), txParams);\n}\n\n/**\n * Wait for a tx receipt. On timeout, checks for stuck nonce and auto-unsticks.\n *\n * **Important**: After unsticking, the error is still re-thrown because the original\n * tx is lost. Callers should use `writeContractWithRetry` / `sendTxWithRetry` which\n * re-fetch nonces automatically. Do NOT manually retry after this throws — use the\n * retry-aware wrappers instead.\n */\nexport async function waitForReceipt(hash: Hex): Promise<TransactionReceipt> {\n const client = getPublicClient();\n try {\n return await client.waitForTransactionReceipt({ hash });\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (err: any) {\n // If receipt wait times out, check for stuck nonce\n const msg = err instanceof Error ? err.message : String(err);\n if (msg.includes(\"timeout\") || msg.includes(\"Timed out\")) {\n if ((await detectStuckNonce()) !== null) {\n console.warn(` Tx ${hash} appears stuck — attempting to unstick wallet...`);\n while ((await detectStuckNonce()) !== null) {\n await unstickWalletSingle();\n }\n }\n }\n throw err;\n }\n}\n","/**\n * Contract error decoding — turns raw reverts into human-readable messages.\n *\n * Uses viem's decodeErrorResult() against a combined ABI of all custom errors\n * from SyndicateVault, SyndicateGovernor, GovernorParameters, SyndicateFactory,\n * and strategy contracts.\n */\n\nimport { type Hex, decodeErrorResult, BaseError } from \"viem\";\nimport { getChain } from \"./network.js\";\n\n// ── Combined error-only ABI for decoding ──\n\nexport const CONTRACT_ERRORS_ABI = [\n // ── SyndicateVault ──\n { type: \"error\", name: \"InvalidOwner\", inputs: [] },\n { type: \"error\", name: \"InvalidExecutorImpl\", inputs: [] },\n { type: \"error\", name: \"NotActiveAgent\", inputs: [] },\n { type: \"error\", name: \"SimulationFailed\", inputs: [] },\n { type: \"error\", name: \"InvalidDepositor\", inputs: [] },\n { type: \"error\", name: \"DepositorAlreadyApproved\", inputs: [] },\n { type: \"error\", name: \"DepositorNotApproved\", inputs: [] },\n { type: \"error\", name: \"NotApprovedDepositor\", inputs: [] },\n { type: \"error\", name: \"AgentAlreadyRegistered\", inputs: [] },\n { type: \"error\", name: \"AgentNotActive\", inputs: [] },\n { type: \"error\", name: \"InvalidAgentRegistry\", inputs: [] },\n { type: \"error\", name: \"NotAgentOwner\", inputs: [] },\n { type: \"error\", name: \"NotGovernor\", inputs: [] },\n { type: \"error\", name: \"RedemptionsLocked\", inputs: [] },\n { type: \"error\", name: \"DepositsLocked\", inputs: [] },\n { type: \"error\", name: \"InvalidAgentAddress\", inputs: [] },\n { type: \"error\", name: \"TransferFailed\", inputs: [] },\n { type: \"error\", name: \"ZeroAddress\", inputs: [] },\n { type: \"error\", name: \"CannotRescueAsset\", inputs: [] },\n { type: \"error\", name: \"NotFactory\", inputs: [] },\n { type: \"error\", name: \"DisallowedBatchCallee\", inputs: [{ name: \"target\", type: \"address\" }] },\n\n // ── SyndicateGovernor ──\n { type: \"error\", name: \"VaultNotRegistered\", inputs: [] },\n { type: \"error\", name: \"VaultAlreadyRegistered\", inputs: [] },\n { type: \"error\", name: \"NotRegisteredAgent\", inputs: [] },\n { type: \"error\", name: \"PerformanceFeeTooHigh\", inputs: [] },\n { type: \"error\", name: \"StrategyDurationTooLong\", inputs: [] },\n { type: \"error\", name: \"StrategyDurationTooShort\", inputs: [] },\n { type: \"error\", name: \"EmptyExecuteCalls\", inputs: [] },\n { type: \"error\", name: \"EmptySettlementCalls\", inputs: [] },\n { type: \"error\", name: \"NotWithinVotingPeriod\", inputs: [] },\n { type: \"error\", name: \"NoVotingPower\", inputs: [] },\n { type: \"error\", name: \"AlreadyVoted\", inputs: [] },\n { type: \"error\", name: \"ProposalNotFound\", inputs: [] },\n { type: \"error\", name: \"ProposalNotApproved\", inputs: [] },\n { type: \"error\", name: \"ExecutionWindowExpired\", inputs: [] },\n { type: \"error\", name: \"StrategyAlreadyActive\", inputs: [] },\n { type: \"error\", name: \"CooldownNotElapsed\", inputs: [] },\n { type: \"error\", name: \"ProposalNotExecuted\", inputs: [] },\n { type: \"error\", name: \"ProposalNotCancellable\", inputs: [] },\n { type: \"error\", name: \"NotProposer\", inputs: [] },\n { type: \"error\", name: \"InvalidVotingPeriod\", inputs: [] },\n { type: \"error\", name: \"InvalidExecutionWindow\", inputs: [] },\n { type: \"error\", name: \"InvalidVetoThresholdBps\", inputs: [] },\n { type: \"error\", name: \"InvalidMaxPerformanceFeeBps\", inputs: [] },\n { type: \"error\", name: \"InvalidStrategyDurationBounds\", inputs: [] },\n { type: \"error\", name: \"InvalidCooldownPeriod\", inputs: [] },\n { type: \"error\", name: \"InvalidVault\", inputs: [] },\n { type: \"error\", name: \"NotVaultOwner\", inputs: [] },\n { type: \"error\", name: \"StrategyDurationNotElapsed\", inputs: [] },\n { type: \"error\", name: \"InvalidProtocolFeeBps\", inputs: [] },\n { type: \"error\", name: \"InvalidProtocolFeeRecipient\", inputs: [] },\n { type: \"error\", name: \"NotCoProposer\", inputs: [] },\n { type: \"error\", name: \"CollaborationExpired\", inputs: [] },\n { type: \"error\", name: \"AlreadyApproved\", inputs: [] },\n { type: \"error\", name: \"InvalidSplits\", inputs: [] },\n { type: \"error\", name: \"TooManyCoProposers\", inputs: [] },\n { type: \"error\", name: \"SplitTooLow\", inputs: [] },\n { type: \"error\", name: \"LeadSplitTooLow\", inputs: [] },\n { type: \"error\", name: \"DuplicateCoProposer\", inputs: [] },\n { type: \"error\", name: \"NotDraftState\", inputs: [] },\n { type: \"error\", name: \"InvalidCollaborationWindow\", inputs: [] },\n { type: \"error\", name: \"NotAuthorized\", inputs: [] },\n { type: \"error\", name: \"InvalidMaxCoProposers\", inputs: [] },\n { type: \"error\", name: \"Reentrancy\", inputs: [] },\n { type: \"error\", name: \"Tier2CallCapExceedsCeiling\", inputs: [{ name: \"index\", type: \"uint256\" }] },\n\n // ── GovernorParameters (timelock) ──\n { type: \"error\", name: \"ChangeAlreadyPending\", inputs: [] },\n { type: \"error\", name: \"NoChangePending\", inputs: [] },\n { type: \"error\", name: \"ChangeNotReady\", inputs: [] },\n { type: \"error\", name: \"InvalidParameterChangeDelay\", inputs: [] },\n { type: \"error\", name: \"InvalidParameterKey\", inputs: [] },\n\n // ── SyndicateFactory ──\n { type: \"error\", name: \"InvalidVaultImpl\", inputs: [] },\n { type: \"error\", name: \"InvalidENSRegistrar\", inputs: [] },\n { type: \"error\", name: \"SubdomainTooShort\", inputs: [] },\n { type: \"error\", name: \"SubdomainTaken\", inputs: [] },\n { type: \"error\", name: \"NotCreator\", inputs: [] },\n { type: \"error\", name: \"InvalidGovernor\", inputs: [] },\n { type: \"error\", name: \"InsufficientCreationFee\", inputs: [] },\n { type: \"error\", name: \"InvalidFeeToken\", inputs: [] },\n { type: \"error\", name: \"ManagementFeeTooHigh\", inputs: [] },\n { type: \"error\", name: \"UpgradesDisabled\", inputs: [] },\n { type: \"error\", name: \"VaultNotDeployed\", inputs: [] },\n { type: \"error\", name: \"StrategyActive\", inputs: [] },\n\n // ── BaseStrategy ──\n { type: \"error\", name: \"AlreadyInitialized\", inputs: [] },\n { type: \"error\", name: \"NotVault\", inputs: [] },\n { type: \"error\", name: \"NotExecuted\", inputs: [] },\n { type: \"error\", name: \"AlreadyExecuted\", inputs: [] },\n { type: \"error\", name: \"AlreadySettled\", inputs: [] },\n\n // ── MoonwellSupplyStrategy / WstETHMoonwellStrategy ──\n { type: \"error\", name: \"InvalidAmount\", inputs: [] },\n { type: \"error\", name: \"MintFailed\", inputs: [] },\n { type: \"error\", name: \"RedeemFailed\", inputs: [] },\n\n // ── AerodromeLPStrategy ──\n { type: \"error\", name: \"GaugeMismatch\", inputs: [] },\n\n // ── WstETHMoonwellStrategy / VeniceInferenceStrategy ──\n { type: \"error\", name: \"SwapFailed\", inputs: [] },\n { type: \"error\", name: \"AlreadySettledParams\", inputs: [] },\n\n // ── PortfolioStrategy / UniswapSwapAdapter ──\n { type: \"error\", name: \"QuoteUnavailable\", inputs: [] },\n { type: \"error\", name: \"UnsupportedMode\", inputs: [] },\n { type: \"error\", name: \"InvalidWeights\", inputs: [] },\n { type: \"error\", name: \"LengthMismatch\", inputs: [] },\n { type: \"error\", name: \"TooManyTokens\", inputs: [] },\n { type: \"error\", name: \"RebalancingInProgress\", inputs: [] },\n { type: \"error\", name: \"StalePrice\", inputs: [] },\n { type: \"error\", name: \"InvalidSlippage\", inputs: [] },\n { type: \"error\", name: \"InvalidPriceDecimals\", inputs: [] },\n\n // ── VeniceInferenceStrategy ──\n { type: \"error\", name: \"NoAgent\", inputs: [] },\n\n // ── ExposureLedger ──\n { type: \"error\", name: \"ApproveLockBelowFloor\", inputs: [] },\n { type: \"error\", name: \"CoverageInputsUnreadable\", inputs: [] },\n { type: \"error\", name: \"InsufficientApproveCoverage\", inputs: [] },\n\n // ── StakedWood ──\n { type: \"error\", name: \"CoverageStillOpen\", inputs: [] },\n] as const;\n\n// ── Human-readable error messages ──\n\nconst ERROR_MESSAGES: Record<string, string> = {\n // Vault — permissions / state\n InvalidOwner: \"The caller is not the vault owner.\",\n NotActiveAgent: \"Your wallet is not registered as an active agent on this vault. Ask the creator to run: sherwood fund approve --agent-id <id> --wallet <your-address>\",\n NotApprovedDepositor: \"Your address is not on the depositor whitelist. Ask the vault creator to approve you.\",\n NotGovernor: \"This operation can only be called by the governor contract.\",\n NotFactory: \"This operation can only be called by the factory contract.\",\n RedemptionsLocked: \"Redemptions are locked while a strategy is executing. Wait for the proposal to be settled.\",\n DepositsLocked: \"Deposits are locked while an active proposal exists. Wait for settlement.\",\n InvalidDepositor: \"Invalid depositor address.\",\n DepositorAlreadyApproved: \"This depositor is already on the whitelist.\",\n DepositorNotApproved: \"This depositor is not on the whitelist.\",\n AgentAlreadyRegistered: \"This agent wallet is already registered on the vault.\",\n AgentNotActive: \"This agent is registered but not active.\",\n InvalidAgentRegistry: \"Agent registry address is invalid.\",\n NotAgentOwner: \"You do not own this ERC-8004 agent identity NFT.\",\n InvalidAgentAddress: \"Invalid agent wallet address (cannot be zero).\",\n InvalidExecutorImpl: \"Executor implementation address is invalid.\",\n SimulationFailed: \"Transaction simulation failed — the batch calls would revert onchain.\",\n TransferFailed: \"ERC-20 token transfer failed. Check token balance and approvals.\",\n ZeroAddress: \"A required address parameter is the zero address.\",\n CannotRescueAsset: \"Cannot rescue the vault's underlying asset — use redeem() instead.\",\n DisallowedBatchCallee: \"A governor-batch call targeted an address that is neither the vault's underlying asset nor a TierRegistry-allowlisted adapter.\",\n\n // Governor — proposal lifecycle\n VaultNotRegistered: \"This vault is not registered with the governor. The factory registers vaults automatically on creation.\",\n VaultAlreadyRegistered: \"This vault is already registered with the governor.\",\n NotRegisteredAgent: \"Your wallet is not a registered agent on this vault. Register first via: sherwood fund approve\",\n PerformanceFeeTooHigh: \"Performance fee exceeds the governor's maxPerformanceFeeBps. Check: sherwood governor info\",\n StrategyDurationTooLong: \"Strategy duration exceeds the governor's maxStrategyDuration. Check: sherwood governor info\",\n StrategyDurationTooShort: \"Strategy duration is below the governor's minStrategyDuration. Check: sherwood governor info\",\n EmptyExecuteCalls: \"Proposal must include at least one execute call.\",\n EmptySettlementCalls: \"Proposal must include at least one settlement call.\",\n NotWithinVotingPeriod: \"Voting period has not started or has already ended. Check: sherwood proposal show <id>\",\n NoVotingPower: \"You have no voting power (zero vault shares at the snapshot time).\",\n AlreadyVoted: \"You have already voted on this proposal.\",\n ProposalNotFound: \"Proposal does not exist. Check the proposal ID.\",\n ProposalNotApproved: \"Proposal is not in Approved state. It may still be in voting or was rejected.\",\n ExecutionWindowExpired: \"The execution window has closed. The proposal is now Expired.\",\n StrategyAlreadyActive: \"Another strategy is currently executing on this vault. Settle it first before executing a new proposal.\",\n CooldownNotElapsed: \"A proposal was recently settled. Wait for the cooldown period to elapse. Check: sherwood governor info\",\n ProposalNotExecuted: \"Proposal has not been executed yet. Execute it first.\",\n ProposalNotCancellable: \"This proposal cannot be cancelled in its current state.\",\n NotProposer: \"Only the original proposer can perform this action.\",\n StrategyDurationNotElapsed: \"Strategy duration has not elapsed yet. Only the proposer can settle early.\",\n\n // Governor — parameter validation\n InvalidVotingPeriod: \"Voting period is outside allowed bounds (check governor constants).\",\n InvalidExecutionWindow: \"Execution window is outside allowed bounds.\",\n InvalidVetoThresholdBps: \"Veto threshold must be between the allowed bounds (in bps).\",\n InvalidMaxPerformanceFeeBps: \"Max performance fee is outside allowed bounds.\",\n InvalidStrategyDurationBounds: \"Strategy duration bounds are invalid (min must be < max).\",\n InvalidCooldownPeriod: \"Cooldown period is outside allowed bounds.\",\n InvalidVault: \"Invalid vault address.\",\n NotVaultOwner: \"Only the vault owner can perform this action.\",\n InvalidProtocolFeeBps: \"Protocol fee exceeds the 10% maximum (1000 bps).\",\n InvalidProtocolFeeRecipient: \"Protocol fee recipient must be set before enabling protocol fees.\",\n\n // Governor — collaborative proposals\n NotCoProposer: \"You are not listed as a co-proposer on this proposal.\",\n CollaborationExpired: \"The collaboration window has expired.\",\n AlreadyApproved: \"This co-proposer has already approved.\",\n InvalidSplits: \"Co-proposer fee splits must sum correctly with the lead proposer split.\",\n TooManyCoProposers: \"Exceeds the maximum number of co-proposers. Check: sherwood governor info\",\n SplitTooLow: \"A co-proposer's fee split is below the minimum.\",\n LeadSplitTooLow: \"The lead proposer's fee split is below the minimum.\",\n DuplicateCoProposer: \"Duplicate co-proposer address in the list.\",\n NotDraftState: \"Proposal must be in Draft state for this operation.\",\n InvalidCollaborationWindow: \"Collaboration window is outside allowed bounds.\",\n NotAuthorized: \"You are not authorized to perform this action.\",\n InvalidMaxCoProposers: \"Max co-proposers value is outside allowed bounds.\",\n Reentrancy: \"Reentrancy detected — this call cannot be made during another call.\",\n Tier2CallCapExceedsCeiling: \"A tier-2 call cap exceeds the vault's tier-2 per-call ceiling (totalAssets × tier2CallCapBps / 10_000). Lower that call's cap.\",\n\n // Governor — parameter timelock\n ChangeAlreadyPending: \"A parameter change is already pending for this parameter. Finalize or cancel it first.\",\n NoChangePending: \"No parameter change is pending for this key.\",\n ChangeNotReady: \"Parameter change timelock has not elapsed yet. Wait for the delay to pass, then finalize.\",\n InvalidParameterChangeDelay: \"Parameter change delay is outside allowed bounds.\",\n InvalidParameterKey: \"Unknown parameter key.\",\n\n // Factory\n InvalidVaultImpl: \"Vault implementation address is invalid.\",\n InvalidENSRegistrar: \"ENS registrar address is invalid.\",\n SubdomainTooShort: \"Subdomain must be at least 3 characters.\",\n SubdomainTaken: \"This subdomain is already taken. Choose a different name.\",\n NotCreator: \"Only the fund creator can perform this action.\",\n InvalidGovernor: \"Governor address is invalid.\",\n InsufficientCreationFee: \"Insufficient creation fee. Check the required fee amount.\",\n InvalidFeeToken: \"Invalid fee token address.\",\n ManagementFeeTooHigh: \"Management fee exceeds the maximum allowed.\",\n UpgradesDisabled: \"Vault upgrades are currently disabled by the factory owner.\",\n VaultNotDeployed: \"Vault has not been deployed yet.\",\n StrategyActive: \"Cannot perform this action while a strategy is actively executing.\",\n\n // Strategy — base\n AlreadyInitialized: \"This strategy clone was already initialized. Deploy a fresh clone.\",\n NotVault: \"Only the vault can call this strategy function.\",\n NotExecuted: \"Strategy has not been executed yet.\",\n AlreadyExecuted: \"Strategy has already been executed.\",\n AlreadySettled: \"Strategy has already been settled.\",\n\n // Strategy — Moonwell / WstETH\n InvalidAmount: \"Invalid amount — must be greater than zero.\",\n MintFailed: \"Moonwell cToken mint failed. The underlying supply may have hit the market cap.\",\n RedeemFailed: \"Moonwell cToken redeem failed. Check that sufficient liquidity is available.\",\n\n // Strategy — Aerodrome\n GaugeMismatch: \"Aerodrome gauge does not match the expected pool.\",\n\n // Strategy — WstETH / Venice\n SwapFailed: \"Token swap failed. Check slippage tolerance and pool liquidity.\",\n AlreadySettledParams: \"Settlement parameters have already been set.\",\n\n // Strategy — Portfolio / UniswapSwapAdapter\n QuoteUnavailable:\n \"Uniswap quoter returned 0 or reverted for a portfolio allocation. \" +\n \"Usually means: (a) no V3 pool exists at the requested fee tier for one of the tokens, \" +\n \"(b) the strategy clone was initialized against an old/broken UniswapSwapAdapter \" +\n \"(check the clone's swapAdapter() vs the current chains JSON), or \" +\n \"(c) the adapter is calling Quoter with the wrong ABI (pre-PR #317 bug).\",\n UnsupportedMode: \"UniswapSwapAdapter doesn't support that swap mode. Only V3 single-hop (mode 0) and multi-hop (mode 1) are supported.\",\n InvalidWeights: \"Portfolio weights must sum to 10000 bps (100%).\",\n LengthMismatch: \"Portfolio input arrays (tokens / weights / swapExtraData / priceDecimals / feeds) must have the same length.\",\n TooManyTokens: \"Portfolio basket exceeds the maximum allocation count (20).\",\n RebalancingInProgress: \"A rebalance is already in flight on this clone. Wait for it to finish.\",\n StalePrice: \"A Chainlink push feed backing a portfolio allocation is older than MAX_PUSH_PRICE_AGE (26h). Wait for the feed to update, or drop that allocation.\",\n InvalidSlippage: \"maxSlippageBps must be > 0 and < 10000.\",\n InvalidPriceDecimals: \"priceDecimals entry exceeds 36. Use 8 for tokenized-stock feeds, 18 for crypto pairs.\",\n\n // Strategy — Venice\n NoAgent: \"No agent is registered on the vault. Register an agent first.\",\n\n // ExposureLedger\n ApproveLockBelowFloor:\n \"An approver slot costs min(ceil(need/100), your whole budget), valued in USD at vote time. \" +\n \"Three ways to hit this: (1) the lock booked to zero — your free budget (k x stake minus open \" +\n \"exposure) is used up, so close an open lock or wait for one to age out; (2) your budget values \" +\n \"to zero — you have no slashable stake, or WOOD prices to zero right now; (3) what you declared \" +\n \"is worth less than the floor — raise --lock-wood on `sherwood proposal review-vote`.\",\n CoverageInputsUnreadable:\n \"The ledger could not read this proposal's coverage inputs (vault asset / required coverage). \" +\n \"Usually there is no such proposal on that governor — an unknown id reads back a zero vault. \" +\n \"Check the proposal id, and that the address really is this vault's governor.\",\n InsufficientApproveCoverage: \"No bonded guardian coverage was raised for this proposal. Execution requires at least one identified, bonded approver with slashable coverage.\",\n\n // StakedWood\n CoverageStillOpen: \"Cannot release the unstake yet — this guardian still backs a proposal that could be challenged. The unstake request stays open; retry after coverage closes.\",\n};\n\n// ── Decoding ──\n\n/**\n * Attempt to decode a hex revert selector into a human-readable error message.\n * Returns null if the selector doesn't match any known contract error.\n */\nexport function decodeContractError(data: Hex): { name: string; message: string } | null {\n try {\n const decoded = decodeErrorResult({\n abi: CONTRACT_ERRORS_ABI,\n data,\n });\n const message = ERROR_MESSAGES[decoded.errorName] || `Contract error: ${decoded.errorName}`;\n return { name: decoded.errorName, message };\n } catch {\n return null;\n }\n}\n\n/**\n * Extract a hex error selector from a viem error's walk chain.\n * viem wraps contract call reverts in ContractFunctionRevertedError which\n * contains a `data` field with the raw 4-byte (or longer) revert payload.\n */\nfunction extractRevertData(err: unknown): Hex | null {\n if (!(err instanceof BaseError)) return null;\n\n // Walk the viem error chain to find revert data\n const revertError = err.walk((e) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (e as any).data !== undefined;\n });\n\n if (revertError) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const data = (revertError as any).data;\n // data can be the hex string directly, or an object with a data field\n if (typeof data === \"string\" && data.startsWith(\"0x\")) {\n return data as Hex;\n }\n if (typeof data === \"object\" && data?.data && typeof data.data === \"string\") {\n return data.data as Hex;\n }\n }\n\n // Fallback: extract 0x + hex from the error message (e.g. \"reverted with 0x62df0545\")\n const msg = err.message || \"\";\n const match = msg.match(/(?:signature|data)\\s*\"?(0x[0-9a-fA-F]+)\"?/);\n if (match) return match[1] as Hex;\n\n return null;\n}\n\n// ── Known common EVM / ERC-20 revert strings ──\n\nconst KNOWN_REVERT_STRINGS: Record<string, string> = {\n \"ERC20: transfer amount exceeds balance\": \"Insufficient token balance for this transfer.\",\n \"ERC20: transfer amount exceeds allowance\": \"Token allowance insufficient. An approval step may have been skipped.\",\n \"ERC20: insufficient allowance\": \"Token allowance insufficient. An approval step may have been skipped.\",\n \"Ownable: caller is not the owner\": \"Only the contract owner can call this function.\",\n \"Pausable: paused\": \"The contract is currently paused.\",\n};\n\n/**\n * Format any caught error into a user-friendly message.\n *\n * Tries (in order):\n * 1. Decode custom error selector from our contract ABIs\n * 2. Match known EVM/ERC-20 revert reason strings\n * 3. Identify nonce / gas issues with actionable advice\n * 4. Fall back to the raw error message\n */\nexport function formatContractError(err: unknown): string {\n // 1. Try to decode custom contract error\n const revertData = extractRevertData(err);\n if (revertData && revertData.length >= 10) {\n const decoded = decodeContractError(revertData);\n if (decoded) return decoded.message;\n }\n\n const rawMsg = err instanceof Error ? err.message : String(err);\n\n // 2. Check for known revert reason strings\n for (const [pattern, message] of Object.entries(KNOWN_REVERT_STRINGS)) {\n if (rawMsg.includes(pattern)) return message;\n }\n\n // 3. Nonce / gas issues — already handled by retry, but surface clearly if they bubble up\n if (rawMsg.includes(\"replacement transaction underpriced\")) {\n return \"A previous transaction is stuck. The CLI retried with higher gas but the error persists. Try again in a moment.\";\n }\n if (rawMsg.includes(\"nonce too low\") || rawMsg.includes(\"NONCE_EXPIRED\")) {\n return \"Transaction nonce conflict — a previous transaction is still pending. Wait a moment and retry.\";\n }\n if (rawMsg.includes(\"insufficient funds for gas\")) {\n return `Insufficient ETH for gas fees. Top up your wallet with ETH on ${getChain().name}.`;\n }\n\n // 4. Clean up common viem wrapper noise\n // Strip \"ContractFunctionRevertedError:\" prefix and \"Docs:\" links\n let cleaned = rawMsg\n .replace(/ContractFunctionRevertedError:\\s*/g, \"\")\n .replace(/Docs:\\s*https:\\/\\/\\S+/g, \"\")\n .replace(/Version:\\s*viem@\\S+/g, \"\")\n .replace(/Request Arguments:[\\s\\S]*$/m, \"\")\n .replace(/Contract Call:[\\s\\S]*?(?=\\n\\n|\\n[A-Z]|$)/m, \"\")\n .trim();\n\n // If we still have \"reverted with the following signature: 0x...\" try one more decode\n const sigMatch = cleaned.match(/signature[:\\s]+\"?(0x[0-9a-fA-F]{8,})\"?/);\n if (sigMatch) {\n const decoded = decodeContractError(sigMatch[1] as Hex);\n if (decoded) return decoded.message;\n // If we can't decode it, at least explain what it is\n const explorer = getChain().blockExplorers?.default?.name ?? \"the block explorer\";\n cleaned = `Contract reverted with unknown error selector ${sigMatch[1]}. Check the transaction on ${explorer} for details.`;\n }\n\n return cleaned;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
PROPOSAL_STATES,
|
|
3
3
|
getProposal
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-CU42ZD4K.js";
|
|
5
5
|
import {
|
|
6
6
|
getPublicClient
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-MIAMGVZ4.js";
|
|
8
8
|
import {
|
|
9
9
|
resolveMetadataSummary
|
|
10
10
|
} from "./chunk-YMB4RJOR.js";
|
|
@@ -16,32 +16,18 @@ var VAULT_EVENTS = [
|
|
|
16
16
|
parseAbiItem("event AgentRegistered(uint256 indexed agentId, address indexed agentAddress)"),
|
|
17
17
|
parseAbiItem("event AgentRemoved(address indexed agentAddress)"),
|
|
18
18
|
parseAbiItem("event DepositorApproved(address indexed depositor)"),
|
|
19
|
-
parseAbiItem("event DepositorRemoved(address indexed depositor)")
|
|
20
|
-
parseAbiItem("event RedemptionsLockedEvent()"),
|
|
21
|
-
parseAbiItem("event RedemptionsUnlockedEvent()"),
|
|
22
|
-
// ISyndicateVault.SandboxRun — a proposal's sandbox was minted, funded and run.
|
|
23
|
-
// NAME COLLISION WARNING: ICallSandbox also declares a `SandboxRun` event with a
|
|
24
|
-
// DIFFERENT shape (SandboxRun(address,uint256,uint256), topic0 0x2638b671…) than
|
|
25
|
-
// this vault-side one (topic0 0x6fbfaa03…). Downstream consumers (the
|
|
26
|
-
// sherwood-monitor Hermes plugin) route by the `type` string, so ONLY the vault
|
|
27
|
-
// event may be emitted as "SandboxRun". If the ICallSandbox event is ever wired
|
|
28
|
-
// here, it MUST get a distinct type string (e.g. "CallSandboxRun").
|
|
29
|
-
parseAbiItem("event SandboxRun(uint256 indexed pid, address indexed sandbox, uint256 funding)")
|
|
19
|
+
parseAbiItem("event DepositorRemoved(address indexed depositor)")
|
|
30
20
|
];
|
|
31
21
|
var GOVERNOR_EVENTS = [
|
|
32
22
|
parseAbiItem("event ProposalCreated(uint256 indexed proposalId, address indexed proposer, address indexed vault, uint256 performanceFeeBps, uint256 strategyDuration, uint256 executeCallCount, uint256 settlementCallCount, string metadataURI)"),
|
|
33
23
|
parseAbiItem("event VoteCast(uint256 indexed proposalId, address indexed voter, uint8 support, uint256 weight)"),
|
|
34
24
|
parseAbiItem("event ProposalExecuted(uint256 indexed proposalId, address indexed vault, uint256 capitalSnapshot)"),
|
|
35
25
|
parseAbiItem("event ProposalSettled(uint256 indexed proposalId, address indexed vault, int256 pnl, uint256 performanceFee, uint256 duration)"),
|
|
36
|
-
parseAbiItem("event ProposalCancelled(uint256 indexed proposalId, address indexed cancelledBy)")
|
|
37
|
-
// ISyndicateGovernor.SandboxPayloadStored — a proposeWithSandbox payload was
|
|
38
|
-
// stored for proposalId. The call set itself is not in the log (read it via
|
|
39
|
-
// `sandboxPayload`); the counts are the cheap off-chain signal.
|
|
40
|
-
parseAbiItem("event SandboxPayloadStored(uint256 indexed proposalId, uint256 funding, uint256 callCount, uint256 tokenCount)")
|
|
26
|
+
parseAbiItem("event ProposalCancelled(uint256 indexed proposalId, address indexed cancelledBy)")
|
|
41
27
|
];
|
|
42
28
|
var GUARDIAN_REGISTRY_EVENTS = [
|
|
43
|
-
parseAbiItem("event ReviewOpened(uint256 indexed proposalId, uint128 totalStakeAtOpen)"),
|
|
44
|
-
parseAbiItem("event ReviewResolved(uint256 indexed proposalId, bool blocked, uint256 slashedAmount)")
|
|
29
|
+
parseAbiItem("event ReviewOpened(address indexed governor, uint256 indexed proposalId, uint128 totalStakeAtOpen)"),
|
|
30
|
+
parseAbiItem("event ReviewResolved(address indexed governor, uint256 indexed proposalId, bool blocked, uint256 slashedAmount)")
|
|
45
31
|
];
|
|
46
32
|
var STAKED_WOOD_EVENTS = [
|
|
47
33
|
parseAbiItem("event GuardianSlashed(bytes32 indexed reviewKey, address indexed approver, uint256 ownSlash, uint256 delegatedSlash)")
|
|
@@ -114,7 +100,7 @@ async function getGovernorEvents(governorAddress, vaultAddress, fromBlock, toBlo
|
|
|
114
100
|
return logToChainEvent(log, eventName);
|
|
115
101
|
});
|
|
116
102
|
}
|
|
117
|
-
async function getGuardianRegistryEvents(registryAddress, fromBlock, toBlock) {
|
|
103
|
+
async function getGuardianRegistryEvents(registryAddress, fromBlock, toBlock, governor) {
|
|
118
104
|
if (registryAddress === "0x0000000000000000000000000000000000000000") {
|
|
119
105
|
return [];
|
|
120
106
|
}
|
|
@@ -124,7 +110,12 @@ async function getGuardianRegistryEvents(registryAddress, fromBlock, toBlock) {
|
|
|
124
110
|
fromBlock,
|
|
125
111
|
toBlock
|
|
126
112
|
});
|
|
127
|
-
|
|
113
|
+
const want = governor?.toLowerCase();
|
|
114
|
+
return logs.filter((log) => {
|
|
115
|
+
if (!want) return true;
|
|
116
|
+
const args = log.args;
|
|
117
|
+
return !args?.governor || args.governor.toLowerCase() === want;
|
|
118
|
+
}).map((log) => {
|
|
128
119
|
const eventName = log.eventName || "UnknownGuardianRegistryEvent";
|
|
129
120
|
return logToChainEvent(log, eventName);
|
|
130
121
|
});
|
|
@@ -221,4 +212,4 @@ export {
|
|
|
221
212
|
getCurrentBlock,
|
|
222
213
|
enrichProposalEvents
|
|
223
214
|
};
|
|
224
|
-
//# sourceMappingURL=chunk-
|
|
215
|
+
//# sourceMappingURL=chunk-R6F57QQF.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/events.ts"],"sourcesContent":["/**\n * On-chain event reader — fetches vault and governor events via viem getLogs.\n *\n * Uses HTTP RPC (no WebSocket needed). Block ranges are capped at 10,000\n * per call to avoid RPC timeouts (~83 minutes on Base at 2 blocks/sec).\n */\n\nimport type { Address, Log } from \"viem\";\nimport { parseAbiItem } from \"viem\";\nimport { getPublicClient } from \"./client.js\";\nimport { getProposal, PROPOSAL_STATES } from \"./governor.js\";\nimport { resolveMetadataSummary } from \"./ipfs.js\";\n\nconst MAX_BLOCK_RANGE = 10_000n;\n\n// ── Event signatures (parseAbiItem format for getLogs) ──\n\nexport const VAULT_EVENTS = [\n parseAbiItem(\"event AgentRegistered(uint256 indexed agentId, address indexed agentAddress)\"),\n parseAbiItem(\"event AgentRemoved(address indexed agentAddress)\"),\n parseAbiItem(\"event DepositorApproved(address indexed depositor)\"),\n parseAbiItem(\"event DepositorRemoved(address indexed depositor)\"),\n] as const;\n\nexport const GOVERNOR_EVENTS = [\n parseAbiItem(\"event ProposalCreated(uint256 indexed proposalId, address indexed proposer, address indexed vault, uint256 performanceFeeBps, uint256 strategyDuration, uint256 executeCallCount, uint256 settlementCallCount, string metadataURI)\"),\n parseAbiItem(\"event VoteCast(uint256 indexed proposalId, address indexed voter, uint8 support, uint256 weight)\"),\n parseAbiItem(\"event ProposalExecuted(uint256 indexed proposalId, address indexed vault, uint256 capitalSnapshot)\"),\n parseAbiItem(\"event ProposalSettled(uint256 indexed proposalId, address indexed vault, int256 pnl, uint256 performanceFee, uint256 duration)\"),\n parseAbiItem(\"event ProposalCancelled(uint256 indexed proposalId, address indexed cancelledBy)\"),\n] as const;\n\n// IGuardianRegistry — guardian review lifecycle for proposals.\n// Every proposal-keyed event leads with `address indexed governor`: the\n// registry serves every per-vault governor, so a proposalId alone is\n// ambiguous. Dropping the governor topic here silently mixes reviews from\n// unrelated vaults into one stream.\nexport const GUARDIAN_REGISTRY_EVENTS = [\n parseAbiItem(\"event ReviewOpened(address indexed governor, uint256 indexed proposalId, uint128 totalStakeAtOpen)\"),\n parseAbiItem(\"event ReviewResolved(address indexed governor, uint256 indexed proposalId, bool blocked, uint256 slashedAmount)\"),\n] as const;\n\n// StakedWood — approver slashes for blocked proposals.\nexport const STAKED_WOOD_EVENTS = [\n parseAbiItem(\"event GuardianSlashed(bytes32 indexed reviewKey, address indexed approver, uint256 ownSlash, uint256 delegatedSlash)\"),\n] as const;\n\n/** Normalized event returned by the session check. */\nexport interface ChainEvent {\n source: \"chain\";\n type: string;\n block: number;\n tx: string;\n args: Record<string, string>;\n}\n\nfunction logToChainEvent(log: Log, eventName: string): ChainEvent {\n const args: Record<string, string> = {};\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const decoded = (log as any).args;\n if (decoded) {\n for (const [key, value] of Object.entries(decoded)) {\n args[key] = String(value);\n }\n }\n\n return {\n source: \"chain\",\n type: eventName,\n block: Number(log.blockNumber),\n tx: log.transactionHash || \"\",\n args,\n };\n}\n\n/**\n * Fetch events in chunks to stay within RPC limits.\n * Returns all logs from `fromBlock` to `toBlock` inclusive.\n * Exported for reuse (e.g. vault.ts getNetDeposited's 0→latest scan).\n */\nexport async function getLogsChunked(params: {\n address: Address;\n events: readonly ReturnType<typeof parseAbiItem>[];\n fromBlock: bigint;\n toBlock: bigint;\n}): Promise<Log[]> {\n const client = getPublicClient();\n const { address, events, fromBlock, toBlock } = params;\n\n const allLogs: Log[] = [];\n let cursor = fromBlock;\n\n while (cursor <= toBlock) {\n const end =\n cursor + MAX_BLOCK_RANGE - 1n > toBlock\n ? toBlock\n : cursor + MAX_BLOCK_RANGE - 1n;\n\n const logs = await client.getLogs({\n address,\n events: events as never,\n fromBlock: cursor,\n toBlock: end,\n });\n\n allLogs.push(...logs);\n cursor = end + 1n;\n }\n\n return allLogs;\n}\n\n/** Fetch vault events (AgentRegistered, Ragequit, etc.) */\nexport async function getVaultEvents(\n vaultAddress: Address,\n fromBlock: bigint,\n toBlock: bigint,\n): Promise<ChainEvent[]> {\n const logs = await getLogsChunked({\n address: vaultAddress,\n events: VAULT_EVENTS,\n fromBlock,\n toBlock,\n });\n\n return logs.map((log) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const eventName = (log as any).eventName || \"UnknownVaultEvent\";\n return logToChainEvent(log, eventName);\n });\n}\n\n/** Fetch governor events filtered to a specific vault. */\nexport async function getGovernorEvents(\n governorAddress: Address,\n vaultAddress: Address,\n fromBlock: bigint,\n toBlock: bigint,\n): Promise<ChainEvent[]> {\n if (governorAddress === \"0x0000000000000000000000000000000000000000\") {\n return []; // Governor not deployed yet\n }\n\n const logs = await getLogsChunked({\n address: governorAddress,\n events: GOVERNOR_EVENTS,\n fromBlock,\n toBlock,\n });\n\n // Filter governor events to only those involving our vault\n return logs\n .filter((log) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const args = (log as any).args;\n if (!args) return true;\n // ProposalCreated, ProposalExecuted, ProposalSettled have `vault` in args\n if (args.vault) {\n return (args.vault as string).toLowerCase() === vaultAddress.toLowerCase();\n }\n // VoteCast, ProposalCancelled don't have vault — include them\n // (agents care about all votes/cancellations on their governor)\n return true;\n })\n .map((log) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const eventName = (log as any).eventName || \"UnknownGovernorEvent\";\n return logToChainEvent(log, eventName);\n });\n}\n\n/**\n * Fetch guardian review events (ReviewOpened, ReviewResolved) from the\n * GuardianRegistry. Returns [] when the registry is not deployed (zero address).\n *\n * The registry serves every per-vault governor, and a proposalId is only\n * unique within one — so pass `governor` to keep another vault's reviews out\n * of the stream. Omitting it returns every review on the chain's registry.\n */\nexport async function getGuardianRegistryEvents(\n registryAddress: Address,\n fromBlock: bigint,\n toBlock: bigint,\n governor?: Address,\n): Promise<ChainEvent[]> {\n if (registryAddress === \"0x0000000000000000000000000000000000000000\") {\n return []; // GuardianRegistry not deployed on this chain\n }\n\n const logs = await getLogsChunked({\n address: registryAddress,\n events: GUARDIAN_REGISTRY_EVENTS,\n fromBlock,\n toBlock,\n });\n\n const want = governor?.toLowerCase();\n return logs\n .filter((log) => {\n if (!want) return true;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const args = (log as any).args;\n return !args?.governor || (args.governor as string).toLowerCase() === want;\n })\n .map((log) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const eventName = (log as any).eventName || \"UnknownGuardianRegistryEvent\";\n return logToChainEvent(log, eventName);\n });\n}\n\n/**\n * Fetch guardian slash events (GuardianSlashed) from StakedWood.\n * Returns [] when sWOOD is not deployed (zero address).\n */\nexport async function getStakedWoodEvents(\n stakedWoodAddress: Address,\n fromBlock: bigint,\n toBlock: bigint,\n): Promise<ChainEvent[]> {\n if (stakedWoodAddress === \"0x0000000000000000000000000000000000000000\") {\n return []; // StakedWood not deployed on this chain\n }\n\n const logs = await getLogsChunked({\n address: stakedWoodAddress,\n events: STAKED_WOOD_EVENTS,\n fromBlock,\n toBlock,\n });\n\n return logs.map((log) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const eventName = (log as any).eventName || \"UnknownStakedWoodEvent\";\n return logToChainEvent(log, eventName);\n });\n}\n\n/** Get current block number from the RPC. */\nexport async function getCurrentBlock(): Promise<bigint> {\n const client = getPublicClient();\n return client.getBlockNumber();\n}\n\n// ── Proposal event enrichment ──\n\nconst PROPOSAL_EVENT_TYPES = new Set([\n \"ProposalCreated\",\n \"VoteCast\",\n \"ProposalExecuted\",\n \"ProposalSettled\",\n \"ProposalCancelled\",\n]);\n\n/**\n * Enrich proposal-related events with IPFS metadata (name, description)\n * and current on-chain state. Best-effort — events are returned un-enriched\n * if RPC or IPFS calls fail.\n *\n * `vault` identifies which per-vault governor to read proposal state from\n * (proposal IDs are scoped to a vault's governor in the per-vault design).\n *\n * An optional metadataCache avoids redundant IPFS fetches across poll cycles\n * in streaming mode (proposal metadata is immutable once pinned).\n */\nexport async function enrichProposalEvents(\n vault: Address,\n events: ChainEvent[],\n metadataCache?: Map<string, { name: string; description: string }>,\n): Promise<ChainEvent[]> {\n const cache = metadataCache ?? new Map<string, { name: string; description: string }>();\n\n const proposalEvents = events.filter((e) => PROPOSAL_EVENT_TYPES.has(e.type));\n if (proposalEvents.length === 0) return events;\n\n // Collect unique proposalIds and their metadata sources\n const idsNeedingLookup = new Set<string>();\n const createdURIs = new Map<string, string>(); // proposalId → metadataURI from event args\n\n for (const event of proposalEvents) {\n const pid = event.args.proposalId;\n if (!pid) continue;\n\n if (event.type === \"ProposalCreated\" && event.args.metadataURI) {\n createdURIs.set(pid, event.args.metadataURI);\n } else if (!cache.has(pid)) {\n idsNeedingLookup.add(pid);\n }\n }\n\n // Fetch on-chain proposal data for non-Created events (parallel, deduplicated)\n const proposalData = new Map<string, { metadataURI: string; state: number }>();\n\n await Promise.all(\n Array.from(idsNeedingLookup).map(async (pid) => {\n try {\n const p = await getProposal(vault, BigInt(pid));\n proposalData.set(pid, { metadataURI: p.metadataURI, state: p.state });\n } catch {\n // RPC failure — skip enrichment for this proposalId\n }\n }),\n );\n\n // Resolve IPFS metadata (parallel, deduplicated, uses cache)\n const allURIs = new Map<string, string>();\n for (const [pid, uri] of createdURIs) allURIs.set(pid, uri);\n for (const [pid, data] of proposalData) {\n if (!allURIs.has(pid)) allURIs.set(pid, data.metadataURI);\n }\n\n await Promise.all(\n Array.from(allURIs.entries()).map(async ([pid, uri]) => {\n if (cache.has(pid) || !uri) return;\n const summary = await resolveMetadataSummary(uri);\n if (summary) cache.set(pid, summary);\n }),\n );\n\n // Inject enrichment fields into event args\n return events.map((event) => {\n if (!PROPOSAL_EVENT_TYPES.has(event.type)) return event;\n const pid = event.args.proposalId;\n if (!pid) return event;\n\n const meta = cache.get(pid);\n const pData = proposalData.get(pid);\n const enrichedArgs = { ...event.args };\n\n if (meta) {\n enrichedArgs.proposalName = meta.name;\n enrichedArgs.proposalDescription = meta.description;\n }\n\n if (event.type === \"ProposalCreated\") {\n enrichedArgs.proposalState = \"Pending\";\n } else if (pData) {\n enrichedArgs.proposalState = PROPOSAL_STATES[pData.state] || \"Unknown\";\n }\n\n return { ...event, args: enrichedArgs };\n });\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import {
|
|
2
2
|
SHERWOOD
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-UOIAY6ZG.js";
|
|
4
4
|
import {
|
|
5
5
|
getAccount,
|
|
6
6
|
getPublicClient,
|
|
7
7
|
waitForReceipt,
|
|
8
8
|
writeContractWithRetry
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-MIAMGVZ4.js";
|
|
10
10
|
import {
|
|
11
11
|
getChain
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-G3FUEM5N.js";
|
|
13
13
|
import {
|
|
14
14
|
SYNDICATE_FACTORY_ABI
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-J2IZWAEW.js";
|
|
16
16
|
|
|
17
17
|
// src/lib/factory.ts
|
|
18
18
|
import { decodeEventLog } from "viem";
|
|
@@ -144,4 +144,4 @@ export {
|
|
|
144
144
|
getActiveFunds,
|
|
145
145
|
updateMetadata
|
|
146
146
|
};
|
|
147
|
-
//# sourceMappingURL=chunk-
|
|
147
|
+
//# sourceMappingURL=chunk-TTF5TDRV.js.map
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getNetwork
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
|
|
5
|
-
// src/lib/addresses.ts
|
|
6
|
-
import { isAddress } from "viem";
|
|
3
|
+
} from "./chunk-G3FUEM5N.js";
|
|
7
4
|
|
|
8
5
|
// src/lib/address-overrides.ts
|
|
9
6
|
import { readFileSync } from "fs";
|
|
@@ -69,6 +66,116 @@ function overridesFor(registry) {
|
|
|
69
66
|
return out;
|
|
70
67
|
}
|
|
71
68
|
|
|
69
|
+
// src/lib/fork-tokens.ts
|
|
70
|
+
var ROBINHOOD_FORK_STOCKS = {
|
|
71
|
+
AAPL: {
|
|
72
|
+
address: "0xaF3D76f1834A1d425780943C99Ea8A608f8a93f9",
|
|
73
|
+
feed: "0x6B22A786bAa607d76728168703a39Ea9C99f2cD0",
|
|
74
|
+
route: "v4:3000:60",
|
|
75
|
+
eligible: true,
|
|
76
|
+
quotedOut: "0.30994905",
|
|
77
|
+
feedDeviationBps: 252
|
|
78
|
+
},
|
|
79
|
+
TSLA: {
|
|
80
|
+
address: "0x322F0929c4625eD5bAd873c95208D54E1c003b2d",
|
|
81
|
+
feed: "0x4A1166a659A55625345e9515b32adECea5547C38",
|
|
82
|
+
route: "v4:3000:60",
|
|
83
|
+
eligible: true,
|
|
84
|
+
quotedOut: "0.27501216",
|
|
85
|
+
feedDeviationBps: 265
|
|
86
|
+
},
|
|
87
|
+
NVDA: {
|
|
88
|
+
address: "0xd0601CE157Db5bdC3162BbaC2a2C8aF5320D9EEC",
|
|
89
|
+
feed: "0x379EC4f7C378F34a1B47E4F3cbeBCbAC3E8E9F15",
|
|
90
|
+
route: "v4:3000:60",
|
|
91
|
+
eligible: true,
|
|
92
|
+
quotedOut: "0.43142676",
|
|
93
|
+
feedDeviationBps: 199
|
|
94
|
+
},
|
|
95
|
+
MSFT: {
|
|
96
|
+
address: "0xe93237C50D904957Cf27E7B1133b510C669c2e74",
|
|
97
|
+
feed: "0x45C3C877C15E6BA2EBB19eA114Ea508d14C1Af2E",
|
|
98
|
+
route: "v4:3000:60",
|
|
99
|
+
eligible: true,
|
|
100
|
+
quotedOut: "0.19882872",
|
|
101
|
+
feedDeviationBps: -18
|
|
102
|
+
},
|
|
103
|
+
AMZN: {
|
|
104
|
+
address: "0x12f190a9F9d7D37a250758b26824B97CE941bF54",
|
|
105
|
+
feed: "0xD5a1508ceD74c084eBf3cBe853e2C968fB2a651C",
|
|
106
|
+
route: "v4:3000:60",
|
|
107
|
+
eligible: true,
|
|
108
|
+
quotedOut: "0.37998363",
|
|
109
|
+
feedDeviationBps: 264
|
|
110
|
+
},
|
|
111
|
+
META: {
|
|
112
|
+
address: "0xc0D6457C16Cc70d6790Dd43521C899C87ce02f35",
|
|
113
|
+
feed: "0x7C38C00C30BEe9378381E7B6135d7283356D71b1",
|
|
114
|
+
route: "v4:3000:60",
|
|
115
|
+
eligible: false,
|
|
116
|
+
quotedOut: "0.16185932",
|
|
117
|
+
feedDeviationBps: 829,
|
|
118
|
+
note: "Quotes, but the pool sits 8.3% above the frozen META/USD feed (v3 agrees: +8.2%), past the sim's 5% buy floor and near the contract's 10% ceiling. Excluded from generated baskets until the pool or feed is re-based."
|
|
119
|
+
},
|
|
120
|
+
AMD: {
|
|
121
|
+
address: "0x86923f96303D656E4aa86D9d42D1e57ad2023fdC",
|
|
122
|
+
feed: "0x943A29E7ae51A4798823ca9eEd2ed533B2A22C72",
|
|
123
|
+
// The fee-3000 pool does NOT exist — only the 10000/200 tier quotes. This
|
|
124
|
+
// is the case that makes guessing a fee tier a bug.
|
|
125
|
+
route: "v4:10000:200",
|
|
126
|
+
eligible: true,
|
|
127
|
+
quotedOut: "0.20887416",
|
|
128
|
+
feedDeviationBps: 53
|
|
129
|
+
},
|
|
130
|
+
SPY: {
|
|
131
|
+
address: "0x117cc2133c37B721F49dE2A7a74833232B3B4C0C",
|
|
132
|
+
feed: "0x319724394D3A0e3669269846abE664Cd621f9f6A",
|
|
133
|
+
route: "v4:3000:60",
|
|
134
|
+
eligible: true,
|
|
135
|
+
quotedOut: "0.12913164",
|
|
136
|
+
feedDeviationBps: 63
|
|
137
|
+
},
|
|
138
|
+
QQQ: {
|
|
139
|
+
address: "0xD5f3879160bc7c32ebb4dC785F8a4F505888de68",
|
|
140
|
+
feed: "0x80901d846d5D7B030F26B480776EE3b29374C2ae",
|
|
141
|
+
// A 10000/200 pool also exists but quoted +48.8% vs feed (near-empty) —
|
|
142
|
+
// never route QQQ through it.
|
|
143
|
+
route: "v4:3000:60",
|
|
144
|
+
eligible: true,
|
|
145
|
+
quotedOut: "0.13873445",
|
|
146
|
+
feedDeviationBps: 23
|
|
147
|
+
},
|
|
148
|
+
SLV: {
|
|
149
|
+
address: "0x411eFb0E7f985935DAec3D4C3ebaEa0d0AD7D89f",
|
|
150
|
+
feed: "0x209b73908e92Ae021826eD79609845451Ecba2ce",
|
|
151
|
+
route: "v3:500",
|
|
152
|
+
v3Only: true,
|
|
153
|
+
eligible: false,
|
|
154
|
+
quotedOut: "1.66443692",
|
|
155
|
+
feedDeviationBps: -389,
|
|
156
|
+
note: "No v4 USDG pool on any probed tier; only Uniswap v3 quotes (500/3000/10000 all do, 500 best). This vnet's v3 position manager is corrupted, so the v3 swap leg is unverified end to end \u2014 excluded from generated baskets."
|
|
157
|
+
},
|
|
158
|
+
GOOGL: {
|
|
159
|
+
address: "0x2e0847E8910a9732eB3fb1bb4b70a580ADAD4FE3",
|
|
160
|
+
feed: "0xF6f373a037c30F0e5010d854385cA89185AE638b",
|
|
161
|
+
route: "v4:3000:60",
|
|
162
|
+
eligible: true,
|
|
163
|
+
quotedOut: "0.29346562",
|
|
164
|
+
feedDeviationBps: 11
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
var ROBINHOOD_FORK_STOCK_SYMBOLS = Object.keys(ROBINHOOD_FORK_STOCKS);
|
|
168
|
+
function forkStockAddresses() {
|
|
169
|
+
return Object.fromEntries(
|
|
170
|
+
ROBINHOOD_FORK_STOCK_SYMBOLS.map((s) => [s, ROBINHOOD_FORK_STOCKS[s].address])
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
function forkStockFeeds() {
|
|
174
|
+
return Object.fromEntries(
|
|
175
|
+
ROBINHOOD_FORK_STOCK_SYMBOLS.map((s) => [`${s}_USD_FEED`, ROBINHOOD_FORK_STOCKS[s].feed])
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
|
|
72
179
|
// src/lib/addresses.ts
|
|
73
180
|
var ZERO = "0x0000000000000000000000000000000000000000";
|
|
74
181
|
var ROBINHOOD_TESTNET_TOKENS = {
|
|
@@ -92,7 +199,17 @@ var ROBINHOOD_TESTNET_TOKENS = {
|
|
|
92
199
|
AMZN: "0x5884aD2f920c162CFBbACc88C9C51AA75eC09E02",
|
|
93
200
|
PLTR: "0x1FBE1a0e43594b3455993B5dE5Fd0A7A266298d0",
|
|
94
201
|
NFLX: "0x3b8262A63d25f0477c4DDE23F83cfe22Cb768C93",
|
|
95
|
-
AMD: "0x71178BAc73cBeb415514eB542a8995b82669778d"
|
|
202
|
+
AMD: "0x71178BAc73cBeb415514eB542a8995b82669778d",
|
|
203
|
+
// Stocks the mainnet fork carries and the testnet does not (lib/fork-tokens.ts).
|
|
204
|
+
// Keyed here as ZERO so the token-shape type covers both chains.
|
|
205
|
+
AAPL: ZERO,
|
|
206
|
+
NVDA: ZERO,
|
|
207
|
+
MSFT: ZERO,
|
|
208
|
+
META: ZERO,
|
|
209
|
+
SPY: ZERO,
|
|
210
|
+
QQQ: ZERO,
|
|
211
|
+
SLV: ZERO,
|
|
212
|
+
GOOGL: ZERO
|
|
96
213
|
};
|
|
97
214
|
var ROBINHOOD_TESTNET_MOONWELL = {
|
|
98
215
|
COMPTROLLER: ZERO,
|
|
@@ -106,7 +223,7 @@ var ROBINHOOD_TESTNET_MOONWELL = {
|
|
|
106
223
|
};
|
|
107
224
|
var ROBINHOOD_TESTNET_UNISWAP = {
|
|
108
225
|
SWAP_ROUTER: "0x3Ce954107b1A675826B33bF23060Dd655e3758fE",
|
|
109
|
-
QUOTER_V2: "
|
|
226
|
+
QUOTER_V2: "0xb06788F027268a9A06c3AD41a88559530D2E54b1",
|
|
110
227
|
SWAP_ADAPTER: "0x4fc3492117cC3bbcE0b210D22a8DC244f9d86490"
|
|
111
228
|
};
|
|
112
229
|
var ROBINHOOD_TESTNET_SYNTHRA = {
|
|
@@ -115,35 +232,13 @@ var ROBINHOOD_TESTNET_SYNTHRA = {
|
|
|
115
232
|
FACTORY: "0x911b4000D3422F482F4062a913885f7b035382Df"
|
|
116
233
|
};
|
|
117
234
|
var ROBINHOOD_TESTNET_CHAINLINK = {
|
|
118
|
-
|
|
119
|
-
|
|
235
|
+
WSTETH_ETH_FEED: ZERO,
|
|
236
|
+
// Tokenized-equity push feeds exist only on the mainnet fork. Keyed as ZERO
|
|
237
|
+
// so the registry shape covers both chains and the fork's `<SYM>_USD_FEED`
|
|
238
|
+
// auto-resolve (template-encoder.ts) has a slot.
|
|
239
|
+
...noneOf(forkStockFeeds())
|
|
120
240
|
};
|
|
121
241
|
var ROBINHOOD_STOCK_ROUTES = {};
|
|
122
|
-
var ROBINHOOD_NON_EQUITY_FEEDS = /* @__PURE__ */ new Set(["ETH", "WETH", "BTC", "LINK", "USDG", "USDC"]);
|
|
123
|
-
function isRobinhoodEquityFeed(symbol) {
|
|
124
|
-
return !ROBINHOOD_NON_EQUITY_FEEDS.has(symbol.toUpperCase());
|
|
125
|
-
}
|
|
126
|
-
function symbolForTokenAddress(address, tokens) {
|
|
127
|
-
if (!address || address.toLowerCase() === ZERO.toLowerCase()) return void 0;
|
|
128
|
-
const want = address.toLowerCase();
|
|
129
|
-
for (const [symbol, addr] of Object.entries(tokens)) {
|
|
130
|
-
if (addr && addr !== ZERO && addr.toLowerCase() === want) return symbol;
|
|
131
|
-
}
|
|
132
|
-
return void 0;
|
|
133
|
-
}
|
|
134
|
-
function robinhoodEquityMaxAge(tokenSpec, tokens, equityMaxAgeSeconds) {
|
|
135
|
-
let symbol;
|
|
136
|
-
if (isAddress(tokenSpec)) {
|
|
137
|
-
symbol = symbolForTokenAddress(tokenSpec, tokens);
|
|
138
|
-
if (!symbol) return { maxPriceAge: 0, unknownAddress: true };
|
|
139
|
-
} else {
|
|
140
|
-
symbol = tokenSpec;
|
|
141
|
-
}
|
|
142
|
-
return {
|
|
143
|
-
maxPriceAge: isRobinhoodEquityFeed(symbol) ? equityMaxAgeSeconds : 0,
|
|
144
|
-
unknownAddress: false
|
|
145
|
-
};
|
|
146
|
-
}
|
|
147
242
|
var ROBINHOOD_TESTNET_INFRA = {
|
|
148
243
|
MULTICALL3: "0xcA11bde05977b3631167028862bE2a173976CA11"
|
|
149
244
|
// Deterministic, same everywhere
|
|
@@ -172,7 +267,6 @@ var ROBINHOOD_TESTNET_SHERWOOD = {
|
|
|
172
267
|
PROTOCOL_CONFIG: "0xC104Eb6a522d6718cA28F344B2373B29d57FF2E0",
|
|
173
268
|
PRICE_ROUTER: "0xDd302ffcfA08071780eC1A2f12BccFB9ba6b6731",
|
|
174
269
|
TIER_REGISTRY: "0x99b8068Dc0F6093466964D581f72d947e3e380DB",
|
|
175
|
-
CALL_SANDBOX_IMPL: "0xf09f6AF7DeBB964eD731376C9Af389F2Ce3d872A",
|
|
176
270
|
// Not in chains/46630.json (econ-security stack not deployed there yet).
|
|
177
271
|
EXPOSURE_LEDGER: ZERO,
|
|
178
272
|
PROPOSER_BOND_ESCROW: ZERO,
|
|
@@ -224,43 +318,40 @@ var ROBINHOOD_FORK_TOKENS = {
|
|
|
224
318
|
cbBTC: ZERO,
|
|
225
319
|
DAI: ZERO,
|
|
226
320
|
AERO: ZERO,
|
|
227
|
-
TSLA: "0x322F0929c4625eD5bAd873c95208D54E1c003b2d",
|
|
228
|
-
AMZN: "0x12f190a9F9d7D37a250758b26824B97CE941bF54",
|
|
229
321
|
PLTR: ZERO,
|
|
230
322
|
NFLX: ZERO,
|
|
231
|
-
|
|
323
|
+
...forkStockAddresses()
|
|
232
324
|
};
|
|
233
325
|
var ROBINHOOD_FORK_UNISWAP = {
|
|
234
326
|
SWAP_ROUTER: "0xcaf681a66d020601342297493863e78c959e5cb2",
|
|
235
327
|
QUOTER_V2: "0x33e885ed0ec9bf04ecfb19341582aadcb4c8a9e7",
|
|
236
|
-
SWAP_ADAPTER: "
|
|
328
|
+
SWAP_ADAPTER: "0x54E6A7af53143556973493fDeC9d7837A77c67eF"
|
|
237
329
|
};
|
|
238
330
|
var ROBINHOOD_FORK_CHAINLINK = {
|
|
239
|
-
|
|
240
|
-
|
|
331
|
+
WSTETH_ETH_FEED: ZERO,
|
|
332
|
+
...forkStockFeeds()
|
|
241
333
|
};
|
|
242
334
|
var ROBINHOOD_FORK_SHERWOOD = {
|
|
243
|
-
FACTORY: "
|
|
335
|
+
FACTORY: "0x619af1488F32B4797f6faDa3C3a8De72a5B693E0",
|
|
244
336
|
GOVERNOR: ZERO,
|
|
245
337
|
// per-vault — always factory.governorOf(vault)
|
|
246
|
-
GUARDIAN_REGISTRY: "
|
|
247
|
-
STAKED_WOOD: "
|
|
338
|
+
GUARDIAN_REGISTRY: "0xD8F9E7446E6d6c02198AAaF674A0C5e3d5D1BF72",
|
|
339
|
+
STAKED_WOOD: "0xdDf2B4C52B9575e0e6D03a3A57D75D06a4a9e203",
|
|
248
340
|
WOOD_TOKEN: "0xF8BC08092C06dB6148114DCf82AF881F1085f92b",
|
|
249
|
-
STRATEGY_FACTORY: "
|
|
341
|
+
STRATEGY_FACTORY: "0xb06788F027268a9A06c3AD41a88559530D2E54b1",
|
|
250
342
|
MERKL_DISTRIBUTOR: ZERO,
|
|
251
343
|
// Guardian-era contracts from sherwood-protocol/chains/9994663.json (SHE-93).
|
|
252
|
-
VAULT_IMPL: "
|
|
253
|
-
BATCH_EXECUTOR_LIB: "
|
|
254
|
-
GOVERNOR_BEACON: "
|
|
255
|
-
PROTOCOL_CONFIG: "
|
|
256
|
-
// Not in chains/9994663.json (no PriceRouter
|
|
344
|
+
VAULT_IMPL: "0xdaB4707c9997a84e931FE98F4688adaFc70b6B95",
|
|
345
|
+
BATCH_EXECUTOR_LIB: "0x899FC2Cac572F64A233344115b488E71E0044f34",
|
|
346
|
+
GOVERNOR_BEACON: "0x3CF45eFE9fBDdd6cB749384Bf5c1bA5Ec96af05d",
|
|
347
|
+
PROTOCOL_CONFIG: "0x8aDb5810B5bF8B9149BE3Ca45Cb441818a9679bB",
|
|
348
|
+
// Not in chains/9994663.json (no PriceRouter on the fork).
|
|
257
349
|
PRICE_ROUTER: ZERO,
|
|
258
|
-
TIER_REGISTRY: "
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
TOKEN_COURT: "0x5DC603881f5d77f41bbd4202F1d518263Dfd497f"
|
|
350
|
+
TIER_REGISTRY: "0x4614f058920941A0a9a852e62485fbDE692D75E1",
|
|
351
|
+
EXPOSURE_LEDGER: "0x99D789E7C8E65dB5597dCa692F082B47BE30AB33",
|
|
352
|
+
PROPOSER_BOND_ESCROW: "0x7d25058c891d3AC5C8bc8Da6aA937DFeE648B5cF",
|
|
353
|
+
CHALLENGE_GAME: "0x7046FececcA6c0f5E66Cc998099593ae71A1bbee",
|
|
354
|
+
TOKEN_COURT: "0xC30bA62727be65fd867385Ce27Ff7C78bd66A897"
|
|
264
355
|
};
|
|
265
356
|
var ROBINHOOD_FORK_STRATEGY_TEMPLATES = {
|
|
266
357
|
MOONWELL_SUPPLY: ZERO,
|
|
@@ -270,7 +361,7 @@ var ROBINHOOD_FORK_STRATEGY_TEMPLATES = {
|
|
|
270
361
|
MAMO_YIELD: ZERO,
|
|
271
362
|
HYPERLIQUID_PERP: ZERO,
|
|
272
363
|
HYPERLIQUID_GRID: ZERO,
|
|
273
|
-
PORTFOLIO: "
|
|
364
|
+
PORTFOLIO: "0xAA5872009c527cCb80343E41C52840CEdb095eb0"
|
|
274
365
|
};
|
|
275
366
|
var TOKEN_REGISTRY = {
|
|
276
367
|
"robinhood-testnet": ROBINHOOD_TESTNET_TOKENS,
|
|
@@ -403,7 +494,6 @@ function CHAINLINK() {
|
|
|
403
494
|
|
|
404
495
|
export {
|
|
405
496
|
ROBINHOOD_STOCK_ROUTES,
|
|
406
|
-
robinhoodEquityMaxAge,
|
|
407
497
|
TOKENS,
|
|
408
498
|
MOONWELL,
|
|
409
499
|
UNISWAP,
|
|
@@ -418,4 +508,4 @@ export {
|
|
|
418
508
|
SYNTHRA,
|
|
419
509
|
CHAINLINK
|
|
420
510
|
};
|
|
421
|
-
//# sourceMappingURL=chunk-
|
|
511
|
+
//# sourceMappingURL=chunk-UOIAY6ZG.js.map
|