@sherwoodagent/cli 0.18.3 → 0.19.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 (48) hide show
  1. package/dist/{chat-7CB4YGGP.js → chat-MUUC5L5W.js} +7 -7
  2. package/dist/{chunk-TWX6FSCM.js → chunk-B4BMCXWK.js} +11 -1
  3. package/dist/chunk-B4BMCXWK.js.map +1 -0
  4. package/dist/chunk-DCT3IDBS.js +458 -0
  5. package/dist/chunk-DCT3IDBS.js.map +1 -0
  6. package/dist/{chunk-MJMWA4LY.js → chunk-FEDSWXSD.js} +2 -2
  7. package/dist/{chunk-FR4LYDPJ.js → chunk-G2RQLZZI.js} +115 -4
  8. package/dist/chunk-G2RQLZZI.js.map +1 -0
  9. package/dist/{chunk-L24NGLKY.js → chunk-HRA2KPGW.js} +8 -3
  10. package/dist/{chunk-L24NGLKY.js.map → chunk-HRA2KPGW.js.map} +1 -1
  11. package/dist/{chunk-ARD44YTT.js → chunk-VZZ2V6EM.js} +5 -5
  12. package/dist/{chunk-TPE6ZTUI.js → chunk-W76CHVD3.js} +59 -5
  13. package/dist/chunk-W76CHVD3.js.map +1 -0
  14. package/dist/{chunk-5ZC2A7UP.js → chunk-WHCXQBPS.js} +4 -4
  15. package/dist/{chunk-Z2PNK3CC.js → chunk-ZXV4TBPE.js} +2 -2
  16. package/dist/client-I56MIQAM.js +21 -0
  17. package/dist/{config-LW4Q6NK5.js → config-2VMLHIXD.js} +6 -2
  18. package/dist/eas-YZF6MN65.js +29 -0
  19. package/dist/{governor-E6AU3UWV.js → governor-ZWKGLGMG.js} +6 -6
  20. package/dist/index.js +70 -293
  21. package/dist/index.js.map +1 -1
  22. package/dist/{network-C32G5D3J.js → network-3MVRM7O4.js} +3 -3
  23. package/dist/research-HC2UOLFT.js +14 -0
  24. package/dist/research-HC2UOLFT.js.map +1 -0
  25. package/dist/{research-MKI4RS2F.js → research-VZKLOTMU.js} +7 -7
  26. package/dist/{session-RAFLL5BD.js → session-X3QFFCJ7.js} +10 -10
  27. package/dist/trade-YCBFXOB3.js +874 -0
  28. package/dist/trade-YCBFXOB3.js.map +1 -0
  29. package/dist/{xmtp-ATRMY76G.js → xmtp-IH57GYSR.js} +6 -6
  30. package/package.json +1 -1
  31. package/dist/chunk-FR4LYDPJ.js.map +0 -1
  32. package/dist/chunk-TPE6ZTUI.js.map +0 -1
  33. package/dist/chunk-TWX6FSCM.js.map +0 -1
  34. package/dist/eas-DOC4QKDF.js +0 -23
  35. package/dist/research-V63URK4C.js +0 -14
  36. /package/dist/{chat-7CB4YGGP.js.map → chat-MUUC5L5W.js.map} +0 -0
  37. /package/dist/{chunk-MJMWA4LY.js.map → chunk-FEDSWXSD.js.map} +0 -0
  38. /package/dist/{chunk-ARD44YTT.js.map → chunk-VZZ2V6EM.js.map} +0 -0
  39. /package/dist/{chunk-5ZC2A7UP.js.map → chunk-WHCXQBPS.js.map} +0 -0
  40. /package/dist/{chunk-Z2PNK3CC.js.map → chunk-ZXV4TBPE.js.map} +0 -0
  41. /package/dist/{config-LW4Q6NK5.js.map → client-I56MIQAM.js.map} +0 -0
  42. /package/dist/{eas-DOC4QKDF.js.map → config-2VMLHIXD.js.map} +0 -0
  43. /package/dist/{governor-E6AU3UWV.js.map → eas-YZF6MN65.js.map} +0 -0
  44. /package/dist/{network-C32G5D3J.js.map → governor-ZWKGLGMG.js.map} +0 -0
  45. /package/dist/{research-V63URK4C.js.map → network-3MVRM7O4.js.map} +0 -0
  46. /package/dist/{research-MKI4RS2F.js.map → research-VZKLOTMU.js.map} +0 -0
  47. /package/dist/{session-RAFLL5BD.js.map → session-X3QFFCJ7.js.map} +0 -0
  48. /package/dist/{xmtp-ATRMY76G.js.map → xmtp-IH57GYSR.js.map} +0 -0
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  SHERWOOD,
3
3
  SYNDICATE_GOVERNOR_ABI
