@sherwoodagent/cli 0.29.1 → 0.38.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/dist/{addresses-NOWMJT4H.js → addresses-6GJP2WAY.js} +4 -4
  2. package/dist/{agent-U6OFXITU.js → agent-NUYY5PF7.js} +1084 -295
  3. package/dist/agent-NUYY5PF7.js.map +1 -0
  4. package/dist/{chat-SIB6GCJF.js → chat-ABL6Z5XZ.js} +8 -8
  5. package/dist/{chunk-OD5JECOR.js → chunk-3RVDBIXD.js} +4 -4
  6. package/dist/{chunk-UW6P2PMP.js → chunk-6X3FGJJO.js} +5 -5
  7. package/dist/{chunk-EYI6JORK.js → chunk-B4AH26UI.js} +2 -2
  8. package/dist/{chunk-H32QA3NV.js → chunk-IJG4CTOI.js} +2 -2
  9. package/dist/{chunk-7W6U6ZC6.js → chunk-LWIPZN5P.js} +5 -5
  10. package/dist/{chunk-BVL3O7UH.js → chunk-O2JHLTDB.js} +4 -4
  11. package/dist/{chunk-C4SYHSY2.js → chunk-ODB2GWA7.js} +4 -4
  12. package/dist/{chunk-N2547R2L.js → chunk-OFR3LCYE.js} +3 -3
  13. package/dist/{chunk-7PDRYBHD.js → chunk-OPKMVIYJ.js} +4 -4
  14. package/dist/{chunk-7PDRYBHD.js.map → chunk-OPKMVIYJ.js.map} +1 -1
  15. package/dist/{chunk-RGOTBJIN.js → chunk-WCBG44IQ.js} +9 -1
  16. package/dist/chunk-WCBG44IQ.js.map +1 -0
  17. package/dist/{client-66VTYDRS.js → client-HKAG55PQ.js} +4 -4
  18. package/dist/{config-YXZKPSZB.js → config-LS7FKZL5.js} +4 -2
  19. package/dist/{eas-YTMCD3UN.js → eas-KBFTHWSI.js} +6 -6
  20. package/dist/{governor-2N3CPFOP.js → governor-KEXLUOGB.js} +6 -6
  21. package/dist/index.js +66 -47
  22. package/dist/index.js.map +1 -1
  23. package/dist/{network-GJA2ZN3O.js → network-KSMKPKNL.js} +3 -3
  24. package/dist/{price-HGBIMFYN.js → price-M5H57DPY.js} +5 -5
  25. package/dist/research-662HNMOG.js +14 -0
  26. package/dist/{research-ECOWBTFP.js → research-W6QW2JJ3.js} +9 -9
  27. package/dist/{session-RTCMOPAQ.js → session-64BCMJIB.js} +10 -10
  28. package/dist/{trade-3HVCELTB.js → trade-7343J4LA.js} +16 -16
  29. package/dist/{xmtp-5FPJN5WE.js → xmtp-EB2CU2LE.js} +20 -15
  30. package/dist/xmtp-EB2CU2LE.js.map +1 -0
  31. package/package.json +7 -5
  32. package/dist/agent-U6OFXITU.js.map +0 -1
  33. package/dist/chunk-RGOTBJIN.js.map +0 -1
  34. package/dist/research-3GNTDKY4.js +0 -14
  35. package/dist/xmtp-5FPJN5WE.js.map +0 -1
  36. /package/dist/{addresses-NOWMJT4H.js.map → addresses-6GJP2WAY.js.map} +0 -0
  37. /package/dist/{chat-SIB6GCJF.js.map → chat-ABL6Z5XZ.js.map} +0 -0
  38. /package/dist/{chunk-OD5JECOR.js.map → chunk-3RVDBIXD.js.map} +0 -0
  39. /package/dist/{chunk-UW6P2PMP.js.map → chunk-6X3FGJJO.js.map} +0 -0
  40. /package/dist/{chunk-EYI6JORK.js.map → chunk-B4AH26UI.js.map} +0 -0
  41. /package/dist/{chunk-H32QA3NV.js.map → chunk-IJG4CTOI.js.map} +0 -0
  42. /package/dist/{chunk-7W6U6ZC6.js.map → chunk-LWIPZN5P.js.map} +0 -0
  43. /package/dist/{chunk-BVL3O7UH.js.map → chunk-O2JHLTDB.js.map} +0 -0
  44. /package/dist/{chunk-C4SYHSY2.js.map → chunk-ODB2GWA7.js.map} +0 -0
  45. /package/dist/{chunk-N2547R2L.js.map → chunk-OFR3LCYE.js.map} +0 -0
  46. /package/dist/{client-66VTYDRS.js.map → client-HKAG55PQ.js.map} +0 -0
  47. /package/dist/{config-YXZKPSZB.js.map → config-LS7FKZL5.js.map} +0 -0
  48. /package/dist/{eas-YTMCD3UN.js.map → eas-KBFTHWSI.js.map} +0 -0
  49. /package/dist/{governor-2N3CPFOP.js.map → governor-KEXLUOGB.js.map} +0 -0
  50. /package/dist/{network-GJA2ZN3O.js.map → network-KSMKPKNL.js.map} +0 -0
  51. /package/dist/{price-HGBIMFYN.js.map → price-M5H57DPY.js.map} +0 -0
  52. /package/dist/{research-3GNTDKY4.js.map → research-662HNMOG.js.map} +0 -0
  53. /package/dist/{research-ECOWBTFP.js.map → research-W6QW2JJ3.js.map} +0 -0
  54. /package/dist/{session-RTCMOPAQ.js.map → session-64BCMJIB.js.map} +0 -0
  55. /package/dist/{trade-3HVCELTB.js.map → trade-7343J4LA.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-UW6P2PMP.js";
12
+ } from "./chunk-6X3FGJJO.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-OD5JECOR.js";
22
+ } from "./chunk-3RVDBIXD.js";
23
23
  import {
24
24
  createSyndicate,
25
25
  getActiveSyndicates,
26
26
  getSyndicate,
27
27
  subdomainExists,
28
28
  updateMetadata
29
- } from "./chunk-BVL3O7UH.js";
29
+ } from "./chunk-O2JHLTDB.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-7W6U6ZC6.js";
52
+ } from "./chunk-LWIPZN5P.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-C4SYHSY2.js";
84
+ } from "./chunk-ODB2GWA7.js";
85
85
  import {
86
86
  fetchMetadata,
87
87
  uploadMetadata
@@ -107,7 +107,7 @@ import {
107
107
  TOKENS,
108
108
  UNISWAP,
109
109
  VENICE
110
- } from "./chunk-7PDRYBHD.js";
110
+ } from "./chunk-OPKMVIYJ.js";
111
111
  import {
112
112
  formatContractError,
113
113
  getAccount,
@@ -115,7 +115,7 @@ import {
115
115
  sendTxWithRetry,
116
116
  waitForReceipt,
117
117
  writeContractWithRetry
118
- } from "./chunk-N2547R2L.js";
118
+ } from "./chunk-OFR3LCYE.js";
119
119
  import {
120
120
  CHAIN_REGISTRY,
121
121
  VALID_NETWORKS,
@@ -125,7 +125,7 @@ import {
125
125
  getRpcUrl,
126
126
  isTestnet,
127
127
  setNetwork
128
- } from "./chunk-H32QA3NV.js";
128
+ } from "./chunk-IJG4CTOI.js";
129
129
  import {
130
130
  addSyndicate,
131
131
  cacheGroupId,
@@ -148,7 +148,7 @@ import {
148
148
  setPrivateKey,
149
149
  setUniswapApiKey,
150
150
  setVeniceApiKey
151
- } from "./chunk-RGOTBJIN.js";
151
+ } from "./chunk-WCBG44IQ.js";
152
152
 
