@sherwoodagent/cli 0.24.0 → 0.25.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.
Files changed (49) hide show
  1. package/dist/{chat-3SAX4VRO.js → chat-MYRUIM54.js} +7 -7
  2. package/dist/{chunk-5NN424VN.js → chunk-2SNPCWB4.js} +4 -4
  3. package/dist/{chunk-LMDHM36X.js → chunk-2UP63CYI.js} +4 -4
  4. package/dist/{chunk-NGET2RWT.js → chunk-66VFSLPS.js} +2 -2
  5. package/dist/{chunk-ZIH3SCFJ.js → chunk-G6LOQCM3.js} +84 -5
  6. package/dist/chunk-G6LOQCM3.js.map +1 -0
  7. package/dist/{chunk-35536GNW.js → chunk-GWIW6DDG.js} +2 -2
  8. package/dist/{chunk-PEJPTKLK.js → chunk-L5RWZSET.js} +5 -5
  9. package/dist/{chunk-R75DM3VL.js → chunk-O7QIRMJO.js} +35 -7
  10. package/dist/chunk-O7QIRMJO.js.map +1 -0
  11. package/dist/{chunk-5S2TBADL.js → chunk-RGOTBJIN.js} +25 -2
  12. package/dist/chunk-RGOTBJIN.js.map +1 -0
  13. package/dist/{chunk-R7Q2L6VV.js → chunk-SBVHGUQJ.js} +3 -3
  14. package/dist/{client-XG6LL6TS.js → client-CWQFYZ5Z.js} +4 -4
  15. package/dist/{config-EHCEKT2B.js → config-YXZKPSZB.js} +8 -2
  16. package/dist/{eas-ZMTIOZH6.js → eas-DGLNPNWX.js} +6 -6
  17. package/dist/{governor-JIXAG6WU.js → governor-3PINJ2X2.js} +6 -6
  18. package/dist/index.js +221 -35
  19. package/dist/index.js.map +1 -1
  20. package/dist/{network-UVMYTKQX.js → network-QEMP3DSP.js} +3 -3
  21. package/dist/{price-AGCWXLZ6.js → price-76BEXJDI.js} +5 -5
  22. package/dist/{research-KUIZM6AK.js → research-FIX3U4LG.js} +9 -9
  23. package/dist/research-ZX7T2ZIJ.js +14 -0
  24. package/dist/{session-2FIR4LJP.js → session-6DJ4A2Q3.js} +10 -10
  25. package/dist/{trade-UTM3DSO3.js → trade-MDVM4XFF.js} +16 -16
  26. package/dist/{xmtp-B2XFVPIV.js → xmtp-64CYLVLO.js} +6 -6
  27. package/package.json +1 -1
  28. package/dist/chunk-5S2TBADL.js.map +0 -1
  29. package/dist/chunk-R75DM3VL.js.map +0 -1
  30. package/dist/chunk-ZIH3SCFJ.js.map +0 -1
  31. package/dist/research-2I6AA3BI.js +0 -14
  32. /package/dist/{chat-3SAX4VRO.js.map → chat-MYRUIM54.js.map} +0 -0
  33. /package/dist/{chunk-5NN424VN.js.map → chunk-2SNPCWB4.js.map} +0 -0
  34. /package/dist/{chunk-LMDHM36X.js.map → chunk-2UP63CYI.js.map} +0 -0
  35. /package/dist/{chunk-NGET2RWT.js.map → chunk-66VFSLPS.js.map} +0 -0
  36. /package/dist/{chunk-35536GNW.js.map → chunk-GWIW6DDG.js.map} +0 -0
  37. /package/dist/{chunk-PEJPTKLK.js.map → chunk-L5RWZSET.js.map} +0 -0
  38. /package/dist/{chunk-R7Q2L6VV.js.map → chunk-SBVHGUQJ.js.map} +0 -0
  39. /package/dist/{client-XG6LL6TS.js.map → client-CWQFYZ5Z.js.map} +0 -0
  40. /package/dist/{config-EHCEKT2B.js.map → config-YXZKPSZB.js.map} +0 -0
  41. /package/dist/{eas-ZMTIOZH6.js.map → eas-DGLNPNWX.js.map} +0 -0
  42. /package/dist/{governor-JIXAG6WU.js.map → governor-3PINJ2X2.js.map} +0 -0
  43. /package/dist/{network-UVMYTKQX.js.map → network-QEMP3DSP.js.map} +0 -0
  44. /package/dist/{price-AGCWXLZ6.js.map → price-76BEXJDI.js.map} +0 -0
  45. /package/dist/{research-KUIZM6AK.js.map → research-FIX3U4LG.js.map} +0 -0
  46. /package/dist/{research-2I6AA3BI.js.map → research-ZX7T2ZIJ.js.map} +0 -0
  47. /package/dist/{session-2FIR4LJP.js.map → session-6DJ4A2Q3.js.map} +0 -0
  48. /package/dist/{trade-UTM3DSO3.js.map → trade-MDVM4XFF.js.map} +0 -0
  49. /package/dist/{xmtp-B2XFVPIV.js.map → xmtp-64CYLVLO.js.map} +0 -0
@@ -2,23 +2,23 @@ import {
2
2
  getTextRecord,
3
3
  resolveSyndicate,
4
4
  setTextRecord
5
- } from "./chunk-ZIH3SCFJ.js";
6
- import "./chunk-R75DM3VL.js";
5
+ } from "./chunk-G6LOQCM3.js";
6
+ import "./chunk-O7QIRMJO.js";
7
7
  import {
8
8
  formatContractError,
9
9
  getAccount
10
- } from "./chunk-R7Q2L6VV.js";
11
- import "./chunk-35536GNW.js";
10
+ } from "./chunk-SBVHGUQJ.js";
11
+ import "./chunk-GWIW6DDG.js";
12
12
  import {
13
13
  cacheGroupId,
14
14
  getCachedGroupId
15
- } from "./chunk-5S2TBADL.js";
15
+ } from "./chunk-RGOTBJIN.js";
16
16
 
17
17
  // src/commands/chat.ts
18
18
  import chalk from "chalk";
19
19
  import ora from "ora";
20
20
  async function loadXmtp() {
21
- return import("./xmtp-B2XFVPIV.js");
21
+ return import("./xmtp-64CYLVLO.js");
22
22
  }
23
23
  function formatTimestamp(date) {
24
24
  return `${date.getHours().toString().padStart(2, "0")}:${date.getMinutes().toString().padStart(2, "0")}`;
@@ -378,4 +378,4 @@ function registerChatCommands(program) {
378
378
  export {
379
379
  registerChatCommands
380
380
  };
381
- //# sourceMappingURL=chat-3SAX4VRO.js.map
381
+ //# sourceMappingURL=chat-MYRUIM54.js.map
@@ -2,18 +2,18 @@ import {
2
2
  EAS_ABI,
3
3
  EAS_CONTRACTS,
4
4
  EAS_SCHEMAS
5
- } from "./chunk-R75DM3VL.js";
5
+ } from "./chunk-O7QIRMJO.js";
6
6
  import {
7
7
  getAccount,
8
8
  getPublicClient,
9
9
  waitForReceipt,
10
10
  writeContractWithRetry
11
- } from "./chunk-R7Q2L6VV.js";
11
+ } from "./chunk-SBVHGUQJ.js";
12
12
  import {
13
13
  getChain,
14
14
  getChainConfig,
15
15
  getNetwork
16
- } from "./chunk-35536GNW.js";
16
+ } from "./chunk-GWIW6DDG.js";
17
17
 
18
18
  // src/lib/eas.ts
19
19
  import { encodeAbiParameters, parseAbiParameters, decodeAbiParameters } from "viem";
@@ -409,4 +409,4 @@ export {
409
409
  queryApprovals,
410
410
  queryJoinRequests
411
411
  };