4
- } from "./chunk-TPE6ZTUI.js";
4
+ } from "./chunk-W76CHVD3.js";
5
5
  import {
6
6
  getAccount,
7
7
  getPublicClient,
8
8
  getWalletClient
9
- } from "./chunk-L24NGLKY.js";
9
+ } from "./chunk-HRA2KPGW.js";
10
10
  import {
11
11
  getChain
12
- } from "./chunk-MJMWA4LY.js";
12
+ } from "./chunk-FEDSWXSD.js";
13
13
 
14
14
  // src/lib/governor.ts
15
15
  import { parseEventLogs } from "viem";
@@ -455,4 +455,4 @@ export {
455
455
  vetoProposal,
456
456
  setProtocolFeeBps
457
457
  };
458
- //# sourceMappingURL=chunk-5ZC2A7UP.js.map
458
+ //# sourceMappingURL=chunk-WHCXQBPS.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getAccount
3
- } from "./chunk-L24NGLKY.js";
3
+ } from "./chunk-HRA2KPGW.js";
4
4
 
5
5
  // src/providers/research/messari.ts
6
6
  import { base, baseSepolia } from "viem/chains";
@@ -436,4 +436,4 @@ export {
436
436
  NansenProvider,
437
437
  getResearchProvider
438
438
  };
