@sherwoodagent/cli 0.85.1 → 0.86.1
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/{chat-DNWTI4CZ.js → chat-ETZSKQDI.js} +13 -13
- package/dist/chat-ETZSKQDI.js.map +1 -0
- package/dist/{chunk-ARSQ5UQA.js → chunk-3IAZQMAW.js} +2 -2
- package/dist/{chunk-FPB23SDH.js → chunk-6QBGTX2Q.js} +93 -19
- package/dist/chunk-6QBGTX2Q.js.map +1 -0
- package/dist/{chunk-65G5BFYR.js → chunk-EA65CDQH.js} +3 -3
- package/dist/{chunk-53W6CYYV.js → chunk-EVUKJ7CJ.js} +2 -2
- package/dist/{chunk-AM6MI2JF.js → chunk-IAM4VIU2.js} +146 -23
- package/dist/chunk-IAM4VIU2.js.map +1 -0
- package/dist/{chunk-M4GX5PL2.js → chunk-OUYMZ5ZC.js} +2 -2
- package/dist/{chunk-TWT56FTL.js → chunk-XPVXNG2K.js} +3 -3
- package/dist/{chunk-6N7EVSAZ.js → chunk-YAS52NEF.js} +19 -6
- package/dist/{chunk-6N7EVSAZ.js.map → chunk-YAS52NEF.js.map} +1 -1
- package/dist/{chunk-VR4VHX4D.js → chunk-YMB4RJOR.js} +2 -2
- package/dist/{chunk-VR4VHX4D.js.map → chunk-YMB4RJOR.js.map} +1 -1
- package/dist/{chunk-I2BBOJNC.js → chunk-ZN2MHIB7.js} +2 -2
- package/dist/{eas-D3BVHBJH.js → eas-KMDAMLXW.js} +3 -3
- package/dist/{governor-35IXAEDJ.js → governor-JNSWPJVQ.js} +7 -5
- package/dist/{identity-3A2D7DGS.js → identity-ATWV2O7Y.js} +4 -4
- package/dist/index.js +239 -148
- package/dist/index.js.map +1 -1
- package/dist/{ipfs-EJ7IHXCU.js → ipfs-M56BLMCW.js} +2 -2
- package/dist/{price-I5T77X7Y.js → price-YNPYE2EO.js} +3 -3
- package/dist/{research-GZNVG3SP.js → research-W74PNYPO.js} +14 -14
- package/dist/research-W74PNYPO.js.map +1 -0
- package/dist/{session-M5QB25PK.js → session-HVRZ6AJM.js} +7 -7
- package/dist/{trade-TCQ5NUNA.js → trade-EOQY72L7.js} +10 -10
- package/dist/trade-EOQY72L7.js.map +1 -0
- package/dist/{vault-K2R4VHVI.js → vault-HWJQJW5U.js} +6 -6
- package/dist/{xmtp-R25Q5GWY.js → xmtp-KW73BGVO.js} +3 -3
- package/package.json +2 -2
- package/dist/chat-DNWTI4CZ.js.map +0 -1
- package/dist/chunk-AM6MI2JF.js.map +0 -1
- package/dist/chunk-FPB23SDH.js.map +0 -1
- package/dist/research-GZNVG3SP.js.map +0 -1
- package/dist/trade-TCQ5NUNA.js.map +0 -1
- /package/dist/{chunk-ARSQ5UQA.js.map → chunk-3IAZQMAW.js.map} +0 -0
- /package/dist/{chunk-65G5BFYR.js.map → chunk-EA65CDQH.js.map} +0 -0
- /package/dist/{chunk-53W6CYYV.js.map → chunk-EVUKJ7CJ.js.map} +0 -0
- /package/dist/{chunk-M4GX5PL2.js.map → chunk-OUYMZ5ZC.js.map} +0 -0
- /package/dist/{chunk-TWT56FTL.js.map → chunk-XPVXNG2K.js.map} +0 -0
- /package/dist/{chunk-I2BBOJNC.js.map → chunk-ZN2MHIB7.js.map} +0 -0
- /package/dist/{eas-D3BVHBJH.js.map → eas-KMDAMLXW.js.map} +0 -0
- /package/dist/{governor-35IXAEDJ.js.map → governor-JNSWPJVQ.js.map} +0 -0
- /package/dist/{identity-3A2D7DGS.js.map → identity-ATWV2O7Y.js.map} +0 -0
- /package/dist/{ipfs-EJ7IHXCU.js.map → ipfs-M56BLMCW.js.map} +0 -0
- /package/dist/{price-I5T77X7Y.js.map → price-YNPYE2EO.js.map} +0 -0
- /package/dist/{session-M5QB25PK.js.map → session-HVRZ6AJM.js.map} +0 -0
- /package/dist/{vault-K2R4VHVI.js.map → vault-HWJQJW5U.js.map} +0 -0
- /package/dist/{xmtp-R25Q5GWY.js.map → xmtp-KW73BGVO.js.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -31,7 +31,7 @@ import {
|
|
|
31
31
|
parseAlignedOverrides,
|
|
32
32
|
resolveToken,
|
|
33
33
|
selectBestFeeTier
|
|
34
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-3IAZQMAW.js";
|
|
35
35
|
import {
|
|
36
36
|
DEFAULT_ISSUING_CHAIN_ID,
|
|
37
37
|
appendVidTag,
|
|
@@ -47,9 +47,10 @@ import {
|
|
|
47
47
|
encodeGuardianStake,
|
|
48
48
|
encodeGuardianUnstake,
|
|
49
49
|
encodeJoinRequest,
|
|
50
|
+
encodeMgmtSplit,
|
|
51
|
+
encodePerfSplit,
|
|
50
52
|
encodePropose,
|
|
51
53
|
encodeProposeWithSandbox,
|
|
52
|
-
encodeProtocolFeeBps,
|
|
53
54
|
encodeRedeem,
|
|
54
55
|
encodeRegisterAgent,
|
|
55
56
|
encodeSettle,
|
|
@@ -64,7 +65,7 @@ import {
|
|
|
64
65
|
setCalldataOnly,
|
|
65
66
|
stripVidTag,
|
|
66
67
|
verifyVidTag
|
|
67
|
-
} from "./chunk-
|
|
68
|
+
} from "./chunk-6QBGTX2Q.js";
|
|
68
69
|
import {
|
|
69
70
|
createApproval,
|
|
70
71
|
createJoinRequest,
|
|
@@ -74,20 +75,20 @@ import {
|
|
|
74
75
|
queryJoinRequests,
|
|
75
76
|
revokeJoinRequest,
|
|
76
77
|
stripReferrerPrefix
|
|
77
|
-
} from "./chunk-
|
|
78
|
+
} from "./chunk-OUYMZ5ZC.js";
|
|
78
79
|
import {
|
|
79
80
|
createFund,
|
|
80
81
|
getActiveFunds,
|
|
81
82
|
getFund,
|
|
82
83
|
subdomainExists,
|
|
83
84
|
updateMetadata
|
|
84
|
-
} from "./chunk-
|
|
85
|
+
} from "./chunk-EVUKJ7CJ.js";
|
|
85
86
|
import {
|
|
86
87
|
resolveFund,
|
|
87
88
|
resolveVaultFund,
|
|
88
89
|
searchFundAcrossChains,
|
|
89
90
|
setTextRecord
|
|
90
|
-
} from "./chunk-
|
|
91
|
+
} from "./chunk-ZN2MHIB7.js";
|
|
91
92
|
import {
|
|
92
93
|
approveDepositor,
|
|
93
94
|
deposit,
|
|
@@ -110,8 +111,8 @@ import {
|
|
|
110
111
|
removeDepositor,
|
|
111
112
|
setAgentFeeBps,
|
|
112
113
|
setVaultAddress
|
|
113
|
-
} from "./chunk-
|
|
114
|
-
import "./chunk-
|
|
114
|
+
} from "./chunk-XPVXNG2K.js";
|
|
115
|
+
import "./chunk-EA65CDQH.js";
|
|
115
116
|
import {
|
|
116
117
|
PROPOSAL_STATE,
|
|
117
118
|
PROPOSAL_STATES,
|
|
@@ -144,12 +145,13 @@ import {
|
|
|
144
145
|
setExecutionWindow,
|
|
145
146
|
setMaxPerformanceFeeBps,
|
|
146
147
|
setMaxStrategyDuration,
|
|
147
|
-
|
|
148
|
+
setMgmtSplit,
|
|
149
|
+
setPerfSplit,
|
|
148
150
|
setVetoThresholdBps,
|
|
149
151
|
setVotingPeriod,
|
|
150
152
|
settleProposal,
|
|
151
153
|
vote
|
|
152
|
-
} from "./chunk-
|
|
154
|
+
} from "./chunk-YAS52NEF.js";
|
|
153
155
|
import {
|
|
154
156
|
AERODROME,
|
|
155
157
|
MOONWELL,
|
|
@@ -158,7 +160,7 @@ import {
|
|
|
158
160
|
TOKENS,
|
|
159
161
|
UNISWAP,
|
|
160
162
|
VENICE
|
|
161
|
-
} from "./chunk-
|
|
163
|
+
} from "./chunk-IAM4VIU2.js";
|
|
162
164
|
import {
|
|
163
165
|
GAS_UNITS,
|
|
164
166
|
estimateGasCushion,
|
|
@@ -217,7 +219,7 @@ import {
|
|
|
217
219
|
fetchMetadata,
|
|
218
220
|
mergeFundMetadata,
|
|
219
221
|
uploadMetadata
|
|
220
|
-
} from "./chunk-
|
|
222
|
+
} from "./chunk-YMB4RJOR.js";
|
|
221
223
|
|
|
222
224
|
// src/index.ts
|
|
223
225
|
import { config as loadDotenv } from "dotenv";
|
|
@@ -490,7 +492,7 @@ function registerGuardianCommands(program2) {
|
|
|
490
492
|
}
|
|
491
493
|
});
|
|
492
494
|
guardian.command("prepare-owner-stake <amount>").description(
|
|
493
|
-
"Bond WOOD as a prospective vault owner \u2014 required before `
|
|
495
|
+
"Bond WOOD as a prospective vault owner \u2014 required before `vault create`. Amount in WOOD (min = swood.minOwnerStake, default 10000)."
|
|
494
496
|
).action(async (amountStr) => {
|
|
495
497
|
const amount = parseUnits(amountStr, 18);
|
|
496
498
|
await ensureWoodAllowance(amount);
|
|
@@ -564,7 +566,7 @@ var TEMPLATES = [
|
|
|
564
566
|
{
|
|
565
567
|
name: "Moonwell Supply",
|
|
566
568
|
key: "moonwell-supply",
|
|
567
|
-
description: "Supply tokens to Moonwell lending market
|
|
569
|
+
description: "Supply tokens to the Moonwell lending market",
|
|
568
570
|
addressKey: "MOONWELL_SUPPLY"
|
|
569
571
|
},
|
|
570
572
|
{
|
|
@@ -582,13 +584,13 @@ var TEMPLATES = [
|
|
|
582
584
|
{
|
|
583
585
|
name: "wstETH Moonwell Yield",
|
|
584
586
|
key: "wsteth-moonwell",
|
|
585
|
-
description: "WETH \u2192 wstETH \u2192 Moonwell \u2014
|
|
587
|
+
description: "WETH \u2192 wstETH \u2192 Moonwell \u2014 Lido staking plus lending",
|
|
586
588
|
addressKey: "WSTETH_MOONWELL"
|
|
587
589
|
},
|
|
588
590
|
{
|
|
589
591
|
name: "Mamo Yield",
|
|
590
592
|
key: "mamo-yield",
|
|
591
|
-
description: "Deposit into Mamo
|
|
593
|
+
description: "Deposit into Mamo \u2014 routes across Moonwell + Morpho vaults",
|
|
592
594
|
addressKey: "MAMO_YIELD"
|
|
593
595
|
},
|
|
594
596
|
{
|
|
@@ -940,7 +942,7 @@ function registerStrategyProposeCommands(strategy2) {
|
|
|
940
942
|
`--proposer ${proposer} is not a registered agent on ${vault}; cloneAndInitDeterministic and propose will both revert.`
|
|
941
943
|
)
|
|
942
944
|
);
|
|
943
|
-
console.error(chalk3.yellow(` Register first: sherwood
|
|
945
|
+
console.error(chalk3.yellow(` Register first: sherwood vault approve --wallet ${proposer}`));
|
|
944
946
|
process.exit(1);
|
|
945
947
|
}
|
|
946
948
|
if (paused) {
|
|
@@ -977,7 +979,7 @@ function registerStrategyProposeCommands(strategy2) {
|
|
|
977
979
|
process.exit(1);
|
|
978
980
|
}
|
|
979
981
|
if (!opts.agent) opts.agent = proposer;
|
|
980
|
-
const { parseDuration: parseDuration3, getGovernorOf: getGovernorOf2 } = await import("./governor-
|
|
982
|
+
const { parseDuration: parseDuration3, getGovernorOf: getGovernorOf2 } = await import("./governor-JNSWPJVQ.js");
|
|
981
983
|
const strategyDuration2 = parseDuration3(opts.duration);
|
|
982
984
|
const chainId = getChain().id;
|
|
983
985
|
try {
|
|
@@ -1048,7 +1050,7 @@ function registerStrategyProposeCommands(strategy2) {
|
|
|
1048
1050
|
console.error(
|
|
1049
1051
|
chalk3.red(
|
|
1050
1052
|
` Signer ${account.address} is not a registered agent on ${vault}.
|
|
1051
|
-
Register first via: sherwood
|
|
1053
|
+
Register first via: sherwood vault approve --wallet ${account.address}`
|
|
1052
1054
|
)
|
|
1053
1055
|
);
|
|
1054
1056
|
process.exit(1);
|
|
@@ -1208,9 +1210,9 @@ function registerStrategyProposeCommands(strategy2) {
|
|
|
1208
1210
|
console.error(chalk3.red("Missing --name or --duration. Use --write-calls to skip proposal submission."));
|
|
1209
1211
|
process.exit(1);
|
|
1210
1212
|
}
|
|
1211
|
-
const { propose: propose2 } = await import("./governor-
|
|
1212
|
-
const { pinJSON } = await import("./ipfs-
|
|
1213
|
-
const { parseDuration: parseDuration2 } = await import("./governor-
|
|
1213
|
+
const { propose: propose2 } = await import("./governor-JNSWPJVQ.js");
|
|
1214
|
+
const { pinJSON } = await import("./ipfs-M56BLMCW.js");
|
|
1215
|
+
const { parseDuration: parseDuration2 } = await import("./governor-JNSWPJVQ.js");
|
|
1214
1216
|
const strategyDuration = parseDuration2(opts.duration);
|
|
1215
1217
|
const metaSpinner = ora2("Pinning metadata to IPFS...").start();
|
|
1216
1218
|
let metadataURI;
|
|
@@ -1242,11 +1244,11 @@ function registerStrategyProposeCommands(strategy2) {
|
|
|
1242
1244
|
metadataURI = `data:application/json;base64,${Buffer.from(inline).toString("base64")}`;
|
|
1243
1245
|
}
|
|
1244
1246
|
try {
|
|
1245
|
-
const { getAgentFeeBps: getAgentFeeBps2 } = await import("./vault-
|
|
1247
|
+
const { getAgentFeeBps: getAgentFeeBps2 } = await import("./vault-HWJQJW5U.js");
|
|
1246
1248
|
const feeBps = await getAgentFeeBps2(vault);
|
|
1247
1249
|
console.log(
|
|
1248
1250
|
chalk3.yellow(
|
|
1249
|
-
` Agent fee for this proposal: ${Number(feeBps) / 100}% (the vault's current agentFeeBps). Run \`sherwood
|
|
1251
|
+
` Agent fee for this proposal: ${Number(feeBps) / 100}% (the vault's current agentFeeBps). Run \`sherwood vault set-agent-fee --bps <bps>\` first to change it.`
|
|
1250
1252
|
)
|
|
1251
1253
|
);
|
|
1252
1254
|
} catch {
|
|
@@ -1513,7 +1515,7 @@ function registerStrategyTemplateCommands(strategy2) {
|
|
|
1513
1515
|
let prices = [];
|
|
1514
1516
|
let priceSource = null;
|
|
1515
1517
|
try {
|
|
1516
|
-
const { getTokenPricesInAsset } = await import("./price-
|
|
1518
|
+
const { getTokenPricesInAsset } = await import("./price-YNPYE2EO.js");
|
|
1517
1519
|
prices = await getTokenPricesInAsset({
|
|
1518
1520
|
tokens: allocations.map((a, i) => ({
|
|
1519
1521
|
token: a.token,
|
|
@@ -1943,7 +1945,7 @@ function registerVeniceCommands(program2) {
|
|
|
1943
1945
|
console.log(chalk5.dim(` Key: ${apiKey.slice(0, 8)}...${apiKey.slice(-4)}`));
|
|
1944
1946
|
console.log(chalk5.dim(" Saved to ~/.sherwood/config.json"));
|
|
1945
1947
|
try {
|
|
1946
|
-
const { createVeniceProvisionAttestation, getEasScanUrl } = await import("./eas-
|
|
1948
|
+
const { createVeniceProvisionAttestation, getEasScanUrl } = await import("./eas-KMDAMLXW.js");
|
|
1947
1949
|
const attestation = await createVeniceProvisionAttestation(account.address);
|
|
1948
1950
|
if (attestation) {
|
|
1949
1951
|
console.log(chalk5.dim(` Attested: ${getEasScanUrl(attestation.uid)}`));
|
|
@@ -2299,7 +2301,7 @@ ${opts.prompt}`;
|
|
|
2299
2301
|
console.log(chalk5.dim(`Model: ${result.model} | Tokens: ${result.usage.promptTokens} in, ${result.usage.completionTokens} out, ${result.usage.totalTokens} total`));
|
|
2300
2302
|
}
|
|
2301
2303
|
try {
|
|
2302
|
-
const { createVeniceInferenceAttestation, getEasScanUrl } = await import("./eas-
|
|
2304
|
+
const { createVeniceInferenceAttestation, getEasScanUrl } = await import("./eas-KMDAMLXW.js");
|
|
2303
2305
|
const { keccak256: keccak2562, toHex, isAddress: isAddr } = await import("viem");
|
|
2304
2306
|
const { getChainContracts: getChainContracts2 } = await import("./config-ZGFS4I7K.js");
|
|
2305
2307
|
const { getChain: getActiveChain } = await import("./network-FEHRFDPJ.js");
|
|
@@ -3298,7 +3300,7 @@ function printSimulationResult(result, callType) {
|
|
|
3298
3300
|
}
|
|
3299
3301
|
async function sendSimulationAlert(subdomain, proposalId, vault, execResult, settleResult) {
|
|
3300
3302
|
try {
|
|
3301
|
-
const xmtp = await import("./xmtp-
|
|
3303
|
+
const xmtp = await import("./xmtp-KW73BGVO.js");
|
|
3302
3304
|
const { getAccount: getAccount2 } = await import("./client-3SE632Q2.js");
|
|
3303
3305
|
const group = await xmtp.getGroup("", subdomain);
|
|
3304
3306
|
const allRisks = [...execResult.risks, ...settleResult?.risks ?? []];
|
|
@@ -4774,7 +4776,7 @@ function registerProposalCommands(program2) {
|
|
|
4774
4776
|
process.exit(1);
|
|
4775
4777
|
}
|
|
4776
4778
|
});
|
|
4777
|
-
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
|
|
4779
|
+
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) => {
|
|
4778
4780
|
try {
|
|
4779
4781
|
let vault;
|
|
4780
4782
|
let executeCalls;
|
|
@@ -5386,14 +5388,78 @@ function registerGovernorCommands(program2) {
|
|
|
5386
5388
|
succeed: (v) => `Cooldown period updated to ${v}s (reverts if the vault has an open proposal).`,
|
|
5387
5389
|
failText: "Failed to set cooldown"
|
|
5388
5390
|
});
|
|
5389
|
-
|
|
5390
|
-
const
|
|
5391
|
+
const parseSplitLeg = (raw, label) => {
|
|
5392
|
+
const v = Number(parseBigIntArg(String(raw), label));
|
|
5393
|
+
if (v > 1e4) {
|
|
5394
|
+
console.error(chalk10.red(`--${label} must be <= 10000 bps, got ${v}`));
|
|
5395
|
+
process.exit(1);
|
|
5396
|
+
}
|
|
5397
|
+
return v;
|
|
5398
|
+
};
|
|
5399
|
+
const requireSum = (legs) => {
|
|
5400
|
+
const sum = Object.values(legs).reduce((a, b) => a + b, 0);
|
|
5401
|
+
if (sum !== 1e4) {
|
|
5402
|
+
const parts = Object.entries(legs).map(([k, v]) => `--${k} ${v}`).join(" ");
|
|
5403
|
+
console.error(
|
|
5404
|
+
chalk10.red(`split legs must sum to 10000 bps, got ${sum} (${parts})`)
|
|
5405
|
+
);
|
|
5406
|
+
process.exit(1);
|
|
5407
|
+
}
|
|
5408
|
+
};
|
|
5409
|
+
const fmtSplit = (legs) => Object.entries(legs).map(([k, v]) => `${k} ${Number(v) / 100}%`).join(" / ");
|
|
5410
|
+
governor.command("set-mgmt-split").description("Set the management-fee split on ProtocolConfig (protocol owner only; legs sum to 10000 bps)").requiredOption("--agent <bps>", "Agent share in bps (e.g. 6000 = 60%)").requiredOption("--protocol <bps>", "Protocol share in bps").requiredOption("--guardian <bps>", "Guardian share in bps").action(async (opts) => {
|
|
5411
|
+
const s = {
|
|
5412
|
+
agentBps: parseSplitLeg(opts.agent, "agent"),
|
|
5413
|
+
protocolBps: parseSplitLeg(opts.protocol, "protocol"),
|
|
5414
|
+
guardianBps: parseSplitLeg(opts.guardian, "guardian")
|
|
5415
|
+
};
|
|
5416
|
+
requireSum({ agent: s.agentBps, protocol: s.protocolBps, guardian: s.guardianBps });
|
|
5417
|
+
if (isCalldataOnly()) {
|
|
5418
|
+
try {
|
|
5419
|
+
emitCalldata(
|
|
5420
|
+
encodeMgmtSplit(
|
|
5421
|
+
{ protocolConfig: await getProtocolConfigAddress(), ...s },
|
|
5422
|
+
getChain().id
|
|
5423
|
+
)
|
|
5424
|
+
);
|
|
5425
|
+
} catch (err) {
|
|
5426
|
+
console.error(chalk10.red(formatContractError(err)));
|
|
5427
|
+
process.exit(1);
|
|
5428
|
+
}
|
|
5429
|
+
return;
|
|
5430
|
+
}
|
|
5431
|
+
const spinner = ora8("Setting management-fee split...").start();
|
|
5432
|
+
try {
|
|
5433
|
+
const hash = await setMgmtSplit(s);
|
|
5434
|
+
const configAddress = await getProtocolConfigAddress();
|
|
5435
|
+
spinner.succeed(
|
|
5436
|
+
G4(`Management-fee split updated to ${fmtSplit({ agent: s.agentBps, protocol: s.protocolBps, guardian: s.guardianBps })} on ProtocolConfig (${configAddress}). In-flight proposals keep their propose-time snapshot.`)
|
|
5437
|
+
);
|
|
5438
|
+
console.log(DIM4(` ${getExplorerUrl(hash)}`));
|
|
5439
|
+
} catch (err) {
|
|
5440
|
+
spinner.fail("Failed to set management-fee split");
|
|
5441
|
+
console.error(chalk10.red(formatContractError(err)));
|
|
5442
|
+
process.exit(1);
|
|
5443
|
+
}
|
|
5444
|
+
});
|
|
5445
|
+
governor.command("set-perf-split").description("Set the performance-fee split on ProtocolConfig (protocol owner only; legs sum to 10000 bps)").requiredOption("--agent <bps>", "Agent share in bps (e.g. 5000 = 50%)").requiredOption("--protocol <bps>", "Protocol share in bps").requiredOption("--guardian <bps>", "Guardian share in bps").requiredOption("--owner <bps>", "Vault-owner share in bps").action(async (opts) => {
|
|
5446
|
+
const s = {
|
|
5447
|
+
agentBps: parseSplitLeg(opts.agent, "agent"),
|
|
5448
|
+
protocolBps: parseSplitLeg(opts.protocol, "protocol"),
|
|
5449
|
+
guardianBps: parseSplitLeg(opts.guardian, "guardian"),
|
|
5450
|
+
ownerBps: parseSplitLeg(opts.owner, "owner")
|
|
5451
|
+
};
|
|
5452
|
+
requireSum({
|
|
5453
|
+
agent: s.agentBps,
|
|
5454
|
+
protocol: s.protocolBps,
|
|
5455
|
+
guardian: s.guardianBps,
|
|
5456
|
+
owner: s.ownerBps
|
|
5457
|
+
});
|
|
5391
5458
|
if (isCalldataOnly()) {
|
|
5392
5459
|
try {
|
|
5393
|
-
const value = parseBigIntArg(rawValue, "bps");
|
|
5394
5460
|
emitCalldata(
|
|
5395
|
-
|
|
5396
|
-
{ protocolConfig: await getProtocolConfigAddress(),
|
|
5461
|
+
encodePerfSplit(
|
|
5462
|
+
{ protocolConfig: await getProtocolConfigAddress(), ...s },
|
|
5397
5463
|
getChain().id
|
|
5398
5464
|
)
|
|
5399
5465
|
);
|
|
@@ -5403,16 +5469,16 @@ function registerGovernorCommands(program2) {
|
|
|
5403
5469
|
}
|
|
5404
5470
|
return;
|
|
5405
5471
|
}
|
|
5406
|
-
const spinner = ora8("Setting
|
|
5472
|
+
const spinner = ora8("Setting performance-fee split...").start();
|
|
5407
5473
|
try {
|
|
5408
|
-
const hash = await
|
|
5474
|
+
const hash = await setPerfSplit(s);
|
|
5409
5475
|
const configAddress = await getProtocolConfigAddress();
|
|
5410
5476
|
spinner.succeed(
|
|
5411
|
-
G4(`
|
|
5477
|
+
G4(`Performance-fee split updated to ${fmtSplit({ agent: s.agentBps, protocol: s.protocolBps, guardian: s.guardianBps, owner: s.ownerBps })} on ProtocolConfig (${configAddress}). In-flight proposals keep their propose-time snapshot.`)
|
|
5412
5478
|
);
|
|
5413
5479
|
console.log(DIM4(` ${getExplorerUrl(hash)}`));
|
|
5414
5480
|
} catch (err) {
|
|
5415
|
-
spinner.fail("Failed to set
|
|
5481
|
+
spinner.fail("Failed to set performance-fee split");
|
|
5416
5482
|
console.error(chalk10.red(formatContractError(err)));
|
|
5417
5483
|
process.exit(1);
|
|
5418
5484
|
}
|
|
@@ -7985,9 +8051,9 @@ try {
|
|
|
7985
8051
|
} catch {
|
|
7986
8052
|
}
|
|
7987
8053
|
var require2 = createRequire(import.meta.url);
|
|
7988
|
-
var CLI_VERSION = "0.
|
|
8054
|
+
var CLI_VERSION = "0.86.1";
|
|
7989
8055
|
async function loadXmtp() {
|
|
7990
|
-
return import("./xmtp-
|
|
8056
|
+
return import("./xmtp-KW73BGVO.js");
|
|
7991
8057
|
}
|
|
7992
8058
|
async function loadCron() {
|
|
7993
8059
|
return import("./cron-E3UAZF5B.js");
|
|
@@ -8007,7 +8073,7 @@ function validateAddress(value, name) {
|
|
|
8007
8073
|
}
|
|
8008
8074
|
function fundShareUrl(subdomain, refParam) {
|
|
8009
8075
|
const host = isTestnet() ? "https://testnet.sherwood.sh" : "https://sherwood.sh";
|
|
8010
|
-
return `${host}/
|
|
8076
|
+
return `${host}/vault/${subdomain}${refParam}`;
|
|
8011
8077
|
}
|
|
8012
8078
|
function resolveVault(opts) {
|
|
8013
8079
|
if (opts.vault) {
|
|
@@ -8015,7 +8081,22 @@ function resolveVault(opts) {
|
|
|
8015
8081
|
}
|
|
8016
8082
|
}
|
|
8017
8083
|
var program = new Command();
|
|
8018
|
-
program.name("sherwood").description("CLI for agent-managed
|
|
8084
|
+
program.name("sherwood").description("CLI for agent-managed onchain vaults").version(CLI_VERSION).configureHelp({
|
|
8085
|
+
subcommandTerm: (cmd) => {
|
|
8086
|
+
const args = cmd.registeredArguments.map((arg) => {
|
|
8087
|
+
const name = arg.name() + (arg.variadic ? "..." : "");
|
|
8088
|
+
return arg.required ? `<${name}>` : `[${name}]`;
|
|
8089
|
+
}).join(" ");
|
|
8090
|
+
return cmd.name() + (cmd.options.length ? " [options]" : "") + (args ? ` ${args}` : "");
|
|
8091
|
+
},
|
|
8092
|
+
commandUsage: (cmd) => {
|
|
8093
|
+
const names = [cmd.name()];
|
|
8094
|
+
for (let ancestor = cmd.parent; ancestor; ancestor = ancestor.parent) {
|
|
8095
|
+
names.unshift(ancestor.name());
|
|
8096
|
+
}
|
|
8097
|
+
return `${names.join(" ")} ${cmd.usage()}`;
|
|
8098
|
+
}
|
|
8099
|
+
}).addOption(
|
|
8019
8100
|
new Option(
|
|
8020
8101
|
"--chain <network>",
|
|
8021
8102
|
"Target network (default: robinhood-fork, chain 9994663 \u2014 where the product lives; robinhood-testnet is chain 46630)"
|
|
@@ -8029,11 +8110,21 @@ program.name("sherwood").description("CLI for agent-managed investment funds").v
|
|
|
8029
8110
|
setCalldataOnly(Boolean(opts.calldataOnly));
|
|
8030
8111
|
setNetwork(opts.chain);
|
|
8031
8112
|
});
|
|
8032
|
-
var
|
|
8033
|
-
|
|
8113
|
+
var LEGACY_GROUP_ALIASES = ["fund", "syndicate"];
|
|
8114
|
+
var vaultCmd = program.command("vault").alias("fund").alias("syndicate").description("Vaults \u2014 launch, inspect, join, and manage deposits").hook("preSubcommand", () => {
|
|
8115
|
+
const typed = process.argv.slice(2).find((arg) => arg === "vault" || LEGACY_GROUP_ALIASES.includes(arg));
|
|
8116
|
+
if (typed && typed !== "vault") {
|
|
8117
|
+
console.error(
|
|
8118
|
+
chalk17.dim(
|
|
8119
|
+
`note: 'sherwood ${typed}' is now 'sherwood vault' \u2014 the old name keeps working for now`
|
|
8120
|
+
)
|
|
8121
|
+
);
|
|
8122
|
+
}
|
|
8123
|
+
});
|
|
8124
|
+
vaultCmd.command("create").description("Launch a new vault via the factory (interactive)").option("--subdomain <name>", "ENS subdomain (skip prompt)").option("--name <name>", "Vault name (skip prompt)").option("--agent-id <id>", "ERC-8004 agent identity token ID (skip prompt)").option("--asset <symbol-or-address>", "Vault asset: USDC, WETH, or a token address").option("--description <text>", "Short description").option("--metadata-uri <uri>", "Override metadata URI (skip IPFS upload)").option("--open-deposits", "Allow anyone to deposit (default: whitelist only)").option("--public-chat", "Enable dashboard spectator mode", false).option("-y, --yes", "Skip confirmation prompt (non-interactive mode)", false).action(async (opts) => {
|
|
8034
8125
|
try {
|
|
8035
8126
|
console.log();
|
|
8036
|
-
console.log(LABEL5(" \u25C6
|
|
8127
|
+
console.log(LABEL5(" \u25C6 Launch Vault"));
|
|
8037
8128
|
SEP6();
|
|
8038
8129
|
if (!isCalldataOnly()) {
|
|
8039
8130
|
const wallet = getAccount();
|
|
@@ -8046,7 +8137,7 @@ fund.command("create").description("Create a new fund via the factory (interacti
|
|
|
8046
8137
|
const name = opts.name || (nonInteractive ? (() => {
|
|
8047
8138
|
throw new Error("--name is required in non-interactive mode (-y)");
|
|
8048
8139
|
})() : await input({
|
|
8049
|
-
message: G6("
|
|
8140
|
+
message: G6("Vault name"),
|
|
8050
8141
|
validate: (v) => v.length > 0 || "Name is required"
|
|
8051
8142
|
}));
|
|
8052
8143
|
const subdomain = opts.subdomain || (nonInteractive ? name.toLowerCase().replace(/\s+/g, "-").replace(/[^a-z0-9-]/g, "") : await input({
|
|
@@ -8054,9 +8145,9 @@ fund.command("create").description("Create a new fund via the factory (interacti
|
|
|
8054
8145
|
default: name.toLowerCase().replace(/\s+/g, "-").replace(/[^a-z0-9-]/g, ""),
|
|
8055
8146
|
validate: (v) => v.length >= 3 || "Must be at least 3 characters"
|
|
8056
8147
|
}));
|
|
8057
|
-
const description = opts.description || (nonInteractive ? `${name} \u2014 a Sherwood
|
|
8148
|
+
const description = opts.description || (nonInteractive ? `${name} \u2014 a Sherwood vault` : await input({
|
|
8058
8149
|
message: G6("Description"),
|
|
8059
|
-
default: `${name} \u2014 a Sherwood
|
|
8150
|
+
default: `${name} \u2014 a Sherwood vault`
|
|
8060
8151
|
}));
|
|
8061
8152
|
const agentIdStr = opts.agentId || (savedAgentId ? nonInteractive ? String(savedAgentId) : await input({ message: G6("Agent ID (ERC-8004)"), default: String(savedAgentId) }) : nonInteractive ? "0" : await input({ message: G6("Agent ID (ERC-8004)"), validate: (v) => /^\d+$/.test(v) || "Must be a number" }));
|
|
8062
8153
|
const openDeposits = opts.openDeposits !== void 0 ? opts.openDeposits : nonInteractive ? false : await confirm({
|
|
@@ -8128,7 +8219,7 @@ fund.command("create").description("Create a new fund via the factory (interacti
|
|
|
8128
8219
|
console.log(W6(` Open deposits: ${openDeposits ? chalk17.yellow("yes (anyone can deposit)") : G6("no (whitelist)")}`));
|
|
8129
8220
|
SEP6();
|
|
8130
8221
|
if (!nonInteractive) {
|
|
8131
|
-
const go = await confirm({ message: G6("Deploy
|
|
8222
|
+
const go = await confirm({ message: G6("Deploy vault?"), default: true });
|
|
8132
8223
|
if (!go) {
|
|
8133
8224
|
console.log(DIM6(" Cancelled."));
|
|
8134
8225
|
return;
|
|
@@ -8180,12 +8271,12 @@ fund.command("create").description("Create a new fund via the factory (interacti
|
|
|
8180
8271
|
const callerAddress = getAccount().address.toLowerCase();
|
|
8181
8272
|
if (existingInfo.creator.toLowerCase() !== callerAddress) {
|
|
8182
8273
|
console.error(chalk17.red(`
|
|
8183
|
-
\u2716 Subdomain '${subdomain}' is already taken by another
|
|
8274
|
+
\u2716 Subdomain '${subdomain}' is already taken by another vault.
|
|
8184
8275
|
`));
|
|
8185
8276
|
process.exit(1);
|
|
8186
8277
|
}
|
|
8187
8278
|
console.log(chalk17.yellow(`
|
|
8188
|
-
\u26A0
|
|
8279
|
+
\u26A0 Vault '${subdomain}' already exists \u2014 resuming setup...
|
|
8189
8280
|
`));
|
|
8190
8281
|
const spinner2 = ora9({ text: W6("Resuming setup..."), color: "green" }).start();
|
|
8191
8282
|
const chainId2 = getChain().id;
|
|
@@ -8228,7 +8319,7 @@ fund.command("create").description("Create a new fund via the factory (interacti
|
|
|
8228
8319
|
}
|
|
8229
8320
|
spinner2.stop();
|
|
8230
8321
|
console.log();
|
|
8231
|
-
console.log(LABEL5(" \u25C6
|
|
8322
|
+
console.log(LABEL5(" \u25C6 Vault Setup Resumed"));
|
|
8232
8323
|
SEP6();
|
|
8233
8324
|
console.log(W6(` ID: ${G6(`#${existingId}`)}`));
|
|
8234
8325
|
console.log(W6(` Vault: ${G6(existingInfo.vault)}`));
|
|
@@ -8237,7 +8328,7 @@ fund.command("create").description("Create a new fund via the factory (interacti
|
|
|
8237
8328
|
const refParam2 = getAgentId() ? `?ref=${getAgentId()}` : "";
|
|
8238
8329
|
console.log(W6(` Share: ${G6(fundShareUrl(subdomain, refParam2))}`));
|
|
8239
8330
|
SEP6();
|
|
8240
|
-
console.log(G6(" \u2713
|
|
8331
|
+
console.log(G6(" \u2713 Vault saved to ~/.sherwood/config.json (set as primary)"));
|
|
8241
8332
|
console.log();
|
|
8242
8333
|
return;
|
|
8243
8334
|
}
|
|
@@ -8266,7 +8357,7 @@ fund.command("create").description("Create a new fund via the factory (interacti
|
|
|
8266
8357
|
// agentAddress = creator EOA (direct execution)
|
|
8267
8358
|
);
|
|
8268
8359
|
} catch (regErr) {
|
|
8269
|
-
console.warn(chalk17.yellow("\n \u26A0 Could not auto-register creator as agent \u2014 register manually with `
|
|
8360
|
+
console.warn(chalk17.yellow("\n \u26A0 Could not auto-register creator as agent \u2014 register manually with `vault add`"));
|
|
8270
8361
|
}
|
|
8271
8362
|
spinner.text = W6("Setting up chat...");
|
|
8272
8363
|
try {
|
|
@@ -8295,7 +8386,7 @@ fund.command("create").description("Create a new fund via the factory (interacti
|
|
|
8295
8386
|
}
|
|
8296
8387
|
spinner.stop();
|
|
8297
8388
|
console.log();
|
|
8298
|
-
console.log(LABEL5(" \u25C6
|
|
8389
|
+
console.log(LABEL5(" \u25C6 Vault Launched"));
|
|
8299
8390
|
SEP6();
|
|
8300
8391
|
console.log(W6(` ID: ${G6(`#${result.fundId}`)}`));
|
|
8301
8392
|
console.log(W6(` Vault: ${G6(result.vault)}`));
|
|
@@ -8306,7 +8397,7 @@ fund.command("create").description("Create a new fund via the factory (interacti
|
|
|
8306
8397
|
const refParam = getAgentId() ? `?ref=${getAgentId()}` : "";
|
|
8307
8398
|
console.log(W6(` Share: ${G6(fundShareUrl(subdomain, refParam))}`));
|
|
8308
8399
|
SEP6();
|
|
8309
|
-
console.log(G6(" \u2713
|
|
8400
|
+
console.log(G6(" \u2713 Vault saved to ~/.sherwood/config.json (set as primary)"));
|
|
8310
8401
|
console.log();
|
|
8311
8402
|
} catch (err) {
|
|
8312
8403
|
console.error(chalk17.red(`
|
|
@@ -8314,8 +8405,8 @@ fund.command("create").description("Create a new fund via the factory (interacti
|
|
|
8314
8405
|
process.exit(1);
|
|
8315
8406
|
}
|
|
8316
8407
|
});
|
|
8317
|
-
|
|
8318
|
-
const spinner = ora9("Loading
|
|
8408
|
+
vaultCmd.command("list").description("List active vaults (queries subgraph, falls back to on-chain)").option("--creator <address>", "Filter by creator address").option("--all-chains", "Aggregate active vaults across all supported chains (on-chain only)").action(async (opts) => {
|
|
8409
|
+
const spinner = ora9("Loading vaults...").start();
|
|
8319
8410
|
try {
|
|
8320
8411
|
let funds = [];
|
|
8321
8412
|
if (opts.allChains) {
|
|
@@ -8358,11 +8449,11 @@ fund.command("list").description("List active funds (queries subgraph, falls bac
|
|
|
8358
8449
|
}
|
|
8359
8450
|
spinner.stop();
|
|
8360
8451
|
if (funds.length === 0) {
|
|
8361
|
-
console.log(chalk17.dim("No active
|
|
8452
|
+
console.log(chalk17.dim("No active vaults found."));
|
|
8362
8453
|
return;
|
|
8363
8454
|
}
|
|
8364
8455
|
console.log();
|
|
8365
|
-
console.log(chalk17.bold(`Active
|
|
8456
|
+
console.log(chalk17.bold(`Active Vaults (${funds.length})`));
|
|
8366
8457
|
if (!process.env.SUBGRAPH_URL && !opts.allChains) {
|
|
8367
8458
|
console.log(chalk17.dim(" (Set SUBGRAPH_URL for faster indexed queries)"));
|
|
8368
8459
|
}
|
|
@@ -8388,13 +8479,35 @@ fund.command("list").description("List active funds (queries subgraph, falls bac
|
|
|
8388
8479
|
console.log();
|
|
8389
8480
|
}
|
|
8390
8481
|
} catch (err) {
|
|
8391
|
-
spinner.fail("Failed to load
|
|
8482
|
+
spinner.fail("Failed to load vaults");
|
|
8392
8483
|
console.error(chalk17.red(formatContractError(err)));
|
|
8393
8484
|
process.exit(1);
|
|
8394
8485
|
}
|
|
8395
8486
|
});
|
|
8396
|
-
|
|
8397
|
-
|
|
8487
|
+
vaultCmd.command("info").description("Display vault details by ID or subdomain (omit the ID to read the configured vault)").argument("[id]", "Vault ID or subdomain name (default: the vault from --vault or config)").option("--vault <address>", "Vault address (default: from config)").action(async (idStr, opts) => {
|
|
8488
|
+
if (!idStr) {
|
|
8489
|
+
resolveVault(opts);
|
|
8490
|
+
const spinner2 = ora9("Loading vault info...").start();
|
|
8491
|
+
try {
|
|
8492
|
+
const info = await getVaultInfo();
|
|
8493
|
+
spinner2.stop();
|
|
8494
|
+
console.log();
|
|
8495
|
+
console.log(chalk17.bold("Vault Info"));
|
|
8496
|
+
console.log(chalk17.dim("\u2500".repeat(40)));
|
|
8497
|
+
console.log(` Address: ${info.address}`);
|
|
8498
|
+
console.log(` Total Assets: ${info.totalAssets}`);
|
|
8499
|
+
console.log(` Agent Count: ${info.agentCount}`);
|
|
8500
|
+
console.log(` Redemptions Locked: ${info.redemptionsLocked}`);
|
|
8501
|
+
console.log(` Management Fee: ${Number(info.managementFeeBps) / 100}%`);
|
|
8502
|
+
console.log();
|
|
8503
|
+
} catch (err) {
|
|
8504
|
+
spinner2.fail("Failed to load vault info");
|
|
8505
|
+
console.error(chalk17.red(formatContractError(err)));
|
|
8506
|
+
process.exit(1);
|
|
8507
|
+
}
|
|
8508
|
+
return;
|
|
8509
|
+
}
|
|
8510
|
+
const spinner = ora9("Loading vault info...").start();
|
|
8398
8511
|
try {
|
|
8399
8512
|
let id;
|
|
8400
8513
|
let crossChainHint = null;
|
|
@@ -8409,7 +8522,7 @@ fund.command("info").description("Display fund details by ID or subdomain").argu
|
|
|
8409
8522
|
spinner.text = `Searching across chains...`;
|
|
8410
8523
|
const hits = await searchFundAcrossChains(idStr);
|
|
8411
8524
|
if (hits.length === 0) {
|
|
8412
|
-
spinner.fail(`
|
|
8525
|
+
spinner.fail(`Vault "${idStr}" not found on any supported chain`);
|
|
8413
8526
|
process.exit(1);
|
|
8414
8527
|
}
|
|
8415
8528
|
const active = getNetwork();
|
|
@@ -8430,16 +8543,16 @@ fund.command("info").description("Display fund details by ID or subdomain").argu
|
|
|
8430
8543
|
if (crossChainHint) {
|
|
8431
8544
|
const others = crossChainHint.others.length > 0 ? ` (also on: ${crossChainHint.others.join(", ")})` : "";
|
|
8432
8545
|
console.log(chalk17.yellow(` Found on chain: ${chalk17.bold(crossChainHint.network)}${others}`));
|
|
8433
|
-
console.log(chalk17.dim(` Re-run with --chain ${crossChainHint.network} to interact with this
|
|
8546
|
+
console.log(chalk17.dim(` Re-run with --chain ${crossChainHint.network} to interact with this vault.`));
|
|
8434
8547
|
console.log();
|
|
8435
8548
|
}
|
|
8436
8549
|
if (!info.vault || info.vault === "0x0000000000000000000000000000000000000000") {
|
|
8437
|
-
console.log(chalk17.red(`
|
|
8550
|
+
console.log(chalk17.red(`Vault #${id} not found.`));
|
|
8438
8551
|
process.exit(1);
|
|
8439
8552
|
}
|
|
8440
8553
|
const date = new Date(Number(info.createdAt) * 1e3).toLocaleDateString();
|
|
8441
8554
|
console.log();
|
|
8442
|
-
console.log(chalk17.bold(`
|
|
8555
|
+
console.log(chalk17.bold(`Vault #${info.id}`));
|
|
8443
8556
|
console.log(chalk17.dim("\u2500".repeat(40)));
|
|
8444
8557
|
if (info.subdomain) {
|
|
8445
8558
|
console.log(` ENS: ${chalk17.bold(`${info.subdomain}.sherwoodagent.eth`)}`);
|
|
@@ -8467,20 +8580,20 @@ fund.command("info").description("Display fund details by ID or subdomain").argu
|
|
|
8467
8580
|
console.log(` Management Fee: ${Number(vaultInfo.managementFeeBps) / 100}%`);
|
|
8468
8581
|
console.log();
|
|
8469
8582
|
} catch (err) {
|
|
8470
|
-
spinner.fail("Failed to load
|
|
8583
|
+
spinner.fail("Failed to load vault info");
|
|
8471
8584
|
console.error(chalk17.red(formatContractError(err)));
|
|
8472
8585
|
process.exit(1);
|
|
8473
8586
|
}
|
|
8474
8587
|
});
|
|
8475
|
-
|
|
8476
|
-
const spinner = ora9({ text: W6("Loading
|
|
8588
|
+
vaultCmd.command("update-metadata").description("Update vault metadata (creator only)").requiredOption("--id <id>", "Vault ID").option("--name <name>", "Vault name").option("--description <text>", "Short description").option("--uri <uri>", "Direct metadata URI (skips IPFS upload)").action(async (opts) => {
|
|
8589
|
+
const spinner = ora9({ text: W6("Loading vault..."), color: "green" }).start();
|
|
8477
8590
|
try {
|
|
8478
8591
|
const fundId = BigInt(opts.id);
|
|
8479
8592
|
let metadataURI = opts.uri;
|
|
8480
8593
|
if (!metadataURI) {
|
|
8481
8594
|
const info = await getFund(fundId);
|
|
8482
8595
|
if (!info.vault || info.vault === "0x0000000000000000000000000000000000000000") {
|
|
8483
|
-
spinner.fail(`
|
|
8596
|
+
spinner.fail(`Vault #${opts.id} not found.`);
|
|
8484
8597
|
process.exit(1);
|
|
8485
8598
|
}
|
|
8486
8599
|
spinner.text = W6("Fetching current metadata...");
|
|
@@ -8515,7 +8628,7 @@ fund.command("update-metadata").description("Update fund metadata (creator only)
|
|
|
8515
8628
|
process.exit(1);
|
|
8516
8629
|
}
|
|
8517
8630
|
});
|
|
8518
|
-
|
|
8631
|
+
vaultCmd.command("approve-depositor").description("Approve an address to deposit (owner only)").option("--vault <address>", "Vault address (default: from config)").requiredOption("--depositor <address>", "Address to approve").action(async (opts) => {
|
|
8519
8632
|
resolveVault(opts);
|
|
8520
8633
|
const depositor = validateAddress(opts.depositor, "depositor");
|
|
8521
8634
|
if (isCalldataOnly()) {
|
|
@@ -8538,7 +8651,7 @@ fund.command("approve-depositor").description("Approve an address to deposit (ow
|
|
|
8538
8651
|
process.exit(1);
|
|
8539
8652
|
}
|
|
8540
8653
|
});
|
|
8541
|
-
|
|
8654
|
+
vaultCmd.command("remove-depositor").description("Remove an address from the depositor whitelist (owner only)").option("--vault <address>", "Vault address (default: from config)").requiredOption("--depositor <address>", "Address to remove").action(async (opts) => {
|
|
8542
8655
|
resolveVault(opts);
|
|
8543
8656
|
const spinner = ora9("Removing depositor...").start();
|
|
8544
8657
|
try {
|
|
@@ -8552,7 +8665,7 @@ fund.command("remove-depositor").description("Remove an address from the deposit
|
|
|
8552
8665
|
process.exit(1);
|
|
8553
8666
|
}
|
|
8554
8667
|
});
|
|
8555
|
-
|
|
8668
|
+
vaultCmd.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(
|
|
8556
8669
|
"--bps <bps>",
|
|
8557
8670
|
`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.`
|
|
8558
8671
|
).action(async (opts) => {
|
|
@@ -8571,7 +8684,7 @@ fund.command("set-agent-fee").description("Set the vault's agent performance fee
|
|
|
8571
8684
|
process.exit(1);
|
|
8572
8685
|
}
|
|
8573
8686
|
});
|
|
8574
|
-
|
|
8687
|
+
vaultCmd.command("add").description("Register an agent on a vault (creator only)").option("--vault <address>", "Vault address (default: from config)").option("--agent-id <id>", "Agent's ERC-8004 identity token ID (resolved from wallet if omitted)").requiredOption("--wallet <address>", "Agent wallet address").action(async (opts) => {
|
|
8575
8688
|
if (isCalldataOnly()) {
|
|
8576
8689
|
resolveVault(opts);
|
|
8577
8690
|
const agentWallet = validateAddress(opts.wallet, "wallet");
|
|
@@ -8602,7 +8715,7 @@ fund.command("add").description("Register an agent on a fund vault (creator only
|
|
|
8602
8715
|
const { creator, subdomain } = await resolveVaultFund(vaultAddress);
|
|
8603
8716
|
const callerAddress = getAccount().address.toLowerCase();
|
|
8604
8717
|
if (creator.toLowerCase() !== callerAddress) {
|
|
8605
|
-
spinner.fail("Only the
|
|
8718
|
+
spinner.fail("Only the vault creator can add agents");
|
|
8606
8719
|
process.exit(1);
|
|
8607
8720
|
}
|
|
8608
8721
|
const agentWallet = validateAddress(opts.wallet, "wallet");
|
|
@@ -8611,7 +8724,7 @@ fund.command("add").description("Register an agent on a fund vault (creator only
|
|
|
8611
8724
|
agentId = BigInt(opts.agentId);
|
|
8612
8725
|
} else {
|
|
8613
8726
|
spinner.text = "Looking up ERC-8004 identity from wallet...";
|
|
8614
|
-
const { lookupAgentIdByWallet } = await import("./identity-
|
|
8727
|
+
const { lookupAgentIdByWallet } = await import("./identity-ATWV2O7Y.js");
|
|
8615
8728
|
const resolved = await lookupAgentIdByWallet(agentWallet);
|
|
8616
8729
|
if (resolved === null) {
|
|
8617
8730
|
spinner.fail("Agent wallet does not own an ERC-8004 identity NFT");
|
|
@@ -8647,11 +8760,11 @@ fund.command("add").description("Register an agent on a fund vault (creator only
|
|
|
8647
8760
|
process.exit(1);
|
|
8648
8761
|
}
|
|
8649
8762
|
});
|
|
8650
|
-
|
|
8763
|
+
vaultCmd.command("share").description("Print the shareable dashboard URL for your vault").option("--subdomain <name>", "Vault subdomain (default: primary)").action(async (opts) => {
|
|
8651
8764
|
try {
|
|
8652
8765
|
const subdomain = opts.subdomain || getPrimaryFund(getChain().id)?.subdomain;
|
|
8653
8766
|
if (!subdomain) {
|
|
8654
|
-
console.error(chalk17.red(" No
|
|
8767
|
+
console.error(chalk17.red(" No vault configured. Pass --subdomain <name> or run 'vault create/join' first."));
|
|
8655
8768
|
process.exit(1);
|
|
8656
8769
|
}
|
|
8657
8770
|
const fundInfo = await resolveFund(subdomain);
|
|
@@ -8659,12 +8772,12 @@ fund.command("share").description("Print the shareable dashboard URL for your fu
|
|
|
8659
8772
|
const refParam = agentId ? `?ref=${agentId}` : "";
|
|
8660
8773
|
const dashboardUrl = fundShareUrl(subdomain, refParam);
|
|
8661
8774
|
console.log();
|
|
8662
|
-
console.log(LABEL5(" \u25C6 Share Your
|
|
8775
|
+
console.log(LABEL5(" \u25C6 Share Your Vault"));
|
|
8663
8776
|
SEP6();
|
|
8664
8777
|
console.log(W6(` Dashboard: ${G6(dashboardUrl)}`));
|
|
8665
8778
|
console.log(W6(` ENS: ${DIM6(`${subdomain}.sherwoodagent.eth`)}`));
|
|
8666
8779
|
console.log(W6(` Vault: ${DIM6(fundInfo.vault)}`));
|
|
8667
|
-
console.log(W6(` Join CLI: ${DIM6(`sherwood
|
|
8780
|
+
console.log(W6(` Join CLI: ${DIM6(`sherwood vault join --subdomain ${subdomain}`)}`));
|
|
8668
8781
|
SEP6();
|
|
8669
8782
|
try {
|
|
8670
8783
|
const { exec } = await import("child_process");
|
|
@@ -8682,12 +8795,12 @@ fund.command("share").description("Print the shareable dashboard URL for your fu
|
|
|
8682
8795
|
process.exit(1);
|
|
8683
8796
|
}
|
|
8684
8797
|
});
|
|
8685
|
-
|
|
8686
|
-
const spinner = ora9("Resolving
|
|
8798
|
+
vaultCmd.command("join").description("Request to join a vault (creates an EAS attestation)").option("--subdomain <name>", "Vault subdomain to join").option("--ref <agentId>", "Referrer agent ID (from invite link)").option("--message <text>", "Message to the creator", "Requesting to join your vault").action(async (opts) => {
|
|
8799
|
+
const spinner = ora9("Resolving vault...").start();
|
|
8687
8800
|
try {
|
|
8688
8801
|
const subdomain = opts.subdomain || getPrimaryFund(getChain().id)?.subdomain;
|
|
8689
8802
|
if (!subdomain) {
|
|
8690
|
-
spinner.fail("No
|
|
8803
|
+
spinner.fail("No vault configured. Pass --subdomain <name> or run 'vault create' first.");
|
|
8691
8804
|
process.exit(1);
|
|
8692
8805
|
}
|
|
8693
8806
|
const agentId = getAgentId();
|
|
@@ -8695,18 +8808,18 @@ fund.command("join").description("Request to join a fund (creates an EAS attesta
|
|
|
8695
8808
|
spinner.fail("No agent identity found. Run 'sherwood identity mint' first.");
|
|
8696
8809
|
process.exit(1);
|
|
8697
8810
|
}
|
|
8698
|
-
let
|
|
8811
|
+
let fund;
|
|
8699
8812
|
try {
|
|
8700
|
-
|
|
8813
|
+
fund = await resolveFund(subdomain);
|
|
8701
8814
|
} catch {
|
|
8702
8815
|
spinner.text = "Searching across chains...";
|
|
8703
8816
|
const hits = await searchFundAcrossChains(subdomain);
|
|
8704
|
-
spinner.fail(`
|
|
8817
|
+
spinner.fail(`Vault "${subdomain}" not found on ${getNetwork()}`);
|
|
8705
8818
|
if (hits.length === 0) {
|
|
8706
8819
|
console.error(chalk17.red(` Not found on any supported chain.`));
|
|
8707
8820
|
} else if (hits.length === 1) {
|
|
8708
8821
|
console.error(chalk17.yellow(` Found on chain: ${chalk17.bold(hits[0].network)}`));
|
|
8709
|
-
console.error(chalk17.dim(` Re-run: sherwood --chain ${hits[0].network}
|
|
8822
|
+
console.error(chalk17.dim(` Re-run: sherwood --chain ${hits[0].network} vault join --subdomain ${subdomain}`));
|
|
8710
8823
|
} else {
|
|
8711
8824
|
const chains = hits.map((h) => h.network).join(", ");
|
|
8712
8825
|
console.error(chalk17.yellow(` Found on chains: ${chalk17.bold(chains)}`));
|
|
@@ -8730,10 +8843,10 @@ fund.command("join").description("Request to join a fund (creates an EAS attesta
|
|
|
8730
8843
|
emitCalldata(
|
|
8731
8844
|
encodeJoinRequest(
|
|
8732
8845
|
{
|
|
8733
|
-
fundId:
|
|
8846
|
+
fundId: fund.id,
|
|
8734
8847
|
agentId: BigInt(agentId),
|
|
8735
|
-
vault:
|
|
8736
|
-
creator:
|
|
8848
|
+
vault: fund.vault,
|
|
8849
|
+
creator: fund.creator,
|
|
8737
8850
|
message: joinMessage,
|
|
8738
8851
|
referrerAgentId: referrerAgentId2
|
|
8739
8852
|
},
|
|
@@ -8744,10 +8857,10 @@ fund.command("join").description("Request to join a fund (creates an EAS attesta
|
|
|
8744
8857
|
}
|
|
8745
8858
|
const callerAddress = getAccount().address;
|
|
8746
8859
|
spinner.text = "Checking membership...";
|
|
8747
|
-
setVaultAddress(
|
|
8860
|
+
setVaultAddress(fund.vault);
|
|
8748
8861
|
const alreadyAgent = await isAgent(callerAddress);
|
|
8749
8862
|
if (alreadyAgent) {
|
|
8750
|
-
spinner.succeed("You are already a registered agent on this
|
|
8863
|
+
spinner.succeed("You are already a registered agent on this vault");
|
|
8751
8864
|
try {
|
|
8752
8865
|
const xmtp = await loadXmtp();
|
|
8753
8866
|
await xmtp.getXmtpClient();
|
|
@@ -8768,12 +8881,12 @@ fund.command("join").description("Request to join a fund (creates an EAS attesta
|
|
|
8768
8881
|
return;
|
|
8769
8882
|
}
|
|
8770
8883
|
spinner.text = "Checking pending requests...";
|
|
8771
|
-
const pendingRequests = await queryJoinRequests(
|
|
8884
|
+
const pendingRequests = await queryJoinRequests(fund.creator);
|
|
8772
8885
|
const existingRequest = pendingRequests.find(
|
|
8773
|
-
(r) => r.attester.toLowerCase() === callerAddress.toLowerCase() && r.decoded.vault.toLowerCase() ===
|
|
8886
|
+
(r) => r.attester.toLowerCase() === callerAddress.toLowerCase() && r.decoded.vault.toLowerCase() === fund.vault.toLowerCase()
|
|
8774
8887
|
);
|
|
8775
8888
|
if (existingRequest) {
|
|
8776
|
-
spinner.succeed("You already have a pending join request for this
|
|
8889
|
+
spinner.succeed("You already have a pending join request for this vault");
|
|
8777
8890
|
console.log(chalk17.dim(` Attestation: ${existingRequest.uid}`));
|
|
8778
8891
|
console.log(chalk17.dim(` Submitted: ${new Date(existingRequest.time * 1e3).toLocaleString()}`));
|
|
8779
8892
|
try {
|
|
@@ -8788,10 +8901,10 @@ fund.command("join").description("Request to join a fund (creates an EAS attesta
|
|
|
8788
8901
|
spinner.text = "Creating join request attestation...";
|
|
8789
8902
|
const referrerAgentId = opts.ref ? parseInt(opts.ref, 10) : void 0;
|
|
8790
8903
|
const joinAttestation = await createJoinRequest(
|
|
8791
|
-
|
|
8904
|
+
fund.id,
|
|
8792
8905
|
BigInt(agentId),
|
|
8793
|
-
|
|
8794
|
-
|
|
8906
|
+
fund.vault,
|
|
8907
|
+
fund.creator,
|
|
8795
8908
|
joinMessage,
|
|
8796
8909
|
referrerAgentId
|
|
8797
8910
|
);
|
|
@@ -8804,7 +8917,7 @@ fund.command("join").description("Request to join a fund (creates an EAS attesta
|
|
|
8804
8917
|
spinner.succeed("Join request created");
|
|
8805
8918
|
console.warn(chalk17.yellow(" \u26A0 Could not initialize XMTP identity \u2014 creator may not be able to auto-add you to chat"));
|
|
8806
8919
|
}
|
|
8807
|
-
addFund(getChain().id, { subdomain, vault:
|
|
8920
|
+
addFund(getChain().id, { subdomain, vault: fund.vault, role: "agent" });
|
|
8808
8921
|
setPrimaryFund(getChain().id, subdomain);
|
|
8809
8922
|
try {
|
|
8810
8923
|
const cron = await loadCron();
|
|
@@ -8819,9 +8932,9 @@ fund.command("join").description("Request to join a fund (creates an EAS attesta
|
|
|
8819
8932
|
console.log();
|
|
8820
8933
|
console.log(LABEL5(" \u25C6 Join Request Submitted"));
|
|
8821
8934
|
SEP6();
|
|
8822
|
-
console.log(W6(`
|
|
8935
|
+
console.log(W6(` Vault: ${G6(`${subdomain}.sherwoodagent.eth`)}`));
|
|
8823
8936
|
console.log(W6(` Agent ID: #${agentId}`));
|
|
8824
|
-
console.log(W6(` Creator: ${DIM6(
|
|
8937
|
+
console.log(W6(` Creator: ${DIM6(fund.creator)}`));
|
|
8825
8938
|
if (joinAttestation) {
|
|
8826
8939
|
console.log(W6(` Attestation: ${DIM6(joinAttestation.uid)}`));
|
|
8827
8940
|
console.log(W6(` Explorer: ${DIM6(getEasExplorerUrl(joinAttestation.hash))}`));
|
|
@@ -8829,9 +8942,9 @@ fund.command("join").description("Request to join a fund (creates an EAS attesta
|
|
|
8829
8942
|
console.log(W6(` Attestation: ${DIM6("skipped on this chain")}`));
|
|
8830
8943
|
}
|
|
8831
8944
|
SEP6();
|
|
8832
|
-
console.log(G6(" \u2713
|
|
8945
|
+
console.log(G6(" \u2713 Vault saved to ~/.sherwood/config.json (set as primary)"));
|
|
8833
8946
|
console.log(G6(" \u2713 The creator can review with:"));
|
|
8834
|
-
console.log(DIM6(` sherwood
|
|
8947
|
+
console.log(DIM6(` sherwood vault requests --subdomain ${subdomain}`));
|
|
8835
8948
|
console.log();
|
|
8836
8949
|
} catch (err) {
|
|
8837
8950
|
spinner.fail("Join request failed");
|
|
@@ -8839,7 +8952,7 @@ fund.command("join").description("Request to join a fund (creates an EAS attesta
|
|
|
8839
8952
|
process.exit(1);
|
|
8840
8953
|
}
|
|
8841
8954
|
});
|
|
8842
|
-
|
|
8955
|
+
vaultCmd.command("requests").description("View pending join requests for a vault (creator only)").option("--subdomain <name>", "Vault subdomain").option("--vault <address>", "Vault address (default: from config)").action(async (opts) => {
|
|
8843
8956
|
const spinner = ora9("Loading join requests...").start();
|
|
8844
8957
|
try {
|
|
8845
8958
|
let creatorAddress;
|
|
@@ -8860,7 +8973,7 @@ fund.command("requests").description("View pending join requests for a fund (cre
|
|
|
8860
8973
|
}
|
|
8861
8974
|
const callerAddress = getAccount().address.toLowerCase();
|
|
8862
8975
|
if (creatorAddress.toLowerCase() !== callerAddress) {
|
|
8863
|
-
spinner.fail("Only the
|
|
8976
|
+
spinner.fail("Only the vault creator can view join requests");
|
|
8864
8977
|
process.exit(1);
|
|
8865
8978
|
}
|
|
8866
8979
|
spinner.text = "Querying EAS attestations...";
|
|
@@ -8908,9 +9021,9 @@ fund.command("requests").description("View pending join requests for a fund (cre
|
|
|
8908
9021
|
console.log();
|
|
8909
9022
|
}
|
|
8910
9023
|
console.log(G6(" To approve:"));
|
|
8911
|
-
console.log(DIM6(` sherwood
|
|
9024
|
+
console.log(DIM6(` sherwood vault approve --agent-id <id> --wallet <addr>`));
|
|
8912
9025
|
console.log(G6(" To reject:"));
|
|
8913
|
-
console.log(DIM6(` sherwood
|
|
9026
|
+
console.log(DIM6(` sherwood vault reject --attestation <uid>`));
|
|
8914
9027
|
console.log();
|
|
8915
9028
|
} catch (err) {
|
|
8916
9029
|
spinner.fail("Failed to load requests");
|
|
@@ -8918,7 +9031,7 @@ fund.command("requests").description("View pending join requests for a fund (cre
|
|
|
8918
9031
|
process.exit(1);
|
|
8919
9032
|
}
|
|
8920
9033
|
});
|
|
8921
|
-
|
|
9034
|
+
vaultCmd.command("approve").description("Approve an agent join request (registers agent + creates EAS approval)").option("--vault <address>", "Vault address (default: from config)").option("--subdomain <name>", "Vault subdomain (alternative to --vault)").requiredOption("--agent-id <id>", "Agent's ERC-8004 identity token ID").requiredOption("--wallet <address>", "Agent wallet address").action(async (opts) => {
|
|
8922
9035
|
const spinner = ora9("Verifying creator...").start();
|
|
8923
9036
|
try {
|
|
8924
9037
|
const approveSubdomain = opts.subdomain || getPrimaryFund(getChain().id)?.subdomain;
|
|
@@ -8948,7 +9061,7 @@ fund.command("approve").description("Approve an agent join request (registers ag
|
|
|
8948
9061
|
}
|
|
8949
9062
|
const callerAddress = getAccount().address.toLowerCase();
|
|
8950
9063
|
if (creator.toLowerCase() !== callerAddress) {
|
|
8951
|
-
spinner.fail("Only the
|
|
9064
|
+
spinner.fail("Only the vault creator can approve agents");
|
|
8952
9065
|
process.exit(1);
|
|
8953
9066
|
}
|
|
8954
9067
|
spinner.text = "Registering agent on vault...";
|
|
@@ -9023,7 +9136,7 @@ fund.command("approve").description("Approve an agent join request (registers ag
|
|
|
9023
9136
|
process.exit(1);
|
|
9024
9137
|
}
|
|
9025
9138
|
});
|
|
9026
|
-
|
|
9139
|
+
vaultCmd.command("reject").description("Reject a join request by revoking its attestation").requiredOption("--attestation <uid>", "Join request attestation UID to revoke").action(async (opts) => {
|
|
9027
9140
|
const spinner = ora9("Revoking attestation...").start();
|
|
9028
9141
|
try {
|
|
9029
9142
|
const hash = await revokeJoinRequest(opts.attestation);
|
|
@@ -9039,10 +9152,10 @@ fund.command("reject").description("Reject a join request by revoking its attest
|
|
|
9039
9152
|
process.exit(1);
|
|
9040
9153
|
}
|
|
9041
9154
|
});
|
|
9042
|
-
|
|
9155
|
+
vaultCmd.command("leave").description("Leave a vault \u2014 removes participation crons and session state").option("--subdomain <name>", "Vault subdomain to leave").action(async (opts) => {
|
|
9043
9156
|
const subdomain = opts.subdomain || getPrimaryFund(getChain().id)?.subdomain;
|
|
9044
9157
|
if (!subdomain) {
|
|
9045
|
-
console.error(chalk17.red(" No
|
|
9158
|
+
console.error(chalk17.red(" No vault configured. Pass --subdomain <name>."));
|
|
9046
9159
|
process.exit(1);
|
|
9047
9160
|
}
|
|
9048
9161
|
const spinner = ora9("Cleaning up...").start();
|
|
@@ -9056,7 +9169,7 @@ fund.command("leave").description("Leave a fund \u2014 removes participation cro
|
|
|
9056
9169
|
}
|
|
9057
9170
|
const { resetSession } = await import("./session-XBQY7SBJ.js");
|
|
9058
9171
|
resetSession(subdomain);
|
|
9059
|
-
spinner.succeed("Left
|
|
9172
|
+
spinner.succeed("Left vault");
|
|
9060
9173
|
if (cronsRemoved) {
|
|
9061
9174
|
console.log(G6(" \u2713 Participation crons removed"));
|
|
9062
9175
|
}
|
|
@@ -9072,18 +9185,18 @@ fund.command("leave").description("Leave a fund \u2014 removes participation cro
|
|
|
9072
9185
|
process.exit(1);
|
|
9073
9186
|
}
|
|
9074
9187
|
});
|
|
9075
|
-
|
|
9188
|
+
vaultCmd.command("set-primary").description("Set the active vault for CLI commands (auto-used when --subdomain is omitted)").option("--subdomain <name>", "Vault subdomain").option("--vault <address>", "Vault address").action(async (opts) => {
|
|
9076
9189
|
try {
|
|
9077
9190
|
const chainId = getChain().id;
|
|
9078
9191
|
const memberships = getFunds(chainId);
|
|
9079
9192
|
if (!opts.subdomain && !opts.vault) {
|
|
9080
9193
|
const primary = getPrimaryFund(chainId);
|
|
9081
9194
|
if (memberships.length === 0) {
|
|
9082
|
-
console.log(DIM6("\n No
|
|
9195
|
+
console.log(DIM6("\n No vaults saved. Create or join one first.\n"));
|
|
9083
9196
|
return;
|
|
9084
9197
|
}
|
|
9085
9198
|
console.log();
|
|
9086
|
-
console.log(LABEL5(" \u25C6 Your
|
|
9199
|
+
console.log(LABEL5(" \u25C6 Your Vaults"));
|
|
9087
9200
|
SEP6();
|
|
9088
9201
|
for (const m of memberships) {
|
|
9089
9202
|
const isPrimary = primary?.subdomain === m.subdomain;
|
|
@@ -9093,7 +9206,7 @@ fund.command("set-primary").description("Set the active fund for CLI commands (a
|
|
|
9093
9206
|
}
|
|
9094
9207
|
SEP6();
|
|
9095
9208
|
if (memberships.length > 1) {
|
|
9096
|
-
console.log(DIM6(" Switch with: sherwood
|
|
9209
|
+
console.log(DIM6(" Switch with: sherwood vault set-primary --subdomain <name>"));
|
|
9097
9210
|
}
|
|
9098
9211
|
console.log();
|
|
9099
9212
|
return;
|
|
@@ -9119,19 +9232,18 @@ fund.command("set-primary").description("Set the active fund for CLI commands (a
|
|
|
9119
9232
|
}
|
|
9120
9233
|
}
|
|
9121
9234
|
if (!target) {
|
|
9122
|
-
console.error(chalk17.red(" Could not resolve
|
|
9235
|
+
console.error(chalk17.red(" Could not resolve vault. Pass --subdomain or --vault."));
|
|
9123
9236
|
process.exit(1);
|
|
9124
9237
|
}
|
|
9125
9238
|
setPrimaryFund(chainId, target);
|
|
9126
9239
|
console.log(G6(`
|
|
9127
|
-
\u2713 Primary
|
|
9240
|
+
\u2713 Primary vault set to ${target}.sherwoodagent.eth
|
|
9128
9241
|
`));
|
|
9129
9242
|
} catch (err) {
|
|
9130
9243
|
console.error(chalk17.red(formatContractError(err)));
|
|
9131
9244
|
process.exit(1);
|
|
9132
9245
|
}
|
|
9133
9246
|
});
|
|
9134
|
-
var vaultCmd = program.command("vault");
|
|
9135
9247
|
vaultCmd.command("deposit").description("Deposit into a vault").option("--vault <address>", "Vault address (default: from config)").requiredOption("--amount <amount>", "Amount to deposit (in asset units)").option("--use-eth", "Auto-wrap ETH \u2192 WETH before depositing (for WETH vaults)").option("--receiver <address>", "Depositor / share receiver (required with --calldata-only)").action(async (opts) => {
|
|
9136
9248
|
resolveVault(opts);
|
|
9137
9249
|
const decimals = await getAssetDecimals();
|
|
@@ -9210,27 +9322,6 @@ vaultCmd.command("deposit").description("Deposit into a vault").option("--vault
|
|
|
9210
9322
|
process.exit(1);
|
|
9211
9323
|
}
|
|
9212
9324
|
});
|
|
9213
|
-
vaultCmd.command("info").description("Display vault state").option("--vault <address>", "Vault address (default: from config)").action(async (opts) => {
|
|
9214
|
-
resolveVault(opts);
|
|
9215
|
-
const spinner = ora9("Loading vault info...").start();
|
|
9216
|
-
try {
|
|
9217
|
-
const info = await getVaultInfo();
|
|
9218
|
-
spinner.stop();
|
|
9219
|
-
console.log();
|
|
9220
|
-
console.log(chalk17.bold("Vault Info"));
|
|
9221
|
-
console.log(chalk17.dim("\u2500".repeat(40)));
|
|
9222
|
-
console.log(` Address: ${info.address}`);
|
|
9223
|
-
console.log(` Total Assets: ${info.totalAssets}`);
|
|
9224
|
-
console.log(` Agent Count: ${info.agentCount}`);
|
|
9225
|
-
console.log(` Redemptions Locked: ${info.redemptionsLocked}`);
|
|
9226
|
-
console.log(` Management Fee: ${Number(info.managementFeeBps) / 100}%`);
|
|
9227
|
-
console.log();
|
|
9228
|
-
} catch (err) {
|
|
9229
|
-
spinner.fail("Failed to load vault info");
|
|
9230
|
-
console.error(chalk17.red(formatContractError(err)));
|
|
9231
|
-
process.exit(1);
|
|
9232
|
-
}
|
|
9233
|
-
});
|
|
9234
9325
|
vaultCmd.command("balance").description("Show LP share balance and asset value").option("--vault <address>", "Vault address (default: from config)").option("--address <address>", "Address to check (default: your wallet)").action(async (opts) => {
|
|
9235
9326
|
resolveVault(opts);
|
|
9236
9327
|
const spinner = ora9("Loading balance...").start();
|
|
@@ -9346,17 +9437,17 @@ ${info.name} (${info.type})`);
|
|
|
9346
9437
|
}
|
|
9347
9438
|
});
|
|
9348
9439
|
try {
|
|
9349
|
-
const { registerChatCommands } = await import("./chat-
|
|
9440
|
+
const { registerChatCommands } = await import("./chat-ETZSKQDI.js");
|
|
9350
9441
|
registerChatCommands(program);
|
|
9351
9442
|
} catch {
|
|
9352
|
-
program.command("chat <name> [action] [actionArgs...]").description("
|
|
9443
|
+
program.command("chat <name> [action] [actionArgs...]").description("Vault chat (XMTP) \u2014 requires @xmtp/cli").action(() => {
|
|
9353
9444
|
console.error(chalk17.red("XMTP CLI not available."));
|
|
9354
9445
|
console.error(chalk17.dim("Install with: npm install -g @xmtp/cli"));
|
|
9355
9446
|
console.error(chalk17.dim("Or reinstall: npm i -g @sherwoodagent/cli"));
|
|
9356
9447
|
process.exit(1);
|
|
9357
9448
|
});
|
|
9358
9449
|
}
|
|
9359
|
-
var { registerSessionCommands } = await import("./session-
|
|
9450
|
+
var { registerSessionCommands } = await import("./session-HVRZ6AJM.js");
|
|
9360
9451
|
registerSessionCommands(program);
|
|
9361
9452
|
registerVeniceCommands(program);
|
|
9362
9453
|
registerAllowanceCommands(program);
|
|
@@ -9365,15 +9456,15 @@ registerProposalCommands(program);
|
|
|
9365
9456
|
registerQueueCommands(program);
|
|
9366
9457
|
registerGovernorCommands(program);
|
|
9367
9458
|
registerGuardianCommands(program);
|
|
9368
|
-
var { registerResearchCommands } = await import("./research-
|
|
9459
|
+
var { registerResearchCommands } = await import("./research-W74PNYPO.js");
|
|
9369
9460
|
registerResearchCommands(program);
|
|
9370
9461
|
var { registerAgentCommands } = await import("./agent-TBLC3WNJ.js");
|
|
9371
9462
|
registerAgentCommands(program);
|
|
9372
|
-
var { registerTradeCommands } = await import("./trade-
|
|
9463
|
+
var { registerTradeCommands } = await import("./trade-EOQY72L7.js");
|
|
9373
9464
|
registerTradeCommands(program);
|
|
9374
9465
|
registerGridCommand(program);
|
|
9375
9466
|
var configCmd = program.command("config");
|
|
9376
|
-
configCmd.command("set").description("Save settings to ~/.sherwood/config.json (persists across sessions)").option("--private-key <key>", "Wallet private key (0x-prefixed)").option("--vault <address>", "Default vault address").option("--rpc <url>", "Custom RPC URL for the active --chain network").option("--notify-to <id>", "Destination for cron summaries (Telegram chat ID, phone, etc.)").option("--uniswap-api-key <key>", "Uniswap Trading API key (from developers.uniswap.org)").option("--venice-api-key <key>", "Venice AI inference API key").option("--anthropic-api-key <key>", "Anthropic Claude API key (for LLM judge)").option("--xmtp-group <subdomain:groupId>", "Cache an XMTP group ID for a
|
|
9467
|
+
configCmd.command("set").description("Save settings to ~/.sherwood/config.json (persists across sessions)").option("--private-key <key>", "Wallet private key (0x-prefixed)").option("--vault <address>", "Default vault address").option("--rpc <url>", "Custom RPC URL for the active --chain network").option("--notify-to <id>", "Destination for cron summaries (Telegram chat ID, phone, etc.)").option("--uniswap-api-key <key>", "Uniswap Trading API key (from developers.uniswap.org)").option("--venice-api-key <key>", "Venice AI inference API key").option("--anthropic-api-key <key>", "Anthropic Claude API key (for LLM judge)").option("--xmtp-group <subdomain:groupId>", "Cache an XMTP group ID for a vault (e.g. my-vault:abc123)").action((opts) => {
|
|
9377
9468
|
let saved = false;
|
|
9378
9469
|
if (opts.privateKey) {
|
|
9379
9470
|
setPrivateKey(opts.privateKey);
|