@gzeoneth/gov-tracker 0.1.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.
Files changed (203) hide show
  1. package/LICENSE +191 -0
  2. package/README.md +201 -0
  3. package/dist/abis.d.ts +79 -0
  4. package/dist/abis.d.ts.map +1 -0
  5. package/dist/abis.js +159 -0
  6. package/dist/abis.js.map +1 -0
  7. package/dist/cli/lib/cli.d.ts +92 -0
  8. package/dist/cli/lib/cli.d.ts.map +1 -0
  9. package/dist/cli/lib/cli.js +562 -0
  10. package/dist/cli/lib/cli.js.map +1 -0
  11. package/dist/cli/lib/election-check.d.ts +46 -0
  12. package/dist/cli/lib/election-check.d.ts.map +1 -0
  13. package/dist/cli/lib/election-check.js +136 -0
  14. package/dist/cli/lib/election-check.js.map +1 -0
  15. package/dist/cli/lib/json-state.d.ts +100 -0
  16. package/dist/cli/lib/json-state.d.ts.map +1 -0
  17. package/dist/cli/lib/json-state.js +225 -0
  18. package/dist/cli/lib/json-state.js.map +1 -0
  19. package/dist/cli/monitor.d.ts +3 -0
  20. package/dist/cli/monitor.d.ts.map +1 -0
  21. package/dist/cli/monitor.js +442 -0
  22. package/dist/cli/monitor.js.map +1 -0
  23. package/dist/constants.d.ts +235 -0
  24. package/dist/constants.d.ts.map +1 -0
  25. package/dist/constants.js +293 -0
  26. package/dist/constants.js.map +1 -0
  27. package/dist/discovery/governor-discovery.d.ts +84 -0
  28. package/dist/discovery/governor-discovery.d.ts.map +1 -0
  29. package/dist/discovery/governor-discovery.js +310 -0
  30. package/dist/discovery/governor-discovery.js.map +1 -0
  31. package/dist/discovery/security-council.d.ts +68 -0
  32. package/dist/discovery/security-council.d.ts.map +1 -0
  33. package/dist/discovery/security-council.js +181 -0
  34. package/dist/discovery/security-council.js.map +1 -0
  35. package/dist/discovery/timelock-discovery.d.ts +99 -0
  36. package/dist/discovery/timelock-discovery.d.ts.map +1 -0
  37. package/dist/discovery/timelock-discovery.js +322 -0
  38. package/dist/discovery/timelock-discovery.js.map +1 -0
  39. package/dist/election.d.ts +172 -0
  40. package/dist/election.d.ts.map +1 -0
  41. package/dist/election.js +464 -0
  42. package/dist/election.js.map +1 -0
  43. package/dist/index.d.ts +56 -0
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/index.js +164 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/stages/base.d.ts +127 -0
  48. package/dist/stages/base.d.ts.map +1 -0
  49. package/dist/stages/base.js +280 -0
  50. package/dist/stages/base.js.map +1 -0
  51. package/dist/stages/l2-to-l1-message.d.ts +108 -0
  52. package/dist/stages/l2-to-l1-message.d.ts.map +1 -0
  53. package/dist/stages/l2-to-l1-message.js +422 -0
  54. package/dist/stages/l2-to-l1-message.js.map +1 -0
  55. package/dist/stages/proposal-created.d.ts +20 -0
  56. package/dist/stages/proposal-created.d.ts.map +1 -0
  57. package/dist/stages/proposal-created.js +62 -0
  58. package/dist/stages/proposal-created.js.map +1 -0
  59. package/dist/stages/proposal-queued.d.ts +39 -0
  60. package/dist/stages/proposal-queued.d.ts.map +1 -0
  61. package/dist/stages/proposal-queued.js +131 -0
  62. package/dist/stages/proposal-queued.js.map +1 -0
  63. package/dist/stages/retryables.d.ts +79 -0
  64. package/dist/stages/retryables.d.ts.map +1 -0
  65. package/dist/stages/retryables.js +307 -0
  66. package/dist/stages/retryables.js.map +1 -0
  67. package/dist/stages/stage-builder.d.ts +46 -0
  68. package/dist/stages/stage-builder.d.ts.map +1 -0
  69. package/dist/stages/stage-builder.js +87 -0
  70. package/dist/stages/stage-builder.js.map +1 -0
  71. package/dist/stages/timelock.d.ts +100 -0
  72. package/dist/stages/timelock.d.ts.map +1 -0
  73. package/dist/stages/timelock.js +552 -0
  74. package/dist/stages/timelock.js.map +1 -0
  75. package/dist/stages/voting.d.ts +18 -0
  76. package/dist/stages/voting.d.ts.map +1 -0
  77. package/dist/stages/voting.js +109 -0
  78. package/dist/stages/voting.js.map +1 -0
  79. package/dist/tracker/context.d.ts +111 -0
  80. package/dist/tracker/context.d.ts.map +1 -0
  81. package/dist/tracker/context.js +264 -0
  82. package/dist/tracker/context.js.map +1 -0
  83. package/dist/tracker/discovery.d.ts +89 -0
  84. package/dist/tracker/discovery.d.ts.map +1 -0
  85. package/dist/tracker/discovery.js +228 -0
  86. package/dist/tracker/discovery.js.map +1 -0
  87. package/dist/tracker/execute.d.ts +44 -0
  88. package/dist/tracker/execute.d.ts.map +1 -0
  89. package/dist/tracker/execute.js +126 -0
  90. package/dist/tracker/execute.js.map +1 -0
  91. package/dist/tracker/index.d.ts +18 -0
  92. package/dist/tracker/index.d.ts.map +1 -0
  93. package/dist/tracker/index.js +70 -0
  94. package/dist/tracker/index.js.map +1 -0
  95. package/dist/tracker/pipeline.d.ts +47 -0
  96. package/dist/tracker/pipeline.d.ts.map +1 -0
  97. package/dist/tracker/pipeline.js +299 -0
  98. package/dist/tracker/pipeline.js.map +1 -0
  99. package/dist/tracker/query.d.ts +45 -0
  100. package/dist/tracker/query.d.ts.map +1 -0
  101. package/dist/tracker/query.js +159 -0
  102. package/dist/tracker/query.js.map +1 -0
  103. package/dist/tracker/state.d.ts +104 -0
  104. package/dist/tracker/state.d.ts.map +1 -0
  105. package/dist/tracker/state.js +287 -0
  106. package/dist/tracker/state.js.map +1 -0
  107. package/dist/tracker.d.ts +261 -0
  108. package/dist/tracker.d.ts.map +1 -0
  109. package/dist/tracker.js +556 -0
  110. package/dist/tracker.js.map +1 -0
  111. package/dist/types/config.d.ts +81 -0
  112. package/dist/types/config.d.ts.map +1 -0
  113. package/dist/types/config.js +6 -0
  114. package/dist/types/config.js.map +1 -0
  115. package/dist/types/core.d.ts +51 -0
  116. package/dist/types/core.d.ts.map +1 -0
  117. package/dist/types/core.js +6 -0
  118. package/dist/types/core.js.map +1 -0
  119. package/dist/types/cross-chain.d.ts +80 -0
  120. package/dist/types/cross-chain.d.ts.map +1 -0
  121. package/dist/types/cross-chain.js +6 -0
  122. package/dist/types/cross-chain.js.map +1 -0
  123. package/dist/types/election.d.ts +59 -0
  124. package/dist/types/election.d.ts.map +1 -0
  125. package/dist/types/election.js +6 -0
  126. package/dist/types/election.js.map +1 -0
  127. package/dist/types/governor.d.ts +71 -0
  128. package/dist/types/governor.d.ts.map +1 -0
  129. package/dist/types/governor.js +6 -0
  130. package/dist/types/governor.js.map +1 -0
  131. package/dist/types/index.d.ts +22 -0
  132. package/dist/types/index.d.ts.map +1 -0
  133. package/dist/types/index.js +21 -0
  134. package/dist/types/index.js.map +1 -0
  135. package/dist/types/stages.d.ts +189 -0
  136. package/dist/types/stages.d.ts.map +1 -0
  137. package/dist/types/stages.js +23 -0
  138. package/dist/types/stages.js.map +1 -0
  139. package/dist/types/timelock.d.ts +108 -0
  140. package/dist/types/timelock.d.ts.map +1 -0
  141. package/dist/types/timelock.js +6 -0
  142. package/dist/types/timelock.js.map +1 -0
  143. package/dist/types/tracking.d.ts +180 -0
  144. package/dist/types/tracking.d.ts.map +1 -0
  145. package/dist/types/tracking.js +6 -0
  146. package/dist/types/tracking.js.map +1 -0
  147. package/dist/types.d.ts +6 -0
  148. package/dist/types.d.ts.map +1 -0
  149. package/dist/types.js +22 -0
  150. package/dist/types.js.map +1 -0
  151. package/dist/utils/chain.d.ts +18 -0
  152. package/dist/utils/chain.d.ts.map +1 -0
  153. package/dist/utils/chain.js +34 -0
  154. package/dist/utils/chain.js.map +1 -0
  155. package/dist/utils/log-filters.d.ts +67 -0
  156. package/dist/utils/log-filters.d.ts.map +1 -0
  157. package/dist/utils/log-filters.js +116 -0
  158. package/dist/utils/log-filters.js.map +1 -0
  159. package/dist/utils/log-search.d.ts +76 -0
  160. package/dist/utils/log-search.d.ts.map +1 -0
  161. package/dist/utils/log-search.js +142 -0
  162. package/dist/utils/log-search.js.map +1 -0
  163. package/dist/utils/logger.d.ts +41 -0
  164. package/dist/utils/logger.d.ts.map +1 -0
  165. package/dist/utils/logger.js +50 -0
  166. package/dist/utils/logger.js.map +1 -0
  167. package/dist/utils/operation-id.d.ts +48 -0
  168. package/dist/utils/operation-id.d.ts.map +1 -0
  169. package/dist/utils/operation-id.js +102 -0
  170. package/dist/utils/operation-id.js.map +1 -0
  171. package/dist/utils/rpc-utils.d.ts +30 -0
  172. package/dist/utils/rpc-utils.d.ts.map +1 -0
  173. package/dist/utils/rpc-utils.js +99 -0
  174. package/dist/utils/rpc-utils.js.map +1 -0
  175. package/dist/utils/salt-computation.d.ts +78 -0
  176. package/dist/utils/salt-computation.d.ts.map +1 -0
  177. package/dist/utils/salt-computation.js +132 -0
  178. package/dist/utils/salt-computation.js.map +1 -0
  179. package/dist/utils/salt-resolver.d.ts +63 -0
  180. package/dist/utils/salt-resolver.d.ts.map +1 -0
  181. package/dist/utils/salt-resolver.js +144 -0
  182. package/dist/utils/salt-resolver.js.map +1 -0
  183. package/dist/utils/scoped-logger.d.ts +43 -0
  184. package/dist/utils/scoped-logger.d.ts.map +1 -0
  185. package/dist/utils/scoped-logger.js +72 -0
  186. package/dist/utils/scoped-logger.js.map +1 -0
  187. package/dist/utils/stage-helpers.d.ts +51 -0
  188. package/dist/utils/stage-helpers.d.ts.map +1 -0
  189. package/dist/utils/stage-helpers.js +143 -0
  190. package/dist/utils/stage-helpers.js.map +1 -0
  191. package/dist/utils/stage-metadata.d.ts +62 -0
  192. package/dist/utils/stage-metadata.d.ts.map +1 -0
  193. package/dist/utils/stage-metadata.js +140 -0
  194. package/dist/utils/stage-metadata.js.map +1 -0
  195. package/dist/utils/timing.d.ts +115 -0
  196. package/dist/utils/timing.d.ts.map +1 -0
  197. package/dist/utils/timing.js +303 -0
  198. package/dist/utils/timing.js.map +1 -0
  199. package/dist/utils/urls.d.ts +20 -0
  200. package/dist/utils/urls.d.ts.map +1 -0
  201. package/dist/utils/urls.js +51 -0
  202. package/dist/utils/urls.js.map +1 -0
  203. package/package.json +72 -0
