@sherwoodagent/cli 0.74.3 → 0.76.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/{addresses-OFFTM6NG.js → addresses-JJPQTF6S.js} +4 -4
- package/dist/{agent-B7V5L2ZL.js → agent-FYRYTKYM.js} +7 -7
- package/dist/{chat-CXUU4AXK.js → chat-CO244AHH.js} +8 -8
- package/dist/{chunk-6MV4ESXM.js → chunk-3TZIOAPH.js} +25 -1
- package/dist/chunk-3TZIOAPH.js.map +1 -0
- package/dist/{chunk-EW6FTUOL.js → chunk-EVTDWMXQ.js} +4 -4
- package/dist/{chunk-2OHX3O55.js → chunk-FP5DZCOM.js} +3 -3
- package/dist/{chunk-UINMHN6S.js → chunk-I6X6NL65.js} +2 -2
- package/dist/{chunk-LHVSS27T.js → chunk-LSVCF24W.js} +2 -2
- package/dist/{chunk-YADJ5YWY.js → chunk-M7CGUYUX.js} +6 -6
- package/dist/{chunk-3ZOWP3VO.js → chunk-MEMYGZWQ.js} +3 -3
- package/dist/{chunk-BD4ZV7FQ.js → chunk-RGFA732Z.js} +3 -3
- package/dist/{chunk-DGLLSZ2D.js → chunk-T2HVR3O6.js} +2 -2
- package/dist/{chunk-4LKU7ASB.js → chunk-TI64P5R4.js} +4 -4
- package/dist/{chunk-6UEQUVTQ.js → chunk-TN7J5LXW.js} +4 -4
- package/dist/{chunk-O65AC2YS.js → chunk-WCX7DKLQ.js} +4 -4
- package/dist/{chunk-K3EYEJMT.js → chunk-WGXZ623D.js} +4 -4
- package/dist/{client-C3C6IXAH.js → client-GRPJRISD.js} +4 -4
- package/dist/{config-7HU4X7EK.js → config-ZGFS4I7K.js} +12 -4
- package/dist/{eas-XWQYAUEM.js → eas-4RIW3IS4.js} +6 -6
- package/dist/{governor-NHXBIFFB.js → governor-7KETSN47.js} +6 -6
- package/dist/index.js +428 -61
- package/dist/index.js.map +1 -1
- package/dist/{network-WU2QC3L4.js → network-UP2X5XDW.js} +3 -3
- package/dist/{price-QSVIM6QY.js → price-LAQSXN7M.js} +6 -6
- package/dist/{providers-YOOQFBN2.js → providers-2J6LL67W.js} +5 -5
- package/dist/{research-NQKYGTLY.js → research-FHQCSLTZ.js} +9 -9
- package/dist/{session-NLI6UFKB.js → session-JQ3IF3IV.js} +11 -11
- package/dist/{trade-6VYB6YJZ.js → trade-5EYPZN7M.js} +17 -17
- package/dist/{vault-45POYGLN.js → vault-5YYTHS5W.js} +8 -8
- package/dist/{xmtp-KH5I6GOL.js → xmtp-OZ5PJFCT.js} +6 -6
- package/package.json +1 -1
- package/dist/chunk-6MV4ESXM.js.map +0 -1
- /package/dist/{addresses-OFFTM6NG.js.map → addresses-JJPQTF6S.js.map} +0 -0
- /package/dist/{agent-B7V5L2ZL.js.map → agent-FYRYTKYM.js.map} +0 -0
- /package/dist/{chat-CXUU4AXK.js.map → chat-CO244AHH.js.map} +0 -0
- /package/dist/{chunk-EW6FTUOL.js.map → chunk-EVTDWMXQ.js.map} +0 -0
- /package/dist/{chunk-2OHX3O55.js.map → chunk-FP5DZCOM.js.map} +0 -0
- /package/dist/{chunk-UINMHN6S.js.map → chunk-I6X6NL65.js.map} +0 -0
- /package/dist/{chunk-LHVSS27T.js.map → chunk-LSVCF24W.js.map} +0 -0
- /package/dist/{chunk-YADJ5YWY.js.map → chunk-M7CGUYUX.js.map} +0 -0
- /package/dist/{chunk-3ZOWP3VO.js.map → chunk-MEMYGZWQ.js.map} +0 -0
- /package/dist/{chunk-BD4ZV7FQ.js.map → chunk-RGFA732Z.js.map} +0 -0
- /package/dist/{chunk-DGLLSZ2D.js.map → chunk-T2HVR3O6.js.map} +0 -0
- /package/dist/{chunk-4LKU7ASB.js.map → chunk-TI64P5R4.js.map} +0 -0
- /package/dist/{chunk-6UEQUVTQ.js.map → chunk-TN7J5LXW.js.map} +0 -0
- /package/dist/{chunk-O65AC2YS.js.map → chunk-WCX7DKLQ.js.map} +0 -0
- /package/dist/{chunk-K3EYEJMT.js.map → chunk-WGXZ623D.js.map} +0 -0
- /package/dist/{client-C3C6IXAH.js.map → client-GRPJRISD.js.map} +0 -0
- /package/dist/{config-7HU4X7EK.js.map → config-ZGFS4I7K.js.map} +0 -0
- /package/dist/{eas-XWQYAUEM.js.map → eas-4RIW3IS4.js.map} +0 -0
- /package/dist/{governor-NHXBIFFB.js.map → governor-7KETSN47.js.map} +0 -0
- /package/dist/{network-WU2QC3L4.js.map → network-UP2X5XDW.js.map} +0 -0
- /package/dist/{price-QSVIM6QY.js.map → price-LAQSXN7M.js.map} +0 -0
- /package/dist/{providers-YOOQFBN2.js.map → providers-2J6LL67W.js.map} +0 -0
- /package/dist/{research-NQKYGTLY.js.map → research-FHQCSLTZ.js.map} +0 -0
- /package/dist/{session-NLI6UFKB.js.map → session-JQ3IF3IV.js.map} +0 -0
- /package/dist/{trade-6VYB6YJZ.js.map → trade-5EYPZN7M.js.map} +0 -0
- /package/dist/{vault-45POYGLN.js.map → vault-5YYTHS5W.js.map} +0 -0
- /package/dist/{xmtp-KH5I6GOL.js.map → xmtp-OZ5PJFCT.js.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
checkApiKeyValid,
|
|
16
16
|
listModels,
|
|
17
17
|
provisionApiKey
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-RGFA732Z.js";
|
|
19
19
|
import {
|
|
20
20
|
approveDepositor,
|
|
21
21
|
deposit,
|
|
@@ -38,8 +38,8 @@ import {
|
|
|
38
38
|
removeDepositor,
|
|
39
39
|
setAgentFeeBps,
|
|
40
40
|
setVaultAddress
|
|
41
|
-
} from "./chunk-
|
|
42
|
-
import "./chunk-
|
|
41
|
+
} from "./chunk-M7CGUYUX.js";
|
|
42
|
+
import "./chunk-MEMYGZWQ.js";
|
|
43
43
|
import {
|
|
44
44
|
applySlippage,
|
|
45
45
|
assetDecimalsForSymbol,
|
|
@@ -50,7 +50,7 @@ import {
|
|
|
50
50
|
getMultiHopQuote,
|
|
51
51
|
getQuote,
|
|
52
52
|
resolveToken
|
|
53
|
-
} from "./chunk-
|
|
53
|
+
} from "./chunk-TI64P5R4.js";
|
|
54
54
|
import {
|
|
55
55
|
createApproval,
|
|
56
56
|
createJoinRequest,
|
|
@@ -61,20 +61,20 @@ import {
|
|
|
61
61
|
queryJoinRequests,
|
|
62
62
|
revokeJoinRequest,
|
|
63
63
|
stripReferrerPrefix
|
|
64
|
-
} from "./chunk-
|
|
64
|
+
} from "./chunk-WCX7DKLQ.js";
|
|
65
65
|
import {
|
|
66
66
|
createFund,
|
|
67
67
|
getActiveFunds,
|
|
68
68
|
getFund,
|
|
69
69
|
subdomainExists,
|
|
70
70
|
updateMetadata
|
|
71
|
-
} from "./chunk-
|
|
71
|
+
} from "./chunk-WGXZ623D.js";
|
|
72
72
|
import {
|
|
73
73
|
resolveFund,
|
|
74
74
|
resolveVaultFund,
|
|
75
75
|
searchFundAcrossChains,
|
|
76
76
|
setTextRecord
|
|
77
|
-
} from "./chunk-
|
|
77
|
+
} from "./chunk-TN7J5LXW.js";
|
|
78
78
|
import {
|
|
79
79
|
PROPOSAL_STATE,
|
|
80
80
|
PROPOSAL_STATES,
|
|
@@ -108,7 +108,7 @@ import {
|
|
|
108
108
|
setVotingPeriod,
|
|
109
109
|
settleProposal,
|
|
110
110
|
vote
|
|
111
|
-
} from "./chunk-
|
|
111
|
+
} from "./chunk-EVTDWMXQ.js";
|
|
112
112
|
import {
|
|
113
113
|
AERODROME,
|
|
114
114
|
AGENT_REGISTRY,
|
|
@@ -118,7 +118,7 @@ import {
|
|
|
118
118
|
TOKENS,
|
|
119
119
|
UNISWAP,
|
|
120
120
|
VENICE
|
|
121
|
-
} from "./chunk-
|
|
121
|
+
} from "./chunk-I6X6NL65.js";
|
|
122
122
|
import {
|
|
123
123
|
GAS_UNITS,
|
|
124
124
|
estimateGasCushion,
|
|
@@ -129,7 +129,7 @@ import {
|
|
|
129
129
|
sendTxWithRetry,
|
|
130
130
|
waitForReceipt,
|
|
131
131
|
writeContractWithRetry
|
|
132
|
-
} from "./chunk-
|
|
132
|
+
} from "./chunk-FP5DZCOM.js";
|
|
133
133
|
import {
|
|
134
134
|
DEFAULT_NETWORK,
|
|
135
135
|
VALID_NETWORKS,
|
|
@@ -141,7 +141,7 @@ import {
|
|
|
141
141
|
isTestnet,
|
|
142
142
|
setNetwork,
|
|
143
143
|
withNetwork
|
|
144
|
-
} from "./chunk-
|
|
144
|
+
} from "./chunk-LSVCF24W.js";
|
|
145
145
|
import {
|
|
146
146
|
addFund,
|
|
147
147
|
cacheGroupId,
|
|
@@ -149,10 +149,13 @@ import {
|
|
|
149
149
|
getCachedGroupId,
|
|
150
150
|
getChainContracts,
|
|
151
151
|
getFunds,
|
|
152
|
+
getIdentityChainId,
|
|
153
|
+
getIdentityProvider,
|
|
152
154
|
getNotifyTo,
|
|
153
155
|
getPrimaryFund,
|
|
154
156
|
getUniswapApiKey,
|
|
155
157
|
getVeniceApiKey,
|
|
158
|
+
getVirtualsIdentity,
|
|
156
159
|
loadConfig,
|
|
157
160
|
requirePrivateKey,
|
|
158
161
|
setAgentId,
|
|
@@ -163,8 +166,9 @@ import {
|
|
|
163
166
|
setPrimaryFund,
|
|
164
167
|
setPrivateKey,
|
|
165
168
|
setUniswapApiKey,
|
|
166
|
-
setVeniceApiKey
|
|
167
|
-
|
|
169
|
+
setVeniceApiKey,
|
|
170
|
+
setVirtualsIdentity
|
|
171
|
+
} from "./chunk-3TZIOAPH.js";
|
|
168
172
|
import {
|
|
169
173
|
BASE_STRATEGY_ABI,
|
|
170
174
|
ERC20_ABI,
|
|
@@ -185,7 +189,7 @@ import {
|
|
|
185
189
|
import { config as loadDotenv } from "dotenv";
|
|
186
190
|
import { createRequire } from "module";
|
|
187
191
|
import { Command, Option } from "commander";
|
|
188
|
-
import { parseUnits as parseUnits8, formatUnits as formatUnits7, isAddress as
|
|
192
|
+
import { parseUnits as parseUnits8, formatUnits as formatUnits7, isAddress as isAddress10 } from "viem";
|
|
189
193
|
import chalk16 from "chalk";
|
|
190
194
|
import ora9 from "ora";
|
|
191
195
|
import { input, confirm, select } from "@inquirer/prompts";
|
|
@@ -2432,7 +2436,7 @@ function registerStrategyTemplateCommands(strategy2) {
|
|
|
2432
2436
|
process.exit(1);
|
|
2433
2437
|
}
|
|
2434
2438
|
if (!opts.agent) opts.agent = proposer;
|
|
2435
|
-
const { parseDuration: parseDuration3, getGovernorOf: getGovernorOf2 } = await import("./governor-
|
|
2439
|
+
const { parseDuration: parseDuration3, getGovernorOf: getGovernorOf2 } = await import("./governor-7KETSN47.js");
|
|
2436
2440
|
const strategyDuration2 = parseDuration3(opts.duration);
|
|
2437
2441
|
const chainId = getChain().id;
|
|
2438
2442
|
try {
|
|
@@ -2658,9 +2662,9 @@ function registerStrategyTemplateCommands(strategy2) {
|
|
|
2658
2662
|
console.error(chalk.red("Missing --name or --duration. Use --write-calls to skip proposal submission."));
|
|
2659
2663
|
process.exit(1);
|
|
2660
2664
|
}
|
|
2661
|
-
const { propose: propose2 } = await import("./governor-
|
|
2665
|
+
const { propose: propose2 } = await import("./governor-7KETSN47.js");
|
|
2662
2666
|
const { pinJSON } = await import("./ipfs-RWSTXTZM.js");
|
|
2663
|
-
const { parseDuration: parseDuration2 } = await import("./governor-
|
|
2667
|
+
const { parseDuration: parseDuration2 } = await import("./governor-7KETSN47.js");
|
|
2664
2668
|
const strategyDuration = parseDuration2(opts.duration);
|
|
2665
2669
|
const metaSpinner = ora("Pinning metadata to IPFS...").start();
|
|
2666
2670
|
let metadataURI;
|
|
@@ -2683,7 +2687,7 @@ function registerStrategyTemplateCommands(strategy2) {
|
|
|
2683
2687
|
process.exit(1);
|
|
2684
2688
|
}
|
|
2685
2689
|
try {
|
|
2686
|
-
const { getAgentFeeBps: getAgentFeeBps2 } = await import("./vault-
|
|
2690
|
+
const { getAgentFeeBps: getAgentFeeBps2 } = await import("./vault-5YYTHS5W.js");
|
|
2687
2691
|
const feeBps = await getAgentFeeBps2(vault);
|
|
2688
2692
|
console.log(
|
|
2689
2693
|
chalk.yellow(
|
|
@@ -2771,7 +2775,7 @@ function registerStrategyTemplateCommands(strategy2) {
|
|
|
2771
2775
|
let prices = [];
|
|
2772
2776
|
let priceSource = null;
|
|
2773
2777
|
try {
|
|
2774
|
-
const { getTokenPricesInAsset } = await import("./price-
|
|
2778
|
+
const { getTokenPricesInAsset } = await import("./price-LAQSXN7M.js");
|
|
2775
2779
|
prices = await getTokenPricesInAsset({
|
|
2776
2780
|
tokens: allocations.map((a, i) => ({
|
|
2777
2781
|
token: a.token,
|
|
@@ -3201,7 +3205,7 @@ function registerVeniceCommands(program2) {
|
|
|
3201
3205
|
console.log(chalk2.dim(` Key: ${apiKey.slice(0, 8)}...${apiKey.slice(-4)}`));
|
|
3202
3206
|
console.log(chalk2.dim(" Saved to ~/.sherwood/config.json"));
|
|
3203
3207
|
try {
|
|
3204
|
-
const { createVeniceProvisionAttestation, getEasScanUrl: getEasScanUrl2 } = await import("./eas-
|
|
3208
|
+
const { createVeniceProvisionAttestation, getEasScanUrl: getEasScanUrl2 } = await import("./eas-4RIW3IS4.js");
|
|
3205
3209
|
const { uid } = await createVeniceProvisionAttestation(account.address);
|
|
3206
3210
|
if (uid !== "0x0000000000000000000000000000000000000000000000000000000000000000") {
|
|
3207
3211
|
console.log(chalk2.dim(` Attested: ${getEasScanUrl2(uid)}`));
|
|
@@ -3557,10 +3561,10 @@ ${opts.prompt}`;
|
|
|
3557
3561
|
console.log(chalk2.dim(`Model: ${result.model} | Tokens: ${result.usage.promptTokens} in, ${result.usage.completionTokens} out, ${result.usage.totalTokens} total`));
|
|
3558
3562
|
}
|
|
3559
3563
|
try {
|
|
3560
|
-
const { createVeniceInferenceAttestation, getEasScanUrl: getEasScanUrl2 } = await import("./eas-
|
|
3564
|
+
const { createVeniceInferenceAttestation, getEasScanUrl: getEasScanUrl2 } = await import("./eas-4RIW3IS4.js");
|
|
3561
3565
|
const { keccak256: keccak2563, toHex, isAddress: isAddr } = await import("viem");
|
|
3562
|
-
const { getChainContracts: getChainContracts2 } = await import("./config-
|
|
3563
|
-
const { getChain: getActiveChain } = await import("./network-
|
|
3566
|
+
const { getChainContracts: getChainContracts2 } = await import("./config-ZGFS4I7K.js");
|
|
3567
|
+
const { getChain: getActiveChain } = await import("./network-UP2X5XDW.js");
|
|
3564
3568
|
const vaultRecipient = opts.vault && isAddr(opts.vault) ? opts.vault : getChainContracts2(getActiveChain().id).vault;
|
|
3565
3569
|
const promptHash = keccak2563(toHex(userContent)).slice(0, 18);
|
|
3566
3570
|
const { uid } = await createVeniceInferenceAttestation(
|
|
@@ -3858,9 +3862,194 @@ function registerAllowanceCommands(program2) {
|
|
|
3858
3862
|
}
|
|
3859
3863
|
|
|
3860
3864
|
// src/commands/identity.ts
|
|
3865
|
+
import { generatePrivateKey } from "viem/accounts";
|
|
3861
3866
|
import chalk4 from "chalk";
|
|
3862
3867
|
import ora4 from "ora";
|
|
3863
3868
|
import { SDK } from "agent0-sdk";
|
|
3869
|
+
|
|
3870
|
+
// src/lib/virtuals.ts
|
|
3871
|
+
import { execFile } from "child_process";
|
|
3872
|
+
import { promisify } from "util";
|
|
3873
|
+
import { createPublicClient, http, recoverMessageAddress, isAddress as isAddress5 } from "viem";
|
|
3874
|
+
import { base, baseSepolia } from "viem/chains";
|
|
3875
|
+
var execFileAsync = promisify(execFile);
|
|
3876
|
+
var BINDING_VERSION = "v1";
|
|
3877
|
+
function buildBindingMessage(sherwoodEoa, issuingChainId, tokenId) {
|
|
3878
|
+
return `sherwood-identity-link:${BINDING_VERSION}:${sherwoodEoa.toLowerCase()}:${issuingChainId}:${tokenId}`;
|
|
3879
|
+
}
|
|
3880
|
+
async function verifyBinding(params) {
|
|
3881
|
+
try {
|
|
3882
|
+
const recovered = await recoverMessageAddress({
|
|
3883
|
+
message: buildBindingMessage(params.sherwoodEoa, params.issuingChainId, params.tokenId),
|
|
3884
|
+
signature: params.signature
|
|
3885
|
+
});
|
|
3886
|
+
return recovered.toLowerCase() === params.virtualsWallet.toLowerCase();
|
|
3887
|
+
} catch {
|
|
3888
|
+
return false;
|
|
3889
|
+
}
|
|
3890
|
+
}
|
|
3891
|
+
var robinhoodChain = {
|
|
3892
|
+
id: 4663,
|
|
3893
|
+
name: "Robinhood Chain",
|
|
3894
|
+
nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
|
|
3895
|
+
rpcUrls: { default: { http: ["https://rpc.mainnet.chain.robinhood.com"] } },
|
|
3896
|
+
blockExplorers: {
|
|
3897
|
+
default: {
|
|
3898
|
+
name: "Robinhood Chain Explorer",
|
|
3899
|
+
url: "https://explorer.mainnet.chain.robinhood.com"
|
|
3900
|
+
}
|
|
3901
|
+
}
|
|
3902
|
+
};
|
|
3903
|
+
var DEFAULT_ISSUING_CHAIN_ID = robinhoodChain.id;
|
|
3904
|
+
var ISSUING_CHAINS = {
|
|
3905
|
+
[robinhoodChain.id]: {
|
|
3906
|
+
chain: robinhoodChain,
|
|
3907
|
+
identityRegistry: "0x8004A169FB4a3325136EB29fA0ceB6D2e539a432"
|
|
3908
|
+
},
|
|
3909
|
+
[base.id]: {
|
|
3910
|
+
chain: base,
|
|
3911
|
+
identityRegistry: "0x8004A169FB4a3325136EB29fA0ceB6D2e539a432"
|
|
3912
|
+
},
|
|
3913
|
+
[baseSepolia.id]: {
|
|
3914
|
+
chain: baseSepolia,
|
|
3915
|
+
identityRegistry: "0x8004A818BFB912233c491871b3d84c89A494BD9e"
|
|
3916
|
+
}
|
|
3917
|
+
};
|
|
3918
|
+
var OWNER_OF_ABI = [
|
|
3919
|
+
{
|
|
3920
|
+
name: "ownerOf",
|
|
3921
|
+
type: "function",
|
|
3922
|
+
stateMutability: "view",
|
|
3923
|
+
inputs: [{ name: "tokenId", type: "uint256" }],
|
|
3924
|
+
outputs: [{ name: "", type: "address" }]
|
|
3925
|
+
}
|
|
3926
|
+
];
|
|
3927
|
+
var ISSUING_RPC_ENV = {
|
|
3928
|
+
[robinhoodChain.id]: "ROBINHOOD_RPC_URL",
|
|
3929
|
+
[base.id]: "BASE_RPC_URL",
|
|
3930
|
+
[baseSepolia.id]: "BASE_SEPOLIA_RPC_URL"
|
|
3931
|
+
};
|
|
3932
|
+
async function ownerOfOnIssuingChain(issuingChainId, tokenId) {
|
|
3933
|
+
const issuing = ISSUING_CHAINS[issuingChainId];
|
|
3934
|
+
if (!issuing) {
|
|
3935
|
+
throw new Error(
|
|
3936
|
+
`Unsupported issuing chain ${issuingChainId}. Supported: ${Object.keys(ISSUING_CHAINS).join(", ")}`
|
|
3937
|
+
);
|
|
3938
|
+
}
|
|
3939
|
+
const rpcOverride = process.env[ISSUING_RPC_ENV[issuingChainId]];
|
|
3940
|
+
const client = createPublicClient({ chain: issuing.chain, transport: http(rpcOverride) });
|
|
3941
|
+
return client.readContract({
|
|
3942
|
+
address: issuing.identityRegistry,
|
|
3943
|
+
abi: OWNER_OF_ABI,
|
|
3944
|
+
functionName: "ownerOf",
|
|
3945
|
+
args: [tokenId]
|
|
3946
|
+
});
|
|
3947
|
+
}
|
|
3948
|
+
var VID_TAG_RE = /\s*\[vid:(v\d+):(\d+):(\d+):(0x[0-9a-fA-F]{40}):(self|0x[0-9a-fA-F]{130})\]\s*$/;
|
|
3949
|
+
function formatVidTag(tag) {
|
|
3950
|
+
return `[vid:${BINDING_VERSION}:${tag.issuingChainId}:${tag.tokenId}:${tag.wallet.toLowerCase()}:${tag.signature}]`;
|
|
3951
|
+
}
|
|
3952
|
+
function appendVidTag(message, tag) {
|
|
3953
|
+
return `${message} ${formatVidTag(tag)}`;
|
|
3954
|
+
}
|
|
3955
|
+
function parseVidTag(message) {
|
|
3956
|
+
if (message.indexOf("[vid:") !== message.lastIndexOf("[vid:")) return null;
|
|
3957
|
+
const match = message.match(VID_TAG_RE);
|
|
3958
|
+
if (!match) return null;
|
|
3959
|
+
if (!isAddress5(match[4])) return null;
|
|
3960
|
+
return {
|
|
3961
|
+
version: match[1],
|
|
3962
|
+
issuingChainId: parseInt(match[2], 10),
|
|
3963
|
+
tokenId: BigInt(match[3]),
|
|
3964
|
+
wallet: match[4],
|
|
3965
|
+
signature: match[5] === "self" ? "self" : match[5]
|
|
3966
|
+
};
|
|
3967
|
+
}
|
|
3968
|
+
function stripVidTag(message) {
|
|
3969
|
+
return message.replace(VID_TAG_RE, "");
|
|
3970
|
+
}
|
|
3971
|
+
async function verifyVidTag(tag, attester, ownerOf = ownerOfOnIssuingChain) {
|
|
3972
|
+
let bindingOk;
|
|
3973
|
+
if (tag.signature === "self") {
|
|
3974
|
+
bindingOk = attester.toLowerCase() === tag.wallet.toLowerCase();
|
|
3975
|
+
} else {
|
|
3976
|
+
bindingOk = await verifyBinding({
|
|
3977
|
+
sherwoodEoa: attester,
|
|
3978
|
+
issuingChainId: tag.issuingChainId,
|
|
3979
|
+
tokenId: tag.tokenId,
|
|
3980
|
+
virtualsWallet: tag.wallet,
|
|
3981
|
+
signature: tag.signature
|
|
3982
|
+
});
|
|
3983
|
+
}
|
|
3984
|
+
if (!bindingOk) {
|
|
3985
|
+
return { bindingOk: false, ownerOk: false, error: "binding failed \u2014 ownership check skipped" };
|
|
3986
|
+
}
|
|
3987
|
+
try {
|
|
3988
|
+
const owner = await ownerOf(tag.issuingChainId, tag.tokenId);
|
|
3989
|
+
return {
|
|
3990
|
+
bindingOk,
|
|
3991
|
+
ownerOk: owner.toLowerCase() === tag.wallet.toLowerCase(),
|
|
3992
|
+
owner
|
|
3993
|
+
};
|
|
3994
|
+
} catch (err) {
|
|
3995
|
+
return { bindingOk, ownerOk: false, error: err.message };
|
|
3996
|
+
}
|
|
3997
|
+
}
|
|
3998
|
+
function makeOwnerOfCache() {
|
|
3999
|
+
const cache = /* @__PURE__ */ new Map();
|
|
4000
|
+
return (chainId, tokenId) => {
|
|
4001
|
+
const key = `${chainId}:${tokenId}`;
|
|
4002
|
+
let p = cache.get(key);
|
|
4003
|
+
if (!p) {
|
|
4004
|
+
p = ownerOfOnIssuingChain(chainId, tokenId);
|
|
4005
|
+
p.catch(() => {
|
|
4006
|
+
});
|
|
4007
|
+
cache.set(key, p);
|
|
4008
|
+
}
|
|
4009
|
+
return p;
|
|
4010
|
+
};
|
|
4011
|
+
}
|
|
4012
|
+
async function acpJson(args) {
|
|
4013
|
+
try {
|
|
4014
|
+
const { stdout } = await execFileAsync("acp", [...args, "--json"], {
|
|
4015
|
+
timeout: 15e3
|
|
4016
|
+
});
|
|
4017
|
+
const start = stdout.indexOf("{");
|
|
4018
|
+
if (start < 0) return null;
|
|
4019
|
+
return JSON.parse(stdout.slice(start));
|
|
4020
|
+
} catch {
|
|
4021
|
+
return null;
|
|
4022
|
+
}
|
|
4023
|
+
}
|
|
4024
|
+
async function detectAcp() {
|
|
4025
|
+
try {
|
|
4026
|
+
await execFileAsync("acp", ["--version"], { timeout: 1e4 });
|
|
4027
|
+
return true;
|
|
4028
|
+
} catch {
|
|
4029
|
+
return false;
|
|
4030
|
+
}
|
|
4031
|
+
}
|
|
4032
|
+
async function acpWhoami() {
|
|
4033
|
+
const json = await acpJson(["agent", "whoami"]);
|
|
4034
|
+
if (!json) return null;
|
|
4035
|
+
const agentId = json.agentId ?? json.id ?? json.agent?.id;
|
|
4036
|
+
const name = json.name ?? json.agent?.name;
|
|
4037
|
+
return {
|
|
4038
|
+
agentId: agentId != null ? String(agentId) : void 0,
|
|
4039
|
+
name: name != null ? String(name) : void 0
|
|
4040
|
+
};
|
|
4041
|
+
}
|
|
4042
|
+
async function acpWalletAddress() {
|
|
4043
|
+
const json = await acpJson(["wallet", "address"]);
|
|
4044
|
+
if (!json) return null;
|
|
4045
|
+
for (const key of ["address", "evmAddress", "evm", "wallet"]) {
|
|
4046
|
+
const value = json[key];
|
|
4047
|
+
if (typeof value === "string" && isAddress5(value)) return value;
|
|
4048
|
+
}
|
|
4049
|
+
return null;
|
|
4050
|
+
}
|
|
4051
|
+
|
|
4052
|
+
// src/commands/identity.ts
|
|
3864
4053
|
var IDENTITY_REGISTRY_ABI2 = [
|
|
3865
4054
|
{
|
|
3866
4055
|
name: "balanceOf",
|
|
@@ -3976,6 +4165,123 @@ function registerIdentityCommands(program2) {
|
|
|
3976
4165
|
process.exit(1);
|
|
3977
4166
|
}
|
|
3978
4167
|
});
|
|
4168
|
+
identity.command("link-virtuals").description("Link a Virtuals economyOS agent identity (ERC-8004 on Base) to this Sherwood install").option("--wallet <address>", "economyOS agent wallet (default: auto-detect via `acp wallet address`)").option("--agent-id <tokenId>", "ERC-8004 token ID on the issuing chain (default: resolve via Agent0 SDK)").option("--chain-id <id>", "Issuing chain ID (4663 = Robinhood Chain, 8453 = Base, 84532 = Base Sepolia)", String(DEFAULT_ISSUING_CHAIN_ID)).option("--binding-sig <hex>", "EIP-191 signature of the binding message by the economyOS wallet").action(async (opts) => {
|
|
4169
|
+
const account = getAccount();
|
|
4170
|
+
const issuingChainId = parseInt(opts.chainId, 10);
|
|
4171
|
+
if (!ISSUING_CHAINS[issuingChainId]) {
|
|
4172
|
+
console.error(chalk4.red(`Unsupported issuing chain ${opts.chainId}. Supported: ${Object.keys(ISSUING_CHAINS).join(", ")}`));
|
|
4173
|
+
process.exit(1);
|
|
4174
|
+
}
|
|
4175
|
+
const spinner = ora4("Resolving economyOS agent...").start();
|
|
4176
|
+
try {
|
|
4177
|
+
let virtualsWallet = opts.wallet;
|
|
4178
|
+
let virtualsAgentId;
|
|
4179
|
+
if (await detectAcp()) {
|
|
4180
|
+
const who = await acpWhoami();
|
|
4181
|
+
virtualsAgentId = who?.agentId;
|
|
4182
|
+
if (!virtualsWallet) {
|
|
4183
|
+
virtualsWallet = await acpWalletAddress() ?? void 0;
|
|
4184
|
+
}
|
|
4185
|
+
}
|
|
4186
|
+
if (!virtualsWallet) {
|
|
4187
|
+
spinner.fail("Could not resolve the economyOS agent wallet");
|
|
4188
|
+
console.error(chalk4.dim(" Install + authenticate the acp CLI (npm i -g @virtuals-protocol/acp-cli; acp configure)"));
|
|
4189
|
+
console.error(chalk4.dim(" or pass --wallet <address> explicitly."));
|
|
4190
|
+
process.exit(1);
|
|
4191
|
+
}
|
|
4192
|
+
let tokenId;
|
|
4193
|
+
if (opts.agentId) {
|
|
4194
|
+
tokenId = BigInt(opts.agentId);
|
|
4195
|
+
} else {
|
|
4196
|
+
spinner.text = `Searching ERC-8004 registry on chain ${issuingChainId} for ${virtualsWallet}...`;
|
|
4197
|
+
const sdk = new SDK({
|
|
4198
|
+
chainId: issuingChainId,
|
|
4199
|
+
rpcUrl: ISSUING_CHAINS[issuingChainId].chain.rpcUrls.default.http[0],
|
|
4200
|
+
privateKey: generatePrivateKey()
|
|
4201
|
+
});
|
|
4202
|
+
const results = await sdk.searchAgents({
|
|
4203
|
+
walletAddress: virtualsWallet,
|
|
4204
|
+
chains: [issuingChainId]
|
|
4205
|
+
});
|
|
4206
|
+
if (results.length === 0) {
|
|
4207
|
+
spinner.fail(`No ERC-8004 registration found for ${virtualsWallet} on chain ${issuingChainId}`);
|
|
4208
|
+
console.error(chalk4.dim(" Register first via the Virtuals CLI:"));
|
|
4209
|
+
console.error(chalk4.dim(` acp agent register-erc8004 --agent-id ${virtualsAgentId ?? "<id>"} --chain-id ${issuingChainId}`));
|
|
4210
|
+
console.error(chalk4.dim(" Then re-run this command (or pass --agent-id <tokenId> directly)."));
|
|
4211
|
+
process.exit(1);
|
|
4212
|
+
}
|
|
4213
|
+
if (results.length > 1) {
|
|
4214
|
+
spinner.fail(`Wallet ${virtualsWallet} has ${results.length} ERC-8004 registrations on chain ${issuingChainId} \u2014 pick one explicitly`);
|
|
4215
|
+
for (const a of results) {
|
|
4216
|
+
const idStr2 = String(a.agentId);
|
|
4217
|
+
const tid = idStr2.includes(":") ? idStr2.split(":")[1] : idStr2;
|
|
4218
|
+
console.error(chalk4.dim(` #${tid} ${a.name || "(no name)"}`));
|
|
4219
|
+
}
|
|
4220
|
+
console.error(chalk4.green(" Re-run with: sherwood identity link-virtuals --agent-id <tokenId>"));
|
|
4221
|
+
process.exit(1);
|
|
4222
|
+
}
|
|
4223
|
+
const idStr = String(results[0].agentId);
|
|
4224
|
+
tokenId = BigInt(idStr.includes(":") ? idStr.split(":")[1] : idStr);
|
|
4225
|
+
}
|
|
4226
|
+
if (tokenId > BigInt(Number.MAX_SAFE_INTEGER)) {
|
|
4227
|
+
spinner.fail(`Token ID ${tokenId} exceeds Number.MAX_SAFE_INTEGER \u2014 cannot be stored in config`);
|
|
4228
|
+
process.exit(1);
|
|
4229
|
+
}
|
|
4230
|
+
spinner.text = `Verifying ownerOf(#${tokenId}) on chain ${issuingChainId}...`;
|
|
4231
|
+
const owner = await ownerOfOnIssuingChain(issuingChainId, tokenId);
|
|
4232
|
+
if (owner.toLowerCase() !== virtualsWallet.toLowerCase()) {
|
|
4233
|
+
spinner.fail(`Agent #${tokenId} on chain ${issuingChainId} is owned by ${owner}, not ${virtualsWallet}`);
|
|
4234
|
+
process.exit(1);
|
|
4235
|
+
}
|
|
4236
|
+
const self = virtualsWallet.toLowerCase() === account.address.toLowerCase();
|
|
4237
|
+
const bindingMessage = buildBindingMessage(account.address, issuingChainId, tokenId);
|
|
4238
|
+
let binding;
|
|
4239
|
+
if (!self) {
|
|
4240
|
+
if (!opts.bindingSig) {
|
|
4241
|
+
spinner.fail("Binding signature required (economyOS wallet differs from your Sherwood wallet)");
|
|
4242
|
+
console.error();
|
|
4243
|
+
console.error(chalk4.bold(" Sign this exact message with the economyOS agent wallet:"));
|
|
4244
|
+
console.error(chalk4.green(` ${bindingMessage}`));
|
|
4245
|
+
console.error();
|
|
4246
|
+
console.error(chalk4.dim(" (e.g. via the acp CLI / app.virtuals.io wallet signing, EIP-191 personal_sign)"));
|
|
4247
|
+
console.error(chalk4.dim(" Then re-run with --binding-sig <signature>."));
|
|
4248
|
+
process.exit(1);
|
|
4249
|
+
}
|
|
4250
|
+
spinner.text = "Verifying binding signature...";
|
|
4251
|
+
const ok = await verifyBinding({
|
|
4252
|
+
sherwoodEoa: account.address,
|
|
4253
|
+
issuingChainId,
|
|
4254
|
+
tokenId,
|
|
4255
|
+
virtualsWallet,
|
|
4256
|
+
signature: opts.bindingSig
|
|
4257
|
+
});
|
|
4258
|
+
if (!ok) {
|
|
4259
|
+
spinner.fail("Binding signature does not recover to the economyOS wallet");
|
|
4260
|
+
console.error(chalk4.dim(` Expected signer: ${virtualsWallet}`));
|
|
4261
|
+
console.error(chalk4.dim(` Signed message must be exactly: ${bindingMessage}`));
|
|
4262
|
+
process.exit(1);
|
|
4263
|
+
}
|
|
4264
|
+
binding = { sig: opts.bindingSig, message: bindingMessage };
|
|
4265
|
+
}
|
|
4266
|
+
setVirtualsIdentity(Number(tokenId), issuingChainId, {
|
|
4267
|
+
agentId: virtualsAgentId,
|
|
4268
|
+
wallet: virtualsWallet,
|
|
4269
|
+
binding
|
|
4270
|
+
});
|
|
4271
|
+
spinner.succeed(`Virtuals identity linked: agent #${tokenId} (chain ${issuingChainId})`);
|
|
4272
|
+
console.log(chalk4.dim(` economyOS wallet: ${virtualsWallet}`));
|
|
4273
|
+
if (virtualsAgentId) console.log(chalk4.dim(` Virtuals agent: ${virtualsAgentId}`));
|
|
4274
|
+
console.log(chalk4.dim(` Sherwood wallet: ${account.address}${self ? " (same as economyOS wallet \u2014 no binding needed)" : " (bound via signature)"}`));
|
|
4275
|
+
console.log(chalk4.dim(` Saved to ~/.sherwood/config.json`));
|
|
4276
|
+
console.log();
|
|
4277
|
+
console.log(chalk4.green("You can now create or join funds with this identity:"));
|
|
4278
|
+
console.log(chalk4.dim(` sherwood fund create --agent-id ${tokenId} --subdomain <name> --name <name>`));
|
|
4279
|
+
} catch (err) {
|
|
4280
|
+
spinner.fail("Failed to link Virtuals identity");
|
|
4281
|
+
console.error(chalk4.red(formatContractError(err)));
|
|
4282
|
+
process.exit(1);
|
|
4283
|
+
}
|
|
4284
|
+
});
|
|
3979
4285
|
identity.command("find").description("Search ERC-8004 agents by wallet address or name (recover a lost agent ID)").option("--wallet <address>", "Filter by owner / wallet address").option("--name <text>", "Filter by agent name (exact or substring match, depending on registry)").option("--all-chains", "Search across all chains, not just the active one").action(async (opts) => {
|
|
3980
4286
|
if (!opts.wallet && !opts.name) {
|
|
3981
4287
|
console.error(chalk4.red("Pass --wallet <address> or --name <text> (or both)."));
|
|
@@ -4022,6 +4328,47 @@ function registerIdentityCommands(program2) {
|
|
|
4022
4328
|
});
|
|
4023
4329
|
identity.command("status").description("Show your agent identity status").action(async () => {
|
|
4024
4330
|
const account = getAccount();
|
|
4331
|
+
if (getIdentityProvider() === "virtuals") {
|
|
4332
|
+
const virtuals = getVirtualsIdentity();
|
|
4333
|
+
const savedId = getAgentId();
|
|
4334
|
+
const issuingChainId = getIdentityChainId();
|
|
4335
|
+
console.log();
|
|
4336
|
+
console.log(chalk4.bold("Agent Identity (ERC-8004 via Virtuals economyOS)"));
|
|
4337
|
+
console.log(chalk4.dim("\u2500".repeat(40)));
|
|
4338
|
+
console.log(` Sherwood wallet: ${account.address}`);
|
|
4339
|
+
console.log(` economyOS wallet: ${virtuals?.wallet ?? chalk4.red("(missing)")}`);
|
|
4340
|
+
if (virtuals?.agentId) console.log(` Virtuals agent: ${virtuals.agentId}`);
|
|
4341
|
+
console.log(` Issuing chain: ${issuingChainId ?? chalk4.red("(missing)")}`);
|
|
4342
|
+
console.log(` Saved ID: ${savedId != null ? `#${savedId}` : chalk4.red("(missing)")}`);
|
|
4343
|
+
if (virtuals?.wallet && savedId != null && issuingChainId != null) {
|
|
4344
|
+
const spinner2 = ora4("Re-verifying link...").start();
|
|
4345
|
+
try {
|
|
4346
|
+
const owner = await ownerOfOnIssuingChain(issuingChainId, BigInt(savedId));
|
|
4347
|
+
const ownerOk = owner.toLowerCase() === virtuals.wallet.toLowerCase();
|
|
4348
|
+
let bindingOk = virtuals.wallet.toLowerCase() === account.address.toLowerCase();
|
|
4349
|
+
if (!bindingOk && virtuals.binding?.sig) {
|
|
4350
|
+
bindingOk = await verifyBinding({
|
|
4351
|
+
sherwoodEoa: account.address,
|
|
4352
|
+
issuingChainId,
|
|
4353
|
+
tokenId: BigInt(savedId),
|
|
4354
|
+
virtualsWallet: virtuals.wallet,
|
|
4355
|
+
signature: virtuals.binding.sig
|
|
4356
|
+
});
|
|
4357
|
+
}
|
|
4358
|
+
spinner2.stop();
|
|
4359
|
+
console.log(` NFT ownership: ${ownerOk ? chalk4.green("verified") : chalk4.red(`FAILED (owner is ${owner})`)}`);
|
|
4360
|
+
console.log(` Binding: ${bindingOk ? chalk4.green("verified") : chalk4.red("FAILED")}`);
|
|
4361
|
+
if (!ownerOk) {
|
|
4362
|
+
console.log(chalk4.yellow(" The NFT moved since linking \u2014 re-run 'sherwood identity link-virtuals'."));
|
|
4363
|
+
}
|
|
4364
|
+
} catch (err) {
|
|
4365
|
+
spinner2.warn("Could not re-verify against the issuing chain");
|
|
4366
|
+
console.log(chalk4.dim(` ${err.message}`));
|
|
4367
|
+
}
|
|
4368
|
+
}
|
|
4369
|
+
console.log();
|
|
4370
|
+
return;
|
|
4371
|
+
}
|
|
4025
4372
|
const registry = AGENT_REGISTRY().IDENTITY_REGISTRY;
|
|
4026
4373
|
const client = getPublicClient();
|
|
4027
4374
|
const spinner = ora4("Checking identity...").start();
|
|
@@ -4115,7 +4462,7 @@ function registerIdentityCommands(program2) {
|
|
|
4115
4462
|
}
|
|
4116
4463
|
|
|
4117
4464
|
// src/commands/proposal.ts
|
|
4118
|
-
import { isAddress as
|
|
4465
|
+
import { isAddress as isAddress6, encodeFunctionData as encodeFunctionData10 } from "viem";
|
|
4119
4466
|
import chalk6 from "chalk";
|
|
4120
4467
|
import ora5 from "ora";
|
|
4121
4468
|
import { readFileSync as readFileSync2 } from "fs";
|
|
@@ -4808,8 +5155,8 @@ function printSimulationResult(result, callType) {
|
|
|
4808
5155
|
}
|
|
4809
5156
|
async function sendSimulationAlert(subdomain, proposalId, vault, execResult, settleResult) {
|
|
4810
5157
|
try {
|
|
4811
|
-
const xmtp = await import("./xmtp-
|
|
4812
|
-
const { getAccount: getAccount2 } = await import("./client-
|
|
5158
|
+
const xmtp = await import("./xmtp-OZ5PJFCT.js");
|
|
5159
|
+
const { getAccount: getAccount2 } = await import("./client-GRPJRISD.js");
|
|
4813
5160
|
const group = await xmtp.getGroup("", subdomain);
|
|
4814
5161
|
const allRisks = [...execResult.risks, ...settleResult?.risks ?? []];
|
|
4815
5162
|
const criticals = allRisks.filter((r) => r.level === "critical");
|
|
@@ -4902,7 +5249,7 @@ function formatTimestamp(ts) {
|
|
|
4902
5249
|
}
|
|
4903
5250
|
function parseVaultOption(raw, spinner) {
|
|
4904
5251
|
const vault = String(raw);
|
|
4905
|
-
if (!
|
|
5252
|
+
if (!isAddress6(vault)) {
|
|
4906
5253
|
if (spinner) spinner.fail(`Invalid vault address: ${vault}`);
|
|
4907
5254
|
else console.error(chalk6.red(`Invalid vault address: ${vault}`));
|
|
4908
5255
|
process.exit(1);
|
|
@@ -4956,7 +5303,7 @@ function registerProposalCommands(program2) {
|
|
|
4956
5303
|
proposal.command("create").description("Submit a strategy proposal").requiredOption("--vault <address>", "Vault address the proposal targets").requiredOption("--name <name>", "Strategy name").requiredOption("--description <text>", "Strategy rationale and risk summary").requiredOption("--duration <duration>", "Strategy duration (e.g. 7d, 24h, 3600)").requiredOption("--execute-calls <path>", "Path to JSON file with execute Call[] array").requiredOption("--settle-calls <path>", "Path to JSON file with settlement Call[] array").option("--strategy <address>", "Live-NAV strategy clone address (default: none \u2014 queue-only)").option("--metadata-uri <uri>", "Override \u2014 skip IPFS upload and use this URI directly").option("--simulate", "Simulate calls via Tenderly before submitting").option("--force", "Submit even if simulation fails (requires --simulate)").action(async (opts) => {
|
|
4957
5304
|
try {
|
|
4958
5305
|
const vault = opts.vault;
|
|
4959
|
-
if (!
|
|
5306
|
+
if (!isAddress6(vault)) {
|
|
4960
5307
|
console.error(chalk6.red(`Invalid vault address: ${opts.vault}`));
|
|
4961
5308
|
process.exit(1);
|
|
4962
5309
|
}
|
|
@@ -4966,7 +5313,7 @@ function registerProposalCommands(program2) {
|
|
|
4966
5313
|
const ZERO_STRATEGY = "0x0000000000000000000000000000000000000000";
|
|
4967
5314
|
let strategy2 = ZERO_STRATEGY;
|
|
4968
5315
|
if (opts.strategy) {
|
|
4969
|
-
if (!
|
|
5316
|
+
if (!isAddress6(opts.strategy)) {
|
|
4970
5317
|
console.error(chalk6.red(`Invalid strategy address: ${opts.strategy}`));
|
|
4971
5318
|
process.exit(1);
|
|
4972
5319
|
}
|
|
@@ -5748,7 +6095,7 @@ function registerProposalCommands(program2) {
|
|
|
5748
6095
|
let riskContext = {};
|
|
5749
6096
|
let proposalId;
|
|
5750
6097
|
if (opts.id) {
|
|
5751
|
-
if (!opts.vault || !
|
|
6098
|
+
if (!opts.vault || !isAddress6(opts.vault)) {
|
|
5752
6099
|
console.error(chalk6.red("\n \u2716 --vault is required when using --id (proposal IDs are per-vault)"));
|
|
5753
6100
|
process.exit(1);
|
|
5754
6101
|
}
|
|
@@ -5772,7 +6119,7 @@ function registerProposalCommands(program2) {
|
|
|
5772
6119
|
console.log(DIM2(`
|
|
5773
6120
|
Simulating proposal #${proposalId} on vault ${vault.slice(0, 10)}...`));
|
|
5774
6121
|
} else if (opts.executeCalls) {
|
|
5775
|
-
if (!opts.vault || !
|
|
6122
|
+
if (!opts.vault || !isAddress6(opts.vault)) {
|
|
5776
6123
|
console.error(chalk6.red("\n \u2716 --vault is required when using --execute-calls"));
|
|
5777
6124
|
process.exit(1);
|
|
5778
6125
|
}
|
|
@@ -5815,7 +6162,7 @@ function registerProposalCommands(program2) {
|
|
|
5815
6162
|
}
|
|
5816
6163
|
|
|
5817
6164
|
// src/commands/queue.ts
|
|
5818
|
-
import { parseUnits as parseUnits5, formatUnits as formatUnits5, isAddress as
|
|
6165
|
+
import { parseUnits as parseUnits5, formatUnits as formatUnits5, isAddress as isAddress7, parseEventLogs } from "viem";
|
|
5819
6166
|
import chalk7 from "chalk";
|
|
5820
6167
|
import ora6 from "ora";
|
|
5821
6168
|
var WETH_ABI2 = [
|
|
@@ -5951,7 +6298,7 @@ var QUEUE_ABI = [
|
|
|
5951
6298
|
];
|
|
5952
6299
|
var KIND_LABELS = ["Redeem", "Deposit"];
|
|
5953
6300
|
function resolveVaultAddress(opt) {
|
|
5954
|
-
if (!opt || !
|
|
6301
|
+
if (!opt || !isAddress7(opt)) {
|
|
5955
6302
|
console.error(chalk7.red(`Invalid or missing --vault address: ${opt ?? "(none)"}`));
|
|
5956
6303
|
process.exit(1);
|
|
5957
6304
|
}
|
|
@@ -6204,7 +6551,7 @@ function registerQueueCommands(program2) {
|
|
|
6204
6551
|
// src/commands/governor.ts
|
|
6205
6552
|
import chalk8 from "chalk";
|
|
6206
6553
|
import ora7 from "ora";
|
|
6207
|
-
import { isAddress as
|
|
6554
|
+
import { isAddress as isAddress8 } from "viem";
|
|
6208
6555
|
var G3 = chalk8.green;
|
|
6209
6556
|
var W3 = chalk8.white;
|
|
6210
6557
|
var DIM3 = chalk8.gray;
|
|
@@ -6213,7 +6560,7 @@ var LABEL3 = chalk8.green.bold;
|
|
|
6213
6560
|
var SEP3 = () => console.log(DIM3("\u2500".repeat(60)));
|
|
6214
6561
|
function parseVaultArg(raw) {
|
|
6215
6562
|
const vault = String(raw);
|
|
6216
|
-
if (!
|
|
6563
|
+
if (!isAddress8(vault)) {
|
|
6217
6564
|
console.error(chalk8.red(`Invalid vault address: ${vault}`));
|
|
6218
6565
|
process.exit(1);
|
|
6219
6566
|
}
|
|
@@ -6388,7 +6735,7 @@ function registerGovernorCommands(program2) {
|
|
|
6388
6735
|
// src/commands/guardian-delegate.ts
|
|
6389
6736
|
import chalk9 from "chalk";
|
|
6390
6737
|
import ora8 from "ora";
|
|
6391
|
-
import { formatUnits as formatUnits6, isAddress as
|
|
6738
|
+
import { formatUnits as formatUnits6, isAddress as isAddress9, parseUnits as parseUnits6 } from "viem";
|
|
6392
6739
|
var G4 = chalk9.green;
|
|
6393
6740
|
var W4 = chalk9.white;
|
|
6394
6741
|
var DIM4 = chalk9.gray;
|
|
@@ -6470,7 +6817,7 @@ function registerGuardianCommands(program2) {
|
|
|
6470
6817
|
const pc = getPublicClient();
|
|
6471
6818
|
let target;
|
|
6472
6819
|
if (addressArg) {
|
|
6473
|
-
if (!
|
|
6820
|
+
if (!isAddress9(addressArg)) {
|
|
6474
6821
|
console.error(chalk9.red("Invalid address"));
|
|
6475
6822
|
process.exit(1);
|
|
6476
6823
|
}
|
|
@@ -6588,7 +6935,7 @@ function registerGuardianCommands(program2) {
|
|
|
6588
6935
|
}
|
|
6589
6936
|
});
|
|
6590
6937
|
guardian.command("delegate <delegate> <amount>").description("Delegate WOOD stake to a guardian. Amount in WOOD.").action(async (delegate, amountStr) => {
|
|
6591
|
-
if (!
|
|
6938
|
+
if (!isAddress9(delegate)) {
|
|
6592
6939
|
console.error(chalk9.red("Invalid delegate address"));
|
|
6593
6940
|
process.exit(1);
|
|
6594
6941
|
}
|
|
@@ -6612,7 +6959,7 @@ function registerGuardianCommands(program2) {
|
|
|
6612
6959
|
}
|
|
6613
6960
|
});
|
|
6614
6961
|
guardian.command("undelegate <delegate> <action>").description("Unstake-delegation flow: 'request' | 'cancel' | 'claim'").action(async (delegate, action) => {
|
|
6615
|
-
if (!
|
|
6962
|
+
if (!isAddress9(delegate)) {
|
|
6616
6963
|
console.error(chalk9.red("Invalid delegate address"));
|
|
6617
6964
|
process.exit(1);
|
|
6618
6965
|
}
|
|
@@ -8646,13 +8993,13 @@ import { join as join4 } from "path";
|
|
|
8646
8993
|
import { homedir as homedir4 } from "os";
|
|
8647
8994
|
import { createHash as createHash2 } from "crypto";
|
|
8648
8995
|
var DEFAULT_SWEEP_DIR = join4(homedir4(), ".sherwood", "grid", "sweeps");
|
|
8649
|
-
function expandSweep(sweep,
|
|
8996
|
+
function expandSweep(sweep, base2) {
|
|
8650
8997
|
const fields = ["leverage", "levelsPerSide", "atrMultiplier", "rebalanceDriftPct"];
|
|
8651
8998
|
const valueLists = {
|
|
8652
|
-
leverage: sweep.leverage && sweep.leverage.length > 0 ? sweep.leverage : [
|
|
8653
|
-
levelsPerSide: sweep.levelsPerSide && sweep.levelsPerSide.length > 0 ? sweep.levelsPerSide : [
|
|
8654
|
-
atrMultiplier: sweep.atrMultiplier && sweep.atrMultiplier.length > 0 ? sweep.atrMultiplier : [
|
|
8655
|
-
rebalanceDriftPct: sweep.rebalanceDriftPct && sweep.rebalanceDriftPct.length > 0 ? sweep.rebalanceDriftPct : [
|
|
8999
|
+
leverage: sweep.leverage && sweep.leverage.length > 0 ? sweep.leverage : [base2.leverage],
|
|
9000
|
+
levelsPerSide: sweep.levelsPerSide && sweep.levelsPerSide.length > 0 ? sweep.levelsPerSide : [base2.levelsPerSide],
|
|
9001
|
+
atrMultiplier: sweep.atrMultiplier && sweep.atrMultiplier.length > 0 ? sweep.atrMultiplier : [base2.atrMultiplier],
|
|
9002
|
+
rebalanceDriftPct: sweep.rebalanceDriftPct && sweep.rebalanceDriftPct.length > 0 ? sweep.rebalanceDriftPct : [base2.rebalanceDriftPct]
|
|
8656
9003
|
};
|
|
8657
9004
|
let combos = [{}];
|
|
8658
9005
|
for (const field of fields) {
|
|
@@ -8691,13 +9038,13 @@ async function runSweep(opts) {
|
|
|
8691
9038
|
tokenSplit = {};
|
|
8692
9039
|
for (const t of opts.tokens) tokenSplit[t] = weight;
|
|
8693
9040
|
}
|
|
8694
|
-
const
|
|
9041
|
+
const base2 = {
|
|
8695
9042
|
...DEFAULT_GRID_CONFIG,
|
|
8696
9043
|
...opts.baseConfig,
|
|
8697
9044
|
tokens: opts.tokens,
|
|
8698
9045
|
tokenSplit
|
|
8699
9046
|
};
|
|
8700
|
-
const combos = expandSweep(opts.sweep,
|
|
9047
|
+
const combos = expandSweep(opts.sweep, base2);
|
|
8701
9048
|
if (combos.length === 0) throw new Error("sweep produced no combinations");
|
|
8702
9049
|
const loader = new HistoricalDataLoader({ noCache: opts.noCache });
|
|
8703
9050
|
if (opts.verbose !== false) {
|
|
@@ -8708,7 +9055,7 @@ async function runSweep(opts) {
|
|
|
8708
9055
|
const runs = [];
|
|
8709
9056
|
for (let i = 0; i < combos.length; i++) {
|
|
8710
9057
|
const combo = combos[i];
|
|
8711
|
-
const config = { ...
|
|
9058
|
+
const config = { ...base2, ...combo };
|
|
8712
9059
|
const runOutPath = join4(sweepDir, `run-${i.toString().padStart(3, "0")}.json`);
|
|
8713
9060
|
if (opts.verbose !== false) {
|
|
8714
9061
|
process.stderr.write(` [sweep] [${i + 1}/${combos.length}] ${JSON.stringify(combo)}
|
|
@@ -9246,9 +9593,9 @@ try {
|
|
|
9246
9593
|
} catch {
|
|
9247
9594
|
}
|
|
9248
9595
|
var require2 = createRequire(import.meta.url);
|
|
9249
|
-
var CLI_VERSION = "0.
|
|
9596
|
+
var CLI_VERSION = "0.76.0";
|
|
9250
9597
|
async function loadXmtp() {
|
|
9251
|
-
return import("./xmtp-
|
|
9598
|
+
return import("./xmtp-OZ5PJFCT.js");
|
|
9252
9599
|
}
|
|
9253
9600
|
async function loadCron() {
|
|
9254
9601
|
return import("./cron-QMLRWDJG.js");
|
|
@@ -9260,7 +9607,7 @@ var BOLD6 = chalk16.white.bold;
|
|
|
9260
9607
|
var LABEL5 = chalk16.green.bold;
|
|
9261
9608
|
var SEP6 = () => console.log(DIM6("\u2500".repeat(60)));
|
|
9262
9609
|
function validateAddress(value, name) {
|
|
9263
|
-
if (!
|
|
9610
|
+
if (!isAddress10(value)) {
|
|
9264
9611
|
console.error(chalk16.red(`Invalid ${name} address: ${value}`));
|
|
9265
9612
|
process.exit(1);
|
|
9266
9613
|
}
|
|
@@ -9849,7 +10196,7 @@ fund.command("add").description("Register an agent on a fund vault (creator only
|
|
|
9849
10196
|
if (opts.agentId) {
|
|
9850
10197
|
agentId = BigInt(opts.agentId);
|
|
9851
10198
|
} else {
|
|
9852
|
-
const { AGENT_REGISTRY: AGENT_REGISTRY2 } = await import("./addresses-
|
|
10199
|
+
const { AGENT_REGISTRY: AGENT_REGISTRY2 } = await import("./addresses-JJPQTF6S.js");
|
|
9853
10200
|
const registry = AGENT_REGISTRY2().IDENTITY_REGISTRY;
|
|
9854
10201
|
if (registry === "0x0000000000000000000000000000000000000000") {
|
|
9855
10202
|
agentId = 0n;
|
|
@@ -9982,6 +10329,16 @@ fund.command("join").description("Request to join a fund (creates an EAS attesta
|
|
|
9982
10329
|
}
|
|
9983
10330
|
process.exit(1);
|
|
9984
10331
|
}
|
|
10332
|
+
let joinMessage = opts.message;
|
|
10333
|
+
const virtualsIdentity = getVirtualsIdentity();
|
|
10334
|
+
if (getIdentityProvider() === "virtuals" && virtualsIdentity) {
|
|
10335
|
+
joinMessage = appendVidTag(joinMessage, {
|
|
10336
|
+
issuingChainId: getIdentityChainId() ?? DEFAULT_ISSUING_CHAIN_ID,
|
|
10337
|
+
tokenId: BigInt(agentId),
|
|
10338
|
+
wallet: virtualsIdentity.wallet,
|
|
10339
|
+
signature: virtualsIdentity.binding?.sig ?? "self"
|
|
10340
|
+
});
|
|
10341
|
+
}
|
|
9985
10342
|
if (isCalldataOnly()) {
|
|
9986
10343
|
const referrerAgentId2 = opts.ref ? parseInt(opts.ref, 10) : void 0;
|
|
9987
10344
|
spinner.stop();
|
|
@@ -9992,7 +10349,7 @@ fund.command("join").description("Request to join a fund (creates an EAS attesta
|
|
|
9992
10349
|
agentId: BigInt(agentId),
|
|
9993
10350
|
vault: fund2.vault,
|
|
9994
10351
|
creator: fund2.creator,
|
|
9995
|
-
message:
|
|
10352
|
+
message: joinMessage,
|
|
9996
10353
|
referrerAgentId: referrerAgentId2
|
|
9997
10354
|
},
|
|
9998
10355
|
getChain().id
|
|
@@ -10050,7 +10407,7 @@ fund.command("join").description("Request to join a fund (creates an EAS attesta
|
|
|
10050
10407
|
BigInt(agentId),
|
|
10051
10408
|
fund2.vault,
|
|
10052
10409
|
fund2.creator,
|
|
10053
|
-
|
|
10410
|
+
joinMessage,
|
|
10054
10411
|
referrerAgentId
|
|
10055
10412
|
);
|
|
10056
10413
|
try {
|
|
@@ -10137,16 +10494,26 @@ fund.command("requests").description("View pending join requests for a fund (cre
|
|
|
10137
10494
|
console.log();
|
|
10138
10495
|
console.log(LABEL5(` \u25C6 Pending Join Requests (${requests.length})`));
|
|
10139
10496
|
SEP6();
|
|
10497
|
+
const ownerOfCached = makeOwnerOfCache();
|
|
10140
10498
|
for (let i = 0; i < requests.length; i++) {
|
|
10141
10499
|
const req = requests[i];
|
|
10142
10500
|
const date = new Date(req.time * 1e3).toLocaleString();
|
|
10143
10501
|
const referrer = parseReferrer(req.decoded.message);
|
|
10144
|
-
const
|
|
10502
|
+
const vid = parseVidTag(req.decoded.message);
|
|
10503
|
+
const cleanMessage = stripReferrerPrefix(stripVidTag(req.decoded.message));
|
|
10145
10504
|
console.log(W6(` ${i + 1}. Agent #${req.decoded.agentId} ${DIM6(`(${req.attester})`)}`));
|
|
10146
10505
|
console.log(DIM6(` Message: "${cleanMessage}"`));
|
|
10147
10506
|
if (referrer !== null) {
|
|
10148
10507
|
console.log(G6(` Referred by: Agent #${referrer}`));
|
|
10149
10508
|
}
|
|
10509
|
+
if (vid) {
|
|
10510
|
+
const v = await verifyVidTag(vid, req.attester, ownerOfCached);
|
|
10511
|
+
const verified = v.bindingOk && v.ownerOk;
|
|
10512
|
+
const badge = verified ? G6("\u2714 verified") : chalk16.red("\u2718 FAILED");
|
|
10513
|
+
console.log(W6(` Virtuals: ${badge} ${DIM6(`(agent #${vid.tokenId} on chain ${vid.issuingChainId}, wallet ${vid.wallet})`)}`));
|
|
10514
|
+
if (!v.bindingOk) console.log(chalk16.red(` binding signature invalid \u2014 do not approve based on this identity`));
|
|
10515
|
+
else if (!v.ownerOk) console.log(chalk16.red(` NFT ownership check failed${v.owner ? ` (owner is ${v.owner})` : v.error ? ` (${v.error})` : ""}`));
|
|
10516
|
+
}
|
|
10150
10517
|
console.log(DIM6(` Requested: ${date}`));
|
|
10151
10518
|
console.log(DIM6(` Attestation: ${req.uid}`));
|
|
10152
10519
|
console.log();
|
|
@@ -10542,7 +10909,7 @@ vaultCmd.command("redeem").description("Redeem vault shares for the underlying a
|
|
|
10542
10909
|
`));
|
|
10543
10910
|
process.exit(1);
|
|
10544
10911
|
}
|
|
10545
|
-
if (opts.receiver && !
|
|
10912
|
+
if (opts.receiver && !isAddress10(opts.receiver)) {
|
|
10546
10913
|
console.error(chalk16.red(`
|
|
10547
10914
|
\u2716 Invalid receiver address: ${opts.receiver}
|
|
10548
10915
|
`));
|
|
@@ -10575,7 +10942,7 @@ vaultCmd.command("redeem").description("Redeem vault shares for the underlying a
|
|
|
10575
10942
|
var strategy = program.command("strategy").description("Strategy templates \u2014 list, clone, propose");
|
|
10576
10943
|
registerStrategyTemplateCommands(strategy);
|
|
10577
10944
|
program.command("providers").description("List available providers (research + swap routing)").action(async () => {
|
|
10578
|
-
const { listProviders } = await import("./providers-
|
|
10945
|
+
const { listProviders } = await import("./providers-2J6LL67W.js");
|
|
10579
10946
|
for (const info of listProviders()) {
|
|
10580
10947
|
console.log(`
|
|
10581
10948
|
${info.name} (${info.type})`);
|
|
@@ -10585,7 +10952,7 @@ ${info.name} (${info.type})`);
|
|
|
10585
10952
|
}
|
|
10586
10953
|
});
|
|
10587
10954
|
try {
|
|
10588
|
-
const { registerChatCommands } = await import("./chat-
|
|
10955
|
+
const { registerChatCommands } = await import("./chat-CO244AHH.js");
|
|
10589
10956
|
registerChatCommands(program);
|
|
10590
10957
|
} catch {
|
|
10591
10958
|
program.command("chat <name> [action] [actionArgs...]").description("Fund chat (XMTP) \u2014 requires @xmtp/cli").action(() => {
|
|
@@ -10595,7 +10962,7 @@ try {
|
|
|
10595
10962
|
process.exit(1);
|
|
10596
10963
|
});
|
|
10597
10964
|
}
|
|
10598
|
-
var { registerSessionCommands } = await import("./session-
|
|
10965
|
+
var { registerSessionCommands } = await import("./session-JQ3IF3IV.js");
|
|
10599
10966
|
registerSessionCommands(program);
|
|
10600
10967
|
registerVeniceCommands(program);
|
|
10601
10968
|
registerAllowanceCommands(program);
|
|
@@ -10604,11 +10971,11 @@ registerProposalCommands(program);
|
|
|
10604
10971
|
registerQueueCommands(program);
|
|
10605
10972
|
registerGovernorCommands(program);
|
|
10606
10973
|
registerGuardianCommands(program);
|
|
10607
|
-
var { registerResearchCommands } = await import("./research-
|
|
10974
|
+
var { registerResearchCommands } = await import("./research-FHQCSLTZ.js");
|
|
10608
10975
|
registerResearchCommands(program);
|
|
10609
|
-
var { registerAgentCommands } = await import("./agent-
|
|
10976
|
+
var { registerAgentCommands } = await import("./agent-FYRYTKYM.js");
|
|
10610
10977
|
registerAgentCommands(program);
|
|
10611
|
-
var { registerTradeCommands } = await import("./trade-
|
|
10978
|
+
var { registerTradeCommands } = await import("./trade-5EYPZN7M.js");
|
|
10612
10979
|
registerTradeCommands(program);
|
|
10613
10980
|
registerGridCommand(program);
|
|
10614
10981
|
var configCmd = program.command("config");
|