412
- //# sourceMappingURL=chunk-5NN424VN.js.map
412
+ //# sourceMappingURL=chunk-2SNPCWB4.js.map
@@ -1,16 +1,16 @@
1
1
  import {
2
2
  SHERWOOD,
3
3
  SYNDICATE_GOVERNOR_ABI
4
- } from "./chunk-R75DM3VL.js";
4
+ } from "./chunk-O7QIRMJO.js";
5
5
  import {
6
6
  getAccount,
7
7
  getPublicClient,
8
8
  waitForReceipt,
9
9
  writeContractWithRetry
10
- } from "./chunk-R7Q2L6VV.js";
10
+ } from "./chunk-SBVHGUQJ.js";
11
11
  import {
12
12
  getChain
13
- } from "./chunk-35536GNW.js";
13
+ } from "./chunk-GWIW6DDG.js";
14
14
 
15
15
  // src/lib/governor.ts
16
16
  import { parseEventLogs } from "viem";
@@ -427,4 +427,4 @@ export {
427
427
  vetoProposal,
428
428
  setProtocolFeeBps
429
429
  };
430
- //# sourceMappingURL=chunk-LMDHM36X.js.map
430
+ //# sourceMappingURL=chunk-2UP63CYI.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getAccount
3
- } from "./chunk-R7Q2L6VV.js";
3
+ } from "./chunk-SBVHGUQJ.js";
4
4
 
5
5
  // src/providers/research/messari.ts
6
6
  import { base, baseSepolia } from "viem/chains";
@@ -445,4 +445,4 @@ export {
445
445
  NansenProvider,
446
446
  getResearchProvider
447
447
  };
448
- //# sourceMappingURL=chunk-NGET2RWT.js.map
448
+ //# sourceMappingURL=chunk-66VFSLPS.js.map
@@ -6,20 +6,20 @@ import {
6
6
  SYNDICATE_FACTORY_ABI,
7
7
  SYNDICATE_VAULT_ABI,
8
8
  TOKENS
9
- } from "./chunk-R75DM3VL.js";
9
+ } from "./chunk-O7QIRMJO.js";
10
10
  import {
11
11
  getAccount,
12
12
  getPublicClient,
13
13
  getWalletClient,
14
14
  waitForReceipt,
15
15
  writeContractWithRetry
16
- } from "./chunk-R7Q2L6VV.js";
16
+ } from "./chunk-SBVHGUQJ.js";
17
17
  import {
18
18
  getChain
19
- } from "./chunk-35536GNW.js";
19
+ } from "./chunk-GWIW6DDG.js";
20
20
  import {
21
21
  getChainContracts
22
- } from "./chunk-5S2TBADL.js";
22
+ } from "./chunk-RGOTBJIN.js";
23
23
 
24
24
  // src/lib/vault.ts
25
25
  import { formatUnits, parseEther } from "viem";
@@ -198,6 +198,82 @@ async function deposit(amount) {
198
198
  await waitForReceipt(depositHash);
199
199
  return depositHash;
200
200
  }