439
- //# sourceMappingURL=chunk-Z2PNK3CC.js.map
439
+ //# sourceMappingURL=chunk-ZXV4TBPE.js.map
@@ -0,0 +1,21 @@
1
+ import {
2
+ estimateFeesWithBuffer,
3
+ getAccount,
4
+ getPublicClient,
5
+ getWalletClient,
6
+ resetClients,
7
+ sendTxWithRetry,
8
+ writeContractWithRetry
9
+ } from "./chunk-HRA2KPGW.js";
10
+ import "./chunk-FEDSWXSD.js";
11
+ import "./chunk-B4BMCXWK.js";
12
+ export {
13
+ estimateFeesWithBuffer,
14
+ getAccount,
15
+ getPublicClient,
16
+ getWalletClient,
17
+ resetClients,
18
+ sendTxWithRetry,
19
+ writeContractWithRetry
20
+ };
21
+ //# sourceMappingURL=client-I56MIQAM.js.map
@@ -6,6 +6,7 @@ import {
6
6
  getConfigRpcUrl,
7
7
  getNotifyTo,
8
8
  getPrivateKey,
9
+ getUniswapApiKey,
9
10
  getVeniceApiKey,
10
11
  loadConfig,
11
12
  saveConfig,
@@ -14,8 +15,9 @@ import {
14
15
  setConfigRpcUrl,
15
16
  setNotifyTo,
16
17
  setPrivateKey,
18
+ setUniswapApiKey,
17
19
  setVeniceApiKey
18
- } from "./chunk-TWX6FSCM.js";
20
+ } from "./chunk-B4BMCXWK.js";
19
21
  export {
20
22
  cacheGroupId,
21
23
  getAgentId,
@@ -24,6 +26,7 @@ export {
24
26
  getConfigRpcUrl,
25
27
  getNotifyTo,
26
28
  getPrivateKey,
29
+ getUniswapApiKey,
27
30
  getVeniceApiKey,
28
31
  loadConfig,
29
32
  saveConfig,
@@ -32,6 +35,7 @@ export {
32
35
  setConfigRpcUrl,
33
36
  setNotifyTo,
34
37
  setPrivateKey,
38
+ setUniswapApiKey,
35
39
  setVeniceApiKey
36
40
  };
37
- //# sourceMappingURL=config-LW4Q6NK5.js.map
41
+ //# sourceMappingURL=config-2VMLHIXD.js.map
@@ -0,0 +1,29 @@
1
+ import {
2
+ createApproval,
3
+ createJoinRequest,
4
+ createResearchAttestation,
5
+ createTradeAttestation,
6
+ createVeniceInferenceAttestation,
7
+ createVeniceProvisionAttestation,
8
+ getEasScanUrl,
9
+ queryApprovals,
10
+ queryJoinRequests,
11
+ revokeAttestation
12
+ } from "./chunk-G2RQLZZI.js";
13
+ import "./chunk-W76CHVD3.js";
14
+ import "./chunk-HRA2KPGW.js";
15
+ import "./chunk-FEDSWXSD.js";
16
+ import "./chunk-B4BMCXWK.js";
17
+ export {
18
+ createApproval,
19
+ createJoinRequest,
20
+ createResearchAttestation,
21
+ createTradeAttestation,
22
+ createVeniceInferenceAttestation,
23
+ createVeniceProvisionAttestation,
24
+ getEasScanUrl,
25
+ queryApprovals,
26
+ queryJoinRequests,
27
+ revokeAttestation
28
+ };
29
+ //# sourceMappingURL=eas-YZF6MN65.js.map
@@ -34,11 +34,11 @@ import {
34
34
  settleProposal,
35
35
  vetoProposal,
36
36
  vote
37
- } from "./chunk-5ZC2A7UP.js";
38
- import "./chunk-TPE6ZTUI.js";
39
- import "./chunk-L24NGLKY.js";
40
- import "./chunk-MJMWA4LY.js";
41
- import "./chunk-TWX6FSCM.js";
37
+ } from "./chunk-WHCXQBPS.js";
38
+ import "./chunk-W76CHVD3.js";
39
+ import "./chunk-HRA2KPGW.js";
40
+ import "./chunk-FEDSWXSD.js";
41
+ import "./chunk-B4BMCXWK.js";
42
42
  export {
43
43
  PROPOSAL_STATE,
44
44
  PROPOSAL_STATES,
@@ -76,4 +76,4 @@ export {
76
76
  vetoProposal,
77
77
  vote
78
78
  };
79
- //# sourceMappingURL=governor-E6AU3UWV.js.map
79
+ //# sourceMappingURL=governor-ZWKGLGMG.js.map
package/dist/index.js CHANGED
@@ -1,4 +1,15 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ UniswapProvider,
4
+ applySlippage,
5
+ chatCompletion,
6
+ checkApiKeyValid,
7
+ encodeSwapPath,
8
+ getMultiHopQuote,
9
+ getQuote,
10
+ listModels,
11
+ provisionApiKey
12
+ } from "./chunk-DCT3IDBS.js";
2
13
  import {
3
14
  PROPOSAL_STATE,
4
15
  PROPOSAL_STATES,
@@ -29,7 +40,7 @@ import {
29
40
  setVotingPeriod,
30
41
  settleProposal,
31
42
  vote
32
- } from "./chunk-5ZC2A7UP.js";
43
+ } from "./chunk-WHCXQBPS.js";
33
44
  import {
34
45
  fetchMetadata,
35
46
  uploadMetadata
@@ -41,7 +52,7 @@ import {
41
52
  queryApprovals,
42
53
  queryJoinRequests,
43
54
  revokeAttestation
44
- } from "./chunk-FR4LYDPJ.js";
55
+ } from "./chunk-G2RQLZZI.js";
45
56
  import {
46
57
  approveDepositor,
47
58
  deposit,
@@ -57,7 +68,7 @@ import {
57
68
  resolveVaultSyndicate,
58
69
  setTextRecord,
59
70
  setVaultAddress
60
- } from "./chunk-ARD44YTT.js";
71
+ } from "./chunk-VZZ2V6EM.js";
61
72
  import {
62
73
  AERODROME,
63
74
  AGENT_REGISTRY,
@@ -67,21 +78,22 @@ import {
67
78
  MOONWELL,
68
79
  SHERWOOD,
69
80
  STRATEGY_TEMPLATES,
81
+ SWAP_ROUTER_ABI,
82
+ SWAP_ROUTER_EXACT_INPUT_SINGLE_ABI,
70
83
  SYNDICATE_FACTORY_ABI,
71
84
  SYNDICATE_VAULT_ABI,
72
85
  TOKENS,
73
86
  UNISWAP,
74
- UNISWAP_QUOTER_V2_ABI,
75
87
  VENICE,
76
88
  VENICE_STAKING_ABI
77
- } from "./chunk-TPE6ZTUI.js";
89
+ } from "./chunk-W76CHVD3.js";
78
90
  import {
79
91
  getAccount,
80
92
  getPublicClient,
81
93
  getWalletClient,
82
94
  sendTxWithRetry,
83
95
  writeContractWithRetry
84
- } from "./chunk-L24NGLKY.js";
96
+ } from "./chunk-HRA2KPGW.js";
85
97
  import {
86
98
  VALID_NETWORKS,
87
99
  getChain,
@@ -90,12 +102,13 @@ import {
90
102
  getRpcUrl,
91
103
  isTestnet,
92
104
  setNetwork
93
- } from "./chunk-MJMWA4LY.js";
105
+ } from "./chunk-FEDSWXSD.js";
94
106
  import {
95
107
  cacheGroupId,
96
108
  getAgentId,
97
109
  getChainContracts,
98
110
  getNotifyTo,
111
+ getUniswapApiKey,
99
112
  getVeniceApiKey,
100
113
  loadConfig,
101
114
  setAgentId,
@@ -103,8 +116,8 @@ import {
103
116
  setConfigRpcUrl,
104
117
  setNotifyTo,
105
118
  setPrivateKey,
106
- setVeniceApiKey
107
- } from "./chunk-TWX6FSCM.js";
119
+ setUniswapApiKey
120
+ } from "./chunk-B4BMCXWK.js";
108
121
 
