@sherwoodagent/cli 0.17.2 → 0.18.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
@@ -29,7 +29,7 @@ import {
29
29
  setVotingPeriod,
30
30
  settleProposal,
31
31
  vote
32
- } from "./chunk-4GTOZMVG.js";
32
+ } from "./chunk-EMDEQLUU.js";
33
33
  import {
34
34
  fetchMetadata,
35
35
  uploadMetadata
@@ -41,7 +41,7 @@ import {
41
41
  queryApprovals,
42
42
  queryJoinRequests,
43
43
  revokeAttestation
44
- } from "./chunk-RAFAIAIE.js";
44
+ } from "./chunk-KYABEFLH.js";
45
45
  import {
46
46
  approveDepositor,
47
47
  deposit,
@@ -57,7 +57,7 @@ import {
57
57
  resolveVaultSyndicate,
58
58
  setTextRecord,
59
59
  setVaultAddress
60
- } from "./chunk-E7KKGN3V.js";
60
+ } from "./chunk-PRX5GLSN.js";
61
61
  import {
62
62
  AERODROME,
63
63
  AGENT_REGISTRY,
@@ -74,7 +74,7 @@ import {
74
74
  UNISWAP_QUOTER_V2_ABI,
75
75
  VENICE,
76
76
  VENICE_STAKING_ABI
77
- } from "./chunk-E3UCNLU3.js";
77
+ } from "./chunk-TPE6ZTUI.js";
78
78
  import {
79
79
  getAccount,
80
80
  getPublicClient,
@@ -108,7 +108,7 @@ import {
108
108
  import { config as loadDotenv } from "dotenv";
109
109
  import { createRequire } from "module";
110
110
  import { Command, Option } from "commander";
111
- import { parseUnits as parseUnits7, isAddress as isAddress5 } from "viem";
111
+ import { parseUnits as parseUnits5, isAddress as isAddress5 } from "viem";
112
112
  import chalk7 from "chalk";
113
113
  import ora7 from "ora";
114
114
  import { input, confirm, select } from "@inquirer/prompts";
@@ -821,9 +821,9 @@ function registerStrategyTemplateCommands(strategy2) {
821
821
  console.error(chalk.red("Missing --name, --performance-fee, or --duration. Use --write-calls to skip proposal submission."));
822
822
  process.exit(1);
823
823
  }
824
- const { propose: propose2 } = await import("./governor-J7WTADUX.js");
824
+ const { propose: propose2 } = await import("./governor-UGIUQYPB.js");
825
825
  const { pinJSON } = await import("./ipfs-6XVOOHSR.js");
826
- const { parseDuration: parseDuration2 } = await import("./governor-J7WTADUX.js");
826
+ const { parseDuration: parseDuration2 } = await import("./governor-UGIUQYPB.js");
827
827
  const performanceFeeBps = BigInt(opts.performanceFee);
828
828
  if (performanceFeeBps < 0n || performanceFeeBps > 10000n) {
829
829
  console.error(chalk.red("--performance-fee must be 0-10000 (basis points)"));
@@ -1060,223 +1060,10 @@ async function getActiveSyndicates2(creator) {
1060
1060
  }
1061
1061
 
1062
1062
  // src/commands/venice.ts
1063
- import { parseUnits as parseUnits4, formatUnits as formatUnits2, isAddress as isAddress2 } from "viem";
1063
+ import { formatUnits as formatUnits2, isAddress as isAddress2 } from "viem";
1064
1064
  import chalk2 from "chalk";
1065
1065
  import ora2 from "ora";
1066
1066
 
1067
- // src/lib/quote.ts
1068
- import { encodeFunctionData as encodeFunctionData5, decodeFunctionResult, concat as concat2, pad, numberToHex } from "viem";
1069
- async function getQuote(params) {
1070
- const client = getPublicClient();
1071
- const calldata = encodeFunctionData5({
1072
- abi: UNISWAP_QUOTER_V2_ABI,
1073
- functionName: "quoteExactInputSingle",
1074
- args: [
1075
- {
1076
- tokenIn: params.tokenIn,
1077
- tokenOut: params.tokenOut,
1078
- amountIn: params.amountIn,
1079
- fee: params.fee,
1080
- sqrtPriceLimitX96: 0n
1081
- }
1082
- ]
1083
- });
1084
- const { data } = await client.call({
1085
- to: UNISWAP().QUOTER_V2,
1086
- data: calldata
1087
- });
1088
- if (!data) {
1089
- throw new Error("Quoter returned no data \u2014 pool may not exist for this pair/fee");
1090
- }
1091
- const [amountOut, sqrtPriceX96After, , gasEstimate] = decodeFunctionResult({
1092
- abi: UNISWAP_QUOTER_V2_ABI,
1093
- functionName: "quoteExactInputSingle",
1094
- data
1095
- });
1096
- return { amountOut, sqrtPriceX96After, gasEstimate };
1097
- }
1098
- function applySlippage(amountOut, slippageBps) {
1099
- return amountOut * BigInt(1e4 - slippageBps) / 10000n;
1100
- }
1101
- function encodeSwapPath(tokens, fees) {
1102
- if (tokens.length < 2 || fees.length !== tokens.length - 1) {
1103
- throw new Error("Invalid path: need at least 2 tokens and (tokens-1) fees");
1104
- }
1105
- const parts = [];
1106
- for (let i = 0; i < tokens.length; i++) {
1107
- parts.push(tokens[i].toLowerCase());
1108
- if (i < fees.length) {
1109
- parts.push(pad(numberToHex(fees[i]), { size: 3 }));
1110
- }
1111
- }
1112
- return concat2(parts);
1113
- }
1114
- async function getMultiHopQuote(params) {
1115
- const client = getPublicClient();
1116
- const calldata = encodeFunctionData5({
1117
- abi: UNISWAP_QUOTER_V2_ABI,
1118
- functionName: "quoteExactInput",
1119
- args: [params.path, params.amountIn]
1120
- });
1121
- const { data } = await client.call({
1122
- to: UNISWAP().QUOTER_V2,
1123
- data: calldata
1124
- });
1125
- if (!data) {
1126
- throw new Error("Quoter returned no data \u2014 pool may not exist for this path");
1127
- }
1128
- const [amountOut, , , gasEstimate] = decodeFunctionResult({
1129
- abi: UNISWAP_QUOTER_V2_ABI,
1130
- functionName: "quoteExactInput",
1131
- data
1132
- });
1133
- return { amountOut, sqrtPriceX96After: 0n, gasEstimate };
1134
- }
1135
-
1136
- // src/strategies/venice-fund.ts
1137
- import { encodeFunctionData as encodeFunctionData6, parseUnits as parseUnits3 } from "viem";
1138
- var ERC20_ABI2 = [
1139
- {
1140
- name: "approve",
1141
- type: "function",
1142
- inputs: [
1143
- { name: "spender", type: "address" },
1144
- { name: "amount", type: "uint256" }
1145
- ],
1146
- outputs: [{ name: "", type: "bool" }]
1147
- }
1148
- ];
1149
- var SWAP_ROUTER_EXACT_INPUT_SINGLE_ABI = [
1150
- {
1151
- name: "exactInputSingle",
1152
- type: "function",
1153
- inputs: [
1154
- {
1155
- name: "params",
1156
- type: "tuple",
1157
- components: [
1158
- { name: "tokenIn", type: "address" },
1159
- { name: "tokenOut", type: "address" },
1160
- { name: "fee", type: "uint24" },
1161
- { name: "recipient", type: "address" },
1162
- { name: "amountIn", type: "uint256" },
1163
- { name: "amountOutMinimum", type: "uint256" },
1164
- { name: "sqrtPriceLimitX96", type: "uint160" }
1165
- ]
1166
- }
1167
- ],
1168
- outputs: [{ name: "amountOut", type: "uint256" }]
1169
- }
1170
- ];
1171
- var SWAP_ROUTER_EXACT_INPUT_ABI = [
1172
- {
1173
- name: "exactInput",
1174
- type: "function",
1175
- inputs: [
1176
- {
1177
- name: "params",
1178
- type: "tuple",
1179
- components: [
1180
- { name: "path", type: "bytes" },
1181
- { name: "recipient", type: "address" },
1182
- { name: "amountIn", type: "uint256" },
1183
- { name: "amountOutMinimum", type: "uint256" }
1184
- ]
1185
- }
1186
- ],
1187
- outputs: [{ name: "amountOut", type: "uint256" }]
1188
- }
1189
- ];
1190
- var STAKING_ABI = [
1191
- {
1192
- name: "stake",
1193
- type: "function",
1194
- inputs: [
1195
- { name: "recipient", type: "address" },
1196
- { name: "amount", type: "uint256" }
1197
- ],
1198
- outputs: []
1199
- }
1200
- ];
1201
- function buildFundBatch(config, vaultAddress, agents, assetAddress, assetDecimals, minVVV, swapPath) {
1202
- const ZERO2 = "0x0000000000000000000000000000000000000000";
1203
- if (VENICE().VVV === ZERO2 || VENICE().STAKING === ZERO2) {
1204
- throw new Error("Venice (VVV/sVVV) is not deployed on this network \u2014 venice fund requires Venice staking contracts");
1205
- }
1206
- const assetAmount = parseUnits3(config.amount, assetDecimals);
1207
- const isWeth = assetAddress.toLowerCase() === TOKENS().WETH.toLowerCase();
1208
- const calls = [];
1209
- calls.push({
1210
- target: assetAddress,
1211
- data: encodeFunctionData6({
1212
- abi: ERC20_ABI2,
1213
- functionName: "approve",
1214
- args: [UNISWAP().SWAP_ROUTER, assetAmount]
1215
- }),
1216
- value: 0n
1217
- });
1218
- if (isWeth) {
1219
- calls.push({
1220
- target: UNISWAP().SWAP_ROUTER,
1221
- data: encodeFunctionData6({
1222
- abi: SWAP_ROUTER_EXACT_INPUT_SINGLE_ABI,
1223
- functionName: "exactInputSingle",
1224
- args: [
1225
- {
1226
- tokenIn: TOKENS().WETH,
1227
- tokenOut: VENICE().VVV,
1228
- fee: config.fee2,
1229
- recipient: vaultAddress,
1230
- amountIn: assetAmount,
1231
- amountOutMinimum: minVVV,
1232
- sqrtPriceLimitX96: 0n
1233
- }
1234
- ]
1235
- }),
1236
- value: 0n
1237
- });
1238
- } else {
1239
- calls.push({
1240
- target: UNISWAP().SWAP_ROUTER,
1241
- data: encodeFunctionData6({
1242
- abi: SWAP_ROUTER_EXACT_INPUT_ABI,
1243
- functionName: "exactInput",
1244
- args: [
1245
- {
1246
- path: swapPath,
1247
- recipient: vaultAddress,
1248
- amountIn: assetAmount,
1249
- amountOutMinimum: minVVV
1250
- }
1251
- ]
1252
- }),
1253
- value: 0n
1254
- });
1255
- }
1256
- calls.push({
1257
- target: VENICE().VVV,
1258
- data: encodeFunctionData6({
1259
- abi: ERC20_ABI2,
1260
- functionName: "approve",
1261
- args: [VENICE().STAKING, minVVV]
1262
- }),
1263
- value: 0n
1264
- });
1265
- const perAgent = minVVV / BigInt(agents.length);
1266
- for (const agent of agents) {
1267
- calls.push({
1268
- target: VENICE().STAKING,
1269
- data: encodeFunctionData6({
1270
- abi: STAKING_ABI,
1271
- functionName: "stake",
1272
- args: [agent, perAgent]
1273
- }),
1274
- value: 0n
1275
- });
1276
- }
1277
- return calls;
1278
- }
1279
-
1280
1067
  // src/lib/venice.ts
1281
1068
  var VENICE_API_BASE = "https://api.venice.ai/api/v1";
1282
1069
  async function provisionApiKey() {
@@ -1391,148 +1178,9 @@ async function listModels() {
1391
1178
  }
1392
1179
 
1393
1180
  // src/commands/venice.ts
1394
- import { readFileSync, writeFileSync as writeFileSync2 } from "fs";
1395
- var VALID_FEES = [500, 3e3, 1e4];
1181
+ import { readFileSync } from "fs";
1396
1182
  function registerVeniceCommands(program2) {
1397
- const venice = program2.command("venice").description("Venice private inference \u2014 stake VVV, provision API keys");
1398
- venice.command("fund").description("Swap vault profits \u2192 VVV \u2192 stake \u2192 distribute sVVV to agents").requiredOption("--vault <address>", "Vault address").requiredOption("--amount <amount>", "Deposit token amount to convert (e.g. 500)").option("--fee1 <tier>", "Fee tier for asset \u2192 WETH hop (500, 3000, 10000)", "3000").option("--fee2 <tier>", "Fee tier for WETH \u2192 VVV hop", "10000").option("--slippage <bps>", "Slippage tolerance in bps", "100").option("--execute", "Execute on-chain (default: simulate only)", false).option("--write-calls <path>", "Write batch calls to JSON file for proposal create (skips execution)").action(async (opts) => {
1399
- const vaultAddress = opts.vault;
1400
- if (!isAddress2(vaultAddress)) {
1401
- console.error(chalk2.red(`Invalid vault address: ${opts.vault}`));
1402
- process.exit(1);
1403
- }
1404
- const fee1 = Number(opts.fee1);
1405
- const fee2 = Number(opts.fee2);
1406
- if (!VALID_FEES.includes(fee1) || !VALID_FEES.includes(fee2)) {
1407
- console.error(chalk2.red(`Invalid fee tier. Valid: ${VALID_FEES.join(", ")}`));
1408
- process.exit(1);
1409
- }
1410
- const slippageBps = Number(opts.slippage);
1411
- const client = getPublicClient();
1412
- const spinner = ora2("Reading vault state...").start();
1413
- let assetAddress;
1414
- let assetDecimals;
1415
- let assetSymbol;
1416
- let totalDeposited;
1417
- let assetBalance;
1418
- let agents;
1419
- try {
1420
- [assetAddress, totalDeposited, agents] = await Promise.all([
1421
- client.readContract({ address: vaultAddress, abi: SYNDICATE_VAULT_ABI, functionName: "asset" }),
1422
- client.readContract({ address: vaultAddress, abi: SYNDICATE_VAULT_ABI, functionName: "totalDeposited" }),
1423
- client.readContract({ address: vaultAddress, abi: SYNDICATE_VAULT_ABI, functionName: "getAgentAddresses" })
1424
- ]);
1425
- [assetDecimals, assetSymbol, assetBalance] = await Promise.all([
1426
- client.readContract({ address: assetAddress, abi: ERC20_ABI, functionName: "decimals" }),
1427
- client.readContract({ address: assetAddress, abi: ERC20_ABI, functionName: "symbol" }),
1428
- client.readContract({ address: assetAddress, abi: ERC20_ABI, functionName: "balanceOf", args: [vaultAddress] })
1429
- ]);
1430
- spinner.stop();
1431
- } catch (err) {
1432
- spinner.fail("Failed to read vault state");
1433
- console.error(chalk2.red(err instanceof Error ? err.message : String(err)));
1434
- process.exit(1);
1435
- }
1436
- if (agents.length === 0) {
1437
- console.error(chalk2.red("No agents registered in vault. Register agents first."));
1438
- process.exit(1);
1439
- }
1440
- const requestedAmount = parseUnits4(opts.amount, assetDecimals);
1441
- const profit = assetBalance > totalDeposited ? assetBalance - totalDeposited : 0n;
1442
- const isWeth = assetAddress.toLowerCase() === TOKENS().WETH.toLowerCase();
1443
- console.log();
1444
- console.log(chalk2.bold("Venice Fund"));
1445
- console.log(chalk2.dim("\u2500".repeat(40)));
1446
- console.log(` Asset: ${assetSymbol} (${assetDecimals} decimals)`);
1447
- console.log(` Amount: ${opts.amount} ${assetSymbol}`);
1448
- console.log(` Vault balance: ${formatUnits2(assetBalance, assetDecimals)} ${assetSymbol}`);
1449
- console.log(` Deposited: ${formatUnits2(totalDeposited, assetDecimals)} ${assetSymbol}`);
1450
- console.log(` Profit: ${formatUnits2(profit, assetDecimals)} ${assetSymbol}`);
1451
- console.log(` Agents: ${agents.length} (sVVV will be split equally)`);
1452
- console.log(` Routing: ${isWeth ? `WETH \u2192 VVV (fee ${fee2})` : `${assetSymbol} \u2192 WETH (fee ${fee1}) \u2192 VVV (fee ${fee2})`}`);
1453
- console.log(` Slippage: ${(slippageBps / 100).toFixed(2)}%`);
1454
- console.log(` Vault: ${vaultAddress}`);
1455
- console.log();
1456
- if (requestedAmount > profit) {
1457
- console.warn(chalk2.yellow(` Warning: amount (${opts.amount}) exceeds available profit (${formatUnits2(profit, assetDecimals)})`));
1458
- console.warn(chalk2.yellow(" This will use deposited capital, not just profits."));
1459
- console.log();
1460
- }
1461
- const quoteSpinner = ora2("Fetching Uniswap quote...").start();
1462
- let amountOut;
1463
- let minOut;
1464
- let swapPath = null;
1465
- try {
1466
- if (isWeth) {
1467
- const quote = await getQuote({
1468
- tokenIn: TOKENS().WETH,
1469
- tokenOut: VENICE().VVV,
1470
- amountIn: requestedAmount,
1471
- fee: fee2
1472
- });
1473
- amountOut = quote.amountOut;
1474
- } else {
1475
- swapPath = encodeSwapPath(
1476
- [assetAddress, TOKENS().WETH, VENICE().VVV],
1477
- [fee1, fee2]
1478
- );
1479
- const quote = await getMultiHopQuote({
1480
- path: swapPath,
1481
- amountIn: requestedAmount
1482
- });
1483
- amountOut = quote.amountOut;
1484
- }
1485
- minOut = applySlippage(amountOut, slippageBps);
1486
- quoteSpinner.succeed(
1487
- `Quote: ${formatUnits2(amountOut, 18)} VVV (min: ${formatUnits2(minOut, 18)}, per agent: ${formatUnits2(minOut / BigInt(agents.length), 18)})`
1488
- );
1489
- } catch (err) {
1490
- quoteSpinner.fail("Failed to fetch quote");
1491
- console.error(chalk2.red(err instanceof Error ? err.message : String(err)));
1492
- process.exit(1);
1493
- }
1494
- const config = {
1495
- amount: opts.amount,
1496
- fee1,
1497
- fee2,
1498
- slippageBps
1499
- };
1500
- const calls = buildFundBatch(config, vaultAddress, agents, assetAddress, assetDecimals, minOut, swapPath);
1501
- console.log();
1502
- console.log(chalk2.bold(`Batch calls (${calls.length}):`));
1503
- console.log(formatBatch(calls));
1504
- console.log();
1505
- if (opts.writeCalls) {
1506
- const callsJson = calls.map((c) => ({
1507
- target: c.target,
1508
- data: c.data,
1509
- value: c.value.toString()
1510
- }));
1511
- writeFileSync2(opts.writeCalls, JSON.stringify(callsJson, null, 2));
1512
- const settlePath = `${opts.writeCalls}.settle.json`;
1513
- writeFileSync2(settlePath, "[]");
1514
- console.log(chalk2.green(`Execute calls written to: ${opts.writeCalls}`));
1515
- console.log(chalk2.green(`Settlement calls written to: ${settlePath}`));
1516
- console.log();
1517
- console.log(chalk2.dim("Use with: sherwood proposal create --execute-calls <path> --settle-calls <path>"));
1518
- return;
1519
- }
1520
- if (!opts.execute) {
1521
- console.log();
1522
- console.log(chalk2.yellow("Dry run complete. Add --execute to submit on-chain, or --write-calls <path> to export for proposals."));
1523
- return;
1524
- }
1525
- const execSpinner = ora2("Executing batch via vault...").start();
1526
- try {
1527
- const txHash = await executeBatch(calls);
1528
- execSpinner.succeed(`Batch executed: ${txHash}`);
1529
- console.log(chalk2.dim(` ${getExplorerUrl(txHash)}`));
1530
- } catch (err) {
1531
- execSpinner.fail("Execution failed");
1532
- console.error(chalk2.red(err instanceof Error ? err.message : String(err)));
1533
- process.exit(1);
1534
- }
1535
- });
1183
+ const venice = program2.command("venice").description("Venice private inference \u2014 provision API keys, run inference");
1536
1184
  venice.command("provision").description("Self-provision a Venice API key (requires sVVV in wallet)").action(async () => {
1537
1185
  const account = getAccount();
1538
1186
  const client = getPublicClient();
@@ -1547,7 +1195,7 @@ function registerVeniceCommands(program2) {
1547
1195
  if (sVvvBalance === 0n) {
1548
1196
  checkSpinner.fail("No sVVV found in wallet");
1549
1197
  console.log(chalk2.yellow(" Your wallet must hold staked VVV (sVVV) to provision a Venice API key."));
1550
- console.log(chalk2.yellow(" Run 'sherwood venice fund' first to distribute sVVV to agents."));
1198
+ console.log(chalk2.yellow(" Use the VeniceInferenceStrategy via a proposal to distribute sVVV to agents."));
1551
1199
  process.exit(1);
1552
1200
  }
1553
1201
  checkSpinner.succeed(`sVVV balance: ${formatUnits2(sVvvBalance, 18)}`);
@@ -1714,13 +1362,82 @@ ${opts.prompt}`;
1714
1362
  }
1715
1363
 
1716
1364
  // src/commands/allowance.ts
1717
- import { parseUnits as parseUnits6, formatUnits as formatUnits3, isAddress as isAddress3 } from "viem";
1365
+ import { parseUnits as parseUnits4, formatUnits as formatUnits3, isAddress as isAddress3 } from "viem";
1718
1366
  import chalk3 from "chalk";
1719
1367
  import ora3 from "ora";
1720
1368
 
1369
+ // src/lib/quote.ts
1370
+ import { encodeFunctionData as encodeFunctionData5, decodeFunctionResult, concat as concat2, pad, numberToHex } from "viem";
1371
+ async function getQuote(params) {
1372
+ const client = getPublicClient();
1373
+ const calldata = encodeFunctionData5({
1374
+ abi: UNISWAP_QUOTER_V2_ABI,
1375
+ functionName: "quoteExactInputSingle",
1376
+ args: [
1377
+ {
1378
+ tokenIn: params.tokenIn,
1379
+ tokenOut: params.tokenOut,
1380
+ amountIn: params.amountIn,
1381
+ fee: params.fee,
1382
+ sqrtPriceLimitX96: 0n
1383
+ }
1384
+ ]
1385
+ });
1386
+ const { data } = await client.call({
1387
+ to: UNISWAP().QUOTER_V2,
1388
+ data: calldata
1389
+ });
1390
+ if (!data) {
1391
+ throw new Error("Quoter returned no data \u2014 pool may not exist for this pair/fee");
1392
+ }
1393
+ const [amountOut, sqrtPriceX96After, , gasEstimate] = decodeFunctionResult({
1394
+ abi: UNISWAP_QUOTER_V2_ABI,
1395
+ functionName: "quoteExactInputSingle",
1396
+ data
1397
+ });
1398
+ return { amountOut, sqrtPriceX96After, gasEstimate };
1399
+ }
1400
+ function applySlippage(amountOut, slippageBps) {
1401
+ return amountOut * BigInt(1e4 - slippageBps) / 10000n;
1402
+ }
1403
+ function encodeSwapPath(tokens, fees) {
1404
+ if (tokens.length < 2 || fees.length !== tokens.length - 1) {
1405
+ throw new Error("Invalid path: need at least 2 tokens and (tokens-1) fees");
1406
+ }
1407
+ const parts = [];
1408
+ for (let i = 0; i < tokens.length; i++) {
1409
+ parts.push(tokens[i].toLowerCase());
1410
+ if (i < fees.length) {
1411
+ parts.push(pad(numberToHex(fees[i]), { size: 3 }));
1412
+ }
1413
+ }
1414
+ return concat2(parts);
1415
+ }
1416
+ async function getMultiHopQuote(params) {
1417
+ const client = getPublicClient();
1418
+ const calldata = encodeFunctionData5({
1419
+ abi: UNISWAP_QUOTER_V2_ABI,
1420
+ functionName: "quoteExactInput",
1421
+ args: [params.path, params.amountIn]
1422
+ });
1423
+ const { data } = await client.call({
1424
+ to: UNISWAP().QUOTER_V2,
1425
+ data: calldata
1426
+ });
1427
+ if (!data) {
1428
+ throw new Error("Quoter returned no data \u2014 pool may not exist for this path");
1429
+ }
1430
+ const [amountOut, , , gasEstimate] = decodeFunctionResult({
1431
+ abi: UNISWAP_QUOTER_V2_ABI,
1432
+ functionName: "quoteExactInput",
1433
+ data
1434
+ });
1435
+ return { amountOut, sqrtPriceX96After: 0n, gasEstimate };
1436
+ }
1437
+
1721
1438
  // src/strategies/allowance-disburse.ts
1722
- import { encodeFunctionData as encodeFunctionData7, parseUnits as parseUnits5 } from "viem";
1723
- var ERC20_ABI3 = [
1439
+ import { encodeFunctionData as encodeFunctionData6, parseUnits as parseUnits3 } from "viem";
1440
+ var ERC20_ABI2 = [
1724
1441
  {
1725
1442
  name: "approve",
1726
1443
  type: "function",
@@ -1740,7 +1457,7 @@ var ERC20_ABI3 = [
1740
1457
  outputs: [{ name: "", type: "bool" }]
1741
1458
  }
1742
1459
  ];
1743
- var SWAP_ROUTER_EXACT_INPUT_SINGLE_ABI2 = [
1460
+ var SWAP_ROUTER_EXACT_INPUT_SINGLE_ABI = [
1744
1461
  {
1745
1462
  name: "exactInputSingle",
1746
1463
  type: "function",
@@ -1762,7 +1479,7 @@ var SWAP_ROUTER_EXACT_INPUT_SINGLE_ABI2 = [
1762
1479
  outputs: [{ name: "amountOut", type: "uint256" }]
1763
1480
  }
1764
1481
  ];
1765
- var SWAP_ROUTER_EXACT_INPUT_ABI2 = [
1482
+ var SWAP_ROUTER_EXACT_INPUT_ABI = [
1766
1483
  {
1767
1484
  name: "exactInput",
1768
1485
  type: "function",
@@ -1782,15 +1499,15 @@ var SWAP_ROUTER_EXACT_INPUT_ABI2 = [
1782
1499
  }
1783
1500
  ];
1784
1501
  function buildDisburseBatch(config, vaultAddress, agents, assetAddress, assetDecimals, minUsdc, swapPath) {
1785
- const assetAmount = parseUnits5(config.amount, assetDecimals);
1502
+ const assetAmount = parseUnits3(config.amount, assetDecimals);
1786
1503
  const isUsdc = assetAddress.toLowerCase() === TOKENS().USDC.toLowerCase();
1787
1504
  const isWeth = assetAddress.toLowerCase() === TOKENS().WETH.toLowerCase();
1788
1505
  const calls = [];
1789
1506
  if (!isUsdc) {
1790
1507
  calls.push({
1791
1508
  target: assetAddress,
1792
- data: encodeFunctionData7({
1793
- abi: ERC20_ABI3,
1509
+ data: encodeFunctionData6({
1510
+ abi: ERC20_ABI2,
1794
1511
  functionName: "approve",
1795
1512
  args: [UNISWAP().SWAP_ROUTER, assetAmount]
1796
1513
  }),
@@ -1799,8 +1516,8 @@ function buildDisburseBatch(config, vaultAddress, agents, assetAddress, assetDec
1799
1516
  if (isWeth) {
1800
1517
  calls.push({
1801
1518
  target: UNISWAP().SWAP_ROUTER,
1802
- data: encodeFunctionData7({
1803
- abi: SWAP_ROUTER_EXACT_INPUT_SINGLE_ABI2,
1519
+ data: encodeFunctionData6({
1520
+ abi: SWAP_ROUTER_EXACT_INPUT_SINGLE_ABI,
1804
1521
  functionName: "exactInputSingle",
1805
1522
  args: [
1806
1523
  {
@@ -1819,8 +1536,8 @@ function buildDisburseBatch(config, vaultAddress, agents, assetAddress, assetDec
1819
1536
  } else {
1820
1537
  calls.push({
1821
1538
  target: UNISWAP().SWAP_ROUTER,
1822
- data: encodeFunctionData7({
1823
- abi: SWAP_ROUTER_EXACT_INPUT_ABI2,
1539
+ data: encodeFunctionData6({
1540
+ abi: SWAP_ROUTER_EXACT_INPUT_ABI,
1824
1541
  functionName: "exactInput",
1825
1542
  args: [
1826
1543
  {
@@ -1839,8 +1556,8 @@ function buildDisburseBatch(config, vaultAddress, agents, assetAddress, assetDec
1839
1556
  for (const agent of agents) {
1840
1557
  calls.push({
1841
1558
  target: TOKENS().USDC,
1842
- data: encodeFunctionData7({
1843
- abi: ERC20_ABI3,
1559
+ data: encodeFunctionData6({
1560
+ abi: ERC20_ABI2,
1844
1561
  functionName: "transfer",
1845
1562
  args: [agent, perAgent]
1846
1563
  }),
@@ -1851,7 +1568,7 @@ function buildDisburseBatch(config, vaultAddress, agents, assetAddress, assetDec
1851
1568
  }
1852
1569
 
1853
1570
  // src/commands/allowance.ts
1854
- var VALID_FEES2 = [500, 3e3, 1e4];
1571
+ var VALID_FEES = [500, 3e3, 1e4];
1855
1572
  function registerAllowanceCommands(program2) {
1856
1573
  const allowance = program2.command("allowance").description("Disburse vault profits to agent wallets");
1857
1574
  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) => {
@@ -1861,8 +1578,8 @@ function registerAllowanceCommands(program2) {
1861
1578
  process.exit(1);
1862
1579
  }
1863
1580
  const fee = Number(opts.fee);
1864
- if (!VALID_FEES2.includes(fee)) {
1865
- console.error(chalk3.red(`Invalid fee tier. Valid: ${VALID_FEES2.join(", ")}`));
1581
+ if (!VALID_FEES.includes(fee)) {
1582
+ console.error(chalk3.red(`Invalid fee tier. Valid: ${VALID_FEES.join(", ")}`));
1866
1583
  process.exit(1);
1867
1584
  }
1868
1585
  const slippageBps = Number(opts.slippage);
@@ -1895,7 +1612,7 @@ function registerAllowanceCommands(program2) {
1895
1612
  console.error(chalk3.red("No agents registered in vault. Register agents first."));
1896
1613
  process.exit(1);
1897
1614
  }
1898
- const requestedAmount = parseUnits6(opts.amount, assetDecimals);
1615
+ const requestedAmount = parseUnits4(opts.amount, assetDecimals);
1899
1616
  const profit = assetBalance > totalDeposited ? assetBalance - totalDeposited : 0n;
1900
1617
  const isUsdc = assetAddress.toLowerCase() === TOKENS().USDC.toLowerCase();
1901
1618
  const isWeth = assetAddress.toLowerCase() === TOKENS().WETH.toLowerCase();
@@ -2735,7 +2452,7 @@ try {
2735
2452
  var require2 = createRequire(import.meta.url);
2736
2453
  var { version: CLI_VERSION } = require2("../package.json");
2737
2454
  async function loadXmtp() {
2738
- return import("./xmtp-2AHDKL2Q.js");
2455
+ return import("./xmtp-MJ53JW2W.js");
2739
2456
  }
2740
2457
  async function loadCron() {
2741
2458
  return import("./cron-SKYKVZ6K.js");
@@ -3412,7 +3129,7 @@ var vaultCmd = program.command("vault");
3412
3129
  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)").action(async (opts) => {
3413
3130
  resolveVault(opts);
3414
3131
  const decimals = await getAssetDecimals();
3415
- const amount = parseUnits7(opts.amount, decimals);
3132
+ const amount = parseUnits5(opts.amount, decimals);
3416
3133
  const spinner = ora7(`Depositing ${opts.amount}...`).start();
3417
3134
  try {
3418
3135
  const hash = await deposit(amount);
@@ -3478,7 +3195,7 @@ ${info.name} (${info.type})`);
3478
3195
  }
3479
3196
  });
3480
3197
  try {
3481
- const { registerChatCommands } = await import("./chat-XTOTPTGV.js");
3198
+ const { registerChatCommands } = await import("./chat-MQPTP4QO.js");
3482
3199
  registerChatCommands(program);
3483
3200
  } catch {
3484
3201
  program.command("chat <name> [action] [actionArgs...]").description("Syndicate chat (XMTP) \u2014 requires @xmtp/cli").action(() => {
@@ -3488,14 +3205,14 @@ try {
3488
3205
  process.exit(1);
3489
3206
  });
3490
3207
  }
3491
- var { registerSessionCommands } = await import("./session-RDBY24HJ.js");
3208
+ var { registerSessionCommands } = await import("./session-CQZ743DX.js");
3492
3209
  registerSessionCommands(program);
3493
3210
  registerVeniceCommands(program);
3494
3211
  registerAllowanceCommands(program);
3495
3212
  registerIdentityCommands(program);
3496
3213
  registerProposalCommands(program);
3497
3214
  registerGovernorCommands(program);
3498
- var { registerResearchCommands } = await import("./research-BYQZ2MLK.js");
3215
+ var { registerResearchCommands } = await import("./research-NCY3MCN4.js");
3499
3216
  registerResearchCommands(program);
3500
3217
  var configCmd = program.command("config");
3501
3218
  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) => {