@sherwoodagent/cli 0.28.0 → 0.29.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 (55) hide show
  1. package/dist/addresses-CQLJSZGN.js +35 -0
  2. package/dist/{agent-C4HZUQNI.js → agent-QIQABFLV.js} +7 -9
  3. package/dist/agent-QIQABFLV.js.map +1 -0
  4. package/dist/{chat-C7EEHQHR.js → chat-N6LSZUSC.js} +44 -12
  5. package/dist/chat-N6LSZUSC.js.map +1 -0
  6. package/dist/{chunk-KEUEO4UE.js → chunk-2H6IGGKN.js} +1 -1
  7. package/dist/chunk-2H6IGGKN.js.map +1 -0
  8. package/dist/{chunk-4OK3ZW54.js → chunk-3EMDYEAD.js} +6 -6
  9. package/dist/{chunk-H57TPN3L.js → chunk-I3UVF2GD.js} +7 -7
  10. package/dist/{chunk-Y3M66Z5O.js → chunk-IIBOFECO.js} +6 -6
  11. package/dist/{chunk-GCTABO5K.js → chunk-QGEIK4H5.js} +2 -2
  12. package/dist/chunk-T5BRUFWV.js +142 -0
  13. package/dist/chunk-T5BRUFWV.js.map +1 -0
  14. package/dist/{chunk-GJPP22NB.js → chunk-WQOTLKVP.js} +27 -2
  15. package/dist/{chunk-GJPP22NB.js.map → chunk-WQOTLKVP.js.map} +1 -1
  16. package/dist/{chunk-6Y4QZMVP.js → chunk-WRG7GAIA.js} +2 -2
  17. package/dist/{chunk-C6JA5EES.js → chunk-YRYPGJ66.js} +8 -8
  18. package/dist/{chunk-RNCK26JE.js → chunk-ZPYN5ZAI.js} +3 -3
  19. package/dist/chunk-ZPYN5ZAI.js.map +1 -0
  20. package/dist/{client-QBVND2OI.js → client-HBMSTSKK.js} +3 -3
  21. package/dist/{eas-CA6BXTG5.js → eas-D3KSAGWT.js} +5 -5
  22. package/dist/{governor-VWAPPCFS.js → governor-3MYMDBRF.js} +5 -5
  23. package/dist/index.js +157 -196
  24. package/dist/index.js.map +1 -1
  25. package/dist/{ipfs-22YLNQ2C.js → ipfs-IGXLLJCF.js} +2 -2
  26. package/dist/{network-V77NDYOW.js → network-X6GM7ROG.js} +2 -2
  27. package/dist/{price-YTWAYSCU.js → price-DXNFNTV6.js} +7 -7
  28. package/dist/{research-CGDUEDL5.js → research-H3I4LALI.js} +8 -8
  29. package/dist/{research-DLZNLY6X.js → research-NCESMYXK.js} +4 -4
  30. package/dist/research-NCESMYXK.js.map +1 -0
  31. package/dist/{session-6NIAZOEH.js → session-5JUUZYIL.js} +11 -11
  32. package/dist/{trade-VGJP6LAN.js → trade-XDE6YCNY.js} +15 -15
  33. package/dist/{xmtp-SF34ZC5H.js → xmtp-XTJ7HDVG.js} +5 -5
  34. package/package.json +1 -1
  35. package/dist/agent-C4HZUQNI.js.map +0 -1
  36. package/dist/chat-C7EEHQHR.js.map +0 -1
  37. package/dist/chunk-KEUEO4UE.js.map +0 -1
  38. package/dist/chunk-RNCK26JE.js.map +0 -1
  39. /package/dist/{client-QBVND2OI.js.map → addresses-CQLJSZGN.js.map} +0 -0
  40. /package/dist/{chunk-4OK3ZW54.js.map → chunk-3EMDYEAD.js.map} +0 -0
  41. /package/dist/{chunk-H57TPN3L.js.map → chunk-I3UVF2GD.js.map} +0 -0
  42. /package/dist/{chunk-Y3M66Z5O.js.map → chunk-IIBOFECO.js.map} +0 -0
  43. /package/dist/{chunk-GCTABO5K.js.map → chunk-QGEIK4H5.js.map} +0 -0
  44. /package/dist/{chunk-6Y4QZMVP.js.map → chunk-WRG7GAIA.js.map} +0 -0
  45. /package/dist/{chunk-C6JA5EES.js.map → chunk-YRYPGJ66.js.map} +0 -0
  46. /package/dist/{eas-CA6BXTG5.js.map → client-HBMSTSKK.js.map} +0 -0
  47. /package/dist/{governor-VWAPPCFS.js.map → eas-D3KSAGWT.js.map} +0 -0
  48. /package/dist/{ipfs-22YLNQ2C.js.map → governor-3MYMDBRF.js.map} +0 -0
  49. /package/dist/{network-V77NDYOW.js.map → ipfs-IGXLLJCF.js.map} +0 -0
  50. /package/dist/{research-DLZNLY6X.js.map → network-X6GM7ROG.js.map} +0 -0
  51. /package/dist/{price-YTWAYSCU.js.map → price-DXNFNTV6.js.map} +0 -0
  52. /package/dist/{research-CGDUEDL5.js.map → research-H3I4LALI.js.map} +0 -0
  53. /package/dist/{session-6NIAZOEH.js.map → session-5JUUZYIL.js.map} +0 -0
  54. /package/dist/{trade-VGJP6LAN.js.map → trade-XDE6YCNY.js.map} +0 -0
  55. /package/dist/{xmtp-SF34ZC5H.js.map → xmtp-XTJ7HDVG.js.map} +0 -0