@@ -0,0 +1,310 @@
1
+ "use strict";
2
+ /**
3
+ * Governor discovery module
4
+ *
5
+ * Find proposals, detect governor type, parse ProposalCreated events.
6
+ * Also includes proposal discovery functions for block range scanning.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.detectProposalType = detectProposalType;
10
+ exports.isElectionProposal = isElectionProposal;
11
+ exports.detectGovernorCapabilities = detectGovernorCapabilities;
12
+ exports.getTimelockAddress = getTimelockAddress;
13
+ exports.getProposalState = getProposalState;
14
+ exports.parseProposalCreatedEvent = parseProposalCreatedEvent;
15
+ exports.findProposalCreatedEvent = findProposalCreatedEvent;
16
+ exports.findProposalByTxHash = findProposalByTxHash;
17
+ exports.getVotingData = getVotingData;
18
+ exports.findProposalQueuedEvent = findProposalQueuedEvent;
19
+ exports.discoverProposals = discoverProposals;
20
+ exports.discoverProposalByTxHash = discoverProposalByTxHash;
21
+ const ethers_1 = require("ethers");
22
+ const constants_1 = require("../constants");
23
+ const log_search_1 = require("../utils/log-search");
24
+ const log_filters_1 = require("../utils/log-filters");
25
+ const rpc_utils_1 = require("../utils/rpc-utils");
26
+ const timing_1 = require("../utils/timing");
27
+ const abis_1 = require("../abis");
28
+ const election_1 = require("../election");
29
+ const chain_1 = require("../utils/chain");
30
+ /**
31
+ * Detect governor type from address
32
+ */
33
+ function detectProposalType(governorAddress) {
34
+ if ((0, chain_1.addressEquals)(governorAddress, constants_1.ADDRESSES.CONSTITUTIONAL_GOVERNOR))
35
+ return "CONSTITUTIONAL";
36
+ if ((0, chain_1.addressEquals)(governorAddress, constants_1.ADDRESSES.NON_CONSTITUTIONAL_GOVERNOR))
37
+ return "NON_CONSTITUTIONAL";
38
+ if ((0, chain_1.addressEquals)(governorAddress, constants_1.ADDRESSES.ELECTION_NOMINEE_GOVERNOR))
39
+ return "ELECTION_NOMINEE";
40
+ if ((0, chain_1.addressEquals)(governorAddress, constants_1.ADDRESSES.ELECTION_MEMBER_GOVERNOR))
41
+ return "ELECTION_MEMBER";
42
+ return "UNKNOWN";
43
+ }
44
+ /**
45
+ * Check if a governor type is a Security Council election governor
46
+ */
47
+ function isElectionProposal(proposalType) {
48
+ return proposalType === "ELECTION_NOMINEE" || proposalType === "ELECTION_MEMBER";
49
+ }
50
+ /**
51
+ * Check if a governor has a timelock() function
52
+ *
53
+ * Governors with timelock route proposals through L2 timelock before execution.
54
+ */
55
+ async function hasTimelock(governorAddress, provider) {
56
+ const governor = new ethers_1.ethers.Contract(governorAddress, abis_1.GOVERNOR_ABI, provider);
57
+ try {
58
+ await governor.timelock();
59
+ return true;
60
+ }
61
+ catch {
62
+ return false;
63
+ }
64
+ }
65
+ /**
66
+ * Detect governor capabilities by probing the contract
67
+ *
68
+ * This function determines the execution path for proposals:
69
+ * - WITH_TIMELOCK: Governor -> L2Timelock -> (optional L1 round-trip)
70
+ * - WITH_VETTING: Same as WITH_TIMELOCK but with vetting period
71
+ * - NO_TIMELOCK: Direct governor.execute() without timelock
72
+ *
73
+ * The detection order matters:
74
+ * 1. Check for timelock() first - most governors have this
75
+ * 2. Check for nomineeVetter() - only Security Council Nominee Election Governor
76
+ * 3. Default to NO_TIMELOCK - Security Council Member Election Governor
77
+ */
78
+ async function detectGovernorCapabilities(governorAddress, provider) {
79
+ // Check for timelock first (most common case)
80
+ if (await hasTimelock(governorAddress, provider)) {
81
+ return "WITH_TIMELOCK";
82
+ }
83
+ // Check for vetting period (Security Council Nominee Election)
84
+ if (await (0, election_1.hasVettingPeriod)(governorAddress, provider)) {
85
+ return "WITH_VETTING";
86
+ }
87
+ // No timelock and no vetting - direct execution
88
+ return "NO_TIMELOCK";
89
+ }
90
+ /**
91
+ * Get the timelock address for a governor
92
+ */
93
+ async function getTimelockAddress(governorAddress, provider) {
94
+ const governor = new ethers_1.ethers.Contract(governorAddress, abis_1.GOVERNOR_ABI, provider);
95
+ return (0, rpc_utils_1.queryWithRetry)(() => governor.timelock());
96
+ }
97
+ /**
98
+ * Get proposal state from governor contract
99
+ */
100
+ async function getProposalState(governorAddress, proposalId, provider) {
101
+ const governor = new ethers_1.ethers.Contract(governorAddress, abis_1.GOVERNOR_ABI, provider);
102
+ const stateNum = (await (0, rpc_utils_1.queryWithRetry)(() => governor.state(ethers_1.BigNumber.from(proposalId))));
103
+ const stateNumber = typeof stateNum === "number" ? stateNum : stateNum.toNumber();
104
+ const state = constants_1.PROPOSAL_STATE_MAP[stateNumber];
105
+ if (!state) {
106
+ throw new Error(`Unknown proposal state number: ${stateNumber}`);
107
+ }
108
+ return state;
109
+ }
110
+ /**
111
+ * Parse ProposalCreated event data
112
+ */
113
+ function parseProposalCreatedEvent(log) {
114
+ try {
115
+ const parsed = abis_1.proposalCreatedInterface.parseLog(log);
116
+ // Cast through unknown required due to ethers' Result type structure
117
+ const args = parsed.args;
118
+ return {
119
+ proposalId: args.proposalId.toString(),
120
+ proposer: args.proposer,
121
+ targets: args.targets,
122
+ values: args.values,
123
+ signatures: args.signatures,
124
+ calldatas: args.calldatas,
125
+ startBlock: args.startBlock,
126
+ endBlock: args.endBlock,
127
+ description: args.description,
128
+ creationBlock: log.blockNumber,
129
+ creationTxHash: log.transactionHash,
130
+ };
131
+ }
132
+ catch {
133
+ return null;
134
+ }
135
+ }
136
+ /**
137
+ * Find ProposalCreated event by proposal ID
138
+ *
139
+ * @param hint - Search optimization hint. Default is backward search from current block.
140
+ */
141
+ async function findProposalCreatedEvent(governorAddress, proposalId, provider, hint) {
142
+ const { blockNumber: currentBlock } = await (0, timing_1.getCurrentBlockInfo)(provider);
143
+ // Apply search hint (default: search backward from current block)
144
+ const fromBlock = hint?.startBlock ?? constants_1.GOVERNANCE_START_BLOCKS.L2;
145
+ const toBlock = hint?.endBlock ?? currentBlock;
146
+ const reverseDirection = hint?.direction === "backward" || !hint?.direction;
147
+ // Note: ProposalCreated event does NOT have indexed proposalId
148
+ // We filter by event topic only and use predicate for exact matching
149
+ return (0, log_search_1.findAndParseEvent)(provider, { address: governorAddress, topics: [constants_1.EVENT_TOPICS.PROPOSAL_CREATED], fromBlock, toBlock }, (l) => parseProposalCreatedEvent(l)?.proposalId === proposalId, parseProposalCreatedEvent, { chunkSize: 10000000, reverseDirection });
150
+ }
151
+ /**
152
+ * Find ProposalCreated event by transaction hash
153
+ */
154
+ async function findProposalByTxHash(txHash, provider) {
155
+ const receipt = await (0, rpc_utils_1.queryWithRetry)(() => provider.getTransactionReceipt(txHash));
156
+ if (!receipt) {
157
+ return null;
158
+ }
159
+ return (0, log_filters_1.findFirstLog)(receipt.logs, { topic: constants_1.EVENT_TOPICS.PROPOSAL_CREATED }, parseProposalCreatedEvent);
160
+ }
161
+ /**
162
+ * Get voting information for a proposal
163
+ */
164
+ async function getVotingData(governorAddress, proposalId, provider) {
165
+ const governor = new ethers_1.ethers.Contract(governorAddress, abis_1.GOVERNOR_ABI, provider);
166
+ const proposalIdBN = ethers_1.BigNumber.from(proposalId);
167
+ // Fetch all voting data in parallel
168
+ const [startBlock, deadline, votes, { blockNumber: currentBlock }] = await Promise.all([
169
+ (0, rpc_utils_1.queryWithRetry)(() => governor.proposalSnapshot(proposalIdBN)),
170
+ (0, rpc_utils_1.queryWithRetry)(() => governor.proposalDeadline(proposalIdBN)),
171
+ (0, rpc_utils_1.queryWithRetry)(() => governor.proposalVotes(proposalIdBN)),
172
+ (0, timing_1.getCurrentBlockInfo)(provider),
173
+ ]);
174
+ // Get quorum at start block
175
+ const quorum = (await (0, rpc_utils_1.queryWithRetry)(() => governor.quorum(startBlock)));
176
+ // Check for extended deadline (late quorum)
177
+ let extendedDeadline;
178
+ try {
179
+ const extended = await governor.proposalExtendedDeadline(proposalIdBN);
180
+ if (extended.gt(0)) {
181
+ extendedDeadline = extended;
182
+ }
183
+ }
184
+ catch {
185
+ // Function not available on this governor
186
+ }
187
+ // Check for vetting deadline (Security Council)
188
+ // IMPORTANT: Vetting deadline is an L1 block number, not L2
189
+ let vettingDeadline;
190
+ let isVettingPeriod = false;
191
+ try {
192
+ const vetting = await governor.proposalVettingDeadline(proposalIdBN);
193
+ if (vetting.gt(0)) {
194
+ vettingDeadline = vetting;
195
+ // Use L1 block number for comparison since vetting deadline is L1-based
196
+ const l1Block = await (0, timing_1.getL1BlockNumberFromL2)(provider);
197
+ isVettingPeriod = l1Block.lte(vetting);
198
+ }
199
+ }
200
+ catch {
201
+ // Function not available on this governor
202
+ }
203
+ const effectiveDeadline = extendedDeadline ?? deadline;
204
+ const hasReachedQuorum = votes.forVotes.gte(quorum);
205
+ const isVotingPeriodOver = ethers_1.BigNumber.from(currentBlock).gt(effectiveDeadline);
206
+ return {
207
+ startBlock,
208
+ endBlock: deadline,
209
+ deadline: effectiveDeadline,
210
+ forVotes: votes.forVotes,
211
+ againstVotes: votes.againstVotes,
212
+ abstainVotes: votes.abstainVotes,
213
+ quorum,
214
+ hasReachedQuorum,
215
+ isVotingPeriodOver,
216
+ extendedDeadline,
217
+ vettingDeadline,
218
+ isVettingPeriod,
219
+ };
220
+ }
221
+ /**
222
+ * Find ProposalQueued event for a proposal
223
+ *
224
+ * Note: ProposalQueued(uint256 proposalId, uint256 eta) has NON-INDEXED parameters,
225
+ * so we cannot filter by proposalId in topics. We must search for all ProposalQueued
226
+ * events and decode the data to find the matching proposalId.
227
+ *
228
+ * @param hint - Search optimization hint. Default is backward search from current block.
229
+ */
230
+ async function findProposalQueuedEvent(governorAddress, proposalId, provider, hint) {
231
+ const { blockNumber: currentBlock } = await (0, timing_1.getCurrentBlockInfo)(provider);
232
+ // Apply search hint (default: search backward from current block)
233
+ const fromBlock = hint?.startBlock ?? constants_1.GOVERNANCE_START_BLOCKS.L2;
234
+ const toBlock = hint?.endBlock ?? currentBlock;
235
+ const reverseDirection = hint?.direction === "backward" || !hint?.direction;
236
+ const targetProposalId = ethers_1.BigNumber.from(proposalId);
237
+ // ProposalQueued has non-indexed parameters, so we search by event signature only
238
+ // and decode the data to match the proposalId
239
+ const log = await (0, log_search_1.findLog)(provider, {
240
+ address: governorAddress,
241
+ topics: [constants_1.EVENT_TOPICS.PROPOSAL_QUEUED],
242
+ fromBlock,
243
+ toBlock,
244
+ }, (logEntry) => {
245
+ try {
246
+ const parsed = abis_1.proposalQueuedInterface.parseLog(logEntry);
247
+ return parsed.args.proposalId.eq(targetProposalId);
248
+ }
249
+ catch {
250
+ return false;
251
+ }
252
+ }, { chunkSize: 10000000, reverseDirection });
253
+ if (!log) {
254
+ return null;
255
+ }
256
+ try {
257
+ const parsed = abis_1.proposalQueuedInterface.parseLog(log);
258
+ return {
259
+ blockNumber: log.blockNumber,
260
+ txHash: log.transactionHash,
261
+ eta: parsed.args.eta,
262
+ };
263
+ }
264
+ catch {
265
+ return null;
266
+ }
267
+ }
268
+ // Discovery Functions (merged from monitor-discovery.ts)
269
+ /** Discover proposals from a governor in a block range */
270
+ async function discoverProposals(governorAddress, fromBlock, toBlock, provider, options = {}) {
271
+ if (fromBlock >= toBlock)
272
+ return [];
273
+ const { logs } = await (0, log_search_1.searchLogsInChunks)(provider, { address: governorAddress, topics: [constants_1.EVENT_TOPICS.PROPOSAL_CREATED], fromBlock, toBlock }, { chunkSize: options.chunkSize ?? constants_1.CHUNK_SIZES.L2 });
274
+ const seen = new Set();
275
+ return logs.flatMap((log) => {
276
+ if (seen.has(log.transactionHash))
277
+ return [];
278
+ seen.add(log.transactionHash);
279
+ const parsed = parseProposalCreatedEvent(log);
280
+ return parsed
281
+ ? [
282
+ {
283
+ governorAddress,
284
+ proposalId: parsed.proposalId,
285
+ creationTxHash: log.transactionHash,
286
+ creationBlock: log.blockNumber,
287
+ },
288
+ ]
289
+ : [];
290
+ });
291
+ }
292
+ /** Discover a proposal by transaction hash */
293
+ async function discoverProposalByTxHash(txHash, provider) {
294
+ const receipt = await (0, rpc_utils_1.queryWithRetry)(() => provider.getTransactionReceipt(txHash));
295
+ if (!receipt)
296
+ return null;
297
+ const log = receipt.logs.find((l) => l.topics[0] === constants_1.EVENT_TOPICS.PROPOSAL_CREATED);
298
+ if (!log)
299
+ return null;
300
+ const parsed = parseProposalCreatedEvent(log);
301
+ return parsed
302
+ ? {
303
+ governorAddress: log.address,
304
+ proposalId: parsed.proposalId,
305
+ creationTxHash: txHash,
306
+ creationBlock: receipt.blockNumber,
307
+ }
308
+ : null;
309
+ }
310
+ //# sourceMappingURL=governor-discovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"governor-discovery.js","sourceRoot":"","sources":["../../src/discovery/governor-discovery.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Security Council special handling
3
+ *
4
+ * Detect Security Council updates, handle vetting periods, generate salts
5
+ */
6
+ import { BigNumber, ethers } from "ethers";
7
+ /**
8
+ * Check vetting period for a Security Council nominee election
9
+ *
10
+ * IMPORTANT: The vetting deadline is an L1 block number, not an L2 block number.
11
+ * We must compare against the L1 block number (via ArbSys) to determine if
12
+ * vetting is still active. This is consistent with how voting deadlines work.
13
+ */
14
+ export declare function checkVettingPeriod(governorAddress: string, proposalId: string, provider: ethers.providers.Provider): Promise<{
15
+ hasVettingPeriod: boolean;
16
+ vettingDeadline: BigNumber | null;
17
+ isVettingActive: boolean;
18
+ vetterAddress: string | null;
19
+ }>;
20
+ /**
21
+ * Detect if a proposal is a Security Council election
22
+ */
23
+ export declare function isSecurityCouncilElectionProposal(targets: string[]): boolean;
24
+ /**
25
+ * Extracted Security Council operation parameters
26
+ */
27
+ export interface SecurityCouncilOperationParams {
28
+ members: string[];
29
+ nonce: BigNumber;
30
+ timelockAddress: string;
31
+ /** Operation ID for this specific operation */
32
+ operationId?: string;
33
+ }
34
+ /**
35
+ * All Security Council operations in a batch transaction
36
+ */
37
+ export interface SecurityCouncilBatchParams {
38
+ /** All operations with their individual params */
39
+ operations: SecurityCouncilOperationParams[];
40
+ /** Common timelock address */
41
+ timelockAddress: string;
42
+ }
43
+ /**
44
+ * Check if a transaction receipt is a Security Council operation
45
+ */
46
+ export declare function isSecurityCouncilOperation(receipt: ethers.providers.TransactionReceipt): boolean;
47
+ /**
48
+ * Extract Security Council params for ALL operations from a CallScheduled receipt
49
+ *
50
+ * SC rotations create MULTIPLE operations in a single transaction, each with
51
+ * its own incrementing nonce. This function returns params for every operation.
52
+ */
53
+ export declare function extractAllSecurityCouncilParams(receipt: ethers.providers.TransactionReceipt): SecurityCouncilBatchParams | null;
54
+ /**
55
+ * Extract Security Council params for a specific operation by operationId
56
+ *
57
+ * Use this when you need the salt for a specific operation in a multi-operation
58
+ * SC rotation batch. Each operation has its own nonce and therefore its own salt.
59
+ */
60
+ export declare function extractSecurityCouncilParamsForOperation(receipt: ethers.providers.TransactionReceipt, targetOperationId: string): SecurityCouncilOperationParams | null;
61
+ /**
62
+ * Extract Security Council params for the last operation in a batch
63
+ *
64
+ * Returns the last operation. Use extractSecurityCouncilParamsForOperation
65
+ * for specific operation lookups.
66
+ */
67
+ export declare function extractSecurityCouncilParams(receipt: ethers.providers.TransactionReceipt): SecurityCouncilOperationParams | null;
68
+ //# sourceMappingURL=security-council.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security-council.d.ts","sourceRoot":"","sources":["../../src/discovery/security-council.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAa3C;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,eAAe,EAAE,MAAM,EACvB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,CAAC,SAAS,CAAC,QAAQ,GAClC,OAAO,CAAC;IACT,gBAAgB,EAAE,OAAO,CAAC;IAC1B,eAAe,EAAE,SAAS,GAAG,IAAI,CAAC;IAClC,eAAe,EAAE,OAAO,CAAC;IACzB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B,CAAC,CAwCD;AAED;;GAEG;AACH,wBAAgB,iCAAiC,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAE5E;AAED;;GAEG;AACH,MAAM,WAAW,8BAA8B;IAC7C,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,EAAE,SAAS,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,+CAA+C;IAC/C,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,kDAAkD;IAClD,UAAU,EAAE,8BAA8B,EAAE,CAAC;IAC7C,8BAA8B;IAC9B,eAAe,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,MAAM,CAAC,SAAS,CAAC,kBAAkB,GAAG,OAAO,CAEhG;AA0CD;;;;;GAKG;AACH,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,MAAM,CAAC,SAAS,CAAC,kBAAkB,GAC3C,0BAA0B,GAAG,IAAI,CAkDnC;AAED;;;;;GAKG;AACH,wBAAgB,wCAAwC,CACtD,OAAO,EAAE,MAAM,CAAC,SAAS,CAAC,kBAAkB,EAC5C,iBAAiB,EAAE,MAAM,GACxB,8BAA8B,GAAG,IAAI,CAWvC;AAED;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,MAAM,CAAC,SAAS,CAAC,kBAAkB,GAC3C,8BAA8B,GAAG,IAAI,CAMvC"}
@@ -0,0 +1,181 @@
1
+ "use strict";
2
+ /**
3
+ * Security Council special handling
4
+ *
5
+ * Detect Security Council updates, handle vetting periods, generate salts
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.checkVettingPeriod = checkVettingPeriod;
9
+ exports.isSecurityCouncilElectionProposal = isSecurityCouncilElectionProposal;
10
+ exports.isSecurityCouncilOperation = isSecurityCouncilOperation;
11
+ exports.extractAllSecurityCouncilParams = extractAllSecurityCouncilParams;
12
+ exports.extractSecurityCouncilParamsForOperation = extractSecurityCouncilParamsForOperation;
13
+ exports.extractSecurityCouncilParams = extractSecurityCouncilParams;
14
+ const ethers_1 = require("ethers");
15
+ const constants_1 = require("../constants");
16
+ const rpc_utils_1 = require("../utils/rpc-utils");
17
+ const timing_1 = require("../utils/timing");
18
+ const chain_1 = require("../utils/chain");
19
+ const abis_1 = require("../abis");
20
+ /**
21
+ * Check vetting period for a Security Council nominee election
22
+ *
23
+ * IMPORTANT: The vetting deadline is an L1 block number, not an L2 block number.
24
+ * We must compare against the L1 block number (via ArbSys) to determine if
25
+ * vetting is still active. This is consistent with how voting deadlines work.
26
+ */
27
+ async function checkVettingPeriod(governorAddress, proposalId, provider) {
28
+ const governor = new ethers_1.ethers.Contract(governorAddress, abis_1.GOVERNOR_WITH_VETTER_ABI, provider);
29
+ try {
30
+ // First check if this governor has vetting functionality
31
+ const [vettingDeadline, vetterAddress] = await Promise.all([
32
+ (0, rpc_utils_1.queryWithRetry)(() => governor.proposalVettingDeadline(proposalId)),
33
+ (0, rpc_utils_1.queryWithRetry)(() => governor.vetter()),
34
+ ]);
35
+ // If no vetting deadline set, no vetting period
36
+ if (!vettingDeadline.gt(0)) {
37
+ return {
38
+ hasVettingPeriod: false,
39
+ vettingDeadline: null,
40
+ isVettingActive: false,
41
+ vetterAddress,
42
+ };
43
+ }
44
+ // CRITICAL: The vetting deadline is an L1 block number.
45
+ // We need to get the current L1 block number via Multicall3.
46
+ const currentL1Block = await (0, timing_1.getL1BlockNumberFromL2)(provider);
47
+ const isVettingActive = currentL1Block.lte(vettingDeadline);
48
+ return {
49
+ hasVettingPeriod: true,
50
+ vettingDeadline,
51
+ isVettingActive,
52
+ vetterAddress,
53
+ };
54
+ }
55
+ catch {
56
+ // Governor doesn't have vetting functionality
57
+ return {
58
+ hasVettingPeriod: false,
59
+ vettingDeadline: null,
60
+ isVettingActive: false,
61
+ vetterAddress: null,
62
+ };
63
+ }
64
+ }
65
+ /**
66
+ * Detect if a proposal is a Security Council election
67
+ */
68
+ function isSecurityCouncilElectionProposal(targets) {
69
+ return targets.some((target) => (0, chain_1.addressEquals)(target, constants_1.ADDRESSES.SECURITY_COUNCIL_MANAGER));
70
+ }
71
+ /**
72
+ * Check if a transaction receipt is a Security Council operation
73
+ */
74
+ function isSecurityCouncilOperation(receipt) {
75
+ return receipt.logs.some((log) => (0, chain_1.addressEquals)(log.address, constants_1.ADDRESSES.SECURITY_COUNCIL_MANAGER));
76
+ }
77
+ /**
78
+ * Extract members and nonce from CallScheduled event data
79
+ *
80
+ * The extraction follows this data nesting:
81
+ * 1. CallScheduled event contains data for ArbSys.sendTxToL1
82
+ * 2. sendTxToL1 contains data for L1Timelock.scheduleBatch
83
+ * 3. scheduleBatch's first payload contains UpgradeExecutor.execute
84
+ * 4. execute contains SecurityCouncilMemberSyncAction.perform(council, members, nonce)
85
+ */
86
+ function extractMembersAndNonceFromCallData(data) {
87
+ try {
88
+ // Step 1: Decode ArbSys.sendTxToL1(destination, data)
89
+ const sendTxToL1Data = abis_1.arbSysInterface.decodeFunctionData("sendTxToL1", data);
90
+ const l1TimelockData = sendTxToL1Data[1];
91
+ // Step 2: Decode L1Timelock.scheduleBatch(...)
92
+ const scheduleBatchData = abis_1.timelockInterface.decodeFunctionData("scheduleBatch", l1TimelockData);
93
+ const payloads = scheduleBatchData[2];
94
+ if (payloads.length === 0) {
95
+ return null;
96
+ }
97
+ // Step 3: Decode UpgradeExecutor.execute(upgrade, data)
98
+ const executeData = abis_1.upgradeExecutorInterface.decodeFunctionData("execute", payloads[0]);
99
+ const actionData = executeData[1];
100
+ // Step 4: Decode SecurityCouncilMemberSyncAction.perform(council, members, nonce)
101
+ const performData = abis_1.memberSyncActionInterface.decodeFunctionData("perform", actionData);
102
+ const members = performData[1];
103
+ const nonce = performData[2];
104
+ return { members, nonce };
105
+ }
106
+ catch {
107
+ return null;
108
+ }
109
+ }
110
+ /**
111
+ * Extract Security Council params for ALL operations from a CallScheduled receipt
112
+ *
113
+ * SC rotations create MULTIPLE operations in a single transaction, each with
114
+ * its own incrementing nonce. This function returns params for every operation.
115
+ */
116
+ function extractAllSecurityCouncilParams(receipt) {
117
+ if (!isSecurityCouncilOperation(receipt)) {
118
+ return null;
119
+ }
120
+ const callScheduledLogs = receipt.logs.filter((log) => log.topics[0] === constants_1.EVENT_TOPICS.CALL_SCHEDULED);
121
+ if (callScheduledLogs.length === 0) {
122
+ return null;
123
+ }
124
+ // Validate all CallScheduled logs come from the same timelock
125
+ // SC operations should all target the same L2 timelock
126
+ const timelockAddress = callScheduledLogs[0].address;
127
+ const hasMultipleTimelocks = callScheduledLogs.some((log) => !(0, chain_1.addressEquals)(log.address, timelockAddress));
128
+ if (hasMultipleTimelocks) {
129
+ // This shouldn't happen for SC operations, but guard against it
130
+ return null;
131
+ }
132
+ const operations = [];
133
+ for (const log of callScheduledLogs) {
134
+ const parsed = abis_1.timelockInterface.parseLog(log);
135
+ const operationId = parsed.args.id;
136
+ const callData = parsed.args.data;
137
+ const extracted = extractMembersAndNonceFromCallData(callData);
138
+ if (extracted) {
139
+ operations.push({
140
+ members: extracted.members,
141
+ nonce: extracted.nonce,
142
+ timelockAddress: log.address,
143
+ operationId,
144
+ });
145
+ }
146
+ }
147
+ if (operations.length === 0) {
148
+ return null;
149
+ }
150
+ return {
151
+ operations,
152
+ timelockAddress,
153
+ };
154
+ }
155
+ /**
156
+ * Extract Security Council params for a specific operation by operationId
157
+ *
158
+ * Use this when you need the salt for a specific operation in a multi-operation
159
+ * SC rotation batch. Each operation has its own nonce and therefore its own salt.
160
+ */
161
+ function extractSecurityCouncilParamsForOperation(receipt, targetOperationId) {
162
+ const batch = extractAllSecurityCouncilParams(receipt);
163
+ if (!batch) {
164
+ return null;
165
+ }
166
+ return (batch.operations.find((op) => op.operationId && (0, chain_1.addressEquals)(op.operationId, targetOperationId)) ?? null);
167
+ }
168
+ /**
169
+ * Extract Security Council params for the last operation in a batch
170
+ *
171
+ * Returns the last operation. Use extractSecurityCouncilParamsForOperation
172
+ * for specific operation lookups.
173
+ */
174
+ function extractSecurityCouncilParams(receipt) {
175
+ const batch = extractAllSecurityCouncilParams(receipt);
176
+ if (!batch || batch.operations.length === 0) {
177
+ return null;
178
+ }
179
+ return batch.operations[batch.operations.length - 1];
180
+ }
181
+ //# sourceMappingURL=security-council.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security-council.js","sourceRoot":"","sources":["../../src/discovery/security-council.ts"],"names":[],"mappings":"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"}