@sherwoodagent/cli 0.5.1 → 0.7.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.
package/dist/index.js CHANGED
@@ -1,8 +1,35 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ uploadMetadata
4
+ } from "./chunk-DVWORPEY.js";
5
+ import {
6
+ createApproval,
7
+ createJoinRequest,
8
+ getEasScanUrl,
9
+ queryApprovals,
10
+ queryJoinRequests,
11
+ revokeAttestation
12
+ } from "./chunk-JY24QVXN.js";
13
+ import {
14
+ approveDepositor,
15
+ deposit,
16
+ executeBatch,
17
+ getAssetDecimals,
18
+ getBalance,
19
+ getVaultAddress,
20
+ getVaultInfo,
21
+ isAgent,
22
+ ragequit,
23
+ registerAgent,
24
+ removeDepositor,
25
+ resolveSyndicate,
26
+ resolveVaultSyndicate,
27
+ setTextRecord,
28
+ setVaultAddress,
29
+ simulateBatch
30
+ } from "./chunk-P4OHGJ3Z.js";
2
31
  import {
3
32
  AGENT_REGISTRY,
4
- EAS_ABI,
5
- EAS_CONTRACTS,
6
33
  EAS_SCHEMAS,
7
34
  ERC20_ABI,
8
35
  MOONWELL,
@@ -14,41 +41,26 @@ import {
14
41
  UNISWAP,
15
42
  UNISWAP_QUOTER_V2_ABI,
16
43
  VENICE,
17
- VENICE_STAKING_ABI,
18
- approveDepositor,
44
+ VENICE_STAKING_ABI
45
+ } from "./chunk-FGSXRXCZ.js";
46
+ import {
19
47
  cacheGroupId,
20
- deposit,
21
- executeBatch,
22
48
  getAccount,
23
49
  getAgentId,
24
- getAssetDecimals,
25
- getBalance,
26
50
  getChain,
27
51
  getChainContracts,
28
52
  getExplorerUrl,
29
- getNetwork,
30
53
  getPublicClient,
31
54
  getRpcUrl,
32
- getVaultAddress,
33
- getVaultInfo,
34
55
  getVeniceApiKey,
35
56
  getWalletClient,
36
- isAgent,
37
57
  loadConfig,
38
- ragequit,
39
- registerAgent,
40
- removeDepositor,
41
- resolveSyndicate,
42
- resolveVaultSyndicate,
43
58
  setAgentId,
44
59
  setChainContract,
45
60
  setNetwork,
46
61
  setPrivateKey,
47
- setTextRecord,
48
- setVaultAddress,
49
- setVeniceApiKey,
50
- simulateBatch
51
- } from "./chunk-3WZLP6BH.js";
62
+ setVeniceApiKey
63
+ } from "./chunk-QMWMT6EH.js";
52
64
 
53
65
  // src/index.ts
54
66
  import { config as loadDotenv } from "dotenv";
@@ -56,7 +68,7 @@ import { Command } from "commander";
56
68
  import { parseUnits as parseUnits8 } from "viem";
57
69
  import chalk5 from "chalk";
58
70
  import ora5 from "ora";
59
- import { input, confirm } from "@inquirer/prompts";
71
+ import { input, confirm, select } from "@inquirer/prompts";
60
72
 
61
73
  // src/providers/moonwell.ts
62
74
  import { base, baseSepolia } from "viem/chains";
@@ -695,34 +707,6 @@ async function listStrategies(typeId) {
695
707
  return strategies;
696
708
  }
697
709
 
