@sherwoodagent/cli 0.73.4 → 0.74.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 (80) hide show
  1. package/dist/{abis-KP7M4IPM.js → abis-D7EDCKVZ.js} +2 -2
  2. package/dist/{addresses-DGB3D457.js → addresses-OFFTM6NG.js} +4 -4
  3. package/dist/{agent-UNSW5IPO.js → agent-IJOOONON.js} +8 -8
  4. package/dist/{chat-KT2WVDT2.js → chat-3PM3GP3C.js} +9 -10
  5. package/dist/{chat-KT2WVDT2.js.map → chat-3PM3GP3C.js.map} +1 -1
  6. package/dist/{chunk-ROKE6ZAW.js → chunk-2OHX3O55.js} +6 -20
  7. package/dist/chunk-2OHX3O55.js.map +1 -0
  8. package/dist/{chunk-GSC7PVEO.js → chunk-6MV4ESXM.js} +43 -7
  9. package/dist/chunk-6MV4ESXM.js.map +1 -0
  10. package/dist/chunk-7BMCLMSE.js +173 -0
  11. package/dist/chunk-7BMCLMSE.js.map +1 -0
  12. package/dist/{chunk-NPWYX6NU.js → chunk-BD4ZV7FQ.js} +3 -3
  13. package/dist/{chunk-BKJ7HYX7.js → chunk-DGLLSZ2D.js} +10 -10
  14. package/dist/chunk-DGLLSZ2D.js.map +1 -0
  15. package/dist/chunk-EGJESQXZ.js +1 -0
  16. package/dist/chunk-I2PC6TBZ.js +3887 -0
  17. package/dist/chunk-I2PC6TBZ.js.map +1 -0
  18. package/dist/{chunk-CHWBQJLT.js → chunk-JF7KAVOM.js} +8 -21
  19. package/dist/chunk-JF7KAVOM.js.map +1 -0
  20. package/dist/{chunk-DXJJMRBM.js → chunk-LHVSS27T.js} +2 -2
  21. package/dist/{chunk-2U4TWPWQ.js → chunk-MUINMYCE.js} +5 -5
  22. package/dist/{chunk-GU5VZGXB.js → chunk-N3NVFSDQ.js} +5 -5
  23. package/dist/{chunk-CZRJ5GWE.js → chunk-RAP6MUMB.js} +54 -24
  24. package/dist/chunk-RAP6MUMB.js.map +1 -0
  25. package/dist/{chunk-ZURDCYGU.js → chunk-RE3PPAXZ.js} +9 -5
  26. package/dist/chunk-RE3PPAXZ.js.map +1 -0
  27. package/dist/{chunk-IFL5SREW.js → chunk-UINMHN6S.js} +2 -2
  28. package/dist/chunk-WBQMGZ5X.js +1253 -0
  29. package/dist/chunk-WBQMGZ5X.js.map +1 -0
  30. package/dist/{client-NAL3HVLK.js → client-C3C6IXAH.js} +4 -4
  31. package/dist/{config-FAQO37S7.js → config-7HU4X7EK.js} +4 -4
  32. package/dist/{eas-QAH7XVLK.js → eas-G4TPLJ6S.js} +7 -7
  33. package/dist/{governor-S56M6BV6.js → governor-PYQQ7QRG.js} +7 -7
  34. package/dist/index.js +201 -1286
  35. package/dist/index.js.map +1 -1
  36. package/dist/{network-MKMX2NG6.js → network-WU2QC3L4.js} +3 -3
  37. package/dist/{price-HHDBMKIE.js → price-DGGB6W2G.js} +15 -37
  38. package/dist/price-DGGB6W2G.js.map +1 -0
  39. package/dist/providers-YOOQFBN2.js +31 -0
  40. package/dist/providers-YOOQFBN2.js.map +1 -0
  41. package/dist/{research-IJBOMYL3.js → research-KX3LCAOQ.js} +9 -9
  42. package/dist/{session-L67AVWBY.js → session-GUVSID3Z.js} +19 -174
  43. package/dist/session-GUVSID3Z.js.map +1 -0
  44. package/dist/{trade-LGFQEK3I.js → trade-WDPMFFYB.js} +277 -43
  45. package/dist/trade-WDPMFFYB.js.map +1 -0
  46. package/dist/{vault-XWFPGHRA.js → vault-WDRLJLJ6.js} +14 -9
  47. package/dist/{xmtp-6US7GH3Z.js → xmtp-Q4ZSQV2Q.js} +11 -15
  48. package/dist/xmtp-Q4ZSQV2Q.js.map +1 -0
  49. package/package.json +2 -1
  50. package/dist/chunk-BKJ7HYX7.js.map +0 -1
  51. package/dist/chunk-BQMOE4FJ.js +0 -1629
  52. package/dist/chunk-BQMOE4FJ.js.map +0 -1
  53. package/dist/chunk-CHWBQJLT.js.map +0 -1
  54. package/dist/chunk-CZRJ5GWE.js.map +0 -1
  55. package/dist/chunk-DIZEB2VV.js +0 -325
  56. package/dist/chunk-DIZEB2VV.js.map +0 -1
  57. package/dist/chunk-GSC7PVEO.js.map +0 -1
  58. package/dist/chunk-ROKE6ZAW.js.map +0 -1
  59. package/dist/chunk-ZURDCYGU.js.map +0 -1
  60. package/dist/price-HHDBMKIE.js.map +0 -1
  61. package/dist/research-4TBGYEVI.js +0 -14
  62. package/dist/session-L67AVWBY.js.map +0 -1
  63. package/dist/trade-LGFQEK3I.js.map +0 -1
  64. package/dist/xmtp-6US7GH3Z.js.map +0 -1
  65. /package/dist/{abis-KP7M4IPM.js.map → abis-D7EDCKVZ.js.map} +0 -0
  66. /package/dist/{addresses-DGB3D457.js.map → addresses-OFFTM6NG.js.map} +0 -0
  67. /package/dist/{agent-UNSW5IPO.js.map → agent-IJOOONON.js.map} +0 -0
  68. /package/dist/{chunk-NPWYX6NU.js.map → chunk-BD4ZV7FQ.js.map} +0 -0
  69. /package/dist/{client-NAL3HVLK.js.map → chunk-EGJESQXZ.js.map} +0 -0
  70. /package/dist/{chunk-DXJJMRBM.js.map → chunk-LHVSS27T.js.map} +0 -0
  71. /package/dist/{chunk-2U4TWPWQ.js.map → chunk-MUINMYCE.js.map} +0 -0
  72. /package/dist/{chunk-GU5VZGXB.js.map → chunk-N3NVFSDQ.js.map} +0 -0
  73. /package/dist/{chunk-IFL5SREW.js.map → chunk-UINMHN6S.js.map} +0 -0
  74. /package/dist/{config-FAQO37S7.js.map → client-C3C6IXAH.js.map} +0 -0
  75. /package/dist/{eas-QAH7XVLK.js.map → config-7HU4X7EK.js.map} +0 -0
  76. /package/dist/{governor-S56M6BV6.js.map → eas-G4TPLJ6S.js.map} +0 -0
  77. /package/dist/{network-MKMX2NG6.js.map → governor-PYQQ7QRG.js.map} +0 -0
  78. /package/dist/{research-4TBGYEVI.js.map → network-WU2QC3L4.js.map} +0 -0
  79. /package/dist/{research-IJBOMYL3.js.map → research-KX3LCAOQ.js.map} +0 -0
  80. /package/dist/{vault-XWFPGHRA.js.map → vault-WDRLJLJ6.js.map} +0 -0
package/dist/index.js CHANGED
@@ -9,19 +9,48 @@ import {
9
9
  hlPlaceLimitOrder,
10
10
  resolveHLCoin
11
11
  } from "./chunk-DBOINZYU.js";
