@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,76 @@
1
+ /**
2
+ * Chunked log search with early exit optimization
3
+ *
4
+ * Critical performance pattern: 10-40x faster than naive log search
5
+ */
6
+ import { ethers } from "ethers";
7
+ /**
8
+ * Log filter parameters
9
+ */
10
+ export interface LogFilter {
11
+ address?: string | string[];
12
+ topics?: (string | string[] | null)[];
13
+ fromBlock: number;
14
+ toBlock: number;
15
+ }
16
+ /**
17
+ * Search result with metadata
18
+ */
19
+ export interface LogSearchResult {
20
+ logs: ethers.providers.Log[];
21
+ searchedBlocks: number;
22
+ chunksProcessed: number;
23
+ earlyExit: boolean;
24
+ /** The log that triggered early exit (if earlyExitCheck returned one) */
25
+ matchedLog?: ethers.providers.Log;
26
+ }
27
+ /**
28
+ * Options for log search
29
+ */
30
+ export interface LogSearchOptions {
31
+ chunkSize?: number;
32
+ delayBetweenChunks?: number;
33
+ earlyExitCheck?: (logs: ethers.providers.Log[]) => ethers.providers.Log | undefined;
34
+ maxChunks?: number;
35
+ reverseDirection?: boolean;
36
+ }
37
+ /**
38
+ * Search for logs in chunks with early exit optimization
39
+ *
40
+ * @example
41
+ * ```typescript
42
+ * // Search for CallExecuted events, stop when found
43
+ * const result = await searchLogsInChunks(
44
+ * l2Provider,
45
+ * {
46
+ * address: timelockAddress,
47
+ * topics: [EVENT_TOPICS.CALL_EXECUTED, operationId],
48
+ * fromBlock: queueBlock,
49
+ * toBlock: currentBlock
50
+ * },
51
+ * {
52
+ * chunkSize: 10_000_000,
53
+ * earlyExitCheck: (logs) => logs.find(l => l.topics[1] === operationId) ?? null
54
+ * }
55
+ * );
56
+ * ```
57
+ */
58
+ export declare function searchLogsInChunks(provider: ethers.providers.Provider, filter: LogFilter, options?: LogSearchOptions): Promise<LogSearchResult>;
59
+ /**
60
+ * Search for a single log matching a predicate
61
+ * Returns immediately when found (early exit optimization)
62
+ */
63
+ export declare function findLog(provider: ethers.providers.Provider, filter: LogFilter, predicate: (log: ethers.providers.Log) => boolean, options?: Omit<LogSearchOptions, "earlyExitCheck">): Promise<ethers.providers.Log | undefined>;
64
+ /**
65
+ * Generic find and parse event - consolidates the common pattern:
66
+ * getSearchDefaults → findLog → parse → null check
67
+ *
68
+ * Reduces boilerplate in timelock-discovery.ts and similar modules.
69
+ */
70
+ export declare function findAndParseEvent<T>(provider: ethers.providers.Provider, filter: LogFilter, predicate: (log: ethers.providers.Log) => boolean, parser: (log: ethers.providers.Log) => T | null, options?: Omit<LogSearchOptions, "earlyExitCheck">): Promise<T | null>;
71
+ /**
72
+ * Create a predicate that matches operationId in topics[1]
73
+ * Common pattern for timelock event filtering
74
+ */
75
+ export declare function createOperationIdPredicate(operationId: string, addressEquals: (a: string, b: string) => boolean): (log: ethers.providers.Log) => boolean;
76
+ //# sourceMappingURL=log-search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log-search.d.ts","sourceRoot":"","sources":["../../src/utils/log-search.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAOhC;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC5B,MAAM,CAAC,EAAE,CAAC,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC;IAC7B,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,OAAO,CAAC;IACnB,yEAAyE;IACzE,UAAU,CAAC,EAAE,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,SAAS,CAAC,GAAG,EAAE,KAAK,MAAM,CAAC,SAAS,CAAC,GAAG,GAAG,SAAS,CAAC;IACpF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,kBAAkB,CACtC,QAAQ,EAAE,MAAM,CAAC,SAAS,CAAC,QAAQ,EACnC,MAAM,EAAE,SAAS,EACjB,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,eAAe,CAAC,CAoH1B;AAED;;;GAGG;AACH,wBAAsB,OAAO,CAC3B,QAAQ,EAAE,MAAM,CAAC,SAAS,CAAC,QAAQ,EACnC,MAAM,EAAE,SAAS,EACjB,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,SAAS,CAAC,GAAG,KAAK,OAAO,EACjD,OAAO,GAAE,IAAI,CAAC,gBAAgB,EAAE,gBAAgB,CAAM,GACrD,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,GAAG,SAAS,CAAC,CAQ3C;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CAAC,CAAC,EACvC,QAAQ,EAAE,MAAM,CAAC,SAAS,CAAC,QAAQ,EACnC,MAAM,EAAE,SAAS,EACjB,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,SAAS,CAAC,GAAG,KAAK,OAAO,EACjD,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,SAAS,CAAC,GAAG,KAAK,CAAC,GAAG,IAAI,EAC/C,OAAO,GAAE,IAAI,CAAC,gBAAgB,EAAE,gBAAgB,CAAM,GACrD,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAInB;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,OAAO,GAC/C,CAAC,GAAG,EAAE,MAAM,CAAC,SAAS,CAAC,GAAG,KAAK,OAAO,CAExC"}
@@ -0,0 +1,142 @@
1
+ "use strict";
2
+ /**
3
+ * Chunked log search with early exit optimization
4
+ *
5
+ * Critical performance pattern: 10-40x faster than naive log search
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.searchLogsInChunks = searchLogsInChunks;
9
+ exports.findLog = findLog;
10
+ exports.findAndParseEvent = findAndParseEvent;
11
+ exports.createOperationIdPredicate = createOperationIdPredicate;
12
+ const constants_1 = require("../constants");
13
+ const rpc_utils_1 = require("./rpc-utils");
14
+ const logger_1 = require("./logger");
15
+ const log = logger_1.loggers.rpc;
16
+ /**
17
+ * Search for logs in chunks with early exit optimization
18
+ *
19
+ * @example
20
+ * ```typescript
21
+ * // Search for CallExecuted events, stop when found
22
+ * const result = await searchLogsInChunks(
23
+ * l2Provider,
24
+ * {
25
+ * address: timelockAddress,
26
+ * topics: [EVENT_TOPICS.CALL_EXECUTED, operationId],
27
+ * fromBlock: queueBlock,
28
+ * toBlock: currentBlock
29
+ * },
30
+ * {
31
+ * chunkSize: 10_000_000,
32
+ * earlyExitCheck: (logs) => logs.find(l => l.topics[1] === operationId) ?? null
33
+ * }
34
+ * );
35
+ * ```
36
+ */
37
+ async function searchLogsInChunks(provider, filter, options = {}) {
38
+ const { chunkSize = constants_1.DEFAULT_CHUNKING_CONFIG.l2ChunkSize, delayBetweenChunks = constants_1.DEFAULT_CHUNKING_CONFIG.delayBetweenChunks, earlyExitCheck, maxChunks, reverseDirection = false, } = options;
39
+ const allLogs = [];
40
+ let chunksProcessed = 0;
41
+ let earlyExit = false;
42
+ let matchedLog;
43
+ const { fromBlock, toBlock } = filter;
44
+ const totalBlocks = toBlock - fromBlock + 1;
45
+ const searchStart = Date.now();
46
+ const addressStr = Array.isArray(filter.address)
47
+ ? `[${filter.address.length} addrs]`
48
+ : filter.address;
49
+ log("searchLogsInChunks: %s blocks=%d-%d (%d blocks, ~%d chunks)", addressStr, fromBlock, toBlock, totalBlocks, Math.ceil(totalBlocks / chunkSize));
50
+ if (totalBlocks <= 0) {
51
+ return { logs: [], searchedBlocks: 0, chunksProcessed: 0, earlyExit: false };
52
+ }
53
+ // Generate chunk ranges
54
+ const chunks = [];
55
+ if (reverseDirection) {
56
+ // Search backwards (useful for finding most recent events)
57
+ for (let end = toBlock; end >= fromBlock; end -= chunkSize) {
58
+ const start = Math.max(end - chunkSize + 1, fromBlock);
59
+ chunks.push({ start, end });
60
+ }
61
+ }
62
+ else {
63
+ // Search forwards (default)
64
+ for (let start = fromBlock; start <= toBlock; start += chunkSize) {
65
+ const end = Math.min(start + chunkSize - 1, toBlock);
66
+ chunks.push({ start, end });
67
+ }
68
+ }
69
+ // Process chunks and track actual blocks searched
70
+ let actualBlocksSearched = 0;
71
+ for (const { start, end } of chunks) {
72
+ if (maxChunks && chunksProcessed >= maxChunks) {
73
+ break;
74
+ }
75
+ const chunkStart = Date.now();
76
+ const logs = await (0, rpc_utils_1.queryWithRetry)(() => provider.getLogs({
77
+ address: filter.address,
78
+ topics: filter.topics,
79
+ fromBlock: start,
80
+ toBlock: end,
81
+ }));
82
+ const chunkMs = Date.now() - chunkStart;
83
+ log(" chunk %d: blocks=%d-%d found=%d logs (%dms)", chunksProcessed + 1, start, end, logs.length, chunkMs);
84
+ allLogs.push(...logs);
85
+ chunksProcessed++;
86
+ actualBlocksSearched += end - start + 1;
87
+ // Early exit check - critical optimization
88
+ if (earlyExitCheck && logs.length > 0) {
89
+ const match = earlyExitCheck(logs);
90
+ if (match) {
91
+ earlyExit = true;
92
+ matchedLog = match;
93
+ break;
94
+ }
95
+ }
96
+ // Rate limiting between chunks
97
+ if (end < toBlock && delayBetweenChunks > 0) {
98
+ await (0, rpc_utils_1.delay)(delayBetweenChunks);
99
+ }
100
+ }
101
+ const totalMs = Date.now() - searchStart;
102
+ log("searchLogsInChunks done: %d logs, %d chunks, %dms%s", allLogs.length, chunksProcessed, totalMs, earlyExit ? " (early exit)" : "");
103
+ return {
104
+ logs: allLogs,
105
+ searchedBlocks: actualBlocksSearched,
106
+ chunksProcessed,
107
+ earlyExit,
108
+ matchedLog,
109
+ };
110
+ }
111
+ /**
112
+ * Search for a single log matching a predicate
113
+ * Returns immediately when found (early exit optimization)
114
+ */
115
+ async function findLog(provider, filter, predicate, options = {}) {
116
+ const result = await searchLogsInChunks(provider, filter, {
117
+ ...options,
118
+ earlyExitCheck: (logs) => logs.find(predicate),
119
+ });
120
+ // Use matchedLog from early exit to avoid double-searching
121
+ return result.matchedLog;
122
+ }
123
+ /**
124
+ * Generic find and parse event - consolidates the common pattern:
125
+ * getSearchDefaults → findLog → parse → null check
126
+ *
127
+ * Reduces boilerplate in timelock-discovery.ts and similar modules.
128
+ */
129
+ async function findAndParseEvent(provider, filter, predicate, parser, options = {}) {
130
+ const log = await findLog(provider, filter, predicate, options);
131
+ if (!log)
132
+ return null;
133
+ return parser(log);
134
+ }
135
+ /**
136
+ * Create a predicate that matches operationId in topics[1]
137
+ * Common pattern for timelock event filtering
138
+ */
139
+ function createOperationIdPredicate(operationId, addressEquals) {
140
+ return (log) => (log.topics[1] ? addressEquals(log.topics[1], operationId) : false);
141
+ }
142
+ //# sourceMappingURL=log-search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log-search.js","sourceRoot":"","sources":["../../src/utils/log-search.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Centralized debug loggers for the SDK
3
+ *
4
+ * Two types of loggers:
5
+ * 1. Regular loggers - for code that runs sequentially
6
+ * 2. Scoped loggers - for code that runs concurrently (auto-prefix with scope)
7
+ *
8
+ * Usage:
9
+ * import { loggers } from "../utils/logger";
10
+ * import { withScope } from "../utils/scoped-logger";
11
+ *
12
+ * // Regular logging
13
+ * loggers.tracker("message %s", value);
14
+ *
15
+ * // Scoped logging (for concurrent operations)
16
+ * await withScope("core-gov", async () => {
17
+ * loggers.discovery("discovering..."); // [core-gov] discovering...
18
+ * });
19
+ */
20
+ export { withScope, getCurrentScope, scopedLog } from "./scoped-logger";
21
+ /**
22
+ * Pre-configured debug loggers for common namespaces.
23
+ *
24
+ * Scoped loggers (discovery, pipeline, stage.*) automatically include
25
+ * the current scope prefix when used within withScope().
26
+ */
27
+ export declare const loggers: {
28
+ readonly tracker: (fmt: string, ...args: unknown[]) => void;
29
+ readonly execution: (fmt: string, ...args: unknown[]) => void;
30
+ readonly election: (fmt: string, ...args: unknown[]) => void;
31
+ readonly rpc: (fmt: string, ...args: unknown[]) => void;
32
+ readonly retryables: (fmt: string, ...args: unknown[]) => void;
33
+ readonly discovery: (fmt: string, ...args: unknown[]) => void;
34
+ readonly pipeline: (fmt: string, ...args: unknown[]) => void;
35
+ readonly stage: {
36
+ readonly timelock: (fmt: string, ...args: unknown[]) => void;
37
+ readonly l2ToL1: (fmt: string, ...args: unknown[]) => void;
38
+ readonly proposalQueued: (fmt: string, ...args: unknown[]) => void;
39
+ };
40
+ };
41
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAKH,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAExE;;;;;GAKG;AACH,eAAO,MAAM,OAAO;;;;;;;;;;;;;CAcV,CAAC"}
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ /**
3
+ * Centralized debug loggers for the SDK
4
+ *
5
+ * Two types of loggers:
6
+ * 1. Regular loggers - for code that runs sequentially
7
+ * 2. Scoped loggers - for code that runs concurrently (auto-prefix with scope)
8
+ *
9
+ * Usage:
10
+ * import { loggers } from "../utils/logger";
11
+ * import { withScope } from "../utils/scoped-logger";
12
+ *
13
+ * // Regular logging
14
+ * loggers.tracker("message %s", value);
15
+ *
16
+ * // Scoped logging (for concurrent operations)
17
+ * await withScope("core-gov", async () => {
18
+ * loggers.discovery("discovering..."); // [core-gov] discovering...
19
+ * });
20
+ */
21
+ Object.defineProperty(exports, "__esModule", { value: true });
22
+ exports.loggers = exports.scopedLog = exports.getCurrentScope = exports.withScope = void 0;
23
+ const scoped_logger_1 = require("./scoped-logger");
24
+ // Re-export scoped logging utilities
25
+ var scoped_logger_2 = require("./scoped-logger");
26
+ Object.defineProperty(exports, "withScope", { enumerable: true, get: function () { return scoped_logger_2.withScope; } });
27
+ Object.defineProperty(exports, "getCurrentScope", { enumerable: true, get: function () { return scoped_logger_2.getCurrentScope; } });
28
+ Object.defineProperty(exports, "scopedLog", { enumerable: true, get: function () { return scoped_logger_2.scopedLog; } });
29
+ /**
30
+ * Pre-configured debug loggers for common namespaces.
31
+ *
32
+ * Scoped loggers (discovery, pipeline, stage.*) automatically include
33
+ * the current scope prefix when used within withScope().
34
+ */
35
+ exports.loggers = {
36
+ // Scoped loggers - auto-prefix with current scope (tracker ID, governor name, etc.)
37
+ tracker: (0, scoped_logger_1.scopedLog)("gov-tracker:tracker"),
38
+ execution: (0, scoped_logger_1.scopedLog)("gov-tracker:execution"),
39
+ election: (0, scoped_logger_1.scopedLog)("gov-tracker:election"),
40
+ rpc: (0, scoped_logger_1.scopedLog)("gov-tracker:rpc"),
41
+ retryables: (0, scoped_logger_1.scopedLog)("gov-tracker:retryables"),
42
+ discovery: (0, scoped_logger_1.scopedLog)("gov-tracker:discovery"),
43
+ pipeline: (0, scoped_logger_1.scopedLog)("gov-tracker:pipeline"),
44
+ stage: {
45
+ timelock: (0, scoped_logger_1.scopedLog)("gov-tracker:stage:timelock"),
46
+ l2ToL1: (0, scoped_logger_1.scopedLog)("gov-tracker:stage:l2-to-l1-message"),
47
+ proposalQueued: (0, scoped_logger_1.scopedLog)("gov-tracker:stage:proposal-queued"),
48
+ },
49
+ };
50
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;GAkBG;;;AAEH,mDAA4C;AAE5C,qCAAqC;AACrC,iDAAwE;AAA/D,0GAAA,SAAS,OAAA;AAAE,gHAAA,eAAe,OAAA;AAAE,0GAAA,SAAS,OAAA;AAE9C;;;;;GAKG;AACU,QAAA,OAAO,GAAG;IACrB,oFAAoF;IACpF,OAAO,EAAE,IAAA,yBAAS,EAAC,qBAAqB,CAAC;IACzC,SAAS,EAAE,IAAA,yBAAS,EAAC,uBAAuB,CAAC;IAC7C,QAAQ,EAAE,IAAA,yBAAS,EAAC,sBAAsB,CAAC;IAC3C,GAAG,EAAE,IAAA,yBAAS,EAAC,iBAAiB,CAAC;IACjC,UAAU,EAAE,IAAA,yBAAS,EAAC,wBAAwB,CAAC;IAC/C,SAAS,EAAE,IAAA,yBAAS,EAAC,uBAAuB,CAAC;IAC7C,QAAQ,EAAE,IAAA,yBAAS,EAAC,sBAAsB,CAAC;IAC3C,KAAK,EAAE;QACL,QAAQ,EAAE,IAAA,yBAAS,EAAC,4BAA4B,CAAC;QACjD,MAAM,EAAE,IAAA,yBAAS,EAAC,oCAAoC,CAAC;QACvD,cAAc,EAAE,IAAA,yBAAS,EAAC,mCAAmC,CAAC;KAC/D;CACO,CAAC"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Operation ID utilities
3
+ *
4
+ * Uses on-chain timelock contract calls for operation ID computation
5
+ * to ensure consistency with the actual contract behavior.
6
+ */
7
+ import { ethers } from "ethers";
8
+ import { TimelockBatchParams, TimelockParams } from "../types";
9
+ /**
10
+ * Compute operation ID using on-chain timelock contract
11
+ */
12
+ export declare function hashOperation(timelockAddress: string, params: TimelockParams, provider: ethers.providers.Provider): Promise<string>;
13
+ /**
14
+ * Compute batch operation ID using on-chain timelock contract
15
+ */
16
+ export declare function hashOperationBatch(timelockAddress: string, params: TimelockBatchParams, provider: ethers.providers.Provider): Promise<string>;
17
+ /**
18
+ * Validate that a salt produces the expected operation ID
19
+ */
20
+ export declare function validateSalt(timelockAddress: string, expectedOperationId: string, params: TimelockParams, provider: ethers.providers.Provider): Promise<boolean>;
21
+ /**
22
+ * Validate that a salt produces the expected operation ID for a batch
23
+ */
24
+ export declare function validateSaltBatch(timelockAddress: string, expectedOperationId: string, params: TimelockBatchParams, provider: ethers.providers.Provider): Promise<boolean>;
25
+ /**
26
+ * Try salt candidates to find matching salt for an operation
27
+ *
28
+ * Supports both single and batch operations.
29
+ */
30
+ export declare function tryFindSalt(timelockAddress: string, expectedOperationId: string, baseParams: Omit<TimelockParams, "salt"> | Omit<TimelockBatchParams, "salt">, candidates: string[], provider: ethers.providers.Provider): Promise<string | null>;
31
+ /**
32
+ * Validate operation parameters and return computed hash with validation status.
33
+ *
34
+ * This is useful for debugging when you want to see the computed hash
35
+ * and whether it matches the expected operation ID.
36
+ *
37
+ * @param timelockAddress - Address of the timelock contract
38
+ * @param expectedOperationId - Expected operation ID to validate against
39
+ * @param params - Operation parameters (single or batch)
40
+ * @param provider - Provider for RPC calls
41
+ * @returns Computed hash and whether it matches expected
42
+ */
43
+ export declare function computeAndValidateOperationHash(timelockAddress: string, expectedOperationId: string, params: TimelockParams | TimelockBatchParams, provider: ethers.providers.Provider): Promise<{
44
+ computedHash: string;
45
+ isValid: boolean;
46
+ error?: string;
47
+ }>;
48
+ //# sourceMappingURL=operation-id.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"operation-id.d.ts","sourceRoot":"","sources":["../../src/utils/operation-id.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAK/D;;GAEG;AACH,wBAAsB,aAAa,CACjC,eAAe,EAAE,MAAM,EACvB,MAAM,EAAE,cAAc,EACtB,QAAQ,EAAE,MAAM,CAAC,SAAS,CAAC,QAAQ,GAClC,OAAO,CAAC,MAAM,CAAC,CAKjB;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,eAAe,EAAE,MAAM,EACvB,MAAM,EAAE,mBAAmB,EAC3B,QAAQ,EAAE,MAAM,CAAC,SAAS,CAAC,QAAQ,GAClC,OAAO,CAAC,MAAM,CAAC,CAOjB;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,eAAe,EAAE,MAAM,EACvB,mBAAmB,EAAE,MAAM,EAC3B,MAAM,EAAE,cAAc,EACtB,QAAQ,EAAE,MAAM,CAAC,SAAS,CAAC,QAAQ,GAClC,OAAO,CAAC,OAAO,CAAC,CAGlB;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,eAAe,EAAE,MAAM,EACvB,mBAAmB,EAAE,MAAM,EAC3B,MAAM,EAAE,mBAAmB,EAC3B,QAAQ,EAAE,MAAM,CAAC,SAAS,CAAC,QAAQ,GAClC,OAAO,CAAC,OAAO,CAAC,CAGlB;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAC/B,eAAe,EAAE,MAAM,EACvB,mBAAmB,EAAE,MAAM,EAC3B,UAAU,EAAE,IAAI,CAAC,cAAc,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC,mBAAmB,EAAE,MAAM,CAAC,EAC5E,UAAU,EAAE,MAAM,EAAE,EACpB,QAAQ,EAAE,MAAM,CAAC,SAAS,CAAC,QAAQ,GAClC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAuBxB;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,+BAA+B,CACnD,eAAe,EAAE,MAAM,EACvB,mBAAmB,EAAE,MAAM,EAC3B,MAAM,EAAE,cAAc,GAAG,mBAAmB,EAC5C,QAAQ,EAAE,MAAM,CAAC,SAAS,CAAC,QAAQ,GAClC,OAAO,CAAC;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAuBrE"}
@@ -0,0 +1,102 @@
1
+ "use strict";
2
+ /**
3
+ * Operation ID utilities
4
+ *
5
+ * Uses on-chain timelock contract calls for operation ID computation
6
+ * to ensure consistency with the actual contract behavior.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.hashOperation = hashOperation;
10
+ exports.hashOperationBatch = hashOperationBatch;
11
+ exports.validateSalt = validateSalt;
12
+ exports.validateSaltBatch = validateSaltBatch;
13
+ exports.tryFindSalt = tryFindSalt;
14
+ exports.computeAndValidateOperationHash = computeAndValidateOperationHash;
15
+ const ethers_1 = require("ethers");
16
+ const rpc_utils_1 = require("./rpc-utils");
17
+ const abis_1 = require("../abis");
18
+ const chain_1 = require("./chain");
19
+ /**
20
+ * Compute operation ID using on-chain timelock contract
21
+ */
22
+ async function hashOperation(timelockAddress, params, provider) {
23
+ const timelock = new ethers_1.ethers.Contract(timelockAddress, abis_1.TIMELOCK_ABI, provider);
24
+ const { target, value, data, predecessor, salt } = params;
25
+ return (0, rpc_utils_1.queryWithRetry)(() => timelock.hashOperation(target, value, data, predecessor, salt));
26
+ }
27
+ /**
28
+ * Compute batch operation ID using on-chain timelock contract
29
+ */
30
+ async function hashOperationBatch(timelockAddress, params, provider) {
31
+ const timelock = new ethers_1.ethers.Contract(timelockAddress, abis_1.TIMELOCK_ABI, provider);
32
+ const { targets, values, payloads, predecessor, salt } = params;
33
+ return (0, rpc_utils_1.queryWithRetry)(() => timelock.hashOperationBatch(targets, values, payloads, predecessor, salt));
34
+ }
35
+ /**
36
+ * Validate that a salt produces the expected operation ID
37
+ */
38
+ async function validateSalt(timelockAddress, expectedOperationId, params, provider) {
39
+ const computed = await hashOperation(timelockAddress, params, provider);
40
+ return (0, chain_1.addressEquals)(computed, expectedOperationId);
41
+ }
42
+ /**
43
+ * Validate that a salt produces the expected operation ID for a batch
44
+ */
45
+ async function validateSaltBatch(timelockAddress, expectedOperationId, params, provider) {
46
+ const computed = await hashOperationBatch(timelockAddress, params, provider);
47
+ return (0, chain_1.addressEquals)(computed, expectedOperationId);
48
+ }
49
+ /**
50
+ * Try salt candidates to find matching salt for an operation
51
+ *
52
+ * Supports both single and batch operations.
53
+ */
54
+ async function tryFindSalt(timelockAddress, expectedOperationId, baseParams, candidates, provider) {
55
+ const isBatch = "targets" in baseParams;
56
+ for (const salt of candidates) {
57
+ const fullParams = { ...baseParams, salt };
58
+ const isValid = isBatch
59
+ ? await validateSaltBatch(timelockAddress, expectedOperationId, fullParams, provider)
60
+ : await validateSalt(timelockAddress, expectedOperationId, fullParams, provider);
61
+ if (isValid) {
62
+ return salt;
63
+ }
64
+ }
65
+ return null;
66
+ }
67
+ /**
68
+ * Validate operation parameters and return computed hash with validation status.
69
+ *
70
+ * This is useful for debugging when you want to see the computed hash
71
+ * and whether it matches the expected operation ID.
72
+ *
73
+ * @param timelockAddress - Address of the timelock contract
74
+ * @param expectedOperationId - Expected operation ID to validate against
75
+ * @param params - Operation parameters (single or batch)
76
+ * @param provider - Provider for RPC calls
77
+ * @returns Computed hash and whether it matches expected
78
+ */
79
+ async function computeAndValidateOperationHash(timelockAddress, expectedOperationId, params, provider) {
80
+ try {
81
+ const isBatch = "targets" in params;
82
+ const computed = isBatch
83
+ ? await hashOperationBatch(timelockAddress, params, provider)
84
+ : await hashOperation(timelockAddress, params, provider);
85
+ const isValid = (0, chain_1.addressEquals)(computed, expectedOperationId);
86
+ return {
87
+ computedHash: computed,
88
+ isValid,
89
+ error: isValid
90
+ ? undefined
91
+ : `Operation hash mismatch: computed ${computed} but expected ${expectedOperationId}. This may indicate incorrect salt or operation parameters.`,
92
+ };
93
+ }
94
+ catch (err) {
95
+ return {
96
+ computedHash: "",
97
+ isValid: false,
98
+ error: `Failed to compute operation hash: ${err instanceof Error ? err.message : String(err)}`,
99
+ };
100
+ }
101
+ }
102
+ //# sourceMappingURL=operation-id.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"operation-id.js","sourceRoot":"","sources":["../../src/utils/operation-id.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * RPC utilities with retry logic and rate limiting
3
+ */
4
+ import { RetryConfig } from "../types";
5
+ /**
6
+ * Delay for specified milliseconds
7
+ */
8
+ export declare function delay(ms: number): Promise<void>;
9
+ /**
10
+ * Error type for RPC failures
11
+ */
12
+ export declare class RpcError extends Error {
13
+ readonly code?: string | undefined;
14
+ readonly cause?: Error | undefined;
15
+ constructor(message: string, code?: string | undefined, cause?: Error | undefined);
16
+ }
17
+ /**
18
+ * Check if an error is retryable
19
+ */
20
+ export declare function isRetryableError(error: unknown): boolean;
21
+ /**
22
+ * Query with retry and exponential backoff
23
+ *
24
+ * @example
25
+ * ```typescript
26
+ * const result = await queryWithRetry(() => provider.getBlockNumber());
27
+ * ```
28
+ */
29
+ export declare function queryWithRetry<T>(queryFn: () => Promise<T>, config?: RetryConfig): Promise<T>;
30
+ //# sourceMappingURL=rpc-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rpc-utils.d.ts","sourceRoot":"","sources":["../../src/utils/rpc-utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAMvC;;GAEG;AACH,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/C;AAED;;GAEG;AACH,qBAAa,QAAS,SAAQ,KAAK;aAGf,IAAI,CAAC,EAAE,MAAM;aACb,KAAK,CAAC,EAAE,KAAK;gBAF7B,OAAO,EAAE,MAAM,EACC,IAAI,CAAC,EAAE,MAAM,YAAA,EACb,KAAK,CAAC,EAAE,KAAK,YAAA;CAKhC;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAyCxD;AAED;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAAC,CAAC,EACpC,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACzB,MAAM,GAAE,WAAkC,GACzC,OAAO,CAAC,CAAC,CAAC,CAsCZ"}
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ /**
3
+ * RPC utilities with retry logic and rate limiting
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.RpcError = void 0;
7
+ exports.delay = delay;
8
+ exports.isRetryableError = isRetryableError;
9
+ exports.queryWithRetry = queryWithRetry;
10
+ const constants_1 = require("../constants");
11
+ const logger_1 = require("./logger");
12
+ const log = logger_1.loggers.rpc;
13
+ /**
14
+ * Delay for specified milliseconds
15
+ */
16
+ function delay(ms) {
17
+ return new Promise((resolve) => setTimeout(resolve, ms));
18
+ }
19
+ /**
20
+ * Error type for RPC failures
21
+ */
22
+ class RpcError extends Error {
23
+ constructor(message, code, cause) {
24
+ super(message);
25
+ this.code = code;
26
+ this.cause = cause;
27
+ this.name = "RpcError";
28
+ }
29
+ }
30
+ exports.RpcError = RpcError;
31
+ /**
32
+ * Check if an error is retryable
33
+ */
34
+ function isRetryableError(error) {
35
+ if (error instanceof Error) {
36
+ const message = error.message.toLowerCase();
37
+ // Rate limiting errors
38
+ if (message.includes("rate limit") ||
39
+ message.includes("too many requests") ||
40
+ message.includes("429")) {
41
+ return true;
42
+ }
43
+ // Server errors
44
+ if (message.includes("server error") ||
45
+ message.includes("502") ||
46
+ message.includes("503") ||
47
+ message.includes("504")) {
48
+ return true;
49
+ }
50
+ // Connection errors
51
+ if (message.includes("econnreset") ||
52
+ message.includes("econnrefused") ||
53
+ message.includes("etimedout") ||
54
+ message.includes("network error") ||
55
+ message.includes("timeout")) {
56
+ return true;
57
+ }
58
+ // Provider-specific errors
59
+ if (message.includes("missing response") || message.includes("request failed")) {
60
+ return true;
61
+ }
62
+ }
63
+ return false;
64
+ }
65
+ /**
66
+ * Query with retry and exponential backoff
67
+ *
68
+ * @example
69
+ * ```typescript
70
+ * const result = await queryWithRetry(() => provider.getBlockNumber());
71
+ * ```
72
+ */
73
+ async function queryWithRetry(queryFn, config = constants_1.DEFAULT_RETRY_CONFIG) {
74
+ let retryDelay = config.initialDelay;
75
+ let lastError;
76
+ for (let attempt = 0; attempt <= config.maxRetries; attempt++) {
77
+ try {
78
+ return await queryFn();
79
+ }
80
+ catch (error) {
81
+ lastError = error instanceof Error ? error : new Error(String(error));
82
+ // Don't retry non-retryable errors
83
+ if (!isRetryableError(error)) {
84
+ const code = error?.code?.toString();
85
+ log("query failed (non-retryable): %s", lastError.message);
86
+ throw new RpcError(`RPC query failed: ${lastError.message}`, code, lastError);
87
+ }
88
+ // Don't retry on last attempt
89
+ if (attempt < config.maxRetries) {
90
+ log("retry attempt %d/%d after %dms: %s", attempt + 1, config.maxRetries, retryDelay, lastError.message);
91
+ await delay(retryDelay);
92
+ retryDelay = Math.min(retryDelay * config.backoffMultiplier, config.maxDelay);
93
+ }
94
+ }
95
+ }
96
+ log("all %d retries exhausted: %s", config.maxRetries + 1, lastError?.message);
97
+ throw new RpcError(`All ${config.maxRetries + 1} retry attempts failed: ${lastError?.message ?? "Unknown error"}`, undefined, lastError);
98
+ }
99
+ //# sourceMappingURL=rpc-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rpc-utils.js","sourceRoot":"","sources":["../../src/utils/rpc-utils.ts"],"names":[],"mappings":"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"}