@sherwoodagent/cli 0.17.3 → 0.18.1
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/{chat-MQPTP4QO.js → chat-7CB4YGGP.js} +4 -4
- package/dist/{chunk-EMDEQLUU.js → chunk-5ZC2A7UP.js} +2 -2
- package/dist/{chunk-PRX5GLSN.js → chunk-ARD44YTT.js} +2 -2
- package/dist/{chunk-KYABEFLH.js → chunk-FR4LYDPJ.js} +2 -2
- package/dist/chunk-L24NGLKY.js +124 -0
- package/dist/chunk-L24NGLKY.js.map +1 -0
- package/dist/{chunk-EDH6ICCT.js → chunk-Z2PNK3CC.js} +2 -2
- package/dist/{eas-Y7HS7FXK.js → eas-DOC4QKDF.js} +3 -3
- package/dist/{governor-UGIUQYPB.js → governor-E6AU3UWV.js} +3 -3
- package/dist/index.js +110 -394
- package/dist/index.js.map +1 -1
- package/dist/{research-NCY3MCN4.js → research-MHN7UGIU.js} +5 -5
- package/dist/{research-IUHVRHR3.js → research-V63URK4C.js} +3 -3
- package/dist/{session-CQZ743DX.js → session-OJX2MILJ.js} +4 -4
- package/dist/{xmtp-MJ53JW2W.js → xmtp-ATRMY76G.js} +3 -3
- package/package.json +1 -1
- package/dist/chunk-N65F7HRF.js +0 -74
- package/dist/chunk-N65F7HRF.js.map +0 -1
- /package/dist/{chat-MQPTP4QO.js.map → chat-7CB4YGGP.js.map} +0 -0
- /package/dist/{chunk-EMDEQLUU.js.map → chunk-5ZC2A7UP.js.map} +0 -0
- /package/dist/{chunk-PRX5GLSN.js.map → chunk-ARD44YTT.js.map} +0 -0
- /package/dist/{chunk-KYABEFLH.js.map → chunk-FR4LYDPJ.js.map} +0 -0
- /package/dist/{chunk-EDH6ICCT.js.map → chunk-Z2PNK3CC.js.map} +0 -0
- /package/dist/{eas-Y7HS7FXK.js.map → eas-DOC4QKDF.js.map} +0 -0
- /package/dist/{governor-UGIUQYPB.js.map → governor-E6AU3UWV.js.map} +0 -0
- /package/dist/{research-NCY3MCN4.js.map → research-MHN7UGIU.js.map} +0 -0
- /package/dist/{research-IUHVRHR3.js.map → research-V63URK4C.js.map} +0 -0
- /package/dist/{session-CQZ743DX.js.map → session-OJX2MILJ.js.map} +0 -0
- /package/dist/{xmtp-MJ53JW2W.js.map → xmtp-ATRMY76G.js.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
setVotingPeriod,
|
|
30
30
|
settleProposal,
|
|
31
31
|
vote
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-5ZC2A7UP.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-
|
|
44
|
+
} from "./chunk-FR4LYDPJ.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-
|
|
60
|
+
} from "./chunk-ARD44YTT.js";
|
|
61
61
|
import {
|
|
62
62
|
AERODROME,
|
|
63
63
|
AGENT_REGISTRY,
|
|
@@ -78,8 +78,10 @@ import {
|
|
|
78
78
|
import {
|
|
79
79
|
getAccount,
|
|
80
80
|
getPublicClient,
|
|
81
|
-
getWalletClient
|
|
82
|
-
|
|
81
|
+
getWalletClient,
|
|
82
|
+
sendTxWithRetry,
|
|
83
|
+
writeContractWithRetry
|
|
84
|
+
} from "./chunk-L24NGLKY.js";
|
|
83
85
|
import {
|
|
84
86
|
VALID_NETWORKS,
|
|
85
87
|
getChain,
|
|
@@ -108,7 +110,7 @@ import {
|
|
|
108
110
|
import { config as loadDotenv } from "dotenv";
|
|
109
111
|
import { createRequire } from "module";
|
|
110
112
|
import { Command, Option } from "commander";
|
|
111
|
-
import { parseUnits as
|
|
113
|
+
import { parseUnits as parseUnits5, isAddress as isAddress5 } from "viem";
|
|
112
114
|
import chalk7 from "chalk";
|
|
113
115
|
import ora7 from "ora";
|
|
114
116
|
import { input, confirm, select } from "@inquirer/prompts";
|
|
@@ -184,10 +186,9 @@ async function cloneTemplate(template) {
|
|
|
184
186
|
template,
|
|
185
187
|
"0x5af43d82803e903d91602b57fd5bf3"
|
|
186
188
|
]);
|
|
187
|
-
const wallet = getWalletClient();
|
|
188
189
|
const account = getAccount();
|
|
189
190
|
const chain = getChain();
|
|
190
|
-
const hash = await
|
|
191
|
+
const hash = await sendTxWithRetry({
|
|
191
192
|
account,
|
|
192
193
|
chain,
|
|
193
194
|
data: creationCode,
|
|
@@ -711,8 +712,7 @@ function registerStrategyTemplateCommands(strategy2) {
|
|
|
711
712
|
try {
|
|
712
713
|
const { initData } = await buildInitDataForTemplate(templateKey, opts, vault);
|
|
713
714
|
const account = getAccount();
|
|
714
|
-
const
|
|
715
|
-
const initHash = await wallet.writeContract({
|
|
715
|
+
const initHash = await writeContractWithRetry({
|
|
716
716
|
account,
|
|
717
717
|
chain: getChain(),
|
|
718
718
|
address: clone,
|
|
@@ -761,8 +761,7 @@ function registerStrategyTemplateCommands(strategy2) {
|
|
|
761
761
|
assetAmount = built.assetAmount;
|
|
762
762
|
extraApprovals = built.extraApprovals;
|
|
763
763
|
const account2 = getAccount();
|
|
764
|
-
const
|
|
765
|
-
const initHash = await wallet.writeContract({
|
|
764
|
+
const initHash = await writeContractWithRetry({
|
|
766
765
|
account: account2,
|
|
767
766
|
chain: getChain(),
|
|
768
767
|
address: clone,
|
|
@@ -821,9 +820,9 @@ function registerStrategyTemplateCommands(strategy2) {
|
|
|
821
820
|
console.error(chalk.red("Missing --name, --performance-fee, or --duration. Use --write-calls to skip proposal submission."));
|
|
822
821
|
process.exit(1);
|
|
823
822
|
}
|
|
824
|
-
const { propose: propose2 } = await import("./governor-
|
|
823
|
+
const { propose: propose2 } = await import("./governor-E6AU3UWV.js");
|
|
825
824
|
const { pinJSON } = await import("./ipfs-6XVOOHSR.js");
|
|
826
|
-
const { parseDuration: parseDuration2 } = await import("./governor-
|
|
825
|
+
const { parseDuration: parseDuration2 } = await import("./governor-E6AU3UWV.js");
|
|
827
826
|
const performanceFeeBps = BigInt(opts.performanceFee);
|
|
828
827
|
if (performanceFeeBps < 0n || performanceFeeBps > 10000n) {
|
|
829
828
|
console.error(chalk.red("--performance-fee must be 0-10000 (basis points)"));
|
|
@@ -1060,223 +1059,10 @@ async function getActiveSyndicates2(creator) {
|
|
|
1060
1059
|
}
|
|
1061
1060
|
|
|
1062
1061
|
// src/commands/venice.ts
|
|
1063
|
-
import {
|
|
1062
|
+
import { formatUnits as formatUnits2, isAddress as isAddress2 } from "viem";
|
|
1064
1063
|
import chalk2 from "chalk";
|
|
1065
1064
|
import ora2 from "ora";
|
|
1066
1065
|
|
|
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
1066
|
// src/lib/venice.ts
|
|
1281
1067
|
var VENICE_API_BASE = "https://api.venice.ai/api/v1";
|
|
1282
1068
|
async function provisionApiKey() {
|
|
@@ -1391,148 +1177,9 @@ async function listModels() {
|
|
|
1391
1177
|
}
|
|
1392
1178
|
|
|
1393
1179
|
// src/commands/venice.ts
|
|
1394
|
-
import { readFileSync
|
|
1395
|
-
var VALID_FEES = [500, 3e3, 1e4];
|
|
1180
|
+
import { readFileSync } from "fs";
|
|
1396
1181
|
function registerVeniceCommands(program2) {
|
|
1397
|
-
const venice = program2.command("venice").description("Venice private inference \u2014
|
|
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
|
-
});
|
|
1182
|
+
const venice = program2.command("venice").description("Venice private inference \u2014 provision API keys, run inference");
|
|
1536
1183
|
venice.command("provision").description("Self-provision a Venice API key (requires sVVV in wallet)").action(async () => {
|
|
1537
1184
|
const account = getAccount();
|
|
1538
1185
|
const client = getPublicClient();
|
|
@@ -1547,7 +1194,7 @@ function registerVeniceCommands(program2) {
|
|
|
1547
1194
|
if (sVvvBalance === 0n) {
|
|
1548
1195
|
checkSpinner.fail("No sVVV found in wallet");
|
|
1549
1196
|
console.log(chalk2.yellow(" Your wallet must hold staked VVV (sVVV) to provision a Venice API key."));
|
|
1550
|
-
console.log(chalk2.yellow("
|
|
1197
|
+
console.log(chalk2.yellow(" Use the VeniceInferenceStrategy via a proposal to distribute sVVV to agents."));
|
|
1551
1198
|
process.exit(1);
|
|
1552
1199
|
}
|
|
1553
1200
|
checkSpinner.succeed(`sVVV balance: ${formatUnits2(sVvvBalance, 18)}`);
|
|
@@ -1714,13 +1361,82 @@ ${opts.prompt}`;
|
|
|
1714
1361
|
}
|
|
1715
1362
|
|
|
1716
1363
|
// src/commands/allowance.ts
|
|
1717
|
-
import { parseUnits as
|
|
1364
|
+
import { parseUnits as parseUnits4, formatUnits as formatUnits3, isAddress as isAddress3 } from "viem";
|
|
1718
1365
|
import chalk3 from "chalk";
|
|
1719
1366
|
import ora3 from "ora";
|
|
1720
1367
|
|
|
1368
|
+
// src/lib/quote.ts
|
|
1369
|
+
import { encodeFunctionData as encodeFunctionData5, decodeFunctionResult, concat as concat2, pad, numberToHex } from "viem";
|
|
1370
|
+
async function getQuote(params) {
|
|
1371
|
+
const client = getPublicClient();
|
|
1372
|
+
const calldata = encodeFunctionData5({
|
|
1373
|
+
abi: UNISWAP_QUOTER_V2_ABI,
|
|
1374
|
+
functionName: "quoteExactInputSingle",
|
|
1375
|
+
args: [
|
|
1376
|
+
{
|
|
1377
|
+
tokenIn: params.tokenIn,
|
|
1378
|
+
tokenOut: params.tokenOut,
|
|
1379
|
+
amountIn: params.amountIn,
|
|
1380
|
+
fee: params.fee,
|
|
1381
|
+
sqrtPriceLimitX96: 0n
|
|
1382
|
+
}
|
|
1383
|
+
]
|
|
1384
|
+
});
|
|
1385
|
+
const { data } = await client.call({
|
|
1386
|
+
to: UNISWAP().QUOTER_V2,
|
|
1387
|
+
data: calldata
|
|
1388
|
+
});
|
|
1389
|
+
if (!data) {
|
|
1390
|
+
throw new Error("Quoter returned no data \u2014 pool may not exist for this pair/fee");
|
|
1391
|
+
}
|
|
1392
|
+
const [amountOut, sqrtPriceX96After, , gasEstimate] = decodeFunctionResult({
|
|
1393
|
+
abi: UNISWAP_QUOTER_V2_ABI,
|
|
1394
|
+
functionName: "quoteExactInputSingle",
|
|
1395
|
+
data
|
|
1396
|
+
});
|
|
1397
|
+
return { amountOut, sqrtPriceX96After, gasEstimate };
|
|
1398
|
+
}
|
|
1399
|
+
function applySlippage(amountOut, slippageBps) {
|
|
1400
|
+
return amountOut * BigInt(1e4 - slippageBps) / 10000n;
|
|
1401
|
+
}
|
|
1402
|
+
function encodeSwapPath(tokens, fees) {
|
|
1403
|
+
if (tokens.length < 2 || fees.length !== tokens.length - 1) {
|
|
1404
|
+
throw new Error("Invalid path: need at least 2 tokens and (tokens-1) fees");
|
|
1405
|
+
}
|
|
1406
|
+
const parts = [];
|
|
1407
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
1408
|
+
parts.push(tokens[i].toLowerCase());
|
|
1409
|
+
if (i < fees.length) {
|
|
1410
|
+
parts.push(pad(numberToHex(fees[i]), { size: 3 }));
|
|
1411
|
+
}
|
|
1412
|
+
}
|
|
1413
|
+
return concat2(parts);
|
|
1414
|
+
}
|
|
1415
|
+
async function getMultiHopQuote(params) {
|
|
1416
|
+
const client = getPublicClient();
|
|
1417
|
+
const calldata = encodeFunctionData5({
|
|
1418
|
+
abi: UNISWAP_QUOTER_V2_ABI,
|
|
1419
|
+
functionName: "quoteExactInput",
|
|
1420
|
+
args: [params.path, params.amountIn]
|
|
1421
|
+
});
|
|
1422
|
+
const { data } = await client.call({
|
|
1423
|
+
to: UNISWAP().QUOTER_V2,
|
|
1424
|
+
data: calldata
|
|
1425
|
+
});
|
|
1426
|
+
if (!data) {
|
|
1427
|
+
throw new Error("Quoter returned no data \u2014 pool may not exist for this path");
|
|
1428
|
+
}
|
|
1429
|
+
const [amountOut, , , gasEstimate] = decodeFunctionResult({
|
|
1430
|
+
abi: UNISWAP_QUOTER_V2_ABI,
|
|
1431
|
+
functionName: "quoteExactInput",
|
|
1432
|
+
data
|
|
1433
|
+
});
|
|
1434
|
+
return { amountOut, sqrtPriceX96After: 0n, gasEstimate };
|
|
1435
|
+
}
|
|
1436
|
+
|
|
1721
1437
|
// src/strategies/allowance-disburse.ts
|
|
1722
|
-
import { encodeFunctionData as
|
|
1723
|
-
var
|
|
1438
|
+
import { encodeFunctionData as encodeFunctionData6, parseUnits as parseUnits3 } from "viem";
|
|
1439
|
+
var ERC20_ABI2 = [
|
|
1724
1440
|
{
|
|
1725
1441
|
name: "approve",
|
|
1726
1442
|
type: "function",
|
|
@@ -1740,7 +1456,7 @@ var ERC20_ABI3 = [
|
|
|
1740
1456
|
outputs: [{ name: "", type: "bool" }]
|
|
1741
1457
|
}
|
|
1742
1458
|
];
|
|
1743
|
-
var
|
|
1459
|
+
var SWAP_ROUTER_EXACT_INPUT_SINGLE_ABI = [
|
|
1744
1460
|
{
|
|
1745
1461
|
name: "exactInputSingle",
|
|
1746
1462
|
type: "function",
|
|
@@ -1762,7 +1478,7 @@ var SWAP_ROUTER_EXACT_INPUT_SINGLE_ABI2 = [
|
|
|
1762
1478
|
outputs: [{ name: "amountOut", type: "uint256" }]
|
|
1763
1479
|
}
|
|
1764
1480
|
];
|
|
1765
|
-
var
|
|
1481
|
+
var SWAP_ROUTER_EXACT_INPUT_ABI = [
|
|
1766
1482
|
{
|
|
1767
1483
|
name: "exactInput",
|
|
1768
1484
|
type: "function",
|
|
@@ -1782,15 +1498,15 @@ var SWAP_ROUTER_EXACT_INPUT_ABI2 = [
|
|
|
1782
1498
|
}
|
|
1783
1499
|
];
|
|
1784
1500
|
function buildDisburseBatch(config, vaultAddress, agents, assetAddress, assetDecimals, minUsdc, swapPath) {
|
|
1785
|
-
const assetAmount =
|
|
1501
|
+
const assetAmount = parseUnits3(config.amount, assetDecimals);
|
|
1786
1502
|
const isUsdc = assetAddress.toLowerCase() === TOKENS().USDC.toLowerCase();
|
|
1787
1503
|
const isWeth = assetAddress.toLowerCase() === TOKENS().WETH.toLowerCase();
|
|
1788
1504
|
const calls = [];
|
|
1789
1505
|
if (!isUsdc) {
|
|
1790
1506
|
calls.push({
|
|
1791
1507
|
target: assetAddress,
|
|
1792
|
-
data:
|
|
1793
|
-
abi:
|
|
1508
|
+
data: encodeFunctionData6({
|
|
1509
|
+
abi: ERC20_ABI2,
|
|
1794
1510
|
functionName: "approve",
|
|
1795
1511
|
args: [UNISWAP().SWAP_ROUTER, assetAmount]
|
|
1796
1512
|
}),
|
|
@@ -1799,8 +1515,8 @@ function buildDisburseBatch(config, vaultAddress, agents, assetAddress, assetDec
|
|
|
1799
1515
|
if (isWeth) {
|
|
1800
1516
|
calls.push({
|
|
1801
1517
|
target: UNISWAP().SWAP_ROUTER,
|
|
1802
|
-
data:
|
|
1803
|
-
abi:
|
|
1518
|
+
data: encodeFunctionData6({
|
|
1519
|
+
abi: SWAP_ROUTER_EXACT_INPUT_SINGLE_ABI,
|
|
1804
1520
|
functionName: "exactInputSingle",
|
|
1805
1521
|
args: [
|
|
1806
1522
|
{
|
|
@@ -1819,8 +1535,8 @@ function buildDisburseBatch(config, vaultAddress, agents, assetAddress, assetDec
|
|
|
1819
1535
|
} else {
|
|
1820
1536
|
calls.push({
|
|
1821
1537
|
target: UNISWAP().SWAP_ROUTER,
|
|
1822
|
-
data:
|
|
1823
|
-
abi:
|
|
1538
|
+
data: encodeFunctionData6({
|
|
1539
|
+
abi: SWAP_ROUTER_EXACT_INPUT_ABI,
|
|
1824
1540
|
functionName: "exactInput",
|
|
1825
1541
|
args: [
|
|
1826
1542
|
{
|
|
@@ -1839,8 +1555,8 @@ function buildDisburseBatch(config, vaultAddress, agents, assetAddress, assetDec
|
|
|
1839
1555
|
for (const agent of agents) {
|
|
1840
1556
|
calls.push({
|
|
1841
1557
|
target: TOKENS().USDC,
|
|
1842
|
-
data:
|
|
1843
|
-
abi:
|
|
1558
|
+
data: encodeFunctionData6({
|
|
1559
|
+
abi: ERC20_ABI2,
|
|
1844
1560
|
functionName: "transfer",
|
|
1845
1561
|
args: [agent, perAgent]
|
|
1846
1562
|
}),
|
|
@@ -1851,7 +1567,7 @@ function buildDisburseBatch(config, vaultAddress, agents, assetAddress, assetDec
|
|
|
1851
1567
|
}
|
|
1852
1568
|
|
|
1853
1569
|
// src/commands/allowance.ts
|
|
1854
|
-
var
|
|
1570
|
+
var VALID_FEES = [500, 3e3, 1e4];
|
|
1855
1571
|
function registerAllowanceCommands(program2) {
|
|
1856
1572
|
const allowance = program2.command("allowance").description("Disburse vault profits to agent wallets");
|
|
1857
1573
|
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 +1577,8 @@ function registerAllowanceCommands(program2) {
|
|
|
1861
1577
|
process.exit(1);
|
|
1862
1578
|
}
|
|
1863
1579
|
const fee = Number(opts.fee);
|
|
1864
|
-
if (!
|
|
1865
|
-
console.error(chalk3.red(`Invalid fee tier. Valid: ${
|
|
1580
|
+
if (!VALID_FEES.includes(fee)) {
|
|
1581
|
+
console.error(chalk3.red(`Invalid fee tier. Valid: ${VALID_FEES.join(", ")}`));
|
|
1866
1582
|
process.exit(1);
|
|
1867
1583
|
}
|
|
1868
1584
|
const slippageBps = Number(opts.slippage);
|
|
@@ -1895,7 +1611,7 @@ function registerAllowanceCommands(program2) {
|
|
|
1895
1611
|
console.error(chalk3.red("No agents registered in vault. Register agents first."));
|
|
1896
1612
|
process.exit(1);
|
|
1897
1613
|
}
|
|
1898
|
-
const requestedAmount =
|
|
1614
|
+
const requestedAmount = parseUnits4(opts.amount, assetDecimals);
|
|
1899
1615
|
const profit = assetBalance > totalDeposited ? assetBalance - totalDeposited : 0n;
|
|
1900
1616
|
const isUsdc = assetAddress.toLowerCase() === TOKENS().USDC.toLowerCase();
|
|
1901
1617
|
const isWeth = assetAddress.toLowerCase() === TOKENS().WETH.toLowerCase();
|
|
@@ -2735,7 +2451,7 @@ try {
|
|
|
2735
2451
|
var require2 = createRequire(import.meta.url);
|
|
2736
2452
|
var { version: CLI_VERSION } = require2("../package.json");
|
|
2737
2453
|
async function loadXmtp() {
|
|
2738
|
-
return import("./xmtp-
|
|
2454
|
+
return import("./xmtp-ATRMY76G.js");
|
|
2739
2455
|
}
|
|
2740
2456
|
async function loadCron() {
|
|
2741
2457
|
return import("./cron-SKYKVZ6K.js");
|
|
@@ -3412,7 +3128,7 @@ var vaultCmd = program.command("vault");
|
|
|
3412
3128
|
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
3129
|
resolveVault(opts);
|
|
3414
3130
|
const decimals = await getAssetDecimals();
|
|
3415
|
-
const amount =
|
|
3131
|
+
const amount = parseUnits5(opts.amount, decimals);
|
|
3416
3132
|
const spinner = ora7(`Depositing ${opts.amount}...`).start();
|
|
3417
3133
|
try {
|
|
3418
3134
|
const hash = await deposit(amount);
|
|
@@ -3467,7 +3183,7 @@ vaultCmd.command("balance").description("Show LP share balance and asset value")
|
|
|
3467
3183
|
var strategy = program.command("strategy").description("Strategy templates \u2014 list, clone, propose");
|
|
3468
3184
|
registerStrategyTemplateCommands(strategy);
|
|
3469
3185
|
program.command("providers").description("List available DeFi providers").action(async () => {
|
|
3470
|
-
const { MessariProvider, NansenProvider } = await import("./research-
|
|
3186
|
+
const { MessariProvider, NansenProvider } = await import("./research-V63URK4C.js");
|
|
3471
3187
|
const providers = [new MoonwellProvider(), new UniswapProvider(), new MessariProvider(), new NansenProvider()];
|
|
3472
3188
|
for (const p of providers) {
|
|
3473
3189
|
const info = p.info();
|
|
@@ -3478,7 +3194,7 @@ ${info.name} (${info.type})`);
|
|
|
3478
3194
|
}
|
|
3479
3195
|
});
|
|
3480
3196
|
try {
|
|
3481
|
-
const { registerChatCommands } = await import("./chat-
|
|
3197
|
+
const { registerChatCommands } = await import("./chat-7CB4YGGP.js");
|
|
3482
3198
|
registerChatCommands(program);
|
|
3483
3199
|
} catch {
|
|
3484
3200
|
program.command("chat <name> [action] [actionArgs...]").description("Syndicate chat (XMTP) \u2014 requires @xmtp/cli").action(() => {
|
|
@@ -3488,14 +3204,14 @@ try {
|
|
|
3488
3204
|
process.exit(1);
|
|
3489
3205
|
});
|
|
3490
3206
|
}
|
|
3491
|
-
var { registerSessionCommands } = await import("./session-
|
|
3207
|
+
var { registerSessionCommands } = await import("./session-OJX2MILJ.js");
|
|
3492
3208
|
registerSessionCommands(program);
|
|
3493
3209
|
registerVeniceCommands(program);
|
|
3494
3210
|
registerAllowanceCommands(program);
|
|
3495
3211
|
registerIdentityCommands(program);
|
|
3496
3212
|
registerProposalCommands(program);
|
|
3497
3213
|
registerGovernorCommands(program);
|
|
3498
|
-
var { registerResearchCommands } = await import("./research-
|
|
3214
|
+
var { registerResearchCommands } = await import("./research-MHN7UGIU.js");
|
|
3499
3215
|
registerResearchCommands(program);
|
|
3500
3216
|
var configCmd = program.command("config");
|
|
3501
3217
|
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) => {
|