@sherwoodagent/cli 0.87.0 → 0.88.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/dist/{agent-A2JEYGQS.js → agent-FCGZL4GF.js} +4 -4
  2. package/dist/{chat-OZAAN5LT.js → chat-AKLYUJZV.js} +6 -6
  3. package/dist/{chunk-37GT3TJX.js → chunk-4ITTHKRX.js} +3 -3
  4. package/dist/{chunk-TTF5TDRV.js → chunk-6D3FNU75.js} +3 -3
  5. package/dist/{chunk-3UYGXGMF.js → chunk-6SAE2VDK.js} +2 -2
  6. package/dist/{chunk-R6F57QQF.js → chunk-BH3VTJ4F.js} +3 -3
  7. package/dist/{chunk-MIAMGVZ4.js → chunk-D4BSBW3Q.js} +215 -4
  8. package/dist/chunk-D4BSBW3Q.js.map +1 -0
  9. package/dist/{chunk-IINWI3LD.js → chunk-EEI6FRTE.js} +2 -2
  10. package/dist/{chunk-UOIAY6ZG.js → chunk-FWQESFFM.js} +13 -3
  11. package/dist/{chunk-UOIAY6ZG.js.map → chunk-FWQESFFM.js.map} +1 -1
  12. package/dist/{chunk-CU42ZD4K.js → chunk-G5MXVAFC.js} +16 -3
  13. package/dist/{chunk-CU42ZD4K.js.map → chunk-G5MXVAFC.js.map} +1 -1
  14. package/dist/{chunk-V7TNYHIK.js → chunk-HMFPP2PE.js} +55 -7
  15. package/dist/chunk-HMFPP2PE.js.map +1 -0
  16. package/dist/{chunk-GR3GSU3I.js → chunk-N2E2Q5GL.js} +4 -4
  17. package/dist/{chunk-JGD6A2Q4.js → chunk-QFGZQYZA.js} +3 -3
  18. package/dist/{chunk-W3XWRWML.js → chunk-SCQAKMMI.js} +119 -38
  19. package/dist/chunk-SCQAKMMI.js.map +1 -0
  20. package/dist/{client-C6N2ASTH.js → client-PYFE6YQR.js} +2 -2
  21. package/dist/{eas-VFTWEI4K.js → eas-B4HR2HXX.js} +8 -4
  22. package/dist/{governor-HVBSI6Z2.js → governor-QFBN6RYS.js} +6 -4
  23. package/dist/{identity-OLD25QEP.js → identity-I2BG4IGT.js} +5 -5
  24. package/dist/index.js +292 -81
  25. package/dist/index.js.map +1 -1
  26. package/dist/{price-O3THX2HL.js → price-EXZDYVDD.js} +4 -4
  27. package/dist/{providers-KZNCCUKT.js → providers-6UZKDFQD.js} +3 -3
  28. package/dist/{research-ARFBFXIT.js → research-T7A27OMB.js} +5 -5
  29. package/dist/{session-A7CYZSSA.js → session-45NQAHFI.js} +7 -7
  30. package/dist/{trade-ZCK332E4.js → trade-ZOVM433K.js} +10 -10
  31. package/dist/{vault-CDI7BELZ.js → vault-WWGSRNRP.js} +6 -6
  32. package/dist/{xmtp-7LAWDKJT.js → xmtp-72IRK7JL.js} +4 -4
  33. package/package.json +2 -2
  34. package/dist/chunk-MIAMGVZ4.js.map +0 -1
  35. package/dist/chunk-V7TNYHIK.js.map +0 -1
  36. package/dist/chunk-W3XWRWML.js.map +0 -1
  37. /package/dist/{agent-A2JEYGQS.js.map → agent-FCGZL4GF.js.map} +0 -0
  38. /package/dist/{chat-OZAAN5LT.js.map → chat-AKLYUJZV.js.map} +0 -0
  39. /package/dist/{chunk-37GT3TJX.js.map → chunk-4ITTHKRX.js.map} +0 -0
  40. /package/dist/{chunk-TTF5TDRV.js.map → chunk-6D3FNU75.js.map} +0 -0
  41. /package/dist/{chunk-3UYGXGMF.js.map → chunk-6SAE2VDK.js.map} +0 -0
  42. /package/dist/{chunk-R6F57QQF.js.map → chunk-BH3VTJ4F.js.map} +0 -0
  43. /package/dist/{chunk-IINWI3LD.js.map → chunk-EEI6FRTE.js.map} +0 -0
  44. /package/dist/{chunk-GR3GSU3I.js.map → chunk-N2E2Q5GL.js.map} +0 -0
  45. /package/dist/{chunk-JGD6A2Q4.js.map → chunk-QFGZQYZA.js.map} +0 -0
  46. /package/dist/{client-C6N2ASTH.js.map → client-PYFE6YQR.js.map} +0 -0
  47. /package/dist/{eas-VFTWEI4K.js.map → eas-B4HR2HXX.js.map} +0 -0
  48. /package/dist/{governor-HVBSI6Z2.js.map → governor-QFBN6RYS.js.map} +0 -0
  49. /package/dist/{identity-OLD25QEP.js.map → identity-I2BG4IGT.js.map} +0 -0
  50. /package/dist/{price-O3THX2HL.js.map → price-EXZDYVDD.js.map} +0 -0
  51. /package/dist/{providers-KZNCCUKT.js.map → providers-6UZKDFQD.js.map} +0 -0
  52. /package/dist/{research-ARFBFXIT.js.map → research-T7A27OMB.js.map} +0 -0
  53. /package/dist/{session-A7CYZSSA.js.map → session-45NQAHFI.js.map} +0 -0
  54. /package/dist/{trade-ZCK332E4.js.map → trade-ZOVM433K.js.map} +0 -0
  55. /package/dist/{vault-CDI7BELZ.js.map → vault-WWGSRNRP.js.map} +0 -0
  56. /package/dist/{xmtp-7LAWDKJT.js.map → xmtp-72IRK7JL.js.map} +0 -0
