@sherwoodagent/cli 0.72.0 → 0.72.3
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-HJDYFLWZ.js → addresses-YDPUPGWQ.js} +3 -3
- package/dist/{agent-6OJKQVEG.js → agent-6IRZUPFT.js} +6 -6
- package/dist/{chat-2DKD3QPA.js → chat-G5M3OK6M.js} +8 -8
- package/dist/{chunk-6SRIVGAV.js → chunk-3NMJ4LUL.js} +4 -4
- package/dist/{chunk-OZLX666C.js → chunk-52U76TRE.js} +2 -2
- package/dist/{chunk-SVSJNZ5D.js → chunk-D4SPHYXA.js} +4 -4
- package/dist/{chunk-ASF2WTSW.js → chunk-FOAX5PGR.js} +4 -4
- package/dist/{chunk-GT3KCKF6.js → chunk-FOS47623.js} +9 -6
- package/dist/chunk-FOS47623.js.map +1 -0
- package/dist/{chunk-RNASYOQT.js → chunk-HYUUR6SC.js} +2 -2
- package/dist/chunk-HYUUR6SC.js.map +1 -0
- package/dist/{chunk-ITZT5HD4.js → chunk-NWY2U753.js} +2 -2
- package/dist/{chunk-YLYANZMC.js → chunk-RAITRCM7.js} +2 -2
- package/dist/{chunk-PDUGL4EY.js → chunk-S6XA7PK4.js} +22 -4
- package/dist/chunk-S6XA7PK4.js.map +1 -0
- package/dist/{chunk-3YUMQGJD.js → chunk-UUHWD7Y3.js} +4 -4
- package/dist/{chunk-UC5RMCB3.js → chunk-WECQ6NVS.js} +2 -2
- package/dist/{client-K4JCNPVV.js → client-QN6SA76M.js} +3 -3
- package/dist/{eas-ZXGUNYC5.js → eas-HM2AUOEY.js} +5 -5
- package/dist/{governor-CV5PITE3.js → governor-RRBTDGDX.js} +9 -5
- package/dist/index.js +101 -42
- package/dist/index.js.map +1 -1
- package/dist/{network-DHWEYXP2.js → network-L6JKNYOJ.js} +2 -2
- package/dist/{price-GOX6P4NT.js → price-AJ4JMHCT.js} +4 -4
- package/dist/{research-6D7NNJX4.js → research-6VEEPEPP.js} +7 -7
- package/dist/{research-EFNVHU7G.js → research-7Z6SFPPX.js} +4 -4
- package/dist/{session-LDLW66K3.js → session-PURMITWE.js} +9 -9
- package/dist/{trade-7NNZXP5B.js → trade-YTGLGCRQ.js} +14 -14
- package/dist/{vault-SIL4QL5U.js → vault-NIPA5JV4.js} +5 -5
- package/dist/{xmtp-QNOVDLXX.js → xmtp-M32JSE4I.js} +6 -6
- package/package.json +1 -1
- package/dist/chunk-GT3KCKF6.js.map +0 -1
- package/dist/chunk-PDUGL4EY.js.map +0 -1
- package/dist/chunk-RNASYOQT.js.map +0 -1
- /package/dist/{addresses-HJDYFLWZ.js.map → addresses-YDPUPGWQ.js.map} +0 -0
- /package/dist/{agent-6OJKQVEG.js.map → agent-6IRZUPFT.js.map} +0 -0
- /package/dist/{chat-2DKD3QPA.js.map → chat-G5M3OK6M.js.map} +0 -0
- /package/dist/{chunk-6SRIVGAV.js.map → chunk-3NMJ4LUL.js.map} +0 -0
- /package/dist/{chunk-OZLX666C.js.map → chunk-52U76TRE.js.map} +0 -0
- /package/dist/{chunk-SVSJNZ5D.js.map → chunk-D4SPHYXA.js.map} +0 -0
- /package/dist/{chunk-ASF2WTSW.js.map → chunk-FOAX5PGR.js.map} +0 -0
- /package/dist/{chunk-ITZT5HD4.js.map → chunk-NWY2U753.js.map} +0 -0
- /package/dist/{chunk-YLYANZMC.js.map → chunk-RAITRCM7.js.map} +0 -0
- /package/dist/{chunk-3YUMQGJD.js.map → chunk-UUHWD7Y3.js.map} +0 -0
- /package/dist/{chunk-UC5RMCB3.js.map → chunk-WECQ6NVS.js.map} +0 -0
- /package/dist/{client-K4JCNPVV.js.map → client-QN6SA76M.js.map} +0 -0
- /package/dist/{eas-ZXGUNYC5.js.map → eas-HM2AUOEY.js.map} +0 -0
- /package/dist/{governor-CV5PITE3.js.map → governor-RRBTDGDX.js.map} +0 -0
- /package/dist/{network-DHWEYXP2.js.map → network-L6JKNYOJ.js.map} +0 -0
- /package/dist/{price-GOX6P4NT.js.map → price-AJ4JMHCT.js.map} +0 -0
- /package/dist/{research-6D7NNJX4.js.map → research-6VEEPEPP.js.map} +0 -0
- /package/dist/{research-EFNVHU7G.js.map → research-7Z6SFPPX.js.map} +0 -0
- /package/dist/{session-LDLW66K3.js.map → session-PURMITWE.js.map} +0 -0
- /package/dist/{trade-7NNZXP5B.js.map → trade-YTGLGCRQ.js.map} +0 -0
- /package/dist/{vault-SIL4QL5U.js.map → vault-NIPA5JV4.js.map} +0 -0
- /package/dist/{xmtp-QNOVDLXX.js.map → xmtp-M32JSE4I.js.map} +0 -0
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
robinhoodTestnet,
|
|
14
14
|
setNetwork,
|
|
15
15
|
withNetwork
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-HYUUR6SC.js";
|
|
17
17
|
import "./chunk-GSC7PVEO.js";
|
|
18
18
|
export {
|
|
19
19
|
CHAIN_REGISTRY,
|
|
@@ -31,4 +31,4 @@ export {
|
|
|
31
31
|
setNetwork,
|
|
32
32
|
withNetwork
|
|
33
33
|
};
|
|
34
|
-
//# sourceMappingURL=network-
|
|
34
|
+
//# sourceMappingURL=network-L6JKNYOJ.js.map
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
SYNTHRA,
|
|
3
3
|
UNISWAP
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-RAITRCM7.js";
|
|
5
5
|
import {
|
|
6
6
|
getPublicClient
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-WECQ6NVS.js";
|
|
8
8
|
import {
|
|
9
9
|
getNetwork
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-HYUUR6SC.js";
|
|
11
11
|
import "./chunk-GSC7PVEO.js";
|
|
12
12
|
import {
|
|
13
13
|
UNISWAP_QUOTER_V2_ABI
|
|
@@ -155,4 +155,4 @@ export {
|
|
|
155
155
|
getTokenPriceInAsset,
|
|
156
156
|
getTokenPricesInAsset
|
|
157
157
|
};
|
|
158
|
-
//# sourceMappingURL=price-
|
|
158
|
+
//# sourceMappingURL=price-AJ4JMHCT.js.map
|
|
@@ -2,12 +2,12 @@ import {
|
|
|
2
2
|
MESSARI_COST_ESTIMATE,
|
|
3
3
|
NANSEN_COST_ESTIMATE,
|
|
4
4
|
getResearchProvider
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-NWY2U753.js";
|
|
6
6
|
import {
|
|
7
7
|
formatContractError,
|
|
8
8
|
getAccount
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import "./chunk-
|
|
9
|
+
} from "./chunk-WECQ6NVS.js";
|
|
10
|
+
import "./chunk-HYUUR6SC.js";
|
|
11
11
|
import "./chunk-GSC7PVEO.js";
|
|
12
12
|
|
|
13
13
|
// src/commands/research.ts
|
|
@@ -16,7 +16,7 @@ import ora from "ora";
|
|
|
16
16
|
import { confirm } from "@inquirer/prompts";
|
|
17
17
|
import { isAddress } from "viem";
|
|
18
18
|
async function loadXmtp() {
|
|
19
|
-
return import("./xmtp-
|
|
19
|
+
return import("./xmtp-M32JSE4I.js");
|
|
20
20
|
}
|
|
21
21
|
var COST_ESTIMATES = {
|
|
22
22
|
messari: MESSARI_COST_ESTIMATE,
|
|
@@ -83,7 +83,7 @@ function formatValue(value) {
|
|
|
83
83
|
}
|
|
84
84
|
async function postResearch(fundName, result, prompt) {
|
|
85
85
|
const { pinJSON } = await import("./ipfs-VGWTUORE.js");
|
|
86
|
-
const { createResearchAttestation, getEasScanUrl } = await import("./eas-
|
|
86
|
+
const { createResearchAttestation, getEasScanUrl } = await import("./eas-HM2AUOEY.js");
|
|
87
87
|
const xmtp = await loadXmtp();
|
|
88
88
|
const pinSpinner = ora("Pinning research result to IPFS...").start();
|
|
89
89
|
let resultUri;
|
|
@@ -113,7 +113,7 @@ async function postResearch(fundName, result, prompt) {
|
|
|
113
113
|
let attestationUid;
|
|
114
114
|
try {
|
|
115
115
|
const { getChainContracts } = await import("./config-FAQO37S7.js");
|
|
116
|
-
const { getChain } = await import("./network-
|
|
116
|
+
const { getChain } = await import("./network-L6JKNYOJ.js");
|
|
117
117
|
const vaultRecipient = getChainContracts(getChain().id).vault;
|
|
118
118
|
const { uid } = await createResearchAttestation(
|
|
119
119
|
result.provider,
|
|
@@ -312,4 +312,4 @@ function registerResearchCommands(program) {
|
|
|
312
312
|
export {
|
|
313
313
|
registerResearchCommands
|
|
314
314
|
};
|
|
315
|
-
//# sourceMappingURL=research-
|
|
315
|
+
//# sourceMappingURL=research-6VEEPEPP.js.map
|
|
@@ -2,13 +2,13 @@ import {
|
|
|
2
2
|
MessariProvider,
|
|
3
3
|
NansenProvider,
|
|
4
4
|
getResearchProvider
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
7
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-NWY2U753.js";
|
|
6
|
+
import "./chunk-WECQ6NVS.js";
|
|
7
|
+
import "./chunk-HYUUR6SC.js";
|
|
8
8
|
import "./chunk-GSC7PVEO.js";
|
|
9
9
|
export {
|
|
10
10
|
MessariProvider,
|
|
11
11
|
NansenProvider,
|
|
12
12
|
getResearchProvider
|
|
13
13
|
};
|
|
14
|
-
//# sourceMappingURL=research-
|
|
14
|
+
//# sourceMappingURL=research-7Z6SFPPX.js.map
|
|
@@ -6,18 +6,18 @@ import {
|
|
|
6
6
|
} from "./chunk-5DWB5Y7G.js";
|
|
7
7
|
import {
|
|
8
8
|
resolveFund
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import "./chunk-
|
|
9
|
+
} from "./chunk-FOS47623.js";
|
|
10
|
+
import "./chunk-UUHWD7Y3.js";
|
|
11
11
|
import {
|
|
12
12
|
PROPOSAL_STATES,
|
|
13
13
|
getGovernorOf,
|
|
14
14
|
getProposal
|
|
15
|
-
} from "./chunk-
|
|
16
|
-
import "./chunk-
|
|
15
|
+
} from "./chunk-S6XA7PK4.js";
|
|
16
|
+
import "./chunk-RAITRCM7.js";
|
|
17
17
|
import {
|
|
18
18
|
getPublicClient
|
|
19
|
-
} from "./chunk-
|
|
20
|
-
import "./chunk-
|
|
19
|
+
} from "./chunk-WECQ6NVS.js";
|
|
20
|
+
import "./chunk-HYUUR6SC.js";
|
|
21
21
|
import {
|
|
22
22
|
loadConfig
|
|
23
23
|
} from "./chunk-GSC7PVEO.js";
|
|
@@ -187,7 +187,7 @@ async function enrichProposalEvents(vault, events, metadataCache) {
|
|
|
187
187
|
|
|
188
188
|
// src/commands/session.ts
|
|
189
189
|
async function loadXmtp() {
|
|
190
|
-
return import("./xmtp-
|
|
190
|
+
return import("./xmtp-M32JSE4I.js");
|
|
191
191
|
}
|
|
192
192
|
async function resolveGovernor(vaultAddress) {
|
|
193
193
|
const client = getPublicClient();
|
|
@@ -435,7 +435,7 @@ function registerSessionCommands(program) {
|
|
|
435
435
|
);
|
|
436
436
|
session.command("cron <name>").description("Manage participation crons (OpenClaw agents)").option("--remove", "Remove participation crons", false).option("--status", "Show cron status", false).action(async (name, opts) => {
|
|
437
437
|
const { isOpenClaw, registerFundCrons, unregisterFundCrons, getFundCronStatus } = await import("./cron-QMLRWDJG.js");
|
|
438
|
-
const { isTestnet } = await import("./network-
|
|
438
|
+
const { isTestnet } = await import("./network-L6JKNYOJ.js");
|
|
439
439
|
const { getNotifyTo } = await import("./config-FAQO37S7.js");
|
|
440
440
|
if (!isOpenClaw()) {
|
|
441
441
|
console.log(chalk.yellow("Not running on OpenClaw \u2014 cron commands unavailable"));
|
|
@@ -477,4 +477,4 @@ function registerSessionCommands(program) {
|
|
|
477
477
|
export {
|
|
478
478
|
registerSessionCommands
|
|
479
479
|
};
|
|
480
|
-
//# sourceMappingURL=session-
|
|
480
|
+
//# sourceMappingURL=session-PURMITWE.js.map
|
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getResearchProvider
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-NWY2U753.js";
|
|
4
4
|
import {
|
|
5
5
|
UniswapProvider,
|
|
6
6
|
getQuote
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-D4SPHYXA.js";
|
|
8
8
|
import {
|
|
9
9
|
chatCompletion
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-52U76TRE.js";
|
|
11
11
|
import {
|
|
12
12
|
TOKENS
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-RAITRCM7.js";
|
|
14
14
|
import {
|
|
15
15
|
formatContractError,
|
|
16
16
|
getAccount,
|
|
17
17
|
getPublicClient
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-WECQ6NVS.js";
|
|
19
19
|
import {
|
|
20
20
|
getExplorerUrl
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-HYUUR6SC.js";
|
|
22
22
|
import {
|
|
23
23
|
loadConfig,
|
|
24
24
|
saveConfig
|
|
@@ -334,7 +334,7 @@ async function getCurrentPrice(tokenAddress, tokenDecimals, feeTier) {
|
|
|
334
334
|
// src/commands/trade.ts
|
|
335
335
|
var uniswap = new UniswapProvider();
|
|
336
336
|
async function loadXmtp() {
|
|
337
|
-
return import("./xmtp-
|
|
337
|
+
return import("./xmtp-M32JSE4I.js");
|
|
338
338
|
}
|
|
339
339
|
var ETH_ADDRESS = "0x0000000000000000000000000000000000000000";
|
|
340
340
|
var KNOWN_MEMECOINS = {
|
|
@@ -518,7 +518,7 @@ function registerTradeCommands(program) {
|
|
|
518
518
|
}
|
|
519
519
|
const wrapSpinner = ora("Wrapping ETH \u2192 WETH...").start();
|
|
520
520
|
try {
|
|
521
|
-
const { writeContractWithRetry, waitForReceipt: waitForReceiptFn } = await import("./client-
|
|
521
|
+
const { writeContractWithRetry, waitForReceipt: waitForReceiptFn } = await import("./client-QN6SA76M.js");
|
|
522
522
|
const wethAddr = TOKENS().WETH;
|
|
523
523
|
const wrapHash = await writeContractWithRetry({
|
|
524
524
|
address: wethAddr,
|
|
@@ -527,7 +527,7 @@ function registerTradeCommands(program) {
|
|
|
527
527
|
args: [],
|
|
528
528
|
value: inputAmount,
|
|
529
529
|
account,
|
|
530
|
-
chain: (await import("./network-
|
|
530
|
+
chain: (await import("./network-L6JKNYOJ.js")).getChain()
|
|
531
531
|
});
|
|
532
532
|
await waitForReceiptFn(wrapHash);
|
|
533
533
|
wrapSpinner.succeed(`Wrapped ${opts.amount} ETH \u2192 WETH`);
|
|
@@ -641,9 +641,9 @@ function registerTradeCommands(program) {
|
|
|
641
641
|
}
|
|
642
642
|
console.log(` Tx: ${chalk.dim(getExplorerUrl(txHash))}`);
|
|
643
643
|
try {
|
|
644
|
-
const { createTradeAttestation, getEasScanUrl } = await import("./eas-
|
|
644
|
+
const { createTradeAttestation, getEasScanUrl } = await import("./eas-HM2AUOEY.js");
|
|
645
645
|
const { getChainContracts } = await import("./config-FAQO37S7.js");
|
|
646
|
-
const { getChain: getActiveChain } = await import("./network-
|
|
646
|
+
const { getChain: getActiveChain } = await import("./network-L6JKNYOJ.js");
|
|
647
647
|
const vaultRecipient = getChainContracts(getActiveChain().id).vault;
|
|
648
648
|
const { uid } = await createTradeAttestation(
|
|
649
649
|
inputAddr,
|
|
@@ -769,9 +769,9 @@ function registerTradeCommands(program) {
|
|
|
769
769
|
}
|
|
770
770
|
console.log(` Tx: ${chalk.dim(getExplorerUrl(txHash))}`);
|
|
771
771
|
try {
|
|
772
|
-
const { createTradeAttestation, getEasScanUrl } = await import("./eas-
|
|
772
|
+
const { createTradeAttestation, getEasScanUrl } = await import("./eas-HM2AUOEY.js");
|
|
773
773
|
const { getChainContracts } = await import("./config-FAQO37S7.js");
|
|
774
|
-
const { getChain: getActiveChain } = await import("./network-
|
|
774
|
+
const { getChain: getActiveChain } = await import("./network-L6JKNYOJ.js");
|
|
775
775
|
const vaultRecipient = getChainContracts(getActiveChain().id).vault;
|
|
776
776
|
const { uid } = await createTradeAttestation(
|
|
777
777
|
tokenAddr,
|
|
@@ -946,4 +946,4 @@ function sleep(ms) {
|
|
|
946
946
|
export {
|
|
947
947
|
registerTradeCommands
|
|
948
948
|
};
|
|
949
|
-
//# sourceMappingURL=trade-
|
|
949
|
+
//# sourceMappingURL=trade-YTGLGCRQ.js.map
|
|
@@ -21,10 +21,10 @@ import {
|
|
|
21
21
|
removeDepositor,
|
|
22
22
|
setAgentFeeBps,
|
|
23
23
|
setVaultAddress
|
|
24
|
-
} from "./chunk-
|
|
25
|
-
import "./chunk-
|
|
26
|
-
import "./chunk-
|
|
27
|
-
import "./chunk-
|
|
24
|
+
} from "./chunk-UUHWD7Y3.js";
|
|
25
|
+
import "./chunk-RAITRCM7.js";
|
|
26
|
+
import "./chunk-WECQ6NVS.js";
|
|
27
|
+
import "./chunk-HYUUR6SC.js";
|
|
28
28
|
import "./chunk-GSC7PVEO.js";
|
|
29
29
|
import "./chunk-BQMOE4FJ.js";
|
|
30
30
|
export {
|
|
@@ -51,4 +51,4 @@ export {
|
|
|
51
51
|
setAgentFeeBps,
|
|
52
52
|
setVaultAddress
|
|
53
53
|
};
|
|
54
|
-
//# sourceMappingURL=vault-
|
|
54
|
+
//# sourceMappingURL=vault-NIPA5JV4.js.map
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getTextRecord
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
5
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-FOS47623.js";
|
|
4
|
+
import "./chunk-UUHWD7Y3.js";
|
|
5
|
+
import "./chunk-RAITRCM7.js";
|
|
6
6
|
import {
|
|
7
7
|
getAccount
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-WECQ6NVS.js";
|
|
9
9
|
import {
|
|
10
10
|
getChainConfig
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-HYUUR6SC.js";
|
|
12
12
|
import {
|
|
13
13
|
cacheGroupId,
|
|
14
14
|
getCachedGroupId,
|
|
@@ -319,4 +319,4 @@ export {
|
|
|
319
319
|
sendReaction,
|
|
320
320
|
streamMessages
|
|
321
321
|
};
|
|
322
|
-
//# sourceMappingURL=xmtp-
|
|
322
|
+
//# sourceMappingURL=xmtp-M32JSE4I.js.map
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/ens.ts"],"sourcesContent":["/**\n * ENS resolution + text records via Durin L2Registry on Base.\n *\n * Two responsibilities:\n * 1. Resolve fund subdomain → on-chain fund data (via factory)\n * 2. Read/write ENS text records (via L2Registry, routed through vault's executeBatch)\n *\n * The vault owns the ENS subdomain node (registered in the factory via\n * `ensRegistrar.register(subdomain, vault)`). Only the vault can write text\n * records. We route writes through vault.executeBatch → L2Registry.setText,\n * which executes as the vault via delegatecall to the shared executor lib.\n */\n\nimport { encodeFunctionData } from \"viem\";\nimport type { Address, Hex } from \"viem\";\nimport { namehash } from \"viem/ens\";\nimport { getPublicClient, getWalletClient, getAccount, waitForReceipt } from \"./client.js\";\nimport {\n getChain,\n getNetwork,\n withNetwork,\n VALID_NETWORKS,\n type Network,\n} from \"./network.js\";\nimport { SYNDICATE_FACTORY_ABI, L2_REGISTRY_ABI } from \"./abis.js\";\nimport { ENS, SHERWOOD } from \"./addresses.js\";\nimport * as vaultLib from \"./vault.js\";\n\n/**\n * Wait for a transaction to be mined before proceeding.\n */\nasync function waitForTx(hash: Hex): Promise<void> {\n await waitForReceipt(hash);\n}\n\nconst ENS_DOMAIN = \"sherwoodagent.eth\";\n\nfunction getFactoryAddress(): Address {\n return SHERWOOD().FACTORY;\n}\n\n// ── Fund Resolution (via factory) ──\n\nexport interface FundResolution {\n id: bigint;\n vault: Address;\n creator: Address;\n subdomain: string;\n}\n\n/**\n * Resolve a fund subdomain to its on-chain data.\n * Uses factory.subdomainToSyndicate() → factory.syndicates().\n */\nexport async function resolveFund(subdomain: string): Promise<FundResolution> {\n const client = getPublicClient();\n const factory = getFactoryAddress();\n\n // Get fund ID from subdomain\n const fundId = (await client.readContract({\n address: factory,\n abi: SYNDICATE_FACTORY_ABI,\n functionName: \"subdomainToSyndicate\",\n args: [subdomain],\n })) as bigint;\n\n if (fundId === 0n) {\n throw new Error(`Fund \"${subdomain}\" not found`);\n }\n\n // Get full fund record\n const result = (await client.readContract({\n address: factory,\n abi: SYNDICATE_FACTORY_ABI,\n functionName: \"syndicates\",\n args: [fundId],\n })) as [bigint, Address, Address, string, bigint, boolean, string];\n\n return {\n id: result[0],\n vault: result[1],\n creator: result[2],\n subdomain: result[6],\n };\n}\n\n/**\n * Probe every supported chain for a subdomain registration. Returns every hit —\n * most queries find zero or one, but post-CREATE3 the same subdomain may exist\n * on multiple chains and the caller needs to disambiguate. RPC errors on\n * individual chains are swallowed so a flaky chain doesn't fail the whole\n * search. The current deployment target is a single (ungated) chain, so this\n * iterates VALID_NETWORKS directly.\n */\nexport async function searchFundAcrossChains(\n subdomain: string,\n): Promise<{ network: Network; result: FundResolution }[]> {\n const candidates = VALID_NETWORKS;\n\n const hits: { network: Network; result: FundResolution }[] = [];\n for (const net of candidates) {\n try {\n const result = await withNetwork(net, () => resolveFund(subdomain));\n hits.push({ network: net, result });\n } catch {\n // Not registered on this chain, or RPC failed — keep searching.\n }\n }\n return hits;\n}\n\n/**\n * Reverse lookup: vault address → fund info.\n * Uses factory.vaultToSyndicate() → factory.syndicates().\n */\nexport async function resolveVaultFund(\n vaultAddress: Address,\n): Promise<FundResolution> {\n const client = getPublicClient();\n const factory = getFactoryAddress();\n\n const fundId = (await client.readContract({\n address: factory,\n abi: SYNDICATE_FACTORY_ABI,\n functionName: \"vaultToSyndicate\",\n args: [vaultAddress],\n })) as bigint;\n\n if (fundId === 0n) {\n throw new Error(`No fund found for vault ${vaultAddress}`);\n }\n\n const result = (await client.readContract({\n address: factory,\n abi: SYNDICATE_FACTORY_ABI,\n functionName: \"syndicates\",\n args: [fundId],\n })) as [bigint, Address, Address, string, bigint, boolean, string];\n\n return {\n id: result[0],\n vault: result[1],\n creator: result[2],\n subdomain: result[6],\n };\n}\n\n// ── ENS Text Records (via L2Registry) ──\n\n/**\n * Compute the ENS node hash for a subdomain under sherwoodagent.eth.\n */\nfunction getSubdomainNode(subdomain: string): Hex {\n return namehash(`${subdomain}.${ENS_DOMAIN}`);\n}\n\n/**\n * Write a text record to the L2Registry via the vault's executeBatch.\n *\n * The vault owns the ENS node, so only the vault can call setText.\n * We route the call through vault.executeBatch (delegatecall → executor lib → L2Registry),\n * which means L2Registry sees msg.sender = vault address.\n *\n * Requires the caller to be a registered agent on the vault (creator is auto-registered).\n */\nexport async function setTextRecord(\n subdomain: string,\n key: string,\n value: string,\n vaultAddress: Address,\n): Promise<Hex> {\n const l2Registry = ENS().L2_REGISTRY;\n const node = getSubdomainNode(subdomain);\n\n vaultLib.setVaultAddress(vaultAddress);\n\n // Encode the L2Registry.setText call\n const setTextData = encodeFunctionData({\n abi: L2_REGISTRY_ABI,\n functionName: \"setText\",\n args: [node, key, value],\n });\n\n // Route through vault.executeBatch (owner only)\n return vaultLib.executeBatch(\n [{ target: l2Registry, data: setTextData, value: 0n }],\n );\n}\n\n/**\n * Read a text record from the L2Registry.\n * Used to look up xmtpGroupId when not cached locally.\n */\nexport async function getTextRecord(\n subdomain: string,\n key: string,\n): Promise<string> {\n const client = getPublicClient();\n const node = getSubdomainNode(subdomain);\n\n return client.readContract({\n address: ENS().L2_REGISTRY,\n abi: L2_REGISTRY_ABI,\n functionName: \"text\",\n args: [node, key],\n }) as Promise<string>;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAaA,SAAS,0BAA0B;AAEnC,SAAS,gBAAgB;AAoBzB,IAAM,aAAa;AAEnB,SAAS,oBAA6B;AACpC,SAAO,SAAS,EAAE;AACpB;AAeA,eAAsB,YAAY,WAA4C;AAC5E,QAAM,SAAS,gBAAgB;AAC/B,QAAM,UAAU,kBAAkB;AAGlC,QAAM,SAAU,MAAM,OAAO,aAAa;AAAA,IACxC,SAAS;AAAA,IACT,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC,SAAS;AAAA,EAClB,CAAC;AAED,MAAI,WAAW,IAAI;AACjB,UAAM,IAAI,MAAM,SAAS,SAAS,aAAa;AAAA,EACjD;AAGA,QAAM,SAAU,MAAM,OAAO,aAAa;AAAA,IACxC,SAAS;AAAA,IACT,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC,MAAM;AAAA,EACf,CAAC;AAED,SAAO;AAAA,IACL,IAAI,OAAO,CAAC;AAAA,IACZ,OAAO,OAAO,CAAC;AAAA,IACf,SAAS,OAAO,CAAC;AAAA,IACjB,WAAW,OAAO,CAAC;AAAA,EACrB;AACF;AAUA,eAAsB,uBACpB,WACyD;AACzD,QAAM,aAAa;AAEnB,QAAM,OAAuD,CAAC;AAC9D,aAAW,OAAO,YAAY;AAC5B,QAAI;AACF,YAAM,SAAS,MAAM,YAAY,KAAK,MAAM,YAAY,SAAS,CAAC;AAClE,WAAK,KAAK,EAAE,SAAS,KAAK,OAAO,CAAC;AAAA,IACpC,QAAQ;AAAA,IAER;AAAA,EACF;AACA,SAAO;AACT;AAMA,eAAsB,iBACpB,cACyB;AACzB,QAAM,SAAS,gBAAgB;AAC/B,QAAM,UAAU,kBAAkB;AAElC,QAAM,SAAU,MAAM,OAAO,aAAa;AAAA,IACxC,SAAS;AAAA,IACT,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC,YAAY;AAAA,EACrB,CAAC;AAED,MAAI,WAAW,IAAI;AACjB,UAAM,IAAI,MAAM,2BAA2B,YAAY,EAAE;AAAA,EAC3D;AAEA,QAAM,SAAU,MAAM,OAAO,aAAa;AAAA,IACxC,SAAS;AAAA,IACT,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC,MAAM;AAAA,EACf,CAAC;AAED,SAAO;AAAA,IACL,IAAI,OAAO,CAAC;AAAA,IACZ,OAAO,OAAO,CAAC;AAAA,IACf,SAAS,OAAO,CAAC;AAAA,IACjB,WAAW,OAAO,CAAC;AAAA,EACrB;AACF;AAOA,SAAS,iBAAiB,WAAwB;AAChD,SAAO,SAAS,GAAG,SAAS,IAAI,UAAU,EAAE;AAC9C;AAWA,eAAsB,cACpB,WACA,KACA,OACA,cACc;AACd,QAAM,aAAa,IAAI,EAAE;AACzB,QAAM,OAAO,iBAAiB,SAAS;AAEvC,EAAS,gBAAgB,YAAY;AAGrC,QAAM,cAAc,mBAAmB;AAAA,IACrC,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC,MAAM,KAAK,KAAK;AAAA,EACzB,CAAC;AAGD,SAAgB;AAAA,IACd,CAAC,EAAE,QAAQ,YAAY,MAAM,aAAa,OAAO,GAAG,CAAC;AAAA,EACvD;AACF;AAMA,eAAsB,cACpB,WACA,KACiB;AACjB,QAAM,SAAS,gBAAgB;AAC/B,QAAM,OAAO,iBAAiB,SAAS;AAEvC,SAAO,OAAO,aAAa;AAAA,IACzB,SAAS,IAAI,EAAE;AAAA,IACf,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC,MAAM,GAAG;AAAA,EAClB,CAAC;AACH;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/governor.ts"],"sourcesContent":["/**\n * Governor contract wrapper — reads/writes to SyndicateGovernor.\n *\n * Per-vault governor design: the factory deploys ONE governor per vault\n * (BeaconProxy). Every helper takes the vault address and resolves its\n * governor via `factory.governorOf(vault)` (memoized per chain+vault —\n * the binding is set once at createSyndicate and never changes).\n *\n * Protocol-wide fee parameters (protocol/guardian fee bps + recipients)\n * live on the separate ProtocolConfig contract, resolved via\n * `factory.protocolConfig()`.\n */\n\nimport type { Address, Hex, Log } from \"viem\";\nimport { parseEventLogs } from \"viem\";\nimport { getPublicClient, getAccount, writeContractWithRetry, waitForReceipt } from \"./client.js\";\nimport { getChain } from \"./network.js\";\nimport { SHERWOOD } from \"./addresses.js\";\nimport { SYNDICATE_GOVERNOR_ABI, SYNDICATE_FACTORY_ABI, PROTOCOL_CONFIG_ABI } from \"./abis.js\";\n\n// ── Types ──\n\nexport interface GovernorParams {\n votingPeriod: bigint;\n executionWindow: bigint;\n vetoThresholdBps: bigint;\n maxPerformanceFeeBps: bigint;\n cooldownPeriod: bigint;\n collaborationWindow: bigint;\n maxCoProposers: bigint;\n minStrategyDuration: bigint;\n maxStrategyDuration: bigint;\n}\n\nexport interface StrategyProposal {\n id: bigint;\n proposer: Address;\n vault: Address;\n /** Strategy contract address whose `positionValue()` the vault polls\n * for live NAV. Set at propose time, immutable thereafter. address(0)\n * for queue-only proposals (no live NAV). */\n strategy: Address;\n metadataURI: string;\n /** Agent fee (bps) snapshotted from the vault's `agentFeeBps` at propose. */\n performanceFeeBps: bigint;\n strategyDuration: bigint;\n votesFor: bigint;\n votesAgainst: bigint;\n votesAbstain: bigint;\n snapshotTimestamp: bigint;\n voteEnd: bigint;\n reviewEnd: bigint;\n executeBy: bigint;\n executedAt: bigint;\n state: number;\n vetoThresholdBps: bigint;\n /** Fee snapshot taken from ProtocolConfig at propose time (PR #421). These\n * four fields sit between `vetoThresholdBps` and `selfManagesFees` in the\n * on-chain `StrategyProposal` struct — omitting them corrupts tuple decode. */\n snapshotProtocolFeeBps: bigint;\n snapshotProtocolFeeRecipient: Address;\n snapshotGuardianFeeBps: bigint;\n snapshotGuardiansFeeRecipient: Address;\n /** `IStrategy.selfManagesFees()` snapshotted at propose (PR #388 #2); read\n * from storage at settle so it can't flip mid-flight or brick settlement. */\n selfManagesFees: boolean;\n}\n\nexport interface CoProposer {\n agent: Address;\n splitBps: bigint;\n}\n\nexport interface BatchCall {\n target: Address;\n data: Hex;\n value: bigint;\n}\n\n// Must match Solidity ISyndicateGovernor.ProposalState ordering. PR #229\n// inserted GuardianReview at index 2, shifting every subsequent state by\n// one. Without this fix, the CLI mislabels Approved (3) as Rejected,\n// Executed (6) as Settled, etc. — and `proposal execute` rejects valid\n// approved proposals.\nexport const PROPOSAL_STATES = [\n \"Draft\",\n \"Pending\",\n \"GuardianReview\",\n \"Approved\",\n \"Rejected\",\n \"Expired\",\n \"Executed\",\n \"Settled\",\n \"Cancelled\",\n] as const;\n\nexport const PROPOSAL_STATE = {\n Draft: 0,\n Pending: 1,\n GuardianReview: 2,\n Approved: 3,\n Rejected: 4,\n Expired: 5,\n Executed: 6,\n Settled: 7,\n Cancelled: 8,\n} as const;\n\nexport const VOTE_TYPE = {\n For: 0,\n Against: 1,\n Abstain: 2,\n} as const;\n\n// ── Duration parser ──\n\nexport function parseDuration(input: string): bigint {\n const match = input.match(/^(\\d+)(d|h|m|s)?$/);\n if (!match) throw new Error(`Invalid duration: ${input}`);\n const value = BigInt(match[1]);\n switch (match[2]) {\n case \"d\":\n return value * 86400n;\n case \"h\":\n return value * 3600n;\n case \"m\":\n return value * 60n;\n case \"s\":\n case undefined:\n return value;\n default:\n throw new Error(`Unknown duration unit: ${match[2]}`);\n }\n}\n\n// ── Address helpers ──\n\n// governorOf(vault) is set once at createSyndicate and never rebinds, so\n// it is safe to memoize per chain+vault for the lifetime of the process.\nconst governorCache = new Map<string, Address>();\n\n/** Resolve the per-vault governor via `factory.governorOf(vault)`. */\nexport async function getGovernorOf(vault: Address): Promise<Address> {\n const key = `${getChain().id}:${vault.toLowerCase()}`;\n const cached = governorCache.get(key);\n if (cached) return cached;\n\n const client = getPublicClient();\n const governor = await client.readContract({\n address: SHERWOOD().FACTORY,\n abi: SYNDICATE_FACTORY_ABI,\n functionName: \"governorOf\",\n args: [vault],\n }) as Address;\n\n if (governor === \"0x0000000000000000000000000000000000000000\") {\n throw new Error(`No governor registered for vault ${vault} — is it a factory-created vault?`);\n }\n\n governorCache.set(key, governor);\n return governor;\n}\n\n// ProtocolConfig is a protocol-wide singleton behind the factory — same\n// set-once semantics as governorOf, memoized per chain.\nconst protocolConfigCache = new Map<number, Address>();\n\n/** Resolve the ProtocolConfig address via `factory.protocolConfig()`. */\nexport async function getProtocolConfigAddress(): Promise<Address> {\n const chainId = getChain().id;\n const cached = protocolConfigCache.get(chainId);\n if (cached) return cached;\n\n const client = getPublicClient();\n const config = await client.readContract({\n address: SHERWOOD().FACTORY,\n abi: SYNDICATE_FACTORY_ABI,\n functionName: \"protocolConfig\",\n }) as Address;\n\n protocolConfigCache.set(chainId, config);\n return config;\n}\n\n// ── Read helpers ──\n\nexport async function getGovernorParams(vault: Address): Promise<GovernorParams> {\n const client = getPublicClient();\n const result = await client.readContract({\n address: await getGovernorOf(vault),\n abi: SYNDICATE_GOVERNOR_ABI,\n functionName: \"getGovernorParams\",\n }) as {\n votingPeriod: bigint;\n executionWindow: bigint;\n vetoThresholdBps: bigint;\n maxPerformanceFeeBps: bigint;\n cooldownPeriod: bigint;\n collaborationWindow: bigint;\n maxCoProposers: bigint;\n minStrategyDuration: bigint;\n maxStrategyDuration: bigint;\n };\n return result;\n}\n\nexport async function getProposal(vault: Address, id: bigint): Promise<StrategyProposal> {\n const client = getPublicClient();\n const result = await client.readContract({\n address: await getGovernorOf(vault),\n abi: SYNDICATE_GOVERNOR_ABI,\n functionName: \"getProposal\",\n args: [id],\n }) as StrategyProposal;\n return result;\n}\n\nexport async function getProposalState(vault: Address, id: bigint): Promise<number> {\n const client = getPublicClient();\n return client.readContract({\n address: await getGovernorOf(vault),\n abi: SYNDICATE_GOVERNOR_ABI,\n functionName: \"getProposalState\",\n args: [id],\n }) as Promise<number>;\n}\n\nexport async function proposalCount(vault: Address): Promise<bigint> {\n const client = getPublicClient();\n return client.readContract({\n address: await getGovernorOf(vault),\n abi: SYNDICATE_GOVERNOR_ABI,\n functionName: \"proposalCount\",\n }) as Promise<bigint>;\n}\n\nexport async function getVoteWeight(vault: Address, proposalId: bigint, voter: Address): Promise<bigint> {\n const client = getPublicClient();\n return client.readContract({\n address: await getGovernorOf(vault),\n abi: SYNDICATE_GOVERNOR_ABI,\n functionName: \"getVoteWeight\",\n args: [proposalId, voter],\n }) as Promise<bigint>;\n}\n\nexport async function hasVoted(vault: Address, proposalId: bigint, voter: Address): Promise<boolean> {\n const client = getPublicClient();\n return client.readContract({\n address: await getGovernorOf(vault),\n abi: SYNDICATE_GOVERNOR_ABI,\n functionName: \"hasVoted\",\n args: [proposalId, voter],\n }) as Promise<boolean>;\n}\n\n// `getProposalCalls` (concat of execute + settle) was dropped in V1.5\n// to reclaim governor bytecode under EIP-170. Use `getExecuteCalls`\n// + `getSettlementCalls` instead — same data, no on-chain copy loop.\n\nexport async function getExecuteCalls(vault: Address, proposalId: bigint): Promise<BatchCall[]> {\n const client = getPublicClient();\n const result = await client.readContract({\n address: await getGovernorOf(vault),\n abi: SYNDICATE_GOVERNOR_ABI,\n functionName: \"getExecuteCalls\",\n args: [proposalId],\n }) as { target: Address; data: Hex; value: bigint }[];\n return result.map((c) => ({ target: c.target, data: c.data, value: c.value }));\n}\n\nexport async function getSettlementCalls(vault: Address, proposalId: bigint): Promise<BatchCall[]> {\n const client = getPublicClient();\n const result = await client.readContract({\n address: await getGovernorOf(vault),\n abi: SYNDICATE_GOVERNOR_ABI,\n functionName: \"getSettlementCalls\",\n args: [proposalId],\n }) as { target: Address; data: Hex; value: bigint }[];\n return result.map((c) => ({ target: c.target, data: c.data, value: c.value }));\n}\n\n// Per-vault governor: `getRegisteredVaults` / `isRegisteredVault` were\n// removed on-chain — a governor serves exactly one vault (`governor.vault()`).\n// Enumerate vaults via the factory (`getAllActiveSyndicates`) instead.\n\nexport async function getActiveProposal(vault: Address): Promise<bigint> {\n const client = getPublicClient();\n return client.readContract({\n address: await getGovernorOf(vault),\n abi: SYNDICATE_GOVERNOR_ABI,\n functionName: \"getActiveProposal\",\n }) as Promise<bigint>;\n}\n\nexport async function getCooldownEnd(vault: Address): Promise<bigint> {\n const client = getPublicClient();\n return client.readContract({\n address: await getGovernorOf(vault),\n abi: SYNDICATE_GOVERNOR_ABI,\n functionName: \"getCooldownEnd\",\n }) as Promise<bigint>;\n}\n\nexport async function openProposalCount(vault: Address): Promise<bigint> {\n const client = getPublicClient();\n return client.readContract({\n address: await getGovernorOf(vault),\n abi: SYNDICATE_GOVERNOR_ABI,\n functionName: \"openProposalCount\",\n }) as Promise<bigint>;\n}\n\nexport async function getCapitalSnapshot(vault: Address, proposalId: bigint): Promise<bigint> {\n const client = getPublicClient();\n return client.readContract({\n address: await getGovernorOf(vault),\n abi: SYNDICATE_GOVERNOR_ABI,\n functionName: \"getCapitalSnapshot\",\n args: [proposalId],\n }) as Promise<bigint>;\n}\n\n/**\n * Extract proposalId from ProposalCreated event logs.\n * Returns undefined if the event is not found or parsing fails.\n */\nexport function parseProposalIdFromLogs(logs: Log[]): bigint | undefined {\n try {\n const parsed = parseEventLogs({\n abi: SYNDICATE_GOVERNOR_ABI,\n logs,\n eventName: \"ProposalCreated\",\n });\n return parsed[0]?.args.proposalId;\n } catch {\n return undefined;\n }\n}\n\n// ── Write helpers ──\n\nexport async function propose(\n vault: Address,\n strategy: Address,\n metadataURI: string,\n strategyDuration: bigint,\n executeCalls: BatchCall[],\n settlementCalls: BatchCall[],\n coProposers: CoProposer[] = [],\n): Promise<{ hash: Hex; proposalId: bigint }> {\n const hash = await writeContractWithRetry({\n account: getAccount(),\n chain: getChain(),\n address: await getGovernorOf(vault),\n abi: SYNDICATE_GOVERNOR_ABI,\n functionName: \"propose\",\n args: [vault, strategy, metadataURI, strategyDuration, executeCalls, settlementCalls, coProposers],\n });\n\n const receipt = await waitForReceipt(hash);\n\n // Parse proposalId from the ProposalCreated event in the receipt logs.\n // Falls back to proposalCount() if event parsing fails.\n let proposalId = parseProposalIdFromLogs(receipt.logs);\n if (proposalId === undefined) {\n try {\n proposalId = await proposalCount(vault);\n } catch {\n proposalId = 0n;\n }\n }\n\n return { hash: receipt.transactionHash, proposalId };\n}\n\nexport async function vote(vault: Address, proposalId: bigint, support: number): Promise<Hex> {\n const hash = await writeContractWithRetry({\n account: getAccount(),\n chain: getChain(),\n address: await getGovernorOf(vault),\n abi: SYNDICATE_GOVERNOR_ABI,\n functionName: \"vote\",\n args: [proposalId, support],\n });\n const receipt = await waitForReceipt(hash);\n return receipt.transactionHash;\n}\n\nexport async function executeProposal(vault: Address, proposalId: bigint): Promise<Hex> {\n const hash = await writeContractWithRetry({\n account: getAccount(),\n chain: getChain(),\n address: await getGovernorOf(vault),\n abi: SYNDICATE_GOVERNOR_ABI,\n functionName: \"executeProposal\",\n args: [proposalId],\n });\n const receipt = await waitForReceipt(hash);\n return receipt.transactionHash;\n}\n\n/**\n * Walk a proposal's executeCalls and pick the strategy clone — the\n * target of the call whose selector matches `BaseStrategy.execute()`\n * (0x61461954). This is the canonical entry point that every Sherwood\n * strategy template inherits from BaseStrategy, so it's a reliable\n * marker even across template families (Moonwell / Aerodrome /\n * Hyperliquid / Mamo / Venice / Portfolio).\n *\n * Returns null when no execute() call is present (e.g. proposals that\n * only do approves and direct ERC-20 transfers without a strategy).\n */\nexport function detectStrategyAdapter(\n calls: { target: Address; data: Hex; value: bigint }[],\n): Address | null {\n const STRATEGY_EXECUTE_SELECTOR = \"0x61461954\";\n for (const call of calls) {\n if (call.data.slice(0, 10).toLowerCase() === STRATEGY_EXECUTE_SELECTOR) {\n return call.target;\n }\n }\n return null;\n}\n\nexport async function settleProposal(vault: Address, proposalId: bigint): Promise<Hex> {\n const hash = await writeContractWithRetry({\n account: getAccount(),\n chain: getChain(),\n address: await getGovernorOf(vault),\n abi: SYNDICATE_GOVERNOR_ABI,\n functionName: \"settleProposal\",\n args: [proposalId],\n });\n const receipt = await waitForReceipt(hash);\n return receipt.transactionHash;\n}\n\nexport async function emergencySettle(vault: Address, proposalId: bigint, calls: BatchCall[]): Promise<Hex> {\n const hash = await writeContractWithRetry({\n account: getAccount(),\n chain: getChain(),\n address: await getGovernorOf(vault),\n abi: SYNDICATE_GOVERNOR_ABI,\n functionName: \"emergencySettleWithCalls\",\n args: [proposalId, calls],\n });\n const receipt = await waitForReceipt(hash);\n return receipt.transactionHash;\n}\n\nexport async function cancelProposal(vault: Address, proposalId: bigint): Promise<Hex> {\n const hash = await writeContractWithRetry({\n account: getAccount(),\n chain: getChain(),\n address: await getGovernorOf(vault),\n abi: SYNDICATE_GOVERNOR_ABI,\n functionName: \"cancelProposal\",\n args: [proposalId],\n });\n const receipt = await waitForReceipt(hash);\n return receipt.transactionHash;\n}\n\nexport async function emergencyCancel(vault: Address, proposalId: bigint): Promise<Hex> {\n const hash = await writeContractWithRetry({\n account: getAccount(),\n chain: getChain(),\n address: await getGovernorOf(vault),\n abi: SYNDICATE_GOVERNOR_ABI,\n functionName: \"emergencyCancel\",\n args: [proposalId],\n });\n const receipt = await waitForReceipt(hash);\n return receipt.transactionHash;\n}\n\n// ── Parameter setters ──\n//\n// Per-vault governor: governance parameters are per-vault now, set by the\n// VAULT OWNER on that vault's governor. Setters revert with\n// `ParamsFrozenDuringProposal` while any proposal is open on the vault.\n\ntype GovernorParamSetter =\n | \"setVotingPeriod\"\n | \"setExecutionWindow\"\n | \"setVetoThresholdBps\"\n | \"setMaxPerformanceFeeBps\"\n | \"setMaxStrategyDuration\"\n | \"setCooldownPeriod\";\n\nasync function setGovernorParam(\n vault: Address,\n functionName: GovernorParamSetter,\n value: bigint,\n): Promise<Hex> {\n const hash = await writeContractWithRetry({\n account: getAccount(),\n chain: getChain(),\n address: await getGovernorOf(vault),\n abi: SYNDICATE_GOVERNOR_ABI,\n functionName,\n args: [value],\n });\n const receipt = await waitForReceipt(hash);\n return receipt.transactionHash;\n}\n\nexport async function setVotingPeriod(vault: Address, seconds: bigint): Promise<Hex> {\n return setGovernorParam(vault, \"setVotingPeriod\", seconds);\n}\n\nexport async function setExecutionWindow(vault: Address, seconds: bigint): Promise<Hex> {\n return setGovernorParam(vault, \"setExecutionWindow\", seconds);\n}\n\nexport async function setVetoThresholdBps(vault: Address, bps: bigint): Promise<Hex> {\n return setGovernorParam(vault, \"setVetoThresholdBps\", bps);\n}\n\nexport async function setMaxPerformanceFeeBps(vault: Address, bps: bigint): Promise<Hex> {\n return setGovernorParam(vault, \"setMaxPerformanceFeeBps\", bps);\n}\n\nexport async function setMaxStrategyDuration(vault: Address, seconds: bigint): Promise<Hex> {\n return setGovernorParam(vault, \"setMaxStrategyDuration\", seconds);\n}\n\nexport async function setCooldownPeriod(vault: Address, seconds: bigint): Promise<Hex> {\n return setGovernorParam(vault, \"setCooldownPeriod\", seconds);\n}\n\nexport async function vetoProposal(vault: Address, proposalId: bigint): Promise<Hex> {\n const hash = await writeContractWithRetry({\n account: getAccount(),\n chain: getChain(),\n address: await getGovernorOf(vault),\n abi: SYNDICATE_GOVERNOR_ABI,\n functionName: \"vetoProposal\",\n args: [proposalId],\n });\n const receipt = await waitForReceipt(hash);\n return receipt.transactionHash;\n}\n\n// ── ProtocolConfig fee setters (protocol-owner only) ──\n//\n// Fee parameters moved off the governor onto the protocol-wide\n// ProtocolConfig contract (resolved via `factory.protocolConfig()`).\n\nexport async function setProtocolFeeBps(bps: bigint): Promise<Hex> {\n const hash = await writeContractWithRetry({\n account: getAccount(),\n chain: getChain(),\n address: await getProtocolConfigAddress(),\n abi: PROTOCOL_CONFIG_ABI,\n functionName: \"setProtocolFeeBps\",\n args: [bps],\n });\n const receipt = await waitForReceipt(hash);\n return receipt.transactionHash;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/network.ts"],"sourcesContent":["/**\n * Network state singleton.\n *\n * Called once at CLI startup via the --chain flag's preAction hook.\n * Every other module reads from here — never hardcodes a chain.\n *\n * Current deployment target: Robinhood L2 testnet (chain 46630) only. Sherwood\n * launches on Robinhood first; other chains may be added back later, at which\n * point they re-enter the Network union + CHAIN_REGISTRY below.\n */\n\nimport { type Chain, defineChain } from \"viem\";\nimport { getConfigRpcUrl } from \"./config.js\";\n\n// ── Robinhood L2 Testnet (Arbitrum Orbit, chain ID 46630) ──\n\nexport const robinhoodTestnet = defineChain({\n id: 46630,\n name: \"Robinhood Chain Testnet\",\n nativeCurrency: { name: \"Ethereum\", symbol: \"ETH\", decimals: 18 },\n rpcUrls: {\n default: { http: [\"https://rpc.testnet.chain.robinhood.com\"] },\n },\n blockExplorers: {\n default: {\n name: \"Blockscout\",\n url: \"https://explorer.testnet.chain.robinhood.com\",\n },\n },\n testnet: true,\n});\n\n// ── Types ──\n\nexport type Network = \"robinhood-testnet\";\n\nexport interface ChainConfig {\n chain: Chain;\n /**\n * Ordered list of public RPC URLs tried in sequence when no user RPC is set.\n * First entry is the primary; the rest are fallbacks used transparently via\n * viem's `fallback` transport on rate-limit / network errors.\n */\n rpcFallbacks: string[];\n /** Legacy env var for backwards compat (optional per chain) */\n rpcEnvVar?: string;\n explorerHost: string;\n /** EAS GraphQL endpoint — null if EAS is not available on this chain */\n easGraphqlUrl: string | null;\n /** EAS scan host — null if unavailable */\n easScanHost: string | null;\n xmtpEnv: \"production\" | \"dev\";\n isTestnet: boolean;\n}\n\n// ── Chain Registry ──\n\nexport const CHAIN_REGISTRY: Record<Network, ChainConfig> = {\n \"robinhood-testnet\": {\n chain: robinhoodTestnet,\n rpcFallbacks: [\"https://rpc.testnet.chain.robinhood.com\"],\n rpcEnvVar: \"ROBINHOOD_TESTNET_RPC_URL\",\n explorerHost: \"explorer.testnet.chain.robinhood.com\",\n easGraphqlUrl: null,\n easScanHost: null,\n xmtpEnv: \"dev\",\n isTestnet: true,\n },\n};\n\nexport const VALID_NETWORKS = Object.keys(CHAIN_REGISTRY) as Network[];\n\nexport const DEFAULT_NETWORK: Network = \"robinhood-testnet\";\n\n// ── Singleton state ──\n\nlet _network: Network = DEFAULT_NETWORK;\n\nexport function setNetwork(n: Network) {\n const config = CHAIN_REGISTRY[n];\n if (!config) {\n throw new Error(\n `Unknown network: ${n}. Valid: ${VALID_NETWORKS.join(\", \")}`,\n );\n }\n _network = n;\n}\n\nexport function getNetwork(): Network {\n return _network;\n}\n\n/**\n * Run `fn` with the network singleton temporarily switched to `network`,\n * restoring the previous network in `finally`.\n *\n * The viem clients (`getPublicClient`, `getWalletClient`) auto-invalidate on\n * chain change, so callers get fresh per-chain RPC + chain context inside the\n * block. Used for cross-chain fund resolution.\n */\nexport async function withNetwork<T>(\n network: Network,\n fn: () => Promise<T>,\n): Promise<T> {\n const previous = _network;\n _network = network;\n try {\n return await fn();\n } finally {\n _network = previous;\n }\n}\n\nexport function getChainConfig(): ChainConfig {\n return CHAIN_REGISTRY[_network];\n}\n\n/**\n * Dev/CI-only chain-id override (`SIM_CHAIN_ID`) for custom-chainId vnet forks.\n * viem asserts the node's chainId matches the chain definition on every write,\n * so signing for such a fork requires the id to be swapped at the source.\n *\n * Interlock: honored ONLY while `SIM_ADDRESSES_FILE` is also set (the vnet\n * e2e harness's address override). A bare SIM_CHAIN_ID does nothing, so this\n * can never redirect signing on a real network run.\n */\nexport function applyChainIdOverride(chain: Chain): Chain {\n const raw = process.env.SIM_CHAIN_ID;\n if (!raw || !process.env.SIM_ADDRESSES_FILE) return chain;\n const id = Number(raw);\n if (!Number.isInteger(id) || id <= 0) return chain;\n return { ...chain, id };\n}\n\nexport function getChain(): Chain {\n return applyChainIdOverride(CHAIN_REGISTRY[_network].chain);\n}\n\n/**\n * Ordered list of RPC URLs to try, deduped:\n * 1. User config (~/.sherwood/config.json) — honored first\n * 2. Legacy env var (ROBINHOOD_TESTNET_RPC_URL)\n * 3. Public fallback list from CHAIN_REGISTRY\n *\n * Fed to viem's `fallback()` transport so rate-limited RPCs transparently\n * advance to the next entry. See issue #182.\n */\nexport function getRpcUrls(): string[] {\n const cfg = CHAIN_REGISTRY[_network];\n const urls: string[] = [];\n\n const fromConfig = getConfigRpcUrl(_network);\n if (fromConfig) urls.push(fromConfig);\n\n if (cfg.rpcEnvVar && process.env[cfg.rpcEnvVar]) {\n urls.push(process.env[cfg.rpcEnvVar]!);\n }\n\n // Vnet harness (SIM_CHAIN_ID + SIM_ADDRESSES_FILE interlock): the fork RPC\n // is the ONLY valid endpoint — the public fallbacks point at the real\n // network. viem's fallback() otherwise rotates there on a vnet hiccup and\n // silently estimates gas/fees against MAINNET state (live finding: an\n // approve estimated at 21.9k gas on mainnet — no code at that address —\n // reverted out-of-gas on the vnet where it needs ~46k). A vnet call must\n // fail loudly, never retarget the real chain.\n if (process.env.SIM_CHAIN_ID && process.env.SIM_ADDRESSES_FILE && urls.length > 0) {\n return Array.from(new Set(urls));\n }\n\n urls.push(...cfg.rpcFallbacks);\n\n return Array.from(new Set(urls));\n}\n\nexport function getRpcUrl(): string {\n return getRpcUrls()[0];\n}\n\nexport function getExplorerUrl(txHash: string): string {\n return `https://${CHAIN_REGISTRY[_network].explorerHost}/tx/${txHash}`;\n}\n\nexport function isTestnet(): boolean {\n return CHAIN_REGISTRY[_network].isTestnet;\n}\n"],"mappings":";;;;;AAWA,SAAqB,mBAAmB;AAKjC,IAAM,mBAAmB,YAAY;AAAA,EAC1C,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,gBAAgB,EAAE,MAAM,YAAY,QAAQ,OAAO,UAAU,GAAG;AAAA,EAChE,SAAS;AAAA,IACP,SAAS,EAAE,MAAM,CAAC,yCAAyC,EAAE;AAAA,EAC/D;AAAA,EACA,gBAAgB;AAAA,IACd,SAAS;AAAA,MACP,MAAM;AAAA,MACN,KAAK;AAAA,IACP;AAAA,EACF;AAAA,EACA,SAAS;AACX,CAAC;AA2BM,IAAM,iBAA+C;AAAA,EAC1D,qBAAqB;AAAA,IACnB,OAAO;AAAA,IACP,cAAc,CAAC,yCAAyC;AAAA,IACxD,WAAW;AAAA,IACX,cAAc;AAAA,IACd,eAAe;AAAA,IACf,aAAa;AAAA,IACb,SAAS;AAAA,IACT,WAAW;AAAA,EACb;AACF;AAEO,IAAM,iBAAiB,OAAO,KAAK,cAAc;AAEjD,IAAM,kBAA2B;AAIxC,IAAI,WAAoB;AAEjB,SAAS,WAAW,GAAY;AACrC,QAAM,SAAS,eAAe,CAAC;AAC/B,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI;AAAA,MACR,oBAAoB,CAAC,YAAY,eAAe,KAAK,IAAI,CAAC;AAAA,IAC5D;AAAA,EACF;AACA,aAAW;AACb;AAEO,SAAS,aAAsB;AACpC,SAAO;AACT;AAUA,eAAsB,YACpB,SACA,IACY;AACZ,QAAM,WAAW;AACjB,aAAW;AACX,MAAI;AACF,WAAO,MAAM,GAAG;AAAA,EAClB,UAAE;AACA,eAAW;AAAA,EACb;AACF;AAEO,SAAS,iBAA8B;AAC5C,SAAO,eAAe,QAAQ;AAChC;AAWO,SAAS,qBAAqB,OAAqB;AACxD,QAAM,MAAM,QAAQ,IAAI;AACxB,MAAI,CAAC,OAAO,CAAC,QAAQ,IAAI,mBAAoB,QAAO;AACpD,QAAM,KAAK,OAAO,GAAG;AACrB,MAAI,CAAC,OAAO,UAAU,EAAE,KAAK,MAAM,EAAG,QAAO;AAC7C,SAAO,EAAE,GAAG,OAAO,GAAG;AACxB;AAEO,SAAS,WAAkB;AAChC,SAAO,qBAAqB,eAAe,QAAQ,EAAE,KAAK;AAC5D;AAWO,SAAS,aAAuB;AACrC,QAAM,MAAM,eAAe,QAAQ;AACnC,QAAM,OAAiB,CAAC;AAExB,QAAM,aAAa,gBAAgB,QAAQ;AAC3C,MAAI,WAAY,MAAK,KAAK,UAAU;AAEpC,MAAI,IAAI,aAAa,QAAQ,IAAI,IAAI,SAAS,GAAG;AAC/C,SAAK,KAAK,QAAQ,IAAI,IAAI,SAAS,CAAE;AAAA,EACvC;AASA,MAAI,QAAQ,IAAI,gBAAgB,QAAQ,IAAI,sBAAsB,KAAK,SAAS,GAAG;AACjF,WAAO,MAAM,KAAK,IAAI,IAAI,IAAI,CAAC;AAAA,EACjC;AAEA,OAAK,KAAK,GAAG,IAAI,YAAY;AAE7B,SAAO,MAAM,KAAK,IAAI,IAAI,IAAI,CAAC;AACjC;AAEO,SAAS,YAAoB;AAClC,SAAO,WAAW,EAAE,CAAC;AACvB;AAEO,SAAS,eAAe,QAAwB;AACrD,SAAO,WAAW,eAAe,QAAQ,EAAE,YAAY,OAAO,MAAM;AACtE;AAEO,SAAS,YAAqB;AACnC,SAAO,eAAe,QAAQ,EAAE;AAClC;","names":[]}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|