@sherwoodagent/cli 0.65.0 → 0.65.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 (45) hide show
  1. package/dist/{addresses-FXTJXDI7.js → addresses-J2LMGUCT.js} +2 -2
  2. package/dist/{agent-IVESTCYM.js → agent-AETROOEW.js} +2 -2
  3. package/dist/{chat-SL4O7Y3C.js → chat-JSSTSE4K.js} +6 -6
  4. package/dist/{chunk-OKGTNYYW.js → chunk-A6TOJEUD.js} +2 -2
  5. package/dist/{chunk-VAOCUQMY.js → chunk-GWMTAW6A.js} +10 -5
  6. package/dist/{chunk-VAOCUQMY.js.map → chunk-GWMTAW6A.js.map} +1 -1
  7. package/dist/{chunk-D4AQBGF4.js → chunk-IL43IMOC.js} +2 -2
  8. package/dist/{chunk-7INQASHO.js → chunk-O4G3SBCI.js} +2 -2
  9. package/dist/{chunk-2H6IGGKN.js → chunk-RHRLYVKM.js} +2 -2
  10. package/dist/chunk-RHRLYVKM.js.map +1 -0
  11. package/dist/{chunk-J42NNFUV.js → chunk-RO26TXXE.js} +39 -20
  12. package/dist/chunk-RO26TXXE.js.map +1 -0
  13. package/dist/{chunk-HE3NY4JJ.js → chunk-UCQEEF3Z.js} +2 -2
  14. package/dist/{chunk-AQNHSYJ7.js → chunk-VYF2TXPX.js} +2 -2
  15. package/dist/{eas-5VIHTS3N.js → eas-K4ZBACYN.js} +3 -3
  16. package/dist/{governor-UBUNIO3U.js → governor-2CDSMSG7.js} +3 -3
  17. package/dist/index.js +185 -154
  18. package/dist/index.js.map +1 -1
  19. package/dist/{ipfs-IGXLLJCF.js → ipfs-FAYWUCS2.js} +2 -2
  20. package/dist/{price-3BXZKK6B.js → price-LCTECRQP.js} +2 -2
  21. package/dist/{research-RL2ASMQ5.js → research-FUQOQWKK.js} +5 -5
  22. package/dist/{research-N3R5MU6Q.js → research-XEXTHDT3.js} +2 -2
  23. package/dist/{session-FPQGAMSS.js → session-FJB2RV2X.js} +6 -6
  24. package/dist/{trade-AJNB4ULF.js → trade-U7H5IFH6.js} +7 -7
  25. package/dist/{xmtp-MR6OJ76L.js → xmtp-6NJ4PW6L.js} +3 -3
  26. package/package.json +1 -1
  27. package/dist/chunk-2H6IGGKN.js.map +0 -1
  28. package/dist/chunk-J42NNFUV.js.map +0 -1
  29. /package/dist/{addresses-FXTJXDI7.js.map → addresses-J2LMGUCT.js.map} +0 -0
  30. /package/dist/{agent-IVESTCYM.js.map → agent-AETROOEW.js.map} +0 -0
  31. /package/dist/{chat-SL4O7Y3C.js.map → chat-JSSTSE4K.js.map} +0 -0
  32. /package/dist/{chunk-OKGTNYYW.js.map → chunk-A6TOJEUD.js.map} +0 -0
  33. /package/dist/{chunk-D4AQBGF4.js.map → chunk-IL43IMOC.js.map} +0 -0
  34. /package/dist/{chunk-7INQASHO.js.map → chunk-O4G3SBCI.js.map} +0 -0
  35. /package/dist/{chunk-HE3NY4JJ.js.map → chunk-UCQEEF3Z.js.map} +0 -0
  36. /package/dist/{chunk-AQNHSYJ7.js.map → chunk-VYF2TXPX.js.map} +0 -0
  37. /package/dist/{eas-5VIHTS3N.js.map → eas-K4ZBACYN.js.map} +0 -0
  38. /package/dist/{governor-UBUNIO3U.js.map → governor-2CDSMSG7.js.map} +0 -0
  39. /package/dist/{ipfs-IGXLLJCF.js.map → ipfs-FAYWUCS2.js.map} +0 -0
  40. /package/dist/{price-3BXZKK6B.js.map → price-LCTECRQP.js.map} +0 -0
  41. /package/dist/{research-RL2ASMQ5.js.map → research-FUQOQWKK.js.map} +0 -0
  42. /package/dist/{research-N3R5MU6Q.js.map → research-XEXTHDT3.js.map} +0 -0
  43. /package/dist/{session-FPQGAMSS.js.map → session-FJB2RV2X.js.map} +0 -0
  44. /package/dist/{trade-AJNB4ULF.js.map → trade-U7H5IFH6.js.map} +0 -0
  45. /package/dist/{xmtp-MR6OJ76L.js.map → xmtp-6NJ4PW6L.js.map} +0 -0