package/dist/index.js CHANGED
@@ -15,7 +15,7 @@ import {
15
15
  checkApiKeyValid,
16
16
  listModels,
17
17
  provisionApiKey
18
- } from "./chunk-IINWI3LD.js";
18
+ } from "./chunk-EEI6FRTE.js";
19
19
  import {
20
20
  DEFAULT_FEE_TIER,
21
21
  HYPERLIQUID_PERP_STRATEGY_ABI,
@@ -31,10 +31,13 @@ import {
31
31
  parseAlignedOverrides,
32
32
  resolveToken,
33
33
  selectBestFeeTier
34
- } from "./chunk-JGD6A2Q4.js";
34
+ } from "./chunk-QFGZQYZA.js";
35
35
  import {
36
36
  DEFAULT_ISSUING_CHAIN_ID,
37
+ STRATEGY_FACTORY_ABI,
37
38
  appendVidTag,
39
+ deriveStrategySalt,
40
+ effectiveStrategySalt,
38
41
  emitCalldata,
39
42
  encodeApproveAgent,
40
43
  encodeApproveDepositor,
@@ -60,11 +63,12 @@ import {
60
63
  isCalldataOnly,
61
64
  makeOwnerOfCache,
62
65
  parseVidTag,
66
+ predictStrategyCloneAddress,
63
67
  registerIdentityCommands,
64
68
  setCalldataOnly,
65
69
  stripVidTag,
66
70
  verifyVidTag
67
- } from "./chunk-V7TNYHIK.js";
71
+ } from "./chunk-HMFPP2PE.js";
68
72
  import {
69
73
  createApproval,
70
74
  createJoinRequest,
@@ -74,20 +78,20 @@ import {
74
78
  queryJoinRequests,
75
79
  revokeJoinRequest,
76
80
  stripReferrerPrefix
77
- } from "./chunk-W3XWRWML.js";
81
+ } from "./chunk-SCQAKMMI.js";
78
82
  import {
79
83
  createFund,
80
84
  getActiveFunds,
81
85
  getFund,
82
86
  subdomainExists,
83
87
  updateMetadata
84
- } from "./chunk-TTF5TDRV.js";
88
+ } from "./chunk-6D3FNU75.js";
85
89
  import {
86
90
  resolveFund,
87
91
  resolveVaultFund,
88
92
  searchFundAcrossChains,
89
93
  setTextRecord
90
- } from "./chunk-37GT3TJX.js";
94
+ } from "./chunk-4ITTHKRX.js";
91
95
  import {
92
96
  approveDepositor,
93
97
  deposit,
@@ -110,8 +114,8 @@ import {
110
114
  removeDepositor,
111
115
  setAgentFeeBps,
112
116
  setVaultAddress
113
- } from "./chunk-GR3GSU3I.js";
114
- import "./chunk-R6F57QQF.js";
117
+ } from "./chunk-N2E2Q5GL.js";
118
+ import "./chunk-BH3VTJ4F.js";
115
119
  import {
116
120
  PROPOSAL_STATE,
117
121
  PROPOSAL_STATES,
@@ -138,6 +142,7 @@ import {
138
142
  parseDuration,
139
143
  proposalCount,
140
144
  propose,
145
+ reclaimProposerBond,
141
146
  scanReviewCandidates,
142
147
  setCooldownPeriod,
143
148
  setExecutionWindow,
@@ -149,7 +154,7 @@ import {
149
154
  setVotingPeriod,
150
155
  settleProposal,
151
156
  vote
152
- } from "./chunk-CU42ZD4K.js";
157
+ } from "./chunk-G5MXVAFC.js";
153
158
  import {
154
159
  AERODROME,
155
160
  MOONWELL,
@@ -158,7 +163,7 @@ import {
158
163
  TOKENS,
159
164
  UNISWAP,
160
165
  VENICE
161
- } from "./chunk-UOIAY6ZG.js";
166
+ } from "./chunk-FWQESFFM.js";
162
167
  import {
163
168
  GAS_UNITS,
164
169
  estimateGasCushion,
@@ -169,7 +174,7 @@ import {
169
174
  sendTxWithRetry,
170
175
  waitForReceipt,
171
176
  writeContractWithRetry
172
- } from "./chunk-MIAMGVZ4.js";
177
+ } from "./chunk-D4BSBW3Q.js";
173
178
  import {
174
179
  DEFAULT_NETWORK,
175
180
  VALID_NETWORKS,
@@ -210,6 +215,7 @@ import {
210
215
  PORTFOLIO_STRATEGY_ABI,
211
216
  SWAP_ROUTER_ABI,
212
217
  SWAP_ROUTER_EXACT_INPUT_SINGLE_ABI,
218
+ SYNDICATE_GOVERNOR_ABI,
213
219
  SYNDICATE_VAULT_ABI,
214
220
  VENICE_STAKING_ABI
215
221
  } from "./chunk-J2IZWAEW.js";
@@ -289,6 +295,126 @@ async function cloneTemplate(template) {
289
295
  return { clone: receipt.contractAddress, hash };
290
296
  }
291
297
 
298
+ // src/lib/strategy-deploy.ts
299
+ var ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
300
+ var STRATEGY_FACTORY_EXTRA_ABI = [
301
+ {
302
+ name: "registerStrategy",
303
+ type: "function",
304
+ stateMutability: "nonpayable",
305
+ inputs: [{ name: "strategy", type: "address" }],
306
+ outputs: []
307
+ },
308
+ {
309
+ name: "isRegisteredStrategy",
310
+ type: "function",
311
+ stateMutability: "view",
312
+ inputs: [{ name: "strategy", type: "address" }],
313
+ outputs: [{ name: "", type: "bool" }]
314
+ },
315
+ {
316
+ name: "approvedTemplate",
317
+ type: "function",
318
+ stateMutability: "view",
319
+ inputs: [{ name: "template", type: "address" }],
320
+ outputs: [{ name: "", type: "bool" }]
321
+ }
322
+ ];
323
+ function planStrategyCloneDeploy(args) {
324
+ const factory = args.factory ?? SHERWOOD().STRATEGY_FACTORY;
325
+ if (!factory || factory === ZERO_ADDRESS) {
326
+ return {
327
+ mode: "raw",
328
+ reason: "no STRATEGY_FACTORY in this network's address book \u2014 falling back to a raw ERC-1167 clone. A governor that gates propose on strategy registration will refuse the resulting proposal."
329
+ };
330
+ }
331
+ const salt = args.salt ?? deriveStrategySalt(args.vault, args.proposer, args.template, args.initData);
332
+ const clone = predictStrategyCloneAddress(
333
+ factory,
334
+ args.template,
335
+ effectiveStrategySalt(args.vault, salt)
336
+ );
337
+ return {
338
+ mode: "factory",
339
+ factory,
340
+ clone,
341
+ salt,
342
+ to: factory,
343
+ functionName: "cloneAndInitDeterministic",
344
+ args: [args.template, args.vault, args.proposer, args.initData, salt]
345
+ };
346
+ }
347
+ async function deployStrategyClone(args) {
348
+ const plan = planStrategyCloneDeploy(args);
349
+ const publicClient = getPublicClient();
350
+ const account = getAccount();
351
+ if (plan.mode === "factory") {
352
+ const approved = await publicClient.readContract({
353
+ address: plan.factory,
354
+ abi: STRATEGY_FACTORY_EXTRA_ABI,
355
+ functionName: "approvedTemplate",
356
+ args: [args.template]
357
+ });
358
+ if (!approved) {
359
+ throw new Error(
360
+ `Template ${args.template} is not on StrategyFactory ${plan.factory}'s allowlist \u2014 cloneAndInitDeterministic would revert TemplateNotApproved. The factory owner must call setTemplateApproval(${args.template}, true).`
361
+ );
362
+ }
363
+ const existing = await publicClient.getCode({ address: plan.clone });
364
+ if (existing && existing !== "0x") {
365
+ throw new Error(
366
+ `A strategy clone already exists at the deterministic address ${plan.clone} (same vault + template + init params as an earlier deploy). Re-run with a different --salt to deploy a fresh clone.`
367
+ );
368
+ }
369
+ const hash2 = await writeContractWithRetry({
370
+ account,
371
+ chain: getChain(),
372
+ address: plan.factory,
373
+ abi: STRATEGY_FACTORY_ABI,
374
+ functionName: plan.functionName,
375
+ args: plan.args
376
+ });
377
+ const receipt = await waitForReceipt(hash2);
378
+ if (receipt.status === "reverted") {
379
+ throw new Error(`StrategyFactory.cloneAndInitDeterministic reverted on-chain (tx: ${hash2})`);
380
+ }
381
+ const deployed = await publicClient.getCode({ address: plan.clone });
382
+ if (!deployed || deployed === "0x") {
383
+ throw new Error(
384
+ `The factory deployed a clone, but not at the predicted address ${plan.clone} (tx: ${hash2}). The CLI's CREATE2 prediction and the factory's salt fold have diverged \u2014 do not propose against this address.`
385
+ );
386
+ }
387
+ return { clone: plan.clone, hash: hash2, viaFactory: true, salt: plan.salt };
388
+ }
389
+ const { clone, hash } = await cloneTemplate(args.template);
390
+ const initHash = await writeContractWithRetry({
391
+ account,
392
+ chain: getChain(),
393
+ address: clone,
394
+ abi: BASE_STRATEGY_ABI,
395
+ functionName: "initialize",
396
+ args: [args.vault, args.proposer, args.initData]
397
+ });
398
+ const initReceipt = await waitForReceipt(initHash);
399
+ if (initReceipt.status === "reverted") {
400
+ throw new Error(`Strategy initialize reverted on-chain (tx: ${initHash})`);
401
+ }
402
+ let registerHash;
403
+ const factory = args.factory ?? SHERWOOD().STRATEGY_FACTORY;
404
+ if (factory && factory !== ZERO_ADDRESS) {
405
+ registerHash = await writeContractWithRetry({
406
+ account,
407
+ chain: getChain(),
408
+ address: factory,
409
+ abi: STRATEGY_FACTORY_EXTRA_ABI,
410
+ functionName: "registerStrategy",
411
+ args: [clone]
412
+ });
413
+ await waitForReceipt(registerHash);
414
+ }
415
+ return { clone, hash, viaFactory: false, initHash, registerHash };
416
+ }
417
+
292
418
  // src/grid/strategy-abi.ts
293
419
  var HYPERLIQUID_GRID_STRATEGY_ABI = [
294
420
  {
@@ -608,6 +734,20 @@ var TEMPLATES = [
608
734
  key: "hyperliquid-grid",
609
735
  description: "ATR-based grid trading on Hyperliquid via HyperEVM precompiles",
610
736
  addressKey: "HYPERLIQUID_GRID"
737
+ },
738
+ {
739
+ name: "Morpho Supply",
740
+ key: "morpho-supply",
741
+ description: "Supply the vault asset to a Morpho market (init encoder not wired in the CLI yet)",
742
+ addressKey: "MORPHO_SUPPLY",
743
+ encoder: false
744
+ },
745
+ {
746
+ name: "Concentrated Liquidity",
747
+ key: "concentrated-liquidity",
748
+ description: "Uniswap-v3-style concentrated LP range (init encoder not wired in the CLI yet)",
749
+ addressKey: "CONCENTRATED_LIQUIDITY",
750
+ encoder: false
611
751
  }
612
752
  ];
613
753
  function resolveTemplate(key) {
@@ -622,6 +762,19 @@ function resolveTemplate(key) {
622
762
  console.error(chalk2.red(`Template "${def.name}" not deployed on this network.`));
623
763
  process.exit(1);
624
764
  }
765
+ if (def.encoder === false) {
766
+ console.error(
767
+ chalk2.red(
768
+ `Template "${def.name}" is deployed at ${address} but the CLI cannot encode its initialize() tuple yet.`
769
+ )
770
+ );
771
+ console.error(
772
+ chalk2.yellow(
773
+ " Deploy it via StrategyFactory.cloneAndInitDeterministic with hand-encoded initData, then reference the clone from `sherwood proposal create`."
774
+ )
775
+ );
776
+ process.exit(1);
777
+ }
625
778
  return { def, address };
626
779
  }
627
780
  async function resolvePortfolioFeeTiers(opts, deps) {
@@ -890,7 +1043,7 @@ function formatBatch(calls) {
890
1043
 
891
1044
  // src/commands/strategy-propose.ts
892
1045
  function registerStrategyProposeCommands(strategy2) {
893
- strategy2.command("propose").description("Clone + init + build calls + submit governance proposal (all-in-one)").argument("<template>", "Template: moonwell-supply, aerodrome-lp, venice-inference, wsteth-moonwell, mamo-yield, portfolio, hyperliquid-perp, hyperliquid-grid").requiredOption("--vault <address>", "Vault address").option("--write-calls <dir>", "Write execute/settle JSON to directory (skip proposal submission)").option("--name <name>", "Proposal name").option("--description <text>", "Proposal description").option("--duration <duration>", "Strategy duration (7d, 24h, etc.)").option("--proposer <address>", "Proposer/agent address (required for --calldata-only \u2014 the external signer)").option("--metadata-uri <uri>", "Metadata URI (required for --calldata-only \u2014 IPFS pin needs a signer)").option("--salt <bytes32>", "CREATE2 salt for the deterministic clone (--calldata-only; default: derived from inputs)").option("--amount <n>", "Asset amount to deploy").option("--min-redeem <n>", "Min asset on settlement (Moonwell)").option("--token <symbol>", "Asset token symbol (default: USDC)").option("--asset <symbol>", "Asset token (USDC, VVV, or address)").option("--agent <address>", "Agent wallet (Venice, default: your wallet)").option("--min-vvv <n>", "Min VVV from swap (Venice)").option("--single-hop", "Single-hop Aerodrome swap (Venice)").option("--token-a <address>", "Token A (Aerodrome)").option("--token-b <address>", "Token B (Aerodrome)").option("--amount-a <n>", "Token A amount (Aerodrome)").option("--amount-b <n>", "Token B amount (Aerodrome)").option("--stable", "Stable pool (Aerodrome)").option("--gauge <address>", "Gauge address (Aerodrome)").option("--lp-token <address>", "LP token address (Aerodrome)").option("--min-a-out <n>", "Min token A on settle (Aerodrome)").option("--min-b-out <n>", "Min token B on settle (Aerodrome)").option("--slippage <bps>", "Slippage tolerance in bps (wstETH, default: 500 = 5%)").option("--mamo-factory <address>", "Mamo StrategyFactory address (Mamo)").option("--tokens <list>", "Comma-separated token addresses or symbols (Portfolio)").option("--weights <list>", "Comma-separated weights in bps, must sum to 10000 (Portfolio)").option("--max-slippage <bps>", "Max slippage bps (Portfolio, default: 500)").option("--fee-tier <n>", "Pool fee tier (Portfolio, default: 3000)").option("--swap-adapter <address>", "Swap adapter address (Portfolio)").option("--feeds <list>", "Comma-separated Chainlink AggregatorV3 push-feed addresses per token (Portfolio; auto-resolved from the registry when a slot is left empty)").option("--price-decimals <list>", "Comma-separated raw feed decimals per token (Portfolio; default 8). Must equal the feed's live decimals().").option("--swap-routes <list>", "Comma-separated per-token swap route spec (Portfolio). Per token: 'v3:<fee>' (mode 0), 'v4:<fee>:<tickSpacing>' (mode 2), or 'v4path:<hop>+<hop>...' (mode 3) where hop='<currency>@<fee>:<tickSpacing>', currency='eth'/'native'=ETH or 'self'=this token or an address. Empty entry = auto-detect / robinhood default.").option(
1046
+ strategy2.command("propose").description("Clone + init + build calls + submit governance proposal (all-in-one)").argument("<template>", "Template: moonwell-supply, aerodrome-lp, venice-inference, wsteth-moonwell, mamo-yield, portfolio, hyperliquid-perp, hyperliquid-grid").requiredOption("--vault <address>", "Vault address").option("--write-calls <dir>", "Write execute/settle JSON to directory (skip proposal submission)").option("--name <name>", "Proposal name").option("--description <text>", "Proposal description").option("--duration <duration>", "Strategy duration (7d, 24h, etc.)").option("--proposer <address>", "Proposer/agent address (required for --calldata-only \u2014 the external signer)").option("--metadata-uri <uri>", "Metadata URI (required for --calldata-only \u2014 IPFS pin needs a signer)").option("--salt <bytes32>", "CREATE2 salt for the deterministic clone (default: derived from vault+proposer+template+initData). Pass a fresh one to re-deploy identical params.").option("--amount <n>", "Asset amount to deploy").option("--min-redeem <n>", "Min asset on settlement (Moonwell)").option("--token <symbol>", "Asset token symbol (default: USDC)").option("--asset <symbol>", "Asset token (USDC, VVV, or address)").option("--agent <address>", "Agent wallet (Venice, default: your wallet)").option("--min-vvv <n>", "Min VVV from swap (Venice)").option("--single-hop", "Single-hop Aerodrome swap (Venice)").option("--token-a <address>", "Token A (Aerodrome)").option("--token-b <address>", "Token B (Aerodrome)").option("--amount-a <n>", "Token A amount (Aerodrome)").option("--amount-b <n>", "Token B amount (Aerodrome)").option("--stable", "Stable pool (Aerodrome)").option("--gauge <address>", "Gauge address (Aerodrome)").option("--lp-token <address>", "LP token address (Aerodrome)").option("--min-a-out <n>", "Min token A on settle (Aerodrome)").option("--min-b-out <n>", "Min token B on settle (Aerodrome)").option("--slippage <bps>", "Slippage tolerance in bps (wstETH, default: 500 = 5%)").option("--mamo-factory <address>", "Mamo StrategyFactory address (Mamo)").option("--tokens <list>", "Comma-separated token addresses or symbols (Portfolio)").option("--weights <list>", "Comma-separated weights in bps, must sum to 10000 (Portfolio)").option("--max-slippage <bps>", "Max slippage bps (Portfolio, default: 500)").option("--fee-tier <n>", "Pool fee tier (Portfolio, default: 3000)").option("--swap-adapter <address>", "Swap adapter address (Portfolio)").option("--feeds <list>", "Comma-separated Chainlink AggregatorV3 push-feed addresses per token (Portfolio; auto-resolved from the registry when a slot is left empty)").option("--price-decimals <list>", "Comma-separated raw feed decimals per token (Portfolio; default 8). Must equal the feed's live decimals().").option("--swap-routes <list>", "Comma-separated per-token swap route spec (Portfolio). Per token: 'v3:<fee>' (mode 0), 'v4:<fee>:<tickSpacing>' (mode 2), or 'v4path:<hop>+<hop>...' (mode 3) where hop='<currency>@<fee>:<tickSpacing>', currency='eth'/'native'=ETH or 'self'=this token or an address. Empty entry = auto-detect / robinhood default.").option(
894
1047
  "--max-drawdown-bps <bps>",
895
1048
  "Declared loss allowance for this proposal, in bps of --amount (0-10000, default 2000 = 20%). This is the envelope voters and guardians are asked to accept, and the basis the settle-price guard sizes its tolerance from \u2014 not a formality."
896
1049
  ).option("--leverage <number>", "Leverage multiplier (Hyperliquid Perp, default: 10)").option("--asset-index <number>", "Perp asset index (Hyperliquid Perp, default: 0 for BTC)").option("--max-position <amount>", "Max position size in USD (Hyperliquid Perp, default: 100000)").option("--max-trades-per-day <n>", "Max trades per day (Hyperliquid Perp, default: 50)").option("--max-order-size <amount>", "Max single-order size in asset units (Hyperliquid Grid, default: 10000)").option("--max-orders-per-tick <n>", "Max orders per tick (Hyperliquid Grid, default: 20)").option("--asset-indices <list>", "Comma-separated perp asset indices (Hyperliquid Grid, default: 0)").action(async (templateKey, opts) => {
@@ -977,7 +1130,7 @@ function registerStrategyProposeCommands(strategy2) {
977
1130
  process.exit(1);
978
1131
  }
979
1132
  if (!opts.agent) opts.agent = proposer;
980
- const { parseDuration: parseDuration3, getGovernorOf: getGovernorOf2 } = await import("./governor-HVBSI6Z2.js");
1133
+ const { parseDuration: parseDuration3, getGovernorOf: getGovernorOf2 } = await import("./governor-QFBN6RYS.js");
981
1134
  const strategyDuration2 = parseDuration3(opts.duration);
982
1135
  const chainId = getChain().id;
983
1136
  try {
@@ -1100,42 +1253,40 @@ function registerStrategyProposeCommands(strategy2) {
1100
1253
  console.error(chalk3.red(formatContractError(err)));
1101
1254
  process.exit(1);
1102
1255
  }
1103
- const cloneSpinner = ora2(`Cloning ${def.name} template...`).start();
1104
1256
  let clone;
1105
- try {
1106
- const result = await cloneTemplate(templateAddr);
1107
- clone = result.clone;
1108
- cloneSpinner.succeed(`Cloned: ${chalk3.green(clone)}`);
1109
- console.log(chalk3.dim(` Tx: ${getExplorerUrl(result.hash)}`));
1110
- } catch (err) {
1111
- cloneSpinner.fail("Clone failed");
1112
- console.error(chalk3.red(formatContractError(err)));
1113
- process.exit(1);
1114
- }
1115
- const initSpinner = ora2("Initializing strategy...").start();
1116
1257
  let asset;
1117
1258
  let assetAmount;
1118
1259
  let extraApprovals;
1260
+ const deploySpinner = ora2(`Deploying ${def.name} strategy...`).start();
1119
1261
  try {
1120
1262
  const built = await resolveAndBuildInitData(templateKey, opts, vault);
1121
1263
  asset = built.asset;
1122
1264
  assetAmount = built.assetAmount;
1123
1265
  extraApprovals = built.extraApprovals;
1124
- const initHash = await writeContractWithRetry({
1125
- account,
1126
- chain: getChain(),
1127
- address: clone,
1128
- abi: BASE_STRATEGY_ABI,
1129
- functionName: "initialize",
1130
- args: [vault, account.address, built.initData]
1266
+ const deployed = await deployStrategyClone({
1267
+ template: templateAddr,
1268
+ vault,
1269
+ proposer: account.address,
1270
+ initData: built.initData,
1271
+ salt: opts.salt
1131
1272
  });
1132
- const initReceipt = await waitForReceipt(initHash);
1133
- if (initReceipt.status === "reverted") {
1134
- throw new Error("Initialize transaction reverted on-chain");
1273
+ clone = deployed.clone;
1274
+ deploySpinner.succeed(
1275
+ deployed.viaFactory ? `Deployed + registered: ${chalk3.green(clone)}` : `Cloned + initialized: ${chalk3.green(clone)}`
1276
+ );
1277
+ console.log(chalk3.dim(` Tx: ${getExplorerUrl(deployed.hash)}`));
1278
+ if (deployed.initHash) console.log(chalk3.dim(` Init tx: ${getExplorerUrl(deployed.initHash)}`));
1279
+ if (deployed.registerHash) console.log(chalk3.dim(` Register tx: ${getExplorerUrl(deployed.registerHash)}`));
1280
+ if (deployed.salt) console.log(chalk3.dim(` Salt: ${deployed.salt}`));
1281
+ if (!deployed.viaFactory) {
1282
+ console.log(
1283
+ chalk3.yellow(
1284
+ " No StrategyFactory on this network \u2014 the clone was deployed raw. A governor that gates propose on strategy registration will refuse it."
1285
+ )
1286
+ );
1135
1287
  }
1136
- initSpinner.succeed("Initialized");
1137
1288
  } catch (err) {
1138
- initSpinner.fail("Initialize failed");
1289
+ deploySpinner.fail("Strategy deploy failed");
1139
1290
  console.error(chalk3.red(formatContractError(err)));
1140
1291
  process.exit(1);
1141
1292
  }
@@ -1208,9 +1359,9 @@ function registerStrategyProposeCommands(strategy2) {
1208
1359
  console.error(chalk3.red("Missing --name or --duration. Use --write-calls to skip proposal submission."));
1209
1360
  process.exit(1);
1210
1361
  }
1211
- const { propose: propose2 } = await import("./governor-HVBSI6Z2.js");
1362
+ const { propose: propose2 } = await import("./governor-QFBN6RYS.js");
1212
1363
  const { pinJSON } = await import("./ipfs-M56BLMCW.js");
1213
- const { parseDuration: parseDuration2 } = await import("./governor-HVBSI6Z2.js");
1364
+ const { parseDuration: parseDuration2 } = await import("./governor-QFBN6RYS.js");
1214
1365
  const strategyDuration = parseDuration2(opts.duration);
1215
1366
  const metaSpinner = ora2("Pinning metadata to IPFS...").start();
1216
1367
  let metadataURI;
@@ -1242,7 +1393,7 @@ function registerStrategyProposeCommands(strategy2) {
1242
1393
  metadataURI = `data:application/json;base64,${Buffer.from(inline).toString("base64")}`;
1243
1394
  }
1244
1395
  try {
1245
- const { getAgentFeeBps: getAgentFeeBps2 } = await import("./vault-CDI7BELZ.js");
1396
+ const { getAgentFeeBps: getAgentFeeBps2 } = await import("./vault-WWGSRNRP.js");
1246
1397
  const feeBps = await getAgentFeeBps2(vault);
1247
1398
  console.log(
1248
1399
  chalk3.yellow(
@@ -1313,6 +1464,11 @@ function registerStrategyTemplateCommands(strategy2) {
1313
1464
  console.log(` ${chalk4.bold(t.name)} (${chalk4.cyan(t.key)})`);
1314
1465
  console.log(` ${t.description}`);
1315
1466
  console.log(` Template: ${chalk4.green(addr)}`);
1467
+ if (t.encoder === false) {
1468
+ console.log(
1469
+ chalk4.yellow(" No CLI init encoder yet \u2014 propose it via hand-encoded initData.")
1470
+ );
1471
+ }
1316
1472
  }
1317
1473
  }
1318
1474
  if (availableCount === 0) {
@@ -1332,7 +1488,7 @@ function registerStrategyTemplateCommands(strategy2) {
1332
1488
  console.log(chalk4.dim("Full proposal: sherwood strategy propose <template> --vault <addr> ..."));
1333
1489
  console.log();
1334
1490
  });
1335
- strategy2.command("clone").description("Clone a strategy template and initialize it").argument("<template>", "Template: moonwell-supply, aerodrome-lp, venice-inference, wsteth-moonwell, mamo-yield, portfolio, hyperliquid-perp, hyperliquid-grid").requiredOption("--vault <address>", "Vault address").option("--amount <n>", "Asset amount to deploy").option("--min-redeem <n>", "Min asset on settlement (Moonwell)").option("--token <symbol>", "Asset token symbol (default: USDC)").option("--asset <symbol>", "Asset token (USDC, VVV, or address)").option("--agent <address>", "Agent wallet (Venice, default: your wallet)").option("--min-vvv <n>", "Min VVV from swap (Venice)").option("--single-hop", "Single-hop Aerodrome swap (Venice)").option("--token-a <address>", "Token A (Aerodrome)").option("--token-b <address>", "Token B (Aerodrome)").option("--amount-a <n>", "Token A amount (Aerodrome)").option("--amount-b <n>", "Token B amount (Aerodrome)").option("--stable", "Stable pool (Aerodrome)").option("--gauge <address>", "Gauge address (Aerodrome)").option("--lp-token <address>", "LP token address (Aerodrome)").option("--min-a-out <n>", "Min token A on settle (Aerodrome)").option("--min-b-out <n>", "Min token B on settle (Aerodrome)").option("--slippage <bps>", "Slippage tolerance in bps (wstETH, default: 500 = 5%)").option("--mamo-factory <address>", "Mamo StrategyFactory address (Mamo)").option("--tokens <list>", "Comma-separated token addresses or symbols (Portfolio)").option("--weights <list>", "Comma-separated weights in bps, must sum to 10000 (Portfolio)").option("--max-slippage <bps>", "Max slippage bps (Portfolio, default: 500)").option("--fee-tier <n>", "Pool fee tier (Portfolio, default: 3000)").option("--swap-adapter <address>", "Swap adapter address (Portfolio)").option("--feeds <list>", "Comma-separated Chainlink AggregatorV3 push-feed addresses per token (Portfolio; auto-resolved from the registry when a slot is left empty)").option("--price-decimals <list>", "Comma-separated raw feed decimals per token (Portfolio; default 8). Must equal the feed's live decimals().").option("--swap-routes <list>", "Comma-separated per-token swap route spec (Portfolio). Per token: 'v3:<fee>' (mode 0), 'v4:<fee>:<tickSpacing>' (mode 2), or 'v4path:<hop>+<hop>...' (mode 3) where hop='<currency>@<fee>:<tickSpacing>', currency='eth'/'native'=ETH or 'self'=this token or an address. Empty entry = auto-detect / robinhood default.").option(
1491
+ strategy2.command("clone").description("Clone a strategy template and initialize it").argument("<template>", "Template: moonwell-supply, aerodrome-lp, venice-inference, wsteth-moonwell, mamo-yield, portfolio, hyperliquid-perp, hyperliquid-grid").requiredOption("--vault <address>", "Vault address").option("--salt <bytes32>", "CREATE2 salt for the deterministic clone (default: derived from vault+proposer+template+initData). Pass a fresh one to re-deploy identical params.").option("--amount <n>", "Asset amount to deploy").option("--min-redeem <n>", "Min asset on settlement (Moonwell)").option("--token <symbol>", "Asset token symbol (default: USDC)").option("--asset <symbol>", "Asset token (USDC, VVV, or address)").option("--agent <address>", "Agent wallet (Venice, default: your wallet)").option("--min-vvv <n>", "Min VVV from swap (Venice)").option("--single-hop", "Single-hop Aerodrome swap (Venice)").option("--token-a <address>", "Token A (Aerodrome)").option("--token-b <address>", "Token B (Aerodrome)").option("--amount-a <n>", "Token A amount (Aerodrome)").option("--amount-b <n>", "Token B amount (Aerodrome)").option("--stable", "Stable pool (Aerodrome)").option("--gauge <address>", "Gauge address (Aerodrome)").option("--lp-token <address>", "LP token address (Aerodrome)").option("--min-a-out <n>", "Min token A on settle (Aerodrome)").option("--min-b-out <n>", "Min token B on settle (Aerodrome)").option("--slippage <bps>", "Slippage tolerance in bps (wstETH, default: 500 = 5%)").option("--mamo-factory <address>", "Mamo StrategyFactory address (Mamo)").option("--tokens <list>", "Comma-separated token addresses or symbols (Portfolio)").option("--weights <list>", "Comma-separated weights in bps, must sum to 10000 (Portfolio)").option("--max-slippage <bps>", "Max slippage bps (Portfolio, default: 500)").option("--fee-tier <n>", "Pool fee tier (Portfolio, default: 3000)").option("--swap-adapter <address>", "Swap adapter address (Portfolio)").option("--feeds <list>", "Comma-separated Chainlink AggregatorV3 push-feed addresses per token (Portfolio; auto-resolved from the registry when a slot is left empty)").option("--price-decimals <list>", "Comma-separated raw feed decimals per token (Portfolio; default 8). Must equal the feed's live decimals().").option("--swap-routes <list>", "Comma-separated per-token swap route spec (Portfolio). Per token: 'v3:<fee>' (mode 0), 'v4:<fee>:<tickSpacing>' (mode 2), or 'v4path:<hop>+<hop>...' (mode 3) where hop='<currency>@<fee>:<tickSpacing>', currency='eth'/'native'=ETH or 'self'=this token or an address. Empty entry = auto-detect / robinhood default.").option(
1336
1492
  "--max-drawdown-bps <bps>",
1337
1493
  "Declared loss allowance for this proposal, in bps of --amount (0-10000, default 2000 = 20%). This is the envelope voters and guardians are asked to accept, and the basis the settle-price guard sizes its tolerance from \u2014 not a formality."
1338
1494
  ).option("--leverage <number>", "Leverage multiplier (Hyperliquid Perp, default: 10)").option("--asset-index <number>", "Perp asset index (Hyperliquid Perp, default: 0 for BTC)").option("--max-position <amount>", "Max position size in USD (Hyperliquid Perp, default: 100000)").option("--max-trades-per-day <n>", "Max trades per day (Hyperliquid Perp, default: 50)").option("--max-order-size <amount>", "Max single-order size in asset units (Hyperliquid Grid, default: 10000)").option("--max-orders-per-tick <n>", "Max orders per tick (Hyperliquid Grid, default: 20)").option("--asset-indices <list>", "Comma-separated perp asset indices (Hyperliquid Grid, default: 0)").action(async (templateKey, opts) => {
@@ -1342,39 +1498,35 @@ function registerStrategyTemplateCommands(strategy2) {
1342
1498
  process.exit(1);
1343
1499
  }
1344
1500
  const { def, address: templateAddr } = resolveTemplate(templateKey);
1345
- const cloneSpinner = ora3(`Cloning ${def.name} template...`).start();
1346
1501
  let clone;
1347
- let cloneHash;
1348
- try {
1349
- const result = await cloneTemplate(templateAddr);
1350
- clone = result.clone;
1351
- cloneHash = result.hash;
1352
- cloneSpinner.succeed(`Cloned: ${chalk4.green(clone)}`);
1353
- console.log(chalk4.dim(` Tx: ${getExplorerUrl(cloneHash)}`));
1354
- } catch (err) {
1355
- cloneSpinner.fail("Clone failed");
1356
- console.error(chalk4.red(formatContractError(err)));
1357
- process.exit(1);
1358
- }
1359
- const initSpinner = ora3("Initializing strategy...").start();
1502
+ const deploySpinner = ora3(`Deploying ${def.name} strategy...`).start();
1360
1503
  try {
1361
1504
  const { initData } = await resolveAndBuildInitData(templateKey, opts, vault);
1362
1505
  const account = getAccount();
1363
- const initHash = await writeContractWithRetry({
1364
- account,
1365
- chain: getChain(),
1366
- address: clone,
1367
- abi: BASE_STRATEGY_ABI,
1368
- functionName: "initialize",
1369
- args: [vault, account.address, initData]
1506
+ const deployed = await deployStrategyClone({
1507
+ template: templateAddr,
1508
+ vault,
1509
+ proposer: account.address,
1510
+ initData,
1511
+ salt: opts.salt
1370
1512
  });
1371
- const receipt = await waitForReceipt(initHash);
1372
- if (receipt.status === "reverted") {
1373
- throw new Error("Initialize transaction reverted on-chain");
1513
+ clone = deployed.clone;
1514
+ deploySpinner.succeed(
1515
+ deployed.viaFactory ? `Deployed + registered: ${chalk4.green(clone)}` : `Cloned + initialized: ${chalk4.green(clone)}`
1516
+ );
1517
+ console.log(chalk4.dim(` Tx: ${getExplorerUrl(deployed.hash)}`));
1518
+ if (deployed.initHash) console.log(chalk4.dim(` Init tx: ${getExplorerUrl(deployed.initHash)}`));
1519
+ if (deployed.registerHash) console.log(chalk4.dim(` Register tx: ${getExplorerUrl(deployed.registerHash)}`));
1520
+ if (deployed.salt) console.log(chalk4.dim(` Salt: ${deployed.salt}`));
1521
+ if (!deployed.viaFactory) {
1522
+ console.log(
1523
+ chalk4.yellow(
1524
+ " No StrategyFactory on this network \u2014 the clone was deployed raw. A governor that gates propose on strategy registration will refuse it."
1525
+ )
1526
+ );
1374
1527
  }
1375
- initSpinner.succeed("Initialized");
1376
1528
  } catch (err) {
1377
- initSpinner.fail("Initialize failed");
1529
+ deploySpinner.fail("Strategy deploy failed");
1378
1530
  console.error(chalk4.red(formatContractError(err)));
1379
1531
  process.exit(1);
1380
1532
  }
@@ -1513,7 +1665,7 @@ function registerStrategyTemplateCommands(strategy2) {
1513
1665
  let prices = [];
1514
1666
  let priceSource = null;
1515
1667
  try {
1516
- const { getTokenPricesInAsset } = await import("./price-O3THX2HL.js");
1668
+ const { getTokenPricesInAsset } = await import("./price-EXZDYVDD.js");
1517
1669
  prices = await getTokenPricesInAsset({
1518
1670
  tokens: allocations.map((a, i) => ({
1519
1671
  token: a.token,
@@ -1922,7 +2074,7 @@ function registerVeniceCommands(program2) {
1922
2074
  console.log(chalk5.dim(` Key: ${apiKey.slice(0, 8)}...${apiKey.slice(-4)}`));
1923
2075
  console.log(chalk5.dim(" Saved to ~/.sherwood/config.json"));
1924
2076
  try {
1925
- const { createVeniceProvisionAttestation, getEasScanUrl } = await import("./eas-VFTWEI4K.js");
2077
+ const { createVeniceProvisionAttestation, getEasScanUrl } = await import("./eas-B4HR2HXX.js");
1926
2078
  const attestation = await createVeniceProvisionAttestation(account.address);
1927
2079
  if (attestation) {
1928
2080
  console.log(chalk5.dim(` Attested: ${getEasScanUrl(attestation.uid)}`));
@@ -2278,7 +2430,7 @@ ${opts.prompt}`;
2278
2430
  console.log(chalk5.dim(`Model: ${result.model} | Tokens: ${result.usage.promptTokens} in, ${result.usage.completionTokens} out, ${result.usage.totalTokens} total`));
2279
2431
  }
2280
2432
  try {
2281
- const { createVeniceInferenceAttestation, getEasScanUrl } = await import("./eas-VFTWEI4K.js");
2433
+ const { createVeniceInferenceAttestation, getEasScanUrl } = await import("./eas-B4HR2HXX.js");
2282
2434
  const { keccak256: keccak2562, toHex, isAddress: isAddr } = await import("viem");
2283
2435
  const { getChainContracts: getChainContracts2 } = await import("./config-ZGFS4I7K.js");
2284
2436
  const { getChain: getActiveChain } = await import("./network-7445KSCF.js");
@@ -3277,8 +3429,8 @@ function printSimulationResult(result, callType) {
3277
3429
  }
3278
3430
  async function sendSimulationAlert(subdomain, proposalId, vault, execResult, settleResult) {
3279
3431
  try {
3280
- const xmtp = await import("./xmtp-7LAWDKJT.js");
3281
- const { getAccount: getAccount2 } = await import("./client-C6N2ASTH.js");
3432
+ const xmtp = await import("./xmtp-72IRK7JL.js");
3433
+ const { getAccount: getAccount2 } = await import("./client-PYFE6YQR.js");
3282
3434
  const group = await xmtp.getGroup("", subdomain);
3283
3435
  const allRisks = [...execResult.risks, ...settleResult?.risks ?? []];
3284
3436
  const criticals = allRisks.filter((r) => r.level === "critical");
@@ -4562,6 +4714,65 @@ function registerProposalCommands(program2) {
4562
4714
  process.exit(1);
4563
4715
  }
4564
4716
  });
4717
+ proposal.command("reclaim-bond").description("Reclaim the proposer bond of a terminal proposal (cancelled / rejected / expired / settled)").requiredOption("--id <proposalId>", "Proposal ID").requiredOption("--vault <address>", "Vault the proposal belongs to (per-vault governor)").action(async (opts) => {
4718
+ try {
4719
+ const proposalId = parseBigIntArg(opts.id, "proposal ID");
4720
+ const vault = parseVaultOption(opts.vault);
4721
+ if (isCalldataOnly()) {
4722
+ const governor = await getGovernorOf(vault);
4723
+ emitCalldata({
4724
+ txs: [
4725
+ {
4726
+ to: governor,
4727
+ data: encodeFunctionData3({
4728
+ abi: SYNDICATE_GOVERNOR_ABI,
4729
+ functionName: "reclaimProposerBond",
4730
+ args: [proposalId]
4731
+ }),
4732
+ value: "0x0",
4733
+ chainId: getChain().id
4734
+ }
4735
+ ],
4736
+ preconditions: [],
4737
+ description: `Release proposal #${proposalId}'s proposer bond from escrow back to the proposer.`,
4738
+ note: "Permissionless \u2014 any wallet may broadcast it; the WOOD goes to whoever posted the bond. The proposal must be Rejected / Expired / Cancelled / Settled, and for an EXECUTED proposal the challenge window (executedAt + strategyDuration + challengeWindow) must have closed."
4739
+ });
4740
+ return;
4741
+ }
4742
+ const spinner = ora6("Loading proposal...").start();
4743
+ const [p, state] = await Promise.all([
4744
+ getProposal(vault, proposalId),
4745
+ getProposalState(vault, proposalId)
4746
+ ]);
4747
+ const TERMINAL = /* @__PURE__ */ new Set([
4748
+ PROPOSAL_STATE.Rejected,
4749
+ PROPOSAL_STATE.Expired,
4750
+ PROPOSAL_STATE.Cancelled,
4751
+ PROPOSAL_STATE.Settled
4752
+ ]);
4753
+ if (!TERMINAL.has(state)) {
4754
+ spinner.fail(
4755
+ `Proposal is ${PROPOSAL_STATES[state] || "Unknown"} \u2014 a bond is only reclaimable from Rejected / Expired / Cancelled / Settled.`
4756
+ );
4757
+ process.exit(1);
4758
+ }
4759
+ if (p.proposerBondWood === 0n) {
4760
+ spinner.fail(
4761
+ "This proposal has no proposer bond left to reclaim (never bonded, already reclaimed, or forfeited)."
4762
+ );
4763
+ process.exit(1);
4764
+ }
4765
+ spinner.text = W3(`Reclaiming ${formatUnits8(p.proposerBondWood, 18)} WOOD...`);
4766
+ const hash = await reclaimProposerBond(vault, proposalId);
4767
+ spinner.succeed(G3(`Bond released: ${formatUnits8(p.proposerBondWood, 18)} WOOD \u2192 ${p.proposer}`));
4768
+ console.log(DIM3(` ${getExplorerUrl(hash)}`));
4769
+ console.log();
4770
+ } catch (err) {
4771
+ console.error(chalk8.red(`
4772
+ \u2716 ${formatContractError(err)}`));
4773
+ process.exit(1);
4774
+ }
4775
+ });
4565
4776
  proposal.command("simulate").description("Simulate proposal calls via Tenderly (or eth_call fallback)").option("--id <proposalId>", "Proposal ID to simulate").option("--vault <address>", "Vault address (required \u2014 proposal IDs are per-vault)").option("--execute-calls <path>", "Path to JSON execute calls file").option("--settle-calls <path>", "Path to JSON settlement calls file").option("--notify <subdomain>", "Send results to vault XMTP chat").action(async (opts) => {
4566
4777
  try {
4567
4778
  let vault;
@@ -7837,9 +8048,9 @@ try {
7837
8048
  } catch {
7838
8049
  }
7839
8050
  var require2 = createRequire(import.meta.url);
7840
- var CLI_VERSION = "0.87.0";
8051
+ var CLI_VERSION = "0.88.0";
7841
8052
  async function loadXmtp() {
7842
- return import("./xmtp-7LAWDKJT.js");
8053
+ return import("./xmtp-72IRK7JL.js");
7843
8054
  }
7844
8055
  async function loadCron() {
7845
8056
  return import("./cron-E3UAZF5B.js");
@@ -8510,7 +8721,7 @@ vaultCmd.command("add").description("Register an agent on a vault (creator only)
8510
8721
  agentId = BigInt(opts.agentId);
8511
8722
  } else {
8512
8723
  spinner.text = "Looking up ERC-8004 identity from wallet...";
8513
- const { lookupAgentIdByWallet } = await import("./identity-OLD25QEP.js");
8724
+ const { lookupAgentIdByWallet } = await import("./identity-I2BG4IGT.js");
8514
8725
  const resolved = await lookupAgentIdByWallet(agentWallet);
8515
8726
  if (resolved === null) {
8516
8727
  spinner.fail("Agent wallet does not own an ERC-8004 identity NFT");
@@ -9213,7 +9424,7 @@ vaultCmd.command("redeem").description("Redeem vault shares for the underlying a
9213
9424
  var strategy = program.command("strategy").description("Strategy templates \u2014 list, clone, propose");
9214
9425
  registerStrategyTemplateCommands(strategy);
9215
9426
  program.command("providers").description("List available providers (research + swap routing)").action(async () => {
9216
- const { listProviders } = await import("./providers-KZNCCUKT.js");
9427
+ const { listProviders } = await import("./providers-6UZKDFQD.js");
9217
9428
  for (const info of listProviders()) {
9218
9429
  console.log(`
9219
9430
  ${info.name} (${info.type})`);
@@ -9223,7 +9434,7 @@ ${info.name} (${info.type})`);
9223
9434
  }
9224
9435
  });
9225
9436
  try {
9226
- const { registerChatCommands } = await import("./chat-OZAAN5LT.js");
9437
+ const { registerChatCommands } = await import("./chat-AKLYUJZV.js");
9227
9438
  registerChatCommands(program);
9228
9439
  } catch {
9229
9440
  program.command("chat <name> [action] [actionArgs...]").description("Vault chat (XMTP) \u2014 requires @xmtp/cli").action(() => {
@@ -9233,7 +9444,7 @@ try {
9233
9444
  process.exit(1);
9234
9445
  });
9235
9446
  }
9236
- var { registerSessionCommands } = await import("./session-A7CYZSSA.js");
9447
+ var { registerSessionCommands } = await import("./session-45NQAHFI.js");
9237
9448
  registerSessionCommands(program);
9238
9449
  registerVeniceCommands(program);
9239
9450
  registerAllowanceCommands(program);
@@ -9242,11 +9453,11 @@ registerProposalCommands(program);
9242
9453
  registerQueueCommands(program);
9243
9454
  registerGovernorCommands(program);
9244
9455
  registerGuardianCommands(program);
9245
- var { registerResearchCommands } = await import("./research-ARFBFXIT.js");
9456
+ var { registerResearchCommands } = await import("./research-T7A27OMB.js");
9246
9457
  registerResearchCommands(program);
9247
- var { registerAgentCommands } = await import("./agent-A2JEYGQS.js");
9458
+ var { registerAgentCommands } = await import("./agent-FCGZL4GF.js");
9248
9459
  registerAgentCommands(program);
9249
- var { registerTradeCommands } = await import("./trade-ZCK332E4.js");
9460
+ var { registerTradeCommands } = await import("./trade-ZOVM433K.js");
9250
9461
  registerTradeCommands(program);
9251
9462
  registerGridCommand(program);
9252
9463
  var configCmd = program.command("config");