@sherwoodagent/cli 0.73.4 → 0.74.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/{abis-KP7M4IPM.js → abis-OLIDCWDS.js} +2 -2
- package/dist/{addresses-DGB3D457.js → addresses-OFFTM6NG.js} +4 -4
- package/dist/{agent-UNSW5IPO.js → agent-B7V5L2ZL.js} +8 -8
- package/dist/{chat-KT2WVDT2.js → chat-CXUU4AXK.js} +9 -10
- package/dist/{chat-KT2WVDT2.js.map → chat-CXUU4AXK.js.map} +1 -1
- package/dist/{chunk-ROKE6ZAW.js → chunk-2OHX3O55.js} +6 -20
- package/dist/chunk-2OHX3O55.js.map +1 -0
- package/dist/chunk-3ZOWP3VO.js +173 -0
- package/dist/chunk-3ZOWP3VO.js.map +1 -0
- package/dist/chunk-4LKU7ASB.js +1253 -0
- package/dist/chunk-4LKU7ASB.js.map +1 -0
- package/dist/{chunk-GSC7PVEO.js → chunk-6MV4ESXM.js} +43 -7
- package/dist/chunk-6MV4ESXM.js.map +1 -0
- package/dist/{chunk-CHWBQJLT.js → chunk-6UEQUVTQ.js} +8 -21
- package/dist/chunk-6UEQUVTQ.js.map +1 -0
- package/dist/{chunk-NPWYX6NU.js → chunk-BD4ZV7FQ.js} +3 -3
- package/dist/{chunk-BKJ7HYX7.js → chunk-DGLLSZ2D.js} +10 -10
- package/dist/chunk-DGLLSZ2D.js.map +1 -0
- package/dist/chunk-EGJESQXZ.js +1 -0
- package/dist/{chunk-ZURDCYGU.js → chunk-EW6FTUOL.js} +9 -5
- package/dist/chunk-EW6FTUOL.js.map +1 -0
- package/dist/{chunk-2U4TWPWQ.js → chunk-K3EYEJMT.js} +5 -5
- package/dist/{chunk-DXJJMRBM.js → chunk-LHVSS27T.js} +2 -2
- package/dist/{chunk-GU5VZGXB.js → chunk-O65AC2YS.js} +5 -5
- package/dist/chunk-TU655ZTV.js +3866 -0
- package/dist/chunk-TU655ZTV.js.map +1 -0
- package/dist/{chunk-IFL5SREW.js → chunk-UINMHN6S.js} +2 -2
- package/dist/{chunk-CZRJ5GWE.js → chunk-YADJ5YWY.js} +54 -24
- package/dist/chunk-YADJ5YWY.js.map +1 -0
- package/dist/{client-NAL3HVLK.js → client-C3C6IXAH.js} +4 -4
- package/dist/{config-FAQO37S7.js → config-7HU4X7EK.js} +4 -4
- package/dist/{eas-QAH7XVLK.js → eas-XWQYAUEM.js} +7 -7
- package/dist/{governor-S56M6BV6.js → governor-NHXBIFFB.js} +7 -7
- package/dist/index.js +201 -1286
- package/dist/index.js.map +1 -1
- package/dist/{network-MKMX2NG6.js → network-WU2QC3L4.js} +3 -3
- package/dist/{price-HHDBMKIE.js → price-QSVIM6QY.js} +15 -37
- package/dist/price-QSVIM6QY.js.map +1 -0
- package/dist/providers-YOOQFBN2.js +31 -0
- package/dist/providers-YOOQFBN2.js.map +1 -0
- package/dist/{research-IJBOMYL3.js → research-NQKYGTLY.js} +9 -9
- package/dist/{session-L67AVWBY.js → session-NLI6UFKB.js} +19 -174
- package/dist/session-NLI6UFKB.js.map +1 -0
- package/dist/{trade-LGFQEK3I.js → trade-6VYB6YJZ.js} +277 -43
- package/dist/trade-6VYB6YJZ.js.map +1 -0
- package/dist/{vault-XWFPGHRA.js → vault-45POYGLN.js} +14 -9
- package/dist/{xmtp-6US7GH3Z.js → xmtp-KH5I6GOL.js} +11 -15
- package/dist/xmtp-KH5I6GOL.js.map +1 -0
- package/package.json +2 -1
- package/dist/chunk-BKJ7HYX7.js.map +0 -1
- package/dist/chunk-BQMOE4FJ.js +0 -1629
- package/dist/chunk-BQMOE4FJ.js.map +0 -1
- package/dist/chunk-CHWBQJLT.js.map +0 -1
- package/dist/chunk-CZRJ5GWE.js.map +0 -1
- package/dist/chunk-DIZEB2VV.js +0 -325
- package/dist/chunk-DIZEB2VV.js.map +0 -1
- package/dist/chunk-GSC7PVEO.js.map +0 -1
- package/dist/chunk-ROKE6ZAW.js.map +0 -1
- package/dist/chunk-ZURDCYGU.js.map +0 -1
- package/dist/price-HHDBMKIE.js.map +0 -1
- package/dist/research-4TBGYEVI.js +0 -14
- package/dist/session-L67AVWBY.js.map +0 -1
- package/dist/trade-LGFQEK3I.js.map +0 -1
- package/dist/xmtp-6US7GH3Z.js.map +0 -1
- /package/dist/{abis-KP7M4IPM.js.map → abis-OLIDCWDS.js.map} +0 -0
- /package/dist/{addresses-DGB3D457.js.map → addresses-OFFTM6NG.js.map} +0 -0
- /package/dist/{agent-UNSW5IPO.js.map → agent-B7V5L2ZL.js.map} +0 -0
- /package/dist/{chunk-NPWYX6NU.js.map → chunk-BD4ZV7FQ.js.map} +0 -0
- /package/dist/{client-NAL3HVLK.js.map → chunk-EGJESQXZ.js.map} +0 -0
- /package/dist/{chunk-2U4TWPWQ.js.map → chunk-K3EYEJMT.js.map} +0 -0
- /package/dist/{chunk-DXJJMRBM.js.map → chunk-LHVSS27T.js.map} +0 -0
- /package/dist/{chunk-GU5VZGXB.js.map → chunk-O65AC2YS.js.map} +0 -0
- /package/dist/{chunk-IFL5SREW.js.map → chunk-UINMHN6S.js.map} +0 -0
- /package/dist/{config-FAQO37S7.js.map → client-C3C6IXAH.js.map} +0 -0
- /package/dist/{eas-QAH7XVLK.js.map → config-7HU4X7EK.js.map} +0 -0
- /package/dist/{governor-S56M6BV6.js.map → eas-XWQYAUEM.js.map} +0 -0
- /package/dist/{network-MKMX2NG6.js.map → governor-NHXBIFFB.js.map} +0 -0
- /package/dist/{research-4TBGYEVI.js.map → network-WU2QC3L4.js.map} +0 -0
- /package/dist/{research-IJBOMYL3.js.map → research-NQKYGTLY.js.map} +0 -0
- /package/dist/{vault-XWFPGHRA.js.map → vault-45POYGLN.js.map} +0 -0
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import {
|
|
2
|
+
PROPOSAL_STATES,
|
|
3
|
+
getProposal
|
|
4
|
+
} from "./chunk-EW6FTUOL.js";
|
|
5
|
+
import {
|
|
6
|
+
getPublicClient
|
|
7
|
+
} from "./chunk-2OHX3O55.js";
|
|
8
|
+
import {
|
|
9
|
+
resolveMetadataSummary
|
|
10
|
+
} from "./chunk-XDGCHURW.js";
|
|
11
|
+
|
|
12
|
+
// src/lib/events.ts
|
|
13
|
+
import { parseAbiItem } from "viem";
|
|
14
|
+
var MAX_BLOCK_RANGE = 10000n;
|
|
15
|
+
var VAULT_EVENTS = [
|
|
16
|
+
parseAbiItem("event AgentRegistered(uint256 indexed agentId, address indexed agentAddress)"),
|
|
17
|
+
parseAbiItem("event AgentRemoved(address indexed agentAddress)"),
|
|
18
|
+
parseAbiItem("event DepositorApproved(address indexed depositor)"),
|
|
19
|
+
parseAbiItem("event DepositorRemoved(address indexed depositor)"),
|
|
20
|
+
parseAbiItem("event RedemptionsLockedEvent()"),
|
|
21
|
+
parseAbiItem("event RedemptionsUnlockedEvent()")
|
|
22
|
+
];
|
|
23
|
+
var GOVERNOR_EVENTS = [
|
|
24
|
+
parseAbiItem("event ProposalCreated(uint256 indexed proposalId, address indexed proposer, address indexed vault, uint256 performanceFeeBps, uint256 strategyDuration, uint256 executeCallCount, uint256 settlementCallCount, string metadataURI)"),
|
|
25
|
+
parseAbiItem("event VoteCast(uint256 indexed proposalId, address indexed voter, uint8 support, uint256 weight)"),
|
|
26
|
+
parseAbiItem("event ProposalExecuted(uint256 indexed proposalId, address indexed vault, uint256 capitalSnapshot)"),
|
|
27
|
+
parseAbiItem("event ProposalSettled(uint256 indexed proposalId, address indexed vault, int256 pnl, uint256 performanceFee, uint256 duration)"),
|
|
28
|
+
parseAbiItem("event ProposalCancelled(uint256 indexed proposalId, address indexed cancelledBy)")
|
|
29
|
+
];
|
|
30
|
+
function logToChainEvent(log, eventName) {
|
|
31
|
+
const args = {};
|
|
32
|
+
const decoded = log.args;
|
|
33
|
+
if (decoded) {
|
|
34
|
+
for (const [key, value] of Object.entries(decoded)) {
|
|
35
|
+
args[key] = String(value);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
source: "chain",
|
|
40
|
+
type: eventName,
|
|
41
|
+
block: Number(log.blockNumber),
|
|
42
|
+
tx: log.transactionHash || "",
|
|
43
|
+
args
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
async function getLogsChunked(params) {
|
|
47
|
+
const client = getPublicClient();
|
|
48
|
+
const { address, events, fromBlock, toBlock } = params;
|
|
49
|
+
const allLogs = [];
|
|
50
|
+
let cursor = fromBlock;
|
|
51
|
+
while (cursor <= toBlock) {
|
|
52
|
+
const end = cursor + MAX_BLOCK_RANGE - 1n > toBlock ? toBlock : cursor + MAX_BLOCK_RANGE - 1n;
|
|
53
|
+
const logs = await client.getLogs({
|
|
54
|
+
address,
|
|
55
|
+
events,
|
|
56
|
+
fromBlock: cursor,
|
|
57
|
+
toBlock: end
|
|
58
|
+
});
|
|
59
|
+
allLogs.push(...logs);
|
|
60
|
+
cursor = end + 1n;
|
|
61
|
+
}
|
|
62
|
+
return allLogs;
|
|
63
|
+
}
|
|
64
|
+
async function getVaultEvents(vaultAddress, fromBlock, toBlock) {
|
|
65
|
+
const logs = await getLogsChunked({
|
|
66
|
+
address: vaultAddress,
|
|
67
|
+
events: VAULT_EVENTS,
|
|
68
|
+
fromBlock,
|
|
69
|
+
toBlock
|
|
70
|
+
});
|
|
71
|
+
return logs.map((log) => {
|
|
72
|
+
const eventName = log.eventName || "UnknownVaultEvent";
|
|
73
|
+
return logToChainEvent(log, eventName);
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
async function getGovernorEvents(governorAddress, vaultAddress, fromBlock, toBlock) {
|
|
77
|
+
if (governorAddress === "0x0000000000000000000000000000000000000000") {
|
|
78
|
+
return [];
|
|
79
|
+
}
|
|
80
|
+
const logs = await getLogsChunked({
|
|
81
|
+
address: governorAddress,
|
|
82
|
+
events: GOVERNOR_EVENTS,
|
|
83
|
+
fromBlock,
|
|
84
|
+
toBlock
|
|
85
|
+
});
|
|
86
|
+
return logs.filter((log) => {
|
|
87
|
+
const args = log.args;
|
|
88
|
+
if (!args) return true;
|
|
89
|
+
if (args.vault) {
|
|
90
|
+
return args.vault.toLowerCase() === vaultAddress.toLowerCase();
|
|
91
|
+
}
|
|
92
|
+
return true;
|
|
93
|
+
}).map((log) => {
|
|
94
|
+
const eventName = log.eventName || "UnknownGovernorEvent";
|
|
95
|
+
return logToChainEvent(log, eventName);
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
async function getCurrentBlock() {
|
|
99
|
+
const client = getPublicClient();
|
|
100
|
+
return client.getBlockNumber();
|
|
101
|
+
}
|
|
102
|
+
var PROPOSAL_EVENT_TYPES = /* @__PURE__ */ new Set([
|
|
103
|
+
"ProposalCreated",
|
|
104
|
+
"VoteCast",
|
|
105
|
+
"ProposalExecuted",
|
|
106
|
+
"ProposalSettled",
|
|
107
|
+
"ProposalCancelled"
|
|
108
|
+
]);
|
|
109
|
+
async function enrichProposalEvents(vault, events, metadataCache) {
|
|
110
|
+
const cache = metadataCache ?? /* @__PURE__ */ new Map();
|
|
111
|
+
const proposalEvents = events.filter((e) => PROPOSAL_EVENT_TYPES.has(e.type));
|
|
112
|
+
if (proposalEvents.length === 0) return events;
|
|
113
|
+
const idsNeedingLookup = /* @__PURE__ */ new Set();
|
|
114
|
+
const createdURIs = /* @__PURE__ */ new Map();
|
|
115
|
+
for (const event of proposalEvents) {
|
|
116
|
+
const pid = event.args.proposalId;
|
|
117
|
+
if (!pid) continue;
|
|
118
|
+
if (event.type === "ProposalCreated" && event.args.metadataURI) {
|
|
119
|
+
createdURIs.set(pid, event.args.metadataURI);
|
|
120
|
+
} else if (!cache.has(pid)) {
|
|
121
|
+
idsNeedingLookup.add(pid);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
const proposalData = /* @__PURE__ */ new Map();
|
|
125
|
+
await Promise.all(
|
|
126
|
+
Array.from(idsNeedingLookup).map(async (pid) => {
|
|
127
|
+
try {
|
|
128
|
+
const p = await getProposal(vault, BigInt(pid));
|
|
129
|
+
proposalData.set(pid, { metadataURI: p.metadataURI, state: p.state });
|
|
130
|
+
} catch {
|
|
131
|
+
}
|
|
132
|
+
})
|
|
133
|
+
);
|
|
134
|
+
const allURIs = /* @__PURE__ */ new Map();
|
|
135
|
+
for (const [pid, uri] of createdURIs) allURIs.set(pid, uri);
|
|
136
|
+
for (const [pid, data] of proposalData) {
|
|
137
|
+
if (!allURIs.has(pid)) allURIs.set(pid, data.metadataURI);
|
|
138
|
+
}
|
|
139
|
+
await Promise.all(
|
|
140
|
+
Array.from(allURIs.entries()).map(async ([pid, uri]) => {
|
|
141
|
+
if (cache.has(pid) || !uri) return;
|
|
142
|
+
const summary = await resolveMetadataSummary(uri);
|
|
143
|
+
if (summary) cache.set(pid, summary);
|
|
144
|
+
})
|
|
145
|
+
);
|
|
146
|
+
return events.map((event) => {
|
|
147
|
+
if (!PROPOSAL_EVENT_TYPES.has(event.type)) return event;
|
|
148
|
+
const pid = event.args.proposalId;
|
|
149
|
+
if (!pid) return event;
|
|
150
|
+
const meta = cache.get(pid);
|
|
151
|
+
const pData = proposalData.get(pid);
|
|
152
|
+
const enrichedArgs = { ...event.args };
|
|
153
|
+
if (meta) {
|
|
154
|
+
enrichedArgs.proposalName = meta.name;
|
|
155
|
+
enrichedArgs.proposalDescription = meta.description;
|
|
156
|
+
}
|
|
157
|
+
if (event.type === "ProposalCreated") {
|
|
158
|
+
enrichedArgs.proposalState = "Pending";
|
|
159
|
+
} else if (pData) {
|
|
160
|
+
enrichedArgs.proposalState = PROPOSAL_STATES[pData.state] || "Unknown";
|
|
161
|
+
}
|
|
162
|
+
return { ...event, args: enrichedArgs };
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export {
|
|
167
|
+
getLogsChunked,
|
|
168
|
+
getVaultEvents,
|
|
169
|
+
getGovernorEvents,
|
|
170
|
+
getCurrentBlock,
|
|
171
|
+
enrichProposalEvents
|
|
172
|
+
};
|
|
173
|
+
//# sourceMappingURL=chunk-3ZOWP3VO.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/events.ts"],"sourcesContent":["/**\n * On-chain event reader — fetches vault and governor events via viem getLogs.\n *\n * Uses HTTP RPC (no WebSocket needed). Block ranges are capped at 10,000\n * per call to avoid RPC timeouts (~83 minutes on Base at 2 blocks/sec).\n */\n\nimport type { Address, Log } from \"viem\";\nimport { parseAbiItem } from \"viem\";\nimport { getPublicClient } from \"./client.js\";\nimport { getProposal, PROPOSAL_STATES } from \"./governor.js\";\nimport { resolveMetadataSummary } from \"./ipfs.js\";\n\nconst MAX_BLOCK_RANGE = 10_000n;\n\n// ── Event signatures (parseAbiItem format for getLogs) ──\n\nconst VAULT_EVENTS = [\n parseAbiItem(\"event AgentRegistered(uint256 indexed agentId, address indexed agentAddress)\"),\n parseAbiItem(\"event AgentRemoved(address indexed agentAddress)\"),\n parseAbiItem(\"event DepositorApproved(address indexed depositor)\"),\n parseAbiItem(\"event DepositorRemoved(address indexed depositor)\"),\n parseAbiItem(\"event RedemptionsLockedEvent()\"),\n parseAbiItem(\"event RedemptionsUnlockedEvent()\"),\n] as const;\n\nconst GOVERNOR_EVENTS = [\n parseAbiItem(\"event ProposalCreated(uint256 indexed proposalId, address indexed proposer, address indexed vault, uint256 performanceFeeBps, uint256 strategyDuration, uint256 executeCallCount, uint256 settlementCallCount, string metadataURI)\"),\n parseAbiItem(\"event VoteCast(uint256 indexed proposalId, address indexed voter, uint8 support, uint256 weight)\"),\n parseAbiItem(\"event ProposalExecuted(uint256 indexed proposalId, address indexed vault, uint256 capitalSnapshot)\"),\n parseAbiItem(\"event ProposalSettled(uint256 indexed proposalId, address indexed vault, int256 pnl, uint256 performanceFee, uint256 duration)\"),\n parseAbiItem(\"event ProposalCancelled(uint256 indexed proposalId, address indexed cancelledBy)\"),\n] as const;\n\n/** Normalized event returned by the session check. */\nexport interface ChainEvent {\n source: \"chain\";\n type: string;\n block: number;\n tx: string;\n args: Record<string, string>;\n}\n\nfunction logToChainEvent(log: Log, eventName: string): ChainEvent {\n const args: Record<string, string> = {};\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const decoded = (log as any).args;\n if (decoded) {\n for (const [key, value] of Object.entries(decoded)) {\n args[key] = String(value);\n }\n }\n\n return {\n source: \"chain\",\n type: eventName,\n block: Number(log.blockNumber),\n tx: log.transactionHash || \"\",\n args,\n };\n}\n\n/**\n * Fetch events in chunks to stay within RPC limits.\n * Returns all logs from `fromBlock` to `toBlock` inclusive.\n * Exported for reuse (e.g. vault.ts getNetDeposited's 0→latest scan).\n */\nexport async function getLogsChunked(params: {\n address: Address;\n events: readonly ReturnType<typeof parseAbiItem>[];\n fromBlock: bigint;\n toBlock: bigint;\n}): Promise<Log[]> {\n const client = getPublicClient();\n const { address, events, fromBlock, toBlock } = params;\n\n const allLogs: Log[] = [];\n let cursor = fromBlock;\n\n while (cursor <= toBlock) {\n const end =\n cursor + MAX_BLOCK_RANGE - 1n > toBlock\n ? toBlock\n : cursor + MAX_BLOCK_RANGE - 1n;\n\n const logs = await client.getLogs({\n address,\n events: events as never,\n fromBlock: cursor,\n toBlock: end,\n });\n\n allLogs.push(...logs);\n cursor = end + 1n;\n }\n\n return allLogs;\n}\n\n/** Fetch vault events (AgentRegistered, Ragequit, etc.) */\nexport async function getVaultEvents(\n vaultAddress: Address,\n fromBlock: bigint,\n toBlock: bigint,\n): Promise<ChainEvent[]> {\n const logs = await getLogsChunked({\n address: vaultAddress,\n events: VAULT_EVENTS,\n fromBlock,\n toBlock,\n });\n\n return logs.map((log) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const eventName = (log as any).eventName || \"UnknownVaultEvent\";\n return logToChainEvent(log, eventName);\n });\n}\n\n/** Fetch governor events filtered to a specific vault. */\nexport async function getGovernorEvents(\n governorAddress: Address,\n vaultAddress: Address,\n fromBlock: bigint,\n toBlock: bigint,\n): Promise<ChainEvent[]> {\n if (governorAddress === \"0x0000000000000000000000000000000000000000\") {\n return []; // Governor not deployed yet\n }\n\n const logs = await getLogsChunked({\n address: governorAddress,\n events: GOVERNOR_EVENTS,\n fromBlock,\n toBlock,\n });\n\n // Filter governor events to only those involving our vault\n return logs\n .filter((log) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const args = (log as any).args;\n if (!args) return true;\n // ProposalCreated, ProposalExecuted, ProposalSettled have `vault` in args\n if (args.vault) {\n return (args.vault as string).toLowerCase() === vaultAddress.toLowerCase();\n }\n // VoteCast, ProposalCancelled don't have vault — include them\n // (agents care about all votes/cancellations on their governor)\n return true;\n })\n .map((log) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const eventName = (log as any).eventName || \"UnknownGovernorEvent\";\n return logToChainEvent(log, eventName);\n });\n}\n\n/** Get current block number from the RPC. */\nexport async function getCurrentBlock(): Promise<bigint> {\n const client = getPublicClient();\n return client.getBlockNumber();\n}\n\n// ── Proposal event enrichment ──\n\nconst PROPOSAL_EVENT_TYPES = new Set([\n \"ProposalCreated\",\n \"VoteCast\",\n \"ProposalExecuted\",\n \"ProposalSettled\",\n \"ProposalCancelled\",\n]);\n\n/**\n * Enrich proposal-related events with IPFS metadata (name, description)\n * and current on-chain state. Best-effort — events are returned un-enriched\n * if RPC or IPFS calls fail.\n *\n * `vault` identifies which per-vault governor to read proposal state from\n * (proposal IDs are scoped to a vault's governor in the per-vault design).\n *\n * An optional metadataCache avoids redundant IPFS fetches across poll cycles\n * in streaming mode (proposal metadata is immutable once pinned).\n */\nexport async function enrichProposalEvents(\n vault: Address,\n events: ChainEvent[],\n metadataCache?: Map<string, { name: string; description: string }>,\n): Promise<ChainEvent[]> {\n const cache = metadataCache ?? new Map<string, { name: string; description: string }>();\n\n const proposalEvents = events.filter((e) => PROPOSAL_EVENT_TYPES.has(e.type));\n if (proposalEvents.length === 0) return events;\n\n // Collect unique proposalIds and their metadata sources\n const idsNeedingLookup = new Set<string>();\n const createdURIs = new Map<string, string>(); // proposalId → metadataURI from event args\n\n for (const event of proposalEvents) {\n const pid = event.args.proposalId;\n if (!pid) continue;\n\n if (event.type === \"ProposalCreated\" && event.args.metadataURI) {\n createdURIs.set(pid, event.args.metadataURI);\n } else if (!cache.has(pid)) {\n idsNeedingLookup.add(pid);\n }\n }\n\n // Fetch on-chain proposal data for non-Created events (parallel, deduplicated)\n const proposalData = new Map<string, { metadataURI: string; state: number }>();\n\n await Promise.all(\n Array.from(idsNeedingLookup).map(async (pid) => {\n try {\n const p = await getProposal(vault, BigInt(pid));\n proposalData.set(pid, { metadataURI: p.metadataURI, state: p.state });\n } catch {\n // RPC failure — skip enrichment for this proposalId\n }\n }),\n );\n\n // Resolve IPFS metadata (parallel, deduplicated, uses cache)\n const allURIs = new Map<string, string>();\n for (const [pid, uri] of createdURIs) allURIs.set(pid, uri);\n for (const [pid, data] of proposalData) {\n if (!allURIs.has(pid)) allURIs.set(pid, data.metadataURI);\n }\n\n await Promise.all(\n Array.from(allURIs.entries()).map(async ([pid, uri]) => {\n if (cache.has(pid) || !uri) return;\n const summary = await resolveMetadataSummary(uri);\n if (summary) cache.set(pid, summary);\n }),\n );\n\n // Inject enrichment fields into event args\n return events.map((event) => {\n if (!PROPOSAL_EVENT_TYPES.has(event.type)) return event;\n const pid = event.args.proposalId;\n if (!pid) return event;\n\n const meta = cache.get(pid);\n const pData = proposalData.get(pid);\n const enrichedArgs = { ...event.args };\n\n if (meta) {\n enrichedArgs.proposalName = meta.name;\n enrichedArgs.proposalDescription = meta.description;\n }\n\n if (event.type === \"ProposalCreated\") {\n enrichedArgs.proposalState = \"Pending\";\n } else if (pData) {\n enrichedArgs.proposalState = PROPOSAL_STATES[pData.state] || \"Unknown\";\n }\n\n return { ...event, args: enrichedArgs };\n });\n}\n"],"mappings":"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","names":[]}
|