109
122
  // src/index.ts
110
123
  import { config as loadDotenv } from "dotenv";
@@ -149,28 +162,6 @@ var MoonwellProvider = class {
149
162
  }
150
163
  };
151
164
 
152
- // src/providers/uniswap.ts
153
- import { base as base2, baseSepolia as baseSepolia2 } from "viem/chains";
154
- var UniswapProvider = class {
155
- info() {
156
- return {
157
- name: "uniswap",
158
- type: "trading",
159
- capabilities: [
160
- "swap.exact-input",
161
- "swap.quote"
162
- ],
163
- supportedChains: [base2, baseSepolia2]
164
- };
165
- }
166
- async swap(params) {
167
- throw new Error("Not implemented \u2014 wire up viem client");
168
- }
169
- async quote(params) {
170
- throw new Error("Not implemented");
171
- }
172
- };
173
-
174
165
  // src/commands/strategy-template.ts
175
166
  import { parseUnits, isAddress, erc20Abi } from "viem";
176
167
  import chalk from "chalk";
@@ -882,9 +873,9 @@ function registerStrategyTemplateCommands(strategy2) {
882
873
  console.error(chalk.red("Missing --name, --performance-fee, or --duration. Use --write-calls to skip proposal submission."));
883
874
  process.exit(1);
884
875
  }
885
- const { propose: propose2 } = await import("./governor-E6AU3UWV.js");
876
+ const { propose: propose2 } = await import("./governor-ZWKGLGMG.js");
886
877
  const { pinJSON } = await import("./ipfs-22YLNQ2C.js");
887
- const { parseDuration: parseDuration2 } = await import("./governor-E6AU3UWV.js");
878
+ const { parseDuration: parseDuration2 } = await import("./governor-ZWKGLGMG.js");
888
879
  const performanceFeeBps = BigInt(opts.performanceFee);