698
- // src/lib/ipfs.ts
699
- var BUNDLED_PINATA_JWT = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mb3JtYXRpb24iOnsiaWQiOiI2NDQ0MGViOC1hYTYyLTQzY2EtOGYwNC04MDZjZmNjY2Y4YTUiLCJlbWFpbCI6ImltdGhhdGNhcmxvc0BnbWFpbC5jb20iLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwicGluX3BvbGljeSI6eyJyZWdpb25zIjpbeyJkZXNpcmVkUmVwbGljYXRpb25Db3VudCI6MSwiaWQiOiJGUkExIn1dLCJ2ZXJzaW9uIjoxfSwibWZhX2VuYWJsZWQiOmZhbHNlLCJzdGF0dXMiOiJBQ1RJVkUifSwiYXV0aGVudGljYXRpb25UeXBlIjoic2NvcGVkS2V5Iiwic2NvcGVkS2V5S2V5IjoiMWJhZWFmMzQwODM3MGQ0NGZkZWEiLCJzY29wZWRLZXlTZWNyZXQiOiIzNDcxMmU5MTkyYTgxNWFhMGRmNjUyYjYyMDQzODQ1MDJjMmU0YWE0MDhkZTJmOTU2NWYwOTk3YTNlY2U3NGU3IiwiZXhwIjoxODAxMjc2ODExfQ.7OMJiOATpqkSwe7Orrpt2b8H_-czH-W61vBm4AHtqfA";
700
- function getPinataApiKey() {
701
- return process.env.PINATA_API_KEY || BUNDLED_PINATA_JWT;
702
- }
703
- async function uploadMetadata(metadata) {
704
- const apiKey = getPinataApiKey();
705
- const response = await fetch("https://api.pinata.cloud/pinning/pinJSONToIPFS", {
706
- method: "POST",
707
- headers: {
708
- "Content-Type": "application/json",
709
- Authorization: `Bearer ${apiKey}`
710
- },
711
- body: JSON.stringify({
712
- pinataContent: metadata,
713
- pinataMetadata: {
714
- name: `sherwood-syndicate-${metadata.name.toLowerCase().replace(/\s+/g, "-")}`
715
- }
716
- })
717
- });
718
- if (!response.ok) {
719
- const text = await response.text();
720
- throw new Error(`Pinata upload failed (${response.status}): ${text}`);
721
- }
722
- const result = await response.json();
723
- return `ipfs://${result.IpfsHash}`;
724
- }
725
-
726
710
  // src/commands/venice.ts
727
711
  import { parseUnits as parseUnits5, formatUnits as formatUnits3, isAddress as isAddress2 } from "viem";
728
712
  import chalk2 from "chalk";
@@ -1690,226 +1674,13 @@ function registerIdentityCommands(program2) {
1690
1674
  });
1691
1675
  }
1692
1676
 
