@sherwoodagent/cli 0.40.5 → 0.41.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/dist/{addresses-J4NSZRGB.js → addresses-JBIU5U3T.js} +2 -2
  2. package/dist/{chat-EYCDCZUA.js → chat-K4LW776Q.js} +5 -5
  3. package/dist/{chunk-KHTM4GB5.js → chunk-3356CHRT.js} +2 -2
  4. package/dist/{chunk-FCM6SSL6.js → chunk-5SRJJLHL.js} +2 -2
  5. package/dist/{chunk-363E34JI.js → chunk-DSH4G5NY.js} +2 -2
  6. package/dist/{chunk-ZN6CUAX7.js → chunk-VMNB4ARO.js} +19 -5
  7. package/dist/chunk-VMNB4ARO.js.map +1 -0
  8. package/dist/{chunk-ITNGXYLB.js → chunk-XENKMSE4.js} +2 -2
  9. package/dist/{chunk-5OMMVOR6.js → chunk-ZUAYDBG6.js} +2 -2
  10. package/dist/{eas-MUKSLDIP.js → eas-MFKUDVXP.js} +3 -3
  11. package/dist/{governor-WA74WFOS.js → governor-Q57YKWO2.js} +3 -3
  12. package/dist/index.js +570 -285
  13. package/dist/index.js.map +1 -1
  14. package/dist/{price-ELYQKRSN.js → price-B63EDNB2.js} +2 -2
  15. package/dist/{research-HXOXZA4N.js → research-K62TKFLF.js} +3 -3
  16. package/dist/{session-NL6KF2Q5.js → session-2TBX4UTS.js} +5 -5
  17. package/dist/{trade-WMPWF6RT.js → trade-S3L2CNV4.js} +6 -6
  18. package/dist/{xmtp-7CZ5LB5O.js → xmtp-2AZ6H7DH.js} +3 -3
  19. package/package.json +5 -3
  20. package/scripts/pin-xmtp-bindings.cjs +91 -0
  21. package/dist/chunk-ZN6CUAX7.js.map +0 -1
  22. /package/dist/{addresses-J4NSZRGB.js.map → addresses-JBIU5U3T.js.map} +0 -0
  23. /package/dist/{chat-EYCDCZUA.js.map → chat-K4LW776Q.js.map} +0 -0
  24. /package/dist/{chunk-KHTM4GB5.js.map → chunk-3356CHRT.js.map} +0 -0
  25. /package/dist/{chunk-FCM6SSL6.js.map → chunk-5SRJJLHL.js.map} +0 -0
  26. /package/dist/{chunk-363E34JI.js.map → chunk-DSH4G5NY.js.map} +0 -0
  27. /package/dist/{chunk-ITNGXYLB.js.map → chunk-XENKMSE4.js.map} +0 -0
  28. /package/dist/{chunk-5OMMVOR6.js.map → chunk-ZUAYDBG6.js.map} +0 -0
  29. /package/dist/{eas-MUKSLDIP.js.map → eas-MFKUDVXP.js.map} +0 -0
  30. /package/dist/{governor-WA74WFOS.js.map → governor-Q57YKWO2.js.map} +0 -0
  31. /package/dist/{price-ELYQKRSN.js.map → price-B63EDNB2.js.map} +0 -0
  32. /package/dist/{research-HXOXZA4N.js.map → research-K62TKFLF.js.map} +0 -0
  33. /package/dist/{session-NL6KF2Q5.js.map → session-2TBX4UTS.js.map} +0 -0
  34. /package/dist/{trade-WMPWF6RT.js.map → trade-S3L2CNV4.js.map} +0 -0
  35. /package/dist/{xmtp-7CZ5LB5O.js.map → xmtp-2AZ6H7DH.js.map} +0 -0
package/dist/index.js CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  getQuote,
10
10
  listModels,
11
11
  provisionApiKey