153
153
  // src/index.ts
154
154
  import { config as loadDotenv } from "dotenv";
@@ -404,7 +404,7 @@ function buildSettleCalls3(clone) {
404
404
  }
405
405
 
406
406
  // src/strategies/wsteth-moonwell-template.ts
407
- import { encodeAbiParameters as encodeAbiParameters4, encodeFunctionData as encodeFunctionData4 } from "viem";
407
+ import { encodeAbiParameters as encodeAbiParameters4, encodeFunctionData as encodeFunctionData4, maxUint256 } from "viem";
408
408
  var INIT_PARAMS_TYPES3 = [
409
409
  {
410
410
  type: "tuple",
@@ -415,8 +415,8 @@ var INIT_PARAMS_TYPES3 = [
415
415
  { name: "aeroRouter", type: "address" },
416
416
  { name: "aeroFactory", type: "address" },
417
417
  { name: "supplyAmount", type: "uint256" },
418
- { name: "minWstethOut", type: "uint256" },
419
- { name: "minWethOut", type: "uint256" },
418
+ { name: "minWstethOutPerWeth", type: "uint256" },
419
+ { name: "minWethOutPerWsteth", type: "uint256" },
420
420
  { name: "deadlineOffset", type: "uint256" }
421
421
  ]
422
422
  }
@@ -425,13 +425,14 @@ function buildInitData4(params) {
425
425
  return encodeAbiParameters4(INIT_PARAMS_TYPES3, [params]);
426
426
  }
427
427
  function buildExecuteCalls4(clone, weth, supplyAmount) {
428
+ const approveAmount = supplyAmount === 0n ? maxUint256 : supplyAmount;
428
429
  return [
429
430
  {
430
431
  target: weth,
431
432
  data: encodeFunctionData4({
432
433
  abi: ERC20_ABI,
433
434
  functionName: "approve",
434
- args: [clone, supplyAmount]
435
+ args: [clone, approveAmount]
435
436
  }),
436
437
  value: 0n
437
438
  },
@@ -442,6 +443,15 @@ function buildExecuteCalls4(clone, weth, supplyAmount) {
442
443
  functionName: "execute"
443
444
  }),
444
445
  value: 0n
446
+ },
447
+ {
448
+ target: weth,
449
+ data: encodeFunctionData4({
450
+ abi: ERC20_ABI,
451
+ functionName: "approve",
452
+ args: [clone, 0n]
453
+ }),
454
+ value: 0n
445
455
  }
446
456
  ];
