@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.
- package/dist/{agent-A2JEYGQS.js → agent-FCGZL4GF.js} +4 -4
- package/dist/{chat-OZAAN5LT.js → chat-AKLYUJZV.js} +6 -6
- package/dist/{chunk-37GT3TJX.js → chunk-4ITTHKRX.js} +3 -3
- package/dist/{chunk-TTF5TDRV.js → chunk-6D3FNU75.js} +3 -3
- package/dist/{chunk-3UYGXGMF.js → chunk-6SAE2VDK.js} +2 -2
- package/dist/{chunk-R6F57QQF.js → chunk-BH3VTJ4F.js} +3 -3
- package/dist/{chunk-MIAMGVZ4.js → chunk-D4BSBW3Q.js} +215 -4
- package/dist/chunk-D4BSBW3Q.js.map +1 -0
- package/dist/{chunk-IINWI3LD.js → chunk-EEI6FRTE.js} +2 -2
- package/dist/{chunk-UOIAY6ZG.js → chunk-FWQESFFM.js} +13 -3
- package/dist/{chunk-UOIAY6ZG.js.map → chunk-FWQESFFM.js.map} +1 -1
- package/dist/{chunk-CU42ZD4K.js → chunk-G5MXVAFC.js} +16 -3
- package/dist/{chunk-CU42ZD4K.js.map → chunk-G5MXVAFC.js.map} +1 -1
- package/dist/{chunk-V7TNYHIK.js → chunk-HMFPP2PE.js} +55 -7
- package/dist/chunk-HMFPP2PE.js.map +1 -0
- package/dist/{chunk-GR3GSU3I.js → chunk-N2E2Q5GL.js} +4 -4
- package/dist/{chunk-JGD6A2Q4.js → chunk-QFGZQYZA.js} +3 -3
- package/dist/{chunk-W3XWRWML.js → chunk-SCQAKMMI.js} +119 -38
- package/dist/chunk-SCQAKMMI.js.map +1 -0
- package/dist/{client-C6N2ASTH.js → client-PYFE6YQR.js} +2 -2
- package/dist/{eas-VFTWEI4K.js → eas-B4HR2HXX.js} +8 -4
- package/dist/{governor-HVBSI6Z2.js → governor-QFBN6RYS.js} +6 -4
- package/dist/{identity-OLD25QEP.js → identity-I2BG4IGT.js} +5 -5
- package/dist/index.js +292 -81
- package/dist/index.js.map +1 -1
- package/dist/{price-O3THX2HL.js → price-EXZDYVDD.js} +4 -4
- package/dist/{providers-KZNCCUKT.js → providers-6UZKDFQD.js} +3 -3
- package/dist/{research-ARFBFXIT.js → research-T7A27OMB.js} +5 -5
- package/dist/{session-A7CYZSSA.js → session-45NQAHFI.js} +7 -7
- package/dist/{trade-ZCK332E4.js → trade-ZOVM433K.js} +10 -10
- package/dist/{vault-CDI7BELZ.js → vault-WWGSRNRP.js} +6 -6
- package/dist/{xmtp-7LAWDKJT.js → xmtp-72IRK7JL.js} +4 -4
- package/package.json +2 -2
- package/dist/chunk-MIAMGVZ4.js.map +0 -1
- package/dist/chunk-V7TNYHIK.js.map +0 -1
- package/dist/chunk-W3XWRWML.js.map +0 -1
- /package/dist/{agent-A2JEYGQS.js.map → agent-FCGZL4GF.js.map} +0 -0
- /package/dist/{chat-OZAAN5LT.js.map → chat-AKLYUJZV.js.map} +0 -0
- /package/dist/{chunk-37GT3TJX.js.map → chunk-4ITTHKRX.js.map} +0 -0
- /package/dist/{chunk-TTF5TDRV.js.map → chunk-6D3FNU75.js.map} +0 -0
- /package/dist/{chunk-3UYGXGMF.js.map → chunk-6SAE2VDK.js.map} +0 -0
- /package/dist/{chunk-R6F57QQF.js.map → chunk-BH3VTJ4F.js.map} +0 -0
- /package/dist/{chunk-IINWI3LD.js.map → chunk-EEI6FRTE.js.map} +0 -0
- /package/dist/{chunk-GR3GSU3I.js.map → chunk-N2E2Q5GL.js.map} +0 -0
- /package/dist/{chunk-JGD6A2Q4.js.map → chunk-QFGZQYZA.js.map} +0 -0
- /package/dist/{client-C6N2ASTH.js.map → client-PYFE6YQR.js.map} +0 -0
- /package/dist/{eas-VFTWEI4K.js.map → eas-B4HR2HXX.js.map} +0 -0
- /package/dist/{governor-HVBSI6Z2.js.map → governor-QFBN6RYS.js.map} +0 -0
- /package/dist/{identity-OLD25QEP.js.map → identity-I2BG4IGT.js.map} +0 -0
- /package/dist/{price-O3THX2HL.js.map → price-EXZDYVDD.js.map} +0 -0
- /package/dist/{providers-KZNCCUKT.js.map → providers-6UZKDFQD.js.map} +0 -0
- /package/dist/{research-ARFBFXIT.js.map → research-T7A27OMB.js.map} +0 -0
- /package/dist/{session-A7CYZSSA.js.map → session-45NQAHFI.js.map} +0 -0
- /package/dist/{trade-ZCK332E4.js.map → trade-ZOVM433K.js.map} +0 -0
- /package/dist/{vault-CDI7BELZ.js.map → vault-WWGSRNRP.js.map} +0 -0
- /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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
88
|
+
} from "./chunk-6D3FNU75.js";
|
|
85
89
|
import {
|
|
86
90
|
resolveFund,
|
|
87
91
|
resolveVaultFund,
|
|
88
92
|
searchFundAcrossChains,
|
|
89
93
|
setTextRecord
|
|
90
|
-
} from "./chunk-
|
|
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-
|
|
114
|
-
import "./chunk-
|
|
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-
|
|
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-
|
|
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-
|
|
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 (
|
|
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-
|
|
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
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
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
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
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
|
-
|
|
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-
|
|
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-
|
|
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-
|
|
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
|
-
|
|
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
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
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
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
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
|
-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
3281
|
-
const { getAccount: getAccount2 } = await import("./client-
|
|
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.
|
|
8051
|
+
var CLI_VERSION = "0.88.0";
|
|
7841
8052
|
async function loadXmtp() {
|
|
7842
|
-
return import("./xmtp-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
9456
|
+
var { registerResearchCommands } = await import("./research-T7A27OMB.js");
|
|
9246
9457
|
registerResearchCommands(program);
|
|
9247
|
-
var { registerAgentCommands } = await import("./agent-
|
|
9458
|
+
var { registerAgentCommands } = await import("./agent-FCGZL4GF.js");
|
|
9248
9459
|
registerAgentCommands(program);
|
|
9249
|
-
var { registerTradeCommands } = await import("./trade-
|
|
9460
|
+
var { registerTradeCommands } = await import("./trade-ZOVM433K.js");
|
|
9250
9461
|
registerTradeCommands(program);
|
|
9251
9462
|
registerGridCommand(program);
|
|
9252
9463
|
var configCmd = program.command("config");
|