package/dist/index.js CHANGED
@@ -9,7 +9,24 @@ import {
9
9
  getQuote,
10
10
  listModels,
11
11
  provisionApiKey
12
- } from "./chunk-Y3M66Z5O.js";
12
+ } from "./chunk-IIBOFECO.js";
13
+ import {
14
+ createApproval,
15
+ createJoinRequest,
16
+ getEasScanUrl,
17
+ parseReferrer,
18
+ queryApprovals,
19
+ queryJoinRequests,
20
+ revokeAttestation,
21
+ stripReferrerPrefix
22
+ } from "./chunk-I3UVF2GD.js";
23
+ import {
24
+ createSyndicate,
25
+ getActiveSyndicates,
26
+ getSyndicate,
27
+ subdomainExists,
28
+ updateMetadata
29
+ } from "./chunk-T5BRUFWV.js";
13
30
  import {
14
31
  approveDepositor,
15
32
  deposit,
@@ -32,7 +49,7 @@ import {
32
49
  resolveVaultSyndicate,
33
50
  setTextRecord,
34
51
  setVaultAddress
35
- } from "./chunk-C6JA5EES.js";
52
+ } from "./chunk-YRYPGJ66.js";
36
53
  import {
37
54
  PROPOSAL_STATE,
38
55
  PROPOSAL_STATES,
@@ -64,21 +81,20 @@ import {
64
81
  setVotingPeriod,
65
82
  settleProposal,
66
83
  vote
67
- } from "./chunk-4OK3ZW54.js";
84
+ } from "./chunk-3EMDYEAD.js";
68
85
  import {
69
86
  fetchMetadata,
70
87
  uploadMetadata
71
- } from "./chunk-KEUEO4UE.js";
88
+ } from "./chunk-2H6IGGKN.js";
72
89
  import {
73
- createApproval,
74
- createJoinRequest,
75
- getEasScanUrl,
76
- parseReferrer,
77
- queryApprovals,
78
- queryJoinRequests,
79
- revokeAttestation,
80
- stripReferrerPrefix
81
- } from "./chunk-H57TPN3L.js";
90
+ BASE_STRATEGY_ABI,
91
+ ERC20_ABI,
92
+ PORTFOLIO_STRATEGY_ABI,
93
+ SWAP_ROUTER_ABI,
94
+ SWAP_ROUTER_EXACT_INPUT_SINGLE_ABI,
95
+ SYNDICATE_VAULT_ABI,
96
+ VENICE_STAKING_ABI
97
+ } from "./chunk-PQ5ZX6ZT.js";
82
98
  import {
83
99
  AERODROME,
84
100
  AGENT_REGISTRY,
@@ -91,17 +107,7 @@ import {
91
107
  TOKENS,
92
108
  UNISWAP,
93
109
  VENICE
94
- } from "./chunk-GJPP22NB.js";
95
- import {
96
- BASE_STRATEGY_ABI,
97
- ERC20_ABI,
98
- PORTFOLIO_STRATEGY_ABI,
99
- SWAP_ROUTER_ABI,
100
- SWAP_ROUTER_EXACT_INPUT_SINGLE_ABI,
101
- SYNDICATE_FACTORY_ABI,
102
- SYNDICATE_VAULT_ABI,
103
- VENICE_STAKING_ABI
104
- } from "./chunk-PQ5ZX6ZT.js";
110
+ } from "./chunk-WQOTLKVP.js";
105
111
  import {
106
112
  formatContractError,
107
113
  getAccount,
@@ -109,7 +115,7 @@ import {
109
115
  sendTxWithRetry,
110
116
  waitForReceipt,
111
117
  writeContractWithRetry
112
- } from "./chunk-6Y4QZMVP.js";
118
+ } from "./chunk-WRG7GAIA.js";
113
119
  import {
114
120
  CHAIN_REGISTRY,
115
121
  VALID_NETWORKS,
@@ -119,12 +125,13 @@ import {
119
125
  getRpcUrl,
120
126
  isTestnet,
121
127
  setNetwork
122
- } from "./chunk-RNCK26JE.js";
128
+ } from "./chunk-ZPYN5ZAI.js";
123
129
  import {
124
130
  addSyndicate,
125
131
  cacheGroupId,
126
132
  cacheSwapRoute,
127
133
  getAgentId,
134
+ getCachedGroupId,
128
135
  getCachedSwapRoute,
129
136
  getChainContracts,
130
137
  getNotifyTo,
@@ -147,7 +154,7 @@ import {
147
154
  import { config as loadDotenv } from "dotenv";
148
155
  import { createRequire } from "module";
149
156
  import { Command, Option } from "commander";
150
- import { parseUnits as parseUnits5, formatUnits as formatUnits5, isAddress as isAddress5 } from "viem";
157
+ import { parseUnits as parseUnits4, formatUnits as formatUnits4, isAddress as isAddress5 } from "viem";
151
158
  import chalk8 from "chalk";
152
159
  import ora7 from "ora";
153
160
  import { input, confirm, select } from "@inquirer/prompts";
@@ -1383,9 +1390,9 @@ function registerStrategyTemplateCommands(strategy2) {
1383
1390
  console.error(chalk.red("Missing --name, --performance-fee, or --duration. Use --write-calls to skip proposal submission."));
1384
1391
  process.exit(1);
1385
1392
  }
1386
- const { propose: propose2 } = await import("./governor-VWAPPCFS.js");
1387
- const { pinJSON } = await import("./ipfs-22YLNQ2C.js");
1388
- const { parseDuration: parseDuration2 } = await import("./governor-VWAPPCFS.js");
1393
+ const { propose: propose2 } = await import("./governor-3MYMDBRF.js");
1394
+ const { pinJSON } = await import("./ipfs-IGXLLJCF.js");
1395
+ const { parseDuration: parseDuration2 } = await import("./governor-3MYMDBRF.js");
1389
1396
  const performanceFeeBps = BigInt(opts.performanceFee);
1390
1397
  if (performanceFeeBps < 0n || performanceFeeBps > 10000n) {
1391
1398
  console.error(chalk.red("--performance-fee must be 0-10000 (basis points)"));
@@ -1493,7 +1500,7 @@ function registerStrategyTemplateCommands(strategy2) {
1493
1500
  let prices = [];
1494
1501
  let priceSource = null;
1495
1502
  try {
1496
- const { getTokenPricesInAsset } = await import("./price-YTWAYSCU.js");
1503
+ const { getTokenPricesInAsset } = await import("./price-DXNFNTV6.js");
1497
1504
  prices = await getTokenPricesInAsset({
1498
1505
  tokens: allocations.map((a, i) => ({
1499
1506
  token: a.token,
@@ -1819,124 +1826,6 @@ function registerStrategyTemplateCommands(strategy2) {
1819
1826
  });
1820
1827
  }
1821
1828
 
1822
- // src/lib/factory.ts
1823
- import { decodeEventLog } from "viem";
1824
- function getFactoryAddress() {
1825
- return SHERWOOD().FACTORY;
1826
- }
1827
- async function createSyndicate(params) {
1828
- const client = getPublicClient();
1829
- const hash = await writeContractWithRetry({
1830
- account: getAccount(),
1831
- chain: getChain(),
1832
- address: getFactoryAddress(),
1833
- abi: SYNDICATE_FACTORY_ABI,
1834
- functionName: "createSyndicate",
1835
- args: [
1836
- params.creatorAgentId,
1837
- {
1838
- metadataURI: params.metadataURI,
1839
- asset: params.asset,
1840
- name: params.name,
1841
- symbol: params.symbol,
1842
- openDeposits: params.openDeposits,
1843
- subdomain: params.subdomain
1844
- }
1845
- ]
1846
- });
1847
- const receipt = await waitForReceipt(hash);
1848
- for (const log of receipt.logs) {
1849
- try {
1850
- const event = decodeEventLog({
1851
- abi: SYNDICATE_FACTORY_ABI,
1852
- data: log.data,
1853
- topics: log.topics
1854
- });
1855
- if (event.eventName === "SyndicateCreated") {
1856
- const args = event.args;
1857
- return {
1858
- hash,
1859
- syndicateId: args.id,
1860
- vault: args.vault
1861
- };
1862
- }
1863
- } catch {
1864
- }
1865
- }
1866
- const count = await getSyndicateCount();
1867
- const info = await getSyndicate(count);
1868
- return {
1869
- hash,
1870
- syndicateId: count,
1871
- vault: info.vault
1872
- };
1873
- }
1874
- async function subdomainExists(subdomain) {
1875
- const client = getPublicClient();
1876
- const id = await client.readContract({
1877
- address: getFactoryAddress(),
1878
- abi: SYNDICATE_FACTORY_ABI,
1879
- functionName: "subdomainToSyndicate",
1880
- args: [subdomain]
1881
- });
1882
- return id > 0n ? id : null;
1883
- }
1884
- async function getSyndicate(id) {
1885
- const client = getPublicClient();
1886
- const result = await client.readContract({
1887
- address: getFactoryAddress(),
1888
- abi: SYNDICATE_FACTORY_ABI,
1889
- functionName: "syndicates",
1890
- args: [id]
1891
- });
1892
- return {
1893
- id: result[0],
1894
- vault: result[1],
1895
- creator: result[2],
1896
- metadataURI: result[3],
1897
- createdAt: result[4],
1898
- active: result[5],
1899
- subdomain: result[6]
1900
- };
1901
- }
1902
- async function getSyndicateCount() {
1903
- const client = getPublicClient();
1904
- return client.readContract({
1905
- address: getFactoryAddress(),
1906
- abi: SYNDICATE_FACTORY_ABI,
1907
- functionName: "syndicateCount"
1908
- });
1909
- }
1910
- async function getActiveSyndicates() {
1911
- const client = getPublicClient();
1912
- const result = await client.readContract({
1913
- address: getFactoryAddress(),
1914
- abi: SYNDICATE_FACTORY_ABI,
1915
- functionName: "getAllActiveSyndicates"
1916
- });
1917
- return result.map((s) => ({
1918
- id: s.id,
1919
- vault: s.vault,
1920
- creator: s.creator,
1921
- metadataURI: s.metadataURI,
1922
- createdAt: s.createdAt,
1923
- active: s.active,
1924
- subdomain: s.subdomain
1925
- }));
1926
- }
1927
- async function updateMetadata(syndicateId, metadataURI) {
1928
- const hash = await writeContractWithRetry({
1929
- account: getAccount(),
1930
- chain: getChain(),
1931
- address: getFactoryAddress(),
1932
- abi: SYNDICATE_FACTORY_ABI,
1933
- functionName: "updateMetadata",
1934
- args: [syndicateId, metadataURI]
1935
- });
1936
- await waitForReceipt(hash);
1937
- return hash;
1938
- }
1939
-
1940
1829
  // src/lib/subgraph.ts
1941
1830
  function getSubgraphUrl() {
1942
1831
  const url = process.env.SUBGRAPH_URL;
@@ -2004,7 +1893,7 @@ async function getActiveSyndicates2(creator) {
2004
1893
  }
2005
1894
 
2006
1895
  // src/commands/venice.ts
2007
- import { formatUnits as formatUnits3, isAddress as isAddress2 } from "viem";
1896
+ import { formatUnits as formatUnits2, isAddress as isAddress2 } from "viem";
2008
1897
  import chalk2 from "chalk";
2009
1898
  import ora2 from "ora";
2010
1899
  import { readFileSync } from "fs";
@@ -2027,7 +1916,7 @@ function registerVeniceCommands(program2) {
2027
1916
  console.log(chalk2.yellow(" Use the VeniceInferenceStrategy via a proposal to distribute sVVV to agents."));
2028
1917
  process.exit(1);
2029
1918
  }
2030
- checkSpinner.succeed(`sVVV balance: ${formatUnits3(sVvvBalance, 18)}`);
1919
+ checkSpinner.succeed(`sVVV balance: ${formatUnits2(sVvvBalance, 18)}`);
2031
1920
  } catch (err) {
2032
1921
  checkSpinner.fail("Failed to check sVVV balance");
2033
1922
  console.error(chalk2.red(formatContractError(err)));
@@ -2040,7 +1929,7 @@ function registerVeniceCommands(program2) {
2040
1929
  console.log(chalk2.dim(` Key: ${apiKey.slice(0, 8)}...${apiKey.slice(-4)}`));
2041
1930
  console.log(chalk2.dim(" Saved to ~/.sherwood/config.json"));
2042
1931
  try {
2043
- const { createVeniceProvisionAttestation, getEasScanUrl: getEasScanUrl2 } = await import("./eas-CA6BXTG5.js");
1932
+ const { createVeniceProvisionAttestation, getEasScanUrl: getEasScanUrl2 } = await import("./eas-D3KSAGWT.js");
2044
1933
  const { uid } = await createVeniceProvisionAttestation(account.address);
2045
1934
  if (uid !== "0x0000000000000000000000000000000000000000000000000000000000000000") {
2046
1935
  console.log(chalk2.dim(` Attested: ${getEasScanUrl2(uid)}`));
@@ -2112,17 +2001,17 @@ function registerVeniceCommands(program2) {
2112
2001
  console.log(chalk2.bold("Venice Inference Status"));
2113
2002
  console.log(chalk2.dim("\u2500".repeat(50)));
2114
2003
  console.log(chalk2.bold("\n Vault"));
2115
- console.log(` Profit available: ${formatUnits3(profit, assetDecimals)} ${assetSymbol}`);
2116
- console.log(` VVV (unstaked): ${formatUnits3(vaultVvvBalance, 18)}`);
2004
+ console.log(` Profit available: ${formatUnits2(profit, assetDecimals)} ${assetSymbol}`);
2005
+ console.log(` VVV (unstaked): ${formatUnits2(vaultVvvBalance, 18)}`);
2117
2006
  console.log(chalk2.bold("\n Agent sVVV Balances"));
2118
2007
  for (const { agent, balance } of agentBalances) {
2119
2008
  const isMe = agent.toLowerCase() === account.address.toLowerCase();
2120
2009
  const label = isMe ? chalk2.green(`${agent} (you)`) : agent;
2121
- console.log(` ${label}: ${formatUnits3(balance, 18)} sVVV`);
2010
+ console.log(` ${label}: ${formatUnits2(balance, 18)} sVVV`);
2122
2011
  }
2123
2012
  console.log(chalk2.bold("\n Your Wallet"));
2124
- console.log(` sVVV: ${formatUnits3(mySvvv, 18)}`);
2125
- console.log(` Pending rewards: ${formatUnits3(myPending, 18)} VVV`);
2013
+ console.log(` sVVV: ${formatUnits2(mySvvv, 18)}`);
2014
+ console.log(` Pending rewards: ${formatUnits2(myPending, 18)} VVV`);
2126
2015
  console.log(chalk2.bold("\n Venice API"));
2127
2016
  console.log(` Key: ${apiKey ? `${apiKey.slice(0, 8)}...${apiKey.slice(-4)}` : chalk2.dim("not provisioned")}`);
2128
2017
  console.log(` Status: ${apiKeyValid ? chalk2.green("valid") : chalk2.red("invalid/missing")}`);
@@ -2191,10 +2080,10 @@ ${opts.prompt}`;
2191
2080
  console.log(chalk2.dim(`Model: ${result.model} | Tokens: ${result.usage.promptTokens} in, ${result.usage.completionTokens} out, ${result.usage.totalTokens} total`));
2192
2081
  }
2193
2082
  try {
2194
- const { createVeniceInferenceAttestation, getEasScanUrl: getEasScanUrl2 } = await import("./eas-CA6BXTG5.js");
2083
+ const { createVeniceInferenceAttestation, getEasScanUrl: getEasScanUrl2 } = await import("./eas-D3KSAGWT.js");
2195
2084
  const { keccak256, toHex, isAddress: isAddr } = await import("viem");
2196
2085
  const { getChainContracts: getChainContracts2 } = await import("./config-YXZKPSZB.js");
2197
- const { getChain: getActiveChain } = await import("./network-V77NDYOW.js");
2086
+ const { getChain: getActiveChain } = await import("./network-X6GM7ROG.js");
2198
2087
  const vaultRecipient = opts.vault && isAddr(opts.vault) ? opts.vault : getChainContracts2(getActiveChain().id).vault;
2199
2088
  const promptHash = keccak256(toHex(userContent)).slice(0, 18);
2200
2089
  const { uid } = await createVeniceInferenceAttestation(
@@ -2218,14 +2107,14 @@ ${opts.prompt}`;
2218
2107
  }
2219
2108
 
2220
2109
  // src/commands/allowance.ts
2221
- import { parseUnits as parseUnits4, formatUnits as formatUnits4, isAddress as isAddress3 } from "viem";
2110
+ import { parseUnits as parseUnits3, formatUnits as formatUnits3, isAddress as isAddress3 } from "viem";
2222
2111
  import chalk3 from "chalk";
2223
2112
  import ora3 from "ora";
2224
2113
 
2225
2114
  // src/strategies/allowance-disburse.ts
2226
- import { encodeFunctionData as encodeFunctionData8, parseUnits as parseUnits3 } from "viem";
2115
+ import { encodeFunctionData as encodeFunctionData8, parseUnits as parseUnits2 } from "viem";
2227
2116
  function buildDisburseBatch(config, vaultAddress, agents, assetAddress, assetDecimals, minUsdc, swapPath) {
2228
- const assetAmount = parseUnits3(config.amount, assetDecimals);
2117
+ const assetAmount = parseUnits2(config.amount, assetDecimals);
2229
2118
  const isUsdc = assetAddress.toLowerCase() === TOKENS().USDC.toLowerCase();
2230
2119
  const isWeth = assetAddress.toLowerCase() === TOKENS().WETH.toLowerCase();
2231
2120
  const calls = [];
@@ -2338,7 +2227,7 @@ function registerAllowanceCommands(program2) {
2338
2227
  console.error(chalk3.red("No agents registered in vault. Register agents first."));
2339
2228
  process.exit(1);
2340
2229
  }
2341
- const requestedAmount = parseUnits4(opts.amount, assetDecimals);
2230
+ const requestedAmount = parseUnits3(opts.amount, assetDecimals);
2342
2231
  const profit = assetBalance > totalDeposited ? assetBalance - totalDeposited : 0n;
2343
2232
  const isUsdc = assetAddress.toLowerCase() === TOKENS().USDC.toLowerCase();
2344
2233
  const isWeth = assetAddress.toLowerCase() === TOKENS().WETH.toLowerCase();
@@ -2347,9 +2236,9 @@ function registerAllowanceCommands(program2) {
2347
2236
  console.log(chalk3.dim("\u2500".repeat(40)));
2348
2237
  console.log(` Asset: ${assetSymbol} (${assetDecimals} decimals)`);
2349
2238
  console.log(` Amount: ${opts.amount} ${assetSymbol}`);
2350
- console.log(` Vault balance: ${formatUnits4(assetBalance, assetDecimals)} ${assetSymbol}`);
2351
- console.log(` Deposited: ${formatUnits4(totalDeposited, assetDecimals)} ${assetSymbol}`);
2352
- console.log(` Profit: ${formatUnits4(profit, assetDecimals)} ${assetSymbol}`);
2239
+ console.log(` Vault balance: ${formatUnits3(assetBalance, assetDecimals)} ${assetSymbol}`);
2240
+ console.log(` Deposited: ${formatUnits3(totalDeposited, assetDecimals)} ${assetSymbol}`);
2241
+ console.log(` Profit: ${formatUnits3(profit, assetDecimals)} ${assetSymbol}`);
2353
2242
  console.log(` Agents: ${agents.length} (USDC will be split equally)`);
2354
2243
  if (!isUsdc) {
2355
2244
  console.log(` Routing: ${isWeth ? `WETH \u2192 USDC (fee ${fee})` : `${assetSymbol} \u2192 WETH \u2192 USDC (fee ${fee})`}`);
@@ -2358,7 +2247,7 @@ function registerAllowanceCommands(program2) {
2358
2247
  console.log(` Vault: ${vaultAddress}`);
2359
2248
  console.log();
2360
2249
  if (requestedAmount > profit) {
2361
- console.warn(chalk3.yellow(` Warning: amount (${opts.amount}) exceeds available profit (${formatUnits4(profit, assetDecimals)})`));
2250
+ console.warn(chalk3.yellow(` Warning: amount (${opts.amount}) exceeds available profit (${formatUnits3(profit, assetDecimals)})`));
2362
2251
  console.warn(chalk3.yellow(" This will use deposited capital, not just profits."));
2363
2252
  console.log();
2364
2253
  }
@@ -2392,7 +2281,7 @@ function registerAllowanceCommands(program2) {
2392
2281
  }
2393
2282
  minUsdc = applySlippage(amountOut, slippageBps);
2394
2283
  quoteSpinner.succeed(
2395
- `Quote: ${formatUnits4(amountOut, 6)} USDC (min: ${formatUnits4(minUsdc, 6)}, per agent: ${formatUnits4(minUsdc / BigInt(agents.length), 6)})`
2284
+ `Quote: ${formatUnits3(amountOut, 6)} USDC (min: ${formatUnits3(minUsdc, 6)}, per agent: ${formatUnits3(minUsdc / BigInt(agents.length), 6)})`
2396
2285
  );
2397
2286
  } catch (err) {
2398
2287
  quoteSpinner.fail("Failed to fetch quote");
@@ -2402,7 +2291,7 @@ function registerAllowanceCommands(program2) {
2402
2291
  }
2403
2292
  const perAgent = minUsdc / BigInt(agents.length);
2404
2293
  if (isUsdc) {
2405
- console.log(chalk3.dim(` Per agent: ${formatUnits4(perAgent, 6)} USDC`));
2294
+ console.log(chalk3.dim(` Per agent: ${formatUnits3(perAgent, 6)} USDC`));
2406
2295
  console.log();
2407
2296
  }
2408
2297
  const config = {
@@ -2469,14 +2358,14 @@ function registerAllowanceCommands(program2) {
2469
2358
  console.log(chalk3.dim("\u2500".repeat(50)));
2470
2359
  console.log(chalk3.bold("\n Vault"));
2471
2360
  console.log(` Asset: ${assetSymbol}`);
2472
- console.log(` Balance: ${formatUnits4(assetBalance, assetDecimals)} ${assetSymbol}`);
2473
- console.log(` Deposited: ${formatUnits4(totalDeposited, assetDecimals)} ${assetSymbol}`);
2474
- console.log(` Profit: ${formatUnits4(profit, assetDecimals)} ${assetSymbol}`);
2361
+ console.log(` Balance: ${formatUnits3(assetBalance, assetDecimals)} ${assetSymbol}`);
2362
+ console.log(` Deposited: ${formatUnits3(totalDeposited, assetDecimals)} ${assetSymbol}`);
2363
+ console.log(` Profit: ${formatUnits3(profit, assetDecimals)} ${assetSymbol}`);
2475
2364
  console.log(chalk3.bold("\n Agent USDC Balances"));
2476
2365
  for (const { agent, balance } of agentBalances) {
2477
2366
  const isMe = agent.toLowerCase() === account.address.toLowerCase();
2478
2367
  const label = isMe ? chalk3.green(`${agent} (you)`) : agent;
2479
- console.log(` ${label}: ${formatUnits4(balance, 6)} USDC`);
2368
+ console.log(` ${label}: ${formatUnits3(balance, 6)} USDC`);
2480
2369
  }
2481
2370
  console.log();
2482
2371
  } catch (err) {
@@ -3323,8 +3212,8 @@ function printSimulationResult(result, callType) {
3323
3212
  }
3324
3213
  async function sendSimulationAlert(subdomain, proposalId, vault, execResult, settleResult) {
3325
3214
  try {
3326
- const xmtp = await import("./xmtp-SF34ZC5H.js");
3327
- const { getAccount: getAccount2 } = await import("./client-QBVND2OI.js");
3215
+ const xmtp = await import("./xmtp-XTJ7HDVG.js");
3216
+ const { getAccount: getAccount2 } = await import("./client-HBMSTSKK.js");
3328
3217
  const group = await xmtp.getGroup("", subdomain);
3329
3218
  const allRisks = [...execResult.risks, ...settleResult?.risks ?? []];
3330
3219
  const criticals = allRisks.filter((r) => r.level === "critical");
@@ -4140,7 +4029,7 @@ try {
4140
4029
  var require2 = createRequire(import.meta.url);
4141
4030
  var { version: CLI_VERSION } = require2("../package.json");
4142
4031
  async function loadXmtp() {
4143
- return import("./xmtp-SF34ZC5H.js");
4032
+ return import("./xmtp-XTJ7HDVG.js");
4144
4033
  }
4145
4034
  async function loadCron() {
4146
4035
  return import("./cron-EOULYO3R.js");
@@ -4477,10 +4366,16 @@ syndicate.command("list").description("List active syndicates (queries subgraph,
4477
4366
  process.exit(1);
4478
4367
  }
4479
4368
  });
4480
- syndicate.command("info").description("Display syndicate details by ID").argument("<id>", "Syndicate ID").action(async (idStr) => {
4369
+ syndicate.command("info").description("Display syndicate details by ID or subdomain").argument("<id>", "Syndicate ID or subdomain name").action(async (idStr) => {
4481
4370
  const spinner = ora7("Loading syndicate info...").start();
4482
4371
  try {
4483
- const id = BigInt(idStr);
4372
+ let id;
4373
+ if (/^\d+$/.test(idStr)) {
4374
+ id = BigInt(idStr);
4375
+ } else {
4376
+ const resolved = await resolveSyndicate(idStr);
4377
+ id = resolved.id;
4378
+ }
4484
4379
  const info = await getSyndicate(id);
4485
4380
  spinner.stop();
4486
4381
  if (!info.vault || info.vault === "0x0000000000000000000000000000000000000000") {
@@ -4501,6 +4396,12 @@ syndicate.command("info").description("Display syndicate details by ID").argumen
4501
4396
  if (info.metadataURI) {
4502
4397
  console.log(` Metadata: ${chalk8.dim(info.metadataURI)}`);
4503
4398
  }
4399
+ if (info.subdomain) {
4400
+ const xmtpGroupId = getCachedGroupId(info.subdomain);
4401
+ if (xmtpGroupId) {
4402
+ console.log(` XMTP Group: ${chalk8.cyan(xmtpGroupId)}`);
4403
+ }
4404
+ }
4504
4405
  setVaultAddress(info.vault);
4505
4406
  const vaultInfo = await getVaultInfo();
4506
4407
  console.log();
@@ -4580,7 +4481,7 @@ syndicate.command("remove-depositor").description("Remove an address from the de
4580
4481
  process.exit(1);
4581
4482
  }
4582
4483
  });
4583
- syndicate.command("add").description("Register an agent on a syndicate vault (creator only)").option("--vault <address>", "Vault address (default: from config)").requiredOption("--agent-id <id>", "Agent's ERC-8004 identity token ID").requiredOption("--wallet <address>", "Agent wallet address").action(async (opts) => {
4484
+ 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) => {
4584
4485
  const spinner = ora7("Verifying creator...").start();
4585
4486
  try {
4586
4487
  resolveVault(opts);
@@ -4592,11 +4493,52 @@ syndicate.command("add").description("Register an agent on a syndicate vault (cr
4592
4493
  process.exit(1);
4593
4494
  }
4594
4495
  const agentWallet = validateAddress(opts.wallet, "wallet");
4496
+ let agentId;
4497
+ if (opts.agentId) {
4498
+ agentId = BigInt(opts.agentId);
4499
+ } else {
4500
+ const { AGENT_REGISTRY: AGENT_REGISTRY2 } = await import("./addresses-CQLJSZGN.js");
4501
+ const registry = AGENT_REGISTRY2().IDENTITY_REGISTRY;
4502
+ if (registry === "0x0000000000000000000000000000000000000000") {
4503
+ agentId = 0n;
4504
+ } else {
4505
+ spinner.text = "Looking up ERC-8004 identity from wallet...";
4506
+ const client = getPublicClient();
4507
+ const balance = await client.readContract({
4508
+ address: registry,
4509
+ abi: [{
4510
+ name: "balanceOf",
4511
+ type: "function",
4512
+ stateMutability: "view",
4513
+ inputs: [{ name: "owner", type: "address" }],
4514
+ outputs: [{ name: "", type: "uint256" }]
4515
+ }],
4516
+ functionName: "balanceOf",
4517
+ args: [agentWallet]
4518
+ });
4519
+ if (balance === 0n) {
4520
+ spinner.fail("Agent wallet does not own an ERC-8004 identity NFT");
4521
+ console.error(chalk8.dim(" Mint one first: sherwood identity mint --name <name>"));
4522
+ process.exit(1);
4523
+ }
4524
+ const tokenId = await client.readContract({
4525
+ address: registry,
4526
+ abi: [{
4527
+ name: "tokenOfOwnerByIndex",
4528
+ type: "function",
4529
+ stateMutability: "view",
4530
+ inputs: [{ name: "owner", type: "address" }, { name: "index", type: "uint256" }],
4531
+ outputs: [{ name: "", type: "uint256" }]
4532
+ }],
4533
+ functionName: "tokenOfOwnerByIndex",
4534
+ args: [agentWallet, 0n]
4535
+ });
4536
+ agentId = tokenId;
4537
+ console.log(chalk8.dim(` Resolved agent ID: #${agentId}`));
4538
+ }
4539
+ }
4595
4540
  spinner.text = "Registering agent...";
4596
- const hash = await registerAgent(
4597
- BigInt(opts.agentId),
4598
- agentWallet
4599
- );
4541
+ const hash = await registerAgent(agentId, agentWallet);
4600
4542
  spinner.succeed(`Agent registered: ${hash}`);
4601
4543
  console.log(chalk8.dim(` ${getExplorerUrl(hash)}`));
4602
4544
  try {
@@ -4606,7 +4548,7 @@ syndicate.command("add").description("Register an agent on a syndicate vault (cr
4606
4548
  await xmtp.addMember(group, opts.wallet);
4607
4549
  await xmtp.sendEnvelope(group, {
4608
4550
  type: "AGENT_REGISTERED",
4609
- agent: { erc8004Id: Number(opts.agentId), address: opts.wallet },
4551
+ agent: { erc8004Id: Number(agentId), address: opts.wallet },
4610
4552
  syndicate: subdomain,
4611
4553
  timestamp: Math.floor(Date.now() / 1e3)
4612
4554
  });
@@ -5032,7 +4974,7 @@ var vaultCmd = program.command("vault");
5032
4974
  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) => {
5033
4975
  resolveVault(opts);
5034
4976
  const decimals = await getAssetDecimals();
5035
- const amount = parseUnits5(opts.amount, decimals);
4977
+ const amount = parseUnits4(opts.amount, decimals);
5036
4978
  try {
5037
4979
  if (!opts.useEth) {
5038
4980
  await preflightDeposit(amount);
@@ -5107,7 +5049,7 @@ vaultCmd.command("redeem").description("Redeem vault shares for the underlying a
5107
5049
  let shares;
5108
5050
  try {
5109
5051
  if (opts.shares) {
5110
- shares = parseUnits5(opts.shares, shareDecimals);
5052
+ shares = parseUnits4(opts.shares, shareDecimals);
5111
5053
  } else {
5112
5054
  shares = await getShareBalance();
5113
5055
  if (shares === 0n) {
@@ -5135,7 +5077,7 @@ vaultCmd.command("redeem").description("Redeem vault shares for the underlying a
5135
5077
  `));
5136
5078
  process.exit(1);
5137
5079
  }
5138
- const sharesDisplay = formatUnits5(shares, shareDecimals);
5080
+ const sharesDisplay = formatUnits4(shares, shareDecimals);
5139
5081
  const spinner = ora7(`Redeeming ${sharesDisplay} shares...`).start();
5140
5082
  try {
5141
5083
  const { hash, assetsOut } = await redeem(
@@ -5144,7 +5086,7 @@ vaultCmd.command("redeem").description("Redeem vault shares for the underlying a
5144
5086
  );
5145
5087
  spinner.succeed(`Redeemed: ${hash}`);
5146
5088
  console.log(chalk8.dim(` ${getExplorerUrl(hash)}`));
5147
- console.log(` Assets received: ${formatUnits5(assetsOut, assetDecimals)}`);
5089
+ console.log(` Assets received: ${formatUnits4(assetsOut, assetDecimals)}`);
5148
5090
  } catch (err) {
5149
5091
  spinner.fail("Redeem failed");
5150
5092
  console.error(chalk8.red(formatContractError(err)));
@@ -5154,7 +5096,7 @@ vaultCmd.command("redeem").description("Redeem vault shares for the underlying a
5154
5096
  var strategy = program.command("strategy").description("Strategy templates \u2014 list, clone, propose");
5155
5097
  registerStrategyTemplateCommands(strategy);
5156
5098
  program.command("providers").description("List available DeFi providers").action(async () => {
5157
- const { MessariProvider, NansenProvider } = await import("./research-DLZNLY6X.js");
5099
+ const { MessariProvider, NansenProvider } = await import("./research-NCESMYXK.js");
5158
5100
  const providers = [new MoonwellProvider(), new UniswapProvider(), new MessariProvider(), new NansenProvider()];
5159
5101
  for (const p of providers) {
5160
5102
  const info = p.info();
@@ -5165,7 +5107,7 @@ ${info.name} (${info.type})`);
5165
5107
  }
5166
5108
  });
5167
5109
  try {
5168
- const { registerChatCommands } = await import("./chat-C7EEHQHR.js");
5110
+ const { registerChatCommands } = await import("./chat-N6LSZUSC.js");
5169
5111
  registerChatCommands(program);
5170
5112
  } catch {
5171
5113
  program.command("chat <name> [action] [actionArgs...]").description("Syndicate chat (XMTP) \u2014 requires @xmtp/cli").action(() => {
@@ -5175,21 +5117,21 @@ try {
5175
5117
  process.exit(1);
5176
5118
  });
5177
5119
  }
5178
- var { registerSessionCommands } = await import("./session-6NIAZOEH.js");
5120
+ var { registerSessionCommands } = await import("./session-5JUUZYIL.js");
5179
5121
  registerSessionCommands(program);
5180
5122
  registerVeniceCommands(program);
5181
5123
  registerAllowanceCommands(program);
5182
5124
  registerIdentityCommands(program);
5183
5125
  registerProposalCommands(program);
5184
5126
  registerGovernorCommands(program);
5185
- var { registerResearchCommands } = await import("./research-CGDUEDL5.js");
5127
+ var { registerResearchCommands } = await import("./research-H3I4LALI.js");
5186
5128
  registerResearchCommands(program);
5187
- var { registerAgentCommands } = await import("./agent-C4HZUQNI.js");
5129
+ var { registerAgentCommands } = await import("./agent-QIQABFLV.js");
5188
5130
  registerAgentCommands(program);
5189
- var { registerTradeCommands } = await import("./trade-VGJP6LAN.js");
5131
+ var { registerTradeCommands } = await import("./trade-XDE6YCNY.js");
5190
5132
  registerTradeCommands(program);
5191
5133
  var configCmd = program.command("config");
5192
- 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").action((opts) => {
5134
+ 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) => {
5193
5135
  let saved = false;
5194
5136
  if (opts.privateKey) {
5195
5137
  setPrivateKey(opts.privateKey);
@@ -5228,8 +5170,19 @@ configCmd.command("set").description("Save settings to ~/.sherwood/config.json (
5228
5170
  console.log(chalk8.green("Venice API key saved to ~/.sherwood/config.json"));
5229
5171
  saved = true;
5230
5172
  }
5173
+ if (opts.xmtpGroup) {
5174
+ const parts = opts.xmtpGroup.split(":");
5175
+ if (parts.length !== 2 || !parts[0] || !parts[1]) {
5176
+ console.log(chalk8.red("Format: --xmtp-group <subdomain>:<groupId>"));
5177
+ process.exit(1);
5178
+ }
5179
+ cacheGroupId(parts[0], parts[1]);
5180
+ console.log(chalk8.green(`XMTP group ID cached for ${parts[0]}`));
5181
+ console.log(chalk8.dim(` Group ID: ${parts[1]}`));
5182
+ saved = true;
5183
+ }
5231
5184
  if (!saved) {
5232
- console.log(chalk8.red("Provide at least one of: --private-key, --vault, --rpc, --notify-to, --uniswap-api-key, --venice-api-key"));
5185
+ console.log(chalk8.red("Provide at least one of: --private-key, --vault, --rpc, --notify-to, --uniswap-api-key, --venice-api-key, --xmtp-group"));
5233
5186
  process.exit(1);
5234
5187
  }
5235
5188
  });
@@ -5249,6 +5202,14 @@ configCmd.command("show").description("Display current config for the active net
5249
5202
  console.log(` Vault: ${contracts.vault ?? chalk8.dim("not set")}`);
5250
5203
  console.log(` Uniswap: ${getUniswapApiKey() ? chalk8.green("API key configured") : chalk8.dim("not set")}`);
5251
5204
  console.log(` Venice: ${getVeniceApiKey() ? chalk8.green("API key configured") : chalk8.dim("not set")}`);
5205
+ const groupEntries = Object.entries(config.groupCache || {}).filter(([, v]) => v);
5206
+ if (groupEntries.length > 0) {
5207
+ console.log();
5208
+ console.log(chalk8.bold(" XMTP Groups"));
5209
+ for (const [sub, gid] of groupEntries) {
5210
+ console.log(` ${sub}: ${chalk8.cyan(gid)}`);
5211
+ }
5212
+ }
5252
5213
  console.log();
5253
5214
  console.log(chalk8.dim(" Config file: ~/.sherwood/config.json"));
5254
5215
  console.log();