447
457
  }
@@ -568,7 +578,7 @@ function buildSettleCalls6(clone) {
568
578
  }
569
579
 
570
580
  // src/strategies/hyperliquid-perp-template.ts
571
- import { encodeAbiParameters as encodeAbiParameters7, encodeFunctionData as encodeFunctionData7 } from "viem";
581
+ import { encodeAbiParameters as encodeAbiParameters7, encodeFunctionData as encodeFunctionData7, maxUint256 as maxUint2562 } from "viem";
572
582
  function buildInitData7(asset, depositAmount, minReturnAmount, perpAssetIndex, leverage, maxPositionSize, maxTradesPerDay) {
573
583
  return encodeAbiParameters7(
574
584
  [
@@ -584,13 +594,14 @@ function buildInitData7(asset, depositAmount, minReturnAmount, perpAssetIndex, l
584
594
  );
585
595
  }
586
596
  function buildExecuteCalls7(clone, asset, amount) {
597
+ const approveAmount = amount === 0n ? maxUint2562 : amount;
587
598
  return [
588
599
  {
589
600
  target: asset,
590
601
  data: encodeFunctionData7({
591
602
  abi: ERC20_ABI,
592
603
  functionName: "approve",
593
- args: [clone, amount]
604
+ args: [clone, approveAmount]
594
605
  }),
595
606
  value: 0n
596
607
  },
@@ -601,6 +612,15 @@ function buildExecuteCalls7(clone, asset, amount) {
601
612
  functionName: "execute"
602
613
  }),
603
614
  value: 0n
615
+ },
616
+ {
617
+ target: asset,
618
+ data: encodeFunctionData7({
619
+ abi: ERC20_ABI,
620
+ functionName: "approve",
621
+ args: [clone, 0n]
622
+ }),
623
+ value: 0n
604
624
  }
605
625
  ];
606
626
  }