889
880
  if (performanceFeeBps < 0n || performanceFeeBps > 10000n) {
890
881
  console.error(chalk.red("--performance-fee must be 0-10000 (basis points)"));
@@ -1124,121 +1115,6 @@ async function getActiveSyndicates2(creator) {
1124
1115
  import { formatUnits as formatUnits2, isAddress as isAddress2 } from "viem";
1125
1116
  import chalk2 from "chalk";
1126
1117
  import ora2 from "ora";
1127
-
1128
- // src/lib/venice.ts
1129
- var VENICE_API_BASE = "https://api.venice.ai/api/v1";
1130
- async function provisionApiKey() {
1131
- const account = getAccount();
1132
- const tokenRes = await fetch(`${VENICE_API_BASE}/api_keys/generate_web3_key`, {
1133
- signal: AbortSignal.timeout(15e3)
1134
- });
1135
- if (!tokenRes.ok) {
1136
- throw new Error(`Failed to get validation token: ${tokenRes.status} ${tokenRes.statusText}`);
1137
- }
1138
- const tokenData = await tokenRes.json();
1139
- const token = tokenData?.data?.token;
1140
- if (!token) {
1141
- throw new Error("Venice API returned no validation token");
1142
- }
1143
- const signature = await account.signMessage({ message: token });
1144
- const keyRes = await fetch(`${VENICE_API_BASE}/api_keys/generate_web3_key`, {
1145
- method: "POST",
1146
- headers: { "Content-Type": "application/json" },
1147
- signal: AbortSignal.timeout(15e3),
1148
- body: JSON.stringify({
1149
- address: account.address,
1150
- signature,
1151
- token,
1152
- apiKeyType: "INFERENCE",
1153
- description: "Sherwood syndicate agent"
1154
- })
1155
- });
1156
- if (!keyRes.ok) {
1157
- const body = await keyRes.text();
1158
- throw new Error(`Failed to generate API key: ${keyRes.status} ${body}`);
1159
- }
1160
- const keyData = await keyRes.json();
1161
- const apiKey = keyData?.data?.apiKey;
1162
- if (!apiKey) {
1163
- throw new Error("Venice API returned no API key");
1164
- }
1165
- setVeniceApiKey(apiKey);
1166
- return apiKey;
1167
- }
1168
- async function checkApiKeyValid() {
1169
- const apiKey = getVeniceApiKey();
1170
- if (!apiKey) return false;
1171
- try {
1172
- const res = await fetch(`${VENICE_API_BASE}/models`, {
1173
- headers: { Authorization: `Bearer ${apiKey}` },
1174
- signal: AbortSignal.timeout(15e3)
1175
- });
1176
- return res.ok;
1177
- } catch {
1178
- return false;
1179
- }
1180
- }
1181
- async function chatCompletion(opts) {
1182
- const apiKey = getVeniceApiKey();
1183
- if (!apiKey) {
1184
- throw new Error("No Venice API key configured. Run 'sherwood venice provision' first.");
1185
- }
1186
- const body = {
1187
- model: opts.model,
1188
- messages: opts.messages
1189
- };
1190
- if (opts.temperature !== void 0) body.temperature = opts.temperature;
1191
- if (opts.maxTokens !== void 0) body.max_tokens = opts.maxTokens;
1192
- const veniceParams = {};
1193
- if (opts.enableWebSearch) veniceParams.enable_web_search = "on";
1194
- if (opts.disableThinking) veniceParams.disable_thinking = true;
1195
- if (Object.keys(veniceParams).length > 0) body.venice_parameters = veniceParams;
1196
- const res = await fetch(`${VENICE_API_BASE}/chat/completions`, {
1197
- method: "POST",
1198
- headers: {
1199
- "Content-Type": "application/json",
1200
- Authorization: `Bearer ${apiKey}`
1201
- },
1202
- signal: AbortSignal.timeout(12e4),
1203
- // inference can be slow
1204
- body: JSON.stringify(body)
1205
- });
1206
- if (!res.ok) {
1207
- const errBody = await res.text();
1208
- throw new Error(`Venice inference failed: ${res.status} ${errBody}`);
1209
- }
1210
- const data = await res.json();
1211
- const choice = data.choices?.[0];
1212
- if (!choice) {
1213
- throw new Error("Venice returned no choices");
1214
- }
1215
- return {
1216
- content: choice.message?.content ?? "",
1217
- model: data.model ?? opts.model,
1218
- usage: {
1219
- promptTokens: data.usage?.prompt_tokens ?? 0,
1220
- completionTokens: data.usage?.completion_tokens ?? 0,
1221
- totalTokens: data.usage?.total_tokens ?? 0
1222
- }
1223
- };
1224
- }
1225
- async function listModels() {
1226
- const apiKey = getVeniceApiKey();
1227
- if (!apiKey) {
1228
- throw new Error("No Venice API key configured. Run 'sherwood venice provision' first.");
1229
- }
1230
- const res = await fetch(`${VENICE_API_BASE}/models`, {
1231
- headers: { Authorization: `Bearer ${apiKey}` },
1232
- signal: AbortSignal.timeout(15e3)
1233
- });
1234
- if (!res.ok) {
1235
- throw new Error(`Failed to list Venice models: ${res.status} ${res.statusText}`);
1236
- }
1237
- const data = await res.json();
1238
- return (data.data ?? []).map((m) => m.id);
1239
- }
1240
-
1241
- // src/commands/venice.ts
1242
1118
  import { readFileSync } from "fs";
1243
1119
  function registerVeniceCommands(program2) {
1244
1120
  const venice = program2.command("venice").description("Venice private inference \u2014 provision API keys, run inference");
@@ -1271,6 +1147,14 @@ function registerVeniceCommands(program2) {
1271
1147
  keySpinner.succeed("Venice API key provisioned");
1272
1148
  console.log(chalk2.dim(` Key: ${apiKey.slice(0, 8)}...${apiKey.slice(-4)}`));
1273
1149
  console.log(chalk2.dim(" Saved to ~/.sherwood/config.json"));
1150
+ try {
1151
+ const { createVeniceProvisionAttestation, getEasScanUrl: getEasScanUrl2 } = await import("./eas-YZF6MN65.js");
1152
+ const { uid } = await createVeniceProvisionAttestation(account.address);
1153
+ if (uid !== "0x0000000000000000000000000000000000000000000000000000000000000000") {
1154
+ console.log(chalk2.dim(` Attested: ${getEasScanUrl2(uid)}`));
1155
+ }
1156
+ } catch {
1157
+ }
1274
1158
  } catch (err) {
1275
1159
  keySpinner.fail("Failed to provision API key");
1276
1160
  console.error(chalk2.red(err instanceof Error ? err.message : String(err)));
@@ -1414,6 +1298,21 @@ ${opts.prompt}`;
1414
1298
  console.log();
1415
1299
  console.log(chalk2.dim(`Model: ${result.model} | Tokens: ${result.usage.promptTokens} in, ${result.usage.completionTokens} out, ${result.usage.totalTokens} total`));
1416
1300
  }
1301
+ try {
1302
+ const { createVeniceInferenceAttestation, getEasScanUrl: getEasScanUrl2 } = await import("./eas-YZF6MN65.js");
1303
+ const { keccak256, toHex } = await import("viem");
1304
+ const promptHash = keccak256(toHex(userContent)).slice(0, 18);
1305
+ const { uid } = await createVeniceInferenceAttestation(
1306
+ result.model,
1307
+ result.usage.promptTokens,
1308
+ result.usage.completionTokens,
1309
+ promptHash
1310
+ );
1311
+ if (uid !== "0x0000000000000000000000000000000000000000000000000000000000000000") {
1312
+ console.log(chalk2.dim(`Attested: ${getEasScanUrl2(uid)}`));
1313
+ }
1314
+ } catch {
1315
+ }
1417
1316
  } catch (err) {
1418
1317
  spinner.fail("Inference failed");
1419
1318
  console.error(chalk2.red(err instanceof Error ? err.message : String(err)));
@@ -1427,138 +1326,8 @@ import { parseUnits as parseUnits4, formatUnits as formatUnits3, isAddress as is
1427
1326
  import chalk3 from "chalk";
1428
1327
  import ora3 from "ora";
1429
1328
 
1430
- // src/lib/quote.ts
1431
- import { encodeFunctionData as encodeFunctionData5, decodeFunctionResult, concat as concat2, pad, numberToHex } from "viem";
1432
- async function getQuote(params) {
1433
- const client = getPublicClient();
1434
- const calldata = encodeFunctionData5({
1435
- abi: UNISWAP_QUOTER_V2_ABI,
1436
- functionName: "quoteExactInputSingle",
1437
- args: [
1438
- {
1439
- tokenIn: params.tokenIn,
1440
- tokenOut: params.tokenOut,
1441
- amountIn: params.amountIn,
1442
- fee: params.fee,
1443
- sqrtPriceLimitX96: 0n
1444
- }
1445
- ]
1446
- });
1447
- const { data } = await client.call({
1448
- to: UNISWAP().QUOTER_V2,
1449
- data: calldata
1450
- });
1451
- if (!data) {
1452
- throw new Error("Quoter returned no data \u2014 pool may not exist for this pair/fee");
1453
- }
1454
- const [amountOut, sqrtPriceX96After, , gasEstimate] = decodeFunctionResult({
1455
- abi: UNISWAP_QUOTER_V2_ABI,
1456
- functionName: "quoteExactInputSingle",
1457
- data
1458
- });
1459
- return { amountOut, sqrtPriceX96After, gasEstimate };
1460
- }
1461
- function applySlippage(amountOut, slippageBps) {
1462
- return amountOut * BigInt(1e4 - slippageBps) / 10000n;
1463
- }
1464
- function encodeSwapPath(tokens, fees) {
1465
- if (tokens.length < 2 || fees.length !== tokens.length - 1) {
1466
- throw new Error("Invalid path: need at least 2 tokens and (tokens-1) fees");
1467
- }
1468
- const parts = [];
1469
- for (let i = 0; i < tokens.length; i++) {
1470
- parts.push(tokens[i].toLowerCase());
1471
- if (i < fees.length) {
1472
- parts.push(pad(numberToHex(fees[i]), { size: 3 }));
1473
- }
1474
- }
1475
- return concat2(parts);
1476
- }
1477
- async function getMultiHopQuote(params) {
1478
- const client = getPublicClient();
1479
- const calldata = encodeFunctionData5({
1480
- abi: UNISWAP_QUOTER_V2_ABI,
1481
- functionName: "quoteExactInput",
1482
- args: [params.path, params.amountIn]
1483
- });
1484
- const { data } = await client.call({
1485
- to: UNISWAP().QUOTER_V2,
1486
- data: calldata
1487
- });
1488
- if (!data) {
1489
- throw new Error("Quoter returned no data \u2014 pool may not exist for this path");
1490
- }
1491
- const [amountOut, , , gasEstimate] = decodeFunctionResult({
1492
- abi: UNISWAP_QUOTER_V2_ABI,
1493
- functionName: "quoteExactInput",
1494
- data
1495
- });
1496
- return { amountOut, sqrtPriceX96After: 0n, gasEstimate };
1497
- }
1498
-
1499
1329
  // src/strategies/allowance-disburse.ts
1500
- import { encodeFunctionData as encodeFunctionData6, parseUnits as parseUnits3 } from "viem";
1501
- var ERC20_ABI2 = [
1502
- {
1503
- name: "approve",
1504
- type: "function",
1505
- inputs: [
1506
- { name: "spender", type: "address" },
1507
- { name: "amount", type: "uint256" }
1508
- ],
1509
- outputs: [{ name: "", type: "bool" }]
1510
- },
1511
- {
1512
- name: "transfer",
1513
- type: "function",
1514
- inputs: [
1515
- { name: "to", type: "address" },
1516
- { name: "amount", type: "uint256" }
1517
- ],
1518
- outputs: [{ name: "", type: "bool" }]
1519
- }
1520
- ];
1521
- var SWAP_ROUTER_EXACT_INPUT_SINGLE_ABI = [
1522
- {
1523
- name: "exactInputSingle",
1524
- type: "function",
1525
- inputs: [
1526
- {
1527
- name: "params",
1528
- type: "tuple",
1529
- components: [
1530
- { name: "tokenIn", type: "address" },
1531
- { name: "tokenOut", type: "address" },
1532
- { name: "fee", type: "uint24" },
1533
- { name: "recipient", type: "address" },
1534
- { name: "amountIn", type: "uint256" },
1535
- { name: "amountOutMinimum", type: "uint256" },
1536
- { name: "sqrtPriceLimitX96", type: "uint160" }
1537
- ]
1538
- }
1539
- ],
1540
- outputs: [{ name: "amountOut", type: "uint256" }]
1541
- }
1542
- ];
1543
- var SWAP_ROUTER_EXACT_INPUT_ABI = [
1544
- {
1545
- name: "exactInput",
1546
- type: "function",
1547
- inputs: [
1548
- {
1549
- name: "params",
1550
- type: "tuple",
1551
- components: [
1552
- { name: "path", type: "bytes" },
1553
- { name: "recipient", type: "address" },
1554
- { name: "amountIn", type: "uint256" },
1555
- { name: "amountOutMinimum", type: "uint256" }
1556
- ]
1557
- }
1558
- ],
1559
- outputs: [{ name: "amountOut", type: "uint256" }]
1560
- }
1561
- ];
1330
+ import { encodeFunctionData as encodeFunctionData5, parseUnits as parseUnits3 } from "viem";
1562
1331
  function buildDisburseBatch(config, vaultAddress, agents, assetAddress, assetDecimals, minUsdc, swapPath) {
1563
1332
  const assetAmount = parseUnits3(config.amount, assetDecimals);
1564
1333
  const isUsdc = assetAddress.toLowerCase() === TOKENS().USDC.toLowerCase();
@@ -1567,8 +1336,8 @@ function buildDisburseBatch(config, vaultAddress, agents, assetAddress, assetDec
1567
1336
  if (!isUsdc) {
1568
1337
  calls.push({
1569
1338
  target: assetAddress,
1570
- data: encodeFunctionData6({
1571
- abi: ERC20_ABI2,
1339
+ data: encodeFunctionData5({
1340
+ abi: ERC20_ABI,
1572
1341
  functionName: "approve",
1573
1342
  args: [UNISWAP().SWAP_ROUTER, assetAmount]
1574
1343
  }),
@@ -1577,7 +1346,7 @@ function buildDisburseBatch(config, vaultAddress, agents, assetAddress, assetDec
1577
1346
  if (isWeth) {
1578
1347
  calls.push({
1579
1348
  target: UNISWAP().SWAP_ROUTER,
1580
- data: encodeFunctionData6({
1349
+ data: encodeFunctionData5({
1581
1350
  abi: SWAP_ROUTER_EXACT_INPUT_SINGLE_ABI,
1582
1351
  functionName: "exactInputSingle",
1583
1352
  args: [
@@ -1597,8 +1366,8 @@ function buildDisburseBatch(config, vaultAddress, agents, assetAddress, assetDec
1597
1366
  } else {
1598
1367
  calls.push({
1599
1368
  target: UNISWAP().SWAP_ROUTER,
1600
- data: encodeFunctionData6({
1601
- abi: SWAP_ROUTER_EXACT_INPUT_ABI,
1369
+ data: encodeFunctionData5({
1370
+ abi: SWAP_ROUTER_ABI,
1602
1371
  functionName: "exactInput",
1603
1372
  args: [
1604
1373
  {
@@ -1617,8 +1386,8 @@ function buildDisburseBatch(config, vaultAddress, agents, assetAddress, assetDec
1617
1386
  for (const agent of agents) {
1618
1387
  calls.push({
1619
1388
  target: TOKENS().USDC,
1620
- data: encodeFunctionData6({
1621
- abi: ERC20_ABI2,
1389
+ data: encodeFunctionData5({
1390
+ abi: ERC20_ABI,
1622
1391
  functionName: "transfer",
1623
1392
  args: [agent, perAgent]
1624
1393
  }),
@@ -2513,7 +2282,7 @@ try {
2513
2282
  var require2 = createRequire(import.meta.url);
2514
2283
  var { version: CLI_VERSION } = require2("../package.json");
2515
2284
  async function loadXmtp() {
2516
- return import("./xmtp-ATRMY76G.js");
2285
+ return import("./xmtp-IH57GYSR.js");
2517
2286
  }
2518
2287
  async function loadCron() {
2519
2288
  return import("./cron-SKYKVZ6K.js");
@@ -3245,7 +3014,7 @@ vaultCmd.command("balance").description("Show LP share balance and asset value")
3245
3014
  var strategy = program.command("strategy").description("Strategy templates \u2014 list, clone, propose");
3246
3015
  registerStrategyTemplateCommands(strategy);
3247
3016
  program.command("providers").description("List available DeFi providers").action(async () => {
3248
- const { MessariProvider, NansenProvider } = await import("./research-V63URK4C.js");
3017
+ const { MessariProvider, NansenProvider } = await import("./research-HC2UOLFT.js");
3249
3018
  const providers = [new MoonwellProvider(), new UniswapProvider(), new MessariProvider(), new NansenProvider()];
3250
3019
  for (const p of providers) {
3251
3020
  const info = p.info();
@@ -3256,7 +3025,7 @@ ${info.name} (${info.type})`);
3256
3025
  }
3257
3026
  });