201
+ async function preflightRedeem(shares) {
202
+ const client = getPublicClient();
203
+ const vaultAddress = getVaultAddress();
204
+ const account = getAccount();
205
+ if (shares === 0n) {
206
+ throw new Error("No shares to redeem.");
207
+ }
208
+ const balance = await client.readContract({
209
+ address: vaultAddress,
210
+ abi: SYNDICATE_VAULT_ABI,
211
+ functionName: "balanceOf",
212
+ args: [account.address]
213
+ });
214
+ if (balance < shares) {
215
+ throw new Error(
216
+ `Insufficient shares. Have ${balance.toString()}, need ${shares.toString()}.`
217
+ );
218
+ }
219
+ const paused = await client.readContract({
220
+ address: vaultAddress,
221
+ abi: SYNDICATE_VAULT_ABI,
222
+ functionName: "paused"
223
+ });
224
+ if (paused) {
225
+ throw new Error("Vault is paused \u2014 redemptions are temporarily disabled.");
226
+ }
227
+ const locked = await client.readContract({
228
+ address: vaultAddress,
229
+ abi: SYNDICATE_VAULT_ABI,
230
+ functionName: "redemptionsLocked"
231
+ });
232
+ if (locked) {
233
+ throw new Error(
234
+ "Redemptions are locked while a strategy is executing. Wait for the proposal to be settled."
235
+ );
236
+ }
237
+ const ethBalance = await client.getBalance({ address: account.address });
238
+ const minGas = parseEther("0.0005");
239
+ if (ethBalance < minGas) {
240
+ throw new Error(
241
+ `Insufficient ETH for gas. Have ${formatUnits(ethBalance, 18)} ETH, need at least 0.0005 ETH.`
242
+ );
243
+ }
244
+ }
245
+ async function redeem(shares, receiver) {
246
+ const client = getPublicClient();
247
+ const vaultAddress = getVaultAddress();
248
+ const account = getAccount();
249
+ const to = receiver ?? account.address;
250
+ const assetsOut = await client.readContract({
251
+ address: vaultAddress,
252
+ abi: SYNDICATE_VAULT_ABI,
253
+ functionName: "previewRedeem",
254
+ args: [shares]
255
+ });
256
+ const hash = await writeContractWithRetry({
257
+ account,
258
+ chain: getChain(),
259
+ address: vaultAddress,
260
+ abi: SYNDICATE_VAULT_ABI,
261
+ functionName: "redeem",
262
+ args: [shares, to, account.address]
263
+ });
264
+ await waitForReceipt(hash);
265
+ return { hash, assetsOut };
266
+ }
267
+ async function getShareBalance(address) {
268
+ const client = getPublicClient();
269
+ const owner = address ?? getAccount().address;
270
+ return client.readContract({
271
+ address: getVaultAddress(),
272
+ abi: SYNDICATE_VAULT_ABI,
273
+ functionName: "balanceOf",
274
+ args: [owner]
275
+ });
276
+ }
201
277
  async function executeBatch(calls) {
202
278
  const hash = await writeContractWithRetry({
203
279
  account: getAccount(),
@@ -421,6 +497,9 @@ export {
421
497
  preflightDeposit,
422
498
  depositWithEthWrap,
423
499
  deposit,
500
+ preflightRedeem,
501
+ redeem,
502
+ getShareBalance,
424
503
  executeBatch,
425
504
  approveDepositor,
426
505
  removeDepositor,
@@ -433,4 +512,4 @@ export {
433
512
  setTextRecord,
434
513
  getTextRecord
435
514
  };
436
- //# sourceMappingURL=chunk-ZIH3SCFJ.js.map
515
+ //# sourceMappingURL=chunk-G6LOQCM3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/vault.ts","../src/lib/ens.ts"],"sourcesContent":["/**\n * SyndicateVault contract wrapper.\n *\n * The vault is the onchain identity — it holds all positions via delegatecall\n * to a shared BatchExecutorLib. No separate executor contract needed.\n */\n\nimport type { Address, Hex } from \"viem\";\nimport { formatUnits, parseEther } from \"viem\";\nimport { getChain } from \"./network.js\";\nimport {\n getPublicClient,\n getAccount,\n getWalletClient,\n writeContractWithRetry,\n waitForReceipt,\n} from \"./client.js\";\nimport { SYNDICATE_VAULT_ABI, ERC20_ABI } from \"./abis.js\";\nimport type { BatchCall } from \"./batch.js\";\nimport { getChainContracts } from \"./config.js\";\nimport { TOKENS } from \"./addresses.js\";\n\n// Per-command override (set by --vault flag in index.ts)\nlet _vaultOverride: Address | null = null;\n\nexport function setVaultAddress(addr: Address): void {\n _vaultOverride = addr;\n}\n\nexport function getVaultAddress(): Address {\n // 1. Per-command override (--vault flag)\n if (_vaultOverride) return _vaultOverride;\n\n // 2. Config (~/.sherwood/config.json) — default vault\n const chainId = getChain().id;\n const fromConfig = getChainContracts(chainId).vault;\n if (fromConfig) return fromConfig as Address;\n\n throw new Error(\n \"Vault address not found. Pass --vault <addr> or run 'sherwood config set --vault <addr>'.\",\n );\n}\n\n// ── Asset Helpers ──\n\n/**\n * Read the vault's underlying ERC-20 asset address.\n */\nexport async function getAssetAddress(): Promise<Address> {\n const client = getPublicClient();\n return client.readContract({\n address: getVaultAddress(),\n abi: SYNDICATE_VAULT_ABI,\n functionName: \"asset\",\n }) as Promise<Address>;\n}\n\n/**\n * Read decimals from the vault's underlying asset.\n * Works with any ERC-20 (USDC=6, WETH=18, WBTC=8, etc.).\n */\nexport async function getAssetDecimals(): Promise<number> {\n const client = getPublicClient();\n const asset = await getAssetAddress();\n return client.readContract({\n address: asset,\n abi: ERC20_ABI,\n functionName: \"decimals\",\n }) as Promise<number>;\n}\n\n// ── WETH ABI (for auto-wrapping ETH) ──\n\nconst WETH_ABI = [\n {\n name: \"deposit\",\n type: \"function\",\n stateMutability: \"payable\",\n inputs: [],\n outputs: [],\n },\n] as const;\n\n// ── Pre-flight Checks ──\n\n/**\n * Validate that a deposit can succeed before submitting any transactions.\n * Throws descriptive errors if any pre-condition fails.\n */\nexport async function preflightDeposit(amount: bigint): Promise<void> {\n const client = getPublicClient();\n const vaultAddress = getVaultAddress();\n const account = getAccount();\n const asset = await getAssetAddress();\n const decimals = await getAssetDecimals();\n\n // 1. Check asset balance\n const balance = (await client.readContract({\n address: asset,\n abi: ERC20_ABI,\n functionName: \"balanceOf\",\n args: [account.address],\n })) as bigint;\n\n if (balance < amount) {\n const symbol = (await client.readContract({\n address: asset,\n abi: ERC20_ABI,\n functionName: \"symbol\",\n })) as string;\n throw new Error(\n `Insufficient ${symbol}. Have ${formatUnits(balance, decimals)}, need ${formatUnits(amount, decimals)}.`,\n );\n }\n\n // 2. Check ETH for gas\n const ethBalance = await client.getBalance({ address: account.address });\n const minGas = parseEther(\"0.0005\");\n if (ethBalance < minGas) {\n throw new Error(\n `Insufficient ETH for gas. Have ${formatUnits(ethBalance, 18)} ETH, need at least 0.0005 ETH. Top up your wallet with ETH on Base.`,\n );\n }\n\n // 3. Check vault not paused\n const paused = (await client.readContract({\n address: vaultAddress,\n abi: SYNDICATE_VAULT_ABI,\n functionName: \"paused\",\n })) as boolean;\n if (paused) {\n throw new Error(\"Vault is paused — deposits are temporarily disabled.\");\n }\n\n // 4. Check deposits not locked (active proposal blocks deposits)\n const locked = (await client.readContract({\n address: vaultAddress,\n abi: SYNDICATE_VAULT_ABI,\n functionName: \"redemptionsLocked\",\n })) as boolean;\n if (locked) {\n throw new Error(\n \"Deposits are locked while a strategy is executing. Wait for the proposal to be settled.\",\n );\n }\n\n // 5. Check depositor approval (if whitelist vault)\n const openDeposits = (await client.readContract({\n address: vaultAddress,\n abi: SYNDICATE_VAULT_ABI,\n functionName: \"openDeposits\",\n })) as boolean;\n if (!openDeposits) {\n const approved = (await client.readContract({\n address: vaultAddress,\n abi: SYNDICATE_VAULT_ABI,\n functionName: \"isApprovedDepositor\",\n args: [account.address],\n })) as boolean;\n if (!approved) {\n throw new Error(\n \"Your address is not an approved depositor. Ask the vault creator to approve you:\\n sherwood syndicate approve-depositor --depositor \" +\n account.address,\n );\n }\n }\n}\n\n// ── LP Functions ──\n\n/**\n * Deposit into the vault with optional ETH auto-wrapping for WETH vaults.\n * When `useEth` is true and the vault asset is WETH, wraps ETH first.\n */\nexport async function depositWithEthWrap(amount: bigint): Promise<Hex> {\n const client = getPublicClient();\n const account = getAccount();\n const asset = await getAssetAddress();\n const wethAddress = TOKENS().WETH;\n\n if (asset.toLowerCase() !== wethAddress.toLowerCase()) {\n throw new Error(\"--use-eth is only supported for WETH vaults.\");\n }\n\n // Check current WETH balance — only wrap the shortfall\n const wethBalance = (await client.readContract({\n address: wethAddress,\n abi: ERC20_ABI,\n functionName: \"balanceOf\",\n args: [account.address],\n })) as bigint;\n\n if (wethBalance < amount) {\n const shortfall = amount - wethBalance;\n\n // Verify sufficient ETH to cover shortfall + gas\n const ethBalance = await client.getBalance({ address: account.address });\n const minGas = parseEther(\"0.0005\");\n if (ethBalance < shortfall + minGas) {\n throw new Error(\n `Insufficient ETH. Have ${formatUnits(ethBalance, 18)} ETH, need ${formatUnits(shortfall, 18)} to wrap + gas.`,\n );\n }\n\n // Wrap ETH → WETH\n const wallet = getWalletClient();\n const wrapHash = await wallet.writeContract({\n address: wethAddress,\n abi: WETH_ABI,\n functionName: \"deposit\",\n args: [],\n value: shortfall,\n account,\n chain: getChain(),\n });\n await client.waitForTransactionReceipt({ hash: wrapHash });\n }\n\n // Proceed with normal deposit\n return deposit(amount);\n}\n\n/**\n * Deposit into the vault. Handles approval + deposit for the vault's asset.\n */\nexport async function deposit(amount: bigint): Promise<Hex> {\n const client = getPublicClient();\n const vaultAddress = getVaultAddress();\n const account = getAccount();\n const asset = await getAssetAddress();\n\n // Check existing allowance — skip approve if sufficient\n const currentAllowance = (await client.readContract({\n address: asset,\n abi: ERC20_ABI,\n functionName: \"allowance\",\n args: [account.address, vaultAddress],\n })) as bigint;\n\n if (currentAllowance < amount) {\n const approveHash = await writeContractWithRetry({\n account,\n chain: getChain(),\n address: asset,\n abi: ERC20_ABI,\n functionName: \"approve\",\n args: [vaultAddress, amount],\n });\n // Wait for approve to confirm before deposit — prevents nonce collision\n await waitForReceipt(approveHash);\n }\n\n // Deposit — retry wrapper handles nonce/gas automatically\n const depositHash = await writeContractWithRetry({\n account,\n chain: getChain(),\n address: vaultAddress,\n abi: SYNDICATE_VAULT_ABI,\n functionName: \"deposit\",\n args: [amount, account.address],\n });\n await waitForReceipt(depositHash);\n return depositHash;\n}\n\n// ── Redeem ──\n\n/**\n * Pre-flight check for redeem. Validates that the caller has enough shares\n * and that the vault allows redemption right now.\n */\nexport async function preflightRedeem(shares: bigint): Promise<void> {\n const client = getPublicClient();\n const vaultAddress = getVaultAddress();\n const account = getAccount();\n\n if (shares === 0n) {\n throw new Error(\"No shares to redeem.\");\n }\n\n // 1. Check share balance\n const balance = (await client.readContract({\n address: vaultAddress,\n abi: SYNDICATE_VAULT_ABI,\n functionName: \"balanceOf\",\n args: [account.address],\n })) as bigint;\n\n if (balance < shares) {\n throw new Error(\n `Insufficient shares. Have ${balance.toString()}, need ${shares.toString()}.`,\n );\n }\n\n // 2. Check vault not paused\n const paused = (await client.readContract({\n address: vaultAddress,\n abi: SYNDICATE_VAULT_ABI,\n functionName: \"paused\",\n })) as boolean;\n if (paused) {\n throw new Error(\"Vault is paused — redemptions are temporarily disabled.\");\n }\n\n // 3. Check redemptions not locked (active proposal blocks redemptions)\n const locked = (await client.readContract({\n address: vaultAddress,\n abi: SYNDICATE_VAULT_ABI,\n functionName: \"redemptionsLocked\",\n })) as boolean;\n if (locked) {\n throw new Error(\n \"Redemptions are locked while a strategy is executing. Wait for the proposal to be settled.\",\n );\n }\n\n // 4. Check ETH for gas\n const ethBalance = await client.getBalance({ address: account.address });\n const minGas = parseEther(\"0.0005\");\n if (ethBalance < minGas) {\n throw new Error(\n `Insufficient ETH for gas. Have ${formatUnits(ethBalance, 18)} ETH, need at least 0.0005 ETH.`,\n );\n }\n}\n\n/**\n * Redeem shares for the underlying asset (standard ERC-4626 redeem).\n * Returns the tx hash and the assets received.\n */\nexport async function redeem(\n shares: bigint,\n receiver?: Address,\n): Promise<{ hash: Hex; assetsOut: bigint }> {\n const client = getPublicClient();\n const vaultAddress = getVaultAddress();\n const account = getAccount();\n const to = receiver ?? account.address;\n\n // Preview so we can report assets received\n const assetsOut = (await client.readContract({\n address: vaultAddress,\n abi: SYNDICATE_VAULT_ABI,\n functionName: \"previewRedeem\",\n args: [shares],\n })) as bigint;\n\n const hash = await writeContractWithRetry({\n account,\n chain: getChain(),\n address: vaultAddress,\n abi: SYNDICATE_VAULT_ABI,\n functionName: \"redeem\",\n args: [shares, to, account.address],\n });\n await waitForReceipt(hash);\n return { hash, assetsOut };\n}\n\n/**\n * Read the current share balance for an address (defaults to the caller).\n */\nexport async function getShareBalance(address?: Address): Promise<bigint> {\n const client = getPublicClient();\n const owner = address ?? getAccount().address;\n return client.readContract({\n address: getVaultAddress(),\n abi: SYNDICATE_VAULT_ABI,\n functionName: \"balanceOf\",\n args: [owner],\n }) as Promise<bigint>;\n}\n\n// ── Batch Execution ──\n\n/**\n * Execute a batch of protocol calls through the vault (owner only).\n * The vault delegatecalls to the executor lib.\n * All calls execute as the vault — positions live on the vault.\n */\nexport async function executeBatch(calls: BatchCall[]): Promise<Hex> {\n const hash = await writeContractWithRetry({\n account: getAccount(),\n chain: getChain(),\n address: getVaultAddress(),\n abi: SYNDICATE_VAULT_ABI,\n functionName: \"executeBatch\",\n args: [\n calls.map((c) => ({\n target: c.target,\n data: c.data,\n value: c.value,\n })),\n ],\n });\n await waitForReceipt(hash);\n return hash;\n}\n\n// ── Depositor Management ──\n\n/**\n * Approve a depositor address (owner only).\n */\nexport async function approveDepositor(depositor: Address): Promise<Hex> {\n const hash = await writeContractWithRetry({\n account: getAccount(),\n chain: getChain(),\n address: getVaultAddress(),\n abi: SYNDICATE_VAULT_ABI,\n functionName: \"approveDepositor\",\n args: [depositor],\n });\n await waitForReceipt(hash);\n return hash;\n}\n\n/**\n * Remove a depositor from the whitelist (owner only).\n */\nexport async function removeDepositor(depositor: Address): Promise<Hex> {\n const hash = await writeContractWithRetry({\n account: getAccount(),\n chain: getChain(),\n address: getVaultAddress(),\n abi: SYNDICATE_VAULT_ABI,\n functionName: \"removeDepositor\",\n args: [depositor],\n });\n await waitForReceipt(hash);\n return hash;\n}\n\n/**\n * Approve multiple depositors in a batch (owner only).\n */\nexport async function approveDepositors(depositors: Address[]): Promise<Hex> {\n const hash = await writeContractWithRetry({\n account: getAccount(),\n chain: getChain(),\n address: getVaultAddress(),\n abi: SYNDICATE_VAULT_ABI,\n functionName: \"approveDepositors\",\n args: [depositors],\n });\n await waitForReceipt(hash);\n return hash;\n}\n\n/**\n * Check if an address is a registered agent on the vault.\n */\nexport async function isAgent(agentAddress: Address): Promise<boolean> {\n const client = getPublicClient();\n return client.readContract({\n address: getVaultAddress(),\n abi: SYNDICATE_VAULT_ABI,\n functionName: \"isAgent\",\n args: [agentAddress],\n }) as Promise<boolean>;\n}\n\n/**\n * Check if an address is an approved depositor.\n */\nexport async function isApprovedDepositor(depositor: Address): Promise<boolean> {\n const client = getPublicClient();\n return client.readContract({\n address: getVaultAddress(),\n abi: SYNDICATE_VAULT_ABI,\n functionName: \"isApprovedDepositor\",\n args: [depositor],\n }) as Promise<boolean>;\n}\n\n/**\n * Get LP share balance and asset value.\n */\nexport async function getBalance(address?: Address): Promise<{\n shares: bigint;\n assetsValue: string;\n percentOfVault: string;\n}> {\n const client = getPublicClient();\n const vaultAddress = getVaultAddress();\n const account = address || getAccount().address;\n\n const [shares, totalSupply] = await Promise.all([\n client.readContract({\n address: vaultAddress,\n abi: SYNDICATE_VAULT_ABI,\n functionName: \"balanceOf\",\n args: [account],\n }) as Promise<bigint>,\n client.readContract({\n address: vaultAddress,\n abi: SYNDICATE_VAULT_ABI,\n functionName: \"totalSupply\",\n }) as Promise<bigint>,\n ]);\n\n let assetsValue = 0n;\n if (shares > 0n) {\n assetsValue = (await client.readContract({\n address: vaultAddress,\n abi: SYNDICATE_VAULT_ABI,\n functionName: \"convertToAssets\",\n args: [shares],\n })) as bigint;\n }\n\n const percent =\n totalSupply > 0n ? ((Number(shares) / Number(totalSupply)) * 100).toFixed(2) : \"0.00\";\n\n const decimals = await getAssetDecimals();\n\n return {\n shares,\n assetsValue: formatUnits(assetsValue, decimals),\n percentOfVault: `${percent}%`,\n };\n}\n\n// ── Agent Management ──\n\n/**\n * Register a new agent (owner only). Requires ERC-8004 agent identity.\n */\nexport async function registerAgent(\n agentId: bigint,\n agentAddress: Address,\n): Promise<Hex> {\n const hash = await writeContractWithRetry({\n account: getAccount(),\n chain: getChain(),\n address: getVaultAddress(),\n abi: SYNDICATE_VAULT_ABI,\n functionName: \"registerAgent\",\n args: [agentId, agentAddress],\n });\n await waitForReceipt(hash);\n return hash;\n}\n\n// ── Views ──\n\nexport interface VaultInfo {\n address: Address;\n totalAssets: string;\n agentCount: bigint;\n redemptionsLocked: boolean;\n managementFeeBps: bigint;\n}\n\n/**\n * Get vault overview info.\n */\nexport async function getVaultInfo(): Promise<VaultInfo> {\n const client = getPublicClient();\n const vaultAddress = getVaultAddress();\n\n const [totalAssets, agentCount, redemptionsLocked, managementFeeBps, decimals] =\n await Promise.all([\n client.readContract({\n address: vaultAddress,\n abi: SYNDICATE_VAULT_ABI,\n functionName: \"totalAssets\",\n }) as Promise<bigint>,\n client.readContract({\n address: vaultAddress,\n abi: SYNDICATE_VAULT_ABI,\n functionName: \"getAgentCount\",\n }) as Promise<bigint>,\n client.readContract({\n address: vaultAddress,\n abi: SYNDICATE_VAULT_ABI,\n functionName: \"redemptionsLocked\",\n }) as Promise<boolean>,\n client.readContract({\n address: vaultAddress,\n abi: SYNDICATE_VAULT_ABI,\n functionName: \"managementFeeBps\",\n }) as Promise<bigint>,\n getAssetDecimals(),\n ]);\n\n return {\n address: vaultAddress,\n totalAssets: formatUnits(totalAssets, decimals),\n agentCount,\n redemptionsLocked,\n managementFeeBps,\n };\n}\n","/**\n * ENS resolution + text records via Durin L2Registry on Base.\n *\n * Two responsibilities:\n * 1. Resolve syndicate subdomain → on-chain syndicate data (via factory)\n * 2. Read/write ENS text records (via L2Registry, routed through vault's executeBatch)\n *\n * The vault owns the ENS subdomain node (registered in the factory via\n * `ensRegistrar.register(subdomain, vault)`). Only the vault can write text\n * records. We route writes through vault.executeBatch → L2Registry.setText,\n * which executes as the vault via delegatecall to the shared executor lib.\n */\n\nimport { encodeFunctionData } from \"viem\";\nimport type { Address, Hex } from \"viem\";\nimport { namehash } from \"viem/ens\";\nimport { getPublicClient, getWalletClient, getAccount, waitForReceipt } from \"./client.js\";\nimport { getChain, getNetwork } from \"./network.js\";\nimport { SYNDICATE_FACTORY_ABI, L2_REGISTRY_ABI } from \"./abis.js\";\nimport { ENS, SHERWOOD } from \"./addresses.js\";\nimport * as vaultLib from \"./vault.js\";\n\n/**\n * Wait for a transaction to be mined before proceeding.\n */\nasync function waitForTx(hash: Hex): Promise<void> {\n await waitForReceipt(hash);\n}\n\nconst ENS_DOMAIN = \"sherwoodagent.eth\";\n\nfunction getFactoryAddress(): Address {\n return SHERWOOD().FACTORY;\n}\n\n// ── Syndicate Resolution (via factory) ──\n\nexport interface SyndicateResolution {\n id: bigint;\n vault: Address;\n creator: Address;\n subdomain: string;\n}\n\n/**\n * Resolve a syndicate subdomain to its on-chain data.\n * Uses factory.subdomainToSyndicate() → factory.syndicates().\n */\nexport async function resolveSyndicate(subdomain: string): Promise<SyndicateResolution> {\n const client = getPublicClient();\n const factory = getFactoryAddress();\n\n // Get syndicate ID from subdomain\n const syndicateId = (await client.readContract({\n address: factory,\n abi: SYNDICATE_FACTORY_ABI,\n functionName: \"subdomainToSyndicate\",\n args: [subdomain],\n })) as bigint;\n\n if (syndicateId === 0n) {\n throw new Error(`Syndicate \"${subdomain}\" not found`);\n }\n\n // Get full syndicate record\n const result = (await client.readContract({\n address: factory,\n abi: SYNDICATE_FACTORY_ABI,\n functionName: \"syndicates\",\n args: [syndicateId],\n })) as [bigint, Address, Address, string, bigint, boolean, string];\n\n return {\n id: result[0],\n vault: result[1],\n creator: result[2],\n subdomain: result[6],\n };\n}\n\n/**\n * Reverse lookup: vault address → syndicate info.\n * Uses factory.vaultToSyndicate() → factory.syndicates().\n */\nexport async function resolveVaultSyndicate(\n vaultAddress: Address,\n): Promise<SyndicateResolution> {\n const client = getPublicClient();\n const factory = getFactoryAddress();\n\n const syndicateId = (await client.readContract({\n address: factory,\n abi: SYNDICATE_FACTORY_ABI,\n functionName: \"vaultToSyndicate\",\n args: [vaultAddress],\n })) as bigint;\n\n if (syndicateId === 0n) {\n throw new Error(`No syndicate found for vault ${vaultAddress}`);\n }\n\n const result = (await client.readContract({\n address: factory,\n abi: SYNDICATE_FACTORY_ABI,\n functionName: \"syndicates\",\n args: [syndicateId],\n })) as [bigint, Address, Address, string, bigint, boolean, string];\n\n return {\n id: result[0],\n vault: result[1],\n creator: result[2],\n subdomain: result[6],\n };\n}\n\n// ── ENS Text Records (via L2Registry) ──\n\n/**\n * Compute the ENS node hash for a subdomain under sherwoodagent.eth.\n */\nfunction getSubdomainNode(subdomain: string): Hex {\n return namehash(`${subdomain}.${ENS_DOMAIN}`);\n}\n\n/**\n * Write a text record to the L2Registry via the vault's executeBatch.\n *\n * The vault owns the ENS node, so only the vault can call setText.\n * We route the call through vault.executeBatch (delegatecall → executor lib → L2Registry),\n * which means L2Registry sees msg.sender = vault address.\n *\n * Requires the caller to be a registered agent on the vault (creator is auto-registered).\n */\nexport async function setTextRecord(\n subdomain: string,\n key: string,\n value: string,\n vaultAddress: Address,\n): Promise<Hex> {\n const l2Registry = ENS().L2_REGISTRY;\n const node = getSubdomainNode(subdomain);\n\n vaultLib.setVaultAddress(vaultAddress);\n\n // Encode the L2Registry.setText call\n const setTextData = encodeFunctionData({\n abi: L2_REGISTRY_ABI,\n functionName: \"setText\",\n args: [node, key, value],\n });\n\n // Route through vault.executeBatch (owner only)\n return vaultLib.executeBatch(\n [{ target: l2Registry, data: setTextData, value: 0n }],\n );\n}\n\n/**\n * Read a text record from the L2Registry.\n * Used to look up xmtpGroupId when not cached locally.\n */\nexport async function getTextRecord(\n subdomain: string,\n key: string,\n): Promise<string> {\n const client = getPublicClient();\n const node = getSubdomainNode(subdomain);\n\n return client.readContract({\n address: ENS().L2_REGISTRY,\n abi: L2_REGISTRY_ABI,\n functionName: \"text\",\n args: [node, key],\n }) as Promise<string>;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAQA,SAAS,aAAa,kBAAkB;AAexC,IAAI,iBAAiC;AAE9B,SAAS,gBAAgB,MAAqB;AACnD,mBAAiB;AACnB;AAEO,SAAS,kBAA2B;AAEzC,MAAI,eAAgB,QAAO;AAG3B,QAAM,UAAU,SAAS,EAAE;AAC3B,QAAM,aAAa,kBAAkB,OAAO,EAAE;AAC9C,MAAI,WAAY,QAAO;AAEvB,QAAM,IAAI;AAAA,IACR;AAAA,EACF;AACF;AAOA,eAAsB,kBAAoC;AACxD,QAAM,SAAS,gBAAgB;AAC/B,SAAO,OAAO,aAAa;AAAA,IACzB,SAAS,gBAAgB;AAAA,IACzB,KAAK;AAAA,IACL,cAAc;AAAA,EAChB,CAAC;AACH;AAMA,eAAsB,mBAAoC;AACxD,QAAM,SAAS,gBAAgB;AAC/B,QAAM,QAAQ,MAAM,gBAAgB;AACpC,SAAO,OAAO,aAAa;AAAA,IACzB,SAAS;AAAA,IACT,KAAK;AAAA,IACL,cAAc;AAAA,EAChB,CAAC;AACH;AAIA,IAAM,WAAW;AAAA,EACf;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ,CAAC;AAAA,IACT,SAAS,CAAC;AAAA,EACZ;AACF;AAQA,eAAsB,iBAAiB,QAA+B;AACpE,QAAM,SAAS,gBAAgB;AAC/B,QAAM,eAAe,gBAAgB;AACrC,QAAM,UAAU,WAAW;AAC3B,QAAM,QAAQ,MAAM,gBAAgB;AACpC,QAAM,WAAW,MAAM,iBAAiB;AAGxC,QAAM,UAAW,MAAM,OAAO,aAAa;AAAA,IACzC,SAAS;AAAA,IACT,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC,QAAQ,OAAO;AAAA,EACxB,CAAC;AAED,MAAI,UAAU,QAAQ;AACpB,UAAM,SAAU,MAAM,OAAO,aAAa;AAAA,MACxC,SAAS;AAAA,MACT,KAAK;AAAA,MACL,cAAc;AAAA,IAChB,CAAC;AACD,UAAM,IAAI;AAAA,MACR,gBAAgB,MAAM,UAAU,YAAY,SAAS,QAAQ,CAAC,UAAU,YAAY,QAAQ,QAAQ,CAAC;AAAA,IACvG;AAAA,EACF;AAGA,QAAM,aAAa,MAAM,OAAO,WAAW,EAAE,SAAS,QAAQ,QAAQ,CAAC;AACvE,QAAM,SAAS,WAAW,QAAQ;AAClC,MAAI,aAAa,QAAQ;AACvB,UAAM,IAAI;AAAA,MACR,kCAAkC,YAAY,YAAY,EAAE,CAAC;AAAA,IAC/D;AAAA,EACF;AAGA,QAAM,SAAU,MAAM,OAAO,aAAa;AAAA,IACxC,SAAS;AAAA,IACT,KAAK;AAAA,IACL,cAAc;AAAA,EAChB,CAAC;AACD,MAAI,QAAQ;AACV,UAAM,IAAI,MAAM,2DAAsD;AAAA,EACxE;AAGA,QAAM,SAAU,MAAM,OAAO,aAAa;AAAA,IACxC,SAAS;AAAA,IACT,KAAK;AAAA,IACL,cAAc;AAAA,EAChB,CAAC;AACD,MAAI,QAAQ;AACV,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAGA,QAAM,eAAgB,MAAM,OAAO,aAAa;AAAA,IAC9C,SAAS;AAAA,IACT,KAAK;AAAA,IACL,cAAc;AAAA,EAChB,CAAC;AACD,MAAI,CAAC,cAAc;AACjB,UAAM,WAAY,MAAM,OAAO,aAAa;AAAA,MAC1C,SAAS;AAAA,MACT,KAAK;AAAA,MACL,cAAc;AAAA,MACd,MAAM,CAAC,QAAQ,OAAO;AAAA,IACxB,CAAC;AACD,QAAI,CAAC,UAAU;AACb,YAAM,IAAI;AAAA,QACR,0IACA,QAAQ;AAAA,MACV;AAAA,IACF;AAAA,EACF;AACF;AAQA,eAAsB,mBAAmB,QAA8B;AACrE,QAAM,SAAS,gBAAgB;AAC/B,QAAM,UAAU,WAAW;AAC3B,QAAM,QAAQ,MAAM,gBAAgB;AACpC,QAAM,cAAc,OAAO,EAAE;AAE7B,MAAI,MAAM,YAAY,MAAM,YAAY,YAAY,GAAG;AACrD,UAAM,IAAI,MAAM,8CAA8C;AAAA,EAChE;AAGA,QAAM,cAAe,MAAM,OAAO,aAAa;AAAA,IAC7C,SAAS;AAAA,IACT,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC,QAAQ,OAAO;AAAA,EACxB,CAAC;AAED,MAAI,cAAc,QAAQ;AACxB,UAAM,YAAY,SAAS;AAG3B,UAAM,aAAa,MAAM,OAAO,WAAW,EAAE,SAAS,QAAQ,QAAQ,CAAC;AACvE,UAAM,SAAS,WAAW,QAAQ;AAClC,QAAI,aAAa,YAAY,QAAQ;AACnC,YAAM,IAAI;AAAA,QACR,0BAA0B,YAAY,YAAY,EAAE,CAAC,cAAc,YAAY,WAAW,EAAE,CAAC;AAAA,MAC/F;AAAA,IACF;AAGA,UAAM,SAAS,gBAAgB;AAC/B,UAAM,WAAW,MAAM,OAAO,cAAc;AAAA,MAC1C,SAAS;AAAA,MACT,KAAK;AAAA,MACL,cAAc;AAAA,MACd,MAAM,CAAC;AAAA,MACP,OAAO;AAAA,MACP;AAAA,MACA,OAAO,SAAS;AAAA,IAClB,CAAC;AACD,UAAM,OAAO,0BAA0B,EAAE,MAAM,SAAS,CAAC;AAAA,EAC3D;AAGA,SAAO,QAAQ,MAAM;AACvB;AAKA,eAAsB,QAAQ,QAA8B;AAC1D,QAAM,SAAS,gBAAgB;AAC/B,QAAM,eAAe,gBAAgB;AACrC,QAAM,UAAU,WAAW;AAC3B,QAAM,QAAQ,MAAM,gBAAgB;AAGpC,QAAM,mBAAoB,MAAM,OAAO,aAAa;AAAA,IAClD,SAAS;AAAA,IACT,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC,QAAQ,SAAS,YAAY;AAAA,EACtC,CAAC;AAED,MAAI,mBAAmB,QAAQ;AAC7B,UAAM,cAAc,MAAM,uBAAuB;AAAA,MAC/C;AAAA,MACA,OAAO,SAAS;AAAA,MAChB,SAAS;AAAA,MACT,KAAK;AAAA,MACL,cAAc;AAAA,MACd,MAAM,CAAC,cAAc,MAAM;AAAA,IAC7B,CAAC;AAED,UAAM,eAAe,WAAW;AAAA,EAClC;AAGA,QAAM,cAAc,MAAM,uBAAuB;AAAA,IAC/C;AAAA,IACA,OAAO,SAAS;AAAA,IAChB,SAAS;AAAA,IACT,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC,QAAQ,QAAQ,OAAO;AAAA,EAChC,CAAC;AACD,QAAM,eAAe,WAAW;AAChC,SAAO;AACT;AAQA,eAAsB,gBAAgB,QAA+B;AACnE,QAAM,SAAS,gBAAgB;AAC/B,QAAM,eAAe,gBAAgB;AACrC,QAAM,UAAU,WAAW;AAE3B,MAAI,WAAW,IAAI;AACjB,UAAM,IAAI,MAAM,sBAAsB;AAAA,EACxC;AAGA,QAAM,UAAW,MAAM,OAAO,aAAa;AAAA,IACzC,SAAS;AAAA,IACT,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC,QAAQ,OAAO;AAAA,EACxB,CAAC;AAED,MAAI,UAAU,QAAQ;AACpB,UAAM,IAAI;AAAA,MACR,6BAA6B,QAAQ,SAAS,CAAC,UAAU,OAAO,SAAS,CAAC;AAAA,IAC5E;AAAA,EACF;AAGA,QAAM,SAAU,MAAM,OAAO,aAAa;AAAA,IACxC,SAAS;AAAA,IACT,KAAK;AAAA,IACL,cAAc;AAAA,EAChB,CAAC;AACD,MAAI,QAAQ;AACV,UAAM,IAAI,MAAM,8DAAyD;AAAA,EAC3E;AAGA,QAAM,SAAU,MAAM,OAAO,aAAa;AAAA,IACxC,SAAS;AAAA,IACT,KAAK;AAAA,IACL,cAAc;AAAA,EAChB,CAAC;AACD,MAAI,QAAQ;AACV,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAGA,QAAM,aAAa,MAAM,OAAO,WAAW,EAAE,SAAS,QAAQ,QAAQ,CAAC;AACvE,QAAM,SAAS,WAAW,QAAQ;AAClC,MAAI,aAAa,QAAQ;AACvB,UAAM,IAAI;AAAA,MACR,kCAAkC,YAAY,YAAY,EAAE,CAAC;AAAA,IAC/D;AAAA,EACF;AACF;AAMA,eAAsB,OACpB,QACA,UAC2C;AAC3C,QAAM,SAAS,gBAAgB;AAC/B,QAAM,eAAe,gBAAgB;AACrC,QAAM,UAAU,WAAW;AAC3B,QAAM,KAAK,YAAY,QAAQ;AAG/B,QAAM,YAAa,MAAM,OAAO,aAAa;AAAA,IAC3C,SAAS;AAAA,IACT,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC,MAAM;AAAA,EACf,CAAC;AAED,QAAM,OAAO,MAAM,uBAAuB;AAAA,IACxC;AAAA,IACA,OAAO,SAAS;AAAA,IAChB,SAAS;AAAA,IACT,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC,QAAQ,IAAI,QAAQ,OAAO;AAAA,EACpC,CAAC;AACD,QAAM,eAAe,IAAI;AACzB,SAAO,EAAE,MAAM,UAAU;AAC3B;AAKA,eAAsB,gBAAgB,SAAoC;AACxE,QAAM,SAAS,gBAAgB;AAC/B,QAAM,QAAQ,WAAW,WAAW,EAAE;AACtC,SAAO,OAAO,aAAa;AAAA,IACzB,SAAS,gBAAgB;AAAA,IACzB,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC,KAAK;AAAA,EACd,CAAC;AACH;AASA,eAAsB,aAAa,OAAkC;AACnE,QAAM,OAAO,MAAM,uBAAuB;AAAA,IACxC,SAAS,WAAW;AAAA,IACpB,OAAO,SAAS;AAAA,IAChB,SAAS,gBAAgB;AAAA,IACzB,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM;AAAA,MACJ,MAAM,IAAI,CAAC,OAAO;AAAA,QAChB,QAAQ,EAAE;AAAA,QACV,MAAM,EAAE;AAAA,QACR,OAAO,EAAE;AAAA,MACX,EAAE;AAAA,IACJ;AAAA,EACF,CAAC;AACD,QAAM,eAAe,IAAI;AACzB,SAAO;AACT;AAOA,eAAsB,iBAAiB,WAAkC;AACvE,QAAM,OAAO,MAAM,uBAAuB;AAAA,IACxC,SAAS,WAAW;AAAA,IACpB,OAAO,SAAS;AAAA,IAChB,SAAS,gBAAgB;AAAA,IACzB,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC,SAAS;AAAA,EAClB,CAAC;AACD,QAAM,eAAe,IAAI;AACzB,SAAO;AACT;AAKA,eAAsB,gBAAgB,WAAkC;AACtE,QAAM,OAAO,MAAM,uBAAuB;AAAA,IACxC,SAAS,WAAW;AAAA,IACpB,OAAO,SAAS;AAAA,IAChB,SAAS,gBAAgB;AAAA,IACzB,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC,SAAS;AAAA,EAClB,CAAC;AACD,QAAM,eAAe,IAAI;AACzB,SAAO;AACT;AAqBA,eAAsB,QAAQ,cAAyC;AACrE,QAAM,SAAS,gBAAgB;AAC/B,SAAO,OAAO,aAAa;AAAA,IACzB,SAAS,gBAAgB;AAAA,IACzB,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC,YAAY;AAAA,EACrB,CAAC;AACH;AAkBA,eAAsB,WAAW,SAI9B;AACD,QAAM,SAAS,gBAAgB;AAC/B,QAAM,eAAe,gBAAgB;AACrC,QAAM,UAAU,WAAW,WAAW,EAAE;AAExC,QAAM,CAAC,QAAQ,WAAW,IAAI,MAAM,QAAQ,IAAI;AAAA,IAC9C,OAAO,aAAa;AAAA,MAClB,SAAS;AAAA,MACT,KAAK;AAAA,MACL,cAAc;AAAA,MACd,MAAM,CAAC,OAAO;AAAA,IAChB,CAAC;AAAA,IACD,OAAO,aAAa;AAAA,MAClB,SAAS;AAAA,MACT,KAAK;AAAA,MACL,cAAc;AAAA,IAChB,CAAC;AAAA,EACH,CAAC;AAED,MAAI,cAAc;AAClB,MAAI,SAAS,IAAI;AACf,kBAAe,MAAM,OAAO,aAAa;AAAA,MACvC,SAAS;AAAA,MACT,KAAK;AAAA,MACL,cAAc;AAAA,MACd,MAAM,CAAC,MAAM;AAAA,IACf,CAAC;AAAA,EACH;AAEA,QAAM,UACJ,cAAc,MAAO,OAAO,MAAM,IAAI,OAAO,WAAW,IAAK,KAAK,QAAQ,CAAC,IAAI;AAEjF,QAAM,WAAW,MAAM,iBAAiB;AAExC,SAAO;AAAA,IACL;AAAA,IACA,aAAa,YAAY,aAAa,QAAQ;AAAA,IAC9C,gBAAgB,GAAG,OAAO;AAAA,EAC5B;AACF;AAOA,eAAsB,cACpB,SACA,cACc;AACd,QAAM,OAAO,MAAM,uBAAuB;AAAA,IACxC,SAAS,WAAW;AAAA,IACpB,OAAO,SAAS;AAAA,IAChB,SAAS,gBAAgB;AAAA,IACzB,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC,SAAS,YAAY;AAAA,EAC9B,CAAC;AACD,QAAM,eAAe,IAAI;AACzB,SAAO;AACT;AAeA,eAAsB,eAAmC;AACvD,QAAM,SAAS,gBAAgB;AAC/B,QAAM,eAAe,gBAAgB;AAErC,QAAM,CAAC,aAAa,YAAY,mBAAmB,kBAAkB,QAAQ,IAC3E,MAAM,QAAQ,IAAI;AAAA,IAChB,OAAO,aAAa;AAAA,MAClB,SAAS;AAAA,MACT,KAAK;AAAA,MACL,cAAc;AAAA,IAChB,CAAC;AAAA,IACD,OAAO,aAAa;AAAA,MAClB,SAAS;AAAA,MACT,KAAK;AAAA,MACL,cAAc;AAAA,IAChB,CAAC;AAAA,IACD,OAAO,aAAa;AAAA,MAClB,SAAS;AAAA,MACT,KAAK;AAAA,MACL,cAAc;AAAA,IAChB,CAAC;AAAA,IACD,OAAO,aAAa;AAAA,MAClB,SAAS;AAAA,MACT,KAAK;AAAA,MACL,cAAc;AAAA,IAChB,CAAC;AAAA,IACD,iBAAiB;AAAA,EACnB,CAAC;AAEH,SAAO;AAAA,IACL,SAAS;AAAA,IACT,aAAa,YAAY,aAAa,QAAQ;AAAA,IAC9C;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;ACpkBA,SAAS,0BAA0B;AAEnC,SAAS,gBAAgB;AAczB,IAAM,aAAa;AAEnB,SAAS,oBAA6B;AACpC,SAAO,SAAS,EAAE;AACpB;AAeA,eAAsB,iBAAiB,WAAiD;AACtF,QAAM,SAAS,gBAAgB;AAC/B,QAAM,UAAU,kBAAkB;AAGlC,QAAM,cAAe,MAAM,OAAO,aAAa;AAAA,IAC7C,SAAS;AAAA,IACT,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC,SAAS;AAAA,EAClB,CAAC;AAED,MAAI,gBAAgB,IAAI;AACtB,UAAM,IAAI,MAAM,cAAc,SAAS,aAAa;AAAA,EACtD;AAGA,QAAM,SAAU,MAAM,OAAO,aAAa;AAAA,IACxC,SAAS;AAAA,IACT,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC,WAAW;AAAA,EACpB,CAAC;AAED,SAAO;AAAA,IACL,IAAI,OAAO,CAAC;AAAA,IACZ,OAAO,OAAO,CAAC;AAAA,IACf,SAAS,OAAO,CAAC;AAAA,IACjB,WAAW,OAAO,CAAC;AAAA,EACrB;AACF;AAMA,eAAsB,sBACpB,cAC8B;AAC9B,QAAM,SAAS,gBAAgB;AAC/B,QAAM,UAAU,kBAAkB;AAElC,QAAM,cAAe,MAAM,OAAO,aAAa;AAAA,IAC7C,SAAS;AAAA,IACT,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC,YAAY;AAAA,EACrB,CAAC;AAED,MAAI,gBAAgB,IAAI;AACtB,UAAM,IAAI,MAAM,gCAAgC,YAAY,EAAE;AAAA,EAChE;AAEA,QAAM,SAAU,MAAM,OAAO,aAAa;AAAA,IACxC,SAAS;AAAA,IACT,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC,WAAW;AAAA,EACpB,CAAC;AAED,SAAO;AAAA,IACL,IAAI,OAAO,CAAC;AAAA,IACZ,OAAO,OAAO,CAAC;AAAA,IACf,SAAS,OAAO,CAAC;AAAA,IACjB,WAAW,OAAO,CAAC;AAAA,EACrB;AACF;AAOA,SAAS,iBAAiB,WAAwB;AAChD,SAAO,SAAS,GAAG,SAAS,IAAI,UAAU,EAAE;AAC9C;AAWA,eAAsB,cACpB,WACA,KACA,OACA,cACc;AACd,QAAM,aAAa,IAAI,EAAE;AACzB,QAAM,OAAO,iBAAiB,SAAS;AAEvC,EAAS,gBAAgB,YAAY;AAGrC,QAAM,cAAc,mBAAmB;AAAA,IACrC,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC,MAAM,KAAK,KAAK;AAAA,EACzB,CAAC;AAGD,SAAgB;AAAA,IACd,CAAC,EAAE,QAAQ,YAAY,MAAM,aAAa,OAAO,GAAG,CAAC;AAAA,EACvD;AACF;AAMA,eAAsB,cACpB,WACA,KACiB;AACjB,QAAM,SAAS,gBAAgB;AAC/B,QAAM,OAAO,iBAAiB,SAAS;AAEvC,SAAO,OAAO,aAAa;AAAA,IACzB,SAAS,IAAI,EAAE;AAAA,IACf,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC,MAAM,GAAG;AAAA,EAClB,CAAC;AACH;","names":[]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getConfigRpcUrl
3
- } from "./chunk-5S2TBADL.js";
3
+ } from "./chunk-RGOTBJIN.js";
4
4
 
5
5
  // src/lib/network.ts
6
6
  import { defineChain } from "viem";
@@ -104,4 +104,4 @@ export {
104
104
  getExplorerUrl,
105
105
  isTestnet
106
106
  };
107
- //# sourceMappingURL=chunk-35536GNW.js.map
107
+ //# sourceMappingURL=chunk-GWIW6DDG.js.map
@@ -1,21 +1,21 @@
1
1
  import {
2
2
  UNISWAP,
3
3
  UNISWAP_QUOTER_V2_ABI
4
- } from "./chunk-R75DM3VL.js";
4
+ } from "./chunk-O7QIRMJO.js";
5
5
  import {
6
6
  getAccount,
7
7
  getPublicClient,
8
8
  sendTxWithRetry,
9
9
  waitForReceipt
10
- } from "./chunk-R7Q2L6VV.js";
10
+ } from "./chunk-SBVHGUQJ.js";
11
11
  import {
12
12
  getChain
13
- } from "./chunk-35536GNW.js";
13
+ } from "./chunk-GWIW6DDG.js";
14
14
  import {
15
15
  getUniswapApiKey,
16
16
  getVeniceApiKey,
17
17
  setVeniceApiKey
18
- } from "./chunk-5S2TBADL.js";
18
+ } from "./chunk-RGOTBJIN.js";
19
19
 