1693
- // src/lib/eas.ts
1694
- import { encodeAbiParameters, parseAbiParameters, decodeAbiParameters } from "viem";
1695
- var ZERO_BYTES32 = "0x0000000000000000000000000000000000000000000000000000000000000000";
1696
- var JOIN_REQUEST_PARAMS = parseAbiParameters("uint256, uint256, address, string");
1697
- var AGENT_APPROVED_PARAMS = parseAbiParameters("uint256, uint256, address");
1698
- function assertSchemasRegistered() {
1699
- const schemas = EAS_SCHEMAS();
1700
- if (schemas.SYNDICATE_JOIN_REQUEST === ZERO_BYTES32 || schemas.AGENT_APPROVED === ZERO_BYTES32) {
1701
- throw new Error(
1702
- "EAS schemas not registered. Run: npx tsx scripts/register-eas-schemas.ts --testnet"
1703
- );
1704
- }
1705
- }
1706
- function getEasGraphqlUrl() {
1707
- return getNetwork() === "base" ? "https://base.easscan.org/graphql" : "https://base-sepolia.easscan.org/graphql";
1708
- }
1709
- function getEasScanUrl(uid) {
1710
- const host = getNetwork() === "base" ? "base.easscan.org" : "base-sepolia.easscan.org";
1711
- return `https://${host}/attestation/view/${uid}`;
1712
- }
1713
- function extractAttestationUid(receipt) {
1714
- for (const log of receipt.logs) {
1715
- if (log.topics.length === 4 && log.data.length >= 66) {
1716
- return "0x" + log.data.slice(2, 66);
1717
- }
1718
- }
1719
- throw new Error("Could not extract attestation UID from transaction receipt");
1720
- }
1721
- async function createJoinRequest(syndicateId, agentId, vault, creatorAddress, message) {
1722
- assertSchemasRegistered();
1723
- const wallet = getWalletClient();
1724
- const client = getPublicClient();
1725
- const data = encodeAbiParameters(JOIN_REQUEST_PARAMS, [
1726
- syndicateId,
1727
- agentId,
1728
- vault,
1729
- message
1730
- ]);
1731
- const hash = await wallet.writeContract({
1732
- account: getAccount(),
1733
- chain: getChain(),
1734
- address: EAS_CONTRACTS().EAS,
1735
- abi: EAS_ABI,
1736
- functionName: "attest",
1737
- args: [{
1738
- schema: EAS_SCHEMAS().SYNDICATE_JOIN_REQUEST,
1739
- data: {
1740
- recipient: creatorAddress,
1741
- expirationTime: 0n,
1742
- revocable: true,
1743
- refUID: ZERO_BYTES32,
1744
- data,
1745
- value: 0n
1746
- }
1747
- }],
1748
- value: 0n
1749
- });
1750
- const receipt = await client.waitForTransactionReceipt({ hash });
1751
- const uid = extractAttestationUid(receipt);
1752
- return { uid, hash };
1753
- }
1754
- async function createApproval(syndicateId, agentId, vault, agentAddress) {
1755
- assertSchemasRegistered();
1756
- const wallet = getWalletClient();
1757
- const client = getPublicClient();
1758
- const data = encodeAbiParameters(AGENT_APPROVED_PARAMS, [
1759
- syndicateId,
1760
- agentId,
1761
- vault
1762
- ]);
1763
- const hash = await wallet.writeContract({
1764
- account: getAccount(),
1765
- chain: getChain(),
1766
- address: EAS_CONTRACTS().EAS,
1767
- abi: EAS_ABI,
1768
- functionName: "attest",
1769
- args: [{
1770
- schema: EAS_SCHEMAS().AGENT_APPROVED,
1771
- data: {
1772
- recipient: agentAddress,
1773
- expirationTime: 0n,
1774
- revocable: true,
1775
- refUID: ZERO_BYTES32,
1776
- data,
1777
- value: 0n
1778
- }
1779
- }],
1780
- value: 0n
1781
- });
1782
- const receipt = await client.waitForTransactionReceipt({ hash });
1783
- const uid = extractAttestationUid(receipt);
1784
- return { uid, hash };
1785
- }
1786
- async function revokeAttestation(schemaUid, attestationUid) {
1787
- const wallet = getWalletClient();
1788
- return wallet.writeContract({
1789
- account: getAccount(),
1790
- chain: getChain(),
1791
- address: EAS_CONTRACTS().EAS,
1792
- abi: EAS_ABI,
1793
- functionName: "revoke",
1794
- args: [{
1795
- schema: schemaUid,
1796
- data: {
1797
- uid: attestationUid,
1798
- value: 0n
1799
- }
1800
- }],
1801
- value: 0n
1802
- });
1803
- }
1804
- async function queryApprovals(attester) {
1805
- assertSchemasRegistered();
1806
- const schemaUid = EAS_SCHEMAS().AGENT_APPROVED;
1807
- const url = getEasGraphqlUrl();
1808
- const query2 = `
1809
- query Approvals($schemaId: String!, $attester: String!) {
1810
- attestations(
1811
- where: {
1812
- schemaId: { equals: $schemaId }
1813
- attester: { equals: $attester }
1814
- revoked: { equals: false }
1815
- }
1816
- orderBy: [{ time: desc }]
1817
- ) {
1818
- id
1819
- attester
1820
- recipient
1821
- time
1822
- data
1823
- }
1824
- }
1825
- `;
1826
- const response = await fetch(url, {
1827
- method: "POST",
1828
- headers: { "Content-Type": "application/json" },
1829
- body: JSON.stringify({
1830
- query: query2,
1831
- variables: { schemaId: schemaUid, attester }
1832
- })
1833
- });
1834
- if (!response.ok) {
1835
- throw new Error(`EAS GraphQL query failed: ${response.statusText}`);
1836
- }
1837
- const json = await response.json();
1838
- if (!json.data?.attestations) return [];
1839
- return json.data.attestations.map((a) => {
1840
- const decoded = decodeAbiParameters(AGENT_APPROVED_PARAMS, a.data);
1841
- return {
1842
- uid: a.id,
1843
- attester: a.attester,
1844
- recipient: a.recipient,
1845
- time: a.time,
1846
- decoded: {
1847
- syndicateId: decoded[0],
1848
- agentId: decoded[1],
1849
- vault: decoded[2]
1850
- }
1851
- };
1852
- });
1853
- }
1854
- async function queryJoinRequests(recipient) {
1855
- assertSchemasRegistered();
1856
- const schemaUid = EAS_SCHEMAS().SYNDICATE_JOIN_REQUEST;
1857
- const url = getEasGraphqlUrl();
1858
- const query2 = `
1859
- query JoinRequests($schemaId: String!, $recipient: String!) {
1860
- attestations(
1861
- where: {
1862
- schemaId: { equals: $schemaId }
1863
- recipient: { equals: $recipient }
1864
- revoked: { equals: false }
1865
- }
1866
- orderBy: [{ time: desc }]
1867
- ) {
1868
- id
1869
- attester
1870
- recipient
1871
- time
1872
- data
1873
- }
1874
- }
1875
- `;
1876
- const response = await fetch(url, {
1877
- method: "POST",
1878
- headers: { "Content-Type": "application/json" },
1879
- body: JSON.stringify({
1880
- query: query2,
1881
- variables: { schemaId: schemaUid, recipient }
1882
- })
1883
- });
1884
- if (!response.ok) {
1885
- throw new Error(`EAS GraphQL query failed: ${response.statusText}`);
1886
- }
1887
- const json = await response.json();
1888
- if (!json.data?.attestations) return [];
1889
- return json.data.attestations.map((a) => {
1890
- const decoded = decodeAbiParameters(JOIN_REQUEST_PARAMS, a.data);
1891
- return {
1892
- uid: a.id,
1893
- attester: a.attester,
1894
- recipient: a.recipient,
1895
- time: a.time,
1896
- decoded: {
1897
- syndicateId: decoded[0],
1898
- agentId: decoded[1],
1899
- vault: decoded[2],
1900
- message: decoded[3]
1901
- }
1902
- };
1903
- });
1904
- }
1905
-
1906
1677
  // src/index.ts
