@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,99 @@
1
+ /**
2
+ * Timelock discovery module
3
+ *
4
+ * Parse CallScheduled events, check timelock state, find operations
5
+ */
6
+ import { BigNumber, ethers } from "ethers";
7
+ import { CallExecutedData, CallScheduledData, TimelockOperationState, TimelockState, SearchHint } from "../types";
8
+ /**
9
+ * Check if address is a known L2 timelock
10
+ */
11
+ export declare function isKnownL2Timelock(address: string): boolean;
12
+ /**
13
+ * Check if address is the L1 timelock
14
+ */
15
+ export declare function isL1Timelock(address: string): boolean;
16
+ /**
17
+ * Get timelock operation state directly from contract (fast path)
18
+ *
19
+ * This is the critical fast-path optimization: 4 cheap state reads
20
+ * instead of expensive log searches
21
+ */
22
+ export declare function getTimelockOperationState(timelockAddress: string, operationId: string, provider: ethers.providers.Provider): Promise<{
23
+ state: TimelockOperationState;
24
+ isOperation: boolean;
25
+ isPending: boolean;
26
+ isReady: boolean;
27
+ isDone: boolean;
28
+ timestamp: BigNumber;
29
+ }>;
30
+ /**
31
+ * Parse CallScheduled event data
32
+ */
33
+ export declare function parseCallScheduledEvent(log: ethers.providers.Log): CallScheduledData | null;
34
+ /**
35
+ * Parse CallExecuted event data
36
+ */
37
+ export declare function parseCallExecutedEvent(log: ethers.providers.Log): CallExecutedData | null;
38
+ /**
39
+ * Find CallScheduled event by operation ID
40
+ *
41
+ * @param hint - Search optimization hint. When startBlock is provided, defaults to forward search.
42
+ */
43
+ export declare function findCallScheduledEvent(timelockAddress: string, operationId: string, provider: ethers.providers.Provider, hint?: SearchHint): Promise<CallScheduledData | null>;
44
+ /**
45
+ * Find CallScheduled event by transaction hash
46
+ */
47
+ export declare function findCallScheduledByTxHash(txHash: string, provider: ethers.providers.Provider): Promise<CallScheduledData[] | undefined>;
48
+ /**
49
+ * Find CallExecuted event by operation ID
50
+ *
51
+ * @param hint - Search optimization hint. When startBlock is provided, defaults to forward search.
52
+ */
53
+ export declare function findCallExecutedEvent(timelockAddress: string, operationId: string, provider: ethers.providers.Provider, hint?: SearchHint): Promise<CallExecutedData | null>;
54
+ /**
55
+ * Get full timelock state with fast-path optimization
56
+ *
57
+ * CRITICAL: Always use fast-path first, then search logs only when needed
58
+ *
59
+ * @param options.fromBlock - REQUIRED when not skipping log search. Start block for event searches.
60
+ * @param options.scheduledData - Pre-fetched CallScheduledData to skip log search
61
+ */
62
+ export declare function getTimelockState(timelockAddress: string, operationId: string, provider: ethers.providers.Provider, options?: {
63
+ fromBlock?: number;
64
+ toBlock?: number;
65
+ skipLogSearch?: boolean;
66
+ /** Pre-fetched scheduled data - skips CallScheduled search if provided */
67
+ scheduledData?: CallScheduledData;
68
+ /** All scheduled data for batch operations */
69
+ allScheduledData?: CallScheduledData[];
70
+ }): Promise<TimelockState>;
71
+ /**
72
+ * Find all CallScheduled events from a transaction for a specific operation ID.
73
+ *
74
+ * A BATCH operation is when multiple CallScheduled events share the same `id` (operationId)
75
+ * but have different `index` values. This is different from multiple SEPARATE operations
76
+ * in a single transaction (which would have different `id` values).
77
+ *
78
+ * @param txHash - Transaction hash to search
79
+ * @param provider - Provider to use
80
+ * @param operationId - Operation ID to filter by (only includes events with this ID)
81
+ * @returns Array of CallScheduledData for the specified operation, sorted by index
82
+ */
83
+ export declare function findAllCallScheduledInTx(txHash: string, provider: ethers.providers.Provider, operationId?: string): Promise<CallScheduledData[]>;
84
+ /**
85
+ * Get the L2 timelock address for a governor type
86
+ */
87
+ export declare function getL2TimelockForGovernor(governorAddress: string): string | null;
88
+ /** Discovered timelock operation from CallScheduled event */
89
+ export interface DiscoveredTimelockOp {
90
+ timelockAddress: string;
91
+ operationId: string;
92
+ scheduledTxHash: string;
93
+ queueBlock: number;
94
+ }
95
+ /** Discover timelock operations in a block range */
96
+ export declare function discoverTimelockOps(timelockAddress: string, fromBlock: number, toBlock: number, provider: ethers.providers.Provider, options?: {
97
+ chunkSize?: number;
98
+ }): Promise<DiscoveredTimelockOp[]>;
99
+ //# sourceMappingURL=timelock-discovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timelock-discovery.d.ts","sourceRoot":"","sources":["../../src/discovery/timelock-discovery.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,322 @@
1
+ "use strict";
2
+ /**
3
+ * Timelock discovery module
4
+ *
5
+ * Parse CallScheduled events, check timelock state, find operations
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.isKnownL2Timelock = isKnownL2Timelock;
9
+ exports.isL1Timelock = isL1Timelock;
10
+ exports.getTimelockOperationState = getTimelockOperationState;
11
+ exports.parseCallScheduledEvent = parseCallScheduledEvent;
12
+ exports.parseCallExecutedEvent = parseCallExecutedEvent;
13
+ exports.findCallScheduledEvent = findCallScheduledEvent;
14
+ exports.findCallScheduledByTxHash = findCallScheduledByTxHash;
15
+ exports.findCallExecutedEvent = findCallExecutedEvent;
16
+ exports.getTimelockState = getTimelockState;
17
+ exports.findAllCallScheduledInTx = findAllCallScheduledInTx;
18
+ exports.getL2TimelockForGovernor = getL2TimelockForGovernor;
19
+ exports.discoverTimelockOps = discoverTimelockOps;
20
+ const ethers_1 = require("ethers");
21
+ const constants_1 = require("../constants");
22
+ const log_search_1 = require("../utils/log-search");
23
+ const log_search_2 = 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 chain_1 = require("../utils/chain");
28
+ const abis_1 = require("../abis");
29
+ const L2_TIMELOCKS = [
30
+ constants_1.ADDRESSES.L2_CONSTITUTIONAL_TIMELOCK,
31
+ constants_1.ADDRESSES.L2_NON_CONSTITUTIONAL_TIMELOCK,
32
+ ];
33
+ /**
34
+ * Check if address is a known L2 timelock
35
+ */
36
+ function isKnownL2Timelock(address) {
37
+ return (0, chain_1.isAddressIn)(address, L2_TIMELOCKS);
38
+ }
39
+ /**
40
+ * Check if address is the L1 timelock
41
+ */
42
+ function isL1Timelock(address) {
43
+ return (0, chain_1.addressEquals)(address, constants_1.ADDRESSES.L1_TIMELOCK);
44
+ }
45
+ /**
46
+ * Get search defaults for timelock event searches.
47
+ * Encapsulates chain-appropriate chunk sizes, default blocks, and direction logic.
48
+ */
49
+ async function getSearchDefaults(timelockAddress, provider, hint) {
50
+ const isL1 = isL1Timelock(timelockAddress);
51
+ const chunkSize = isL1 ? 10000 : 10000000;
52
+ const defaultStartBlock = isL1 ? constants_1.GOVERNANCE_START_BLOCKS.L1 : constants_1.GOVERNANCE_START_BLOCKS.L2;
53
+ const toBlock = hint?.endBlock ?? (await (0, timing_1.getCurrentBlockInfo)(provider)).blockNumber;
54
+ const fromBlock = hint?.startBlock ?? defaultStartBlock;
55
+ // When startBlock is provided, default to forward search (more efficient)
56
+ // When no startBlock, default to backward search (find most recent)
57
+ const reverseDirection = hint?.direction === "backward" || (hint?.direction !== "forward" && !hint?.startBlock);
58
+ return { chunkSize, fromBlock, toBlock, reverseDirection };
59
+ }
60
+ /**
61
+ * Get timelock operation state directly from contract (fast path)
62
+ *
63
+ * This is the critical fast-path optimization: 4 cheap state reads
64
+ * instead of expensive log searches
65
+ */
66
+ async function getTimelockOperationState(timelockAddress, operationId, provider) {
67
+ const timelock = new ethers_1.ethers.Contract(timelockAddress, abis_1.TIMELOCK_ABI, provider);
68
+ // Fast parallel state checks
69
+ const [isOperation, isPending, isReady, isDone, timestamp] = await Promise.all([
70
+ (0, rpc_utils_1.queryWithRetry)(() => timelock.isOperation(operationId)),
71
+ (0, rpc_utils_1.queryWithRetry)(() => timelock.isOperationPending(operationId)),
72
+ (0, rpc_utils_1.queryWithRetry)(() => timelock.isOperationReady(operationId)),
73
+ (0, rpc_utils_1.queryWithRetry)(() => timelock.isOperationDone(operationId)),
74
+ (0, rpc_utils_1.queryWithRetry)(() => timelock.getTimestamp(operationId)),
75
+ ]);
76
+ let state = "UNKNOWN";
77
+ if (!isOperation) {
78
+ state = "UNKNOWN";
79
+ }
80
+ else if (isDone) {
81
+ state = "DONE";
82
+ }
83
+ else if (isReady) {
84
+ state = "READY";
85
+ }
86
+ else if (isPending) {
87
+ state = "PENDING";
88
+ }
89
+ return {
90
+ state,
91
+ isOperation,
92
+ isPending,
93
+ isReady,
94
+ isDone,
95
+ timestamp,
96
+ };
97
+ }
98
+ /**
99
+ * Parse CallScheduled event data
100
+ */
101
+ function parseCallScheduledEvent(log) {
102
+ try {
103
+ const parsed = abis_1.timelockInterface.parseLog(log);
104
+ return {
105
+ operationId: parsed.args.id,
106
+ index: parsed.args.index,
107
+ target: parsed.args.target,
108
+ value: parsed.args.value,
109
+ data: parsed.args.data,
110
+ predecessor: parsed.args.predecessor,
111
+ delay: parsed.args.delay,
112
+ blockNumber: log.blockNumber,
113
+ txHash: log.transactionHash,
114
+ logIndex: log.logIndex,
115
+ timelockAddress: log.address,
116
+ };
117
+ }
118
+ catch {
119
+ return null;
120
+ }
121
+ }
122
+ /**
123
+ * Parse CallExecuted event data
124
+ */
125
+ function parseCallExecutedEvent(log) {
126
+ try {
127
+ const parsed = abis_1.timelockInterface.parseLog(log);
128
+ return {
129
+ operationId: parsed.args.id,
130
+ index: parsed.args.index,
131
+ target: parsed.args.target,
132
+ value: parsed.args.value,
133
+ data: parsed.args.data,
134
+ blockNumber: log.blockNumber,
135
+ txHash: log.transactionHash,
136
+ logIndex: log.logIndex,
137
+ };
138
+ }
139
+ catch {
140
+ return null;
141
+ }
142
+ }
143
+ /**
144
+ * Find CallScheduled event by operation ID
145
+ *
146
+ * @param hint - Search optimization hint. When startBlock is provided, defaults to forward search.
147
+ */
148
+ async function findCallScheduledEvent(timelockAddress, operationId, provider, hint) {
149
+ const { chunkSize, fromBlock, toBlock, reverseDirection } = await getSearchDefaults(timelockAddress, provider, hint);
150
+ return (0, log_search_2.findAndParseEvent)(provider, {
151
+ address: timelockAddress,
152
+ topics: [constants_1.EVENT_TOPICS.CALL_SCHEDULED, operationId],
153
+ fromBlock,
154
+ toBlock,
155
+ }, (0, log_search_2.createOperationIdPredicate)(operationId, chain_1.addressEquals), parseCallScheduledEvent, { chunkSize, reverseDirection });
156
+ }
157
+ /**
158
+ * Find CallScheduled event by transaction hash
159
+ */
160
+ async function findCallScheduledByTxHash(txHash, provider) {
161
+ const receipt = await (0, rpc_utils_1.queryWithRetry)(() => provider.getTransactionReceipt(txHash));
162
+ if (!receipt) {
163
+ return undefined;
164
+ }
165
+ const results = (0, log_filters_1.findAndParseLogs)(receipt.logs, { topic: constants_1.EVENT_TOPICS.CALL_SCHEDULED }, parseCallScheduledEvent);
166
+ return results.length > 0 ? results : undefined;
167
+ }
168
+ /**
169
+ * Find CallExecuted event by operation ID
170
+ *
171
+ * @param hint - Search optimization hint. When startBlock is provided, defaults to forward search.
172
+ */
173
+ async function findCallExecutedEvent(timelockAddress, operationId, provider, hint) {
174
+ const { chunkSize, fromBlock, toBlock, reverseDirection } = await getSearchDefaults(timelockAddress, provider, hint);
175
+ return (0, log_search_2.findAndParseEvent)(provider, {
176
+ address: timelockAddress,
177
+ topics: [constants_1.EVENT_TOPICS.CALL_EXECUTED, operationId],
178
+ fromBlock,
179
+ toBlock,
180
+ }, (0, log_search_2.createOperationIdPredicate)(operationId, chain_1.addressEquals), parseCallExecutedEvent, { chunkSize, reverseDirection });
181
+ }
182
+ /**
183
+ * Get full timelock state with fast-path optimization
184
+ *
185
+ * CRITICAL: Always use fast-path first, then search logs only when needed
186
+ *
187
+ * @param options.fromBlock - REQUIRED when not skipping log search. Start block for event searches.
188
+ * @param options.scheduledData - Pre-fetched CallScheduledData to skip log search
189
+ */
190
+ async function getTimelockState(timelockAddress, operationId, provider, options = {}) {
191
+ // FAST PATH: Check state before expensive log search
192
+ const contractState = await getTimelockOperationState(timelockAddress, operationId, provider);
193
+ const state = {
194
+ operationId,
195
+ state: contractState.state,
196
+ isReady: contractState.isReady,
197
+ isDone: contractState.isDone,
198
+ };
199
+ // Calculate ETA from timestamp
200
+ if (contractState.timestamp.gt(0) && !contractState.isDone) {
201
+ state.eta = contractState.timestamp.toNumber();
202
+ }
203
+ // Use pre-fetched scheduled data if provided (avoids log search entirely)
204
+ if (options.scheduledData) {
205
+ state.scheduledData = options.scheduledData;
206
+ if (options.allScheduledData && options.allScheduledData.length > 1) {
207
+ state.allScheduledData = options.allScheduledData;
208
+ state.isBatch = true;
209
+ }
210
+ }
211
+ // SLOW PATH: Only search for logs when needed and not already provided
212
+ if (!options.skipLogSearch && !state.scheduledData) {
213
+ // fromBlock is required for log searches
214
+ if (options.fromBlock === undefined) {
215
+ throw new Error("fromBlock is required when searching logs in getTimelockState");
216
+ }
217
+ const fromBlock = options.fromBlock; // Store validated value for TypeScript
218
+ // Only search for scheduled data if the operation exists
219
+ if (contractState.isOperation) {
220
+ const scheduledData = await findCallScheduledEvent(timelockAddress, operationId, provider, {
221
+ startBlock: fromBlock,
222
+ endBlock: options.toBlock,
223
+ });
224
+ if (scheduledData) {
225
+ state.scheduledData = scheduledData;
226
+ // Check if this is a batch operation by looking for multiple CallScheduled events
227
+ // with the SAME operationId (not just any events in the same tx)
228
+ const allScheduledData = await findAllCallScheduledInTx(scheduledData.txHash, provider, operationId);
229
+ if (allScheduledData.length > 1) {
230
+ state.allScheduledData = allScheduledData;
231
+ state.isBatch = true;
232
+ }
233
+ }
234
+ }
235
+ }
236
+ // Only search for executed data if the operation is done
237
+ if (!options.skipLogSearch && contractState.isDone) {
238
+ // fromBlock is required for log searches
239
+ if (options.fromBlock === undefined) {
240
+ throw new Error("fromBlock is required when searching logs in getTimelockState");
241
+ }
242
+ // Use scheduledData blockNumber if available, otherwise use fromBlock
243
+ const executedSearchStart = state.scheduledData?.blockNumber ?? options.fromBlock;
244
+ const executedData = await findCallExecutedEvent(timelockAddress, operationId, provider, {
245
+ startBlock: executedSearchStart,
246
+ endBlock: options.toBlock,
247
+ });
248
+ if (executedData) {
249
+ state.executedData = executedData;
250
+ }
251
+ }
252
+ return state;
253
+ }
254
+ /**
255
+ * Find all CallScheduled events from a transaction for a specific operation ID.
256
+ *
257
+ * A BATCH operation is when multiple CallScheduled events share the same `id` (operationId)
258
+ * but have different `index` values. This is different from multiple SEPARATE operations
259
+ * in a single transaction (which would have different `id` values).
260
+ *
261
+ * @param txHash - Transaction hash to search
262
+ * @param provider - Provider to use
263
+ * @param operationId - Operation ID to filter by (only includes events with this ID)
264
+ * @returns Array of CallScheduledData for the specified operation, sorted by index
265
+ */
266
+ async function findAllCallScheduledInTx(txHash, provider, operationId) {
267
+ const receipt = await (0, rpc_utils_1.queryWithRetry)(() => provider.getTransactionReceipt(txHash));
268
+ if (!receipt) {
269
+ return [];
270
+ }
271
+ const results = [];
272
+ for (const log of receipt.logs) {
273
+ if (log.topics[0] === constants_1.EVENT_TOPICS.CALL_SCHEDULED) {
274
+ const parsed = parseCallScheduledEvent(log);
275
+ if (parsed) {
276
+ // If operationId is specified, only include events with that ID
277
+ // This distinguishes a batch (same ID, different index) from
278
+ // multiple separate operations (different IDs)
279
+ if (!operationId || (0, chain_1.addressEquals)(parsed.operationId, operationId)) {
280
+ results.push(parsed);
281
+ }
282
+ }
283
+ }
284
+ }
285
+ // Sort by index to maintain order
286
+ return results.sort((a, b) => a.index.toNumber() - b.index.toNumber());
287
+ }
288
+ /**
289
+ * Get the L2 timelock address for a governor type
290
+ */
291
+ function getL2TimelockForGovernor(governorAddress) {
292
+ const normalized = governorAddress.toLowerCase();
293
+ if (normalized === constants_1.ADDRESSES.CONSTITUTIONAL_GOVERNOR.toLowerCase()) {
294
+ return constants_1.ADDRESSES.L2_CONSTITUTIONAL_TIMELOCK;
295
+ }
296
+ if (normalized === constants_1.ADDRESSES.NON_CONSTITUTIONAL_GOVERNOR.toLowerCase()) {
297
+ return constants_1.ADDRESSES.L2_NON_CONSTITUTIONAL_TIMELOCK;
298
+ }
299
+ return null;
300
+ }
301
+ /** Discover timelock operations in a block range */
302
+ async function discoverTimelockOps(timelockAddress, fromBlock, toBlock, provider, options = {}) {
303
+ if (fromBlock >= toBlock)
304
+ return [];
305
+ const { logs } = await (0, log_search_1.searchLogsInChunks)(provider, { address: timelockAddress, topics: [constants_1.EVENT_TOPICS.CALL_SCHEDULED], fromBlock, toBlock }, { chunkSize: options.chunkSize ?? constants_1.CHUNK_SIZES.L2 });
306
+ const seen = new Set();
307
+ return logs.flatMap((log) => {
308
+ const operationId = log.topics[1];
309
+ if (seen.has(operationId))
310
+ return [];
311
+ seen.add(operationId);
312
+ return [
313
+ {
314
+ timelockAddress,
315
+ operationId,
316
+ scheduledTxHash: log.transactionHash,
317
+ queueBlock: log.blockNumber,
318
+ },
319
+ ];
320
+ });
321
+ }
322
+ //# sourceMappingURL=timelock-discovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timelock-discovery.js","sourceRoot":"","sources":["../../src/discovery/timelock-discovery.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;AA2BH,8CAEC;AAKD,oCAEC;AAmCD,8DA2CC;AAKD,0DAoBC;AAKD,wDAiBC;AAOD,wDAwBC;AAKD,8DAiBC;AAOD,sDAwBC;AAUD,4CAwFC;AAcD,4DA6BC;AAKD,4DAYC;AAaD,kDA6BC;AA3bD,mCAA2C;AAQ3C,4CAA6F;AAC7F,oDAAyD;AACzD,oDAAoF;AACpF,sDAAwD;AACxD,kDAAoD;AACpD,4CAAsD;AACtD,0CAA4D;AAC5D,kCAA0D;AAE1D,MAAM,YAAY,GAAG;IACnB,qBAAS,CAAC,0BAA0B;IACpC,qBAAS,CAAC,8BAA8B;CAChC,CAAC;AAEX;;GAEG;AACH,SAAgB,iBAAiB,CAAC,OAAe;IAC/C,OAAO,IAAA,mBAAW,EAAC,OAAO,EAAE,YAAY,CAAC,CAAC;AAC5C,CAAC;AAED;;GAEG;AACH,SAAgB,YAAY,CAAC,OAAe;IAC1C,OAAO,IAAA,qBAAa,EAAC,OAAO,EAAE,qBAAS,CAAC,WAAW,CAAC,CAAC;AACvD,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,iBAAiB,CAC9B,eAAuB,EACvB,QAAmC,EACnC,IAAiB;IAOjB,MAAM,IAAI,GAAG,YAAY,CAAC,eAAe,CAAC,CAAC;IAC3C,MAAM,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC,KAAM,CAAC,CAAC,CAAC,QAAU,CAAC;IAC7C,MAAM,iBAAiB,GAAG,IAAI,CAAC,CAAC,CAAC,mCAAuB,CAAC,EAAE,CAAC,CAAC,CAAC,mCAAuB,CAAC,EAAE,CAAC;IACzF,MAAM,OAAO,GAAG,IAAI,EAAE,QAAQ,IAAI,CAAC,MAAM,IAAA,4BAAmB,EAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC;IACpF,MAAM,SAAS,GAAG,IAAI,EAAE,UAAU,IAAI,iBAAiB,CAAC;IACxD,0EAA0E;IAC1E,oEAAoE;IACpE,MAAM,gBAAgB,GACpB,IAAI,EAAE,SAAS,KAAK,UAAU,IAAI,CAAC,IAAI,EAAE,SAAS,KAAK,SAAS,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IAEzF,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,gBAAgB,EAAE,CAAC;AAC7D,CAAC;AAED;;;;;GAKG;AACI,KAAK,UAAU,yBAAyB,CAC7C,eAAuB,EACvB,WAAmB,EACnB,QAAmC;IASnC,MAAM,QAAQ,GAAG,IAAI,eAAM,CAAC,QAAQ,CAAC,eAAe,EAAE,mBAAY,EAAE,QAAQ,CAAC,CAAC;IAE9E,6BAA6B;IAC7B,MAAM,CAAC,WAAW,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAC7E,IAAA,0BAAc,EAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,WAAW,CAAC,CAAqB;QAC3E,IAAA,0BAAc,EAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC,WAAW,CAAC,CAAqB;QAClF,IAAA,0BAAc,EAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAqB;QAChF,IAAA,0BAAc,EAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC,WAAW,CAAC,CAAqB;QAC/E,IAAA,0BAAc,EAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC,WAAW,CAAC,CAAuB;KAC/E,CAAC,CAAC;IAEH,IAAI,KAAK,GAA2B,SAAS,CAAC;IAE9C,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,KAAK,GAAG,SAAS,CAAC;IACpB,CAAC;SAAM,IAAI,MAAM,EAAE,CAAC;QAClB,KAAK,GAAG,MAAM,CAAC;IACjB,CAAC;SAAM,IAAI,OAAO,EAAE,CAAC;QACnB,KAAK,GAAG,OAAO,CAAC;IAClB,CAAC;SAAM,IAAI,SAAS,EAAE,CAAC;QACrB,KAAK,GAAG,SAAS,CAAC;IACpB,CAAC;IAED,OAAO;QACL,KAAK;QACL,WAAW;QACX,SAAS;QACT,OAAO;QACP,MAAM;QACN,SAAS;KACV,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAgB,uBAAuB,CAAC,GAAyB;IAC/D,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,wBAAiB,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QAE/C,OAAO;YACL,WAAW,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE;YAC3B,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK;YACxB,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM;YAC1B,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK;YACxB,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI;YACtB,WAAW,EAAE,MAAM,CAAC,IAAI,CAAC,WAAW;YACpC,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK;YACxB,WAAW,EAAE,GAAG,CAAC,WAAW;YAC5B,MAAM,EAAE,GAAG,CAAC,eAAe;YAC3B,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,eAAe,EAAE,GAAG,CAAC,OAAO;SAC7B,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAgB,sBAAsB,CAAC,GAAyB;IAC9D,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,wBAAiB,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QAE/C,OAAO;YACL,WAAW,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE;YAC3B,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK;YACxB,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM;YAC1B,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK;YACxB,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI;YACtB,WAAW,EAAE,GAAG,CAAC,WAAW;YAC5B,MAAM,EAAE,GAAG,CAAC,eAAe;YAC3B,QAAQ,EAAE,GAAG,CAAC,QAAQ;SACvB,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;GAIG;AACI,KAAK,UAAU,sBAAsB,CAC1C,eAAuB,EACvB,WAAmB,EACnB,QAAmC,EACnC,IAAiB;IAEjB,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,gBAAgB,EAAE,GAAG,MAAM,iBAAiB,CACjF,eAAe,EACf,QAAQ,EACR,IAAI,CACL,CAAC;IAEF,OAAO,IAAA,8BAAiB,EACtB,QAAQ,EACR;QACE,OAAO,EAAE,eAAe;QACxB,MAAM,EAAE,CAAC,wBAAY,CAAC,cAAc,EAAE,WAAW,CAAC;QAClD,SAAS;QACT,OAAO;KACR,EACD,IAAA,uCAA0B,EAAC,WAAW,EAAE,qBAAa,CAAC,EACtD,uBAAuB,EACvB,EAAE,SAAS,EAAE,gBAAgB,EAAE,CAChC,CAAC;AACJ,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,yBAAyB,CAC7C,MAAc,EACd,QAAmC;IAEnC,MAAM,OAAO,GAAG,MAAM,IAAA,0BAAc,EAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC,CAAC;IAEnF,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,OAAO,GAAG,IAAA,8BAAgB,EAC9B,OAAO,CAAC,IAAI,EACZ,EAAE,KAAK,EAAE,wBAAY,CAAC,cAAc,EAAE,EACtC,uBAAuB,CACxB,CAAC;IAEF,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;AAClD,CAAC;AAED;;;;GAIG;AACI,KAAK,UAAU,qBAAqB,CACzC,eAAuB,EACvB,WAAmB,EACnB,QAAmC,EACnC,IAAiB;IAEjB,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,gBAAgB,EAAE,GAAG,MAAM,iBAAiB,CACjF,eAAe,EACf,QAAQ,EACR,IAAI,CACL,CAAC;IAEF,OAAO,IAAA,8BAAiB,EACtB,QAAQ,EACR;QACE,OAAO,EAAE,eAAe;QACxB,MAAM,EAAE,CAAC,wBAAY,CAAC,aAAa,EAAE,WAAW,CAAC;QACjD,SAAS;QACT,OAAO;KACR,EACD,IAAA,uCAA0B,EAAC,WAAW,EAAE,qBAAa,CAAC,EACtD,sBAAsB,EACtB,EAAE,SAAS,EAAE,gBAAgB,EAAE,CAChC,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACI,KAAK,UAAU,gBAAgB,CACpC,eAAuB,EACvB,WAAmB,EACnB,QAAmC,EACnC,UAQI,EAAE;IAEN,qDAAqD;IACrD,MAAM,aAAa,GAAG,MAAM,yBAAyB,CAAC,eAAe,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC;IAE9F,MAAM,KAAK,GAAkB;QAC3B,WAAW;QACX,KAAK,EAAE,aAAa,CAAC,KAAK;QAC1B,OAAO,EAAE,aAAa,CAAC,OAAO;QAC9B,MAAM,EAAE,aAAa,CAAC,MAAM;KAC7B,CAAC;IAEF,+BAA+B;IAC/B,IAAI,aAAa,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC;QAC3D,KAAK,CAAC,GAAG,GAAG,aAAa,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;IACjD,CAAC;IAED,0EAA0E;IAC1E,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;QAC1B,KAAK,CAAC,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;QAC5C,IAAI,OAAO,CAAC,gBAAgB,IAAI,OAAO,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpE,KAAK,CAAC,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC;YAClD,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC;QACvB,CAAC;IACH,CAAC;IAED,uEAAuE;IACvE,IAAI,CAAC,OAAO,CAAC,aAAa,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,CAAC;QACnD,yCAAyC;QACzC,IAAI,OAAO,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;YACpC,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAC;QACnF,CAAC;QACD,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,uCAAuC;QAE5E,yDAAyD;QACzD,IAAI,aAAa,CAAC,WAAW,EAAE,CAAC;YAC9B,MAAM,aAAa,GAAG,MAAM,sBAAsB,CAAC,eAAe,EAAE,WAAW,EAAE,QAAQ,EAAE;gBACzF,UAAU,EAAE,SAAS;gBACrB,QAAQ,EAAE,OAAO,CAAC,OAAO;aAC1B,CAAC,CAAC;YACH,IAAI,aAAa,EAAE,CAAC;gBAClB,KAAK,CAAC,aAAa,GAAG,aAAa,CAAC;gBAEpC,kFAAkF;gBAClF,iEAAiE;gBACjE,MAAM,gBAAgB,GAAG,MAAM,wBAAwB,CACrD,aAAa,CAAC,MAAM,EACpB,QAAQ,EACR,WAAW,CACZ,CAAC;gBACF,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAChC,KAAK,CAAC,gBAAgB,GAAG,gBAAgB,CAAC;oBAC1C,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC;gBACvB,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,yDAAyD;IACzD,IAAI,CAAC,OAAO,CAAC,aAAa,IAAI,aAAa,CAAC,MAAM,EAAE,CAAC;QACnD,yCAAyC;QACzC,IAAI,OAAO,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;YACpC,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAC;QACnF,CAAC;QACD,sEAAsE;QACtE,MAAM,mBAAmB,GAAG,KAAK,CAAC,aAAa,EAAE,WAAW,IAAI,OAAO,CAAC,SAAS,CAAC;QAClF,MAAM,YAAY,GAAG,MAAM,qBAAqB,CAAC,eAAe,EAAE,WAAW,EAAE,QAAQ,EAAE;YACvF,UAAU,EAAE,mBAAmB;YAC/B,QAAQ,EAAE,OAAO,CAAC,OAAO;SAC1B,CAAC,CAAC;QACH,IAAI,YAAY,EAAE,CAAC;YACjB,KAAK,CAAC,YAAY,GAAG,YAAY,CAAC;QACpC,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;;;;GAWG;AACI,KAAK,UAAU,wBAAwB,CAC5C,MAAc,EACd,QAAmC,EACnC,WAAoB;IAEpB,MAAM,OAAO,GAAG,MAAM,IAAA,0BAAc,EAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC,CAAC;IAEnF,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,OAAO,GAAwB,EAAE,CAAC;IAExC,KAAK,MAAM,GAAG,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QAC/B,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,wBAAY,CAAC,cAAc,EAAE,CAAC;YAClD,MAAM,MAAM,GAAG,uBAAuB,CAAC,GAAG,CAAC,CAAC;YAC5C,IAAI,MAAM,EAAE,CAAC;gBACX,gEAAgE;gBAChE,6DAA6D;gBAC7D,+CAA+C;gBAC/C,IAAI,CAAC,WAAW,IAAI,IAAA,qBAAa,EAAC,MAAM,CAAC,WAAW,EAAE,WAAW,CAAC,EAAE,CAAC;oBACnE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBACvB,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,kCAAkC;IAClC,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;AACzE,CAAC;AAED;;GAEG;AACH,SAAgB,wBAAwB,CAAC,eAAuB;IAC9D,MAAM,UAAU,GAAG,eAAe,CAAC,WAAW,EAAE,CAAC;IAEjD,IAAI,UAAU,KAAK,qBAAS,CAAC,uBAAuB,CAAC,WAAW,EAAE,EAAE,CAAC;QACnE,OAAO,qBAAS,CAAC,0BAA0B,CAAC;IAC9C,CAAC;IAED,IAAI,UAAU,KAAK,qBAAS,CAAC,2BAA2B,CAAC,WAAW,EAAE,EAAE,CAAC;QACvE,OAAO,qBAAS,CAAC,8BAA8B,CAAC;IAClD,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAYD,oDAAoD;AAC7C,KAAK,UAAU,mBAAmB,CACvC,eAAuB,EACvB,SAAiB,EACjB,OAAe,EACf,QAAmC,EACnC,UAAkC,EAAE;IAEpC,IAAI,SAAS,IAAI,OAAO;QAAE,OAAO,EAAE,CAAC;IAEpC,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAA,+BAAkB,EACvC,QAAQ,EACR,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,CAAC,wBAAY,CAAC,cAAc,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,EACvF,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,uBAAW,CAAC,EAAE,EAAE,CACnD,CAAC;IAEF,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;QAC1B,MAAM,WAAW,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAClC,IAAI,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC;YAAE,OAAO,EAAE,CAAC;QACrC,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACtB,OAAO;YACL;gBACE,eAAe;gBACf,WAAW;gBACX,eAAe,EAAE,GAAG,CAAC,eAAe;gBACpC,UAAU,EAAE,GAAG,CAAC,WAAW;aAC5B;SACF,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,172 @@
1
+ /**
2
+ * Security Council Election Tracking
3
+ *
4
+ * Provides functions to check election status and prepare election creation transactions.
5
+ * Based on SecurityCouncilElectionTracker from governance repo.
6
+ *
7
+ * @module election
8
+ */
9
+ import { ethers, BigNumber } from "ethers";
10
+ import { PreparedTransaction, ElectionProposalStatus, ElectionStatus } from "./types";
11
+ /**
12
+ * Prepared election creation transaction
13
+ */
14
+ export interface PreparedElectionCreation {
15
+ /** Transaction to send */
16
+ transaction: PreparedTransaction;
17
+ /** Election index being created */
18
+ electionIndex: number;
19
+ }
20
+ /**
21
+ * Election proposal parameters needed for execute() call
22
+ */
23
+ export interface ElectionProposalParams {
24
+ /** Target addresses */
25
+ targets: string[];
26
+ /** ETH values */
27
+ values: BigNumber[];
28
+ /** Call data for each target */
29
+ calldatas: string[];
30
+ /** Proposal description */
31
+ description: string;
32
+ /** Keccak256 hash of description */
33
+ descriptionHash: string;
34
+ }
35
+ /**
36
+ * Check the status of the Security Council election
37
+ *
38
+ * Determines if a new election can be created and when the next one is scheduled.
39
+ *
40
+ * @param l2Provider - Arbitrum One provider
41
+ * @param l1Provider - Ethereum mainnet provider (for L1 timestamp)
42
+ * @param nomineeGovernorAddress - Optional override for nominee election governor address
43
+ * @returns Election status information
44
+ *
45
+ * @example
46
+ * ```typescript
47
+ * const status = await checkElectionStatus(l2Provider, l1Provider);
48
+ *
49
+ * if (status.canCreateElection) {
50
+ * console.log("Election ready to create!");
51
+ * } else {
52
+ * console.log(`Next election in ${status.timeUntilElection}`);
53
+ * }
54
+ * ```
55
+ */
56
+ export declare function checkElectionStatus(l2Provider: ethers.providers.Provider, l1Provider: ethers.providers.Provider, nomineeGovernorAddress?: string): Promise<ElectionStatus>;
57
+ /**
58
+ * Prepare a transaction to create a new Security Council election
59
+ *
60
+ * Only call this if checkElectionStatus indicates canCreateElection is true.
61
+ *
62
+ * @param electionStatus - Status from checkElectionStatus (provides current election count)
63
+ * @param nomineeGovernorAddress - Optional override for nominee election governor address
64
+ * @returns Prepared transaction for creating the election
65
+ *
66
+ * @example
67
+ * ```typescript
68
+ * const status = await checkElectionStatus(l2Provider, l1Provider);
69
+ *
70
+ * if (status.canCreateElection) {
71
+ * const { transaction, electionIndex } = prepareElectionCreation(status);
72
+ * console.log(`Creating election #${electionIndex}`);
73
+ * // Execute with your signer
74
+ * const tx = await signer.sendTransaction({
75
+ * to: transaction.to,
76
+ * data: transaction.data,
77
+ * });
78
+ * await tx.wait();
79
+ * }
80
+ * ```
81
+ */
82
+ export declare function prepareElectionCreation(electionStatus: Pick<ElectionStatus, "electionCount">, nomineeGovernorAddress?: string): PreparedElectionCreation;
83
+ /**
84
+ * Check if a governor has a vetting period (is a nominee election governor)
85
+ *
86
+ * @param governorAddress - Address of the governor to check
87
+ * @param provider - Provider for the chain the governor is on
88
+ * @returns True if the governor has a vetting period
89
+ */
90
+ export declare function hasVettingPeriod(governorAddress: string, provider: ethers.providers.Provider): Promise<boolean>;
91
+ /**
92
+ * Track the status of a Security Council election by its index
93
+ *
94
+ * This function provides detailed tracking of an election's progress through
95
+ * the nominee selection, vetting, and member election phases.
96
+ *
97
+ * @param electionIndex - The election index to track
98
+ * @param l2Provider - Arbitrum One provider
99
+ * @param l1Provider - Ethereum mainnet provider (for L1 block number)
100
+ * @param options - Optional address overrides
101
+ * @returns Detailed election proposal status
102
+ *
103
+ * @example
104
+ * ```typescript
105
+ * const status = await trackElectionProposal(
106
+ * 5, // election index
107
+ * l2Provider,
108
+ * l1Provider
109
+ * );
110
+ *
111
+ * if (status.phase === "VETTING_PERIOD") {
112
+ * console.log(`${status.compliantNomineeCount}/6 nominees compliant`);
113
+ * }
114
+ * ```
115
+ */
116
+ export declare function trackElectionProposal(electionIndex: number, l2Provider: ethers.providers.Provider, _l1Provider: ethers.providers.Provider, options?: {
117
+ nomineeGovernorAddress?: string;
118
+ memberGovernorAddress?: string;
119
+ }): Promise<ElectionProposalStatus>;
120
+ /**
121
+ * Get the proposal ID for a given election index
122
+ *
123
+ * Uses getProposeArgs to get proposal parameters and hashProposal to calculate the proposal ID.
124
+ *
125
+ * @param electionIndex - Election index
126
+ * @param provider - L2 provider
127
+ * @param nomineeGovernorAddress - Optional governor address override
128
+ * @returns Proposal ID or null if election not yet created
129
+ */
130
+ export declare function getElectionProposalId(electionIndex: number, provider: ethers.providers.Provider, nomineeGovernorAddress?: string): Promise<string | null>;
131
+ /**
132
+ * Get the proposal parameters for an election proposal
133
+ *
134
+ * Searches for the ProposalCreated event to extract targets, values, calldatas,
135
+ * and description needed for execute() call.
136
+ *
137
+ * @param electionIndex - Election index
138
+ * @param provider - L2 provider
139
+ * @param nomineeGovernorAddress - Optional governor address override
140
+ * @returns Election proposal params or null if not found
141
+ */
142
+ export declare function getElectionProposalParams(electionIndex: number, provider: ethers.providers.Provider, nomineeGovernorAddress?: string): Promise<ElectionProposalParams | null>;
143
+ /**
144
+ * Prepare a transaction to trigger member election creation
145
+ *
146
+ * After the vetting period ends with 6+ compliant nominees, calling execute()
147
+ * on the NomineeElectionGovernor creates the member election proposal.
148
+ *
149
+ * @param electionStatus - Status from trackElectionProposal (must have canProceedToMemberPhase=true)
150
+ * @param provider - L2 provider
151
+ * @param nomineeGovernorAddress - Optional governor address override
152
+ * @returns Prepared transaction or null if not ready
153
+ *
154
+ * @example
155
+ * ```typescript
156
+ * const status = await trackElectionProposal(5, l2Provider, l1Provider);
157
+ *
158
+ * if (status.canProceedToMemberPhase) {
159
+ * const prepared = await prepareMemberElectionTrigger(status, l2Provider);
160
+ * if (prepared) {
161
+ * const tx = await signer.sendTransaction({
162
+ * to: prepared.to,
163
+ * data: prepared.data,
164
+ * });
165
+ * await tx.wait();
166
+ * console.log("Member election created!");
167
+ * }
168
+ * }
169
+ * ```
170
+ */
171
+ export declare function prepareMemberElectionTrigger(electionStatus: Pick<ElectionProposalStatus, "electionIndex" | "canProceedToMemberPhase">, provider: ethers.providers.Provider, nomineeGovernorAddress?: string): Promise<PreparedTransaction | null>;
172
+ //# sourceMappingURL=election.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"election.d.ts","sourceRoot":"","sources":["../src/election.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAG3C,OAAO,EACL,mBAAmB,EAKnB,sBAAsB,EACtB,cAAc,EACf,MAAM,SAAS,CAAC;AAYjB;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,0BAA0B;IAC1B,WAAW,EAAE,mBAAmB,CAAC;IACjC,mCAAmC;IACnC,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,uBAAuB;IACvB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,iBAAiB;IACjB,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,gCAAgC;IAChC,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,2BAA2B;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,oCAAoC;IACpC,eAAe,EAAE,MAAM,CAAC;CACzB;AAsBD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,mBAAmB,CACvC,UAAU,EAAE,MAAM,CAAC,SAAS,CAAC,QAAQ,EACrC,UAAU,EAAE,MAAM,CAAC,SAAS,CAAC,QAAQ,EACrC,sBAAsB,GAAE,MAA4C,GACnE,OAAO,CAAC,cAAc,CAAC,CA6CzB;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,uBAAuB,CACrC,cAAc,EAAE,IAAI,CAAC,cAAc,EAAE,eAAe,CAAC,EACrD,sBAAsB,GAAE,MAA4C,GACnE,wBAAwB,CAe1B;AAED;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CACpC,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,MAAM,CAAC,SAAS,CAAC,QAAQ,GAClC,OAAO,CAAC,OAAO,CAAC,CASlB;AAiDD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAsB,qBAAqB,CACzC,aAAa,EAAE,MAAM,EACrB,UAAU,EAAE,MAAM,CAAC,SAAS,CAAC,QAAQ,EACrC,WAAW,EAAE,MAAM,CAAC,SAAS,CAAC,QAAQ,EACtC,OAAO,GAAE;IACP,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAC3B,GACL,OAAO,CAAC,sBAAsB,CAAC,CAiIjC;AAED;;;;;;;;;GASG;AACH,wBAAsB,qBAAqB,CACzC,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,CAAC,SAAS,CAAC,QAAQ,EACnC,sBAAsB,GAAE,MAA4C,GACnE,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAwBxB;AAID;;;;;;;;;;GAUG;AACH,wBAAsB,yBAAyB,CAC7C,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,CAAC,SAAS,CAAC,QAAQ,EACnC,sBAAsB,GAAE,MAA4C,GACnE,OAAO,CAAC,sBAAsB,GAAG,IAAI,CAAC,CA4DxC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAsB,4BAA4B,CAChD,cAAc,EAAE,IAAI,CAAC,sBAAsB,EAAE,eAAe,GAAG,yBAAyB,CAAC,EACzF,QAAQ,EAAE,MAAM,CAAC,SAAS,CAAC,QAAQ,EACnC,sBAAsB,GAAE,MAA4C,GACnE,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAmCrC"}