@sherwoodagent/cli 0.90.0 → 0.90.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{agent-QU2OSWS4.js → agent-LVDMPKHK.js} +9 -9
- package/dist/agent-LVDMPKHK.js.map +1 -0
- package/dist/{chat-PFXIL6WT.js → chat-HS7OIE2Y.js} +8 -8
- package/dist/{chunk-KXUA5BEH.js → chunk-5G4SESMO.js} +47 -8
- package/dist/chunk-5G4SESMO.js.map +1 -0
- package/dist/{chunk-KPTKX226.js → chunk-6H6EFHDS.js} +4 -4
- package/dist/{chunk-ZCRVHITI.js → chunk-7GITFGA4.js} +4 -4
- package/dist/{chunk-WIUPOQNS.js → chunk-D5Y73ITZ.js} +2 -2
- package/dist/{chunk-2SIUEMPV.js → chunk-FS5DXFRG.js} +4 -4
- package/dist/{chunk-74QYNLJE.js → chunk-G3LPD43A.js} +3 -3
- package/dist/{chunk-J3JMMJLN.js → chunk-IDMSU2X4.js} +6 -6
- package/dist/{chunk-KRASHQRB.js → chunk-IXU23PP5.js} +3 -3
- package/dist/{chunk-LIW6K4OJ.js → chunk-JDTTJDGP.js} +2 -2
- package/dist/{chunk-3R57ETXQ.js → chunk-LSY4GYJ2.js} +2 -2
- package/dist/{chunk-DQZJULNP.js → chunk-POTFZJYN.js} +4 -4
- package/dist/{chunk-I7NYU4JB.js → chunk-RYKETWBU.js} +5 -3
- package/dist/{chunk-5XMQQ4LX.js → chunk-V6XUXLJF.js} +4 -4
- package/dist/{chunk-XQHRKFFH.js → chunk-WJWLM5QE.js} +6 -6
- package/dist/{chunk-QUAVAJWE.js → chunk-XJR2YQK3.js} +1 -15
- package/dist/chunk-XJR2YQK3.js.map +1 -0
- package/dist/{client-3BFK7TNL.js → client-4CKVYBRP.js} +4 -4
- package/dist/{config-UZ2GIXAO.js → config-WIHIVOGZ.js} +2 -6
- package/dist/{eas-YTAAJSLU.js → eas-JOU76WZ2.js} +6 -6
- package/dist/{governor-53PNPDCZ.js → governor-4XHJ52H4.js} +6 -6
- package/dist/{identity-M6UIVBNX.js → identity-3BLNFZ42.js} +7 -7
- package/dist/index.js +41 -47
- package/dist/index.js.map +1 -1
- package/dist/{launchpad-LHMBN4TV.js → launchpad-ZVC7Z5JJ.js} +8 -6
- package/dist/{lighter-preflight-R7C6HY3M.js → lighter-preflight-ERF425PP.js} +6 -6
- package/dist/{network-EZ5X2BF7.js → network-XQLQ4MSH.js} +3 -3
- package/dist/{price-PBFF6NFU.js → price-4QVQAIHX.js} +6 -6
- package/dist/{providers-22A42FKP.js → providers-P27BDYZ2.js} +5 -5
- package/dist/{research-ZH34O7YL.js → research-N2R76ELJ.js} +9 -9
- package/dist/{session-GSWEE4M3.js → session-ZIJYGOAT.js} +11 -11
- package/dist/{trade-SHK7GKSI.js → trade-2J555BS7.js} +17 -17
- package/dist/{vault-3T6UHCPE.js → vault-WC7AS7SM.js} +8 -8
- package/dist/{xmtp-EOMKXRTB.js → xmtp-NJXD7T7E.js} +6 -6
- package/package.json +1 -2
- package/dist/agent-QU2OSWS4.js.map +0 -1
- package/dist/chunk-KXUA5BEH.js.map +0 -1
- package/dist/chunk-QUAVAJWE.js.map +0 -1
- /package/dist/{chat-PFXIL6WT.js.map → chat-HS7OIE2Y.js.map} +0 -0
- /package/dist/{chunk-KPTKX226.js.map → chunk-6H6EFHDS.js.map} +0 -0
- /package/dist/{chunk-ZCRVHITI.js.map → chunk-7GITFGA4.js.map} +0 -0
- /package/dist/{chunk-WIUPOQNS.js.map → chunk-D5Y73ITZ.js.map} +0 -0
- /package/dist/{chunk-2SIUEMPV.js.map → chunk-FS5DXFRG.js.map} +0 -0
- /package/dist/{chunk-74QYNLJE.js.map → chunk-G3LPD43A.js.map} +0 -0
- /package/dist/{chunk-J3JMMJLN.js.map → chunk-IDMSU2X4.js.map} +0 -0
- /package/dist/{chunk-KRASHQRB.js.map → chunk-IXU23PP5.js.map} +0 -0
- /package/dist/{chunk-LIW6K4OJ.js.map → chunk-JDTTJDGP.js.map} +0 -0
- /package/dist/{chunk-3R57ETXQ.js.map → chunk-LSY4GYJ2.js.map} +0 -0
- /package/dist/{chunk-DQZJULNP.js.map → chunk-POTFZJYN.js.map} +0 -0
- /package/dist/{chunk-I7NYU4JB.js.map → chunk-RYKETWBU.js.map} +0 -0
- /package/dist/{chunk-5XMQQ4LX.js.map → chunk-V6XUXLJF.js.map} +0 -0
- /package/dist/{chunk-XQHRKFFH.js.map → chunk-WJWLM5QE.js.map} +0 -0
- /package/dist/{client-3BFK7TNL.js.map → client-4CKVYBRP.js.map} +0 -0
- /package/dist/{config-UZ2GIXAO.js.map → config-WIHIVOGZ.js.map} +0 -0
- /package/dist/{eas-YTAAJSLU.js.map → eas-JOU76WZ2.js.map} +0 -0
- /package/dist/{governor-53PNPDCZ.js.map → governor-4XHJ52H4.js.map} +0 -0
- /package/dist/{identity-M6UIVBNX.js.map → identity-3BLNFZ42.js.map} +0 -0
- /package/dist/{launchpad-LHMBN4TV.js.map → launchpad-ZVC7Z5JJ.js.map} +0 -0
- /package/dist/{lighter-preflight-R7C6HY3M.js.map → lighter-preflight-ERF425PP.js.map} +0 -0
- /package/dist/{network-EZ5X2BF7.js.map → network-XQLQ4MSH.js.map} +0 -0
- /package/dist/{price-PBFF6NFU.js.map → price-4QVQAIHX.js.map} +0 -0
- /package/dist/{providers-22A42FKP.js.map → providers-P27BDYZ2.js.map} +0 -0
- /package/dist/{research-ZH34O7YL.js.map → research-N2R76ELJ.js.map} +0 -0
- /package/dist/{session-GSWEE4M3.js.map → session-ZIJYGOAT.js.map} +0 -0
- /package/dist/{trade-SHK7GKSI.js.map → trade-2J555BS7.js.map} +0 -0
- /package/dist/{vault-3T6UHCPE.js.map → vault-WC7AS7SM.js.map} +0 -0
- /package/dist/{xmtp-EOMKXRTB.js.map → xmtp-NJXD7T7E.js.map} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/launchpad.ts"],"sourcesContent":["/**\n * Launchpad — template flags + operator commands.\n *\n * sherwood launchpad status <strategy> launch, reserve, claim window, fee venue\n * sherwood launchpad claim <strategy> take the signer's slice of the reserve\n * sherwood launchpad claim-for <strategy> <holder> pay a holder their slice (permissionless)\n * sherwood launchpad collect-fees <strategy> push accrued creator fees to the vault\n * sherwood launchpad finalize <strategy> graduate + bond a StonkBrokers launch\n *\n * Every write runs its own preflight and refuses before sending a transaction\n * that would revert. Every write honours the global `--calldata-only` flag.\n *\n * WHAT STATUS DELIBERATELY DOES NOT SHOW: a price for the launch token. The\n * template exists to acquire an asset the protocol refuses to price (its\n * settlement never sells the fund token, because that price is movable inside\n * the settling transaction), so this view prints balances and times only.\n */\n\nimport type { Command } from \"commander\";\nimport type { Address, Hex } from \"viem\";\nimport { formatUnits, isAddress } from \"viem\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport type { ChainId } from \"@sherwoodagent/sdk\";\n\nimport {\n getPublicClient,\n getAccount,\n writeContractWithRetry,\n waitForReceipt,\n formatContractError,\n} from \"../lib/client.js\";\nimport { getChain, getExplorerUrl } from \"../lib/network.js\";\nimport { isCalldataOnly, emitCalldata } from \"../lib/calldata.js\";\nimport { LAUNCHPAD_STRATEGY_ABI, LAUNCH_ADAPTER_ABI, SYNDICATE_VAULT_ABI, ERC20_ABI } from \"../lib/abis.js\";\nimport { LAUNCH_ADAPTERS } from \"../lib/addresses.js\";\nimport {\n decodeStonkVenueData,\n decodeSushiVenueData,\n encodeClaimCalldata,\n encodeClaimForCalldata,\n encodeCollectFeesCalldata,\n encodeFinalizeCalldata,\n sameAddr,\n type LaunchVenue,\n} from \"../strategies/launchpad-template.js\";\n\nconst ZERO: Address = \"0x0000000000000000000000000000000000000000\";\nconst ZERO_REF: Hex = \"0x0000000000000000000000000000000000000000000000000000000000000000\";\n\nexport const STRATEGY_STATES = [\"Pending\", \"Executed\", \"Settled\"] as const;\n/** `ILaunchAdapter.LaunchPhase`, by ordinal. */\nexport const LAUNCH_PHASES = [\"None\", \"Curve\", \"Closing\", \"Live\", \"Failed\"] as const;\n\n// ── Template flags (registered on `strategy propose` / `clone` / `init`) ──\n\n/**\n * The Launchpad template's flags. Added to an existing command only where the\n * flag is not already declared, so a flag shared with another template (e.g.\n * `--swap-adapter`, `--max-drawdown-bps`) keeps its original declaration.\n */\nexport const LAUNCHPAD_TEMPLATE_OPTIONS: ReadonlyArray<readonly [string, string]> = [\n [\"--venue <venue>\", \"Launchpad: launch venue, sushi or stonk (default: sushi)\"],\n [\"--asset-in <n>\", \"Launchpad: vault-asset budget for the launch, in human units (required)\"],\n [\"--quote <token>\", \"Launchpad: quote token the fund token is paired against — symbol or address (required)\"],\n [\"--reserve <n>\", \"Launchpad: launch tokens held back for holders' claims, whole tokens or a percent of supply like 10% (required; at most 20%)\"],\n [\"--min-tokens-out <n>\", \"Launchpad: slippage floor on the dev buy, whole launch tokens (required; >= --reserve on Sushi)\"],\n [\"--claim-window <duration>\", \"Launchpad: how long holders may claim, e.g. 7d (required; at most 14d; clamped to the proposal duration − 5m)\"],\n [\"--token-name <name>\", \"Launchpad: launch token name (required)\"],\n [\"--token-symbol <symbol>\", \"Launchpad: launch token symbol (required)\"],\n [\"--min-quote-out <n>\", \"Launchpad: floor on the asset→quote swap, in quote units (default: adapter quote less --settle-slippage-bps)\"],\n [\"--deadline <ts|duration>\", \"Launchpad: venue deadline, unix seconds or a duration from now, 0 for none (default: governor collaboration + voting + execution windows + 1d)\"],\n [\"--settle-slippage-bps <bps>\", \"Settle-time slippage tolerance in bps, 1-1000 (Launchpad: quote conversion; CL: the settle swap, can only be tightened later; default 500)\"],\n [\"--max-fee-in <n>\", \"Launchpad: most the native launch fee may cost, in the token that pays it (default: live cost + 25%; lower than the live cost is refused)\"],\n [\"--quote-swap-route <spec>\", \"Launchpad: asset→quote route, 0x extraData or v3:<fee> / v4:<fee>:<ts> / v4path:… (default: best v3 tier quoted by the swap adapter)\"],\n [\"--fee-swap-route <spec>\", \"Launchpad: quote→fee-token route when the fee token is neither asset nor quote (default: best v3 tier)\"],\n [\"--launch-adapter <address>\", \"Launchpad: launch adapter override (default: LAUNCH_ADAPTERS()[venue])\"],\n [\"--swap-adapter <address>\", \"Swap adapter address\"],\n [\"--liquidity <mode>\", \"Launchpad/Sushi: standard or moon (default: standard)\"],\n [\"--fee-mode <mode>\", \"Launchpad/Sushi: fee disposition, direct, burn or buyback (default: direct; holders is refused)\"],\n [\"--stonk-supply <n>\", \"Launchpad/Stonk: total supply in whole tokens (default: 1000000000)\"],\n [\"--start-mcap <usd>\", \"Launchpad/Stonk: starting market cap in USD (default: 10000)\"],\n [\"--grad-mcap <usd>\", \"Launchpad/Stonk: graduation market cap in USD (default: 100000)\"],\n [\"--start-tax-bps <bps>\", \"Launchpad/Stonk: opening trade tax (default: 1000)\"],\n [\"--tax-decay-bps <bps>\", \"Launchpad/Stonk: tax decay per minute; start/decay × 60 is the curve window (default: 100 → 600s)\"],\n [\"--sells-disabled\", \"Launchpad/Stonk: disable sells on the curve\"],\n [\"--buffer-secs <n>\", \"Launchpad/Stonk: opening anti-snipe shield in seconds (default: 60)\"],\n [\"--unsold-mode <mode>\", \"Launchpad/Stonk: unsold supply at graduation, burn or lp (default: burn)\"],\n [\"--open-ended\", \"Launchpad/Stonk: no closing deadline (requires sells and --post-tax-bps 100-500)\"],\n [\"--post-tax-bps <bps>\", \"Launchpad/Stonk: tax after the decay schedule (default: 0, or 100 with --open-ended)\"],\n [\"--bond-venue <n>\", \"Launchpad/Stonk: AMM bond() mints the locked LP on (default: 0)\"],\n [\"--max-buy-ppm <n>\", \"Launchpad/Stonk: per-wallet buy cap in ppm of supply, 0 = none (default: 0; a cap also caps the fund's dev buy)\"],\n [\n \"--max-drawdown-bps <bps>\",\n \"Declared loss allowance. Launchpad default: --asset-in / totalAssets + 200 bps, because a launch settles as a loss of ~--asset-in; a lower value is refused\",\n ],\n];\n\nexport function addLaunchpadTemplateOptions(cmd: Command): Command {\n for (const [flags, description] of LAUNCHPAD_TEMPLATE_OPTIONS) {\n const long = flags.split(/[ ,]/)[0];\n if (cmd.options.some((o) => o.long === long)) continue;\n cmd.option(flags, description);\n }\n return cmd;\n}\n\n// ── Reads ──\n\nexport interface LaunchpadSnapshot {\n strategy: Address;\n state: (typeof STRATEGY_STATES)[number];\n vault: Address;\n proposer: Address;\n asset: Address;\n quoteToken: Address;\n launchAdapter: Address;\n swapAdapter: Address;\n venue: LaunchVenue | \"unknown\";\n venueData: Hex;\n launchToken: Address;\n launchRef: Hex;\n tokenName: string;\n tokenSymbol: string;\n launchSupply: bigint;\n reserveAmount: bigint;\n reserve: bigint;\n totalClaimed: bigint;\n snap: bigint;\n windowEnd: bigint;\n anyoneSettleAt: bigint;\n assetIn: bigint;\n maxFeeIn: bigint;\n phase: (typeof LAUNCH_PHASES)[number] | null;\n /** Latest block timestamp. */\n now: bigint;\n /** The vault's ERC-5805 clock (timestamp-based on v1). */\n vaultClock: bigint;\n}\n\n/** The subset of a viem PublicClient these commands read through. */\nexport interface LaunchpadReadClient {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n readContract(args: any): Promise<any>;\n getBlock(args?: { blockTag?: \"latest\" }): Promise<{ timestamp: bigint }>;\n}\n\nfunction venueOf(adapter: Address): LaunchVenue | \"unknown\" {\n const a = LAUNCH_ADAPTERS() as Record<string, Address>;\n if (a.SUSHI && a.SUSHI !== ZERO && sameAddr(adapter, a.SUSHI)) return \"sushi\";\n if (a.STONK && a.STONK !== ZERO && sameAddr(adapter, a.STONK)) return \"stonk\";\n return \"unknown\";\n}\n\nexport async function readLaunchpad(strategy: Address, client: LaunchpadReadClient): Promise<LaunchpadSnapshot> {\n const read = (functionName: string, args?: unknown[]) =>\n client.readContract({ address: strategy, abi: LAUNCHPAD_STRATEGY_ABI, functionName, args });\n\n let name: string;\n try {\n name = (await read(\"name\")) as string;\n } catch {\n throw new Error(`${strategy} does not answer name() — not a strategy clone`);\n }\n if (name !== \"Launchpad\") throw new Error(`${strategy} is a \"${name}\" strategy, not Launchpad`);\n\n const [\n stateN, vault, proposer, asset, quoteToken, launchAdapter, swapAdapter, venueData, launchToken, launchRef,\n tokenName, tokenSymbol, launchSupply, reserveAmount, reserve, totalClaimed, snap, windowEnd, anyoneSettleAt,\n assetIn, maxFeeIn, block,\n ] = (await Promise.all([\n read(\"state\"), read(\"vault\"), read(\"proposer\"), read(\"asset\"), read(\"quoteToken\"), read(\"launchAdapter\"),\n read(\"swapAdapter\"), read(\"venueData\"), read(\"launchToken\"), read(\"launchRef\"), read(\"tokenName\"),\n read(\"tokenSymbol\"), read(\"launchSupply\"), read(\"reserveAmount\"), read(\"reserve\"), read(\"totalClaimed\"),\n read(\"snap\"), read(\"windowEnd\"), read(\"anyoneSettleAt\"), read(\"assetIn\"), read(\"maxFeeIn\"),\n client.getBlock({ blockTag: \"latest\" }),\n ])) as [\n number, Address, Address, Address, Address, Address, Address, Hex, Address, Hex, string, string, bigint, bigint,\n bigint, bigint, bigint, bigint, bigint, bigint, bigint, { timestamp: bigint },\n ];\n\n let phase: LaunchpadSnapshot[\"phase\"] = null;\n if (launchRef !== ZERO_REF) {\n try {\n const p = Number(\n await client.readContract({ address: launchAdapter, abi: LAUNCH_ADAPTER_ABI, functionName: \"phase\", args: [launchRef] }),\n );\n phase = LAUNCH_PHASES[p] ?? null;\n } catch {\n phase = null;\n }\n }\n\n let vaultClock = block.timestamp;\n try {\n vaultClock = BigInt(await client.readContract({ address: vault, abi: SYNDICATE_VAULT_ABI, functionName: \"clock\" }));\n } catch {\n /* v1 vaults are timestamp-clocked; fall back to the block timestamp */\n }\n\n return {\n strategy,\n state: STRATEGY_STATES[Number(stateN)] ?? \"Pending\",\n vault,\n proposer,\n asset,\n quoteToken,\n launchAdapter,\n swapAdapter,\n venue: venueOf(launchAdapter),\n venueData,\n launchToken,\n launchRef,\n tokenName,\n tokenSymbol,\n launchSupply,\n reserveAmount,\n reserve,\n totalClaimed,\n snap,\n windowEnd,\n anyoneSettleAt,\n assetIn,\n maxFeeIn,\n phase,\n now: block.timestamp,\n vaultClock,\n };\n}\n\n/**\n * Why `holder` cannot claim right now, or `null` when a claim would succeed.\n * Mirrors `LaunchpadStrategy._claim`'s gates in order.\n */\nexport function claimBlocker(\n s: LaunchpadSnapshot,\n h: { claimed: boolean; claimable: bigint; isQueue: boolean },\n): string | null {\n if (s.state !== \"Executed\") {\n return s.state === \"Pending\"\n ? \"the launch has not executed yet — there is no reserve to claim (NotClaimable)\"\n : \"the strategy has settled; the unclaimed reserve went to the vault in kind (NotClaimable)\";\n }\n if (s.now > s.windowEnd) return `the claim window closed at ${fmtTs(s.windowEnd)} (ClaimWindowClosed)`;\n if (s.vaultClock <= s.snap) return \"the snapshot is not final yet — claim from the next block (SnapshotNotFinal)\";\n if (h.claimed) return \"this holder already claimed (AlreadyClaimed)\";\n if (h.isQueue) return \"the vault's withdrawal queue cannot receive launch tokens (QueueCannotClaim)\";\n if (h.claimable === 0n) return \"this holder had no vault shares at the snapshot (ZeroEntitlement)\";\n return null;\n}\n\nasync function readHolder(\n s: LaunchpadSnapshot,\n holder: Address,\n client: LaunchpadReadClient,\n): Promise<{ claimed: boolean; claimable: bigint; isQueue: boolean }> {\n const [claimed, claimable, queue] = (await Promise.all([\n client.readContract({ address: s.strategy, abi: LAUNCHPAD_STRATEGY_ABI, functionName: \"claimed\", args: [holder] }),\n client.readContract({ address: s.strategy, abi: LAUNCHPAD_STRATEGY_ABI, functionName: \"claimable\", args: [holder] }),\n client\n .readContract({ address: s.vault, abi: SYNDICATE_VAULT_ABI, functionName: \"withdrawalQueue\" })\n .catch(() => ZERO),\n ])) as [boolean, bigint, Address];\n return { claimed, claimable, isQueue: queue !== ZERO && sameAddr(queue, holder) };\n}\n\nfunction fmtTs(ts: bigint): string {\n if (ts === 0n) return \"—\";\n return `${new Date(Number(ts) * 1000).toISOString()} (${ts})`;\n}\n\nfunction fmtCountdown(target: bigint, now: bigint): string {\n if (target === 0n) return \"\";\n if (target <= now) return \" — passed\";\n const secs = Number(target - now);\n const d = Math.floor(secs / 86400);\n const h = Math.floor((secs % 86400) / 3600);\n const m = Math.floor((secs % 3600) / 60);\n return ` — in ${d}d ${h}h ${m}m`;\n}\n\nfunction fmtTokens(v: bigint): string {\n return formatUnits(v, 18);\n}\n\nfunction parseAddressArg(raw: string, what: string): Address {\n if (!isAddress(raw)) {\n console.error(chalk.red(`Invalid ${what} address: ${raw}`));\n process.exit(1);\n }\n return raw as Address;\n}\n\nfunction venueDetail(s: LaunchpadSnapshot): string {\n if (s.venue === \"sushi\") {\n const v = decodeSushiVenueData(s.venueData);\n return v ? `Sushi Launchpad V2 — liquidity ${v.liquidityMode}, fee disposition ${v.feeMode}` : \"Sushi Launchpad V2 — unreadable venue data\";\n }\n if (s.venue === \"stonk\") {\n const v = decodeStonkVenueData(s.venueData);\n if (!v) return \"StonkBrokers — unreadable venue data\";\n return (\n `StonkBrokers — start $${formatUnits(v.startMcapUsd8, 8)}, graduation $${formatUnits(v.gradMcapUsd8, 8)}, ` +\n `tax ${v.startTaxBps} bps −${v.taxDecayPerMinuteBps}/min, ${v.openEnded ? \"open-ended\" : \"timed\"}, ` +\n `unsold ${v.unsoldMode === 0 ? \"burned\" : \"LP'd\"}`\n );\n }\n return `unrecognised launch adapter ${s.launchAdapter}`;\n}\n\n/** Emit one unsigned tx as a PreparedAction (the `--calldata-only` convention). */\nfunction emitSingleTx(to: Address, data: Hex, description: string): void {\n emitCalldata({\n txs: [{ to, data, value: \"0x0\", chainId: getChain().id as ChainId }],\n preconditions: [],\n description,\n });\n}\n\nasync function sendTx(label: string, address: Address, abi: unknown, functionName: string, args: unknown[]): Promise<void> {\n const spinner = ora(label).start();\n try {\n const hash = await writeContractWithRetry({\n account: getAccount(),\n chain: getChain(),\n address,\n abi,\n functionName,\n args,\n });\n const receipt = await waitForReceipt(hash);\n if (receipt.status === \"reverted\") throw new Error(`${functionName} reverted on-chain (${hash})`);\n spinner.succeed(`${label} done`);\n console.log(chalk.dim(` Tx: ${getExplorerUrl(hash)}`));\n } catch (err) {\n spinner.fail(`${label} failed`);\n console.error(chalk.red(formatContractError(err)));\n process.exit(1);\n }\n}\n\nasync function loadOrExit(strategyRaw: string): Promise<LaunchpadSnapshot> {\n const strategy = parseAddressArg(strategyRaw, \"strategy\");\n try {\n return await readLaunchpad(strategy, getPublicClient());\n } catch (err) {\n console.error(chalk.red(formatContractError(err)));\n process.exit(1);\n }\n}\n\nfunction signerAddress(): Address | null {\n try {\n return getAccount().address;\n } catch {\n return null;\n }\n}\n\n// ── Commands ──\n\nexport function registerLaunchpadCommands(program: Command): void {\n const lp = program\n .command(\"launchpad\")\n .description(\"Launchpad strategy operations: status, reserve claims, fee collection, Stonk finalize\");\n\n lp.command(\"status\")\n .description(\"Show a Launchpad strategy: launch, reserve, claim window, venue\")\n .argument(\"<strategy>\", \"LaunchpadStrategy clone address\")\n .option(\"--holder <address>\", \"Show this holder's claim (default: your wallet, when a key is configured)\")\n .option(\"--json\", \"Print JSON\")\n .action(async (strategyRaw: string, opts: { holder?: string; json?: boolean }) => {\n const s = await loadOrExit(strategyRaw);\n const client = getPublicClient();\n const holder = opts.holder ? parseAddressArg(opts.holder, \"holder\") : signerAddress();\n\n let holderView: { holder: Address; claimable: bigint; claimableNow: bigint; claimed: boolean; blocker: string | null } | null = null;\n if (holder) {\n const h = await readHolder(s, holder, client);\n const blocker = claimBlocker(s, h);\n // `claimable()` ignores the time gates on purpose; gate it here.\n holderView = { holder, claimable: h.claimable, claimableNow: blocker ? 0n : h.claimable, claimed: h.claimed, blocker };\n }\n\n let assetSymbol = \"asset\";\n let assetDecimals = 18;\n try {\n [assetSymbol, assetDecimals] = (await Promise.all([\n client.readContract({ address: s.asset, abi: ERC20_ABI, functionName: \"symbol\" }),\n client.readContract({ address: s.asset, abi: ERC20_ABI, functionName: \"decimals\" }),\n ])) as [string, number];\n } catch {\n /* cosmetic */\n }\n\n if (opts.json) {\n const out = {\n ...s,\n venueDetail: venueDetail(s),\n unclaimed: s.reserve - s.totalClaimed,\n holder: holderView,\n };\n console.log(JSON.stringify(out, (_k, v) => (typeof v === \"bigint\" ? v.toString() : v), 2));\n return;\n }\n\n const launched = s.launchToken !== ZERO;\n console.log();\n console.log(chalk.bold(`Launchpad ${s.strategy}`));\n console.log(` State: ${s.state}${s.phase ? ` (venue phase: ${s.phase})` : \"\"}`);\n console.log(` Venue: ${venueDetail(s)}`);\n console.log(` Launch adapter: ${s.launchAdapter}`);\n console.log(` Vault: ${s.vault}`);\n console.log(` Token: ${s.tokenName} (${s.tokenSymbol})${launched ? ` at ${s.launchToken}` : \" — not launched yet\"}`);\n if (launched) console.log(` launchRef: ${s.launchRef}`);\n console.log(` Budget: ${formatUnits(s.assetIn, assetDecimals)} ${assetSymbol}; quote ${s.quoteToken}`);\n console.log(` Supply: ${fmtTokens(s.launchSupply)}`);\n if (launched) {\n const unclaimed = s.reserve - s.totalClaimed;\n console.log(` Reserve: ${fmtTokens(s.reserve)} (claimed ${fmtTokens(s.totalClaimed)}, unclaimed ${fmtTokens(unclaimed)})`);\n console.log(` Snapshot: vault clock ${s.snap}`);\n console.log(` Claim window end: ${fmtTs(s.windowEnd)}${fmtCountdown(s.windowEnd, s.now)}`);\n console.log(` Anyone-settle at: ${fmtTs(s.anyoneSettleAt)}${fmtCountdown(s.anyoneSettleAt, s.now)}`);\n } else {\n console.log(` Reserve: ${fmtTokens(s.reserveAmount)} (configured)`);\n }\n console.log(chalk.dim(\" Creator fees are paid to the vault, not into the claim pot: `sherwood launchpad collect-fees`.\"));\n if (holderView) {\n console.log();\n console.log(` Holder ${holderView.holder}:`);\n console.log(` Entitlement: ${fmtTokens(holderView.claimable)}${holderView.claimed ? \" (already claimed)\" : \"\"}`);\n console.log(` Claimable now: ${fmtTokens(holderView.claimableNow)}`);\n if (holderView.blocker) console.log(chalk.dim(` Why not: ${holderView.blocker}`));\n }\n console.log();\n });\n\n lp.command(\"claim\")\n .description(\"Claim your pro-rata slice of the launch reserve (dividend in kind; shares are not burned)\")\n .argument(\"<strategy>\", \"LaunchpadStrategy clone address\")\n .option(\"--holder <address>\", \"With --calldata-only: the external signer, for the preflight\")\n .action(async (strategyRaw: string, opts: { holder?: string }) => {\n const s = await loadOrExit(strategyRaw);\n const holder = opts.holder ? parseAddressArg(opts.holder, \"holder\") : signerAddress();\n if (!holder && !isCalldataOnly()) {\n console.error(chalk.red(\"No signer configured — set a private key, or use --calldata-only --holder <address>.\"));\n process.exit(1);\n }\n if (holder) {\n const h = await readHolder(s, holder, getPublicClient());\n const blocker = claimBlocker(s, h);\n if (blocker) {\n console.error(chalk.red(`Cannot claim for ${holder}: ${blocker}`));\n process.exit(1);\n }\n if (!isCalldataOnly()) console.log(chalk.dim(` Claiming ${fmtTokens(h.claimable)} ${s.tokenSymbol}`));\n } else {\n const blocker = claimBlocker(s, { claimed: false, claimable: 1n, isQueue: false });\n if (blocker) {\n console.error(chalk.red(`Cannot claim: ${blocker}`));\n process.exit(1);\n }\n }\n if (isCalldataOnly()) {\n emitSingleTx(s.strategy, encodeClaimCalldata(), `Claim the signer's slice of the ${s.tokenSymbol} reserve from ${s.strategy}.`);\n return;\n }\n await sendTx(\"Claiming reserve\", s.strategy, LAUNCHPAD_STRATEGY_ABI, \"claim\", []);\n });\n\n lp.command(\"claim-for\")\n .description(\"Pay a holder their slice of the reserve (permissionless; tokens go to the holder, never the caller)\")\n .argument(\"<strategy>\", \"LaunchpadStrategy clone address\")\n .argument(\"<holder>\", \"Holder to pay\")\n .action(async (strategyRaw: string, holderRaw: string) => {\n const holder = parseAddressArg(holderRaw, \"holder\");\n const s = await loadOrExit(strategyRaw);\n const h = await readHolder(s, holder, getPublicClient());\n const blocker = claimBlocker(s, h);\n if (blocker) {\n console.error(chalk.red(`Cannot claim for ${holder}: ${blocker}`));\n process.exit(1);\n }\n if (isCalldataOnly()) {\n emitSingleTx(\n s.strategy,\n encodeClaimForCalldata(holder),\n `Pay ${holder} their ${fmtTokens(h.claimable)} ${s.tokenSymbol} reserve slice from ${s.strategy}.`,\n );\n return;\n }\n console.log(chalk.dim(` Paying ${holder} ${fmtTokens(h.claimable)} ${s.tokenSymbol}`));\n await sendTx(\"Claiming for holder\", s.strategy, LAUNCHPAD_STRATEGY_ABI, \"claimFor\", [holder]);\n });\n\n lp.command(\"collect-fees\")\n .description(\"Push the launch's accrued creator fees to the fund's vault (permissionless; never pays the caller)\")\n .argument(\"<strategy>\", \"LaunchpadStrategy clone address\")\n .action(async (strategyRaw: string) => {\n const s = await loadOrExit(strategyRaw);\n if (s.launchRef === ZERO_REF) {\n console.error(chalk.red(\"The launch has not executed yet — there is no launch to collect fees from.\"));\n process.exit(1);\n }\n if (isCalldataOnly()) {\n emitSingleTx(\n s.launchAdapter,\n encodeCollectFeesCalldata(s.launchRef),\n `collectFees(${s.launchRef}) on ${s.launchAdapter}: pays accrued creator fees to vault ${s.vault}.`,\n );\n return;\n }\n await sendTx(\"Collecting fees to the vault\", s.launchAdapter, LAUNCH_ADAPTER_ABI, \"collectFees\", [s.launchRef]);\n console.log(chalk.dim(` Fees (if any accrued) went to vault ${s.vault}; a later proposal decides what to do with them.`));\n });\n\n lp.command(\"finalize\")\n .description(\"Graduate + bond a StonkBrokers launch (no-op on Sushi, which is live from the launch block)\")\n .argument(\"<strategy>\", \"LaunchpadStrategy clone address\")\n .action(async (strategyRaw: string) => {\n const s = await loadOrExit(strategyRaw);\n if (s.launchRef === ZERO_REF) {\n console.error(chalk.red(\"The launch has not executed yet — nothing to finalize.\"));\n process.exit(1);\n }\n if (s.venue === \"sushi\" || s.phase === \"Live\") {\n console.log(\n chalk.yellow(\n s.venue === \"sushi\"\n ? \"Sushi launches are live from the launch block; finalize is a no-op there. Nothing sent.\"\n : \"The launch is already bonded (Live). Nothing sent.\",\n ),\n );\n return;\n }\n if (s.phase === \"Failed\") {\n console.log(chalk.yellow(\"The launch was aborted at the venue (Failed); there is nothing to graduate. Nothing sent.\"));\n return;\n }\n if (s.phase === \"Curve\") {\n console.log(\n chalk.yellow(\" The curve is still open (phase Curve): graduate will likely be skipped by the venue until it closes.\"),\n );\n }\n if (isCalldataOnly()) {\n emitSingleTx(s.launchAdapter, encodeFinalizeCalldata(s.launchRef), `finalize(${s.launchRef}) on ${s.launchAdapter}.`);\n return;\n }\n await sendTx(\"Finalizing launch\", s.launchAdapter, LAUNCH_ADAPTER_ABI, \"finalize\", [s.launchRef]);\n\n // FALLBACK for StonkLaunchAdapter builds without the `VenueLegStarved`\n // guard (sherwood-strategies#6). Their `cloneFinalize` calls the pad's\n // `bond` through a raw call that cannot revert the tx, so under the\n // estimated gas limit graduation runs, `bond` (~1.4M gas) runs out, and\n // the launch is left graduated-but-unbonded (phase Closing) with a\n // `VenueLegSkipped(\"bond\")` log. `bond` is permissionless at the venue,\n // so finish it there directly, and never fail the command over it.\n const after = await readLaunchpad(s.strategy, getPublicClient()).catch(() => null);\n if (after?.phase === \"Closing\") {\n await bondAtVenue(s.launchRef);\n }\n });\n}\n\n/** The clone's pad + launch id, read from the clone the launch ref names. */\nconst STONK_CLONE_VIEWS_ABI = [\n { type: \"function\", name: \"pad\", inputs: [], outputs: [{ name: \"\", type: \"address\" }], stateMutability: \"view\" },\n { type: \"function\", name: \"launchId\", inputs: [], outputs: [{ name: \"\", type: \"uint256\" }], stateMutability: \"view\" },\n] as const;\n\nexport const STONK_PAD_BOND_ABI = [\n { type: \"function\", name: \"bond\", inputs: [{ name: \"id\", type: \"uint256\" }], outputs: [], stateMutability: \"nonpayable\" },\n] as const;\n\n/**\n * Where a StonkBrokers launch is bonded: the ref's low 20 bytes are the\n * per-launch clone, which stores the pad and the pad's launch id.\n */\nexport async function stonkBondCall(\n launchRef: Hex,\n client: { readContract: (args: never) => Promise<unknown> },\n): Promise<{ pad: Address; launchId: bigint }> {\n const clone = `0x${launchRef.slice(-40)}` as Address;\n const read = client.readContract as (args: {\n address: Address;\n abi: typeof STONK_CLONE_VIEWS_ABI;\n functionName: \"pad\" | \"launchId\";\n }) => Promise<unknown>;\n const [pad, launchId] = await Promise.all([\n read({ address: clone, abi: STONK_CLONE_VIEWS_ABI, functionName: \"pad\" }),\n read({ address: clone, abi: STONK_CLONE_VIEWS_ABI, functionName: \"launchId\" }),\n ]);\n return { pad: pad as Address, launchId: launchId as bigint };\n}\n\nasync function bondAtVenue(launchRef: Hex): Promise<void> {\n let target: { pad: Address; launchId: bigint };\n try {\n target = await stonkBondCall(launchRef, getPublicClient() as never);\n } catch (err) {\n console.log(chalk.yellow(` Still graduated-but-unbonded, and the clone's pad could not be read: ${formatContractError(err)}`));\n return;\n }\n console.log(\n chalk.yellow(\n ` finalize left the launch graduated but unbonded (the adapter's bond leg ran out of gas).\\n` +\n ` Bonding it at the venue directly: pad ${target.pad} bond(${target.launchId}) — permissionless.`,\n ),\n );\n const spinner = ora(\"Bonding at the venue\").start();\n try {\n const hash = await writeContractWithRetry({\n account: getAccount(),\n chain: getChain(),\n address: target.pad,\n abi: STONK_PAD_BOND_ABI,\n functionName: \"bond\",\n args: [target.launchId],\n });\n const receipt = await waitForReceipt(hash);\n if (receipt.status === \"reverted\") throw new Error(`bond reverted on-chain (${hash})`);\n spinner.succeed(\"Bonded at the venue (phase Live)\");\n console.log(chalk.dim(` Tx: ${getExplorerUrl(hash)}`));\n } catch (err) {\n spinner.warn(\"The venue did not bond it yet\");\n console.log(chalk.dim(` ${formatContractError(err)} — re-run \\`launchpad finalize\\` later.`));\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/config.ts","../src/lib/settings.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\";\nimport { privateKeyToAccount } from \"viem/accounts\";\nimport { resolveSetting } from \"./settings.js\";\n\nconst CONFIG_DIR = path.join(os.homedir(), \".sherwood\");\nconst CONFIG_PATH = path.join(CONFIG_DIR, \"config.json\");\nconst DASHBOARD_BRIDGE_PATH = path.join(CONFIG_DIR, \"dashboard.json\");\n\n/** Per-chain user-specific addresses (stored by chainId). */\nexport interface ChainContracts {\n vault?: string; // user's default vault address\n}\n\n/** A fund the agent belongs to (creator or member). */\nexport interface FundMembership {\n subdomain: string;\n vault: string;\n role: \"creator\" | \"agent\";\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 anthropicApiKey?: string; // Anthropic Claude API key (for LLM judge)\n agentId?: number; // ERC-8004 identity token ID\n identityProvider?: \"agent0\" | \"virtuals\"; // who issued the identity (absent ⇒ agent0)\n identityChainId?: number; // chain the ERC-8004 NFT lives on (absent ⇒ active chain)\n virtuals?: VirtualsIdentity; // economyOS link details (identityProvider === \"virtuals\")\n contracts?: Record<string, ChainContracts>; // chainId → user addresses\n funds?: Record<string, FundMembership[]>; // chainId → fund memberships\n primaryFund?: Record<string, string>; // chainId → subdomain of the active fund\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 _xmtpMigrated?: boolean; // one-time flag: revoked stale installations from ~/.xmtp/ era\n /** Cached swap routes per chain: chainId → { tokenPair → SwapRoute } */\n swapRoutes?: Record<string, Record<string, SwapRoute>>;\n // ── lighter ──\n /** Lighter L2 agent key from `sherwood lighter keygen` (see LighterKeyConfig). */\n lighter?: LighterKeyConfig;\n}\n\n/** Linked Virtuals economyOS identity (see lib/virtuals.ts). */\nexport interface VirtualsIdentity {\n agentId?: string; // Virtuals platform agent ID (opaque, e.g. \"abc-123\")\n wallet: string; // economyOS agent wallet (identity holder)\n binding?: {\n sig: string; // EIP-191 signature by the economyOS wallet\n message: string; // the exact signed binding message\n };\n}\n\n/** Persisted swap route detected by the CLI during portfolio strategy proposal. */\nexport interface SwapRoute {\n mode: \"direct\" | \"multi-hop\";\n feeTier: number; // direct pool fee tier\n hop?: { via: string; feeIn: number; feeOut: number }; // multi-hop details\n detectedAt: number; // unix timestamp\n}\n\nexport function loadConfig(): SherwoodConfig {\n if (fs.existsSync(CONFIG_PATH)) {\n const config = JSON.parse(fs.readFileSync(CONFIG_PATH, \"utf-8\"));\n if (!config.groupCache) config.groupCache = {};\n return config;\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 writeDashboardBridge(config);\n}\n\n/**\n * Public-safe derivation of config.json for Hermes dashboard plugins to read.\n * Excludes privateKey + every other sensitive field. Hermes' sherwood-companion\n * plugin reads ~/.sherwood/dashboard.json to auto-detect the operator's\n * primary fund without prompting.\n *\n * Wrapped in try/catch — bridge-write failure must not break a config save.\n */\nfunction writeDashboardBridge(config: SherwoodConfig): void {\n try {\n let agentWallet: string | null = null;\n if (config.privateKey) {\n const key = config.privateKey.startsWith(\"0x\")\n ? (config.privateKey as `0x${string}`)\n : (`0x${config.privateKey}` as `0x${string}`);\n agentWallet = privateKeyToAccount(key).address;\n }\n const bridge = {\n version: 1,\n agentWallet,\n funds: config.funds ?? {},\n primaryFund: config.primaryFund ?? {},\n };\n fs.writeFileSync(\n DASHBOARD_BRIDGE_PATH,\n JSON.stringify(bridge, null, 2),\n { mode: 0o600 },\n );\n } catch {\n // Non-fatal: plugin will fall back to manual subdomain entry.\n }\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 invalidateCachedGroupId(subdomain: string): void {\n const config = loadConfig();\n if (config.groupCache[subdomain]) {\n delete config.groupCache[subdomain];\n saveConfig(config);\n }\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 resolveSetting(\"veniceApiKey\", loadConfig(), process.env);\n}\n\n// ── Anthropic API Key ──\n\nexport function setAnthropicApiKey(apiKey: string): void {\n const config = loadConfig();\n config.anthropicApiKey = apiKey;\n saveConfig(config);\n}\n\nexport function getAnthropicApiKey(): string | undefined {\n return resolveSetting(\"anthropicApiKey\", loadConfig(), process.env);\n}\n\n/**\n * Bind an agent0-minted (or loaded) identity. Clears any previously linked\n * Virtuals state — otherwise `fund join` would emit a vid tag mixing the new\n * agent0 token with the stale economyOS wallet/binding (renders ✘ to\n * creators) and `identity status` would misreport the provider.\n */\nexport function setAgentId(agentId: number): void {\n const config = loadConfig();\n config.agentId = agentId;\n delete config.identityProvider;\n delete config.identityChainId;\n delete config.virtuals;\n saveConfig(config);\n}\n\n/**\n * Persist a linked Virtuals economyOS identity. Sets the ERC-8004 token ID\n * as the active agentId and stamps provider + issuing chain alongside it.\n */\nexport function setVirtualsIdentity(\n tokenId: number,\n issuingChainId: number,\n identity: VirtualsIdentity,\n): void {\n const config = loadConfig();\n config.agentId = tokenId;\n config.identityProvider = \"virtuals\";\n config.identityChainId = issuingChainId;\n config.virtuals = identity;\n saveConfig(config);\n}\n\nexport function getVirtualsIdentity(): VirtualsIdentity | undefined {\n return loadConfig().virtuals;\n}\n\n/** Identity provider for the saved agentId. Absent field ⇒ legacy agent0 mint. */\nexport function getIdentityProvider(): \"agent0\" | \"virtuals\" {\n return loadConfig().identityProvider ?? \"agent0\";\n}\n\nexport function getIdentityChainId(): number | undefined {\n return loadConfig().identityChainId;\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\n/**\n * Resolve the signing key (config → PRIVATE_KEY env, 0x-normalized) or\n * throw with the canonical setup hint. Every path that signs or derives\n * identity from the key (viem clients, Agent0 SDK, XMTP) must use this,\n * so they can never resolve different keys.\n */\nexport function requirePrivateKey(): `0x${string}` {\n const key = resolveSetting(\"privateKey\", loadConfig(), process.env);\n if (!key) {\n throw new Error(\n \"Private key not found. Run 'sherwood config set --private-key <key>' or set PRIVATE_KEY env var.\",\n );\n }\n return key as `0x${string}`;\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 resolveSetting(\"uniswapApiKey\", loadConfig(), process.env);\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\n// ── Fund Membership ──\n\n/**\n * Add (or update) a fund membership. Deduplicates by subdomain.\n * Automatically sets it as primary if it's the first fund on this chain.\n */\nexport function addFund(\n chainId: number,\n membership: FundMembership,\n): void {\n const config = loadConfig();\n const cid = String(chainId);\n if (!config.funds) config.funds = {};\n if (!config.funds[cid]) config.funds[cid] = [];\n\n // Upsert — replace existing entry with same subdomain\n const idx = config.funds[cid].findIndex(\n (s) => s.subdomain === membership.subdomain,\n );\n if (idx >= 0) {\n config.funds[cid][idx] = membership;\n } else {\n config.funds[cid].push(membership);\n }\n\n // Auto-set as primary if it's the first fund (or no primary set)\n if (!config.primaryFund) config.primaryFund = {};\n if (!config.primaryFund[cid]) {\n config.primaryFund[cid] = membership.subdomain;\n }\n\n saveConfig(config);\n}\n\n/** Get all fund memberships for a chain. */\nexport function getFunds(chainId: number): FundMembership[] {\n const config = loadConfig();\n return config.funds?.[String(chainId)] ?? [];\n}\n\n/** Set which fund is the active/primary one for CLI commands. */\nexport function setPrimaryFund(\n chainId: number,\n subdomain: string,\n): void {\n const config = loadConfig();\n if (!config.primaryFund) config.primaryFund = {};\n config.primaryFund[String(chainId)] = subdomain;\n saveConfig(config);\n}\n\n/**\n * Get the primary fund for this chain.\n * Falls back to ChainContracts.vault for backwards compat with older configs.\n */\nexport function getPrimaryFund(\n chainId: number,\n): FundMembership | undefined {\n const config = loadConfig();\n const cid = String(chainId);\n\n // Check new funds store first\n const primarySubdomain = config.primaryFund?.[cid];\n if (primarySubdomain && config.funds?.[cid]) {\n const found = config.funds[cid].find(\n (s) => s.subdomain === primarySubdomain,\n );\n if (found) return found;\n }\n\n // Backwards compat: if funds list has entries but no primary, use the first one\n if (config.funds?.[cid]?.length) {\n return config.funds[cid][0];\n }\n\n // Legacy fallback: config only has a vault address, no subdomain\n const vault = config.contracts?.[cid]?.vault;\n if (vault) {\n return { subdomain: \"\", vault, role: \"creator\" };\n }\n\n return undefined;\n}\n\n// ── Swap Route Cache ──\n\nfunction swapRouteKey(asset: string, token: string): string {\n return `${asset.toLowerCase()}→${token.toLowerCase()}`;\n}\n\n/** Get a cached swap route for a token pair on a chain. */\nexport function getCachedSwapRoute(chainId: number, asset: string, token: string): SwapRoute | undefined {\n const config = loadConfig();\n return config.swapRoutes?.[String(chainId)]?.[swapRouteKey(asset, token)];\n}\n\n/** Save a detected swap route to the config cache. */\nexport function cacheSwapRoute(chainId: number, asset: string, token: string, route: SwapRoute): void {\n const config = loadConfig();\n const cid = String(chainId);\n if (!config.swapRoutes) config.swapRoutes = {};\n if (!config.swapRoutes[cid]) config.swapRoutes[cid] = {};\n config.swapRoutes[cid][swapRouteKey(asset, token)] = route;\n saveConfig(config);\n}\n\n/** Clear all cached swap routes for a chain (e.g. after pool migration). */\nexport function clearSwapRoutes(chainId: number): void {\n const config = loadConfig();\n delete config.swapRoutes?.[String(chainId)];\n saveConfig(config);\n}\n\n// ── lighter ──\n//\n// The Lighter L2 agent key `sherwood lighter keygen` generates. The pubkey goes\n// into a lighter-perp proposal's init data (`--pubkey` defaults to it); the\n// private key is the off-chain agent's TRADE-ONLY secret — it can place and\n// cancel orders on the strategy's account but can never withdraw (withdrawals\n// are venue-authed to the strategy contract). Kept in the 0600 config file.\n\nexport interface LighterKeyConfig {\n pubKey: string; // 40-byte Goldilocks pubkey, 0x-hex\n privateKey: string; // L2 API private key, 0x-hex\n apiKeyIndex: number; // 2..254\n createdAt: string; // ISO timestamp\n}\n\nexport function getLighterKeyConfig(): LighterKeyConfig | undefined {\n return loadConfig().lighter;\n}\n\n/**\n * Saves the L2 PRIVATE key, so it also forces config.json to 0600: saveConfig's\n * `mode` only applies when the file is created, and an existing config may be\n * 0644 (older CLIs, a hand-edit, a restore).\n */\nexport function setLighterKeyConfig(key: LighterKeyConfig): void {\n const config = loadConfig();\n config.lighter = key;\n saveConfig(config);\n fs.chmodSync(CONFIG_PATH, 0o600);\n}\n// ── /lighter ──\n","/**\n * Single owner of config → env resolution for user settings. Every\n * config-or-env setting resolves through the table below — accessors in\n * config.ts and requirePrivateKey() delegate here.\n */\n\nimport { type SherwoodConfig } from \"./config.js\";\n\ntype Env = Record<string, string | undefined>;\n\nconst hex0x = (v: string): string => (v.startsWith(\"0x\") ? v : `0x${v}`);\n\ninterface SettingSpec {\n fromConfig: (c: Partial<SherwoodConfig>) => string | undefined;\n envVar?: string;\n normalize?: (v: string) => string;\n}\n\nconst SETTINGS = {\n privateKey: {\n fromConfig: (c) => c.privateKey,\n envVar: \"PRIVATE_KEY\",\n normalize: hex0x,\n },\n veniceApiKey: {\n fromConfig: (c) => c.veniceApiKey,\n envVar: \"VENICE_API_KEY\",\n },\n anthropicApiKey: {\n fromConfig: (c) => c.anthropicApiKey,\n envVar: \"ANTHROPIC_API_KEY\",\n },\n uniswapApiKey: {\n fromConfig: (c) => c.uniswapApiKey,\n envVar: \"UNISWAP_API_KEY\",\n },\n} satisfies Record<string, SettingSpec>;\n\nexport type SettingKey = keyof typeof SETTINGS;\n\nexport function resolveSetting(\n key: SettingKey,\n config: Partial<SherwoodConfig>,\n env: Env,\n): string | undefined {\n const spec: SettingSpec = SETTINGS[key];\n // Empty string counts as absent on both sources: an empty config key\n // falls through to the env, and a blank `PRIVATE_KEY=` dotenv line\n // resolves to undefined (so callers show the setup hint) instead of\n // normalizing to a bare \"0x\".\n const raw =\n spec.fromConfig(config) || (spec.envVar ? env[spec.envVar] : undefined);\n if (!raw) return undefined;\n return spec.normalize ? spec.normalize(raw) : raw;\n}\n"],"mappings":"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","names":[]}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|