@@ -928,14 +948,11 @@ async function buildInitDataForTemplate(templateKey, opts, vault) {
928
948
  };
929
949
  }
930
950
  if (templateKey === "wsteth-moonwell") {
931
- if (!opts.amount) {
932
- console.error(chalk.red("--amount is required for wsteth-moonwell template"));
933
- process.exit(1);
934
- }
935
- const supplyAmount = parseUnits(opts.amount, 18);
951
+ const supplyAmount = opts.amount ? parseUnits(opts.amount, 18) : 0n;
936
952
  const slippageBps = BigInt(opts.slippage || "500");
937
- const minWstethOut = supplyAmount - supplyAmount * slippageBps / 10000n;
938
- const minWethOut = supplyAmount - supplyAmount * slippageBps / 10000n;
953
+ const ONE = 10n ** 18n;
954
+ const minWstethOutPerWeth = ONE * (10000n - slippageBps) / 10000n;
955
+ const minWethOutPerWsteth = ONE * (10000n - slippageBps) / 10000n;
939
956
  const params = {
940
957
  weth: TOKENS().WETH,
941
958
  wsteth: TOKENS().wstETH,
@@ -943,8 +960,8 @@ async function buildInitDataForTemplate(templateKey, opts, vault) {
943
960
  aeroRouter: AERODROME().ROUTER,
944
961
  aeroFactory: AERODROME().FACTORY,
945
962
  supplyAmount,
946
- minWstethOut,
947
- minWethOut,
963
+ minWstethOutPerWeth,
964
+ minWethOutPerWsteth,
948
965
  deadlineOffset: 300n
949
966
  };
950
967
  return {
@@ -1035,15 +1052,17 @@ async function buildInitDataForTemplate(templateKey, opts, vault) {
1035
1052
  };
1036
1053
  }
1037
1054
  if (templateKey === "hyperliquid-perp") {
1038
- if (!opts.amount) {
1039
- console.error(chalk.red("--amount is required for hyperliquid-perp template"));
1040
- process.exit(1);
1041
- }
1042
1055
  const token = opts.token || "USDC";
1043
1056
  const asset = resolveToken(token);
1044
1057
  const decimals = token.toUpperCase() === "USDC" ? 6 : 18;
1045
- const depositAmount = parseUnits(opts.amount, decimals);
1046
- const minReturn = parseUnits(opts.minReturn || opts.amount, decimals);
1058
+ const depositAmount = opts.amount ? parseUnits(opts.amount, decimals) : 0n;
1059
+ if (depositAmount === 0n && !opts.minReturn) {
1060
+ console.error(chalk.red(
1061
+ "--min-return is required when --amount is omitted (dynamic-all mode).\n The settlement floor can't be derived without a reference deposit \u2014 set it explicitly to the minimum USDC you'll accept back from HyperCore."
1062
+ ));
1063
+ process.exit(1);
1064
+ }
1065
+ const minReturn = opts.minReturn ? parseUnits(opts.minReturn, decimals) : opts.amount ? parseUnits(opts.amount, decimals) : 0n;
1047
1066
  const leverage = Number(opts.leverage || "10");
1048
1067
  const assetIndex = Number(opts.assetIndex || "0");
1049
1068
  const maxPosition = parseUnits(opts.maxPosition || "100000", decimals);
@@ -1390,9 +1409,9 @@ function registerStrategyTemplateCommands(strategy2) {
1390
1409
  console.error(chalk.red("Missing --name, --performance-fee, or --duration. Use --write-calls to skip proposal submission."));
1391
1410
  process.exit(1);
1392
1411
  }
1393
- const { propose: propose2 } = await import("./governor-2N3CPFOP.js");
1412
+ const { propose: propose2 } = await import("./governor-KEXLUOGB.js");
1394
1413
  const { pinJSON } = await import("./ipfs-IGXLLJCF.js");
1395
- const { parseDuration: parseDuration2 } = await import("./governor-2N3CPFOP.js");
1414
+ const { parseDuration: parseDuration2 } = await import("./governor-KEXLUOGB.js");
1396
1415
  const performanceFeeBps = BigInt(opts.performanceFee);
1397
1416
  if (performanceFeeBps < 0n || performanceFeeBps > 10000n) {
1398
1417
  console.error(chalk.red("--performance-fee must be 0-10000 (basis points)"));
@@ -1500,7 +1519,7 @@ function registerStrategyTemplateCommands(strategy2) {
1500
1519
  let prices = [];
1501
1520
  let priceSource = null;
1502
1521
  try {
1503
- const { getTokenPricesInAsset } = await import("./price-HGBIMFYN.js");
1522
+ const { getTokenPricesInAsset } = await import("./price-M5H57DPY.js");
1504
1523
  prices = await getTokenPricesInAsset({
1505
1524
  tokens: allocations.map((a, i) => ({
1506
1525
  token: a.token,
@@ -1929,7 +1948,7 @@ function registerVeniceCommands(program2) {
1929
1948
  console.log(chalk2.dim(` Key: ${apiKey.slice(0, 8)}...${apiKey.slice(-4)}`));
1930
1949
  console.log(chalk2.dim(" Saved to ~/.sherwood/config.json"));
1931
1950
  try {
1932
- const { createVeniceProvisionAttestation, getEasScanUrl: getEasScanUrl2 } = await import("./eas-YTMCD3UN.js");
1951
+ const { createVeniceProvisionAttestation, getEasScanUrl: getEasScanUrl2 } = await import("./eas-KBFTHWSI.js");
1933
1952
  const { uid } = await createVeniceProvisionAttestation(account.address);
1934
1953
  if (uid !== "0x0000000000000000000000000000000000000000000000000000000000000000") {
1935
1954
  console.log(chalk2.dim(` Attested: ${getEasScanUrl2(uid)}`));
@@ -2080,10 +2099,10 @@ ${opts.prompt}`;
2080
2099
  console.log(chalk2.dim(`Model: ${result.model} | Tokens: ${result.usage.promptTokens} in, ${result.usage.completionTokens} out, ${result.usage.totalTokens} total`));
2081
2100
  }
2082
2101
  try {
2083
- const { createVeniceInferenceAttestation, getEasScanUrl: getEasScanUrl2 } = await import("./eas-YTMCD3UN.js");
2102
+ const { createVeniceInferenceAttestation, getEasScanUrl: getEasScanUrl2 } = await import("./eas-KBFTHWSI.js");
2084
2103
  const { keccak256, toHex, isAddress: isAddr } = await import("viem");
2085
- const { getChainContracts: getChainContracts2 } = await import("./config-YXZKPSZB.js");
2086
- const { getChain: getActiveChain } = await import("./network-GJA2ZN3O.js");
2104
+ const { getChainContracts: getChainContracts2 } = await import("./config-LS7FKZL5.js");
2105
+ const { getChain: getActiveChain } = await import("./network-KSMKPKNL.js");
2087
2106
  const vaultRecipient = opts.vault && isAddr(opts.vault) ? opts.vault : getChainContracts2(getActiveChain().id).vault;
2088
2107
  const promptHash = keccak256(toHex(userContent)).slice(0, 18);
2089
2108
  const { uid } = await createVeniceInferenceAttestation(
@@ -3212,8 +3231,8 @@ function printSimulationResult(result, callType) {
3212
3231
  }
3213
3232
  async function sendSimulationAlert(subdomain, proposalId, vault, execResult, settleResult) {
3214
3233
  try {
3215
- const xmtp = await import("./xmtp-5FPJN5WE.js");
3216
- const { getAccount: getAccount2 } = await import("./client-66VTYDRS.js");
3234
+ const xmtp = await import("./xmtp-EB2CU2LE.js");
3235
+ const { getAccount: getAccount2 } = await import("./client-HKAG55PQ.js");
3217
3236
  const group = await xmtp.getGroup("", subdomain);
3218
3237
  const allRisks = [...execResult.risks, ...settleResult?.risks ?? []];
3219
3238
  const criticals = allRisks.filter((r) => r.level === "critical");
@@ -4029,7 +4048,7 @@ try {
4029
4048
  var require2 = createRequire(import.meta.url);
4030
4049
  var { version: CLI_VERSION } = require2("../package.json");
4031
4050
  async function loadXmtp() {
4032
- return import("./xmtp-5FPJN5WE.js");
4051
+ return import("./xmtp-EB2CU2LE.js");
4033
4052
  }
4034
4053
  async function loadCron() {
4035
4054
  return import("./cron-EOULYO3R.js");
@@ -4497,7 +4516,7 @@ syndicate.command("add").description("Register an agent on a syndicate vault (cr
4497
4516
  if (opts.agentId) {
4498
4517
  agentId = BigInt(opts.agentId);
4499
4518
  } else {
4500
- const { AGENT_REGISTRY: AGENT_REGISTRY2 } = await import("./addresses-NOWMJT4H.js");
4519
+ const { AGENT_REGISTRY: AGENT_REGISTRY2 } = await import("./addresses-6GJP2WAY.js");
4501
4520
  const registry = AGENT_REGISTRY2().IDENTITY_REGISTRY;
4502
4521
  if (registry === "0x0000000000000000000000000000000000000000") {
4503
4522
  agentId = 0n;
@@ -5096,7 +5115,7 @@ vaultCmd.command("redeem").description("Redeem vault shares for the underlying a
5096
5115
  var strategy = program.command("strategy").description("Strategy templates \u2014 list, clone, propose");
5097
5116
  registerStrategyTemplateCommands(strategy);
5098
5117
  program.command("providers").description("List available DeFi providers").action(async () => {
5099
- const { MessariProvider, NansenProvider } = await import("./research-3GNTDKY4.js");
5118
+ const { MessariProvider, NansenProvider } = await import("./research-662HNMOG.js");
5100
5119
  const providers = [new MoonwellProvider(), new UniswapProvider(), new MessariProvider(), new NansenProvider()];
5101
5120
  for (const p of providers) {
5102
5121
  const info = p.info();
@@ -5107,7 +5126,7 @@ ${info.name} (${info.type})`);
5107
5126
  }
5108
5127
  });
5109
5128
  try {
5110
- const { registerChatCommands } = await import("./chat-SIB6GCJF.js");
5129
+ const { registerChatCommands } = await import("./chat-ABL6Z5XZ.js");
5111
5130
  registerChatCommands(program);
5112
5131
  } catch {
5113
5132
  program.command("chat <name> [action] [actionArgs...]").description("Syndicate chat (XMTP) \u2014 requires @xmtp/cli").action(() => {
@@ -5117,18 +5136,18 @@ try {
5117
5136
  process.exit(1);
5118
5137
  });
5119
5138
  }
5120
- var { registerSessionCommands } = await import("./session-RTCMOPAQ.js");
5139
+ var { registerSessionCommands } = await import("./session-64BCMJIB.js");
5121
5140
  registerSessionCommands(program);
5122
5141
  registerVeniceCommands(program);
5123
5142
  registerAllowanceCommands(program);
5124
5143
  registerIdentityCommands(program);
5125
5144
  registerProposalCommands(program);
5126
5145
  registerGovernorCommands(program);
5127
- var { registerResearchCommands } = await import("./research-ECOWBTFP.js");
5146
+ var { registerResearchCommands } = await import("./research-W6QW2JJ3.js");
5128
5147
  registerResearchCommands(program);
5129
- var { registerAgentCommands } = await import("./agent-U6OFXITU.js");
5148
+ var { registerAgentCommands } = await import("./agent-NUYY5PF7.js");
5130
5149
  registerAgentCommands(program);
5131
- var { registerTradeCommands } = await import("./trade-3HVCELTB.js");
5150
+ var { registerTradeCommands } = await import("./trade-7343J4LA.js");
5132
5151
  registerTradeCommands(program);
5133
5152
  var configCmd = program.command("config");
5134
5153
  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) => {