1907
1678
  try {
1908
1679
  loadDotenv();
1909
1680
  } catch {
1910
1681
  }
1911
1682
  async function loadXmtp() {
1912
- return import("./xmtp-PICTODCB.js");
1683
+ return import("./xmtp-PQ4VJWTW.js");
1913
1684
  }
1914
1685
  var G = chalk5.green;
1915
1686
  var W = chalk5.white;
@@ -1931,7 +1702,7 @@ program.name("sherwood").description("CLI for agent-managed investment syndicate
1931
1702
  }
1932
1703
  });
1933
1704
  var syndicate = program.command("syndicate");
1934
- syndicate.command("create").description("Create a new syndicate via the factory (interactive)").option("--subdomain <name>", "ENS subdomain (skip prompt)").option("--name <name>", "Syndicate name (skip prompt)").option("--agent-id <id>", "ERC-8004 agent identity token ID (skip prompt)").option("--asset <address>", "Underlying asset address").option("--description <text>", "Short description").option("--metadata-uri <uri>", "Override metadata URI (skip IPFS upload)").option("--open-deposits", "Allow anyone to deposit (no whitelist)").option("--public-chat", "Enable dashboard spectator mode", false).action(async (opts) => {
1705
+ syndicate.command("create").description("Create a new syndicate via the factory (interactive)").option("--subdomain <name>", "ENS subdomain (skip prompt)").option("--name <name>", "Syndicate name (skip prompt)").option("--agent-id <id>", "ERC-8004 agent identity token ID (skip prompt)").option("--asset <symbol-or-address>", "Vault asset: USDC, WETH, or a token address").option("--description <text>", "Short description").option("--metadata-uri <uri>", "Override metadata URI (skip IPFS upload)").option("--open-deposits", "Allow anyone to deposit (no whitelist)").option("--public-chat", "Enable dashboard spectator mode", false).action(async (opts) => {
1935
1706
  try {
1936
1707
  console.log();
1937
1708
  console.log(LABEL(" \u25C6 Create Syndicate"));
@@ -1959,7 +1730,32 @@ syndicate.command("create").description("Create a new syndicate via the factory
1959
1730
  message: G("Open deposits? (anyone can deposit)"),
1960
1731
  default: true
1961
1732
  });
1962
- const asset = opts.asset || TOKENS().USDC;
1733
+ const ASSET_SYMBOLS = {
1734
+ USDC: TOKENS().USDC,
1735
+ WETH: TOKENS().WETH
1736
+ };
1737
+ let asset;
1738
+ if (opts.asset) {
1739
+ const upper = opts.asset.toUpperCase();
1740
+ if (ASSET_SYMBOLS[upper]) {
1741
+ asset = ASSET_SYMBOLS[upper];
1742
+ } else if (opts.asset.startsWith("0x") && opts.asset.length === 42) {
1743
+ asset = opts.asset;
1744
+ } else {
1745
+ const supported = Object.keys(ASSET_SYMBOLS).join(", ");
1746
+ console.error(chalk5.red(` Unknown asset "${opts.asset}". Use a symbol (${supported}) or a 0x address.`));
1747
+ process.exit(1);
1748
+ }
1749
+ } else {
1750
+ const assetChoice = await select({
1751
+ message: G("Vault asset (what token do depositors provide?)"),
1752
+ choices: [
1753
+ { name: "USDC", value: "USDC", description: "USD Coin (6 decimals)" },
1754
+ { name: "WETH", value: "WETH", description: "Wrapped Ether (18 decimals)" }
1755
+ ]
1756
+ });
1757
+ asset = ASSET_SYMBOLS[assetChoice];
1758
+ }
1963
1759
  const publicClient = getPublicClient();
1964
1760
  const [decimals, assetSymbol] = await Promise.all([
1965
1761
  publicClient.readContract({ address: asset, abi: ERC20_ABI, functionName: "decimals" }),
@@ -2633,8 +2429,9 @@ strategy.command("run").description("Execute the levered swap strategy").option(
2633
2429
  resolveVault(opts);
2634
2430
  await runLeveredSwap(opts);
2635
2431
  });
2636
- program.command("providers").description("List available DeFi providers").action(() => {
2637
- const providers = [new MoonwellProvider(), new UniswapProvider()];
2432
+ program.command("providers").description("List available DeFi providers").action(async () => {
2433
+ const { MessariProvider, NansenProvider } = await import("./research-K6MRGQFD.js");
2434
+ const providers = [new MoonwellProvider(), new UniswapProvider(), new MessariProvider(), new NansenProvider()];
2638
2435
  for (const p of providers) {
2639
2436
  const info = p.info();
2640
2437
  console.log(`
@@ -2644,7 +2441,7 @@ ${info.name} (${info.type})`);
2644
2441
  }
2645
2442
  });
2646
2443
  try {
2647
- const { registerChatCommands } = await import("./chat-HHXJOCKN.js");
2444
+ const { registerChatCommands } = await import("./chat-E5AXULN3.js");
2648
2445
  registerChatCommands(program);
2649
2446
  } catch {
2650
2447
  program.command("chat <name> [action] [actionArgs...]").description("Syndicate chat (XMTP) \u2014 requires @xmtp/cli").action(() => {
@@ -2654,9 +2451,13 @@ try {
2654
2451
  process.exit(1);
2655
2452
  });
2656
2453
  }
2454
+ var { registerSessionCommands } = await import("./session-BBNSJYAQ.js");
2455
+ registerSessionCommands(program);
2657
2456
  registerVeniceCommands(program);
2658
2457
  registerAllowanceCommands(program);
2659
2458
  registerIdentityCommands(program);
2459
+ var { registerResearchCommands } = await import("./research-4RV3AQGW.js");
2460
+ registerResearchCommands(program);
2660
2461
  var configCmd = program.command("config");
2661
2462
  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").action((opts) => {
2662
2463
  let saved = false;