20
20
  // src/providers/uniswap.ts
21
21
  import { isAddress } from "viem";
@@ -449,4 +449,4 @@ export {
449
449
  encodeSwapPath,
450
450
  getMultiHopQuote
451
451
  };
452
- //# sourceMappingURL=chunk-PEJPTKLK.js.map
452
+ //# sourceMappingURL=chunk-L5RWZSET.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getNetwork
3
- } from "./chunk-35536GNW.js";
3
+ } from "./chunk-GWIW6DDG.js";
4
4
 
5
5
  // src/lib/addresses.ts
6
6
  var ZERO = "0x0000000000000000000000000000000000000000";
@@ -26,7 +26,8 @@ var BASE_MOONWELL = {
26
26
  };
27
27
  var BASE_UNISWAP = {
28
28
  SWAP_ROUTER: "0x2626664c2603336E57B271c5C0b26F421741e481",
29
- QUOTER_V2: "0x3d4e44Eb1374240CE5F1B871ab261CD16335B76a"
29
+ QUOTER_V2: "0x3d4e44Eb1374240CE5F1B871ab261CD16335B76a",
30
+ SWAP_ADAPTER: "0x121AaC2B96Ec365e457fcCc1C2ED5a6142064069"
30
31
  };
31
32
  var BASE_SEPOLIA_TOKENS = {
32
33
  USDC: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
@@ -52,8 +53,9 @@ var BASE_SEPOLIA_MOONWELL = {
52
53
  var BASE_SEPOLIA_UNISWAP = {
53
54
  SWAP_ROUTER: "0x94cC0AaC535CCDB3C01d6787D6413C739ae12bc4",
54
55
  // Uniswap V3 SwapRouter02
55
- QUOTER_V2: "0xC5290058841028F1614F3A6F0F5816cAd0df5E27"
56
+ QUOTER_V2: "0xC5290058841028F1614F3A6F0F5816cAd0df5E27",
56
57
  // Uniswap V3 QuoterV2
58
+ SWAP_ADAPTER: ZERO
57
59
  };
58
60
  var ROBINHOOD_TESTNET_TOKENS = {
59
61
  USDC: ZERO,
@@ -81,7 +83,8 @@ var ROBINHOOD_TESTNET_MOONWELL = {
81
83
  };
82
84
  var ROBINHOOD_TESTNET_UNISWAP = {
83
85
  SWAP_ROUTER: ZERO,
84
- QUOTER_V2: ZERO
86
+ QUOTER_V2: ZERO,
87
+ SWAP_ADAPTER: ZERO
85
88
  };
86
89
  var BASE_SYNTHRA = { ROUTER: ZERO, QUOTER: ZERO, FACTORY: ZERO };
87
90
  var BASE_SEPOLIA_SYNTHRA = { ROUTER: ZERO, QUOTER: ZERO, FACTORY: ZERO };
@@ -90,7 +93,7 @@ var ROBINHOOD_TESTNET_SYNTHRA = {
90
93
  QUOTER: "0x231606c321A99DE81e28fE48B07a93F1ba49e713",
91
94
  FACTORY: "0x911b4000D3422F482F4062a913885f7b035382Df"
92
95
  };
93
- var BASE_CHAINLINK = { VERIFIER_PROXY: ZERO };
96
+ var BASE_CHAINLINK = { VERIFIER_PROXY: "0xDE1A28D87Afd0f546505B28AB50410A5c3a7387a" };
94
97
  var BASE_SEPOLIA_CHAINLINK = { VERIFIER_PROXY: ZERO };
95
98
  var ROBINHOOD_TESTNET_CHAINLINK = {
96
99
  VERIFIER_PROXY: "0x72790f9eB82db492a7DDb6d2af22A270Dcc3Db64"
@@ -165,7 +168,7 @@ var BASE_STRATEGY_TEMPLATES = {
165
168
  VENICE_INFERENCE: "0xd882056ba6b0aEd8908c541884B327121E2f2C9C",
166
169
  WSTETH_MOONWELL: "0x6d026e2f5Ff0C34A01690EC46Cb601B8fF391985",
167
170
  MAMO_YIELD: "0x5c98808Ce5e51767ba2d969F75312eEFF0b14a6A",
168
- PORTFOLIO: ZERO
171
+ PORTFOLIO: "0x7865eEA4063c22d0F55FdD412D345495c7b73f64"
169
172
  };
170
173
  var BASE_SEPOLIA_STRATEGY_TEMPLATES = {
171
174
  MOONWELL_SUPPLY: ZERO,
@@ -552,6 +555,31 @@ var SYNDICATE_VAULT_ABI = [
552
555
  inputs: [],
553
556
  outputs: [{ name: "", type: "uint256" }]
554
557
  },
558
+ {
559
+ name: "previewRedeem",
560
+ type: "function",
561
+ stateMutability: "view",
562
+ inputs: [{ name: "shares", type: "uint256" }],
563
+ outputs: [{ name: "assets", type: "uint256" }]
564
+ },
565
+ {
566
+ name: "maxRedeem",
567
+ type: "function",
568
+ stateMutability: "view",
569
+ inputs: [{ name: "owner", type: "address" }],
570
+ outputs: [{ name: "shares", type: "uint256" }]
571
+ },
572
+ {
573
+ name: "redeem",
574
+ type: "function",
575
+ stateMutability: "nonpayable",
576
+ inputs: [
577
+ { name: "shares", type: "uint256" },
578
+ { name: "receiver", type: "address" },
579
+ { name: "owner", type: "address" }
580
+ ],
581
+ outputs: [{ name: "assets", type: "uint256" }]
582
+ },
555
583
  // ── Events ──
556
584
  {
557
585
  name: "AgentRegistered",
@@ -1655,4 +1683,4 @@ export {
1655
1683
  BASE_STRATEGY_ABI,
1656
1684
  PORTFOLIO_STRATEGY_ABI
1657
1685
  };
1658
- //# sourceMappingURL=chunk-R75DM3VL.js.map
1686
+ //# sourceMappingURL=chunk-O7QIRMJO.js.map