12
- import {
13
- UniswapProvider,
14
- applySlippage,
15
- encodeSwapPath,
16
- getMultiHopQuote,
17
- getQuote
18
- } from "./chunk-DIZEB2VV.js";
12
+ import "./chunk-EGJESQXZ.js";
19
13
  import {
20
14
  chatCompletion,
21
15
  checkApiKeyValid,
22
16
  listModels,
23
17
  provisionApiKey
24
- } from "./chunk-NPWYX6NU.js";
18
+ } from "./chunk-BD4ZV7FQ.js";
19
+ import {
20
+ approveDepositor,
21
+ deposit,
22
+ depositWithEthWrap,
23
+ getAgentAddresses,
24
+ getAgentFeeBps,
25
+ getAssetAddress,
26
+ getAssetDecimals,
27
+ getBalance,
28
+ getNetDeposited,
29
+ getShareBalance,
30
+ getVaultAddress,
31
+ getVaultInfo,
32
+ getVaultOwner,
33
+ isAgent,
34
+ preflightDeposit,
35
+ preflightRedeem,
36
+ redeem,
37
+ registerAgent,
38
+ removeDepositor,
39
+ setAgentFeeBps,
40
+ setVaultAddress
41
+ } from "./chunk-RAP6MUMB.js";
42
+ import "./chunk-7BMCLMSE.js";
43
+ import {
44
+ applySlippage,
45
+ assetDecimalsForSymbol,
46
+ buildCallsForTemplate,
47
+ buildInitDataForTemplate,
48
+ computeProposalAssetChecks,
49
+ encodeSwapPath,
50
+ getMultiHopQuote,
51
+ getQuote,
52
+ resolveToken
53
+ } from "./chunk-WBQMGZ5X.js";
25
54
  import {
26
55
  createApproval,
27
56
  createJoinRequest,
@@ -32,42 +61,20 @@ import {
32
61
  queryJoinRequests,
33
62
  revokeJoinRequest,
34
63
  stripReferrerPrefix
35
- } from "./chunk-GU5VZGXB.js";
64
+ } from "./chunk-N3NVFSDQ.js";
36
65
  import {
37
66
  createFund,
38
67
  getActiveFunds,
39
68
  getFund,
40
69
  subdomainExists,
41
70
  updateMetadata
42
- } from "./chunk-2U4TWPWQ.js";
71
+ } from "./chunk-MUINMYCE.js";
43
72
  import {
44
73
  resolveFund,
45
74
  resolveVaultFund,
46
75
  searchFundAcrossChains,
47
76
  setTextRecord
48
- } from "./chunk-CHWBQJLT.js";
49
- import {
50
- approveDepositor,
51
- deposit,
52
- depositWithEthWrap,
53
- executeBatch,
54
- getAgentFeeBps,
55
- getAssetAddress,
56
- getAssetDecimals,
57
- getBalance,
58
- getShareBalance,
59
- getVaultAddress,
60
- getVaultInfo,
61
- getVaultOwner,
62
- isAgent,
63
- preflightDeposit,
64
- preflightRedeem,
65
- redeem,
66
- registerAgent,
67
- removeDepositor,
68
- setAgentFeeBps,
69
- setVaultAddress
70
- } from "./chunk-CZRJ5GWE.js";
77
+ } from "./chunk-JF7KAVOM.js";
71
78
  import {
72
79
  PROPOSAL_STATE,
73
80
  PROPOSAL_STATES,
@@ -101,21 +108,17 @@ import {
101
108
  setVotingPeriod,
102
109
  settleProposal,
103
110
  vote
104
- } from "./chunk-ZURDCYGU.js";
111
+ } from "./chunk-RE3PPAXZ.js";
105
112
  import {
106
113
  AERODROME,
107
114
  AGENT_REGISTRY,
108
- CHAINLINK,
109
115
  MOONWELL,
110
- ROBINHOOD_STOCK_ROUTES,
111
116
  SHERWOOD,
112
117
  STRATEGY_TEMPLATES,
113
- SYNTHRA,
114
118
  TOKENS,
115
119
  UNISWAP,
116
- VENICE,
117
- robinhoodEquityMaxAge
118
- } from "./chunk-IFL5SREW.js";
120
+ VENICE
121
+ } from "./chunk-UINMHN6S.js";
119
122
  import {
120
123
  GAS_UNITS,
121
124
  estimateGasCushion,
@@ -126,7 +129,7 @@ import {
126
129
  sendTxWithRetry,
127
130
  waitForReceipt,
128
131
  writeContractWithRetry
129
- } from "./chunk-ROKE6ZAW.js";
132
+ } from "./chunk-2OHX3O55.js";
130
133
  import {
131
134
  DEFAULT_NETWORK,
132
135
  VALID_NETWORKS,
@@ -138,7 +141,7 @@ import {
138
141
  isTestnet,
139
142
  setNetwork,
140
143
  withNetwork
141
- } from "./chunk-DXJJMRBM.js";
144
+ } from "./chunk-LHVSS27T.js";
142
145
  import {
143
146
  addFund,
144
147
  cacheGroupId,
@@ -151,6 +154,7 @@ import {
151
154
  getUniswapApiKey,
152
155
  getVeniceApiKey,
153
156
  loadConfig,
157
+ requirePrivateKey,
154
158
  setAgentId,
155
159
  setAnthropicApiKey,
156
160
  setChainContract,
@@ -160,7 +164,7 @@ import {
160
164
  setPrivateKey,
161
165
  setUniswapApiKey,
162
166
  setVeniceApiKey
163
- } from "./chunk-GSC7PVEO.js";
167
+ } from "./chunk-6MV4ESXM.js";
164
168
  import {
165
169
  BASE_STRATEGY_ABI,
166
170
  ERC20_ABI,
@@ -170,7 +174,7 @@ import {
170
174
  SWAP_ROUTER_EXACT_INPUT_SINGLE_ABI,
171
175
  SYNDICATE_VAULT_ABI,
172
176
  VENICE_STAKING_ABI
173
- } from "./chunk-BQMOE4FJ.js";
177
+ } from "./chunk-I2PC6TBZ.js";
174
178
  import {
175
179
  fetchMetadata,
176
180
  mergeFundMetadata,
@@ -186,6 +190,9 @@ import chalk16 from "chalk";
186
190
  import ora9 from "ora";
187
191
  import { input, confirm, select } from "@inquirer/prompts";
188
192
 
193
+ // src/lib/generated/contract-constants.ts
194
+ var MAX_AGENT_FEE_BPS = 1500;
195
+
189
196
  // src/lib/format.ts
190
197
  function formatDurationShort(seconds) {
191
198
  const s = Number(seconds);
@@ -216,42 +223,8 @@ function parseBigIntArg(value, name) {
216
223
  return BigInt(value);
217
224
  }
218
225
 
219
- // src/providers/moonwell.ts
220
- import { base, baseSepolia } from "viem/chains";
221
- var MoonwellProvider = class {
222
- info() {
223
- return {
224
- name: "moonwell",
225
- type: "lending",
226
- capabilities: [
227
- "lend.deposit",
228
- "lend.borrow",
229
- "lend.repay",
230
- "lend.withdraw",
231
- "lend.positions"
232
- ],
233
- supportedChains: [base, baseSepolia]
234
- };
235
- }
236
- async depositCollateral(params) {
237
- throw new Error("Not implemented \u2014 wire up viem client");
238
- }
239
- async borrow(params) {
240
- throw new Error("Not implemented");
241
- }
242
- async repay(params) {
243
- throw new Error("Not implemented");
244
- }
245
- async withdrawCollateral(params) {
246
- throw new Error("Not implemented");
247
- }
248
- async getPosition(account) {
249
- throw new Error("Not implemented");
250
- }
251
- };
252
-
253
226
  // src/commands/strategy-template.ts
254
- import { parseUnits, formatUnits as formatUnits2, isAddress as isAddress2, erc20Abi, encodeAbiParameters as encodeAbiParameters11, decodeAbiParameters } from "viem";
227
+ import { parseUnits, formatUnits as formatUnits2, isAddress as isAddress2, erc20Abi, encodeAbiParameters as encodeAbiParameters3, decodeAbiParameters } from "viem";
255
228
  import chalk from "chalk";
256
229
  import ora from "ora";
257
230
  import { writeFileSync, mkdirSync } from "fs";
@@ -2077,603 +2050,8 @@ function encodeSetCommission(args, chainId) {
2077
2050
  // ../sdk/dist/reads/funds.js
2078
2051
  import { getAddress as getAddress8 } from "viem";
2079
2052
 
2080
- // src/strategies/moonwell-supply-template.ts
2081
- import { encodeAbiParameters as encodeAbiParameters3, encodeFunctionData as encodeFunctionData8 } from "viem";
2082
- function buildInitData(underlying, mToken, supplyAmount, minRedeemAmount, isNativeEthMarket) {
2083
- return encodeAbiParameters3(
2084
- [
2085
- { type: "address" },
2086
- { type: "address" },
2087
- { type: "uint256" },
2088
- { type: "uint256" },
2089
- { type: "bool" }
2090
- ],
2091
- [underlying, mToken, supplyAmount, minRedeemAmount, isNativeEthMarket]
2092
- );
2093
- }
2094
- function buildExecuteCalls(clone, underlying, supplyAmount) {
2095
- return [
2096
- {
2097
- target: underlying,
2098
- data: encodeFunctionData8({
2099
- abi: ERC20_ABI,
2100
- functionName: "approve",
2101
- args: [clone, supplyAmount]
2102
- }),
2103
- value: 0n
2104
- },
2105
- {
2106
- target: clone,
2107
- data: encodeFunctionData8({
2108
- abi: BASE_STRATEGY_ABI,
2109
- functionName: "execute"
2110
- }),
2111
- value: 0n
2112
- }
2113
- ];
2114
- }
2115
- function buildSettleCalls(clone) {
2116
- return [
2117
- {
2118
- target: clone,
2119
- data: encodeFunctionData8({
2120
- abi: BASE_STRATEGY_ABI,
2121
- functionName: "settle"
2122
- }),
2123
- value: 0n
2124
- }
2125
- ];
2126
- }
2127
-
2128
- // src/strategies/venice-inference-template.ts
2129
- import { encodeAbiParameters as encodeAbiParameters4, encodeFunctionData as encodeFunctionData9 } from "viem";
2130
- var INIT_PARAMS_TYPES = [
2131
- {
2132
- type: "tuple",
2133
- components: [
2134
- { name: "asset", type: "address" },
2135
- { name: "weth", type: "address" },
2136
- { name: "vvv", type: "address" },
2137
- { name: "sVVV", type: "address" },
2138
- { name: "aeroRouter", type: "address" },
2139
- { name: "aeroFactory", type: "address" },
2140
- { name: "agent", type: "address" },
2141
- { name: "assetAmount", type: "uint256" },
2142
- { name: "minVVV", type: "uint256" },
2143
- { name: "deadlineOffset", type: "uint256" },
2144
- { name: "singleHop", type: "bool" }
2145
- ]
2146
- }
2147
- ];
2148
- function buildInitData2(params) {
2149
- return encodeAbiParameters4(INIT_PARAMS_TYPES, [params]);
2150
- }
2151
- function buildExecuteCalls2(clone, asset, assetAmount) {
2152
- return [
2153
- {
2154
- target: asset,
2155
- data: encodeFunctionData9({
2156
- abi: ERC20_ABI,
2157
- functionName: "approve",
2158
- args: [clone, assetAmount]
2159
- }),
2160
- value: 0n
2161
- },
2162
- {
2163
- target: clone,
2164
- data: encodeFunctionData9({
2165
- abi: BASE_STRATEGY_ABI,
2166
- functionName: "execute"
2167
- }),
2168
- value: 0n
2169
- }
2170
- ];
2171
- }
2172
- function buildSettleCalls2(clone) {
2173
- return [
2174
- {
2175
- target: clone,
2176
- data: encodeFunctionData9({
2177
- abi: BASE_STRATEGY_ABI,
2178
- functionName: "settle"
2179
- }),
2180
- value: 0n
2181
- }
2182
- ];
2183
- }
2184
-
2185
- // src/strategies/aerodrome-lp-template.ts
2186
- import { encodeAbiParameters as encodeAbiParameters5, encodeFunctionData as encodeFunctionData10 } from "viem";
2187
- var INIT_PARAMS_TYPES2 = [
2188
- {
2189
- type: "tuple",
2190
- components: [
2191
- { name: "tokenA", type: "address" },
2192
- { name: "tokenB", type: "address" },
2193
- { name: "stable", type: "bool" },
2194
- { name: "factory", type: "address" },
2195
- { name: "router", type: "address" },
2196
- { name: "gauge", type: "address" },
2197
- { name: "lpToken", type: "address" },
2198
- { name: "amountADesired", type: "uint256" },
2199
- { name: "amountBDesired", type: "uint256" },
2200
- { name: "amountAMin", type: "uint256" },
2201
- { name: "amountBMin", type: "uint256" },
2202
- { name: "minAmountAOut", type: "uint256" },
2203
- { name: "minAmountBOut", type: "uint256" }
2204
- ]
2205
- }
2206
- ];
2207
- function buildInitData3(params) {
2208
- return encodeAbiParameters5(INIT_PARAMS_TYPES2, [params]);
2209
- }
2210
- function buildExecuteCalls3(clone, tokenA, amountA, tokenB, amountB) {
2211
- return [
2212
- {
2213
- target: tokenA,
2214
- data: encodeFunctionData10({
2215
- abi: ERC20_ABI,
2216
- functionName: "approve",
2217
- args: [clone, amountA]
2218
- }),
2219
- value: 0n
2220
- },
2221
- {
2222
- target: tokenB,
2223
- data: encodeFunctionData10({
2224
- abi: ERC20_ABI,
2225
- functionName: "approve",
2226
- args: [clone, amountB]
2227
- }),
2228
- value: 0n
2229
- },
2230
- {
2231
- target: clone,
2232
- data: encodeFunctionData10({
2233
- abi: BASE_STRATEGY_ABI,
2234
- functionName: "execute"
2235
- }),
2236
- value: 0n
2237
- }
2238
- ];
2239
- }
2240
- function buildSettleCalls3(clone) {
2241
- return [
2242
- {
2243
- target: clone,
2244
- data: encodeFunctionData10({
2245
- abi: BASE_STRATEGY_ABI,
2246
- functionName: "settle"
2247
- }),
2248
- value: 0n
2249
- }
2250
- ];
2251
- }
2252
-
2253
- // src/strategies/wsteth-moonwell-template.ts
2254
- import { encodeAbiParameters as encodeAbiParameters6, encodeFunctionData as encodeFunctionData11, maxUint256 as maxUint2562 } from "viem";
2255
- var INIT_PARAMS_TYPES3 = [
2256
- {
2257
- type: "tuple",
2258
- components: [
2259
- { name: "weth", type: "address" },
2260
- { name: "wsteth", type: "address" },
2261
- { name: "mwsteth", type: "address" },
2262
- { name: "aeroRouter", type: "address" },
2263
- { name: "aeroFactory", type: "address" },
2264
- { name: "chainlinkWstethEthFeed", type: "address" },
2265
- { name: "supplyAmount", type: "uint256" },
2266
- { name: "minWstethOutPerWeth", type: "uint256" },
2267
- { name: "minWethOutPerWsteth", type: "uint256" },
2268
- { name: "deadlineOffset", type: "uint256" }
2269
- ]
2270
- }
2271
- ];
2272
- function buildInitData4(params) {
2273
- return encodeAbiParameters6(INIT_PARAMS_TYPES3, [params]);
2274
- }
2275
- function buildExecuteCalls4(clone, weth, supplyAmount) {
2276
- const approveAmount = supplyAmount === 0n ? maxUint2562 : supplyAmount;
2277
- return [
2278
- {
2279
- target: weth,
2280
- data: encodeFunctionData11({
2281
- abi: ERC20_ABI,
2282
- functionName: "approve",
2283
- args: [clone, approveAmount]
2284
- }),
2285
- value: 0n
2286
- },
2287
- {
2288
- target: clone,
2289
- data: encodeFunctionData11({
2290
- abi: BASE_STRATEGY_ABI,
2291
- functionName: "execute"
2292
- }),
2293
- value: 0n
2294
- },
2295
- {
2296
- target: weth,
2297
- data: encodeFunctionData11({
2298
- abi: ERC20_ABI,
2299
- functionName: "approve",
2300
- args: [clone, 0n]
2301
- }),
2302
- value: 0n
2303
- }
2304
- ];
2305
- }
2306
- function buildSettleCalls4(clone) {
2307
- return [
2308
- {
2309
- target: clone,
2310
- data: encodeFunctionData11({
2311
- abi: BASE_STRATEGY_ABI,
2312
- functionName: "settle"
2313
- }),
2314
- value: 0n
2315
- }
2316
- ];
2317
- }
2318
-
2319
- // src/strategies/mamo-yield-template.ts
2320
- import { encodeAbiParameters as encodeAbiParameters7, encodeFunctionData as encodeFunctionData12 } from "viem";
2321
- function buildInitData5(underlying, mamoFactory, minRedeemAmount) {
2322
- return encodeAbiParameters7(
2323
- [
2324
- { type: "address" },
2325
- { type: "address" },
2326
- { type: "uint256" }
2327
- ],
2328
- [underlying, mamoFactory, minRedeemAmount]
2329
- );
2330
- }
2331
- function buildExecuteCalls5(clone, underlying, amount) {
2332
- return [
2333
- {
2334
- target: underlying,
2335
- data: encodeFunctionData12({
2336
- abi: ERC20_ABI,
2337
- functionName: "approve",
2338
- args: [clone, amount]
2339
- }),
2340
- value: 0n
2341
- },
2342
- {
2343
- target: clone,
2344
- data: encodeFunctionData12({
2345
- abi: BASE_STRATEGY_ABI,
2346
- functionName: "execute"
2347
- }),
2348
- value: 0n
2349
- }
2350
- ];
2351
- }
2352
- function buildSettleCalls5(clone) {
2353
- return [
2354
- {
2355
- target: clone,
2356
- data: encodeFunctionData12({
2357
- abi: BASE_STRATEGY_ABI,
2358
- functionName: "settle"
2359
- }),
2360
- value: 0n
2361
- }
2362
- ];
2363
- }
2364
-
2365
- // src/strategies/portfolio-template.ts
2366
- import { concat as concat2, encodeAbiParameters as encodeAbiParameters8, encodeFunctionData as encodeFunctionData13, numberToHex, pad } from "viem";
2367
- function withMode(mode, routeData) {
2368
- const modeByte = `0x${mode.toString(16).padStart(2, "0")}`;
2369
- return concat2([modeByte, routeData]);
2370
- }
2371
- function v3SingleHopExtraData(fee) {
2372
- return withMode(0, encodeAbiParameters8([{ type: "uint24" }], [fee]));
2373
- }
2374
- function v4SingleHopExtraData(fee, tickSpacing) {
2375
- return withMode(
2376
- 2,
2377
- encodeAbiParameters8(
2378
- [{ type: "uint24" }, { type: "int24" }],
2379
- [fee, tickSpacing]
2380
- )
2381
- );
2382
- }
2383
- function v4PathExtraData(hops) {
2384
- if (hops.length < 2) throw new Error("v4PathExtraData: mode 3 needs >= 2 hops (use v4SingleHopExtraData for one)");
2385
- return withMode(
2386
- 3,
2387
- encodeAbiParameters8(
2388
- [
2389
- {
2390
- type: "tuple[]",
2391
- components: [
2392
- { type: "address", name: "currency" },
2393
- { type: "uint24", name: "fee" },
2394
- { type: "int24", name: "tickSpacing" }
2395
- ]
2396
- }
2397
- ],
2398
- [hops.map((h) => ({ currency: h.currency, fee: h.fee, tickSpacing: h.tickSpacing }))]
2399
- )
2400
- );
2401
- }
2402
- var EQUITY_MAX_PRICE_AGE_SECONDS = 96 * 60 * 60;
2403
- var MIN_MAX_PRICE_AGE = 3600;
2404
- var MAX_MAX_PRICE_AGE = 2592e3;
2405
- function pushFeedId(feed, maxAgeSeconds) {
2406
- if (maxAgeSeconds === void 0 || maxAgeSeconds === 0) {
2407
- return pad(feed, { size: 32 });
2408
- }
2409
- if (!Number.isInteger(maxAgeSeconds) || maxAgeSeconds < MIN_MAX_PRICE_AGE || maxAgeSeconds > MAX_MAX_PRICE_AGE) {
2410
- throw new Error(
2411
- `pushFeedId: maxAgeSeconds must be an integer in [${MIN_MAX_PRICE_AGE}, ${MAX_MAX_PRICE_AGE}] (or 0 for the contract default), got ${maxAgeSeconds}`
2412
- );
2413
- }
2414
- const packed = BigInt(maxAgeSeconds) << 160n | BigInt(feed);
2415
- return numberToHex(packed, { size: 32 });
2416
- }
2417
- function buildInitData6(asset, swapAdapter, chainlinkVerifier, allocations, totalAmount, maxSlippageBps) {
2418
- const tokens = allocations.map((a) => a.token);
2419
- const weightsBps = allocations.map((a) => BigInt(a.weightBps));
2420
- const swapExtraData = allocations.map((a) => a.swapExtraData);
2421
- const priceDecimals = allocations.map((a) => a.priceDecimals);
2422
- const feedIds = allocations.map((a) => a.feedId);
2423
- return encodeAbiParameters8(
2424
- [
2425
- { type: "address" },
2426
- { type: "address" },
2427
- { type: "address" },
2428
- { type: "address[]" },
2429
- { type: "uint256[]" },
2430
- { type: "uint256" },
2431
- { type: "uint256" },
2432
- { type: "bytes[]" },
2433
- { type: "uint8[]" },
2434
- { type: "bytes32[]" }
2435
- ],
2436
- [
2437
- asset,
2438
- swapAdapter,
2439
- chainlinkVerifier,
2440
- tokens,
2441
- weightsBps,
2442
- totalAmount,
2443
- BigInt(maxSlippageBps),
2444
- swapExtraData,
2445
- priceDecimals,
2446
- feedIds
2447
- ]
2448
- );
2449
- }
2450
- function buildExecuteCalls6(clone, asset, totalAmount) {
2451
- return [
2452
- {
2453
- target: asset,
2454
- data: encodeFunctionData13({
2455
- abi: ERC20_ABI,
2456
- functionName: "approve",
2457
- args: [clone, totalAmount]
2458
- }),
2459
- value: 0n
2460
- },
2461
- {
2462
- target: clone,
2463
- data: encodeFunctionData13({
2464
- abi: BASE_STRATEGY_ABI,
2465
- functionName: "execute"
2466
- }),
2467
- value: 0n
2468
- }
2469
- ];
2470
- }
2471
- function buildSettleCalls6(clone) {
2472
- return [
2473
- {
2474
- target: clone,
2475
- data: encodeFunctionData13({
2476
- abi: BASE_STRATEGY_ABI,
2477
- functionName: "settle"
2478
- }),
2479
- value: 0n
2480
- }
2481
- ];
2482
- }
2483
-
2484
- // src/strategies/hyperliquid-perp-template.ts
2485
- import { encodeAbiParameters as encodeAbiParameters9, encodeFunctionData as encodeFunctionData14, maxUint256 as maxUint2563 } from "viem";
2486
- function buildInitData7(asset, depositAmount, perpAssetIndex, leverage, maxPositionSize, maxTradesPerDay) {
2487
- return encodeAbiParameters9(
2488
- [
2489
- { type: "address" },
2490
- { type: "uint256" },
2491
- { type: "uint32" },
2492
- { type: "uint32" },
2493
- { type: "uint256" },
2494
- { type: "uint32" }
2495
- ],
2496
- [asset, depositAmount, perpAssetIndex, leverage, maxPositionSize, maxTradesPerDay]
2497
- );
2498
- }
2499
- function buildExecuteCalls7(clone, asset, amount) {
2500
- const approveAmount = amount === 0n ? maxUint2563 : amount;
2501
- return [
2502
- {
2503
- target: asset,
2504
- data: encodeFunctionData14({
2505
- abi: ERC20_ABI,
2506
- functionName: "approve",
2507
- args: [clone, approveAmount]
2508
- }),
2509
- value: 0n
2510
- },
2511
- {
2512
- target: clone,
2513
- data: encodeFunctionData14({
2514
- abi: BASE_STRATEGY_ABI,
2515
- functionName: "execute"
2516
- }),
2517
- value: 0n
2518
- },
2519
- {
2520
- target: asset,
2521
- data: encodeFunctionData14({
2522
- abi: ERC20_ABI,
2523
- functionName: "approve",
2524
- args: [clone, 0n]
2525
- }),
2526
- value: 0n
2527
- }
2528
- ];
2529
- }
2530
- function buildSettleCalls7(clone) {
2531
- return [
2532
- {
2533
- target: clone,
2534
- data: encodeFunctionData14({
2535
- abi: BASE_STRATEGY_ABI,
2536
- functionName: "settle"
2537
- }),
2538
- value: 0n
2539
- }
2540
- ];
2541
- }
2542
-
2543
- // src/strategies/hyperliquid-grid-template.ts
2544
- import { encodeAbiParameters as encodeAbiParameters10, encodeFunctionData as encodeFunctionData15, maxUint256 as maxUint2564 } from "viem";
2545
- function buildInitData8(asset, depositAmount, leverage, maxOrderSize, maxOrdersPerTick, assetIndices) {
2546
- return encodeAbiParameters10(
2547
- [
2548
- { type: "address" },
2549
- { type: "uint256" },
2550
- { type: "uint32" },
2551
- { type: "uint256" },
2552
- { type: "uint32" },
2553
- { type: "uint32[]" }
2554
- ],
2555
- [asset, depositAmount, leverage, maxOrderSize, maxOrdersPerTick, assetIndices]
2556
- );
2557
- }
2558
- function buildExecuteCalls8(clone, asset, amount) {
2559
- const approveAmount = amount === 0n ? maxUint2564 : amount;
2560
- return [
2561
- {
2562
- target: asset,
2563
- data: encodeFunctionData15({
2564
- abi: ERC20_ABI,
2565
- functionName: "approve",
2566
- args: [clone, approveAmount]
2567
- }),
2568
- value: 0n
2569
- },
2570
- {
2571
- target: clone,
2572
- data: encodeFunctionData15({
2573
- abi: BASE_STRATEGY_ABI,
2574
- functionName: "execute"
2575
- }),
2576
- value: 0n
2577
- },
2578
- {
2579
- target: asset,
2580
- data: encodeFunctionData15({
2581
- abi: ERC20_ABI,
2582
- functionName: "approve",
2583
- args: [clone, 0n]
2584
- }),
2585
- value: 0n
2586
- }
2587
- ];
2588
- }
2589
- function buildSettleCalls8(clone) {
2590
- return [
2591
- {
2592
- target: clone,
2593
- data: encodeFunctionData15({
2594
- abi: BASE_STRATEGY_ABI,
2595
- functionName: "settle"
2596
- }),
2597
- value: 0n
2598
- }
2599
- ];
2600
- }
2601
-
2602
2053
  // src/commands/strategy-template.ts
2603
- import { concat as concat3, numberToHex as numberToHex2 } from "viem";
2604
2054
  var ZERO = "0x0000000000000000000000000000000000000000";
2605
- var ZERO_BYTES323 = "0x0000000000000000000000000000000000000000000000000000000000000000";
2606
- function encodeV3Path(tokens, fees) {
2607
- if (tokens.length !== fees.length + 1) throw new Error("tokens.length must be fees.length + 1");
2608
- const parts = [];
2609
- for (let i = 0; i < tokens.length; i++) {
2610
- parts.push(tokens[i].toLowerCase());
2611
- if (i < fees.length) {
2612
- parts.push(numberToHex2(fees[i], { size: 3 }));
2613
- }
2614
- }
2615
- return concat3(parts);
2616
- }
2617
- function buildSwapExtraData(network, tokenIn, tokenOut, feeTier, hop, perHopSlippageBps = 100) {
2618
- if (hop) {
2619
- const path = encodeV3Path([tokenIn, hop.via, tokenOut], [hop.feeIn, hop.feeOut]);
2620
- const encoded2 = encodeAbiParameters11(
2621
- [{ type: "bytes" }, { type: "uint16" }],
2622
- [path, perHopSlippageBps]
2623
- );
2624
- return `0x01${encoded2.slice(2)}`;
2625
- }
2626
- const encoded = encodeAbiParameters11([{ type: "uint24" }], [feeTier]);
2627
- return `0x00${encoded.slice(2)}`;
2628
- }
2629
- function parseSwapRouteSpec(spec, token) {
2630
- const s = spec.trim();
2631
- const [kind, ...restParts] = s.split(":");
2632
- const rest = restParts.join(":");
2633
- switch (kind) {
2634
- case "v3": {
2635
- const fee = Number(rest);
2636
- if (!Number.isInteger(fee) || fee <= 0) throw new Error(`bad v3 fee in '${spec}'`);
2637
- return v3SingleHopExtraData(fee);
2638
- }
2639
- case "v4": {
2640
- const [feeStr, tsStr] = rest.split(":");
2641
- const fee = Number(feeStr);
2642
- const tickSpacing = Number(tsStr);
2643
- if (!Number.isInteger(fee) || fee <= 0) throw new Error(`bad v4 fee in '${spec}'`);
2644
- if (!Number.isInteger(tickSpacing) || tickSpacing <= 0) throw new Error(`bad v4 tickSpacing in '${spec}'`);
2645
- return v4SingleHopExtraData(fee, tickSpacing);
2646
- }
2647
- case "v4path": {
2648
- const hops = rest.split("+").map((hopStr) => {
2649
- const [currencyRaw, feeTs] = hopStr.split("@");
2650
- if (!feeTs) throw new Error(`bad v4path hop '${hopStr}' in '${spec}' (expected currency@fee:tickSpacing)`);
2651
- const [feeStr, tsStr] = feeTs.split(":");
2652
- const fee = Number(feeStr);
2653
- const tickSpacing = Number(tsStr);
2654
- if (!Number.isInteger(fee) || fee <= 0) throw new Error(`bad v4path fee in '${spec}'`);
2655
- if (!Number.isInteger(tickSpacing) || tickSpacing <= 0) throw new Error(`bad v4path tickSpacing in '${spec}'`);
2656
- const c = currencyRaw.trim().toLowerCase();
2657
- let currency;
2658
- if (c === "eth" || c === "native") currency = ZERO;
2659
- else if (c === "self") currency = token;
2660
- else if (isAddress2(currencyRaw.trim())) currency = currencyRaw.trim();
2661
- else throw new Error(`bad v4path currency '${currencyRaw}' in '${spec}' (use eth/native/self/0x-address)`);
2662
- return { currency, fee, tickSpacing };
2663
- });
2664
- return v4PathExtraData(hops);
2665
- }
2666
- default:
2667
- throw new Error(`unknown swap-route kind '${kind}' in '${spec}' (use v3/v4/v4path)`);
2668
- }
2669
- }
2670
- async function detectSwapRoute(asset, token, preferredFeeTier) {
2671
- const network = getNetwork();
2672
- return {
2673
- extraData: buildSwapExtraData(network, asset, token, preferredFeeTier),
2674
- routeDesc: `direct (fee ${preferredFeeTier})`
2675
- };
2676
- }
2677
2055
  var TEMPLATES = [
2678
2056
  {
2679
2057
  name: "Moonwell Supply",
@@ -2738,537 +2116,72 @@ function resolveTemplate(key) {
2738
2116
  }
2739
2117
  return { def, address };
2740
2118
  }
2741
- function computeProposalAssetChecks(templateKey, opts) {
2742
- if (templateKey === "moonwell-supply" || templateKey === "mamo-yield") {
2743
- if (!opts.amount) return [];
2744
- const token = opts.token || "USDC";
2745
- const asset = resolveToken(token);
2746
- const decimals = token.toUpperCase() === "USDC" ? 6 : 18;
2747
- return [{ asset, amount: parseUnits(opts.amount, decimals), label: token.toUpperCase() }];
2748
- }
2119
+ async function resolveChainInputsForTemplate(templateKey, opts) {
2749
2120
  if (templateKey === "venice-inference") {
2750
- if (!opts.amount) return [];
2751
- const assetSymbol = opts.asset || "USDC";
2752
- const asset = resolveToken(assetSymbol);
2753
- const decimals = assetSymbol.toUpperCase() === "USDC" ? 6 : 18;
2754
- return [{ asset, amount: parseUnits(opts.amount, decimals), label: assetSymbol.toUpperCase() }];
2755
- }
2756
- if (templateKey === "aerodrome-lp") {
2757
- if (!opts.tokenA || !opts.tokenB || !opts.amountA || !opts.amountB) return [];
2758
- return [];
2759
- }
2760
- if (templateKey === "wsteth-moonwell") {
2761
- if (!opts.amount) return [];
2762
- return [{
2763
- asset: TOKENS().WETH,
2764
- amount: parseUnits(opts.amount, 18),
2765
- label: "WETH"
2766
- }];
2767
- }
2768
- if (templateKey === "portfolio") {
2769
- if (!opts.amount) return [];
2770
- const assetSymbol = opts.asset || defaultPortfolioAsset();
2771
- const asset = resolveToken(assetSymbol);
2772
- const decimals = assetDecimalsForSymbol(assetSymbol);
2773
- return [{ asset, amount: parseUnits(opts.amount, decimals), label: assetSymbol.toUpperCase() }];
2774
- }
2775
- if (templateKey === "hyperliquid-perp" || templateKey === "hyperliquid-grid") {
2776
- if (!opts.amount) return [];
2777
- const token = opts.token || "USDC";
2778
- const asset = resolveToken(token);
2779
- const decimals = token.toUpperCase() === "USDC" ? 6 : 18;
2780
- return [{ asset, amount: parseUnits(opts.amount, decimals), label: token.toUpperCase() }];
2781
- }
2782
- return [];
2783
- }
2784
- function parseAlignedOverrides(raw, expectedLen) {
2785
- if (raw === void 0) return { values: [], mismatch: false };
2786
- const values = raw.split(",").map((s) => s.trim());
2787
- return { values, mismatch: values.length !== expectedLen };
2788
- }
2789
- async function buildInitDataForTemplate(templateKey, opts, vault) {
2790
- if (templateKey === "moonwell-supply") {
2791
- if (!opts.amount) {
2792
- console.error(chalk.red("--amount is required for moonwell-supply template"));
2793
- process.exit(1);
2794
- }
2795
- const token = opts.token || "USDC";
2796
- const underlying = resolveToken(token);
2797
- const mToken = resolveMToken(token);
2798
- const decimals = token.toUpperCase() === "USDC" ? 6 : 18;
2799
- const supplyAmount = parseUnits(opts.amount, decimals);
2800
- const minRedeem = parseUnits(opts.minRedeem || opts.amount, decimals);
2801
- const isNativeEthMarket = token.toUpperCase() !== "USDC";
2802
- return {
2803
- initData: buildInitData(underlying, mToken, supplyAmount, minRedeem, isNativeEthMarket),
2804
- asset: underlying,
2805
- assetAmount: supplyAmount
2806
- };
2807
- }
2808
- if (templateKey === "venice-inference") {
2809
- if (!opts.amount) {
2810
- console.error(chalk.red("--amount is required for venice-inference template"));
2811
- process.exit(1);
2812
- }
2121
+ if (!opts.amount) return {};
2813
2122
  const assetSymbol = opts.asset || "USDC";
2814
2123
  const asset = resolveToken(assetSymbol);
2815
2124
  const vvv = VENICE().VVV;
2816
2125
  const isDirect = asset.toLowerCase() === vvv.toLowerCase();
2817
- const decimals = assetSymbol.toUpperCase() === "USDC" ? 6 : 18;
2818
- const assetAmount = parseUnits(opts.amount, decimals);
2819
- const agent = opts.agent || getAccount().address;
2820
- const isSingleHop = !!opts.singleHop;
2821
- let minVVV = 0n;
2822
- if (!isDirect) {
2823
- if (opts.minVvv) {
2824
- minVVV = parseUnits(opts.minVvv, 18);
2825
- } else {
2826
- const publicClient = getPublicClient();
2827
- const aeroRouterAbi = [{
2828
- name: "getAmountsOut",
2829
- type: "function",
2830
- stateMutability: "view",
2831
- inputs: [
2832
- { name: "amountIn", type: "uint256" },
2833
- { name: "routes", type: "tuple[]", components: [
2834
- { name: "from", type: "address" },
2835
- { name: "to", type: "address" },
2836
- { name: "stable", type: "bool" },
2837
- { name: "factory", type: "address" }
2838
- ] }
2839
- ],
2840
- outputs: [{ name: "amounts", type: "uint256[]" }]
2841
- }];
2842
- const routes = isSingleHop ? [{ from: asset, to: vvv, stable: false, factory: AERODROME().FACTORY }] : [
2843
- { from: asset, to: TOKENS().WETH, stable: false, factory: AERODROME().FACTORY },
2844
- { from: TOKENS().WETH, to: vvv, stable: false, factory: AERODROME().FACTORY }
2845
- ];
2846
- try {
2847
- const amounts = await publicClient.readContract({
2848
- address: AERODROME().ROUTER,
2849
- abi: aeroRouterAbi,
2850
- functionName: "getAmountsOut",
2851
- args: [assetAmount, routes]
2852
- });
2853
- const expectedVVV = amounts[amounts.length - 1];
2854
- minVVV = expectedVVV * 95n / 100n;
2855
- console.log(chalk.dim(` Auto-quoted minVVV: ${(Number(minVVV) / 1e18).toFixed(4)} VVV (5% slippage on ~${(Number(expectedVVV) / 1e18).toFixed(4)} VVV)`));
2856
- } catch {
2857
- console.error(chalk.red("Could not quote USDC\u2192VVV price. Pass --min-vvv <amount> manually."));
2858
- process.exit(1);
2859
- }
2860
- }
2861
- }
2862
- const params = {
2863
- asset,
2864
- weth: isDirect ? ZERO : TOKENS().WETH,
2865
- vvv,
2866
- sVVV: VENICE().STAKING,
2867
- aeroRouter: isDirect ? ZERO : AERODROME().ROUTER,
2868
- aeroFactory: isDirect ? ZERO : AERODROME().FACTORY,
2869
- agent,
2870
- assetAmount,
2871
- minVVV,
2872
- deadlineOffset: 300n,
2873
- singleHop: isSingleHop
2874
- };
2875
- return {
2876
- initData: buildInitData2(params),
2877
- asset,
2878
- assetAmount
2126
+ const resolved = {
2127
+ veniceAgent: opts.agent || getAccount().address
2879
2128
  };
2880
- }
2881
- if (templateKey === "aerodrome-lp") {
2882
- for (const flag of ["tokenA", "tokenB", "amountA", "amountB", "lpToken"]) {
2883
- if (!opts[flag]) {
2884
- console.error(chalk.red(`--${flag.replace(/([A-Z])/g, "-$1").toLowerCase()} is required for aerodrome-lp template`));
2129
+ if (!isDirect && !opts.minVvv) {
2130
+ const decimals = assetDecimalsForSymbol(assetSymbol);
2131
+ const assetAmount = parseUnits(opts.amount, decimals);
2132
+ const isSingleHop = !!opts.singleHop;
2133
+ const publicClient = getPublicClient();
2134
+ const aeroRouterAbi = [{
2135
+ name: "getAmountsOut",
2136
+ type: "function",
2137
+ stateMutability: "view",
2138
+ inputs: [
2139
+ { name: "amountIn", type: "uint256" },
2140
+ { name: "routes", type: "tuple[]", components: [
2141
+ { name: "from", type: "address" },
2142
+ { name: "to", type: "address" },
2143
+ { name: "stable", type: "bool" },
2144
+ { name: "factory", type: "address" }
2145
+ ] }
2146
+ ],
2147
+ outputs: [{ name: "amounts", type: "uint256[]" }]
2148
+ }];
2149
+ const routes = isSingleHop ? [{ from: asset, to: vvv, stable: false, factory: AERODROME().FACTORY }] : [
2150
+ { from: asset, to: TOKENS().WETH, stable: false, factory: AERODROME().FACTORY },
2151
+ { from: TOKENS().WETH, to: vvv, stable: false, factory: AERODROME().FACTORY }
2152
+ ];
2153
+ try {
2154
+ const amounts = await publicClient.readContract({
2155
+ address: AERODROME().ROUTER,
2156
+ abi: aeroRouterAbi,
2157
+ functionName: "getAmountsOut",
2158
+ args: [assetAmount, routes]
2159
+ });
2160
+ const expectedVVV = amounts[amounts.length - 1];
2161
+ const minVVV = expectedVVV * 95n / 100n;
2162
+ console.log(chalk.dim(` Auto-quoted minVVV: ${(Number(minVVV) / 1e18).toFixed(4)} VVV (5% slippage on ~${(Number(expectedVVV) / 1e18).toFixed(4)} VVV)`));
2163
+ resolved.veniceMinVVV = minVVV;
2164
+ } catch {
2165
+ console.error(chalk.red("Could not quote USDC\u2192VVV price. Pass --min-vvv <amount> manually."));
2885
2166
  process.exit(1);
2886
2167
  }
2887
2168
  }
2888
- const tokenA = opts.tokenA;
2889
- const tokenB = opts.tokenB;
2169
+ return resolved;
2170
+ }
2171
+ if (templateKey === "aerodrome-lp") {
2172
+ if (!opts.tokenA || !opts.tokenB || !opts.amountA || !opts.amountB || !opts.lpToken) return {};
2890
2173
  const publicClient = getPublicClient();
2891
2174
  const [decimalsA, decimalsB] = await Promise.all([
2892
- publicClient.readContract({ address: tokenA, abi: erc20Abi, functionName: "decimals" }),
2893
- publicClient.readContract({ address: tokenB, abi: erc20Abi, functionName: "decimals" })
2175
+ publicClient.readContract({ address: opts.tokenA, abi: erc20Abi, functionName: "decimals" }),
2176
+ publicClient.readContract({ address: opts.tokenB, abi: erc20Abi, functionName: "decimals" })
2894
2177
  ]);
2895
- const amountA = parseUnits(opts.amountA, decimalsA);
2896
- const amountB = parseUnits(opts.amountB, decimalsB);
2897
- const minAOut = parseUnits(opts.minAOut || "0", decimalsA);
2898
- const minBOut = parseUnits(opts.minBOut || "0", decimalsB);
2899
- const params = {
2900
- tokenA,
2901
- tokenB,
2902
- stable: !!opts.stable,
2903
- factory: AERODROME().FACTORY,
2904
- router: AERODROME().ROUTER,
2905
- gauge: opts.gauge || ZERO,
2906
- lpToken: opts.lpToken,
2907
- amountADesired: amountA,
2908
- amountBDesired: amountB,
2909
- amountAMin: amountA,
2910
- // use desired as min for now
2911
- amountBMin: amountB,
2912
- minAmountAOut: minAOut,
2913
- minAmountBOut: minBOut
2914
- };
2915
- return {
2916
- initData: buildInitData3(params),
2917
- asset: tokenA,
2918
- assetAmount: amountA,
2919
- extraApprovals: [{ token: tokenB, amount: amountB }]
2920
- };
2921
- }
2922
- if (templateKey === "wsteth-moonwell") {
2923
- const supplyAmount = opts.amount ? parseUnits(opts.amount, 18) : 0n;
2924
- const slippageBps = BigInt(opts.slippage || "500");
2925
- const ONE = 10n ** 18n;
2926
- const minWstethOutPerWeth = ONE * (10000n - slippageBps) / 10000n;
2927
- const minWethOutPerWsteth = ONE * (10000n - slippageBps) / 10000n;
2928
- const params = {
2929
- weth: TOKENS().WETH,
2930
- wsteth: TOKENS().wstETH,
2931
- mwsteth: MOONWELL().mWstETH,
2932
- aeroRouter: AERODROME().ROUTER,
2933
- aeroFactory: AERODROME().FACTORY,
2934
- chainlinkWstethEthFeed: CHAINLINK().WSTETH_ETH_FEED,
2935
- supplyAmount,
2936
- minWstethOutPerWeth,
2937
- minWethOutPerWsteth,
2938
- deadlineOffset: 300n
2939
- };
2940
- return {
2941
- initData: buildInitData4(params),
2942
- asset: TOKENS().WETH,
2943
- assetAmount: supplyAmount
2944
- };
2945
- }
2946
- if (templateKey === "mamo-yield") {
2947
- if (!opts.amount) {
2948
- console.error(chalk.red("--amount is required for mamo-yield template"));
2949
- process.exit(1);
2950
- }
2951
- if (!opts.mamoFactory) {
2952
- console.error(chalk.red("--mamo-factory is required for mamo-yield template"));
2953
- process.exit(1);
2954
- }
2955
- const token = opts.token || "USDC";
2956
- const underlying = resolveToken(token);
2957
- const decimals = token.toUpperCase() === "USDC" ? 6 : 18;
2958
- const amount = parseUnits(opts.amount, decimals);
2959
- const minRedeemAmount = parseUnits(opts.minRedeem || opts.amount, decimals);
2960
- return {
2961
- initData: buildInitData5(underlying, opts.mamoFactory, minRedeemAmount),
2962
- asset: underlying,
2963
- assetAmount: amount
2964
- };
2965
- }
2966
- if (templateKey === "portfolio") {
2967
- let robinhoodDefaultRoute2 = function(token, symbol) {
2968
- if (network !== "robinhood") return null;
2969
- if (wethAddr !== ZERO && token.toLowerCase() === wethAddr.toLowerCase()) {
2970
- return { extraData: v3SingleHopExtraData(500), routeDesc: "v3 direct (fee 500)" };
2971
- }
2972
- const r = ROBINHOOD_STOCK_ROUTES[symbol.toUpperCase()];
2973
- if (r) {
2974
- return {
2975
- extraData: v4PathExtraData([
2976
- { currency: ZERO, fee: r.nativeFee, tickSpacing: r.nativeTickSpacing },
2977
- { currency: token, fee: r.stockFee, tickSpacing: r.stockTickSpacing }
2978
- ]),
2979
- routeDesc: `v4 multi-hop (USDG\u2192ETH fee ${r.nativeFee} / ts ${r.nativeTickSpacing} \u2192 ${symbol.toUpperCase()} fee ${r.stockFee} / ts ${r.stockTickSpacing})`
2980
- };
2981
- }
2982
- return null;
2983
- };
2984
- var robinhoodDefaultRoute = robinhoodDefaultRoute2;
2985
- if (!opts.amount) {
2986
- console.error(chalk.red("--amount is required for portfolio template"));
2987
- process.exit(1);
2988
- }
2989
- if (!opts.tokens || !opts.weights) {
2990
- console.error(chalk.red("--tokens and --weights are required for portfolio template"));
2991
- console.error(chalk.dim(" --tokens: comma-separated token addresses or symbols"));
2992
- console.error(chalk.dim(" --weights: comma-separated bps (must sum to 10000)"));
2993
- process.exit(1);
2994
- }
2995
- const network = getNetwork();
2996
- const tokens = TOKENS();
2997
- const assetSymbol = opts.asset || defaultPortfolioAsset();
2998
- const asset = resolveToken(assetSymbol);
2999
- const decimals = assetDecimalsForSymbol(assetSymbol);
3000
- const totalAmount = parseUnits(opts.amount, decimals);
3001
- const maxSlippageBps = Number(opts.maxSlippage || "500");
3002
- const feeTier = opts.feeTier || "3000";
3003
- const tokenSpecs = opts.tokens.split(",").map((t) => t.trim());
3004
- const tokenAddrs = tokenSpecs.map((trimmed) => {
3005
- if (isAddress2(trimmed)) return trimmed;
3006
- const allTokens = tokens;
3007
- const resolved = allTokens[trimmed.toUpperCase()];
3008
- if (resolved && resolved !== ZERO) return resolved;
3009
- console.error(chalk.red(`Unknown token: ${trimmed}`));
3010
- process.exit(1);
3011
- });
3012
- const weightsBps = opts.weights.split(",").map((w) => Number(w.trim()));
3013
- if (tokenAddrs.length !== weightsBps.length) {
3014
- console.error(chalk.red("--tokens and --weights must have same length"));
3015
- process.exit(1);
3016
- }
3017
- if (weightsBps.reduce((a, b) => a + b, 0) !== 1e4) {
3018
- console.error(chalk.red(`Weights must sum to 10000`));
3019
- process.exit(1);
3020
- }
3021
- const swapAdapter = opts.swapAdapter || resolveSwapAdapter();
3022
- const chainlinkVerifier = CHAINLINK().VERIFIER_PROXY;
3023
- const pushMode = chainlinkVerifier === ZERO;
3024
- const chainlink = CHAINLINK();
3025
- const feedIds = parseAlignedOverrides(opts.feedIds, tokenAddrs.length);
3026
- const feedIdOverrides = feedIds.values;
3027
- if (feedIds.mismatch) {
3028
- console.error(chalk.red("--feed-ids must have the same length as --tokens"));
3029
- process.exit(1);
3030
- }
3031
- const priceDecimals = parseAlignedOverrides(opts.priceDecimals, tokenAddrs.length);
3032
- const priceDecimalOverrides = priceDecimals.values;
3033
- if (priceDecimals.mismatch) {
3034
- console.error(chalk.red("--price-decimals must have the same length as --tokens"));
3035
- process.exit(1);
3036
- }
3037
- const swapRoutes = parseAlignedOverrides(opts.swapRoutes, tokenAddrs.length);
3038
- const swapRouteOverrides = swapRoutes.values;
3039
- if (swapRoutes.mismatch) {
3040
- console.error(chalk.red("--swap-routes must have the same length as --tokens"));
3041
- process.exit(1);
3042
- }
3043
- const maxPriceAges = parseAlignedOverrides(opts.maxPriceAges, tokenAddrs.length);
3044
- const maxPriceAgeOverrides = maxPriceAges.values;
3045
- if (maxPriceAges.mismatch) {
3046
- console.error(chalk.red("--max-price-ages must have the same length as --tokens"));
3047
- process.exit(1);
3048
- }
3049
- const wethAddr = TOKENS().WETH;
3050
- console.log(chalk.dim(" Detecting swap routes..."));
3051
- const allocations = [];
3052
- for (let i = 0; i < tokenAddrs.length; i++) {
3053
- const token = tokenAddrs[i];
3054
- let route = null;
3055
- const override = swapRouteOverrides[i];
3056
- if (override) {
3057
- try {
3058
- route = { extraData: parseSwapRouteSpec(override, token), routeDesc: `explicit '${override}'` };
3059
- } catch (e) {
3060
- console.error(chalk.red(`Bad --swap-routes entry for ${tokenSpecs[i]}: ${e.message}`));
3061
- process.exit(1);
3062
- }
3063
- }
3064
- if (!route) route = robinhoodDefaultRoute2(token, tokenSpecs[i]);
3065
- if (!route && network === "robinhood") {
3066
- console.error(
3067
- chalk.red(
3068
- `No verified default swap route for ${tokenSpecs[i]} on robinhood mainnet.`
3069
- )
3070
- );
3071
- console.error(
3072
- chalk.yellow(
3073
- ` Pass --swap-routes to set it explicitly for this token, e.g.
3074
- --swap-routes 'v4path:eth@500:10+self@50000:1000' (USDG\u2192ETH\u2192${tokenSpecs[i].toUpperCase()})`
3075
- )
3076
- );
3077
- process.exit(1);
3078
- }
3079
- if (!route) route = await detectSwapRoute(asset, token, Number(feeTier));
3080
- if (!route) {
3081
- console.error(chalk.red(`No swap route found for ${token}. No Uniswap V3 pool (direct or via WETH). Pass --swap-routes to set it explicitly.`));
3082
- process.exit(1);
3083
- }
3084
- console.log(chalk.dim(` ${token.slice(0, 10)}... \u2192 ${route.routeDesc}`));
3085
- let feedId = feedIdOverrides[i];
3086
- let priceDecimals2 = priceDecimalOverrides[i] ? Number(priceDecimalOverrides[i]) : pushMode ? 8 : 18;
3087
- const sym = tokenSpecs[i].toUpperCase();
3088
- let maxPriceAge = 0;
3089
- if (maxPriceAgeOverrides[i]) {
3090
- maxPriceAge = Number(maxPriceAgeOverrides[i]);
3091
- if (!Number.isInteger(maxPriceAge) || maxPriceAge < 0) {
3092
- console.error(chalk.red(`Bad --max-price-ages entry for ${tokenSpecs[i]}: '${maxPriceAgeOverrides[i]}' (expected a non-negative integer count of seconds)`));
3093
- process.exit(1);
3094
- }
3095
- } else if (pushMode && network === "robinhood") {
3096
- const { maxPriceAge: age, unknownAddress } = robinhoodEquityMaxAge(
3097
- tokenSpecs[i],
3098
- tokens,
3099
- EQUITY_MAX_PRICE_AGE_SECONDS
3100
- );
3101
- maxPriceAge = age;
3102
- if (unknownAddress && feedIdOverrides[i]) {
3103
- console.warn(
3104
- chalk.yellow(
3105
- ` Warning: token ${tokenSpecs[i]} is not in the ${network} registry, so its push feed uses the contract's 26h default max-price-age.
3106
- If this is a tokenized-equity feed, pass --max-price-ages (e.g. ${EQUITY_MAX_PRICE_AGE_SECONDS}) for this slot or it will trip StalePrice over long weekends.`
3107
- )
3108
- );
3109
- }
3110
- }
3111
- if (pushMode && !feedId) {
3112
- const feedKey = sym === "WETH" || sym === "ETH" ? "ETH_USD_FEED" : `${sym}_USD_FEED`;
3113
- const feed = isAddress2(tokenSpecs[i]) ? void 0 : chainlink[feedKey];
3114
- if (!feed || feed === ZERO) {
3115
- console.error(chalk.red(`No Chainlink push feed for ${tokenSpecs[i]} on ${network}. Pass --feed-ids <feedAddr,...> to supply AggregatorV3 addresses.`));
3116
- process.exit(1);
3117
- }
3118
- feedId = pushFeedId(feed, maxPriceAge);
3119
- } else if (pushMode && feedId && isAddress2(feedId)) {
3120
- feedId = pushFeedId(feedId, maxPriceAge);
3121
- }
3122
- if (!feedId || feedId === ZERO_BYTES323) {
3123
- console.error(chalk.red(`Missing Chainlink feedId for allocation ${i} (${tokenSpecs[i]}). The strategy requires a non-zero feedId per token \u2014 pass --feed-ids as a comma-separated list.`));
3124
- process.exit(1);
3125
- }
3126
- allocations.push({
3127
- token,
3128
- weightBps: weightsBps[i],
3129
- swapExtraData: route.extraData,
3130
- priceDecimals: priceDecimals2,
3131
- feedId
3132
- });
3133
- }
3134
- return {
3135
- initData: buildInitData6(asset, swapAdapter, chainlinkVerifier, allocations, totalAmount, maxSlippageBps),
3136
- asset,
3137
- assetAmount: totalAmount
3138
- };
2178
+ return { aerodromeDecimals: { decimalsA, decimalsB } };
3139
2179
  }
3140
- if (templateKey === "hyperliquid-perp") {
3141
- const token = opts.token || "USDC";
3142
- const asset = resolveToken(token);
3143
- const decimals = token.toUpperCase() === "USDC" ? 6 : 18;
3144
- const depositAmount = opts.amount ? parseUnits(opts.amount, decimals) : 0n;
3145
- const leverage = Number(opts.leverage || "10");
3146
- const assetIndex = Number(opts.assetIndex || "0");
3147
- const maxPosition = parseUnits(opts.maxPosition || "100000", decimals);
3148
- const maxTradesDay = Number(opts.maxTradesPerDay || "50");
3149
- return {
3150
- initData: buildInitData7(asset, depositAmount, assetIndex, leverage, maxPosition, maxTradesDay),
3151
- asset,
3152
- assetAmount: depositAmount
3153
- };
3154
- }
3155
- if (templateKey === "hyperliquid-grid") {
3156
- const token = opts.token || "USDC";
3157
- const asset = resolveToken(token);
3158
- const decimals = token.toUpperCase() === "USDC" ? 6 : 18;
3159
- const depositAmount = opts.amount ? parseUnits(opts.amount, decimals) : 0n;
3160
- const leverage = Number(opts.leverage || "5");
3161
- const maxOrderSize = parseUnits(opts.maxOrderSize || "10000", decimals);
3162
- const maxOrdersPerTick = Number(opts.maxOrdersPerTick || "20");
3163
- const assetIndices = (opts.assetIndices || "0").split(",").map((s) => Number(s.trim())).filter((n) => !Number.isNaN(n));
3164
- return {
3165
- initData: buildInitData8(asset, depositAmount, leverage, maxOrderSize, maxOrdersPerTick, assetIndices),
3166
- asset,
3167
- assetAmount: depositAmount
3168
- };
3169
- }
3170
- throw new Error(`No init builder for template: ${templateKey}`);
2180
+ return {};
3171
2181
  }
3172
- function buildCallsForTemplate(templateKey, clone, asset, assetAmount, extraApprovals) {
3173
- if (templateKey === "moonwell-supply") {
3174
- return {
3175
- executeCalls: buildExecuteCalls(clone, asset, assetAmount),
3176
- settleCalls: buildSettleCalls(clone)
3177
- };
3178
- }
3179
- if (templateKey === "venice-inference") {
3180
- return {
3181
- executeCalls: buildExecuteCalls2(clone, asset, assetAmount),
3182
- settleCalls: buildSettleCalls2(clone)
3183
- };
3184
- }
3185
- if (templateKey === "aerodrome-lp") {
3186
- const tokenB = extraApprovals?.[0]?.token ?? ZERO;
3187
- const amountB = extraApprovals?.[0]?.amount ?? 0n;
3188
- return {
3189
- executeCalls: buildExecuteCalls3(clone, asset, assetAmount, tokenB, amountB),
3190
- settleCalls: buildSettleCalls3(clone)
3191
- };
3192
- }
3193
- if (templateKey === "wsteth-moonwell") {
3194
- return {
3195
- executeCalls: buildExecuteCalls4(clone, asset, assetAmount),
3196
- settleCalls: buildSettleCalls4(clone)
3197
- };
3198
- }
3199
- if (templateKey === "mamo-yield") {
3200
- return {
3201
- executeCalls: buildExecuteCalls5(clone, asset, assetAmount),
3202
- settleCalls: buildSettleCalls5(clone)
3203
- };
3204
- }
3205
- if (templateKey === "portfolio") {
3206
- return {
3207
- executeCalls: buildExecuteCalls6(clone, asset, assetAmount),
3208
- settleCalls: buildSettleCalls6(clone)
3209
- };
3210
- }
3211
- if (templateKey === "hyperliquid-perp") {
3212
- return {
3213
- executeCalls: buildExecuteCalls7(clone, asset, assetAmount),
3214
- settleCalls: buildSettleCalls7(clone)
3215
- };
3216
- }
3217
- if (templateKey === "hyperliquid-grid") {
3218
- return {
3219
- executeCalls: buildExecuteCalls8(clone, asset, assetAmount),
3220
- settleCalls: buildSettleCalls8(clone)
3221
- };
3222
- }
3223
- throw new Error(`No call builder for template: ${templateKey}`);
3224
- }
3225
- function resolveSwapAdapter() {
3226
- const network = getNetwork();
3227
- if (network === "robinhood-testnet" && SYNTHRA().ROUTER === ZERO) {
3228
- console.error(chalk.red("Synthra DEX not available"));
3229
- process.exit(1);
3230
- }
3231
- const adapterAddr = UNISWAP().SWAP_ADAPTER;
3232
- if (adapterAddr !== ZERO) return adapterAddr;
3233
- console.error(chalk.red("UniswapSwapAdapter not deployed yet. Use --swap-adapter to specify manually."));
3234
- process.exit(1);
3235
- }
3236
- function resolveToken(symbolOrAddress) {
3237
- if (isAddress2(symbolOrAddress)) return symbolOrAddress;
3238
- const upper = symbolOrAddress.toUpperCase();
3239
- const tokenMap = {
3240
- ...TOKENS(),
3241
- VVV: VENICE().VVV
3242
- };
3243
- const addr = tokenMap[upper];
3244
- if (!addr || addr === ZERO) {
3245
- console.error(chalk.red(`Unknown token: ${symbolOrAddress}`));
3246
- process.exit(1);
3247
- }
3248
- return addr;
3249
- }
3250
- function defaultPortfolioAsset() {
3251
- const network = getNetwork();
3252
- if (network === "robinhood-testnet") return "WETH";
3253
- return "USDC";
3254
- }
3255
- function assetDecimalsForSymbol(symbol) {
3256
- const upper = symbol.toUpperCase();
3257
- return upper === "USDC" || upper === "USDG" ? 6 : 18;
3258
- }
3259
- function resolveMToken(tokenSymbol) {
3260
- const upper = tokenSymbol.toUpperCase();
3261
- const moonwell = MOONWELL();
3262
- const mTokenMap = {
3263
- USDC: moonwell.mUSDC,
3264
- WETH: moonwell.mWETH
3265
- };
3266
- const addr = mTokenMap[upper];
3267
- if (!addr || addr === ZERO) {
3268
- console.error(chalk.red(`No Moonwell market for: ${tokenSymbol}`));
3269
- process.exit(1);
3270
- }
3271
- return addr;
2182
+ async function resolveAndBuildInitData(templateKey, opts, vault) {
2183
+ const resolved = await resolveChainInputsForTemplate(templateKey, opts);
2184
+ return buildInitDataForTemplate(templateKey, opts, vault, resolved);
3272
2185
  }
3273
2186
  function serializeCalls(calls) {
3274
2187
  return JSON.stringify(
@@ -3339,7 +2252,7 @@ function registerStrategyTemplateCommands(strategy2) {
3339
2252
  }
3340
2253
  const initSpinner = ora("Initializing strategy...").start();
3341
2254
  try {
3342
- const { initData } = await buildInitDataForTemplate(templateKey, opts, vault);
2255
+ const { initData } = await resolveAndBuildInitData(templateKey, opts, vault);
3343
2256
  const account = getAccount();
3344
2257
  const initHash = await writeContractWithRetry({
3345
2258
  account,
@@ -3408,7 +2321,7 @@ function registerStrategyTemplateCommands(strategy2) {
3408
2321
  }
3409
2322
  const initSpinner = ora("Initializing strategy clone...").start();
3410
2323
  try {
3411
- const { initData } = await buildInitDataForTemplate(templateKey, opts, vault);
2324
+ const { initData } = await resolveAndBuildInitData(templateKey, opts, vault);
3412
2325
  const account = getAccount();
3413
2326
  const initHash = await writeContractWithRetry({
3414
2327
  account,
@@ -3519,12 +2432,12 @@ function registerStrategyTemplateCommands(strategy2) {
3519
2432
  process.exit(1);
3520
2433
  }
3521
2434
  if (!opts.agent) opts.agent = proposer;
3522
- const { parseDuration: parseDuration3, getGovernorOf: getGovernorOf2 } = await import("./governor-S56M6BV6.js");
2435
+ const { parseDuration: parseDuration3, getGovernorOf: getGovernorOf2 } = await import("./governor-PYQQ7QRG.js");
3523
2436
  const strategyDuration2 = parseDuration3(opts.duration);
3524
2437
  const chainId = getChain().id;
3525
2438
  try {
3526
2439
  const governor = await getGovernorOf2(vault);
3527
- const built = await buildInitDataForTemplate(templateKey, opts, vault);
2440
+ const built = await resolveAndBuildInitData(templateKey, opts, vault);
3528
2441
  const deploy = encodeStrategyDeploy(
3529
2442
  {
3530
2443
  template: templateAddr,
@@ -3654,7 +2567,7 @@ function registerStrategyTemplateCommands(strategy2) {
3654
2567
  let assetAmount;
3655
2568
  let extraApprovals;
3656
2569
  try {
3657
- const built = await buildInitDataForTemplate(templateKey, opts, vault);
2570
+ const built = await resolveAndBuildInitData(templateKey, opts, vault);
3658
2571
  asset = built.asset;
3659
2572
  assetAmount = built.assetAmount;
3660
2573
  extraApprovals = built.extraApprovals;
@@ -3745,9 +2658,9 @@ function registerStrategyTemplateCommands(strategy2) {
3745
2658
  console.error(chalk.red("Missing --name or --duration. Use --write-calls to skip proposal submission."));
3746
2659
  process.exit(1);
3747
2660
  }
3748
- const { propose: propose2 } = await import("./governor-S56M6BV6.js");
2661
+ const { propose: propose2 } = await import("./governor-PYQQ7QRG.js");
3749
2662
  const { pinJSON } = await import("./ipfs-RWSTXTZM.js");
3750
- const { parseDuration: parseDuration2 } = await import("./governor-S56M6BV6.js");
2663
+ const { parseDuration: parseDuration2 } = await import("./governor-PYQQ7QRG.js");
3751
2664
  const strategyDuration = parseDuration2(opts.duration);
3752
2665
  const metaSpinner = ora("Pinning metadata to IPFS...").start();
3753
2666
  let metadataURI;
@@ -3770,7 +2683,7 @@ function registerStrategyTemplateCommands(strategy2) {
3770
2683
  process.exit(1);
3771
2684
  }
3772
2685
  try {
3773
- const { getAgentFeeBps: getAgentFeeBps2 } = await import("./vault-XWFPGHRA.js");
2686
+ const { getAgentFeeBps: getAgentFeeBps2 } = await import("./vault-WDRLJLJ6.js");
3774
2687
  const feeBps = await getAgentFeeBps2(vault);
3775
2688
  console.log(
3776
2689
  chalk.yellow(
@@ -3858,7 +2771,7 @@ function registerStrategyTemplateCommands(strategy2) {
3858
2771
  let prices = [];
3859
2772
  let priceSource = null;
3860
2773
  try {
3861
- const { getTokenPricesInAsset } = await import("./price-HHDBMKIE.js");
2774
+ const { getTokenPricesInAsset } = await import("./price-DGGB6W2G.js");
3862
2775
  prices = await getTokenPricesInAsset({
3863
2776
  tokens: allocations.map((a, i) => ({
3864
2777
  token: a.token,
@@ -4107,7 +3020,7 @@ function registerStrategyTemplateCommands(strategy2) {
4107
3020
  });
4108
3021
  const updateSpinner = ora("Updating target weights...").start();
4109
3022
  try {
4110
- const innerData = encodeAbiParameters11(
3023
+ const innerData = encodeAbiParameters3(
4111
3024
  [{ type: "uint256[]" }, { type: "uint256" }, { type: "bytes[]" }],
4112
3025
  [newWeightsBps.map((w) => BigInt(w)), BigInt(maxSlip), swapData]
4113
3026
  );
@@ -4288,7 +3201,7 @@ function registerVeniceCommands(program2) {
4288
3201
  console.log(chalk2.dim(` Key: ${apiKey.slice(0, 8)}...${apiKey.slice(-4)}`));
4289
3202
  console.log(chalk2.dim(" Saved to ~/.sherwood/config.json"));
4290
3203
  try {
4291
- const { createVeniceProvisionAttestation, getEasScanUrl: getEasScanUrl2 } = await import("./eas-QAH7XVLK.js");
3204
+ const { createVeniceProvisionAttestation, getEasScanUrl: getEasScanUrl2 } = await import("./eas-G4TPLJ6S.js");
4292
3205
  const { uid } = await createVeniceProvisionAttestation(account.address);
4293
3206
  if (uid !== "0x0000000000000000000000000000000000000000000000000000000000000000") {
4294
3207
  console.log(chalk2.dim(` Attested: ${getEasScanUrl2(uid)}`));
@@ -4510,8 +3423,8 @@ function registerVeniceCommands(program2) {
4510
3423
  try {
4511
3424
  const [assetAddress, totalDeposited, agents] = await Promise.all([
4512
3425
  client.readContract({ address: vaultAddress, abi: SYNDICATE_VAULT_ABI, functionName: "asset" }),
4513
- client.readContract({ address: vaultAddress, abi: SYNDICATE_VAULT_ABI, functionName: "totalDeposited" }),
4514
- client.readContract({ address: vaultAddress, abi: SYNDICATE_VAULT_ABI, functionName: "getAgentAddresses" })
3426
+ getNetDeposited(vaultAddress),
3427
+ getAgentAddresses(vaultAddress)
4515
3428
  ]);
4516
3429
  const [assetDecimals, assetSymbol, assetBalance] = await Promise.all([
4517
3430
  client.readContract({ address: assetAddress, abi: ERC20_ABI, functionName: "decimals" }),
@@ -4644,10 +3557,10 @@ ${opts.prompt}`;
4644
3557
  console.log(chalk2.dim(`Model: ${result.model} | Tokens: ${result.usage.promptTokens} in, ${result.usage.completionTokens} out, ${result.usage.totalTokens} total`));
4645
3558
  }
4646
3559
  try {
4647
- const { createVeniceInferenceAttestation, getEasScanUrl: getEasScanUrl2 } = await import("./eas-QAH7XVLK.js");
3560
+ const { createVeniceInferenceAttestation, getEasScanUrl: getEasScanUrl2 } = await import("./eas-G4TPLJ6S.js");
4648
3561
  const { keccak256: keccak2563, toHex, isAddress: isAddr } = await import("viem");
4649
- const { getChainContracts: getChainContracts2 } = await import("./config-FAQO37S7.js");
4650
- const { getChain: getActiveChain } = await import("./network-MKMX2NG6.js");
3562
+ const { getChainContracts: getChainContracts2 } = await import("./config-7HU4X7EK.js");
3563
+ const { getChain: getActiveChain } = await import("./network-WU2QC3L4.js");
4651
3564
  const vaultRecipient = opts.vault && isAddr(opts.vault) ? opts.vault : getChainContracts2(getActiveChain().id).vault;
4652
3565
  const promptHash = keccak2563(toHex(userContent)).slice(0, 18);
4653
3566
  const { uid } = await createVeniceInferenceAttestation(
@@ -4676,7 +3589,7 @@ import chalk3 from "chalk";
4676
3589
  import ora3 from "ora";
4677
3590
 
4678
3591
  // src/strategies/allowance-disburse.ts
4679
- import { encodeFunctionData as encodeFunctionData16, parseUnits as parseUnits3 } from "viem";
3592
+ import { encodeFunctionData as encodeFunctionData8, parseUnits as parseUnits3 } from "viem";
4680
3593
  function buildDisburseBatch(config, vaultAddress, agents, assetAddress, assetDecimals, minUsdc, swapPath) {
4681
3594
  const assetAmount = parseUnits3(config.amount, assetDecimals);
4682
3595
  const isUsdc = assetAddress.toLowerCase() === TOKENS().USDC.toLowerCase();
@@ -4685,7 +3598,7 @@ function buildDisburseBatch(config, vaultAddress, agents, assetAddress, assetDec
4685
3598
  if (!isUsdc) {
4686
3599
  calls.push({
4687
3600
  target: assetAddress,
4688
- data: encodeFunctionData16({
3601
+ data: encodeFunctionData8({
4689
3602
  abi: ERC20_ABI,
4690
3603
  functionName: "approve",
4691
3604
  args: [UNISWAP().SWAP_ROUTER, assetAmount]
@@ -4695,7 +3608,7 @@ function buildDisburseBatch(config, vaultAddress, agents, assetAddress, assetDec
4695
3608
  if (isWeth) {
4696
3609
  calls.push({
4697
3610
  target: UNISWAP().SWAP_ROUTER,
4698
- data: encodeFunctionData16({
3611
+ data: encodeFunctionData8({
4699
3612
  abi: SWAP_ROUTER_EXACT_INPUT_SINGLE_ABI,
4700
3613
  functionName: "exactInputSingle",
4701
3614
  args: [
@@ -4715,7 +3628,7 @@ function buildDisburseBatch(config, vaultAddress, agents, assetAddress, assetDec
4715
3628
  } else {
4716
3629
  calls.push({
4717
3630
  target: UNISWAP().SWAP_ROUTER,
4718
- data: encodeFunctionData16({
3631
+ data: encodeFunctionData8({
4719
3632
  abi: SWAP_ROUTER_ABI,
4720
3633
  functionName: "exactInput",
4721
3634
  args: [
@@ -4735,7 +3648,7 @@ function buildDisburseBatch(config, vaultAddress, agents, assetAddress, assetDec
4735
3648
  for (const agent of agents) {
4736
3649
  calls.push({
4737
3650
  target: TOKENS().USDC,
4738
- data: encodeFunctionData16({
3651
+ data: encodeFunctionData8({
4739
3652
  abi: ERC20_ABI,
4740
3653
  functionName: "transfer",
4741
3654
  args: [agent, perAgent]
@@ -4750,12 +3663,25 @@ function buildDisburseBatch(config, vaultAddress, agents, assetAddress, assetDec
4750
3663
  var VALID_FEES = [500, 3e3, 1e4];
4751
3664
  function registerAllowanceCommands(program2) {
4752
3665
  const allowance = program2.command("allowance").description("Disburse vault profits to agent wallets");
4753
- allowance.command("disburse").description("Swap vault profits \u2192 USDC \u2192 distribute to all agent operator wallets").requiredOption("--vault <address>", "Vault address").requiredOption("--amount <amount>", "Deposit token amount to convert & distribute (e.g. 500)").option("--fee <tier>", "Fee tier for asset \u2192 USDC swap (500, 3000, 10000)", "3000").option("--slippage <bps>", "Slippage tolerance in bps", "100").option("--execute", "Execute on-chain (default: simulate only)", false).action(async (opts) => {
3666
+ allowance.command("disburse").description("Swap vault profits \u2192 USDC \u2192 distribute to all agent operator wallets").requiredOption("--vault <address>", "Vault address").requiredOption("--amount <amount>", "Deposit token amount to convert & distribute (e.g. 500)").option("--fee <tier>", "Fee tier for asset \u2192 USDC swap (500, 3000, 10000)", "3000").option("--slippage <bps>", "Slippage tolerance in bps", "100").option("--execute", "Unavailable \u2014 the vault has no owner-direct batch path (V-C3); fails with guidance", false).action(async (opts) => {
4754
3667
  const vaultAddress = opts.vault;
4755
3668
  if (!isAddress4(vaultAddress)) {
4756
3669
  console.error(chalk3.red(`Invalid vault address: ${opts.vault}`));
4757
3670
  process.exit(1);
4758
3671
  }
3672
+ if (opts.execute) {
3673
+ console.error(
3674
+ chalk3.red(
3675
+ "allowance disburse --execute is not available: the vault no longer exposes owner-direct batch execution (executeBatch was removed on-chain, V-C3)."
3676
+ )
3677
+ );
3678
+ console.error(
3679
+ chalk3.dim(
3680
+ "Vault funds can only move through governor-approved batches (executeGovernorBatch via the proposal lifecycle). Run without --execute to simulate the batch."
3681
+ )
3682
+ );
3683
+ process.exit(1);
3684
+ }
4759
3685
  const fee = Number(opts.fee);
4760
3686
  if (!VALID_FEES.includes(fee)) {
4761
3687
  console.error(chalk3.red(`Invalid fee tier. Valid: ${VALID_FEES.join(", ")}`));
@@ -4773,8 +3699,8 @@ function registerAllowanceCommands(program2) {
4773
3699
  try {
4774
3700
  [assetAddress, totalDeposited, agents] = await Promise.all([
4775
3701
  client.readContract({ address: vaultAddress, abi: SYNDICATE_VAULT_ABI, functionName: "asset" }),
4776
- client.readContract({ address: vaultAddress, abi: SYNDICATE_VAULT_ABI, functionName: "totalDeposited" }),
4777
- client.readContract({ address: vaultAddress, abi: SYNDICATE_VAULT_ABI, functionName: "getAgentAddresses" })
3702
+ getNetDeposited(vaultAddress),
3703
+ getAgentAddresses(vaultAddress)
4778
3704
  ]);
4779
3705
  [assetDecimals, assetSymbol, assetBalance] = await Promise.all([
4780
3706
  client.readContract({ address: assetAddress, abi: ERC20_ABI, functionName: "decimals" }),
@@ -4801,7 +3727,7 @@ function registerAllowanceCommands(program2) {
4801
3727
  console.log(` Asset: ${assetSymbol} (${assetDecimals} decimals)`);
4802
3728
  console.log(` Amount: ${opts.amount} ${assetSymbol}`);
4803
3729
  console.log(` Vault balance: ${formatUnits4(assetBalance, assetDecimals)} ${assetSymbol}`);
4804
- console.log(` Deposited: ${formatUnits4(totalDeposited, assetDecimals)} ${assetSymbol}`);
3730
+ console.log(` Net deposited (est.): ${formatUnits4(totalDeposited, assetDecimals)} ${assetSymbol}`);
4805
3731
  console.log(` Profit: ${formatUnits4(profit, assetDecimals)} ${assetSymbol}`);
4806
3732
  console.log(` Agents: ${agents.length} (USDC will be split equally)`);
4807
3733
  if (!isUsdc) {
@@ -4868,21 +3794,12 @@ function registerAllowanceCommands(program2) {
4868
3794
  console.log(chalk3.bold(`Batch calls (${calls.length}):`));
4869
3795
  console.log(formatBatch(calls));
4870
3796
  console.log();
4871
- if (!opts.execute) {
4872
- console.log();
4873
- console.log(chalk3.yellow("Dry run complete. Add --execute to submit on-chain."));
4874
- return;
4875
- }
4876
- const execSpinner = ora3("Executing batch via vault...").start();
4877
- try {
4878
- const txHash = await executeBatch(calls);
4879
- execSpinner.succeed(`Batch executed: ${txHash}`);
4880
- console.log(chalk3.dim(` ${getExplorerUrl(txHash)}`));
4881
- } catch (err) {
4882
- execSpinner.fail("Execution failed");
4883
- console.error(chalk3.red(formatContractError(err)));
4884
- process.exit(1);
4885
- }
3797
+ console.log();
3798
+ console.log(
3799
+ chalk3.yellow(
3800
+ "Dry run complete. On-chain execution is unavailable \u2014 the vault has no owner-direct batch path (V-C3); disbursement requires a governor proposal."
3801
+ )
3802
+ );
4886
3803
  });
4887
3804
  allowance.command("status").description("Show vault profit and agent USDC balances").requiredOption("--vault <address>", "Vault address").action(async (opts) => {
4888
3805
  const vaultAddress = opts.vault;
@@ -4895,8 +3812,8 @@ function registerAllowanceCommands(program2) {
4895
3812
  try {
4896
3813
  const [assetAddress, totalDeposited, agents] = await Promise.all([
4897
3814
  client.readContract({ address: vaultAddress, abi: SYNDICATE_VAULT_ABI, functionName: "asset" }),
4898
- client.readContract({ address: vaultAddress, abi: SYNDICATE_VAULT_ABI, functionName: "totalDeposited" }),
4899
- client.readContract({ address: vaultAddress, abi: SYNDICATE_VAULT_ABI, functionName: "getAgentAddresses" })
3815
+ getNetDeposited(vaultAddress),
3816
+ getAgentAddresses(vaultAddress)
4900
3817
  ]);
4901
3818
  const [assetDecimals, assetSymbol, assetBalance] = await Promise.all([
4902
3819
  client.readContract({ address: assetAddress, abi: ERC20_ABI, functionName: "decimals" }),
@@ -4923,7 +3840,7 @@ function registerAllowanceCommands(program2) {
4923
3840
  console.log(chalk3.bold("\n Vault"));
4924
3841
  console.log(` Asset: ${assetSymbol}`);
4925
3842
  console.log(` Balance: ${formatUnits4(assetBalance, assetDecimals)} ${assetSymbol}`);
4926
- console.log(` Deposited: ${formatUnits4(totalDeposited, assetDecimals)} ${assetSymbol}`);
3843
+ console.log(` Net deposited (est.): ${formatUnits4(totalDeposited, assetDecimals)} ${assetSymbol}`);
4927
3844
  console.log(` Profit: ${formatUnits4(profit, assetDecimals)} ${assetSymbol}`);
4928
3845
  console.log(chalk3.bold("\n Agent USDC Balances"));
4929
3846
  for (const { agent, balance } of agentBalances) {
@@ -4961,18 +3878,12 @@ var IDENTITY_REGISTRY_ABI2 = [
4961
3878
  }
4962
3879
  ];
4963
3880
  function getAgent0SDK() {
4964
- const config = loadConfig();
4965
- const key = config.privateKey || process.env.PRIVATE_KEY;
4966
- if (!key) {
4967
- throw new Error(
4968
- "Private key not found. Run 'sherwood config set --private-key <key>' or set PRIVATE_KEY env var."
4969
- );
4970
- }
3881
+ const key = requirePrivateKey();
4971
3882
  const chain = getChain();
4972
3883
  const sdkConfig = {
4973
3884
  chainId: chain.id,
4974
3885
  rpcUrl: getRpcUrl(),
4975
- privateKey: key.startsWith("0x") ? key : `0x${key}`
3886
+ privateKey: key
4976
3887
  };
4977
3888
  if (chain.id !== getChainConfig().chain.id) {
4978
3889
  sdkConfig.registryOverrides = {
@@ -5204,13 +4115,13 @@ function registerIdentityCommands(program2) {
5204
4115
  }
5205
4116
 
5206
4117
  // src/commands/proposal.ts
5207
- import { isAddress as isAddress5, encodeFunctionData as encodeFunctionData18 } from "viem";
4118
+ import { isAddress as isAddress5, encodeFunctionData as encodeFunctionData10 } from "viem";
5208
4119
  import chalk6 from "chalk";
5209
4120
  import ora5 from "ora";
5210
4121
  import { readFileSync as readFileSync2 } from "fs";
5211
4122
 
5212
4123
  // src/lib/simulate.ts
5213
- import { decodeFunctionData as decodeFunctionData2, encodeFunctionData as encodeFunctionData17 } from "viem";
4124
+ import { decodeFunctionData as decodeFunctionData2, encodeFunctionData as encodeFunctionData9 } from "viem";
5214
4125
  import chalk5 from "chalk";
5215
4126
 
5216
4127
  // src/lib/risk.ts
@@ -5769,7 +4680,7 @@ async function simulateViaApi(vault, calls) {
5769
4680
  async function simulateViaEthCall(vault, calls) {
5770
4681
  const governor = await getGovernorOf(vault);
5771
4682
  const client = getPublicClient();
5772
- const input2 = encodeFunctionData17({
4683
+ const input2 = encodeFunctionData9({
5773
4684
  abi: SYNDICATE_VAULT_ABI,
5774
4685
  functionName: "executeGovernorBatch",
5775
4686
  args: [calls.map((c) => ({ target: c.target, data: c.data, value: c.value }))]
@@ -5897,8 +4808,8 @@ function printSimulationResult(result, callType) {
5897
4808
  }
5898
4809
  async function sendSimulationAlert(subdomain, proposalId, vault, execResult, settleResult) {
5899
4810
  try {
5900
- const xmtp = await import("./xmtp-6US7GH3Z.js");
5901
- const { getAccount: getAccount2 } = await import("./client-NAL3HVLK.js");
4811
+ const xmtp = await import("./xmtp-Q4ZSQV2Q.js");
4812
+ const { getAccount: getAccount2 } = await import("./client-C3C6IXAH.js");
5902
4813
  const group = await xmtp.getGroup("", subdomain);
5903
4814
  const allRisks = [...execResult.risks, ...settleResult?.risks ?? []];
5904
4815
  const criticals = allRisks.filter((r) => r.level === "critical");
@@ -6581,7 +5492,7 @@ function registerProposalCommands(program2) {
6581
5492
  process.exit(1);
6582
5493
  }
6583
5494
  const asset = await getAssetAddress();
6584
- const noopCalldata = encodeFunctionData18({
5495
+ const noopCalldata = encodeFunctionData10({
6585
5496
  abi: ERC20_ABI,
6586
5497
  functionName: "balanceOf",
6587
5498
  args: [vault]
@@ -8595,13 +7506,13 @@ var GridExecutor = class {
8595
7506
  import chalk13 from "chalk";
8596
7507
  import { mkdir as mkdir3, readFile as readFile3, rename as rename2, writeFile as writeFile3 } from "fs/promises";
8597
7508
  import { dirname as dirname3 } from "path";
8598
- import { encodeAbiParameters as encodeAbiParameters13, parseUnits as parseUnits7 } from "viem";
7509
+ import { encodeAbiParameters as encodeAbiParameters5, parseUnits as parseUnits7 } from "viem";
8599
7510
 
8600
7511
  // src/grid/cloid.ts
8601
- import { keccak256 as keccak2562, encodeAbiParameters as encodeAbiParameters12 } from "viem";
7512
+ import { keccak256 as keccak2562, encodeAbiParameters as encodeAbiParameters4 } from "viem";
8602
7513
  function gridCloid(strategy2, assetIndex, isBuy, levelIndex, nonce) {
8603
7514
  const hash = keccak2562(
8604
- encodeAbiParameters12(
7515
+ encodeAbiParameters4(
8605
7516
  [
8606
7517
  { type: "address" },
8607
7518
  { type: "uint32" },
@@ -8621,11 +7532,11 @@ var UINT64_MAX = 18446744073709551615n;
8621
7532
  var ACTION_PLACE_GRID = 1;
8622
7533
  var ACTION_CANCEL_ALL = 2;
8623
7534
  var ACTION_CANCEL_AND_PLACE = 3;
8624
- function chunkArray(arr, size2) {
8625
- if (size2 <= 0) throw new Error(`chunk size must be > 0 (got ${size2})`);
7535
+ function chunkArray(arr, size) {
7536
+ if (size <= 0) throw new Error(`chunk size must be > 0 (got ${size})`);
8626
7537
  if (arr.length === 0) return [];
8627
7538
  const out = [];
8628
- for (let i = 0; i < arr.length; i += size2) out.push(arr.slice(i, i + size2));
7539
+ for (let i = 0; i < arr.length; i += size) out.push(arr.slice(i, i + size));
8629
7540
  return out;
8630
7541
  }
8631
7542
  var GRID_ORDER_COMPONENTS = [
@@ -8828,7 +7739,7 @@ var OnchainGridExecutor = class {
8828
7739
  for (const chunk of chunks) {
8829
7740
  const nonce = this.bumpNonce(token);
8830
7741
  const { encoded, cloids } = this.encodeOrders(assetIndex, chunk, meta, nonce);
8831
- const data = encodeAbiParameters13(
7742
+ const data = encodeAbiParameters5(
8832
7743
  [{ type: "uint8" }, { type: "tuple[]", components: [...GRID_ORDER_COMPONENTS] }],
8833
7744
  [ACTION_PLACE_GRID, encoded]
8834
7745
  );
@@ -8846,7 +7757,7 @@ var OnchainGridExecutor = class {
8846
7757
  this.bumpNonce(token);
8847
7758
  return "0x";
8848
7759
  }
8849
- const data = encodeAbiParameters13(
7760
+ const data = encodeAbiParameters5(
8850
7761
  [{ type: "uint8" }, { type: "uint32" }, { type: "uint128[]" }],
8851
7762
  [ACTION_CANCEL_ALL, assetIndex, cloids]
8852
7763
  );
@@ -8875,7 +7786,7 @@ var OnchainGridExecutor = class {
8875
7786
  const { encoded, cloids } = this.encodeOrders(assetIndex, chunk, meta, newNonce);
8876
7787
  let data;
8877
7788
  if (i === 0) {
8878
- data = encodeAbiParameters13(
7789
+ data = encodeAbiParameters5(
8879
7790
  [
8880
7791
  { type: "uint8" },
8881
7792
  { type: "uint32" },
@@ -8885,7 +7796,7 @@ var OnchainGridExecutor = class {
8885
7796
  [ACTION_CANCEL_AND_PLACE, assetIndex, oldCloids, encoded]
8886
7797
  );
8887
7798
  } else {
8888
- data = encodeAbiParameters13(
7799
+ data = encodeAbiParameters5(
8889
7800
  [{ type: "uint8" }, { type: "tuple[]", components: [...GRID_ORDER_COMPONENTS] }],
8890
7801
  [ACTION_PLACE_GRID, encoded]
8891
7802
  );
@@ -9395,8 +8306,8 @@ function computeDrawdown(curve) {
9395
8306
  }
9396
8307
  function isoToYmdHms(ms) {
9397
8308
  const d = new Date(ms);
9398
- const pad2 = (n) => n.toString().padStart(2, "0");
9399
- return `${d.getUTCFullYear()}${pad2(d.getUTCMonth() + 1)}${pad2(d.getUTCDate())}-${pad2(d.getUTCHours())}${pad2(d.getUTCMinutes())}${pad2(d.getUTCSeconds())}`;
8309
+ const pad = (n) => n.toString().padStart(2, "0");
8310
+ return `${d.getUTCFullYear()}${pad(d.getUTCMonth() + 1)}${pad(d.getUTCDate())}-${pad(d.getUTCHours())}${pad(d.getUTCMinutes())}${pad(d.getUTCSeconds())}`;
9400
8311
  }
9401
8312
  function makeRunId(fromMs, toMs, config) {
9402
8313
  return `bt-${isoToYmdHms(Date.now())}-${shortHash({ fromMs, toMs, config })}`;
@@ -9735,13 +8646,13 @@ import { join as join4 } from "path";
9735
8646
  import { homedir as homedir4 } from "os";
9736
8647
  import { createHash as createHash2 } from "crypto";
9737
8648
  var DEFAULT_SWEEP_DIR = join4(homedir4(), ".sherwood", "grid", "sweeps");
9738
- function expandSweep(sweep, base2) {
8649
+ function expandSweep(sweep, base) {
9739
8650
  const fields = ["leverage", "levelsPerSide", "atrMultiplier", "rebalanceDriftPct"];
9740
8651
  const valueLists = {
9741
- leverage: sweep.leverage && sweep.leverage.length > 0 ? sweep.leverage : [base2.leverage],
9742
- levelsPerSide: sweep.levelsPerSide && sweep.levelsPerSide.length > 0 ? sweep.levelsPerSide : [base2.levelsPerSide],
9743
- atrMultiplier: sweep.atrMultiplier && sweep.atrMultiplier.length > 0 ? sweep.atrMultiplier : [base2.atrMultiplier],
9744
- rebalanceDriftPct: sweep.rebalanceDriftPct && sweep.rebalanceDriftPct.length > 0 ? sweep.rebalanceDriftPct : [base2.rebalanceDriftPct]
8652
+ leverage: sweep.leverage && sweep.leverage.length > 0 ? sweep.leverage : [base.leverage],
8653
+ levelsPerSide: sweep.levelsPerSide && sweep.levelsPerSide.length > 0 ? sweep.levelsPerSide : [base.levelsPerSide],
8654
+ atrMultiplier: sweep.atrMultiplier && sweep.atrMultiplier.length > 0 ? sweep.atrMultiplier : [base.atrMultiplier],
8655
+ rebalanceDriftPct: sweep.rebalanceDriftPct && sweep.rebalanceDriftPct.length > 0 ? sweep.rebalanceDriftPct : [base.rebalanceDriftPct]
9745
8656
  };
9746
8657
  let combos = [{}];
9747
8658
  for (const field of fields) {
@@ -9757,8 +8668,8 @@ function expandSweep(sweep, base2) {
9757
8668
  }
9758
8669
  function makeSweepId(opts) {
9759
8670
  const d = /* @__PURE__ */ new Date();
9760
- const pad2 = (n) => n.toString().padStart(2, "0");
9761
- const stamp = `${d.getUTCFullYear()}${pad2(d.getUTCMonth() + 1)}${pad2(d.getUTCDate())}-${pad2(d.getUTCHours())}${pad2(d.getUTCMinutes())}${pad2(d.getUTCSeconds())}`;
8671
+ const pad = (n) => n.toString().padStart(2, "0");
8672
+ const stamp = `${d.getUTCFullYear()}${pad(d.getUTCMonth() + 1)}${pad(d.getUTCDate())}-${pad(d.getUTCHours())}${pad(d.getUTCMinutes())}${pad(d.getUTCSeconds())}`;
9762
8673
  const hash = createHash2("sha256").update(JSON.stringify({
9763
8674
  fromMs: opts.fromMs,
9764
8675
  toMs: opts.toMs,
@@ -9780,13 +8691,13 @@ async function runSweep(opts) {
9780
8691
  tokenSplit = {};
9781
8692
  for (const t of opts.tokens) tokenSplit[t] = weight;
9782
8693
  }
9783
- const base2 = {
8694
+ const base = {
9784
8695
  ...DEFAULT_GRID_CONFIG,
9785
8696
  ...opts.baseConfig,
9786
8697
  tokens: opts.tokens,
9787
8698
  tokenSplit
9788
8699
  };
9789
- const combos = expandSweep(opts.sweep, base2);
8700
+ const combos = expandSweep(opts.sweep, base);
9790
8701
  if (combos.length === 0) throw new Error("sweep produced no combinations");
9791
8702
  const loader = new HistoricalDataLoader({ noCache: opts.noCache });
9792
8703
  if (opts.verbose !== false) {
@@ -9797,7 +8708,7 @@ async function runSweep(opts) {
9797
8708
  const runs = [];
9798
8709
  for (let i = 0; i < combos.length; i++) {
9799
8710
  const combo = combos[i];
9800
- const config = { ...base2, ...combo };
8711
+ const config = { ...base, ...combo };
9801
8712
  const runOutPath = join4(sweepDir, `run-${i.toString().padStart(3, "0")}.json`);
9802
8713
  if (opts.verbose !== false) {
9803
8714
  process.stderr.write(` [sweep] [${i + 1}/${combos.length}] ${JSON.stringify(combo)}
@@ -10335,9 +9246,9 @@ try {
10335
9246
  } catch {
10336
9247
  }
10337
9248
  var require2 = createRequire(import.meta.url);
10338
- var CLI_VERSION = "0.73.4";
9249
+ var CLI_VERSION = "0.74.2";
10339
9250
  async function loadXmtp() {
10340
- return import("./xmtp-6US7GH3Z.js");
9251
+ return import("./xmtp-Q4ZSQV2Q.js");
10341
9252
  }
10342
9253
  async function loadCron() {
10343
9254
  return import("./cron-QMLRWDJG.js");
@@ -10539,8 +9450,12 @@ fund.command("create").description("Create a new fund via the factory (interacti
10539
9450
  } catch {
10540
9451
  spinner2.text = W6("Creating chat group...");
10541
9452
  const groupId = await xmtp.createFundGroup(xmtpClient, subdomain, opts.publicChat);
10542
- await setTextRecord(subdomain, "xmtpGroupId", groupId, existingInfo.vault);
10543
9453
  cacheGroupId(subdomain, groupId);
9454
+ try {
9455
+ await setTextRecord(subdomain, "xmtpGroupId", groupId, existingInfo.vault);
9456
+ } catch {
9457
+ console.log(chalk16.dim(" ENS text record skipped (metadata fallback active)"));
9458
+ }
10544
9459
  }
10545
9460
  } catch {
10546
9461
  console.warn(chalk16.yellow("\n \u26A0 Could not set up XMTP chat group"));
@@ -10601,6 +9516,7 @@ fund.command("create").description("Create a new fund via the factory (interacti
10601
9516
  try {
10602
9517
  await setTextRecord(subdomain, "xmtpGroupId", groupId, result.vault);
10603
9518
  } catch {
9519
+ console.log(chalk16.dim(" ENS text record skipped (metadata fallback active)"));
10604
9520
  }
10605
9521
  } catch {
10606
9522
  console.warn(chalk16.yellow("\n \u26A0 Could not create XMTP chat group"));
@@ -10877,7 +9793,7 @@ fund.command("remove-depositor").description("Remove an address from the deposit
10877
9793
  });
10878
9794
  fund.command("set-agent-fee").description("Set the vault's agent performance fee in bps (vault owner only)").option("--vault <address>", "Vault address (default: from config)").requiredOption(
10879
9795
  "--bps <bps>",
10880
- "Agent fee in bps (e.g. 1000 = 10%; max 1500 = 15%). The governor clamps the realized fee to its configured maxPerformanceFeeBps, which may be lower."
9796
+ `Agent fee in bps (e.g. 1000 = 10%; max ${MAX_AGENT_FEE_BPS} = ${MAX_AGENT_FEE_BPS / 100}%). The governor clamps the realized fee to its configured maxPerformanceFeeBps, which may be lower.`
10881
9797
  ).action(async (opts) => {
10882
9798
  resolveVault(opts);
10883
9799
  const spinner = ora9("Setting agent fee...").start();
@@ -10933,7 +9849,7 @@ fund.command("add").description("Register an agent on a fund vault (creator only
10933
9849
  if (opts.agentId) {
10934
9850
  agentId = BigInt(opts.agentId);
10935
9851
  } else {
10936
- const { AGENT_REGISTRY: AGENT_REGISTRY2 } = await import("./addresses-DGB3D457.js");
9852
+ const { AGENT_REGISTRY: AGENT_REGISTRY2 } = await import("./addresses-OFFTM6NG.js");
10937
9853
  const registry = AGENT_REGISTRY2().IDENTITY_REGISTRY;
10938
9854
  if (registry === "0x0000000000000000000000000000000000000000") {
10939
9855
  agentId = 0n;
@@ -11658,19 +10574,18 @@ vaultCmd.command("redeem").description("Redeem vault shares for the underlying a
11658
10574
  });
11659
10575
  var strategy = program.command("strategy").description("Strategy templates \u2014 list, clone, propose");
11660
10576
  registerStrategyTemplateCommands(strategy);
11661
- program.command("providers").description("List available DeFi providers").action(async () => {
11662
- const { MessariProvider, NansenProvider } = await import("./research-4TBGYEVI.js");
11663
- const providers = [new MoonwellProvider(), new UniswapProvider(), new MessariProvider(), new NansenProvider()];
11664
- for (const p of providers) {
11665
- const info = p.info();
10577
+ program.command("providers").description("List available providers (research + swap routing)").action(async () => {
10578
+ const { listProviders } = await import("./providers-YOOQFBN2.js");
10579
+ for (const info of listProviders()) {
11666
10580
  console.log(`
11667
10581
  ${info.name} (${info.type})`);
11668
10582
  console.log(` Capabilities: ${info.capabilities.join(", ")}`);
11669
- console.log(` Chains: ${info.supportedChains.map((c) => c.name).join(", ")}`);
10583
+ const chains = info.supportedChains.map((c) => c.name).join(", ");
10584
+ console.log(` Chains: ${chains || "any (chain-agnostic)"}`);
11670
10585
  }
11671
10586
  });
11672
10587
  try {
11673
- const { registerChatCommands } = await import("./chat-KT2WVDT2.js");
10588
+ const { registerChatCommands } = await import("./chat-3PM3GP3C.js");
11674
10589
  registerChatCommands(program);
11675
10590
  } catch {
11676
10591
  program.command("chat <name> [action] [actionArgs...]").description("Fund chat (XMTP) \u2014 requires @xmtp/cli").action(() => {
@@ -11680,7 +10595,7 @@ try {
11680
10595
  process.exit(1);
11681
10596
  });
11682
10597
  }
11683
- var { registerSessionCommands } = await import("./session-L67AVWBY.js");
10598
+ var { registerSessionCommands } = await import("./session-GUVSID3Z.js");
11684
10599
  registerSessionCommands(program);
11685
10600
  registerVeniceCommands(program);
11686
10601
  registerAllowanceCommands(program);
@@ -11689,11 +10604,11 @@ registerProposalCommands(program);
11689
10604
  registerQueueCommands(program);
11690
10605
  registerGovernorCommands(program);
11691
10606
  registerGuardianCommands(program);
11692
- var { registerResearchCommands } = await import("./research-IJBOMYL3.js");
10607
+ var { registerResearchCommands } = await import("./research-KX3LCAOQ.js");
11693
10608
  registerResearchCommands(program);
11694
- var { registerAgentCommands } = await import("./agent-UNSW5IPO.js");
10609
+ var { registerAgentCommands } = await import("./agent-IJOOONON.js");
11695
10610
  registerAgentCommands(program);
11696
- var { registerTradeCommands } = await import("./trade-LGFQEK3I.js");
10611
+ var { registerTradeCommands } = await import("./trade-WDPMFFYB.js");
11697
10612
  registerTradeCommands(program);
11698
10613
  registerGridCommand(program);
11699
10614
  var configCmd = program.command("config");