3258
3027
  try {
3259
- const { registerChatCommands } = await import("./chat-7CB4YGGP.js");
3028
+ const { registerChatCommands } = await import("./chat-MUUC5L5W.js");
3260
3029
  registerChatCommands(program);
3261
3030
  } catch {
3262
3031
  program.command("chat <name> [action] [actionArgs...]").description("Syndicate chat (XMTP) \u2014 requires @xmtp/cli").action(() => {
@@ -3266,17 +3035,19 @@ try {
3266
3035
  process.exit(1);
3267
3036
  });
3268
3037
  }
3269
- var { registerSessionCommands } = await import("./session-RAFLL5BD.js");
3038
+ var { registerSessionCommands } = await import("./session-X3QFFCJ7.js");
3270
3039
  registerSessionCommands(program);
3271
3040
  registerVeniceCommands(program);
3272
3041
  registerAllowanceCommands(program);
3273
3042
  registerIdentityCommands(program);
3274
3043
  registerProposalCommands(program);
3275
3044
  registerGovernorCommands(program);
3276
- var { registerResearchCommands } = await import("./research-MKI4RS2F.js");
3045
+ var { registerResearchCommands } = await import("./research-VZKLOTMU.js");
3277
3046
  registerResearchCommands(program);
3047
+ var { registerTradeCommands } = await import("./trade-YCBFXOB3.js");
3048
+ registerTradeCommands(program);
3278
3049
  var configCmd = program.command("config");
3279
- 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.)").action((opts) => {
3050
+ 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)").action((opts) => {
3280
3051
  let saved = false;