12
- } from "./chunk-ITNGXYLB.js";
12
+ } from "./chunk-XENKMSE4.js";
13
13
  import {
14
14
  createApproval,
15
15
  createJoinRequest,
@@ -19,14 +19,14 @@ import {
19
19
  queryJoinRequests,
20
20
  revokeAttestation,
21
21
  stripReferrerPrefix
22
- } from "./chunk-FCM6SSL6.js";
22
+ } from "./chunk-5SRJJLHL.js";
23
23
  import {
24
24
  createSyndicate,
25
25
  getActiveSyndicates,
26
26
  getSyndicate,
27
27
  subdomainExists,
28
28
  updateMetadata
29
- } from "./chunk-KHTM4GB5.js";
29
+ } from "./chunk-3356CHRT.js";
30
30
  import {
31
31
  approveDepositor,
32
32
  deposit,
@@ -49,7 +49,7 @@ import {
49
49
  resolveVaultSyndicate,
50
50
  setTextRecord,
51
51
  setVaultAddress
52
- } from "./chunk-363E34JI.js";
52
+ } from "./chunk-DSH4G5NY.js";
53
53
  import {
54
54
  PROPOSAL_STATE,
55
55
  PROPOSAL_STATES,
@@ -81,7 +81,7 @@ import {
81
81
  setVotingPeriod,
82
82
  settleProposal,
83
83
  vote
84
- } from "./chunk-5OMMVOR6.js";
84
+ } from "./chunk-ZUAYDBG6.js";
85
85
  import {
86
86
  AERODROME,
87
87
  AGENT_REGISTRY,
@@ -94,11 +94,12 @@ import {
94
94
  TOKENS,
95
95
  UNISWAP,
96
96
  VENICE
97
- } from "./chunk-ZN6CUAX7.js";
97
+ } from "./chunk-VMNB4ARO.js";
98
98
  import {
99
99
  formatContractError,
100
100
  getAccount,
101
101
  getPublicClient,
102
+ getWalletClient,
102
103
  sendTxWithRetry,
103
104
  waitForReceipt,
104
105
  writeContractWithRetry
@@ -154,9 +155,9 @@ import {
154
155
  import { config as loadDotenv } from "dotenv";
155
156
  import { createRequire } from "module";
156
157
  import { Command, Option } from "commander";
157
- import { parseUnits as parseUnits4, formatUnits as formatUnits4, isAddress as isAddress5 } from "viem";
158
- import chalk8 from "chalk";
159
- import ora7 from "ora";
158
+ import { parseUnits as parseUnits5, formatUnits as formatUnits5, isAddress as isAddress6 } from "viem";
159
+ import chalk9 from "chalk";
160
+ import ora8 from "ora";
160
161
  import { input, confirm, select } from "@inquirer/prompts";
161
162
 
162
163
  // src/providers/moonwell.ts
@@ -1444,9 +1445,9 @@ function registerStrategyTemplateCommands(strategy2) {
1444
1445
  console.error(chalk.red("Missing --name, --performance-fee, or --duration. Use --write-calls to skip proposal submission."));
1445
1446
  process.exit(1);
1446
1447
  }
1447
- const { propose: propose2 } = await import("./governor-WA74WFOS.js");
1448
+ const { propose: propose2 } = await import("./governor-Q57YKWO2.js");
1448
1449
  const { pinJSON } = await import("./ipfs-IGXLLJCF.js");
1449
- const { parseDuration: parseDuration2 } = await import("./governor-WA74WFOS.js");
1450
+ const { parseDuration: parseDuration2 } = await import("./governor-Q57YKWO2.js");
1450
1451
  const performanceFeeBps = BigInt(opts.performanceFee);
1451
1452
  if (performanceFeeBps < 0n || performanceFeeBps > 10000n) {
1452
1453
  console.error(chalk.red("--performance-fee must be 0-10000 (basis points)"));
@@ -1553,7 +1554,7 @@ function registerStrategyTemplateCommands(strategy2) {
1553
1554
  let prices = [];
1554
1555
  let priceSource = null;
1555
1556
  try {
1556
- const { getTokenPricesInAsset } = await import("./price-ELYQKRSN.js");
1557
+ const { getTokenPricesInAsset } = await import("./price-B63EDNB2.js");
1557
1558
  prices = await getTokenPricesInAsset({
1558
1559
  tokens: allocations.map((a, i) => ({
1559
1560
  token: a.token,
@@ -1982,7 +1983,7 @@ function registerVeniceCommands(program2) {
1982
1983
  console.log(chalk2.dim(` Key: ${apiKey.slice(0, 8)}...${apiKey.slice(-4)}`));
1983
1984
  console.log(chalk2.dim(" Saved to ~/.sherwood/config.json"));
1984
1985
  try {
1985
- const { createVeniceProvisionAttestation, getEasScanUrl: getEasScanUrl2 } = await import("./eas-MUKSLDIP.js");
1986
+ const { createVeniceProvisionAttestation, getEasScanUrl: getEasScanUrl2 } = await import("./eas-MFKUDVXP.js");
1986
1987
  const { uid } = await createVeniceProvisionAttestation(account.address);
1987
1988
  if (uid !== "0x0000000000000000000000000000000000000000000000000000000000000000") {
1988
1989
  console.log(chalk2.dim(` Attested: ${getEasScanUrl2(uid)}`));
@@ -2133,7 +2134,7 @@ ${opts.prompt}`;
2133
2134
  console.log(chalk2.dim(`Model: ${result.model} | Tokens: ${result.usage.promptTokens} in, ${result.usage.completionTokens} out, ${result.usage.totalTokens} total`));
2134
2135
  }
2135
2136
  try {
2136
- const { createVeniceInferenceAttestation, getEasScanUrl: getEasScanUrl2 } = await import("./eas-MUKSLDIP.js");
2137
+ const { createVeniceInferenceAttestation, getEasScanUrl: getEasScanUrl2 } = await import("./eas-MFKUDVXP.js");
2137
2138
  const { keccak256, toHex, isAddress: isAddr } = await import("viem");
2138
2139
  const { getChainContracts: getChainContracts2 } = await import("./config-LS7FKZL5.js");
2139
2140
  const { getChain: getActiveChain } = await import("./network-KSMKPKNL.js");
@@ -2507,12 +2508,12 @@ function registerIdentityCommands(program2) {
2507
2508
  identity.command("load").description("Load an existing ERC-8004 agent identity into your config").requiredOption("--id <tokenId>", "Agent token ID to load").action(async (opts) => {
2508
2509
  const account = getAccount();
2509
2510
  const client = getPublicClient();
2510
- const registry = AGENT_REGISTRY().IDENTITY_REGISTRY;
2511
+ const registry2 = AGENT_REGISTRY().IDENTITY_REGISTRY;
2511
2512
  const tokenId = Number(opts.id);
2512
2513
  const spinner = ora4(`Verifying ownership of agent #${tokenId}...`).start();
2513
2514
  try {
2514
2515
  const owner = await client.readContract({
2515
- address: registry,
2516
+ address: registry2,
2516
2517
  abi: IDENTITY_REGISTRY_ABI,
2517
2518
  functionName: "ownerOf",
2518
2519
  args: [BigInt(tokenId)]
@@ -2533,12 +2534,12 @@ function registerIdentityCommands(program2) {
2533
2534
  });
2534
2535
  identity.command("status").description("Show your agent identity status").action(async () => {
2535
2536
  const account = getAccount();
2536
- const registry = AGENT_REGISTRY().IDENTITY_REGISTRY;
2537
+ const registry2 = AGENT_REGISTRY().IDENTITY_REGISTRY;
2537
2538
  const client = getPublicClient();
2538
2539
  const spinner = ora4("Checking identity...").start();
2539
2540
  try {
2540
2541
  const balance = await client.readContract({
2541
- address: registry,
2542
+ address: registry2,
2542
2543
  abi: IDENTITY_REGISTRY_ABI,
2543
2544
  functionName: "balanceOf",
2544
2545
  args: [account.address]
@@ -2549,12 +2550,12 @@ function registerIdentityCommands(program2) {
2549
2550
  console.log(chalk4.bold("Agent Identity (ERC-8004)"));
2550
2551
  console.log(chalk4.dim("\u2500".repeat(40)));
2551
2552
  console.log(` Wallet: ${account.address}`);
2552
- console.log(` Registry: ${registry}`);
2553
+ console.log(` Registry: ${registry2}`);
2553
2554
  console.log(` NFTs owned: ${balance.toString()}`);
2554
2555
  if (savedId) {
2555
2556
  try {
2556
2557
  const owner = await client.readContract({
2557
- address: registry,
2558
+ address: registry2,
2558
2559
  abi: IDENTITY_REGISTRY_ABI,
2559
2560
  functionName: "ownerOf",
2560
2561
  args: [BigInt(savedId)]
@@ -3265,7 +3266,7 @@ function printSimulationResult(result, callType) {
3265
3266
  }
3266
3267
  async function sendSimulationAlert(subdomain, proposalId, vault, execResult, settleResult) {
3267
3268
  try {
3268
- const xmtp = await import("./xmtp-7CZ5LB5O.js");
3269
+ const xmtp = await import("./xmtp-2AZ6H7DH.js");
3269
3270
  const { getAccount: getAccount2 } = await import("./client-HKAG55PQ.js");
3270
3271
  const group = await xmtp.getGroup("", subdomain);
3271
3272
  const allRisks = [...execResult.risks, ...settleResult?.risks ?? []];
@@ -4074,6 +4075,289 @@ function registerGovernorCommands(program2) {
4074
4075
  });
4075
4076
  }
4076
4077
 
4078
+ // src/commands/guardian-delegate.ts
4079
+ import chalk8 from "chalk";
4080
+ import ora7 from "ora";
4081
+ import { formatUnits as formatUnits4, isAddress as isAddress5, parseUnits as parseUnits4 } from "viem";
4082
+ var G4 = chalk8.green;
4083
+ var W4 = chalk8.white;
4084
+ var DIM4 = chalk8.gray;
4085
+ var BOLD4 = chalk8.white.bold;
4086
+ var LABEL4 = chalk8.green.bold;
4087
+ var WARN = chalk8.yellow;
4088
+ var SEP4 = () => console.log(DIM4("\u2500".repeat(60)));
4089
+ var GUARDIAN_REGISTRY_ABI = [
4090
+ // Guardian stake
4091
+ { type: "function", name: "stakeAsGuardian", inputs: [{ type: "uint256" }, { type: "uint256" }], outputs: [], stateMutability: "nonpayable" },
4092
+ { type: "function", name: "requestUnstakeGuardian", inputs: [], outputs: [], stateMutability: "nonpayable" },
4093
+ { type: "function", name: "cancelUnstakeGuardian", inputs: [], outputs: [], stateMutability: "nonpayable" },
4094
+ { type: "function", name: "claimUnstakeGuardian", inputs: [], outputs: [], stateMutability: "nonpayable" },
4095
+ // Delegation
4096
+ { type: "function", name: "delegateStake", inputs: [{ type: "address" }, { type: "uint256" }], outputs: [], stateMutability: "nonpayable" },
4097
+ { type: "function", name: "requestUnstakeDelegation", inputs: [{ type: "address" }], outputs: [], stateMutability: "nonpayable" },
4098
+ { type: "function", name: "cancelUnstakeDelegation", inputs: [{ type: "address" }], outputs: [], stateMutability: "nonpayable" },
4099
+ { type: "function", name: "claimUnstakeDelegation", inputs: [{ type: "address" }], outputs: [], stateMutability: "nonpayable" },
4100
+ // Commission
4101
+ { type: "function", name: "setCommission", inputs: [{ type: "uint256" }], outputs: [], stateMutability: "nonpayable" },
4102
+ // Views
4103
+ { type: "function", name: "guardianStake", inputs: [{ type: "address" }], outputs: [{ type: "uint256" }], stateMutability: "view" },
4104
+ { type: "function", name: "isActiveGuardian", inputs: [{ type: "address" }], outputs: [{ type: "bool" }], stateMutability: "view" },
4105
+ { type: "function", name: "commissionOf", inputs: [{ type: "address" }], outputs: [{ type: "uint256" }], stateMutability: "view" },
4106
+ { type: "function", name: "delegationOf", inputs: [{ type: "address" }, { type: "address" }], outputs: [{ type: "uint256" }], stateMutability: "view" },
4107
+ { type: "function", name: "delegatedInbound", inputs: [{ type: "address" }], outputs: [{ type: "uint256" }], stateMutability: "view" },
4108
+ // Guardian-fee claim (vault asset)
4109
+ { type: "function", name: "claimProposalReward", inputs: [{ type: "uint256" }], outputs: [], stateMutability: "nonpayable" },
4110
+ { type: "function", name: "claimDelegatorProposalReward", inputs: [{ type: "address" }, { type: "uint256" }], outputs: [], stateMutability: "nonpayable" }
4111
+ ];
4112
+ var ERC20_ABI2 = [
4113
+ { type: "function", name: "approve", inputs: [{ type: "address" }, { type: "uint256" }], outputs: [{ type: "bool" }], stateMutability: "nonpayable" },
4114
+ { type: "function", name: "balanceOf", inputs: [{ type: "address" }], outputs: [{ type: "uint256" }], stateMutability: "view" },
4115
+ { type: "function", name: "decimals", inputs: [], outputs: [{ type: "uint8" }], stateMutability: "view" }
4116
+ ];
4117
+ function requireAddress(name, addr) {
4118
+ if (addr === "0x0000000000000000000000000000000000000000") {
4119
+ console.error(chalk8.red(`${name} is not deployed on ${getNetwork()}. Update cli/src/lib/addresses.ts after deploy.`));
4120
+ process.exit(1);
4121
+ }
4122
+ return addr;
4123
+ }
4124
+ function registry() {
4125
+ return requireAddress("GUARDIAN_REGISTRY", SHERWOOD().GUARDIAN_REGISTRY);
4126
+ }
4127
+ function wood() {
4128
+ return requireAddress("WOOD_TOKEN", SHERWOOD().WOOD_TOKEN);
4129
+ }
4130
+ async function ensureWoodAllowance(amount) {
4131
+ const wallet = getWalletClient();
4132
+ const pc = getPublicClient();
4133
+ const addr = wallet.account.address;
4134
+ const current = await pc.readContract({
4135
+ address: wood(),
4136
+ abi: [{ type: "function", name: "allowance", inputs: [{ type: "address" }, { type: "address" }], outputs: [{ type: "uint256" }], stateMutability: "view" }],
4137
+ functionName: "allowance",
4138
+ args: [addr, registry()]
4139
+ });
4140
+ if (current >= amount) return;
4141
+ const spinner = ora7("Approving WOOD...").start();
4142
+ try {
4143
+ const hash = await wallet.writeContract({
4144
+ address: wood(),
4145
+ abi: ERC20_ABI2,
4146
+ functionName: "approve",
4147
+ args: [registry(), 2n ** 256n - 1n],
4148
+ chain: null,
4149
+ account: wallet.account
4150
+ });
4151
+ await pc.waitForTransactionReceipt({ hash });
4152
+ spinner.succeed("WOOD approval granted");
4153
+ } catch (err) {
4154
+ spinner.fail("WOOD approval failed");
4155
+ throw err;
4156
+ }
4157
+ }
4158
+ function registerGuardianCommands(program2) {
4159
+ const guardian = program2.command("guardian").description("Guardian staking, delegation, and rewards (V1.5)");
4160
+ guardian.command("status [address]").description("Show guardian stake + commission + active status for an address (default: caller)").action(async (addressArg) => {
4161
+ const pc = getPublicClient();
4162
+ let target;
4163
+ if (addressArg) {
4164
+ if (!isAddress5(addressArg)) {
4165
+ console.error(chalk8.red("Invalid address"));
4166
+ process.exit(1);
4167
+ }
4168
+ target = addressArg;
4169
+ } else {
4170
+ const wallet = getWalletClient();
4171
+ target = wallet.account.address;
4172
+ }
4173
+ const spinner = ora7("Loading...").start();
4174
+ try {
4175
+ const [stake, active, commission] = await Promise.all([
4176
+ pc.readContract({ address: registry(), abi: GUARDIAN_REGISTRY_ABI, functionName: "guardianStake", args: [target] }),
4177
+ pc.readContract({ address: registry(), abi: GUARDIAN_REGISTRY_ABI, functionName: "isActiveGuardian", args: [target] }),
4178
+ pc.readContract({ address: registry(), abi: GUARDIAN_REGISTRY_ABI, functionName: "commissionOf", args: [target] })
4179
+ ]);
4180
+ const delegatedIn = await pc.readContract({
4181
+ address: registry(),
4182
+ abi: GUARDIAN_REGISTRY_ABI,
4183
+ functionName: "delegatedInbound",
4184
+ args: [target]
4185
+ });
4186
+ spinner.stop();
4187
+ console.log();
4188
+ console.log(LABEL4(" \u25C6 Guardian Status"));
4189
+ SEP4();
4190
+ console.log(W4(` Address: ${G4(target)}`));
4191
+ console.log(W4(` Active guardian: ${active ? G4("yes") : DIM4("no")}`));
4192
+ console.log(W4(` Own stake: ${BOLD4(formatUnits4(stake, 18))} WOOD`));
4193
+ console.log(W4(` Delegated inbound: ${BOLD4(formatUnits4(delegatedIn, 18))} WOOD`));
4194
+ console.log(W4(` Commission: ${BOLD4(`${Number(commission) / 100}%`)}`));
4195
+ SEP4();
4196
+ console.log();
4197
+ } catch (err) {
4198
+ spinner.fail("Failed to load");
4199
+ console.error(chalk8.red(formatContractError(err)));
4200
+ process.exit(1);
4201
+ }
4202
+ });
4203
+ guardian.command("stake <amount>").description("Stake as a guardian. Amount in WOOD (min = registry.minGuardianStake).").option("--agent-id <id>", "ERC-8004 agent ID to associate (first-stake only)", "0").action(async (amountStr, opts) => {
4204
+ const amount = parseUnits4(amountStr, 18);
4205
+ const agentId = BigInt(opts.agentId);
4206
+ await ensureWoodAllowance(amount);
4207
+ const wallet = getWalletClient();
4208
+ const pc = getPublicClient();
4209
+ const spinner = ora7(`Staking ${amountStr} WOOD...`).start();
4210
+ try {
4211
+ const hash = await wallet.writeContract({
4212
+ address: registry(),
4213
+ abi: GUARDIAN_REGISTRY_ABI,
4214
+ functionName: "stakeAsGuardian",
4215
+ args: [amount, agentId],
4216
+ chain: null,
4217
+ account: wallet.account
4218
+ });
4219
+ await pc.waitForTransactionReceipt({ hash });
4220
+ spinner.succeed(`Staked. Tx: ${hash}`);
4221
+ } catch (err) {
4222
+ spinner.fail("Stake failed");
4223
+ console.error(chalk8.red(formatContractError(err)));
4224
+ process.exit(1);
4225
+ }
4226
+ });
4227
+ guardian.command("unstake <action>").description("Unstake flow: 'request' | 'cancel' | 'claim' (7d cooldown)").action(async (action) => {
4228
+ const fn = { request: "requestUnstakeGuardian", cancel: "cancelUnstakeGuardian", claim: "claimUnstakeGuardian" }[action];
4229
+ if (!fn) {
4230
+ console.error(chalk8.red(`Unknown action '${action}'. Use request | cancel | claim.`));
4231
+ process.exit(1);
4232
+ }
4233
+ const wallet = getWalletClient();
4234
+ const pc = getPublicClient();
4235
+ const spinner = ora7(`${action}...`).start();
4236
+ try {
4237
+ const hash = await wallet.writeContract({ address: registry(), abi: GUARDIAN_REGISTRY_ABI, functionName: fn, args: [], chain: null, account: wallet.account });
4238
+ await pc.waitForTransactionReceipt({ hash });
4239
+ spinner.succeed(`${action} confirmed. Tx: ${hash}`);
4240
+ } catch (err) {
4241
+ spinner.fail(`${action} failed`);
4242
+ console.error(chalk8.red(formatContractError(err)));
4243
+ process.exit(1);
4244
+ }
4245
+ });
4246
+ guardian.command("delegate <delegate> <amount>").description("Delegate WOOD stake to a guardian. Amount in WOOD.").action(async (delegate, amountStr) => {
4247
+ if (!isAddress5(delegate)) {
4248
+ console.error(chalk8.red("Invalid delegate address"));
4249
+ process.exit(1);
4250
+ }
4251
+ const amount = parseUnits4(amountStr, 18);
4252
+ await ensureWoodAllowance(amount);
4253
+ const wallet = getWalletClient();
4254
+ const pc = getPublicClient();
4255
+ const spinner = ora7(`Delegating ${amountStr} WOOD to ${delegate}...`).start();
4256
+ try {
4257
+ const hash = await wallet.writeContract({ address: registry(), abi: GUARDIAN_REGISTRY_ABI, functionName: "delegateStake", args: [delegate, amount], chain: null, account: wallet.account });
4258
+ await pc.waitForTransactionReceipt({ hash });
4259
+ spinner.succeed(`Delegated. Tx: ${hash}`);
4260
+ } catch (err) {
4261
+ spinner.fail("Delegation failed");
4262
+ console.error(chalk8.red(formatContractError(err)));
4263
+ process.exit(1);
4264
+ }
4265
+ });
4266
+ guardian.command("undelegate <delegate> <action>").description("Unstake-delegation flow: 'request' | 'cancel' | 'claim'").action(async (delegate, action) => {
4267
+ if (!isAddress5(delegate)) {
4268
+ console.error(chalk8.red("Invalid delegate address"));
4269
+ process.exit(1);
4270
+ }
4271
+ const fn = { request: "requestUnstakeDelegation", cancel: "cancelUnstakeDelegation", claim: "claimUnstakeDelegation" }[action];
4272
+ if (!fn) {
4273
+ console.error(chalk8.red(`Unknown action '${action}'. Use request | cancel | claim.`));
4274
+ process.exit(1);
4275
+ }
4276
+ const wallet = getWalletClient();
4277
+ const pc = getPublicClient();
4278
+ const spinner = ora7(`${action}...`).start();
4279
+ try {
4280
+ const hash = await wallet.writeContract({ address: registry(), abi: GUARDIAN_REGISTRY_ABI, functionName: fn, args: [delegate], chain: null, account: wallet.account });
4281
+ await pc.waitForTransactionReceipt({ hash });
4282
+ spinner.succeed(`${action} confirmed. Tx: ${hash}`);
4283
+ } catch (err) {
4284
+ spinner.fail(`${action} failed`);
4285
+ console.error(chalk8.red(formatContractError(err)));
4286
+ process.exit(1);
4287
+ }
4288
+ });
4289
+ guardian.command("set-commission <bps>").description("Set your commission rate in bps (0-5000 = 0-50%). Raises capped cumulatively at 500 bps/epoch.").action(async (bpsStr) => {
4290
+ const bps = BigInt(bpsStr);
4291
+ if (bps > 5000n) {
4292
+ console.error(chalk8.red("Commission cannot exceed 5000 bps (50%)"));
4293
+ process.exit(1);
4294
+ }
4295
+ const wallet = getWalletClient();
4296
+ const pc = getPublicClient();
4297
+ const spinner = ora7(`Setting commission to ${Number(bps) / 100}%...`).start();
4298
+ try {
4299
+ const hash = await wallet.writeContract({ address: registry(), abi: GUARDIAN_REGISTRY_ABI, functionName: "setCommission", args: [bps], chain: null, account: wallet.account });
4300
+ await pc.waitForTransactionReceipt({ hash });
4301
+ spinner.succeed(`Commission set. Tx: ${hash}`);
4302
+ } catch (err) {
4303
+ spinner.fail("setCommission failed");
4304
+ console.error(chalk8.red(formatContractError(err)));
4305
+ process.exit(1);
4306
+ }
4307
+ });
4308
+ guardian.command("claim-proposal <proposalId>").description("Claim guardian-fee commission for a settled proposal you voted Approve on (vault asset).").action(async (pidStr) => {
4309
+ const pid = BigInt(pidStr);
4310
+ const wallet = getWalletClient();
4311
+ const pc = getPublicClient();
4312
+ const spinner = ora7("Claiming...").start();
4313
+ try {
4314
+ const hash = await wallet.writeContract({ address: registry(), abi: GUARDIAN_REGISTRY_ABI, functionName: "claimProposalReward", args: [pid], chain: null, account: wallet.account });
4315
+ await pc.waitForTransactionReceipt({ hash });
4316
+ spinner.succeed(`Claimed. Tx: ${hash}`);
4317
+ } catch (err) {
4318
+ spinner.fail("Claim failed");
4319
+ console.error(chalk8.red(formatContractError(err)));
4320
+ process.exit(1);
4321
+ }
4322
+ });
4323
+ guardian.command("claim-delegator <delegate> <proposalId>").description("Claim your delegator share of a delegate's guardian-fee pool for a specific proposal.").action(async (delegate, pidStr) => {
4324
+ if (!isAddress5(delegate)) {
4325
+ console.error(chalk8.red("Invalid delegate address"));
4326
+ process.exit(1);
4327
+ }
4328
+ const pid = BigInt(pidStr);
4329
+ const wallet = getWalletClient();
4330
+ const pc = getPublicClient();
4331
+ const spinner = ora7("Claiming delegator share...").start();
4332
+ try {
4333
+ const hash = await wallet.writeContract({ address: registry(), abi: GUARDIAN_REGISTRY_ABI, functionName: "claimDelegatorProposalReward", args: [delegate, pid], chain: null, account: wallet.account });
4334
+ await pc.waitForTransactionReceipt({ hash });
4335
+ spinner.succeed(`Claimed. Tx: ${hash}`);
4336
+ } catch (err) {
4337
+ spinner.fail("Claim failed");
4338
+ console.error(chalk8.red(formatContractError(err)));
4339
+ process.exit(1);
4340
+ }
4341
+ });
4342
+ guardian.command("claim-wood").description("Open merkl.xyz to claim WOOD epoch block-rewards (off-chain distribution).").action(async () => {
4343
+ const wallet = getWalletClient();
4344
+ const addr = wallet.account.address;
4345
+ const url = `https://merkl.angle.money/user/${addr}`;
4346
+ console.log();
4347
+ console.log(LABEL4(" \u25C6 Merkl Reward Claim"));
4348
+ SEP4();
4349
+ console.log(W4(" WOOD epoch block-rewards are distributed off-chain via Merkl."));
4350
+ console.log(W4(" Open this URL in your browser to view + claim pending rewards:"));
4351
+ console.log();
4352
+ console.log(G4(` ${url}`));
4353
+ console.log();
4354
+ console.log(WARN(" Note: guardian-fee rewards (vault assets) are claimed on-chain"));
4355
+ console.log(WARN(" via `sherwood guardian claim-proposal <pid>`."));
4356
+ SEP4();
4357
+ console.log();
4358
+ });
4359
+ }
4360
+
4077
4361
  // src/index.ts
4078
4362
  try {
4079
4363
  loadDotenv();
@@ -4082,20 +4366,20 @@ try {
4082
4366
  var require2 = createRequire(import.meta.url);
4083
4367
  var { version: CLI_VERSION } = require2("../package.json");
4084
4368
  async function loadXmtp() {
4085
- return import("./xmtp-7CZ5LB5O.js");
4369
+ return import("./xmtp-2AZ6H7DH.js");
4086
4370
  }
4087
4371
  async function loadCron() {
4088
4372
  return import("./cron-EOULYO3R.js");
4089
4373
  }
4090
- var G4 = chalk8.green;
4091
- var W4 = chalk8.white;
4092
- var DIM4 = chalk8.gray;
4093
- var BOLD4 = chalk8.white.bold;
4094
- var LABEL4 = chalk8.green.bold;
4095
- var SEP4 = () => console.log(DIM4("\u2500".repeat(60)));
4374
+ var G5 = chalk9.green;
4375
+ var W5 = chalk9.white;
4376
+ var DIM5 = chalk9.gray;
4377
+ var BOLD5 = chalk9.white.bold;
4378
+ var LABEL5 = chalk9.green.bold;
4379
+ var SEP5 = () => console.log(DIM5("\u2500".repeat(60)));
4096
4380
  function validateAddress(value, name) {
4097
- if (!isAddress5(value)) {
4098
- console.error(chalk8.red(`Invalid ${name} address: ${value}`));
4381
+ if (!isAddress6(value)) {
4382
+ console.error(chalk9.red(`Invalid ${name} address: ${value}`));
4099
4383
  process.exit(1);
4100
4384
  }
4101
4385
  return value;
@@ -4115,7 +4399,7 @@ program.name("sherwood").description("CLI for agent-managed investment syndicate
4115
4399
  process.env.ENABLE_TESTNET = "true";
4116
4400
  if (network !== "base") {
4117
4401
  console.warn(
4118
- chalk8.yellow("[warn] --testnet ignored, --chain takes precedence")
4402
+ chalk9.yellow("[warn] --testnet ignored, --chain takes precedence")
4119
4403
  );
4120
4404
  } else {
4121
4405
  network = "base-sepolia";
@@ -4123,39 +4407,39 @@ program.name("sherwood").description("CLI for agent-managed investment syndicate
4123
4407
  }
4124
4408
  setNetwork(network);
4125
4409
  if (getNetwork() !== "base") {
4126
- console.log(chalk8.yellow(`[${getNetwork()}]`));
4410
+ console.log(chalk9.yellow(`[${getNetwork()}]`));
4127
4411
  }
4128
4412
  });
4129
4413
  var syndicate = program.command("syndicate");
4130
4414
  syndicate.command("create").description("Create a new syndicate via the factory (interactive)").option("--subdomain <name>", "ENS subdomain (skip prompt)").option("--name <name>", "Syndicate 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 (no whitelist)").option("--public-chat", "Enable dashboard spectator mode", false).option("-y, --yes", "Skip confirmation prompt (non-interactive mode)", false).action(async (opts) => {
4131
4415
  try {
4132
4416
  console.log();
4133
- console.log(LABEL4(" \u25C6 Create Syndicate"));
4134
- SEP4();
4417
+ console.log(LABEL5(" \u25C6 Create Syndicate"));
4418
+ SEP5();
4135
4419
  const wallet = getAccount();
4136
- console.log(DIM4(` Wallet: ${wallet.address}`));
4137
- console.log(DIM4(` Network: ${getChain().name}`));
4138
- SEP4();
4420
+ console.log(DIM5(` Wallet: ${wallet.address}`));
4421
+ console.log(DIM5(` Network: ${getChain().name}`));
4422
+ SEP5();
4139
4423
  const savedAgentId = getAgentId();
4140
4424
  const nonInteractive = opts.yes;
4141
4425
  const name = opts.name || (nonInteractive ? (() => {
4142
4426
  throw new Error("--name is required in non-interactive mode (-y)");
4143
4427
  })() : await input({
4144
- message: G4("Syndicate name"),
4428
+ message: G5("Syndicate name"),
4145
4429
  validate: (v) => v.length > 0 || "Name is required"
4146
4430
  }));
4147
4431
  const subdomain = opts.subdomain || (nonInteractive ? name.toLowerCase().replace(/\s+/g, "-").replace(/[^a-z0-9-]/g, "") : await input({
4148
- message: G4("ENS subdomain"),
4432
+ message: G5("ENS subdomain"),
4149
4433
  default: name.toLowerCase().replace(/\s+/g, "-").replace(/[^a-z0-9-]/g, ""),
4150
4434
  validate: (v) => v.length >= 3 || "Must be at least 3 characters"
4151
4435
  }));
4152
4436
  const description = opts.description || (nonInteractive ? `${name} \u2014 a Sherwood syndicate` : await input({
4153
- message: G4("Description"),
4437
+ message: G5("Description"),
4154
4438
  default: `${name} \u2014 a Sherwood syndicate`
4155
4439
  }));
4156
- const agentIdStr = opts.agentId || (savedAgentId ? nonInteractive ? String(savedAgentId) : await input({ message: G4("Agent ID (ERC-8004)"), default: String(savedAgentId) }) : nonInteractive ? "0" : await input({ message: G4("Agent ID (ERC-8004)"), validate: (v) => /^\d+$/.test(v) || "Must be a number" }));
4440
+ const agentIdStr = opts.agentId || (savedAgentId ? nonInteractive ? String(savedAgentId) : await input({ message: G5("Agent ID (ERC-8004)"), default: String(savedAgentId) }) : nonInteractive ? "0" : await input({ message: G5("Agent ID (ERC-8004)"), validate: (v) => /^\d+$/.test(v) || "Must be a number" }));
4157
4441
  const openDeposits = opts.openDeposits !== void 0 ? opts.openDeposits : nonInteractive ? true : await confirm({
4158
- message: G4("Open deposits? (anyone can deposit)"),
4442
+ message: G5("Open deposits? (anyone can deposit)"),
4159
4443
  default: true
4160
4444
  });
4161
4445
  const ASSET_SYMBOLS = {
@@ -4171,14 +4455,14 @@ syndicate.command("create").description("Create a new syndicate via the factory
4171
4455
  asset = opts.asset;
4172
4456
  } else {
4173
4457
  const supported = Object.keys(ASSET_SYMBOLS).join(", ");
4174
- console.error(chalk8.red(` Unknown asset "${opts.asset}". Use a symbol (${supported}) or a 0x address.`));
4458
+ console.error(chalk9.red(` Unknown asset "${opts.asset}". Use a symbol (${supported}) or a 0x address.`));
4175
4459
  process.exit(1);
4176
4460
  }
4177
4461
  } else if (nonInteractive) {
4178
4462
  asset = TOKENS().USDC !== "0x0000000000000000000000000000000000000000" ? ASSET_SYMBOLS.USDC : ASSET_SYMBOLS.WETH;
4179
4463
  } else {
4180
4464
  const assetChoice = await select({
4181
- message: G4("Vault asset (what token do depositors provide?)"),
4465
+ message: G5("Vault asset (what token do depositors provide?)"),
4182
4466
  choices: [
4183
4467
  { name: "USDC", value: "USDC", description: "USD Coin (6 decimals)" },
4184
4468
  { name: "WETH", value: "WETH", description: "Wrapped Ether (18 decimals)" }
@@ -4193,26 +4477,26 @@ syndicate.command("create").description("Create a new syndicate via the factory
4193
4477
  ]);
4194
4478
  const symbol = `sw${assetSymbol}`;
4195
4479
  console.log();
4196
- console.log(LABEL4(" \u25C6 Review"));
4197
- SEP4();
4198
- console.log(W4(` Name: ${BOLD4(name)}`));
4199
- console.log(W4(` ENS: ${G4(`${subdomain}.sherwoodagent.eth`)}`));
4200
- console.log(W4(` Description: ${DIM4(description)}`));
4201
- console.log(W4(` Agent ID: #${agentIdStr}`));
4202
- console.log(W4(` Asset: ${assetSymbol} (${asset.slice(0, 10)}...)`));
4203
- console.log(W4(` Share token: ${symbol}`));
4204
- console.log(W4(` Open deposits: ${openDeposits ? G4("yes") : chalk8.red("no (whitelist)")}`));
4205
- SEP4();
4480
+ console.log(LABEL5(" \u25C6 Review"));
4481
+ SEP5();
4482
+ console.log(W5(` Name: ${BOLD5(name)}`));
4483
+ console.log(W5(` ENS: ${G5(`${subdomain}.sherwoodagent.eth`)}`));
4484
+ console.log(W5(` Description: ${DIM5(description)}`));
4485
+ console.log(W5(` Agent ID: #${agentIdStr}`));
4486
+ console.log(W5(` Asset: ${assetSymbol} (${asset.slice(0, 10)}...)`));
4487
+ console.log(W5(` Share token: ${symbol}`));
4488
+ console.log(W5(` Open deposits: ${openDeposits ? G5("yes") : chalk9.red("no (whitelist)")}`));
4489
+ SEP5();
4206
4490
  if (!nonInteractive) {
4207
- const go = await confirm({ message: G4("Deploy syndicate?"), default: true });
4491
+ const go = await confirm({ message: G5("Deploy syndicate?"), default: true });
4208
4492
  if (!go) {
4209
- console.log(DIM4(" Cancelled."));
4493
+ console.log(DIM5(" Cancelled."));
4210
4494
  return;
4211
4495
  }
4212
4496
  }
4213
4497
  let metadataURI = opts.metadataUri || "";
4214
4498
  if (!metadataURI) {
4215
- const spinner2 = ora7({ text: W4("Uploading metadata to IPFS..."), color: "green" }).start();
4499
+ const spinner2 = ora8({ text: W5("Uploading metadata to IPFS..."), color: "green" }).start();
4216
4500
  try {
4217
4501
  const metadata = {
4218
4502
  schema: "sherwood/syndicate/v1",
@@ -4226,9 +4510,9 @@ syndicate.command("create").description("Create a new syndicate via the factory
4226
4510
  links: {}
4227
4511
  };
4228
4512
  metadataURI = await uploadMetadata(metadata);
4229
- spinner2.succeed(G4(`Metadata pinned: ${DIM4(metadataURI)}`));
4513
+ spinner2.succeed(G5(`Metadata pinned: ${DIM5(metadataURI)}`));
4230
4514
  } catch (err) {
4231
- spinner2.warn(chalk8.yellow(`IPFS upload failed \u2014 using inline metadata`));
4515
+ spinner2.warn(chalk9.yellow(`IPFS upload failed \u2014 using inline metadata`));
4232
4516
  const json = JSON.stringify({ name, description, subdomain, asset: assetSymbol, openDeposits, createdBy: "@sherwoodagent/cli" });
4233
4517
  metadataURI = `data:application/json;base64,${Buffer.from(json).toString("base64")}`;
4234
4518
  }
@@ -4238,43 +4522,43 @@ syndicate.command("create").description("Create a new syndicate via the factory
4238
4522
  const existingInfo = await getSyndicate(existingId);
4239
4523
  const callerAddress = getAccount().address.toLowerCase();
4240
4524
  if (existingInfo.creator.toLowerCase() !== callerAddress) {
4241
- console.error(chalk8.red(`
4525
+ console.error(chalk9.red(`
4242
4526
  \u2716 Subdomain '${subdomain}' is already taken by another syndicate.
4243
4527
  `));
4244
4528
  process.exit(1);
4245
4529
  }
4246
- console.log(chalk8.yellow(`
4530
+ console.log(chalk9.yellow(`
4247
4531
  \u26A0 Syndicate '${subdomain}' already exists \u2014 resuming setup...
4248
4532
  `));
4249
- const spinner2 = ora7({ text: W4("Resuming setup..."), color: "green" }).start();
4533
+ const spinner2 = ora8({ text: W5("Resuming setup..."), color: "green" }).start();
4250
4534
  const chainId2 = getChain().id;
4251
4535
  setChainContract(chainId2, "vault", existingInfo.vault);
4252
4536
  addSyndicate(chainId2, { subdomain, vault: existingInfo.vault, role: "creator" });
4253
4537
  setPrimarySyndicate(chainId2, subdomain);
4254
- spinner2.text = W4("Checking agent registration...");
4538
+ spinner2.text = W5("Checking agent registration...");
4255
4539
  try {
4256
4540
  setVaultAddress(existingInfo.vault);
4257
4541
  const isAlreadyAgent = await isAgent(getAccount().address);
4258
4542
  if (!isAlreadyAgent) {
4259
- spinner2.text = W4("Registering creator as agent...");
4543
+ spinner2.text = W5("Registering creator as agent...");
4260
4544
  await registerAgent(BigInt(agentIdStr), getAccount().address);
4261
4545
  }
4262
4546
  } catch {
4263
4547
  }
4264
- spinner2.text = W4("Checking chat group...");
4548
+ spinner2.text = W5("Checking chat group...");
4265
4549
  try {
4266
4550
  const xmtp = await loadXmtp();
4267
4551
  const xmtpClient = await xmtp.getXmtpClient();
4268
4552
  try {
4269
4553
  await xmtp.getGroup(xmtpClient, subdomain);
4270
4554
  } catch {
4271
- spinner2.text = W4("Creating chat group...");
4555
+ spinner2.text = W5("Creating chat group...");
4272
4556
  const groupId = await xmtp.createSyndicateGroup(xmtpClient, subdomain, opts.publicChat);
4273
4557
  await setTextRecord(subdomain, "xmtpGroupId", groupId, existingInfo.vault);
4274
4558
  cacheGroupId(subdomain, groupId);
4275
4559
  }
4276
4560
  } catch {
4277
- console.warn(chalk8.yellow("\n \u26A0 Could not set up XMTP chat group"));
4561
+ console.warn(chalk9.yellow("\n \u26A0 Could not set up XMTP chat group"));
4278
4562
  }
4279
4563
  try {
4280
4564
  const cron = await loadCron();
@@ -4283,20 +4567,20 @@ syndicate.command("create").description("Create a new syndicate via the factory
4283
4567
  }
4284
4568
  spinner2.stop();
4285
4569
  console.log();
4286
- console.log(LABEL4(" \u25C6 Syndicate Setup Resumed"));
4287
- SEP4();
4288
- console.log(W4(` ID: ${G4(`#${existingId}`)}`));
4289
- console.log(W4(` Vault: ${G4(existingInfo.vault)}`));
4290
- console.log(W4(` ENS: ${G4(`${subdomain}.sherwoodagent.eth`)}`));
4291
- console.log(W4(` Chat: ${DIM4(`sherwood chat ${subdomain}`)}`));
4570
+ console.log(LABEL5(" \u25C6 Syndicate Setup Resumed"));
4571
+ SEP5();
4572
+ console.log(W5(` ID: ${G5(`#${existingId}`)}`));
4573
+ console.log(W5(` Vault: ${G5(existingInfo.vault)}`));
4574
+ console.log(W5(` ENS: ${G5(`${subdomain}.sherwoodagent.eth`)}`));
4575
+ console.log(W5(` Chat: ${DIM5(`sherwood chat ${subdomain}`)}`));
4292
4576
  const refParam2 = getAgentId() ? `?ref=${getAgentId()}` : "";
4293
- console.log(W4(` Share: ${G4(`https://sherwood.sh/syndicate/${subdomain}${refParam2}`)}`));
4294
- SEP4();
4295
- console.log(G4(" \u2713 Syndicate saved to ~/.sherwood/config.json (set as primary)"));
4577
+ console.log(W5(` Share: ${G5(`https://sherwood.sh/syndicate/${subdomain}${refParam2}`)}`));
4578
+ SEP5();
4579
+ console.log(G5(" \u2713 Syndicate saved to ~/.sherwood/config.json (set as primary)"));
4296
4580
  console.log();
4297
4581
  return;
4298
4582
  }
4299
- const spinner = ora7({ text: W4("Deploying vault via factory..."), color: "green" }).start();
4583
+ const spinner = ora8({ text: W5("Deploying vault via factory..."), color: "green" }).start();
4300
4584
  const result = await createSyndicate({
4301
4585
  creatorAgentId: BigInt(agentIdStr),
4302
4586
  metadataURI,
@@ -4311,7 +4595,7 @@ syndicate.command("create").description("Create a new syndicate via the factory
4311
4595
  addSyndicate(chainId, { subdomain, vault: result.vault, role: "creator" });
4312
4596
  setPrimarySyndicate(chainId, subdomain);
4313
4597
  await new Promise((r) => setTimeout(r, 2e3));
4314
- spinner.text = W4("Registering creator as agent...");
4598
+ spinner.text = W5("Registering creator as agent...");
4315
4599
  try {
4316
4600
  setVaultAddress(result.vault);
4317
4601
  const creatorAddress = getAccount().address;
@@ -4321,9 +4605,9 @@ syndicate.command("create").description("Create a new syndicate via the factory
4321
4605
  // agentAddress = creator EOA (direct execution)
4322
4606
  );
4323
4607
  } catch (regErr) {
4324
- console.warn(chalk8.yellow("\n \u26A0 Could not auto-register creator as agent \u2014 register manually with `syndicate add`"));
4608
+ console.warn(chalk9.yellow("\n \u26A0 Could not auto-register creator as agent \u2014 register manually with `syndicate add`"));
4325
4609
  }
4326
- spinner.text = W4("Setting up chat...");
4610
+ spinner.text = W5("Setting up chat...");
4327
4611
  try {
4328
4612
  const xmtp = await loadXmtp();
4329
4613
  const xmtpClient = await xmtp.getXmtpClient();
@@ -4334,42 +4618,42 @@ syndicate.command("create").description("Create a new syndicate via the factory
4334
4618
  } catch {
4335
4619
  }
4336
4620
  } catch {
4337
- console.warn(chalk8.yellow("\n \u26A0 Could not create XMTP chat group"));
4338
- console.warn(chalk8.dim(` Recover later with: sherwood chat ${subdomain} init`));
4621
+ console.warn(chalk9.yellow("\n \u26A0 Could not create XMTP chat group"));
4622
+ console.warn(chalk9.dim(` Recover later with: sherwood chat ${subdomain} init`));
4339
4623
  }
4340
4624
  try {
4341
4625
  const cron = await loadCron();
4342
4626
  const cronResult = cron.registerSyndicateCrons(subdomain, isTestnet(), getNotifyTo());
4343
4627
  if (cronResult.isOpenClaw && cronResult.registered) {
4344
- console.log(G4(" \u2713 Participation crons registered (15m check + hourly summary)"));
4628
+ console.log(G5(" \u2713 Participation crons registered (15m check + hourly summary)"));
4345
4629
  } else if (!cronResult.isOpenClaw) {
4346
- console.log(DIM4(" Tip: Set up a scheduled process to run `sherwood session check " + subdomain + "` periodically"));
4630
+ console.log(DIM5(" Tip: Set up a scheduled process to run `sherwood session check " + subdomain + "` periodically"));
4347
4631
  }
4348
4632
  } catch {
4349
4633
  }
4350
4634
  spinner.stop();
4351
4635
  console.log();
4352
- console.log(LABEL4(" \u25C6 Syndicate Created"));
4353
- SEP4();
4354
- console.log(W4(` ID: ${G4(`#${result.syndicateId}`)}`));
4355
- console.log(W4(` Vault: ${G4(result.vault)}`));
4356
- console.log(W4(` ENS: ${G4(`${subdomain}.sherwoodagent.eth`)}`));
4357
- console.log(W4(` Metadata: ${DIM4(metadataURI.length > 50 ? metadataURI.slice(0, 50) + "..." : metadataURI)}`));
4358
- console.log(W4(` Explorer: ${DIM4(getExplorerUrl(result.hash))}`));
4359
- console.log(W4(` Chat: ${DIM4(`sherwood chat ${subdomain}`)}`));
4636
+ console.log(LABEL5(" \u25C6 Syndicate Created"));
4637
+ SEP5();
4638
+ console.log(W5(` ID: ${G5(`#${result.syndicateId}`)}`));
4639
+ console.log(W5(` Vault: ${G5(result.vault)}`));
4640
+ console.log(W5(` ENS: ${G5(`${subdomain}.sherwoodagent.eth`)}`));
4641
+ console.log(W5(` Metadata: ${DIM5(metadataURI.length > 50 ? metadataURI.slice(0, 50) + "..." : metadataURI)}`));
4642
+ console.log(W5(` Explorer: ${DIM5(getExplorerUrl(result.hash))}`));
4643
+ console.log(W5(` Chat: ${DIM5(`sherwood chat ${subdomain}`)}`));
4360
4644
  const refParam = getAgentId() ? `?ref=${getAgentId()}` : "";
4361
- console.log(W4(` Share: ${G4(`https://sherwood.sh/syndicate/${subdomain}${refParam}`)}`));
4362
- SEP4();
4363
- console.log(G4(" \u2713 Syndicate saved to ~/.sherwood/config.json (set as primary)"));
4645
+ console.log(W5(` Share: ${G5(`https://sherwood.sh/syndicate/${subdomain}${refParam}`)}`));
4646
+ SEP5();
4647
+ console.log(G5(" \u2713 Syndicate saved to ~/.sherwood/config.json (set as primary)"));
4364
4648
  console.log();
4365
4649
  } catch (err) {
4366
- console.error(chalk8.red(`
4650
+ console.error(chalk9.red(`
4367
4651
  \u2716 ${formatContractError(err)}`));
4368
4652
  process.exit(1);
4369
4653
  }
4370
4654
  });
4371
4655
  syndicate.command("list").description("List active syndicates (queries subgraph, falls back to on-chain)").option("--creator <address>", "Filter by creator address").action(async (opts) => {
4372
- const spinner = ora7("Loading syndicates...").start();
4656
+ const spinner = ora8("Loading syndicates...").start();
4373
4657
  try {
4374
4658
  let syndicates;
4375
4659
  if (process.env.SUBGRAPH_URL) {
@@ -4388,39 +4672,39 @@ syndicate.command("list").description("List active syndicates (queries subgraph,
4388
4672
  }
4389
4673
  spinner.stop();
4390
4674
  if (syndicates.length === 0) {
4391
- console.log(chalk8.dim("No active syndicates found."));
4675
+ console.log(chalk9.dim("No active syndicates found."));
4392
4676
  return;
4393
4677
  }
4394
4678
  console.log();
4395
- console.log(chalk8.bold(`Active Syndicates (${syndicates.length})`));
4679
+ console.log(chalk9.bold(`Active Syndicates (${syndicates.length})`));
4396
4680
  if (!process.env.SUBGRAPH_URL) {
4397
- console.log(chalk8.dim(" (Set SUBGRAPH_URL for faster indexed queries)"));
4681
+ console.log(chalk9.dim(" (Set SUBGRAPH_URL for faster indexed queries)"));
4398
4682
  }
4399
- console.log(chalk8.dim("\u2500".repeat(70)));
4683
+ console.log(chalk9.dim("\u2500".repeat(70)));
4400
4684
  for (const s of syndicates) {
4401
4685
  const ts = typeof s.createdAt === "string" ? Number(s.createdAt) : Number(s.createdAt);
4402
4686
  const date = new Date(ts * 1e3).toLocaleDateString();
4403
4687
  const ensName = s.subdomain ? `${s.subdomain}.sherwoodagent.eth` : "";
4404
- console.log(` #${s.id} ${chalk8.bold(ensName || String(s.vault))}`);
4405
- if (ensName) console.log(` Vault: ${chalk8.cyan(String(s.vault))}`);
4688
+ console.log(` #${s.id} ${chalk9.bold(ensName || String(s.vault))}`);
4689
+ if (ensName) console.log(` Vault: ${chalk9.cyan(String(s.vault))}`);
4406
4690
  console.log(` Creator: ${s.creator}`);
4407
4691
  console.log(` Created: ${date}`);
4408
4692
  if (s.totalDeposits) {
4409
4693
  console.log(` Deposits: ${s.totalDeposits} USDC`);
4410
4694
  }
4411
4695
  if (s.metadataURI) {
4412
- console.log(` Metadata: ${chalk8.dim(s.metadataURI)}`);
4696
+ console.log(` Metadata: ${chalk9.dim(s.metadataURI)}`);
4413
4697
  }
4414
4698
  console.log();
4415
4699
  }
4416
4700
  } catch (err) {
4417
4701
  spinner.fail("Failed to load syndicates");
4418
- console.error(chalk8.red(formatContractError(err)));
4702
+ console.error(chalk9.red(formatContractError(err)));
4419
4703
  process.exit(1);
4420
4704
  }
4421
4705
  });
4422
4706
  syndicate.command("info").description("Display syndicate details by ID or subdomain").argument("<id>", "Syndicate ID or subdomain name").action(async (idStr) => {
4423
- const spinner = ora7("Loading syndicate info...").start();
4707
+ const spinner = ora8("Loading syndicate info...").start();
4424
4708
  try {
4425
4709
  let id;
4426
4710
  if (/^\d+$/.test(idStr)) {
@@ -4432,33 +4716,33 @@ syndicate.command("info").description("Display syndicate details by ID or subdom
4432
4716
  const info = await getSyndicate(id);
4433
4717
  spinner.stop();
4434
4718
  if (!info.vault || info.vault === "0x0000000000000000000000000000000000000000") {
4435
- console.log(chalk8.red(`Syndicate #${id} not found.`));
4719
+ console.log(chalk9.red(`Syndicate #${id} not found.`));
4436
4720
  process.exit(1);
4437
4721
  }
4438
4722
  const date = new Date(Number(info.createdAt) * 1e3).toLocaleDateString();
4439
4723
  console.log();
4440
- console.log(chalk8.bold(`Syndicate #${info.id}`));
4441
- console.log(chalk8.dim("\u2500".repeat(40)));
4724
+ console.log(chalk9.bold(`Syndicate #${info.id}`));
4725
+ console.log(chalk9.dim("\u2500".repeat(40)));
4442
4726
  if (info.subdomain) {
4443
- console.log(` ENS: ${chalk8.bold(`${info.subdomain}.sherwoodagent.eth`)}`);
4727
+ console.log(` ENS: ${chalk9.bold(`${info.subdomain}.sherwoodagent.eth`)}`);
4444
4728
  }
4445
- console.log(` Vault: ${chalk8.cyan(info.vault)}`);
4729
+ console.log(` Vault: ${chalk9.cyan(info.vault)}`);
4446
4730
  console.log(` Creator: ${info.creator}`);
4447
4731
  console.log(` Created: ${date}`);
4448
- console.log(` Active: ${info.active ? chalk8.green("yes") : chalk8.red("no")}`);
4732
+ console.log(` Active: ${info.active ? chalk9.green("yes") : chalk9.red("no")}`);
4449
4733
  if (info.metadataURI) {
4450
- console.log(` Metadata: ${chalk8.dim(info.metadataURI)}`);
4734
+ console.log(` Metadata: ${chalk9.dim(info.metadataURI)}`);
4451
4735
  }
4452
4736
  if (info.subdomain) {
4453
4737
  const xmtpGroupId = getCachedGroupId(info.subdomain);
4454
4738
  if (xmtpGroupId) {
4455
- console.log(` XMTP Group: ${chalk8.cyan(xmtpGroupId)}`);
4739
+ console.log(` XMTP Group: ${chalk9.cyan(xmtpGroupId)}`);
4456
4740
  }
4457
4741
  }
4458
4742
  setVaultAddress(info.vault);
4459
4743
  const vaultInfo = await getVaultInfo();
4460
4744
  console.log();
4461
- console.log(chalk8.bold(" Vault Stats"));
4745
+ console.log(chalk9.bold(" Vault Stats"));
4462
4746
  console.log(` Total Assets: ${vaultInfo.totalAssets}`);
4463
4747
  console.log(` Agent Count: ${vaultInfo.agentCount}`);
4464
4748
  console.log(` Redemptions Locked: ${vaultInfo.redemptionsLocked}`);
@@ -4466,12 +4750,12 @@ syndicate.command("info").description("Display syndicate details by ID or subdom
4466
4750
  console.log();
4467
4751
  } catch (err) {
4468
4752
  spinner.fail("Failed to load syndicate info");
4469
- console.error(chalk8.red(formatContractError(err)));
4753
+ console.error(chalk9.red(formatContractError(err)));
4470
4754
  process.exit(1);
4471
4755
  }
4472
4756
  });
4473
4757
  syndicate.command("update-metadata").description("Update syndicate metadata (creator only)").requiredOption("--id <id>", "Syndicate ID").option("--name <name>", "Syndicate name").option("--description <text>", "Short description").option("--uri <uri>", "Direct metadata URI (skips IPFS upload)").action(async (opts) => {
4474
- const spinner = ora7({ text: W4("Loading syndicate..."), color: "green" }).start();
4758
+ const spinner = ora8({ text: W5("Loading syndicate..."), color: "green" }).start();
4475
4759
  try {
4476
4760
  const syndicateId = BigInt(opts.id);
4477
4761
  let metadataURI = opts.uri;
@@ -4483,7 +4767,7 @@ syndicate.command("update-metadata").description("Update syndicate metadata (cre
4483
4767
  }
4484
4768
  const name = opts.name || info.subdomain;
4485
4769
  const description = opts.description || `${name} \u2014 a Sherwood syndicate on ${info.subdomain}.sherwoodagent.eth`;
4486
- spinner.text = W4("Uploading metadata to IPFS...");
4770
+ spinner.text = W5("Uploading metadata to IPFS...");
4487
4771
  const metadata = {
4488
4772
  schema: "sherwood/syndicate/v1",
4489
4773
  name,
@@ -4494,48 +4778,48 @@ syndicate.command("update-metadata").description("Update syndicate metadata (cre
4494
4778
  links: {}
4495
4779
  };
4496
4780
  metadataURI = await uploadMetadata(metadata);
4497
- spinner.text = W4("Updating on-chain metadata...");
4781
+ spinner.text = W5("Updating on-chain metadata...");
4498
4782
  }
4499
4783
  const hash = await updateMetadata(syndicateId, metadataURI);
4500
- spinner.succeed(G4(`Metadata updated`));
4501
- console.log(DIM4(` IPFS: ${metadataURI}`));
4502
- console.log(DIM4(` ${getExplorerUrl(hash)}`));
4784
+ spinner.succeed(G5(`Metadata updated`));
4785
+ console.log(DIM5(` IPFS: ${metadataURI}`));
4786
+ console.log(DIM5(` ${getExplorerUrl(hash)}`));
4503
4787
  } catch (err) {
4504
4788
  spinner.fail("Metadata update failed");
4505
- console.error(chalk8.red(formatContractError(err)));
4789
+ console.error(chalk9.red(formatContractError(err)));
4506
4790
  process.exit(1);
4507
4791
  }
4508
4792
  });
4509
4793
  syndicate.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) => {
4510
4794
  resolveVault(opts);
4511
- const spinner = ora7("Approving depositor...").start();
4795
+ const spinner = ora8("Approving depositor...").start();
4512
4796
  try {
4513
4797
  const depositor = validateAddress(opts.depositor, "depositor");
4514
4798
  const hash = await approveDepositor(depositor);
4515
4799
  spinner.succeed(`Depositor approved: ${hash}`);
4516
- console.log(chalk8.dim(` ${getExplorerUrl(hash)}`));
4800
+ console.log(chalk9.dim(` ${getExplorerUrl(hash)}`));
4517
4801
  } catch (err) {
4518
4802
  spinner.fail("Approval failed");
4519
- console.error(chalk8.red(formatContractError(err)));
4803
+ console.error(chalk9.red(formatContractError(err)));
4520
4804
  process.exit(1);
4521
4805
  }
4522
4806
  });
4523
4807
  syndicate.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) => {
4524
4808
  resolveVault(opts);
4525
- const spinner = ora7("Removing depositor...").start();
4809
+ const spinner = ora8("Removing depositor...").start();
4526
4810
  try {
4527
4811
  const depositor = validateAddress(opts.depositor, "depositor");
4528
4812
  const hash = await removeDepositor(depositor);
4529
4813
  spinner.succeed(`Depositor removed: ${hash}`);
4530
- console.log(chalk8.dim(` ${getExplorerUrl(hash)}`));
4814
+ console.log(chalk9.dim(` ${getExplorerUrl(hash)}`));
4531
4815
  } catch (err) {
4532
4816
  spinner.fail("Removal failed");
4533
- console.error(chalk8.red(formatContractError(err)));
4817
+ console.error(chalk9.red(formatContractError(err)));
4534
4818
  process.exit(1);
4535
4819
  }
4536
4820
  });
4537
4821
  syndicate.command("add").description("Register an agent on a syndicate 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) => {
4538
- const spinner = ora7("Verifying creator...").start();
4822
+ const spinner = ora8("Verifying creator...").start();
4539
4823
  try {
4540
4824
  resolveVault(opts);
4541
4825
  const vaultAddress = getVaultAddress();
@@ -4550,15 +4834,15 @@ syndicate.command("add").description("Register an agent on a syndicate vault (cr
4550
4834
  if (opts.agentId) {
4551
4835
  agentId = BigInt(opts.agentId);
4552
4836
  } else {
4553
- const { AGENT_REGISTRY: AGENT_REGISTRY2 } = await import("./addresses-J4NSZRGB.js");
4554
- const registry = AGENT_REGISTRY2().IDENTITY_REGISTRY;
4555
- if (registry === "0x0000000000000000000000000000000000000000") {
4837
+ const { AGENT_REGISTRY: AGENT_REGISTRY2 } = await import("./addresses-JBIU5U3T.js");
4838
+ const registry2 = AGENT_REGISTRY2().IDENTITY_REGISTRY;
4839
+ if (registry2 === "0x0000000000000000000000000000000000000000") {
4556
4840
  agentId = 0n;
4557
4841
  } else {
4558
4842
  spinner.text = "Looking up ERC-8004 identity from wallet...";
4559
4843
  const client = getPublicClient();
4560
4844
  const balance = await client.readContract({
4561
- address: registry,
4845
+ address: registry2,
4562
4846
  abi: [{
4563
4847
  name: "balanceOf",
4564
4848
  type: "function",
@@ -4571,11 +4855,11 @@ syndicate.command("add").description("Register an agent on a syndicate vault (cr
4571
4855
  });
4572
4856
  if (balance === 0n) {
4573
4857
  spinner.fail("Agent wallet does not own an ERC-8004 identity NFT");
4574
- console.error(chalk8.dim(" Mint one first: sherwood identity mint --name <name>"));
4858
+ console.error(chalk9.dim(" Mint one first: sherwood identity mint --name <name>"));
4575
4859
  process.exit(1);
4576
4860
  }
4577
4861
  const tokenId = await client.readContract({
4578
- address: registry,
4862
+ address: registry2,
4579
4863
  abi: [{
4580
4864
  name: "tokenOfOwnerByIndex",
4581
4865
  type: "function",
@@ -4587,13 +4871,13 @@ syndicate.command("add").description("Register an agent on a syndicate vault (cr
4587
4871
  args: [agentWallet, 0n]
4588
4872
  });
4589
4873
  agentId = tokenId;
4590
- console.log(chalk8.dim(` Resolved agent ID: #${agentId}`));
4874
+ console.log(chalk9.dim(` Resolved agent ID: #${agentId}`));
4591
4875
  }
4592
4876
  }
4593
4877
  spinner.text = "Registering agent...";
4594
4878
  const hash = await registerAgent(agentId, agentWallet);
4595
4879
  spinner.succeed(`Agent registered: ${hash}`);
4596
- console.log(chalk8.dim(` ${getExplorerUrl(hash)}`));
4880
+ console.log(chalk9.dim(` ${getExplorerUrl(hash)}`));
4597
4881
  try {
4598
4882
  const xmtp = await loadXmtp();
4599
4883
  const xmtpClient = await xmtp.getXmtpClient();
@@ -4605,14 +4889,14 @@ syndicate.command("add").description("Register an agent on a syndicate vault (cr
4605
4889
  syndicate: subdomain,
4606
4890
  timestamp: Math.floor(Date.now() / 1e3)
4607
4891
  });
4608
- console.log(chalk8.dim(` Added to chat: ${subdomain}`));
4892
+ console.log(chalk9.dim(` Added to chat: ${subdomain}`));
4609
4893
  } catch {
4610
- console.warn(chalk8.yellow(" \u26A0 Could not add agent to chat group"));
4611
- console.warn(chalk8.dim(` If no group exists, run: sherwood chat ${subdomain} init`));
4894
+ console.warn(chalk9.yellow(" \u26A0 Could not add agent to chat group"));
4895
+ console.warn(chalk9.dim(` If no group exists, run: sherwood chat ${subdomain} init`));
4612
4896
  }
4613
4897
  } catch (err) {
4614
4898
  spinner.fail("Registration failed");
4615
- console.error(chalk8.red(formatContractError(err)));
4899
+ console.error(chalk9.red(formatContractError(err)));
4616
4900
  process.exit(1);
4617
4901
  }
4618
4902
  });
@@ -4620,7 +4904,7 @@ syndicate.command("share").description("Print the shareable dashboard URL for yo
4620
4904
  try {
4621
4905
  const subdomain = opts.subdomain || getPrimarySyndicate(getChain().id)?.subdomain;
4622
4906
  if (!subdomain) {
4623
- console.error(chalk8.red(" No syndicate configured. Pass --subdomain <name> or run 'syndicate create/join' first."));
4907
+ console.error(chalk9.red(" No syndicate configured. Pass --subdomain <name> or run 'syndicate create/join' first."));
4624
4908
  process.exit(1);
4625
4909
  }
4626
4910
  const syndicateInfo = await resolveSyndicate(subdomain);
@@ -4628,13 +4912,13 @@ syndicate.command("share").description("Print the shareable dashboard URL for yo
4628
4912
  const refParam = agentId ? `?ref=${agentId}` : "";
4629
4913
  const dashboardUrl = `https://sherwood.sh/syndicate/${subdomain}${refParam}`;
4630
4914
  console.log();
4631
- console.log(LABEL4(" \u25C6 Share Your Syndicate"));
4632
- SEP4();
4633
- console.log(W4(` Dashboard: ${G4(dashboardUrl)}`));
4634
- console.log(W4(` ENS: ${DIM4(`${subdomain}.sherwoodagent.eth`)}`));
4635
- console.log(W4(` Vault: ${DIM4(syndicateInfo.vault)}`));
4636
- console.log(W4(` Join CLI: ${DIM4(`sherwood syndicate join --subdomain ${subdomain}`)}`));
4637
- SEP4();
4915
+ console.log(LABEL5(" \u25C6 Share Your Syndicate"));
4916
+ SEP5();
4917
+ console.log(W5(` Dashboard: ${G5(dashboardUrl)}`));
4918
+ console.log(W5(` ENS: ${DIM5(`${subdomain}.sherwoodagent.eth`)}`));
4919
+ console.log(W5(` Vault: ${DIM5(syndicateInfo.vault)}`));
4920
+ console.log(W5(` Join CLI: ${DIM5(`sherwood syndicate join --subdomain ${subdomain}`)}`));
4921
+ SEP5();
4638
4922
  try {
4639
4923
  const { exec } = await import("child_process");
4640
4924
  const platform = (await import("os")).platform();
@@ -4642,17 +4926,17 @@ syndicate.command("share").description("Print the shareable dashboard URL for yo
4642
4926
  const proc = exec(cmd);
4643
4927
  proc.stdin?.write(dashboardUrl);
4644
4928
  proc.stdin?.end();
4645
- console.log(G4(" \u2713 Dashboard URL copied to clipboard"));
4929
+ console.log(G5(" \u2713 Dashboard URL copied to clipboard"));
4646
4930
  } catch {
4647
4931
  }
4648
4932
  console.log();
4649
4933
  } catch (err) {
4650
- console.error(chalk8.red(` \u2716 ${formatContractError(err)}`));
4934
+ console.error(chalk9.red(` \u2716 ${formatContractError(err)}`));
4651
4935
  process.exit(1);
4652
4936
  }
4653
4937
  });
4654
4938
  syndicate.command("join").description("Request to join a syndicate (creates an EAS attestation)").option("--subdomain <name>", "Syndicate subdomain to join").option("--ref <agentId>", "Referrer agent ID (from invite link)").option("--message <text>", "Message to the creator", "Requesting to join your syndicate").action(async (opts) => {
4655
- const spinner = ora7("Resolving syndicate...").start();
4939
+ const spinner = ora8("Resolving syndicate...").start();
4656
4940
  try {
4657
4941
  const subdomain = opts.subdomain || getPrimarySyndicate(getChain().id)?.subdomain;
4658
4942
  if (!subdomain) {
@@ -4674,17 +4958,17 @@ syndicate.command("join").description("Request to join a syndicate (creates an E
4674
4958
  try {
4675
4959
  const xmtp = await loadXmtp();
4676
4960
  await xmtp.getXmtpClient();
4677
- console.log(chalk8.dim(" XMTP identity ready"));
4961
+ console.log(chalk9.dim(" XMTP identity ready"));
4678
4962
  } catch {
4679
- console.warn(chalk8.yellow(" \u26A0 Could not initialize XMTP identity"));
4963
+ console.warn(chalk9.yellow(" \u26A0 Could not initialize XMTP identity"));
4680
4964
  }
4681
4965
  try {
4682
4966
  const cron = await loadCron();
4683
4967
  const cronResult = cron.registerSyndicateCrons(subdomain, isTestnet(), getNotifyTo());
4684
4968
  if (cronResult.isOpenClaw && cronResult.registered) {
4685
- console.log(chalk8.green(" \u2713 Participation crons registered"));
4969
+ console.log(chalk9.green(" \u2713 Participation crons registered"));
4686
4970
  } else if (!cronResult.isOpenClaw) {
4687
- console.log(chalk8.dim(" Tip: Set up a scheduled process to run `sherwood session check " + subdomain + "` periodically"));
4971
+ console.log(chalk9.dim(" Tip: Set up a scheduled process to run `sherwood session check " + subdomain + "` periodically"));
4688
4972
  }
4689
4973
  } catch {
4690
4974
  }
@@ -4697,14 +4981,14 @@ syndicate.command("join").description("Request to join a syndicate (creates an E
4697
4981
  );
4698
4982
  if (existingRequest) {
4699
4983
  spinner.succeed("You already have a pending join request for this syndicate");
4700
- console.log(chalk8.dim(` Attestation: ${existingRequest.uid}`));
4701
- console.log(chalk8.dim(` Submitted: ${new Date(existingRequest.time * 1e3).toLocaleString()}`));
4984
+ console.log(chalk9.dim(` Attestation: ${existingRequest.uid}`));
4985
+ console.log(chalk9.dim(` Submitted: ${new Date(existingRequest.time * 1e3).toLocaleString()}`));
4702
4986
  try {
4703
4987
  const xmtp = await loadXmtp();
4704
4988
  await xmtp.getXmtpClient();
4705
- console.log(chalk8.dim(" XMTP identity ready"));
4989
+ console.log(chalk9.dim(" XMTP identity ready"));
4706
4990
  } catch {
4707
- console.warn(chalk8.yellow(" \u26A0 Could not initialize XMTP identity"));
4991
+ console.warn(chalk9.yellow(" \u26A0 Could not initialize XMTP identity"));
4708
4992
  }
4709
4993
  return;
4710
4994
  }
@@ -4725,7 +5009,7 @@ syndicate.command("join").description("Request to join a syndicate (creates an E
4725
5009
  spinner.succeed("Join request created (XMTP identity ready)");
4726
5010
  } catch {
4727
5011
  spinner.succeed("Join request created");
4728
- console.warn(chalk8.yellow(" \u26A0 Could not initialize XMTP identity \u2014 creator may not be able to auto-add you to chat"));
5012
+ console.warn(chalk9.yellow(" \u26A0 Could not initialize XMTP identity \u2014 creator may not be able to auto-add you to chat"));
4729
5013
  }
4730
5014
  addSyndicate(getChain().id, { subdomain, vault: syndicate2.vault, role: "agent" });
4731
5015
  setPrimarySyndicate(getChain().id, subdomain);
@@ -4733,34 +5017,34 @@ syndicate.command("join").description("Request to join a syndicate (creates an E
4733
5017
  const cron = await loadCron();
4734
5018
  const cronResult = cron.registerSyndicateCrons(subdomain, isTestnet(), getNotifyTo());
4735
5019
  if (cronResult.isOpenClaw && cronResult.registered) {
4736
- console.log(G4(" \u2713 Participation crons registered (will activate after approval)"));
5020
+ console.log(G5(" \u2713 Participation crons registered (will activate after approval)"));
4737
5021
  } else if (!cronResult.isOpenClaw) {
4738
- console.log(DIM4(" Tip: Set up a scheduled process to run `sherwood session check " + subdomain + "` periodically"));
5022
+ console.log(DIM5(" Tip: Set up a scheduled process to run `sherwood session check " + subdomain + "` periodically"));
4739
5023
  }
4740
5024
  } catch {
4741
5025
  }
4742
5026
  console.log();
4743
- console.log(LABEL4(" \u25C6 Join Request Submitted"));
4744
- SEP4();
4745
- console.log(W4(` Syndicate: ${G4(`${subdomain}.sherwoodagent.eth`)}`));
4746
- console.log(W4(` Agent ID: #${agentId}`));
4747
- console.log(W4(` Creator: ${DIM4(syndicate2.creator)}`));
4748
- console.log(W4(` Attestation: ${DIM4(uid)}`));
4749
- console.log(W4(` EAS Scan: ${DIM4(getEasScanUrl(uid))}`));
4750
- console.log(W4(` Explorer: ${DIM4(getExplorerUrl(hash))}`));
4751
- SEP4();
4752
- console.log(G4(" \u2713 Syndicate saved to ~/.sherwood/config.json (set as primary)"));
4753
- console.log(G4(" \u2713 The creator can review with:"));
4754
- console.log(DIM4(` sherwood syndicate requests --subdomain ${subdomain}`));
5027
+ console.log(LABEL5(" \u25C6 Join Request Submitted"));
5028
+ SEP5();
5029
+ console.log(W5(` Syndicate: ${G5(`${subdomain}.sherwoodagent.eth`)}`));
5030
+ console.log(W5(` Agent ID: #${agentId}`));
5031
+ console.log(W5(` Creator: ${DIM5(syndicate2.creator)}`));
5032
+ console.log(W5(` Attestation: ${DIM5(uid)}`));
5033
+ console.log(W5(` EAS Scan: ${DIM5(getEasScanUrl(uid))}`));
5034
+ console.log(W5(` Explorer: ${DIM5(getExplorerUrl(hash))}`));
5035
+ SEP5();
5036
+ console.log(G5(" \u2713 Syndicate saved to ~/.sherwood/config.json (set as primary)"));
5037
+ console.log(G5(" \u2713 The creator can review with:"));
5038
+ console.log(DIM5(` sherwood syndicate requests --subdomain ${subdomain}`));
4755
5039
  console.log();
4756
5040
  } catch (err) {
4757
5041
  spinner.fail("Join request failed");
4758
- console.error(chalk8.red(formatContractError(err)));
5042
+ console.error(chalk9.red(formatContractError(err)));
4759
5043
  process.exit(1);
4760
5044
  }
4761
5045
  });
4762
5046
  syndicate.command("requests").description("View pending join requests for a syndicate (creator only)").option("--subdomain <name>", "Syndicate subdomain").option("--vault <address>", "Vault address (default: from config)").action(async (opts) => {
4763
- const spinner = ora7("Loading join requests...").start();
5047
+ const spinner = ora8("Loading join requests...").start();
4764
5048
  try {
4765
5049
  let creatorAddress;
4766
5050
  let subdomain;
@@ -4796,39 +5080,39 @@ syndicate.command("requests").description("View pending join requests for a synd
4796
5080
  );
4797
5081
  spinner.stop();
4798
5082
  if (requests.length === 0) {
4799
- console.log(DIM4("\n No pending join requests.\n"));
5083
+ console.log(DIM5("\n No pending join requests.\n"));
4800
5084
  return;
4801
5085
  }
4802
5086
  console.log();
4803
- console.log(LABEL4(` \u25C6 Pending Join Requests (${requests.length})`));
4804
- SEP4();
5087
+ console.log(LABEL5(` \u25C6 Pending Join Requests (${requests.length})`));
5088
+ SEP5();
4805
5089
  for (let i = 0; i < requests.length; i++) {
4806
5090
  const req = requests[i];
4807
5091
  const date = new Date(req.time * 1e3).toLocaleString();
4808
5092
  const referrer = parseReferrer(req.decoded.message);
4809
5093
  const cleanMessage = stripReferrerPrefix(req.decoded.message);
4810
- console.log(W4(` ${i + 1}. Agent #${req.decoded.agentId} ${DIM4(`(${req.attester})`)}`));
4811
- console.log(DIM4(` Message: "${cleanMessage}"`));
5094
+ console.log(W5(` ${i + 1}. Agent #${req.decoded.agentId} ${DIM5(`(${req.attester})`)}`));
5095
+ console.log(DIM5(` Message: "${cleanMessage}"`));
4812
5096
  if (referrer !== null) {
4813
- console.log(G4(` Referred by: Agent #${referrer}`));
5097
+ console.log(G5(` Referred by: Agent #${referrer}`));
4814
5098
  }
4815
- console.log(DIM4(` Requested: ${date}`));
4816
- console.log(DIM4(` Attestation: ${req.uid}`));
5099
+ console.log(DIM5(` Requested: ${date}`));
5100
+ console.log(DIM5(` Attestation: ${req.uid}`));
4817
5101
  console.log();
4818
5102
  }
4819
- console.log(G4(" To approve:"));
4820
- console.log(DIM4(` sherwood syndicate approve --agent-id <id> --wallet <addr>`));
4821
- console.log(G4(" To reject:"));
4822
- console.log(DIM4(` sherwood syndicate reject --attestation <uid>`));
5103
+ console.log(G5(" To approve:"));
5104
+ console.log(DIM5(` sherwood syndicate approve --agent-id <id> --wallet <addr>`));
5105
+ console.log(G5(" To reject:"));
5106
+ console.log(DIM5(` sherwood syndicate reject --attestation <uid>`));
4823
5107
  console.log();
4824
5108
  } catch (err) {
4825
5109
  spinner.fail("Failed to load requests");
4826
- console.error(chalk8.red(formatContractError(err)));
5110
+ console.error(chalk9.red(formatContractError(err)));
4827
5111
  process.exit(1);
4828
5112
  }
4829
5113
  });
4830
5114
  syndicate.command("approve").description("Approve an agent join request (registers agent + creates EAS approval)").option("--vault <address>", "Vault address (default: from config)").option("--subdomain <name>", "Syndicate subdomain (alternative to --vault)").requiredOption("--agent-id <id>", "Agent's ERC-8004 identity token ID").requiredOption("--wallet <address>", "Agent wallet address").action(async (opts) => {
4831
- const spinner = ora7("Verifying creator...").start();
5115
+ const spinner = ora8("Verifying creator...").start();
4832
5116
  try {
4833
5117
  const approveSubdomain = opts.subdomain || getPrimarySyndicate(getChain().id)?.subdomain;
4834
5118
  if (approveSubdomain && !opts.vault) {
@@ -4853,11 +5137,11 @@ syndicate.command("approve").description("Approve an agent join request (registe
4853
5137
  agentWallet
4854
5138
  );
4855
5139
  agentWasRegistered = true;
4856
- console.log(DIM4(` Agent registered: ${getExplorerUrl(regHash)}`));
5140
+ console.log(DIM5(` Agent registered: ${getExplorerUrl(regHash)}`));
4857
5141
  } catch (regErr) {
4858
5142
  const msg = regErr instanceof Error ? regErr.message : String(regErr);
4859
5143
  if (msg.includes("0xe098d3ee") || msg.includes("AgentAlreadyRegistered")) {
4860
- console.log(DIM4(" Agent already registered on vault \u2014 skipping"));
5144
+ console.log(DIM5(" Agent already registered on vault \u2014 skipping"));
4861
5145
  } else {
4862
5146
  throw regErr;
4863
5147
  }
@@ -4873,7 +5157,7 @@ syndicate.command("approve").description("Approve an agent join request (registe
4873
5157
  let approvalUid;
4874
5158
  if (alreadyApproved) {
4875
5159
  approvalUid = alreadyApproved.uid;
4876
- console.log(DIM4(` Approval attestation already exists \u2014 skipping`));
5160
+ console.log(DIM5(` Approval attestation already exists \u2014 skipping`));
4877
5161
  } else {
4878
5162
  spinner.text = "Creating approval attestation...";
4879
5163
  const result = await createApproval(
@@ -4896,48 +5180,48 @@ syndicate.command("approve").description("Approve an agent join request (registe
4896
5180
  syndicate: subdomain,
4897
5181
  timestamp: Math.floor(Date.now() / 1e3)
4898
5182
  });
4899
- console.log(DIM4(` Added to chat: ${subdomain}`));
5183
+ console.log(DIM5(` Added to chat: ${subdomain}`));
4900
5184
  } catch {
4901
- console.warn(chalk8.yellow(" \u26A0 Could not add agent to chat group"));
4902
- console.warn(chalk8.dim(` If no group exists, run: sherwood chat ${subdomain} init`));
5185
+ console.warn(chalk9.yellow(" \u26A0 Could not add agent to chat group"));
5186
+ console.warn(chalk9.dim(` If no group exists, run: sherwood chat ${subdomain} init`));
4903
5187
  }
4904
5188
  spinner.succeed("Agent approved and registered");
4905
5189
  console.log();
4906
- console.log(LABEL4(" \u25C6 Agent Approved"));
4907
- SEP4();
4908
- console.log(W4(` Agent ID: #${opts.agentId}`));
4909
- console.log(W4(` Wallet: ${G4(opts.wallet)}`));
4910
- console.log(W4(` Approval: ${DIM4(approvalUid)}`));
4911
- console.log(W4(` EAS Scan: ${DIM4(getEasScanUrl(approvalUid))}`));
4912
- SEP4();
5190
+ console.log(LABEL5(" \u25C6 Agent Approved"));
5191
+ SEP5();
5192
+ console.log(W5(` Agent ID: #${opts.agentId}`));
5193
+ console.log(W5(` Wallet: ${G5(opts.wallet)}`));
5194
+ console.log(W5(` Approval: ${DIM5(approvalUid)}`));
5195
+ console.log(W5(` EAS Scan: ${DIM5(getEasScanUrl(approvalUid))}`));
5196
+ SEP5();
4913
5197
  } catch (err) {
4914
5198
  spinner.fail("Approval failed");
4915
- console.error(chalk8.red(formatContractError(err)));
5199
+ console.error(chalk9.red(formatContractError(err)));
4916
5200
  process.exit(1);
4917
5201
  }
4918
5202
  });
4919
5203
  syndicate.command("reject").description("Reject a join request by revoking its attestation").requiredOption("--attestation <uid>", "Join request attestation UID to revoke").action(async (opts) => {
4920
- const spinner = ora7("Revoking attestation...").start();
5204
+ const spinner = ora8("Revoking attestation...").start();
4921
5205
  try {
4922
5206
  const hash = await revokeAttestation(
4923
5207
  EAS_SCHEMAS().SYNDICATE_JOIN_REQUEST,
4924
5208
  opts.attestation
4925
5209
  );
4926
5210
  spinner.succeed("Join request rejected");
4927
- console.log(DIM4(` ${getExplorerUrl(hash)}`));
5211
+ console.log(DIM5(` ${getExplorerUrl(hash)}`));
4928
5212
  } catch (err) {
4929
5213
  spinner.fail("Rejection failed");
4930
- console.error(chalk8.red(formatContractError(err)));
5214
+ console.error(chalk9.red(formatContractError(err)));
4931
5215
  process.exit(1);
4932
5216
  }
4933
5217
  });
4934
5218
  syndicate.command("leave").description("Leave a syndicate \u2014 removes participation crons and session state").option("--subdomain <name>", "Syndicate subdomain to leave").action(async (opts) => {
4935
5219
  const subdomain = opts.subdomain || getPrimarySyndicate(getChain().id)?.subdomain;
4936
5220
  if (!subdomain) {
4937
- console.error(chalk8.red(" No syndicate configured. Pass --subdomain <name>."));
5221
+ console.error(chalk9.red(" No syndicate configured. Pass --subdomain <name>."));
4938
5222
  process.exit(1);
4939
5223
  }
4940
- const spinner = ora7("Cleaning up...").start();
5224
+ const spinner = ora8("Cleaning up...").start();
4941
5225
  try {
4942
5226
  let cronsRemoved = false;
4943
5227
  try {
@@ -4950,17 +5234,17 @@ syndicate.command("leave").description("Leave a syndicate \u2014 removes partici
4950
5234
  resetSession(subdomain);
4951
5235
  spinner.succeed("Left syndicate");
4952
5236
  if (cronsRemoved) {
4953
- console.log(G4(" \u2713 Participation crons removed"));
5237
+ console.log(G5(" \u2713 Participation crons removed"));
4954
5238
  }
4955
- console.log(G4(" \u2713 Session state cleared"));
5239
+ console.log(G5(" \u2713 Session state cleared"));
4956
5240
  console.log();
4957
- console.log(chalk8.dim(" Note: This does not remove you on-chain. To exit your position:"));
4958
- console.log(chalk8.dim(" sherwood vault balance \u2014 check your LP share balance"));
4959
- console.log(chalk8.dim(" Redeem shares via the vault contract or dashboard"));
5241
+ console.log(chalk9.dim(" Note: This does not remove you on-chain. To exit your position:"));
5242
+ console.log(chalk9.dim(" sherwood vault balance \u2014 check your LP share balance"));
5243
+ console.log(chalk9.dim(" Redeem shares via the vault contract or dashboard"));
4960
5244
  console.log();
4961
5245
  } catch (err) {
4962
5246
  spinner.fail("Leave failed");
4963
- console.error(chalk8.red(err instanceof Error ? err.message : String(err)));
5247
+ console.error(chalk9.red(err instanceof Error ? err.message : String(err)));
4964
5248
  process.exit(1);
4965
5249
  }
4966
5250
  });
@@ -4971,21 +5255,21 @@ syndicate.command("set-primary").description("Set the active syndicate for CLI c
4971
5255
  if (!opts.subdomain && !opts.vault) {
4972
5256
  const primary = getPrimarySyndicate(chainId);
4973
5257
  if (memberships.length === 0) {
4974
- console.log(DIM4("\n No syndicates saved. Create or join one first.\n"));
5258
+ console.log(DIM5("\n No syndicates saved. Create or join one first.\n"));
4975
5259
  return;
4976
5260
  }
4977
5261
  console.log();
4978
- console.log(LABEL4(" \u25C6 Your Syndicates"));
4979
- SEP4();
5262
+ console.log(LABEL5(" \u25C6 Your Syndicates"));
5263
+ SEP5();
4980
5264
  for (const m of memberships) {
4981
5265
  const isPrimary = primary?.subdomain === m.subdomain;
4982
- const marker = isPrimary ? G4(" \u2605") : "";
4983
- console.log(W4(` ${m.subdomain}.sherwoodagent.eth${marker} ${DIM4(`(${m.role})`)}`));
4984
- console.log(DIM4(` vault: ${m.vault}`));
5266
+ const marker = isPrimary ? G5(" \u2605") : "";
5267
+ console.log(W5(` ${m.subdomain}.sherwoodagent.eth${marker} ${DIM5(`(${m.role})`)}`));
5268
+ console.log(DIM5(` vault: ${m.vault}`));
4985
5269
  }
4986
- SEP4();
5270
+ SEP5();
4987
5271
  if (memberships.length > 1) {
4988
- console.log(DIM4(" Switch with: sherwood syndicate set-primary --subdomain <name>"));
5272
+ console.log(DIM5(" Switch with: sherwood syndicate set-primary --subdomain <name>"));
4989
5273
  }
4990
5274
  console.log();
4991
5275
  return;
@@ -5011,15 +5295,15 @@ syndicate.command("set-primary").description("Set the active syndicate for CLI c
5011
5295
  }
5012
5296
  }
5013
5297
  if (!target) {
5014
- console.error(chalk8.red(" Could not resolve syndicate. Pass --subdomain or --vault."));
5298
+ console.error(chalk9.red(" Could not resolve syndicate. Pass --subdomain or --vault."));
5015
5299
  process.exit(1);
5016
5300
  }
5017
5301
  setPrimarySyndicate(chainId, target);
5018
- console.log(G4(`
5302
+ console.log(G5(`
5019
5303
  \u2713 Primary syndicate set to ${target}.sherwoodagent.eth
5020
5304
  `));
5021
5305
  } catch (err) {
5022
- console.error(chalk8.red(formatContractError(err)));
5306
+ console.error(chalk9.red(formatContractError(err)));
5023
5307
  process.exit(1);
5024
5308
  }
5025
5309
  });
@@ -5027,18 +5311,18 @@ var vaultCmd = program.command("vault");
5027
5311
  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)").action(async (opts) => {
5028
5312
  resolveVault(opts);
5029
5313
  const decimals = await getAssetDecimals();
5030
- const amount = parseUnits4(opts.amount, decimals);
5314
+ const amount = parseUnits5(opts.amount, decimals);
5031
5315
  try {
5032
5316
  if (!opts.useEth) {
5033
5317
  await preflightDeposit(amount);
5034
5318
  }
5035
5319
  } catch (err) {
5036
- console.error(chalk8.red(`
5320
+ console.error(chalk9.red(`
5037
5321
  \u2716 ${err instanceof Error ? err.message : String(err)}
5038
5322
  `));
5039
5323
  process.exit(1);
5040
5324
  }
5041
- const spinner = ora7(`Depositing ${opts.amount}...`).start();
5325
+ const spinner = ora8(`Depositing ${opts.amount}...`).start();
5042
5326
  try {
5043
5327
  let hash;
5044
5328
  if (opts.useEth) {
@@ -5048,22 +5332,22 @@ vaultCmd.command("deposit").description("Deposit into a vault").option("--vault
5048
5332
  hash = await deposit(amount);
5049
5333
  }
5050
5334
  spinner.succeed(`Deposited: ${hash}`);
5051
- console.log(chalk8.dim(` ${getExplorerUrl(hash)}`));
5335
+ console.log(chalk9.dim(` ${getExplorerUrl(hash)}`));
5052
5336
  } catch (err) {
5053
5337
  spinner.fail("Deposit failed");
5054
- console.error(chalk8.red(formatContractError(err)));
5338
+ console.error(chalk9.red(formatContractError(err)));
5055
5339
  process.exit(1);
5056
5340
  }
5057
5341
  });
5058
5342
  vaultCmd.command("info").description("Display vault state").option("--vault <address>", "Vault address (default: from config)").action(async (opts) => {
5059
5343
  resolveVault(opts);
5060
- const spinner = ora7("Loading vault info...").start();
5344
+ const spinner = ora8("Loading vault info...").start();
5061
5345
  try {
5062
5346
  const info = await getVaultInfo();
5063
5347
  spinner.stop();
5064
5348
  console.log();
5065
- console.log(chalk8.bold("Vault Info"));
5066
- console.log(chalk8.dim("\u2500".repeat(40)));
5349
+ console.log(chalk9.bold("Vault Info"));
5350
+ console.log(chalk9.dim("\u2500".repeat(40)));
5067
5351
  console.log(` Address: ${info.address}`);
5068
5352
  console.log(` Total Assets: ${info.totalAssets}`);
5069
5353
  console.log(` Agent Count: ${info.agentCount}`);
@@ -5072,26 +5356,26 @@ vaultCmd.command("info").description("Display vault state").option("--vault <add
5072
5356
  console.log();
5073
5357
  } catch (err) {
5074
5358
  spinner.fail("Failed to load vault info");
5075
- console.error(chalk8.red(formatContractError(err)));
5359
+ console.error(chalk9.red(formatContractError(err)));
5076
5360
  process.exit(1);
5077
5361
  }
5078
5362
  });
5079
5363
  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) => {
5080
5364
  resolveVault(opts);
5081
- const spinner = ora7("Loading balance...").start();
5365
+ const spinner = ora8("Loading balance...").start();
5082
5366
  try {
5083
5367
  const balance = await getBalance(opts.address);
5084
5368
  spinner.stop();
5085
5369
  console.log();
5086
- console.log(chalk8.bold("LP Position"));
5087
- console.log(chalk8.dim("\u2500".repeat(40)));
5370
+ console.log(chalk9.bold("LP Position"));
5371
+ console.log(chalk9.dim("\u2500".repeat(40)));
5088
5372
  console.log(` Shares: ${balance.shares.toString()}`);
5089
5373
  console.log(` Asset Value: ${balance.assetsValue}`);
5090
5374
  console.log(` % of Vault: ${balance.percentOfVault}`);
5091
5375
  console.log();
5092
5376
  } catch (err) {
5093
5377
  spinner.fail("Failed to load balance");
5094
- console.error(chalk8.red(formatContractError(err)));
5378
+ console.error(chalk9.red(formatContractError(err)));
5095
5379
  process.exit(1);
5096
5380
  }
5097
5381
  });
@@ -5102,22 +5386,22 @@ vaultCmd.command("redeem").description("Redeem vault shares for the underlying a
5102
5386
  let shares;
5103
5387
  try {
5104
5388
  if (opts.shares) {
5105
- shares = parseUnits4(opts.shares, shareDecimals);
5389
+ shares = parseUnits5(opts.shares, shareDecimals);
5106
5390
  } else {
5107
5391
  shares = await getShareBalance();
5108
5392
  if (shares === 0n) {
5109
- console.error(chalk8.red("\n \u2716 No shares to redeem.\n"));
5393
+ console.error(chalk9.red("\n \u2716 No shares to redeem.\n"));
5110
5394
  process.exit(1);
5111
5395
  }
5112
5396
  }
5113
5397
  } catch (err) {
5114
- console.error(chalk8.red(`
5398
+ console.error(chalk9.red(`
5115
5399
  \u2716 ${err instanceof Error ? err.message : String(err)}
5116
5400
  `));
5117
5401
  process.exit(1);
5118
5402
  }
5119
- if (opts.receiver && !isAddress5(opts.receiver)) {
5120
- console.error(chalk8.red(`
5403
+ if (opts.receiver && !isAddress6(opts.receiver)) {
5404
+ console.error(chalk9.red(`
5121
5405
  \u2716 Invalid receiver address: ${opts.receiver}
5122
5406
  `));
5123
5407
  process.exit(1);
@@ -5125,24 +5409,24 @@ vaultCmd.command("redeem").description("Redeem vault shares for the underlying a
5125
5409
  try {
5126
5410
  await preflightRedeem(shares);
5127
5411
  } catch (err) {
5128
- console.error(chalk8.red(`
5412
+ console.error(chalk9.red(`
5129
5413
  \u2716 ${err instanceof Error ? err.message : String(err)}
5130
5414
  `));
5131
5415
  process.exit(1);
5132
5416
  }
5133
- const sharesDisplay = formatUnits4(shares, shareDecimals);
5134
- const spinner = ora7(`Redeeming ${sharesDisplay} shares...`).start();
5417
+ const sharesDisplay = formatUnits5(shares, shareDecimals);
5418
+ const spinner = ora8(`Redeeming ${sharesDisplay} shares...`).start();
5135
5419
  try {
5136
5420
  const { hash, assetsOut } = await redeem(
5137
5421
  shares,
5138
5422
  opts.receiver
5139
5423
  );
5140
5424
  spinner.succeed(`Redeemed: ${hash}`);
5141
- console.log(chalk8.dim(` ${getExplorerUrl(hash)}`));
5142
- console.log(` Assets received: ${formatUnits4(assetsOut, assetDecimals)}`);
5425
+ console.log(chalk9.dim(` ${getExplorerUrl(hash)}`));
5426
+ console.log(` Assets received: ${formatUnits5(assetsOut, assetDecimals)}`);
5143
5427
  } catch (err) {
5144
5428
  spinner.fail("Redeem failed");
5145
- console.error(chalk8.red(formatContractError(err)));
5429
+ console.error(chalk9.red(formatContractError(err)));
5146
5430
  process.exit(1);
5147
5431
  }
5148
5432
  });
@@ -5160,28 +5444,29 @@ ${info.name} (${info.type})`);
5160
5444
  }
5161
5445
  });
5162
5446
  try {
5163
- const { registerChatCommands } = await import("./chat-EYCDCZUA.js");
5447
+ const { registerChatCommands } = await import("./chat-K4LW776Q.js");
5164
5448
  registerChatCommands(program);
5165
5449
  } catch {
5166
5450
  program.command("chat <name> [action] [actionArgs...]").description("Syndicate chat (XMTP) \u2014 requires @xmtp/cli").action(() => {
5167
- console.error(chalk8.red("XMTP CLI not available."));
5168
- console.error(chalk8.dim("Install with: npm install -g @xmtp/cli"));
5169
- console.error(chalk8.dim("Or reinstall: npm i -g @sherwoodagent/cli"));
5451
+ console.error(chalk9.red("XMTP CLI not available."));
5452
+ console.error(chalk9.dim("Install with: npm install -g @xmtp/cli"));
5453
+ console.error(chalk9.dim("Or reinstall: npm i -g @sherwoodagent/cli"));
5170
5454
  process.exit(1);
5171
5455
  });
5172
5456
  }
5173
- var { registerSessionCommands } = await import("./session-NL6KF2Q5.js");
5457
+ var { registerSessionCommands } = await import("./session-2TBX4UTS.js");
5174
5458
  registerSessionCommands(program);
5175
5459
  registerVeniceCommands(program);
5176
5460
  registerAllowanceCommands(program);
5177
5461
  registerIdentityCommands(program);
5178
5462
  registerProposalCommands(program);
5179
5463
  registerGovernorCommands(program);
5180
- var { registerResearchCommands } = await import("./research-HXOXZA4N.js");
5464
+ registerGuardianCommands(program);
5465
+ var { registerResearchCommands } = await import("./research-K62TKFLF.js");
5181
5466
  registerResearchCommands(program);
5182
5467
  var { registerAgentCommands } = await import("./agent-XBYSALOA.js");
5183
5468
  registerAgentCommands(program);
5184
- var { registerTradeCommands } = await import("./trade-WMPWF6RT.js");
5469
+ var { registerTradeCommands } = await import("./trade-S3L2CNV4.js");
5185
5470
  registerTradeCommands(program);
5186
5471
  var configCmd = program.command("config");
5187
5472
  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 SyndicateVault 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("--xmtp-group <subdomain:groupId>", "Cache an XMTP group ID for a syndicate (e.g. my-fund:abc123)").action((opts) => {
@@ -5189,53 +5474,53 @@ configCmd.command("set").description("Save settings to ~/.sherwood/config.json (
5189
5474
  if (opts.privateKey) {
5190
5475
  setPrivateKey(opts.privateKey);
5191
5476
  const account = getAccount();
5192
- console.log(chalk8.green("Private key saved to ~/.sherwood/config.json"));
5193
- console.log(chalk8.dim(` Wallet: ${account.address}`));
5477
+ console.log(chalk9.green("Private key saved to ~/.sherwood/config.json"));
5478
+ console.log(chalk9.dim(` Wallet: ${account.address}`));
5194
5479
  saved = true;
5195
5480
  }
5196
5481
  if (opts.vault) {
5197
5482
  const chainId = getChain().id;
5198
5483
  setChainContract(chainId, "vault", opts.vault);
5199
- console.log(chalk8.green(`Vault saved to ~/.sherwood/config.json (chain ${chainId})`));
5200
- console.log(chalk8.dim(` Vault: ${opts.vault}`));
5484
+ console.log(chalk9.green(`Vault saved to ~/.sherwood/config.json (chain ${chainId})`));
5485
+ console.log(chalk9.dim(` Vault: ${opts.vault}`));
5201
5486
  saved = true;
5202
5487
  }
5203
5488
  if (opts.rpc) {
5204
5489
  const network = getNetwork();
5205
5490
  setConfigRpcUrl(network, opts.rpc);
5206
- console.log(chalk8.green(`RPC URL saved for ${network}`));
5207
- console.log(chalk8.dim(` RPC: ${opts.rpc}`));
5491
+ console.log(chalk9.green(`RPC URL saved for ${network}`));
5492
+ console.log(chalk9.dim(` RPC: ${opts.rpc}`));
5208
5493
  saved = true;
5209
5494
  }
5210
5495
  if (opts.notifyTo) {
5211
5496
  setNotifyTo(opts.notifyTo);
5212
- console.log(chalk8.green("Notify destination saved to ~/.sherwood/config.json"));
5213
- console.log(chalk8.dim(` Notify to: ${opts.notifyTo}`));
5497
+ console.log(chalk9.green("Notify destination saved to ~/.sherwood/config.json"));
5498
+ console.log(chalk9.dim(` Notify to: ${opts.notifyTo}`));
5214
5499
  saved = true;
5215
5500
  }
5216
5501
  if (opts.uniswapApiKey) {
5217
5502
  setUniswapApiKey(opts.uniswapApiKey);
5218
- console.log(chalk8.green("Uniswap API key saved to ~/.sherwood/config.json"));
5503
+ console.log(chalk9.green("Uniswap API key saved to ~/.sherwood/config.json"));
5219
5504
  saved = true;
5220
5505
  }
5221
5506
  if (opts.veniceApiKey) {
5222
5507
  setVeniceApiKey(opts.veniceApiKey);
5223
- console.log(chalk8.green("Venice API key saved to ~/.sherwood/config.json"));
5508
+ console.log(chalk9.green("Venice API key saved to ~/.sherwood/config.json"));
5224
5509
  saved = true;
5225
5510
  }
5226
5511
  if (opts.xmtpGroup) {
5227
5512
  const parts = opts.xmtpGroup.split(":");
5228
5513
  if (parts.length !== 2 || !parts[0] || !parts[1]) {
5229
- console.log(chalk8.red("Format: --xmtp-group <subdomain>:<groupId>"));
5514
+ console.log(chalk9.red("Format: --xmtp-group <subdomain>:<groupId>"));
5230
5515
  process.exit(1);
5231
5516
  }
5232
5517
  cacheGroupId(parts[0], parts[1]);
5233
- console.log(chalk8.green(`XMTP group ID cached for ${parts[0]}`));
5234
- console.log(chalk8.dim(` Group ID: ${parts[1]}`));
5518
+ console.log(chalk9.green(`XMTP group ID cached for ${parts[0]}`));
5519
+ console.log(chalk9.dim(` Group ID: ${parts[1]}`));
5235
5520
  saved = true;
5236
5521
  }
5237
5522
  if (!saved) {
5238
- console.log(chalk8.red("Provide at least one of: --private-key, --vault, --rpc, --notify-to, --uniswap-api-key, --venice-api-key, --xmtp-group"));
5523
+ console.log(chalk9.red("Provide at least one of: --private-key, --vault, --rpc, --notify-to, --uniswap-api-key, --venice-api-key, --xmtp-group"));
5239
5524
  process.exit(1);
5240
5525
  }
5241
5526
  });
@@ -5246,25 +5531,25 @@ configCmd.command("show").description("Display current config for the active net
5246
5531
  const config = loadConfig();
5247
5532
  const customRpc = config.rpc?.[network];
5248
5533
  console.log();
5249
- console.log(chalk8.bold(`Sherwood Config`));
5250
- console.log(chalk8.dim("\u2500".repeat(50)));
5251
- console.log(` Network: ${chalk8.cyan(network)} (chain ${chainId})`);
5252
- console.log(` RPC: ${customRpc ? chalk8.green(customRpc) : chalk8.dim("default")}`);
5253
- console.log(` Wallet: ${config.privateKey ? chalk8.green("configured") : chalk8.dim("not set")}`);
5254
- console.log(` Agent ID: ${config.agentId ?? chalk8.dim("not set")}`);
5255
- console.log(` Vault: ${contracts.vault ?? chalk8.dim("not set")}`);
5256
- console.log(` Uniswap: ${getUniswapApiKey() ? chalk8.green("API key configured") : chalk8.dim("not set")}`);
5257
- console.log(` Venice: ${getVeniceApiKey() ? chalk8.green("API key configured") : chalk8.dim("not set")}`);
5534
+ console.log(chalk9.bold(`Sherwood Config`));
5535
+ console.log(chalk9.dim("\u2500".repeat(50)));
5536
+ console.log(` Network: ${chalk9.cyan(network)} (chain ${chainId})`);
5537
+ console.log(` RPC: ${customRpc ? chalk9.green(customRpc) : chalk9.dim("default")}`);
5538
+ console.log(` Wallet: ${config.privateKey ? chalk9.green("configured") : chalk9.dim("not set")}`);
5539
+ console.log(` Agent ID: ${config.agentId ?? chalk9.dim("not set")}`);
5540
+ console.log(` Vault: ${contracts.vault ?? chalk9.dim("not set")}`);
5541
+ console.log(` Uniswap: ${getUniswapApiKey() ? chalk9.green("API key configured") : chalk9.dim("not set")}`);
5542
+ console.log(` Venice: ${getVeniceApiKey() ? chalk9.green("API key configured") : chalk9.dim("not set")}`);
5258
5543
  const groupEntries = Object.entries(config.groupCache || {}).filter(([, v]) => v);
5259
5544
  if (groupEntries.length > 0) {
5260
5545
  console.log();
5261
- console.log(chalk8.bold(" XMTP Groups"));
5546
+ console.log(chalk9.bold(" XMTP Groups"));
5262
5547
  for (const [sub, gid] of groupEntries) {
5263
- console.log(` ${sub}: ${chalk8.cyan(gid)}`);
5548
+ console.log(` ${sub}: ${chalk9.cyan(gid)}`);
5264
5549
  }
5265
5550
  }
5266
5551
  console.log();
5267
- console.log(chalk8.dim(" Config file: ~/.sherwood/config.json"));
5552
+ console.log(chalk9.dim(" Config file: ~/.sherwood/config.json"));
5268
5553
  console.log();
5269
5554
  });
5270
5555
  program.parse();