package/dist/index.js CHANGED
@@ -15,7 +15,7 @@ import {
15
15
  encodeSwapPath,
16
16
  getMultiHopQuote,
17
17
  getQuote
18
- } from "./chunk-AQNHSYJ7.js";
18
+ } from "./chunk-VYF2TXPX.js";
19
19
  import {
20
20
  chatCompletion,
21
21
  checkApiKeyValid,
@@ -32,14 +32,14 @@ import {
32
32
  queryJoinRequests,
33
33
  revokeJoinRequest,
34
34
  stripReferrerPrefix
35
- } from "./chunk-HE3NY4JJ.js";
35
+ } from "./chunk-UCQEEF3Z.js";
36
36
  import {
37
37
  createSyndicate,
38
38
  getActiveSyndicates,
39
39
  getSyndicate,
40
40
  subdomainExists,
41
41
  updateMetadata
42
- } from "./chunk-D4AQBGF4.js";
42
+ } from "./chunk-IL43IMOC.js";
43
43
  import {
44
44
  approveDepositor,
45
45
  deposit,
@@ -63,7 +63,7 @@ import {
63
63
  searchSyndicateAcrossChains,
64
64
  setTextRecord,
65
65
  setVaultAddress
66
- } from "./chunk-7INQASHO.js";
66
+ } from "./chunk-O4G3SBCI.js";
67
67
  import {
68
68
  PROPOSAL_STATE,
69
69
  PROPOSAL_STATES,
@@ -95,7 +95,7 @@ import {
95
95
  setVotingPeriod,
96
96
  settleProposal,
97
97
  vote
98
- } from "./chunk-OKGTNYYW.js";
98
+ } from "./chunk-A6TOJEUD.js";
99
99
  import {
100
100
  AERODROME,
101
101
  AGENT_REGISTRY,
@@ -107,7 +107,7 @@ import {
107
107
  TOKENS,
108
108
  UNISWAP,
109
109
  VENICE
110
- } from "./chunk-VAOCUQMY.js";
110
+ } from "./chunk-GWMTAW6A.js";
111
111
  import {
112
112
  formatContractError,
113
113
  getAccount,
@@ -165,13 +165,13 @@ import {
165
165
  import {
166
166
  fetchMetadata,
167
167
  uploadMetadata
168
- } from "./chunk-2H6IGGKN.js";
168
+ } from "./chunk-RHRLYVKM.js";
169
169
 
170
170
  // src/index.ts
171
171
  import { config as loadDotenv } from "dotenv";
172
172
  import { createRequire } from "module";
173
173
  import { Command, Option } from "commander";
174
- import { parseUnits as parseUnits7, formatUnits as formatUnits6, isAddress as isAddress7 } from "viem";
174
+ import { parseUnits as parseUnits7, formatUnits as formatUnits6, isAddress as isAddress8 } from "viem";
175
175
  import chalk15 from "chalk";
176
176
  import ora8 from "ora";
177
177
  import { input, confirm, select } from "@inquirer/prompts";
@@ -211,7 +211,7 @@ var MoonwellProvider = class {
211
211
  };
212
212
 
213
213
  // src/commands/strategy-template.ts
214
- import { parseUnits, formatUnits as formatUnits2, isAddress as isAddress2, erc20Abi, encodeAbiParameters as encodeAbiParameters11, decodeAbiParameters } from "viem";
214
+ import { parseUnits, formatUnits as formatUnits2, isAddress as isAddress3, erc20Abi, encodeAbiParameters as encodeAbiParameters11, decodeAbiParameters } from "viem";
215
215
  import chalk from "chalk";
216
216
  import ora from "ora";
217
217
  import { writeFileSync, mkdirSync } from "fs";
@@ -240,6 +240,20 @@ async function cloneTemplate(template) {
240
240
  return { clone: receipt.contractAddress, hash };
241
241
  }
242
242
 
243
+ // src/lib/tokens.ts
244
+ import { isAddress, getAddress } from "viem";
245
+ var ZERO = "0x0000000000000000000000000000000000000000";
246
+ function resolveTokenInput(input2, tokens) {
247
+ const trimmed = input2.trim();
248
+ if (isAddress(trimmed, { strict: false })) return getAddress(trimmed);
249
+ if (/^0x/i.test(trimmed)) {
250
+ throw new Error(`Invalid token address: ${trimmed}`);
251
+ }
252
+ const resolved = tokens[trimmed.toUpperCase()];
253
+ if (resolved && resolved !== ZERO) return resolved;
254
+ throw new Error(`Unknown token symbol: ${trimmed} (also accepts a 0x address)`);
255
+ }
256
+
243
257
  // src/grid/strategy-abi.ts
244
258
  var HYPERLIQUID_GRID_STRATEGY_ABI = [
245
259
  {
@@ -1105,7 +1119,7 @@ function getDeployment(chainId) {
1105
1119
  }
1106
1120
 
1107
1121
  // ../sdk/dist/encoders/vault.js
1108
- import { encodeFunctionData, getAddress, maxUint256 } from "viem";
1122
+ import { encodeFunctionData, getAddress as getAddress2, maxUint256 } from "viem";
1109
1123
  var WETH_ABI = [
1110
1124
  {
1111
1125
  name: "deposit",
@@ -1147,14 +1161,14 @@ function encodeDeposit(args, chainId) {
1147
1161
  if (args.assets <= 0n) {
1148
1162
  throw usage("`assets` must be > 0");
1149
1163
  }
1150
- const vault = getAddress(args.vault);
1151
- const receiver = getAddress(args.receiver);
1152
- const asset = getAddress(args.asset);
1164
+ const vault = getAddress2(args.vault);
1165
+ const receiver = getAddress2(args.receiver);
1166
+ const asset = getAddress2(args.asset);
1153
1167
  const txs = [];
1154
1168
  let wrapped = false;
1155
1169
  if (args.wrapEth) {
1156
1170
  const weth = getDeployment(chainId).tokens.weth;
1157
- if (!weth || getAddress(weth.address) !== asset) {
1171
+ if (!weth || getAddress2(weth.address) !== asset) {
1158
1172
  throw usage("`wrapEth` is only valid for WETH vaults \u2014 the vault asset must be the chain's WETH.");
1159
1173
  }
1160
1174
  const held = args.currentWethBalance ?? 0n;
@@ -1219,9 +1233,9 @@ function formatUnits(value, decimals) {
1219
1233
  function encodeRedeem(args, chainId) {
1220
1234
  if (args.shares <= 0n)
1221
1235
  throw usage("`shares` must be > 0");
1222
- const vault = getAddress(args.vault);
1223
- const receiver = getAddress(args.receiver);
1224
- const owner = getAddress(args.owner);
1236
+ const vault = getAddress2(args.vault);
1237
+ const receiver = getAddress2(args.receiver);
1238
+ const owner = getAddress2(args.owner);
1225
1239
  return {
1226
1240
  txs: [
1227
1241
  {
@@ -1243,8 +1257,8 @@ function encodeRedeem(args, chainId) {
1243
1257
  };
1244
1258
  }
1245
1259
  function encodeApproveDepositor(args, chainId) {
1246
- const vault = getAddress(args.vault);
1247
- const depositor = getAddress(args.depositor);
1260
+ const vault = getAddress2(args.vault);
1261
+ const depositor = getAddress2(args.depositor);
1248
1262
  return {
1249
1263
  txs: [
1250
1264
  {
@@ -1264,8 +1278,8 @@ function encodeApproveDepositor(args, chainId) {
1264
1278
  };
1265
1279
  }
1266
1280
  function encodeRegisterAgent(args, chainId) {
1267
- const vault = getAddress(args.vault);
1268
- const agentAddress = getAddress(args.agentAddress);
1281
+ const vault = getAddress2(args.vault);
1282
+ const agentAddress = getAddress2(args.agentAddress);
1269
1283
  const id = typeof args.agentId === "bigint" ? args.agentId : BigInt(args.agentId);
1270
1284
  if (id < 0n)
1271
1285
  throw usage("`agentId` must be a non-negative integer");
@@ -1289,7 +1303,7 @@ function encodeRegisterAgent(args, chainId) {
1289
1303
  }
1290
1304
 
1291
1305
  // ../sdk/dist/encoders/governor.js
1292
- import { encodeFunctionData as encodeFunctionData2, getAddress as getAddress2, isAddress } from "viem";
1306
+ import { encodeFunctionData as encodeFunctionData2, getAddress as getAddress3, isAddress as isAddress2 } from "viem";
1293
1307
  var ZERO_VALUE2 = "0x0";
1294
1308
  var VOTE_TYPES = {
1295
1309
  For: 0,
@@ -1370,7 +1384,7 @@ function validateBatchCall(call, scope, idx) {
1370
1384
  throw usage(`\`${scope}[${idx}]\` must be an object`);
1371
1385
  }
1372
1386
  const c = call;
1373
- if (typeof c.target !== "string" || !isAddress(c.target)) {
1387
+ if (typeof c.target !== "string" || !isAddress2(c.target)) {
1374
1388
  throw usage(`\`${scope}[${idx}].target\` must be a 0x-prefixed address`);
1375
1389
  }
1376
1390
  if (typeof c.data !== "string" || !/^0x[0-9a-fA-F]*$/.test(c.data)) {
@@ -1392,11 +1406,11 @@ function validateBatchCall(call, scope, idx) {
1392
1406
  } else {
1393
1407
  throw usage(`\`${scope}[${idx}].value\` must be a non-negative integer string (or omitted for 0)`);
1394
1408
  }
1395
- return { target: getAddress2(c.target), data: c.data, value };
1409
+ return { target: getAddress3(c.target), data: c.data, value };
1396
1410
  }
1397
1411
  function encodePropose(args, chainId) {
1398
- const vault = getAddress2(args.vault);
1399
- const strategy2 = args.strategy === ZERO_ADDRESS2 ? ZERO_ADDRESS2 : getAddress2(args.strategy);
1412
+ const vault = getAddress3(args.vault);
1413
+ const strategy2 = args.strategy === ZERO_ADDRESS2 ? ZERO_ADDRESS2 : getAddress3(args.strategy);
1400
1414
  if (typeof args.metadataURI !== "string" || args.metadataURI.length === 0) {
1401
1415
  throw usage("`metadataURI` must be a non-empty string (e.g. ipfs://...)");
1402
1416
  }
@@ -1421,7 +1435,7 @@ function encodePropose(args, chainId) {
1421
1435
  }
1422
1436
  const agent = cp.agent;
1423
1437
  const splitBps = cp.splitBps;
1424
- if (typeof agent !== "string" || !isAddress(agent)) {
1438
+ if (typeof agent !== "string" || !isAddress2(agent)) {
1425
1439
  throw usage(`\`coProposers[${i}].agent\` must be a 0x-prefixed address`);
1426
1440
  }
1427
1441
  let bps;
@@ -1437,7 +1451,7 @@ function encodePropose(args, chainId) {
1437
1451
  if (bps < 0n || bps > 10000n) {
1438
1452
  throw usage(`\`coProposers[${i}].splitBps\` must be in [0, 10000]`);
1439
1453
  }
1440
- return { agent: getAddress2(agent), splitBps: bps };
1454
+ return { agent: getAddress3(agent), splitBps: bps };
1441
1455
  });
1442
1456
  const data = encodeFunctionData2({
1443
1457
  abi: SYNDICATE_GOVERNOR_ABI,
@@ -1540,7 +1554,7 @@ function encodeGovernorParam(args, chainId) {
1540
1554
  }
1541
1555
 
1542
1556
  // ../sdk/dist/encoders/factory.js
1543
- import { encodeFunctionData as encodeFunctionData3, getAddress as getAddress3 } from "viem";
1557
+ import { encodeFunctionData as encodeFunctionData3, getAddress as getAddress4 } from "viem";
1544
1558
  var ZERO_VALUE3 = "0x0";
1545
1559
  var SUBDOMAIN_RE = /^[a-z0-9-]{1,63}$/;
1546
1560
  function encodeCreateSyndicate(args, chainId) {
@@ -1559,7 +1573,7 @@ function encodeCreateSyndicate(args, chainId) {
1559
1573
  if (!SUBDOMAIN_RE.test(args.subdomain)) {
1560
1574
  throw usage("`subdomain` must match /^[a-z0-9-]{1,63}$/ (lowercase letters, digits, hyphens)");
1561
1575
  }
1562
- const asset = getAddress3(args.asset);
1576
+ const asset = getAddress4(args.asset);
1563
1577
  const creatorAgentId = typeof args.creatorAgentId === "bigint" ? args.creatorAgentId : BigInt(args.creatorAgentId);
1564
1578
  if (creatorAgentId < 0n)
1565
1579
  throw usage("`creatorAgentId` must be non-negative");
@@ -1592,7 +1606,7 @@ function encodeCreateSyndicate(args, chainId) {
1592
1606
  }
1593
1607
 
1594
1608
  // ../sdk/dist/encoders/strategy.js
1595
- import { concatHex, encodeAbiParameters, encodeFunctionData as encodeFunctionData4, encodePacked, getAddress as getAddress4, getCreate2Address, isHex, keccak256 } from "viem";
1609
+ import { concatHex, encodeAbiParameters, encodeFunctionData as encodeFunctionData4, encodePacked, getAddress as getAddress5, getCreate2Address, isHex, keccak256 } from "viem";
1596
1610
  var ZERO_ADDRESS3 = "0x0000000000000000000000000000000000000000";
1597
1611
  var ZERO_VALUE4 = "0x0";
1598
1612
  var ERC1167_PREFIX = "0x3d602d80600a3d3981f3363d3d373d3d3d363d73";
@@ -1600,20 +1614,20 @@ var ERC1167_SUFFIX = "0x5af43d82803e903d91602b57fd5bf3";
1600
1614
  function predictStrategyCloneAddress(factory, template, salt) {
1601
1615
  const initCode = concatHex([
1602
1616
  ERC1167_PREFIX,
1603
- getAddress4(template),
1617
+ getAddress5(template),
1604
1618
  ERC1167_SUFFIX
1605
1619
  ]);
1606
1620
  return getCreate2Address({
1607
- from: getAddress4(factory),
1621
+ from: getAddress5(factory),
1608
1622
  salt,
1609
1623
  bytecode: initCode
1610
1624
  });
1611
1625
  }
1612
1626
  function deriveStrategySalt(vault, proposer, template, initData) {
1613
- return keccak256(encodePacked(["address", "address", "address", "bytes"], [getAddress4(vault), getAddress4(proposer), getAddress4(template), initData]));
1627
+ return keccak256(encodePacked(["address", "address", "address", "bytes"], [getAddress5(vault), getAddress5(proposer), getAddress5(template), initData]));
1614
1628
  }
1615
1629
  function effectiveStrategySalt(vault, salt) {
1616
- return keccak256(encodeAbiParameters([{ type: "address" }, { type: "bytes32" }], [getAddress4(vault), salt]));
1630
+ return keccak256(encodeAbiParameters([{ type: "address" }, { type: "bytes32" }], [getAddress5(vault), salt]));
1617
1631
  }
1618
1632
  function requireSalt(value) {
1619
1633
  if (typeof value !== "string" || !isHex(value) || value.length !== 66) {
@@ -1622,9 +1636,9 @@ function requireSalt(value) {
1622
1636
  return value;
1623
1637
  }
1624
1638
  function encodeStrategyDeploy(args, chainId) {
1625
- const template = getAddress4(args.template);
1626
- const vault = getAddress4(args.vault);
1627
- const proposer = getAddress4(args.proposer);
1639
+ const template = getAddress5(args.template);
1640
+ const vault = getAddress5(args.vault);
1641
+ const proposer = getAddress5(args.proposer);
1628
1642
  if (typeof args.initData !== "string" || !isHex(args.initData)) {
1629
1643
  throw usage("`initData` must be a 0x-prefixed hex string");
1630
1644
  }
@@ -1634,7 +1648,7 @@ function encodeStrategyDeploy(args, chainId) {
1634
1648
  if (proposer === ZERO_ADDRESS3) {
1635
1649
  throw usage("`proposer` must be a non-zero address");
1636
1650
  }
1637
- const factory = args.factory ? getAddress4(args.factory) : getDeployment(chainId).sherwood.strategyFactory;
1651
+ const factory = args.factory ? getAddress5(args.factory) : getDeployment(chainId).sherwood.strategyFactory;
1638
1652
  if (factory === ZERO_ADDRESS3) {
1639
1653
  throw unavailable(`StrategyFactory is not yet deployed on chain ${chainId} \u2014 mirror its address into the SDK once it lands (issue #387), or pass an explicit \`factory\`.`);
1640
1654
  }
@@ -1658,7 +1672,7 @@ function encodeStrategyDeploy(args, chainId) {
1658
1672
  }
1659
1673
 
1660
1674
  // ../sdk/dist/encoders/identity.js
1661
- import { encodeFunctionData as encodeFunctionData5, getAddress as getAddress5 } from "viem";
1675
+ import { encodeFunctionData as encodeFunctionData5, getAddress as getAddress6 } from "viem";
1662
1676
  var ZERO_ADDRESS4 = "0x0000000000000000000000000000000000000000";
1663
1677
  var ERC8004_TYPE = "https://eips.ethereum.org/EIPS/eip-8004#registration-v1";
1664
1678
  var B64_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
@@ -1702,7 +1716,7 @@ function encodeIdentityMint(args, chainId) {
1702
1716
  return {
1703
1717
  txs: [
1704
1718
  {
1705
- to: getAddress5(registry2),
1719
+ to: getAddress6(registry2),
1706
1720
  data: encodeFunctionData5({
1707
1721
  abi: IDENTITY_REGISTRY_ABI,
1708
1722
  functionName: "register",
@@ -1719,7 +1733,7 @@ function encodeIdentityMint(args, chainId) {
1719
1733
  }
1720
1734
 
1721
1735
  // ../sdk/dist/encoders/eas.js
1722
- import { encodeAbiParameters as encodeAbiParameters2, encodeFunctionData as encodeFunctionData6, getAddress as getAddress6, parseAbiParameters } from "viem";
1736
+ import { encodeAbiParameters as encodeAbiParameters2, encodeFunctionData as encodeFunctionData6, getAddress as getAddress7, parseAbiParameters } from "viem";
1723
1737
  var ZERO_ADDRESS5 = "0x0000000000000000000000000000000000000000";
1724
1738
  var ZERO_BYTES322 = "0x0000000000000000000000000000000000000000000000000000000000000000";
1725
1739
  var JOIN_REQUEST_PARAMS = parseAbiParameters("uint256, uint256, address, string");
@@ -1737,7 +1751,7 @@ function formatMessageWithChain(message, sourceSlug, easSlug) {
1737
1751
  }
1738
1752
  function buildAttestTx(easAddress, schema, recipient, data, chainId) {
1739
1753
  return {
1740
- to: getAddress6(easAddress),
1754
+ to: getAddress7(easAddress),
1741
1755
  data: encodeFunctionData6({
1742
1756
  abi: EAS_ABI,
1743
1757
  functionName: "attest",
@@ -1770,15 +1784,15 @@ function encodeJoinRequest(args, chainId) {
1770
1784
  const data = encodeAbiParameters2(JOIN_REQUEST_PARAMS, [
1771
1785
  toBig(args.syndicateId),
1772
1786
  toBig(args.agentId),
1773
- getAddress6(args.vault),
1787
+ getAddress7(args.vault),
1774
1788
  message
1775
1789
  ]);
1776
1790
  return {
1777
1791
  txs: [
1778
- buildAttestTx(eas.address, eas.schemas.joinRequest, getAddress6(args.creator), data, eas.chainId)
1792
+ buildAttestTx(eas.address, eas.schemas.joinRequest, getAddress7(args.creator), data, eas.chainId)
1779
1793
  ],
1780
1794
  preconditions: [],
1781
- description: `Request to join syndicate ${toBig(args.syndicateId).toString()} (vault ${getAddress6(args.vault)}).`,
1795
+ description: `Request to join syndicate ${toBig(args.syndicateId).toString()} (vault ${getAddress7(args.vault)}).`,
1782
1796
  note: "EAS coordination attestation \u2014 always submitted on Base, even for syndicates on another chain. Revocable; the creator discovers it via the join-request schema."
1783
1797
  };
1784
1798
  }
@@ -1796,9 +1810,9 @@ function encodeApproveAgent(args, chainId) {
1796
1810
  const data = encodeAbiParameters2(AGENT_APPROVED_PARAMS, [
1797
1811
  toBig(args.syndicateId),
1798
1812
  toBig(args.agentId),
1799
- getAddress6(args.vault)
1813
+ getAddress7(args.vault)
1800
1814
  ]);
1801
- const attestTx = buildAttestTx(eas.address, eas.schemas.agentApproved, getAddress6(args.agentAddress), data, eas.chainId);
1815
+ const attestTx = buildAttestTx(eas.address, eas.schemas.agentApproved, getAddress7(args.agentAddress), data, eas.chainId);
1802
1816
  return {
1803
1817
  txs: [registerTx, attestTx],
1804
1818
  preconditions: [],
@@ -1808,7 +1822,7 @@ function encodeApproveAgent(args, chainId) {
1808
1822
  }
1809
1823
 
1810
1824
  // ../sdk/dist/encoders/guardian.js
1811
- import { encodeFunctionData as encodeFunctionData7, getAddress as getAddress7 } from "viem";
1825
+ import { encodeFunctionData as encodeFunctionData7, getAddress as getAddress8 } from "viem";
1812
1826
  var ZERO_VALUE5 = "0x0";
1813
1827
  function registryTx(chainId, data) {
1814
1828
  const registry2 = getDeployment(chainId).sherwood.guardianRegistry;
@@ -1886,7 +1900,7 @@ function encodeGuardianUnstake(args, chainId) {
1886
1900
  function encodeGuardianDelegate(args, chainId) {
1887
1901
  if (args.amount <= 0n)
1888
1902
  throw usage("`amount` must be > 0");
1889
- const delegate = getAddress7(args.delegate);
1903
+ const delegate = getAddress8(args.delegate);
1890
1904
  const data = encodeFunctionData7({
1891
1905
  abi: GUARDIAN_REGISTRY_ABI,
1892
1906
  functionName: "delegateStake",
@@ -1909,7 +1923,7 @@ function encodeDelegationUnstake(args, chainId) {
1909
1923
  if (!fn) {
1910
1924
  throw usage(`\`action\` must be one of: ${Object.keys(DELEGATION_UNSTAKE_FN).join(", ")}`);
1911
1925
  }
1912
- const delegate = getAddress7(args.delegate);
1926
+ const delegate = getAddress8(args.delegate);
1913
1927
  const data = encodeFunctionData7({
1914
1928
  abi: GUARDIAN_REGISTRY_ABI,
1915
1929
  functionName: fn,
@@ -1954,7 +1968,7 @@ function encodeClaimProposalReward(args, chainId) {
1954
1968
  }
1955
1969
  function encodeClaimDelegatorProposalReward(args, chainId) {
1956
1970
  const proposalId = parseUint(args.proposalId, "proposalId");
1957
- const delegate = getAddress7(args.delegate);
1971
+ const delegate = getAddress8(args.delegate);
1958
1972
  const data = encodeFunctionData7({
1959
1973
  abi: GUARDIAN_REGISTRY_ABI,
1960
1974
  functionName: "claimDelegatorProposalReward",
@@ -1969,7 +1983,7 @@ function encodeClaimDelegatorProposalReward(args, chainId) {
1969
1983
  }
1970
1984
 
1971
1985
  // ../sdk/dist/reads/syndicates.js
1972
- import { getAddress as getAddress8 } from "viem";
1986
+ import { getAddress as getAddress9 } from "viem";
1973
1987
 
1974
1988
  // src/strategies/moonwell-supply-template.ts
1975
1989
  import { encodeAbiParameters as encodeAbiParameters3, encodeFunctionData as encodeFunctionData8 } from "viem";
@@ -2441,7 +2455,7 @@ function buildSettleCalls8(clone) {
2441
2455
 
2442
2456
  // src/commands/strategy-template.ts
2443
2457
  import { concat as concat2, numberToHex } from "viem";
2444
- var ZERO = "0x0000000000000000000000000000000000000000";
2458
+ var ZERO2 = "0x0000000000000000000000000000000000000000";
2445
2459
  function encodeV3Path(tokens, fees) {
2446
2460
  if (tokens.length !== fees.length + 1) throw new Error("tokens.length must be fees.length + 1");
2447
2461
  const parts = [];
@@ -2617,7 +2631,7 @@ function resolveTemplate(key) {
2617
2631
  process.exit(1);
2618
2632
  }
2619
2633
  const address = STRATEGY_TEMPLATES()[def.addressKey];
2620
- if (address === ZERO) {
2634
+ if (address === ZERO2) {
2621
2635
  console.error(chalk.red(`Template "${def.name}" not deployed on this network.`));
2622
2636
  process.exit(1);
2623
2637
  }
@@ -2741,11 +2755,11 @@ async function buildInitDataForTemplate(templateKey, opts, vault) {
2741
2755
  }
2742
2756
  const params = {
2743
2757
  asset,
2744
- weth: isDirect ? ZERO : TOKENS().WETH,
2758
+ weth: isDirect ? ZERO2 : TOKENS().WETH,
2745
2759
  vvv,
2746
2760
  sVVV: VENICE().STAKING,
2747
- aeroRouter: isDirect ? ZERO : AERODROME().ROUTER,
2748
- aeroFactory: isDirect ? ZERO : AERODROME().FACTORY,
2761
+ aeroRouter: isDirect ? ZERO2 : AERODROME().ROUTER,
2762
+ aeroFactory: isDirect ? ZERO2 : AERODROME().FACTORY,
2749
2763
  agent,
2750
2764
  assetAmount,
2751
2765
  minVVV,
@@ -2782,7 +2796,7 @@ async function buildInitDataForTemplate(templateKey, opts, vault) {
2782
2796
  stable: !!opts.stable,
2783
2797
  factory: AERODROME().FACTORY,
2784
2798
  router: AERODROME().ROUTER,
2785
- gauge: opts.gauge || ZERO,
2799
+ gauge: opts.gauge || ZERO2,
2786
2800
  lpToken: opts.lpToken,
2787
2801
  amountADesired: amountA,
2788
2802
  amountBDesired: amountB,
@@ -2863,13 +2877,12 @@ async function buildInitDataForTemplate(templateKey, opts, vault) {
2863
2877
  const maxSlippageBps = Number(opts.maxSlippage || "500");
2864
2878
  const feeTier = opts.feeTier || "3000";
2865
2879
  const tokenAddrs = opts.tokens.split(",").map((t) => {
2866
- const trimmed = t.trim();
2867
- if (isAddress2(trimmed)) return trimmed;
2868
- const allTokens = tokens;
2869
- const resolved = allTokens[trimmed.toUpperCase()];
2870
- if (resolved && resolved !== ZERO) return resolved;
2871
- console.error(chalk.red(`Unknown token: ${trimmed}`));
2872
- process.exit(1);
2880
+ try {
2881
+ return resolveTokenInput(t, tokens);
2882
+ } catch (err) {
2883
+ console.error(chalk.red(err instanceof Error ? err.message : String(err)));
2884
+ process.exit(1);
2885
+ }
2873
2886
  });
2874
2887
  const weightsBps = opts.weights.split(",").map((w) => Number(w.trim()));
2875
2888
  if (tokenAddrs.length !== weightsBps.length) {
@@ -2955,7 +2968,7 @@ function buildCallsForTemplate(templateKey, clone, asset, assetAmount, extraAppr
2955
2968
  };
2956
2969
  }
2957
2970
  if (templateKey === "aerodrome-lp") {
2958
- const tokenB = extraApprovals?.[0]?.token ?? ZERO;
2971
+ const tokenB = extraApprovals?.[0]?.token ?? ZERO2;
2959
2972
  const amountB = extraApprovals?.[0]?.amount ?? 0n;
2960
2973
  return {
2961
2974
  executeCalls: buildExecuteCalls3(clone, asset, assetAmount, tokenB, amountB),
@@ -2997,34 +3010,33 @@ function buildCallsForTemplate(templateKey, clone, asset, assetAmount, extraAppr
2997
3010
  function resolveSwapAdapter() {
2998
3011
  const network = getNetwork();
2999
3012
  if (network === "robinhood-testnet") {
3000
- if (SYNTHRA().ROUTER === ZERO) {
3013
+ if (SYNTHRA().ROUTER === ZERO2) {
3001
3014
  console.error(chalk.red("Synthra DEX not available"));
3002
3015
  process.exit(1);
3003
3016
  }
3004
3017
  return "0xdae81cDCfcB14c56fCeB788A147Fcd6CbEdfEeca";
3005
3018
  }
3006
3019
  const adapterAddr = UNISWAP().SWAP_ADAPTER;
3007
- if (adapterAddr !== ZERO) return adapterAddr;
3020
+ if (adapterAddr !== ZERO2) return adapterAddr;
3008
3021
  console.error(chalk.red("UniswapSwapAdapter not deployed yet. Use --swap-adapter to specify manually."));
3009
3022
  process.exit(1);
3010
3023
  }
3011
3024
  function resolveToken(symbolOrAddress) {
3012
- if (isAddress2(symbolOrAddress)) return symbolOrAddress;
3013
- const upper = symbolOrAddress.toUpperCase();
3014
3025
  const tokens = TOKENS();
3015
3026
  const tokenMap = {
3016
3027
  USDC: tokens.USDC,
3017
3028
  WETH: tokens.WETH,
3018
3029
  DAI: tokens.DAI,
3019
3030
  AERO: tokens.AERO,
3031
+ AAVE: tokens.AAVE,
3020
3032
  VVV: VENICE().VVV
3021
3033
  };
3022
- const addr = tokenMap[upper];
3023
- if (!addr || addr === ZERO) {
3024
- console.error(chalk.red(`Unknown token: ${symbolOrAddress}`));
3034
+ try {
3035
+ return resolveTokenInput(symbolOrAddress, tokenMap);
3036
+ } catch (err) {
3037
+ console.error(chalk.red(err instanceof Error ? err.message : String(err)));
3025
3038
  process.exit(1);
3026
3039
  }
3027
- return addr;
3028
3040
  }
3029
3041
  function resolveMToken(tokenSymbol) {
3030
3042
  const upper = tokenSymbol.toUpperCase();
@@ -3034,7 +3046,7 @@ function resolveMToken(tokenSymbol) {
3034
3046
  WETH: moonwell.mWETH
3035
3047
  };
3036
3048
  const addr = mTokenMap[upper];
3037
- if (!addr || addr === ZERO) {
3049
+ if (!addr || addr === ZERO2) {
3038
3050
  console.error(chalk.red(`No Moonwell market for: ${tokenSymbol}`));
3039
3051
  process.exit(1);
3040
3052
  }
@@ -3061,7 +3073,7 @@ function registerStrategyTemplateCommands(strategy2) {
3061
3073
  let availableCount = 0;
3062
3074
  for (const t of TEMPLATES) {
3063
3075
  const addr = templates[t.addressKey];
3064
- if (addr !== ZERO) {
3076
+ if (addr !== ZERO2) {
3065
3077
  availableCount++;
3066
3078
  console.log();
3067
3079
  console.log(` ${chalk.bold(t.name)} (${chalk.cyan(t.key)})`);
@@ -3073,7 +3085,7 @@ function registerStrategyTemplateCommands(strategy2) {
3073
3085
  console.log();
3074
3086
  console.log(chalk.yellow(" No strategy templates deployed on this network."));
3075
3087
  }
3076
- const unavailable2 = TEMPLATES.filter((t) => templates[t.addressKey] === ZERO);
3088
+ const unavailable2 = TEMPLATES.filter((t) => templates[t.addressKey] === ZERO2);
3077
3089
  if (unavailable2.length > 0) {
3078
3090
  console.log();
3079
3091
  console.log(chalk.dim(` Not available on ${network}:`));
@@ -3088,7 +3100,7 @@ function registerStrategyTemplateCommands(strategy2) {
3088
3100
  });
3089
3101
  strategy2.command("clone").description("Clone a strategy template and initialize it").argument("<template>", "Template: moonwell-supply, aerodrome-lp, venice-inference, wsteth-moonwell, mamo-yield, portfolio, hyperliquid-perp, hyperliquid-grid").requiredOption("--vault <address>", "Vault address").option("--amount <n>", "Asset amount to deploy").option("--min-redeem <n>", "Min asset on settlement (Moonwell)").option("--token <symbol>", "Asset token symbol (default: USDC)").option("--asset <symbol>", "Asset token (USDC, VVV, or address)").option("--agent <address>", "Agent wallet (Venice, default: your wallet)").option("--min-vvv <n>", "Min VVV from swap (Venice)").option("--single-hop", "Single-hop Aerodrome swap (Venice)").option("--token-a <address>", "Token A (Aerodrome)").option("--token-b <address>", "Token B (Aerodrome)").option("--amount-a <n>", "Token A amount (Aerodrome)").option("--amount-b <n>", "Token B amount (Aerodrome)").option("--stable", "Stable pool (Aerodrome)").option("--gauge <address>", "Gauge address (Aerodrome)").option("--lp-token <address>", "LP token address (Aerodrome)").option("--min-a-out <n>", "Min token A on settle (Aerodrome)").option("--min-b-out <n>", "Min token B on settle (Aerodrome)").option("--slippage <bps>", "Slippage tolerance in bps (wstETH, default: 500 = 5%)").option("--mamo-factory <address>", "Mamo StrategyFactory address (Mamo)").option("--tokens <list>", "Comma-separated token addresses or symbols (Portfolio)").option("--weights <list>", "Comma-separated weights in bps, must sum to 10000 (Portfolio)").option("--max-slippage <bps>", "Max slippage bps (Portfolio, default: 500)").option("--fee-tier <n>", "Pool fee tier (Portfolio, default: 3000)").option("--swap-adapter <address>", "Swap adapter address (Portfolio)").option("--leverage <number>", "Leverage multiplier (Hyperliquid Perp, default: 10)").option("--asset-index <number>", "Perp asset index (Hyperliquid Perp, default: 0 for BTC)").option("--max-position <amount>", "Max position size in USD (Hyperliquid Perp, default: 100000)").option("--max-trades-per-day <n>", "Max trades per day (Hyperliquid Perp, default: 50)").option("--max-order-size <amount>", "Max single-order size in asset units (Hyperliquid Grid, default: 10000)").option("--max-orders-per-tick <n>", "Max orders per tick (Hyperliquid Grid, default: 20)").option("--asset-indices <list>", "Comma-separated perp asset indices (Hyperliquid Grid, default: 0)").action(async (templateKey, opts) => {
3090
3102
  const vault = opts.vault;
3091
- if (!isAddress2(vault)) {
3103
+ if (!isAddress3(vault)) {
3092
3104
  console.error(chalk.red("Invalid vault address"));
3093
3105
  process.exit(1);
3094
3106
  }
@@ -3157,11 +3169,11 @@ function registerStrategyTemplateCommands(strategy2) {
3157
3169
  strategy2.command("init").description("Initialize an already-deployed but uninitialized strategy clone").argument("<template>", "Template: moonwell-supply, aerodrome-lp, venice-inference, wsteth-moonwell, mamo-yield, portfolio, hyperliquid-perp, hyperliquid-grid").requiredOption("--clone <address>", "Clone address to initialize").requiredOption("--vault <address>", "Vault address").option("--amount <n>", "Asset amount to deploy").option("--min-redeem <n>", "Min asset on settlement (Moonwell)").option("--token <symbol>", "Asset token symbol (default: USDC)").option("--asset <symbol>", "Asset token (USDC, VVV, or address)").option("--agent <address>", "Agent wallet (Venice, default: your wallet)").option("--min-vvv <n>", "Min VVV from swap (Venice)").option("--single-hop", "Single-hop Aerodrome swap (Venice)").option("--token-a <address>", "Token A (Aerodrome)").option("--token-b <address>", "Token B (Aerodrome)").option("--amount-a <n>", "Token A amount (Aerodrome)").option("--amount-b <n>", "Token B amount (Aerodrome)").option("--stable", "Stable pool (Aerodrome)").option("--gauge <address>", "Gauge address (Aerodrome)").option("--lp-token <address>", "LP token address (Aerodrome)").option("--min-a-out <n>", "Min token A on settle (Aerodrome)").option("--min-b-out <n>", "Min token B on settle (Aerodrome)").option("--slippage <bps>", "Slippage tolerance in bps (wstETH, default: 500 = 5%)").option("--mamo-factory <address>", "Mamo StrategyFactory address (Mamo)").option("--tokens <list>", "Comma-separated token addresses or symbols (Portfolio)").option("--weights <list>", "Comma-separated weights in bps, must sum to 10000 (Portfolio)").option("--max-slippage <bps>", "Max slippage bps (Portfolio, default: 500)").option("--fee-tier <n>", "Pool fee tier (Portfolio, default: 3000)").option("--swap-adapter <address>", "Swap adapter address (Portfolio)").option("--leverage <number>", "Leverage multiplier (Hyperliquid Perp, default: 10)").option("--asset-index <number>", "Perp asset index (Hyperliquid Perp, default: 0 for BTC)").option("--max-position <amount>", "Max position size in USD (Hyperliquid Perp, default: 100000)").option("--max-trades-per-day <n>", "Max trades per day (Hyperliquid Perp, default: 50)").option("--max-order-size <amount>", "Max single-order size in asset units (Hyperliquid Grid, default: 10000)").option("--max-orders-per-tick <n>", "Max orders per tick (Hyperliquid Grid, default: 20)").option("--asset-indices <list>", "Comma-separated perp asset indices (Hyperliquid Grid, default: 0)").action(async (templateKey, opts) => {
3158
3170
  const clone = opts.clone;
3159
3171
  const vault = opts.vault;
3160
- if (!isAddress2(clone)) {
3172
+ if (!isAddress3(clone)) {
3161
3173
  console.error(chalk.red("Invalid clone address"));
3162
3174
  process.exit(1);
3163
3175
  }
3164
- if (!isAddress2(vault)) {
3176
+ if (!isAddress3(vault)) {
3165
3177
  console.error(chalk.red("Invalid vault address"));
3166
3178
  process.exit(1);
3167
3179
  }
@@ -3212,7 +3224,7 @@ function registerStrategyTemplateCommands(strategy2) {
3212
3224
  });
3213
3225
  strategy2.command("propose").description("Clone + init + build calls + submit governance proposal (all-in-one)").argument("<template>", "Template: moonwell-supply, aerodrome-lp, venice-inference, wsteth-moonwell, mamo-yield, portfolio, hyperliquid-perp, hyperliquid-grid").requiredOption("--vault <address>", "Vault address").option("--write-calls <dir>", "Write execute/settle JSON to directory (skip proposal submission)").option("--name <name>", "Proposal name").option("--description <text>", "Proposal description").option("--performance-fee <bps>", "Agent fee in bps").option("--duration <duration>", "Strategy duration (7d, 24h, etc.)").option("--proposer <address>", "Proposer/agent address (required for --calldata-only \u2014 the external signer)").option("--metadata-uri <uri>", "Metadata URI (required for --calldata-only \u2014 IPFS pin needs a signer)").option("--salt <bytes32>", "CREATE2 salt for the deterministic clone (--calldata-only; default: derived from inputs)").option("--amount <n>", "Asset amount to deploy").option("--min-redeem <n>", "Min asset on settlement (Moonwell)").option("--token <symbol>", "Asset token symbol (default: USDC)").option("--asset <symbol>", "Asset token (USDC, VVV, or address)").option("--agent <address>", "Agent wallet (Venice, default: your wallet)").option("--min-vvv <n>", "Min VVV from swap (Venice)").option("--single-hop", "Single-hop Aerodrome swap (Venice)").option("--token-a <address>", "Token A (Aerodrome)").option("--token-b <address>", "Token B (Aerodrome)").option("--amount-a <n>", "Token A amount (Aerodrome)").option("--amount-b <n>", "Token B amount (Aerodrome)").option("--stable", "Stable pool (Aerodrome)").option("--gauge <address>", "Gauge address (Aerodrome)").option("--lp-token <address>", "LP token address (Aerodrome)").option("--min-a-out <n>", "Min token A on settle (Aerodrome)").option("--min-b-out <n>", "Min token B on settle (Aerodrome)").option("--slippage <bps>", "Slippage tolerance in bps (wstETH, default: 500 = 5%)").option("--mamo-factory <address>", "Mamo StrategyFactory address (Mamo)").option("--tokens <list>", "Comma-separated token addresses or symbols (Portfolio)").option("--weights <list>", "Comma-separated weights in bps, must sum to 10000 (Portfolio)").option("--max-slippage <bps>", "Max slippage bps (Portfolio, default: 500)").option("--fee-tier <n>", "Pool fee tier (Portfolio, default: 3000)").option("--swap-adapter <address>", "Swap adapter address (Portfolio)").option("--leverage <number>", "Leverage multiplier (Hyperliquid Perp, default: 10)").option("--asset-index <number>", "Perp asset index (Hyperliquid Perp, default: 0 for BTC)").option("--max-position <amount>", "Max position size in USD (Hyperliquid Perp, default: 100000)").option("--max-trades-per-day <n>", "Max trades per day (Hyperliquid Perp, default: 50)").option("--max-order-size <amount>", "Max single-order size in asset units (Hyperliquid Grid, default: 10000)").option("--max-orders-per-tick <n>", "Max orders per tick (Hyperliquid Grid, default: 20)").option("--asset-indices <list>", "Comma-separated perp asset indices (Hyperliquid Grid, default: 0)").action(async (templateKey, opts) => {
3214
3226
  const vault = opts.vault;
3215
- if (!isAddress2(vault)) {
3227
+ if (!isAddress3(vault)) {
3216
3228
  console.error(chalk.red("Invalid vault address"));
3217
3229
  process.exit(1);
3218
3230
  }
@@ -3220,7 +3232,7 @@ function registerStrategyTemplateCommands(strategy2) {
3220
3232
  if (isCalldataOnly()) {
3221
3233
  const missing = [];
3222
3234
  if (!opts.proposer) missing.push("--proposer <address> (the external signer)");
3223
- if (!opts.metadataUri) missing.push("--metadata-uri <uri> (IPFS pin needs a signer)");
3235
+ if (!opts.metadataUri && !opts.name) missing.push("--name <name> (or --metadata-uri <uri>)");
3224
3236
  if (!opts.performanceFee) missing.push("--performance-fee <bps>");
3225
3237
  if (!opts.duration) missing.push("--duration <d>");
3226
3238
  if (missing.length > 0) {
@@ -3228,7 +3240,7 @@ function registerStrategyTemplateCommands(strategy2) {
3228
3240
  process.exit(1);
3229
3241
  }
3230
3242
  const proposer = opts.proposer;
3231
- if (!isAddress2(proposer)) {
3243
+ if (!isAddress3(proposer)) {
3232
3244
  console.error(chalk.red("Invalid --proposer address"));
3233
3245
  process.exit(1);
3234
3246
  }
@@ -3295,7 +3307,7 @@ function registerStrategyTemplateCommands(strategy2) {
3295
3307
  process.exit(1);
3296
3308
  }
3297
3309
  if (!opts.agent) opts.agent = proposer;
3298
- const { parseDuration: parseDuration3 } = await import("./governor-UBUNIO3U.js");
3310
+ const { parseDuration: parseDuration3 } = await import("./governor-2CDSMSG7.js");
3299
3311
  const strategyDuration2 = parseDuration3(opts.duration);
3300
3312
  const chainId = getChain().id;
3301
3313
  try {
@@ -3317,11 +3329,35 @@ function registerStrategyTemplateCommands(strategy2) {
3317
3329
  built.assetAmount,
3318
3330
  built.extraApprovals
3319
3331
  );
3332
+ let metadataURI2 = opts.metadataUri;
3333
+ if (!metadataURI2) {
3334
+ const { pinJSON: pinJSON2 } = await import("./ipfs-FAYWUCS2.js");
3335
+ try {
3336
+ metadataURI2 = await pinJSON2(
3337
+ {
3338
+ name: opts.name,
3339
+ description: opts.description || "",
3340
+ proposer,
3341
+ vault,
3342
+ strategyClone: deploy.clone,
3343
+ template: def.key,
3344
+ performanceFeeBps: performanceFeeBps2,
3345
+ strategyDuration: Number(strategyDuration2),
3346
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
3347
+ },
3348
+ opts.name
3349
+ );
3350
+ } catch {
3351
+ metadataURI2 = `data:application/json;base64,${Buffer.from(
3352
+ JSON.stringify({ name: opts.name, description: opts.description || "", vault })
3353
+ ).toString("base64")}`;
3354
+ }
3355
+ }
3320
3356
  const proposeAction = encodePropose(
3321
3357
  {
3322
3358
  vault,
3323
3359
  strategy: deploy.clone,
3324
- metadataURI: opts.metadataUri,
3360
+ metadataURI: metadataURI2,
3325
3361
  performanceFeeBps: performanceFeeBps2,
3326
3362
  strategyDuration: strategyDuration2,
3327
3363
  executeCalls: executeCalls2,
@@ -3520,9 +3556,9 @@ function registerStrategyTemplateCommands(strategy2) {
3520
3556
  console.error(chalk.red("Missing --name, --performance-fee, or --duration. Use --write-calls to skip proposal submission."));
3521
3557
  process.exit(1);
3522
3558
  }
3523
- const { propose: propose2 } = await import("./governor-UBUNIO3U.js");
3524
- const { pinJSON } = await import("./ipfs-IGXLLJCF.js");
3525
- const { parseDuration: parseDuration2 } = await import("./governor-UBUNIO3U.js");
3559
+ const { propose: propose2 } = await import("./governor-2CDSMSG7.js");
3560
+ const { pinJSON } = await import("./ipfs-FAYWUCS2.js");
3561
+ const { parseDuration: parseDuration2 } = await import("./governor-2CDSMSG7.js");
3526
3562
  const performanceFeeBps = BigInt(opts.performanceFee);
3527
3563
  if (performanceFeeBps < 0n || performanceFeeBps > 10000n) {
3528
3564
  console.error(chalk.red("--performance-fee must be 0-10000 (basis points)"));
@@ -3581,7 +3617,7 @@ function registerStrategyTemplateCommands(strategy2) {
3581
3617
  console.log();
3582
3618
  });
3583
3619
  strategy2.command("status").description("Show portfolio strategy status \u2014 allocations, balances, drift, PnL (Portfolio only)").argument("<clone>", "Strategy clone address").option("--json", "Output machine-readable JSON for agent consumption").action(async (cloneArg, opts) => {
3584
- if (!isAddress2(cloneArg)) {
3620
+ if (!isAddress3(cloneArg)) {
3585
3621
  console.error(chalk.red("Invalid clone address"));
3586
3622
  process.exit(1);
3587
3623
  }
@@ -3630,7 +3666,7 @@ function registerStrategyTemplateCommands(strategy2) {
3630
3666
  let prices = [];
3631
3667
  let priceSource = null;
3632
3668
  try {
3633
- const { getTokenPricesInAsset } = await import("./price-3BXZKK6B.js");
3669
+ const { getTokenPricesInAsset } = await import("./price-LCTECRQP.js");
3634
3670
  prices = await getTokenPricesInAsset({
3635
3671
  tokens: allocations.map((a, i) => ({
3636
3672
  token: a.token,
@@ -3791,7 +3827,7 @@ function registerStrategyTemplateCommands(strategy2) {
3791
3827
  }
3792
3828
  });
3793
3829
  strategy2.command("rebalance").description("Rebalance a portfolio strategy \u2014 sell all positions, re-buy at target weights (Portfolio only)").argument("<clone>", "Strategy clone address").option("--new-weights <list>", "Comma-separated new weights in bps (must sum to 10000). Updates weights before rebalancing.").option("--max-slippage <bps>", "New max slippage bps (used with --new-weights)").option("--dry-run", "Show what would happen without executing").action(async (cloneArg, opts) => {
3794
- if (!isAddress2(cloneArg)) {
3830
+ if (!isAddress3(cloneArg)) {
3795
3831
  console.error(chalk.red("Invalid clone address"));
3796
3832
  process.exit(1);
3797
3833
  }
@@ -4023,7 +4059,7 @@ async function getActiveSyndicates2(creator) {
4023
4059
  }
4024
4060
 
4025
4061
  // src/commands/venice.ts
4026
- import { formatUnits as formatUnits3, isAddress as isAddress3, parseUnits as parseUnits2 } from "viem";
4062
+ import { formatUnits as formatUnits3, isAddress as isAddress4, parseUnits as parseUnits2 } from "viem";
4027
4063
  import chalk2 from "chalk";
4028
4064
  import ora2 from "ora";
4029
4065
  import { readFileSync } from "fs";
@@ -4060,7 +4096,7 @@ function registerVeniceCommands(program2) {
4060
4096
  console.log(chalk2.dim(` Key: ${apiKey.slice(0, 8)}...${apiKey.slice(-4)}`));
4061
4097
  console.log(chalk2.dim(" Saved to ~/.sherwood/config.json"));
4062
4098
  try {
4063
- const { createVeniceProvisionAttestation, getEasScanUrl: getEasScanUrl2 } = await import("./eas-5VIHTS3N.js");
4099
+ const { createVeniceProvisionAttestation, getEasScanUrl: getEasScanUrl2 } = await import("./eas-K4ZBACYN.js");
4064
4100
  const { uid } = await createVeniceProvisionAttestation(account.address);
4065
4101
  if (uid !== "0x0000000000000000000000000000000000000000000000000000000000000000") {
4066
4102
  console.log(chalk2.dim(` Attested: ${getEasScanUrl2(uid)}`));
@@ -4272,7 +4308,7 @@ function registerVeniceCommands(program2) {
4272
4308
  });
4273
4309
  venice.command("status").description("Show Venice inference status: sVVV balances, DIEM, API key").requiredOption("--vault <address>", "Vault address").action(async (opts) => {
4274
4310
  const vaultAddress = opts.vault;
4275
- if (!isAddress3(vaultAddress)) {
4311
+ if (!isAddress4(vaultAddress)) {
4276
4312
  console.error(chalk2.red(`Invalid vault address: ${opts.vault}`));
4277
4313
  process.exit(1);
4278
4314
  }
@@ -4416,7 +4452,7 @@ ${opts.prompt}`;
4416
4452
  console.log(chalk2.dim(`Model: ${result.model} | Tokens: ${result.usage.promptTokens} in, ${result.usage.completionTokens} out, ${result.usage.totalTokens} total`));
4417
4453
  }
4418
4454
  try {
4419
- const { createVeniceInferenceAttestation, getEasScanUrl: getEasScanUrl2 } = await import("./eas-5VIHTS3N.js");
4455
+ const { createVeniceInferenceAttestation, getEasScanUrl: getEasScanUrl2 } = await import("./eas-K4ZBACYN.js");
4420
4456
  const { keccak256: keccak2563, toHex, isAddress: isAddr } = await import("viem");
4421
4457
  const { getChainContracts: getChainContracts2 } = await import("./config-REASKDIK.js");
4422
4458
  const { getChain: getActiveChain } = await import("./network-3ZU7UBDU.js");
@@ -4443,7 +4479,7 @@ ${opts.prompt}`;
4443
4479
  }
4444
4480
 
4445
4481
  // src/commands/allowance.ts
4446
- import { parseUnits as parseUnits4, formatUnits as formatUnits4, isAddress as isAddress4 } from "viem";
4482
+ import { parseUnits as parseUnits4, formatUnits as formatUnits4, isAddress as isAddress5 } from "viem";
4447
4483
  import chalk3 from "chalk";
4448
4484
  import ora3 from "ora";
4449
4485
 
@@ -4524,7 +4560,7 @@ function registerAllowanceCommands(program2) {
4524
4560
  const allowance = program2.command("allowance").description("Disburse vault profits to agent wallets");
4525
4561
  allowance.command("disburse").description("Swap vault profits \u2192 USDC \u2192 distribute to all agent operator wallets").requiredOption("--vault <address>", "Vault address").requiredOption("--amount <amount>", "Deposit token amount to convert & distribute (e.g. 500)").option("--fee <tier>", "Fee tier for asset \u2192 USDC swap (500, 3000, 10000)", "3000").option("--slippage <bps>", "Slippage tolerance in bps", "100").option("--execute", "Execute on-chain (default: simulate only)", false).action(async (opts) => {
4526
4562
  const vaultAddress = opts.vault;
4527
- if (!isAddress4(vaultAddress)) {
4563
+ if (!isAddress5(vaultAddress)) {
4528
4564
  console.error(chalk3.red(`Invalid vault address: ${opts.vault}`));
4529
4565
  process.exit(1);
4530
4566
  }
@@ -4658,7 +4694,7 @@ function registerAllowanceCommands(program2) {
4658
4694
  });
4659
4695
  allowance.command("status").description("Show vault profit and agent USDC balances").requiredOption("--vault <address>", "Vault address").action(async (opts) => {
4660
4696
  const vaultAddress = opts.vault;
4661
- if (!isAddress4(vaultAddress)) {
4697
+ if (!isAddress5(vaultAddress)) {
4662
4698
  console.error(chalk3.red(`Invalid vault address: ${opts.vault}`));
4663
4699
  process.exit(1);
4664
4700
  }
@@ -4966,7 +5002,7 @@ function registerIdentityCommands(program2) {
4966
5002
  }
4967
5003
 
4968
5004
  // src/commands/proposal.ts
4969
- import { isAddress as isAddress5, encodeFunctionData as encodeFunctionData18 } from "viem";
5005
+ import { isAddress as isAddress6, encodeFunctionData as encodeFunctionData18 } from "viem";
4970
5006
  import chalk6 from "chalk";
4971
5007
  import ora5 from "ora";
4972
5008
  import { readFileSync as readFileSync2 } from "fs";
@@ -5695,7 +5731,7 @@ function printSimulationResult(result, callType) {
5695
5731
  }
5696
5732
  async function sendSimulationAlert(subdomain, proposalId, vault, execResult, settleResult) {
5697
5733
  try {
5698
- const xmtp = await import("./xmtp-MR6OJ76L.js");
5734
+ const xmtp = await import("./xmtp-6NJ4PW6L.js");
5699
5735
  const { getAccount: getAccount2 } = await import("./client-KBBFAMEI.js");
5700
5736
  const group = await xmtp.getGroup("", subdomain);
5701
5737
  const allRisks = [...execResult.risks, ...settleResult?.risks ?? []];
@@ -5798,10 +5834,10 @@ function parseCallsFile(path) {
5798
5834
  }
5799
5835
  function registerProposalCommands(program2) {
5800
5836
  const proposal = program2.command("proposal").description("Governance proposals \u2014 create, vote, execute, settle");
5801
- proposal.command("create").description("Submit a strategy proposal").requiredOption("--vault <address>", "Vault address the proposal targets").requiredOption("--name <name>", "Strategy name").requiredOption("--description <text>", "Strategy rationale and risk summary").requiredOption("--performance-fee <bps>", "Agent fee in bps (e.g. 1500 = 15%)").requiredOption("--duration <duration>", "Strategy duration (e.g. 7d, 24h, 3600)").requiredOption("--execute-calls <path>", "Path to JSON file with execute Call[] array").requiredOption("--settle-calls <path>", "Path to JSON file with settlement Call[] array").option("--strategy <address>", "Live-NAV strategy clone address (default: none \u2014 queue-only)").option("--metadata-uri <uri>", "Override \u2014 skip IPFS upload and use this URI directly").option("--simulate", "Simulate calls via Tenderly before submitting").option("--force", "Submit even if simulation fails (requires --simulate)").action(async (opts) => {
5837
+ proposal.command("create").description("Submit a strategy proposal").requiredOption("--vault <address>", "Vault address the proposal targets").requiredOption("--name <name>", "Strategy name").requiredOption("--description <text>", "Strategy rationale and risk summary").requiredOption("--performance-fee <bps>", "Agent fee in bps (e.g. 1500 = 15%)").requiredOption("--duration <duration>", "Strategy duration (e.g. 7d, 24h, 3600)").requiredOption("--execute-calls <path>", "Path to JSON file with execute Call[] array").requiredOption("--settle-calls <path>", "Path to JSON file with settlement Call[] array").option("--strategy <address>", "Live-NAV strategy clone address (default: none \u2014 queue-only)").option("--metadata-uri <uri>", "Override \u2014 skip metadata pinning and use this URI directly").option("--simulate", "Simulate calls via Tenderly before submitting").option("--force", "Submit even if simulation fails (requires --simulate)").action(async (opts) => {
5802
5838
  try {
5803
5839
  const vault = opts.vault;
5804
- if (!isAddress5(vault)) {
5840
+ if (!isAddress6(vault)) {
5805
5841
  console.error(chalk6.red(`Invalid vault address: ${opts.vault}`));
5806
5842
  process.exit(1);
5807
5843
  }
@@ -5812,28 +5848,43 @@ function registerProposalCommands(program2) {
5812
5848
  const ZERO_STRATEGY = "0x0000000000000000000000000000000000000000";
5813
5849
  let strategy2 = ZERO_STRATEGY;
5814
5850
  if (opts.strategy) {
5815
- if (!isAddress5(opts.strategy)) {
5851
+ if (!isAddress6(opts.strategy)) {
5816
5852
  console.error(chalk6.red(`Invalid strategy address: ${opts.strategy}`));
5817
5853
  process.exit(1);
5818
5854
  }
5819
5855
  strategy2 = opts.strategy;
5820
5856
  }
5821
- if (isCalldataOnly()) {
5822
- if (!opts.metadataUri) {
5823
- console.error(
5824
- chalk6.red(
5825
- "--calldata-only requires --metadata-uri (IPFS metadata upload needs a signing wallet)"
5826
- )
5827
- );
5828
- process.exit(1);
5857
+ const pinProposalMetadata = async (proposer) => {
5858
+ const proposalMeta = {
5859
+ schema: "sherwood/proposal/v1",
5860
+ name: opts.name,
5861
+ description: opts.description,
5862
+ chain: getNetwork(),
5863
+ strategies: [],
5864
+ terms: {},
5865
+ links: {},
5866
+ ...proposer ? { proposer } : {},
5867
+ vault,
5868
+ performanceFeeBps: Number(performanceFeeBps),
5869
+ strategyDuration: Number(strategyDuration),
5870
+ createdAt: Math.floor(Date.now() / 1e3)
5871
+ };
5872
+ try {
5873
+ return await uploadMetadata(proposalMeta);
5874
+ } catch {
5875
+ const json = JSON.stringify({ name: opts.name, description: opts.description, vault });
5876
+ return `data:application/json;base64,${Buffer.from(json).toString("base64")}`;
5829
5877
  }
5878
+ };
5879
+ if (isCalldataOnly()) {
5830
5880
  try {
5881
+ const metadataURI2 = opts.metadataUri || await pinProposalMetadata();
5831
5882
  emitCalldata(
5832
5883
  encodePropose(
5833
5884
  {
5834
5885
  vault,
5835
5886
  strategy: strategy2,
5836
- metadataURI: opts.metadataUri,
5887
+ metadataURI: metadataURI2,
5837
5888
  performanceFeeBps: Number(performanceFeeBps),
5838
5889
  strategyDuration,
5839
5890
  executeCalls,
@@ -5851,31 +5902,11 @@ function registerProposalCommands(program2) {
5851
5902
  let metadataURI = opts.metadataUri || "";
5852
5903
  if (!metadataURI) {
5853
5904
  const spinner2 = ora5({ text: W2("Uploading metadata to IPFS..."), color: "green" }).start();
5854
- try {
5855
- const account = getAccount();
5856
- const metadata = {
5857
- schema: "sherwood/proposal/v1",
5858
- name: opts.name,
5859
- description: opts.description,
5860
- chain: getNetwork(),
5861
- strategies: [],
5862
- terms: {},
5863
- links: {}
5864
- };
5865
- const proposalMeta = {
5866
- ...metadata,
5867
- proposer: account.address,
5868
- vault,
5869
- performanceFeeBps: Number(performanceFeeBps),
5870
- strategyDuration: Number(strategyDuration),
5871
- createdAt: Math.floor(Date.now() / 1e3)
5872
- };
5873
- metadataURI = await uploadMetadata(proposalMeta);
5874
- spinner2.succeed(G2(`Metadata pinned: ${DIM2(metadataURI)}`));
5875
- } catch (err) {
5905
+ metadataURI = await pinProposalMetadata(getAccount().address);
5906
+ if (metadataURI.startsWith("data:")) {
5876
5907
  spinner2.warn(chalk6.yellow("IPFS upload failed \u2014 using inline metadata"));
5877
- const json = JSON.stringify({ name: opts.name, description: opts.description, vault });
5878
- metadataURI = `data:application/json;base64,${Buffer.from(json).toString("base64")}`;
5908
+ } else {
5909
+ spinner2.succeed(G2(`Metadata pinned: ${DIM2(metadataURI)}`));
5879
5910
  }
5880
5911
  }
5881
5912
  console.log();
@@ -6423,7 +6454,7 @@ function registerProposalCommands(program2) {
6423
6454
  console.log(DIM2(`
6424
6455
  Simulating proposal #${proposalId} on vault ${vault.slice(0, 10)}...`));
6425
6456
  } else if (opts.executeCalls) {
6426
- if (!opts.vault || !isAddress5(opts.vault)) {
6457
+ if (!opts.vault || !isAddress6(opts.vault)) {
6427
6458
  console.error(chalk6.red("\n \u2716 --vault is required when using --execute-calls"));
6428
6459
  process.exit(1);
6429
6460
  }
@@ -6627,7 +6658,7 @@ function registerGovernorCommands(program2) {
6627
6658
  // src/commands/guardian-delegate.ts
6628
6659
  import chalk8 from "chalk";
6629
6660
  import ora7 from "ora";
6630
- import { formatUnits as formatUnits5, isAddress as isAddress6, parseUnits as parseUnits5 } from "viem";
6661
+ import { formatUnits as formatUnits5, isAddress as isAddress7, parseUnits as parseUnits5 } from "viem";
6631
6662
  var G4 = chalk8.green;
6632
6663
  var W4 = chalk8.white;
6633
6664
  var DIM4 = chalk8.gray;
@@ -6710,7 +6741,7 @@ function registerGuardianCommands(program2) {
6710
6741
  const pc = getPublicClient();
6711
6742
  let target;
6712
6743
  if (addressArg) {
6713
- if (!isAddress6(addressArg)) {
6744
+ if (!isAddress7(addressArg)) {
6714
6745
  console.error(chalk8.red("Invalid address"));
6715
6746
  process.exit(1);
6716
6747
  }
@@ -6801,7 +6832,7 @@ function registerGuardianCommands(program2) {
6801
6832
  }
6802
6833
  });
6803
6834
  guardian.command("delegate <delegate> <amount>").description("Delegate WOOD stake to a guardian. Amount in WOOD.").action(async (delegate, amountStr) => {
6804
- if (!isAddress6(delegate)) {
6835
+ if (!isAddress7(delegate)) {
6805
6836
  console.error(chalk8.red("Invalid delegate address"));
6806
6837
  process.exit(1);
6807
6838
  }
@@ -6825,7 +6856,7 @@ function registerGuardianCommands(program2) {
6825
6856
  }
6826
6857
  });
6827
6858
  guardian.command("undelegate <delegate> <action>").description("Unstake-delegation flow: 'request' | 'cancel' | 'claim'").action(async (delegate, action) => {
6828
- if (!isAddress6(delegate)) {
6859
+ if (!isAddress7(delegate)) {
6829
6860
  console.error(chalk8.red("Invalid delegate address"));
6830
6861
  process.exit(1);
6831
6862
  }
@@ -6894,7 +6925,7 @@ function registerGuardianCommands(program2) {
6894
6925
  }
6895
6926
  });
6896
6927
  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) => {
6897
- if (!isAddress6(delegate)) {
6928
+ if (!isAddress7(delegate)) {
6898
6929
  console.error(chalk8.red("Invalid delegate address"));
6899
6930
  process.exit(1);
6900
6931
  }
@@ -9501,9 +9532,9 @@ try {
9501
9532
  } catch {
9502
9533
  }
9503
9534
  var require2 = createRequire(import.meta.url);
9504
- var CLI_VERSION = "0.65.0";
9535
+ var CLI_VERSION = "0.65.2";
9505
9536
  async function loadXmtp() {
9506
- return import("./xmtp-MR6OJ76L.js");
9537
+ return import("./xmtp-6NJ4PW6L.js");
9507
9538
  }
9508
9539
  async function loadCron() {
9509
9540
  return import("./cron-EOULYO3R.js");
@@ -9515,7 +9546,7 @@ var BOLD6 = chalk15.white.bold;
9515
9546
  var LABEL5 = chalk15.green.bold;
9516
9547
  var SEP6 = () => console.log(DIM6("\u2500".repeat(60)));
9517
9548
  function validateAddress(value, name) {
9518
- if (!isAddress7(value)) {
9549
+ if (!isAddress8(value)) {
9519
9550
  console.error(chalk15.red(`Invalid ${name} address: ${value}`));
9520
9551
  process.exit(1);
9521
9552
  }
@@ -10084,7 +10115,7 @@ syndicate.command("add").description("Register an agent on a syndicate vault (cr
10084
10115
  if (opts.agentId) {
10085
10116
  agentId = BigInt(opts.agentId);
10086
10117
  } else {
10087
- const { AGENT_REGISTRY: AGENT_REGISTRY2 } = await import("./addresses-FXTJXDI7.js");
10118
+ const { AGENT_REGISTRY: AGENT_REGISTRY2 } = await import("./addresses-J2LMGUCT.js");
10088
10119
  const registry2 = AGENT_REGISTRY2().IDENTITY_REGISTRY;
10089
10120
  if (registry2 === "0x0000000000000000000000000000000000000000") {
10090
10121
  agentId = 0n;
@@ -10777,7 +10808,7 @@ vaultCmd.command("redeem").description("Redeem vault shares for the underlying a
10777
10808
  `));
10778
10809
  process.exit(1);
10779
10810
  }
10780
- if (opts.receiver && !isAddress7(opts.receiver)) {
10811
+ if (opts.receiver && !isAddress8(opts.receiver)) {
10781
10812
  console.error(chalk15.red(`
10782
10813
  \u2716 Invalid receiver address: ${opts.receiver}
10783
10814
  `));
@@ -10810,7 +10841,7 @@ vaultCmd.command("redeem").description("Redeem vault shares for the underlying a
10810
10841
  var strategy = program.command("strategy").description("Strategy templates \u2014 list, clone, propose");
10811
10842
  registerStrategyTemplateCommands(strategy);
10812
10843
  program.command("providers").description("List available DeFi providers").action(async () => {
10813
- const { MessariProvider, NansenProvider } = await import("./research-N3R5MU6Q.js");
10844
+ const { MessariProvider, NansenProvider } = await import("./research-XEXTHDT3.js");
10814
10845
  const providers = [new MoonwellProvider(), new UniswapProvider(), new MessariProvider(), new NansenProvider()];
10815
10846
  for (const p of providers) {
10816
10847
  const info = p.info();
@@ -10821,7 +10852,7 @@ ${info.name} (${info.type})`);
10821
10852
  }
10822
10853
  });
10823
10854
  try {
10824
- const { registerChatCommands } = await import("./chat-SL4O7Y3C.js");
10855
+ const { registerChatCommands } = await import("./chat-JSSTSE4K.js");
10825
10856
  registerChatCommands(program);
10826
10857
  } catch {
10827
10858
  program.command("chat <name> [action] [actionArgs...]").description("Syndicate chat (XMTP) \u2014 requires @xmtp/cli").action(() => {
@@ -10831,7 +10862,7 @@ try {
10831
10862
  process.exit(1);
10832
10863
  });
10833
10864
  }
10834
- var { registerSessionCommands } = await import("./session-FPQGAMSS.js");
10865
+ var { registerSessionCommands } = await import("./session-FJB2RV2X.js");
10835
10866
  registerSessionCommands(program);
10836
10867
  registerVeniceCommands(program);
10837
10868
  registerAllowanceCommands(program);
@@ -10839,11 +10870,11 @@ registerIdentityCommands(program);
10839
10870
  registerProposalCommands(program);
10840
10871
  registerGovernorCommands(program);
10841
10872
  registerGuardianCommands(program);
10842
- var { registerResearchCommands } = await import("./research-RL2ASMQ5.js");
10873
+ var { registerResearchCommands } = await import("./research-FUQOQWKK.js");
10843
10874
  registerResearchCommands(program);
10844
- var { registerAgentCommands } = await import("./agent-IVESTCYM.js");
10875
+ var { registerAgentCommands } = await import("./agent-AETROOEW.js");
10845
10876
  registerAgentCommands(program);
10846
- var { registerTradeCommands } = await import("./trade-AJNB4ULF.js");
10877
+ var { registerTradeCommands } = await import("./trade-U7H5IFH6.js");
10847
10878
  registerTradeCommands(program);
10848
10879
  registerGridCommand(program);
10849
10880
  var configCmd = program.command("config");