3281
3052
  if (opts.privateKey) {
3282
3053
  setPrivateKey(opts.privateKey);
@@ -3305,8 +3076,13 @@ configCmd.command("set").description("Save settings to ~/.sherwood/config.json (
3305
3076
  console.log(chalk7.dim(` Notify to: ${opts.notifyTo}`));
3306
3077
  saved = true;
3307
3078
  }
3079
+ if (opts.uniswapApiKey) {
3080
+ setUniswapApiKey(opts.uniswapApiKey);
3081
+ console.log(chalk7.green("Uniswap API key saved to ~/.sherwood/config.json"));
3082
+ saved = true;
3083
+ }
3308
3084
  if (!saved) {
3309
- console.log(chalk7.red("Provide at least one of: --private-key, --vault, --rpc, --notify-to"));
3085
+ console.log(chalk7.red("Provide at least one of: --private-key, --vault, --rpc, --notify-to, --uniswap-api-key"));
3310
3086
  process.exit(1);
3311
3087
  }
3312
3088
  });
@@ -3324,6 +3100,7 @@ configCmd.command("show").description("Display current config for the active net
3324
3100
  console.log(` Wallet: ${config.privateKey ? chalk7.green("configured") : chalk7.dim("not set")}`);
3325
3101
  console.log(` Agent ID: ${config.agentId ?? chalk7.dim("not set")}`);
3326
3102
  console.log(` Vault: ${contracts.vault ?? chalk7.dim("not set")}`);
3103
+ console.log(` Uniswap: ${getUniswapApiKey() ? chalk7.green("API key configured") : chalk7.dim("not set")}`);
3327
3104
  console.log();
3328
3105
  console.log(chalk7.dim(" Config file: ~/.sherwood/config.json"));
3329
3106
  console.log();