@apibara/evm-rpc 2.1.0-beta.50 → 2.1.0-beta.52

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -340,6 +340,25 @@ function createBlockRangeOracle({
340
340
  };
341
341
  }
342
342
 
343
+ async function retry({
344
+ fn,
345
+ maxAttempts = 3,
346
+ delay = 100
347
+ }) {
348
+ let attempts = 0;
349
+ while (true) {
350
+ try {
351
+ return await fn();
352
+ } catch (error) {
353
+ attempts++;
354
+ if (attempts >= maxAttempts)
355
+ throw error;
356
+ console.warn(`RPC error ${error}. Retrying in ${delay}ms`);
357
+ await new Promise((resolve) => setTimeout(resolve, delay));
358
+ }
359
+ }
360
+ }
361
+
343
362
  var __defProp = Object.defineProperty;
344
363
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
345
364
  var __publicField = (obj, key, value) => {
@@ -520,12 +539,14 @@ class EvmRpcStream extends rpc.RpcStreamConfig {
520
539
  filter
521
540
  }) {
522
541
  try {
523
- return await fetchLogsForRange({
524
- client: this.client,
525
- fromBlock,
526
- toBlock,
527
- filter,
528
- mergeGetLogs: this.options.mergeGetLogsFilter === "always"
542
+ return await retry({
543
+ fn: () => fetchLogsForRange({
544
+ client: this.client,
545
+ fromBlock,
546
+ toBlock,
547
+ filter,
548
+ mergeGetLogs: this.options.mergeGetLogsFilter === "always"
549
+ })
529
550
  });
530
551
  } catch (error) {
531
552
  this.blockRangeOracle.handleError(error);
@@ -536,19 +557,23 @@ class EvmRpcStream extends rpc.RpcStreamConfig {
536
557
  blockHash,
537
558
  filter
538
559
  }) {
539
- return await fetchLogsByBlockHash({
540
- client: this.client,
541
- blockHash,
542
- filter,
543
- mergeGetLogs: this.options.mergeGetLogsFilter === "always" || this.options.mergeGetLogsFilter === "accepted"
560
+ return await retry({
561
+ fn: () => fetchLogsByBlockHash({
562
+ client: this.client,
563
+ blockHash,
564
+ filter,
565
+ mergeGetLogs: this.options.mergeGetLogsFilter === "always" || this.options.mergeGetLogsFilter === "accepted"
566
+ })
544
567
  });
545
568
  }
546
569
  async fetchBlockHeaderByNumberWithRetry({
547
570
  blockNumber
548
571
  }) {
549
- const block = await this.client.request({
550
- method: "eth_getBlockByNumber",
551
- params: [viem.numberToHex(blockNumber), false]
572
+ const block = await retry({
573
+ fn: () => this.client.request({
574
+ method: "eth_getBlockByNumber",
575
+ params: [viem.numberToHex(blockNumber), false]
576
+ })
552
577
  });
553
578
  if (block === null) {
554
579
  throw new Error(`Block ${blockNumber} not found`);
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/filter.ts","../src/transform.ts","../src/log-fetcher.ts","../src/range-oracle.ts","../src/stream-config.ts","../src/rate-limited-http.ts"],"sourcesContent":["import type { LogFilter as DnaLogFilter, HeaderFilter } from \"@apibara/evm\";\nimport type { ValidateFilterResult } from \"@apibara/protocol/rpc\";\nimport { isHex } from \"viem\";\n\nexport type Filter = {\n header?: HeaderFilter;\n logs: LogFilter[];\n};\n\nexport type LogFilter = Pick<\n DnaLogFilter,\n \"address\" | \"topics\" | \"strict\" | \"id\"\n>;\n\nexport function validateFilter(filter: Filter): ValidateFilterResult {\n if (!filter.logs || filter.logs.length === 0) {\n return { valid: false, error: \"Missing logs filter\" };\n }\n\n let logFilterIndex = 0;\n for (const logFilter of filter.logs ?? []) {\n if (\n logFilter.address === undefined &&\n (logFilter.topics?.length ?? 0) === 0\n ) {\n return {\n valid: false,\n error: `Must provide at least one address or topic in log filter at position ${logFilterIndex}`,\n };\n }\n\n if (logFilter.address) {\n if (!isHex(logFilter.address)) {\n return {\n valid: false,\n error: \"Invalid address format. Expected 0x-prefixed hex string\",\n };\n }\n }\n\n if (logFilter.topics) {\n for (let i = 0; i < logFilter.topics.length; i++) {\n const topic = logFilter.topics[i];\n if (topic === null) {\n continue;\n }\n\n if (!isHex(topic)) {\n return {\n valid: false,\n error: `Invalid topic at index ${i}: ${topic}. Must be null or a 0x-prefixed hex string`,\n };\n }\n }\n }\n\n logFilterIndex++;\n }\n\n return { valid: true };\n}\n","import {\n type RpcBlock,\n type RpcLog,\n type Block as ViemBlock,\n formatBlock,\n hexToNumber,\n} from \"viem\";\nimport type { BlockHeader as DnaBlockHeader, Log as DnaLog } from \"./block\";\n\nexport function viemRpcLogToDna(viemLog: RpcLog): DnaLog {\n if (\n viemLog.logIndex === null ||\n viemLog.transactionIndex === null ||\n viemLog.transactionHash === null\n ) {\n throw new Error(\n \"Invalid log: missing required fields: logIndex, transactionIndex, transactionHash\",\n );\n }\n\n return {\n filterIds: [],\n logIndex: hexToNumber(viemLog.logIndex),\n address: viemLog.address,\n topics: viemLog.topics,\n data: viemLog.data,\n transactionIndex: hexToNumber(viemLog.transactionIndex),\n transactionHash: viemLog.transactionHash,\n transactionStatus: viemLog.removed ? \"reverted\" : \"succeeded\",\n };\n}\n\nexport function rpcBlockHeaderToDna(block: RpcBlock): DnaBlockHeader {\n const formattedBlock = formatBlock(block);\n return viemBlockHeaderToDna(formattedBlock);\n}\n\nexport function viemBlockHeaderToDna(viemBlock: ViemBlock): DnaBlockHeader {\n if (viemBlock.number === null || !viemBlock.hash) {\n throw new Error(\n `Invalid block: missing required fields (number: ${viemBlock.number}, hash: ${viemBlock.hash})`,\n );\n }\n\n return {\n blockNumber: viemBlock.number,\n blockHash: viemBlock.hash,\n parentBlockHash: viemBlock.parentHash,\n unclesHash: viemBlock.sha3Uncles,\n miner: viemBlock.miner ?? undefined,\n stateRoot: viemBlock.stateRoot,\n transactionsRoot: viemBlock.transactionsRoot,\n receiptsRoot: viemBlock.receiptsRoot,\n logsBloom: viemBlock.logsBloom ?? undefined,\n difficulty: viemBlock.difficulty,\n gasLimit: viemBlock.gasLimit,\n gasUsed: viemBlock.gasUsed,\n timestamp: new Date(Number(viemBlock.timestamp) * 1000),\n extraData: viemBlock.extraData,\n mixHash: viemBlock.mixHash ?? undefined,\n nonce: viemBlock.nonce ? BigInt(viemBlock.nonce) : undefined,\n baseFeePerGas: viemBlock.baseFeePerGas ?? undefined,\n withdrawalsRoot: viemBlock.withdrawalsRoot ?? undefined,\n totalDifficulty: viemBlock.totalDifficulty ?? undefined,\n blobGasUsed: viemBlock.blobGasUsed ?? undefined,\n excessBlobGas: viemBlock.excessBlobGas ?? undefined,\n parentBeaconBlockRoot: viemBlock.parentBeaconBlockRoot ?? undefined,\n requestsHash: undefined, // TODO: check\n };\n}\n","import type { LogFilter } from \"@apibara/evm\";\nimport type { Bytes } from \"@apibara/protocol\";\nimport type { RpcLog } from \"viem\";\nimport {\n hexToNumber,\n isAddressEqual,\n isHex,\n numberToHex,\n pad,\n trim,\n} from \"viem\";\nimport type { Log } from \"./block\";\nimport type { Filter } from \"./filter\";\nimport type { ViemRpcClient } from \"./stream-config\";\nimport { viemRpcLogToDna } from \"./transform\";\n\nexport async function fetchLogsByBlockHash({\n client,\n blockHash,\n filter,\n mergeGetLogs,\n}: {\n client: ViemRpcClient;\n blockHash: Bytes;\n filter: Filter;\n mergeGetLogs: boolean;\n}): Promise<{ logs: Log[] }> {\n if (!filter.logs || filter.logs.length === 0) {\n return { logs: [] };\n }\n\n const responses = mergeGetLogs\n ? await mergedGetLogsCalls({\n client,\n filter,\n blockHash,\n })\n : await standardGetLogsCalls({\n client,\n filter,\n blockHash,\n });\n\n const allLogs: Log[] = [];\n const seenLogsByIndex: Record<number, number> = {};\n\n for (const { logFilters, logs } of responses) {\n for (const log of logs) {\n if (log.blockNumber === null) {\n throw new Error(\"Log block number is null\");\n }\n\n for (const logFilter of logFilters) {\n const refinedLog = refineLog(log, logFilter);\n\n if (refinedLog) {\n const existingPosition = seenLogsByIndex[refinedLog.logIndex];\n\n if (existingPosition !== undefined) {\n const existingLog = allLogs[existingPosition];\n (existingLog.filterIds as number[]).push(logFilter.id ?? 0);\n } else {\n (refinedLog.filterIds as number[]).push(logFilter.id ?? 0);\n\n allLogs.push(refinedLog);\n seenLogsByIndex[refinedLog.logIndex] = allLogs.length - 1;\n }\n }\n }\n }\n }\n\n return { logs: allLogs };\n}\n\nexport async function fetchLogsForRange({\n client,\n fromBlock,\n toBlock,\n filter,\n mergeGetLogs,\n}: {\n client: ViemRpcClient;\n fromBlock: bigint;\n toBlock: bigint;\n filter: Filter;\n mergeGetLogs: boolean;\n}): Promise<{ logs: Record<number, Log[]>; blockNumbers: bigint[] }> {\n const logsByBlock: Record<number, Log[]> = {};\n\n if (!filter.logs || filter.logs.length === 0) {\n return { logs: logsByBlock, blockNumbers: [] };\n }\n\n const responses = mergeGetLogs\n ? await mergedGetLogsCalls({\n client,\n filter,\n fromBlock: numberToHex(fromBlock),\n toBlock: numberToHex(toBlock),\n })\n : await standardGetLogsCalls({\n client,\n filter,\n fromBlock: numberToHex(fromBlock),\n toBlock: numberToHex(toBlock),\n });\n\n const blockNumbers = new Set<bigint>();\n\n const seenLogsByBlockNumberAndIndex: Record<\n number,\n Record<number, number>\n > = {};\n\n for (const { logFilters, logs } of responses) {\n for (const log of logs) {\n if (log.blockNumber === null) {\n throw new Error(\"Log block number is null\");\n }\n\n for (const logFilter of logFilters) {\n const refinedLog = refineLog(log, logFilter);\n\n if (refinedLog) {\n const blockNumber = hexToNumber(log.blockNumber);\n blockNumbers.add(BigInt(blockNumber));\n\n if (!logsByBlock[blockNumber]) {\n logsByBlock[blockNumber] = [];\n }\n\n if (!seenLogsByBlockNumberAndIndex[blockNumber]) {\n seenLogsByBlockNumberAndIndex[blockNumber] = {};\n }\n\n const existingPosition =\n seenLogsByBlockNumberAndIndex[blockNumber][refinedLog.logIndex];\n\n if (existingPosition !== undefined) {\n const existingLog = logsByBlock[blockNumber][existingPosition];\n (existingLog.filterIds as number[]).push(logFilter.id ?? 0);\n } else {\n (refinedLog.filterIds as number[]).push(logFilter.id ?? 0);\n\n logsByBlock[blockNumber].push(refinedLog);\n seenLogsByBlockNumberAndIndex[blockNumber][refinedLog.logIndex] =\n logsByBlock[blockNumber].length - 1;\n }\n }\n }\n }\n }\n\n const sortedBlockNumbers = Array.from(blockNumbers).sort((a, b) =>\n a < b ? -1 : a > b ? 1 : 0,\n );\n\n return { logs: logsByBlock, blockNumbers: sortedBlockNumbers };\n}\n\nfunction refineLog(log: RpcLog, filter: LogFilter): Log | null {\n if (log.removed) {\n return null;\n }\n\n if (filter.address && !isAddressEqual(log.address, filter.address)) {\n return null;\n }\n\n const filterTopics = filter.topics ?? [];\n if (filter.strict && log.topics.length !== filterTopics.length) {\n return null;\n }\n\n if (filterTopics.length === 0) {\n return viemRpcLogToDna(log);\n }\n\n if (log.topics.length < filterTopics.length) {\n return null;\n }\n\n for (let i = 0; i < filterTopics.length; i++) {\n const filterTopic = filterTopics[i];\n const logTopic = log.topics[i];\n\n if (filterTopic === null) continue;\n\n if (!logTopic) return null;\n\n if (!isHex(filterTopic) || !isHex(logTopic)) {\n return null;\n }\n\n const normalizedFilter = pad(trim(filterTopic), { size: 32 });\n const normalizedLog = pad(trim(logTopic), { size: 32 });\n\n if (normalizedFilter !== normalizedLog) {\n return null;\n }\n }\n\n return viemRpcLogToDna(log);\n}\n\nasync function mergedGetLogsCalls({\n client,\n filter,\n blockHash,\n fromBlock,\n toBlock,\n}: {\n client: ViemRpcClient;\n filter: Filter;\n blockHash?: Bytes;\n fromBlock?: `0x${string}`;\n toBlock?: `0x${string}`;\n}) {\n const blockParams = blockHash ? { blockHash } : { fromBlock, toBlock };\n\n const filtersWithAddress = filter.logs.filter((f) => f.address !== undefined);\n const filtersWithoutAddress = filter.logs.filter(\n (f) => f.address === undefined,\n );\n\n const promises: Promise<{\n logs: RpcLog[];\n logFilters: typeof filter.logs;\n }>[] = [];\n\n if (filtersWithAddress.length > 0) {\n const addresses = filtersWithAddress.map((f) => f.address!);\n\n promises.push(\n client\n .request({\n method: \"eth_getLogs\",\n params: [\n {\n address: addresses,\n ...blockParams,\n },\n ],\n })\n .then((logs: RpcLog[]) => ({ logs, logFilters: filtersWithAddress })),\n );\n }\n\n if (filtersWithoutAddress.length > 0) {\n promises.push(\n client\n .request({\n method: \"eth_getLogs\",\n params: [\n {\n ...blockParams,\n },\n ],\n })\n .then((logs: RpcLog[]) => ({\n logs,\n logFilters: filtersWithoutAddress,\n })),\n );\n }\n\n return await Promise.all(promises);\n}\n\nasync function standardGetLogsCalls({\n client,\n filter,\n blockHash,\n fromBlock,\n toBlock,\n}: {\n client: ViemRpcClient;\n filter: Filter;\n blockHash?: Bytes;\n fromBlock?: `0x${string}`;\n toBlock?: `0x${string}`;\n}) {\n const blockParams = blockHash ? { blockHash } : { fromBlock, toBlock };\n return await Promise.all(\n filter.logs.map(async (logFilter) => {\n const logs = await client.request({\n method: \"eth_getLogs\",\n params: [\n {\n address: logFilter.address,\n topics:\n logFilter.topics !== undefined\n ? [...logFilter.topics]\n : undefined,\n ...blockParams,\n },\n ],\n });\n\n return { logs, logFilters: [logFilter] };\n }),\n );\n}\n","const BLOCK_RANGE_ERROR_PATTERNS = [\"invalid block range params\"] as const;\n\nexport type BlockRange = {\n start: bigint;\n end: bigint;\n};\n\nexport type BlockRangeOracle = {\n clampRange(original: BlockRange): BlockRange;\n handleSuccess(): void;\n handleError(error: unknown): { retry: boolean };\n};\n\nexport function createBlockRangeOracle({\n startingSize,\n minSize = 1n,\n maxSize = 10_000n,\n}: {\n startingSize: bigint;\n minSize?: bigint;\n maxSize?: bigint;\n}): BlockRangeOracle {\n let currentSize = startingSize;\n\n return {\n clampRange(original: BlockRange): BlockRange {\n const start = original.start;\n let end = original.end;\n\n const newEnd = start + currentSize - 1n;\n if (newEnd < end) {\n end = newEnd;\n }\n\n return { start, end };\n },\n handleSuccess(): void {\n // TODO: we can track how many successful requests and increase the size.\n // Probably want to receive the number of logs as argument and have a \"target\"\n },\n handleError(error: unknown): { retry: boolean } {\n if (error instanceof Error) {\n const message = error.message.toLowerCase();\n const isBlockRangeError = BLOCK_RANGE_ERROR_PATTERNS.some((pattern) =>\n message.includes(pattern),\n );\n\n if (isBlockRangeError) {\n if (currentSize > minSize) {\n const newSize = currentSize / 2n;\n currentSize = newSize > minSize ? newSize : minSize;\n }\n\n return { retry: true };\n }\n }\n\n return { retry: false };\n },\n };\n}\n","import type { Bytes } from \"@apibara/protocol\";\nimport {\n type BlockInfo,\n type FetchBlockByNumberArgs,\n type FetchBlockByNumberResult,\n type FetchBlockRangeArgs,\n type FetchBlockRangeResult,\n type FetchBlockResult,\n type FetchCursorArgs,\n RpcStreamConfig,\n type ValidateFilterResult,\n} from \"@apibara/protocol/rpc\";\nimport {\n type EIP1193Parameters,\n type PublicRpcSchema,\n type RpcBlock,\n formatBlock,\n numberToHex,\n toHex,\n} from \"viem\";\nimport type { Block, Log } from \"./block\";\nimport { type Filter, validateFilter } from \"./filter\";\nimport { fetchLogsByBlockHash, fetchLogsForRange } from \"./log-fetcher\";\nimport { type BlockRangeOracle, createBlockRangeOracle } from \"./range-oracle\";\nimport { rpcBlockHeaderToDna } from \"./transform\";\n\nexport type RequestParameters = EIP1193Parameters<PublicRpcSchema>;\n\nexport type RequestReturnType<method extends RequestParameters[\"method\"]> =\n Extract<PublicRpcSchema[number], { Method: method }>[\"ReturnType\"];\n\n// Require just the bare minimum from the provided viem client.\nexport type ViemRpcClient = {\n request: <TParams extends RequestParameters>(\n params: TParams,\n ) => Promise<RequestReturnType<TParams[\"method\"]>>;\n};\n\nexport type EvmRpcStreamOptions = {\n /** How many blocks to fetch in a single eth_getLogs call. */\n getLogsRangeSize?: bigint;\n /** How often to refresh the head block. */\n headRefreshIntervalMs?: number;\n /** How often to refresh the finalized block. */\n finalizedRefreshIntervalMs?: number;\n /** Force sending accepted headers even if no data matched. */\n alwaysSendAcceptedHeaders?: boolean;\n /** Merge multiple `eth_getLogs` calls into a single one, filtering data on the client. */\n mergeGetLogsFilter?: \"always\" | \"accepted\" | false;\n};\n\nexport class EvmRpcStream extends RpcStreamConfig<Filter, Block> {\n private blockRangeOracle: BlockRangeOracle;\n\n constructor(\n private client: ViemRpcClient,\n private options: EvmRpcStreamOptions = {},\n ) {\n super();\n\n this.blockRangeOracle = createBlockRangeOracle({\n startingSize: options.getLogsRangeSize ?? 1_000n,\n // Use the provided size to limit the maximum range size\n maxSize: options.getLogsRangeSize ? options.getLogsRangeSize : undefined,\n });\n }\n\n headRefreshIntervalMs(): number {\n return this.options.headRefreshIntervalMs ?? 3_000;\n }\n\n finalizedRefreshIntervalMs(): number {\n return this.options.finalizedRefreshIntervalMs ?? 30_000;\n }\n\n validateFilter(filter: Filter): ValidateFilterResult {\n return validateFilter(filter);\n }\n\n async fetchCursor(args: FetchCursorArgs): Promise<BlockInfo | null> {\n let block: RpcBlock | null = null;\n if (args.blockNumber !== undefined) {\n const blockNumber = toHex(args.blockNumber);\n block = await this.client.request({\n method: \"eth_getBlockByNumber\",\n params: [blockNumber, false],\n });\n } else if (args.blockTag) {\n block = await this.client.request({\n method: \"eth_getBlockByNumber\",\n params: [args.blockTag, false],\n });\n } else if (args.blockHash) {\n block = await this.client.request({\n method: \"eth_getBlockByHash\",\n params: [args.blockHash, false],\n });\n } else {\n throw new Error(\n \"One of blockNumber, blockHash or blockTag must be provided\",\n );\n }\n\n if (!block) {\n return null;\n }\n\n const formattedBlock = formatBlock(block);\n\n if (formattedBlock.number === null) {\n throw new Error(\"RPC block is missing required block number\");\n }\n\n if (formattedBlock.hash === null) {\n throw new Error(\"RPC block is missing required block hash\");\n }\n\n return {\n blockNumber: formattedBlock.number,\n blockHash: formattedBlock.hash,\n parentBlockHash: formattedBlock.parentHash,\n };\n }\n\n async fetchBlockRange({\n startBlock,\n finalizedBlock,\n force,\n filter,\n }: FetchBlockRangeArgs<Filter>): Promise<FetchBlockRangeResult<Block>> {\n const { start: fromBlock, end: toBlock } = this.blockRangeOracle.clampRange(\n { start: startBlock, end: finalizedBlock },\n );\n\n // console.log(\"Fetching block range\", fromBlock, toBlock, filter);\n\n const { logs: logsByBlockNumber, blockNumbers } =\n await this.fetchLogsForRangeWithRetry({\n fromBlock,\n toBlock,\n filter,\n });\n\n // If the client needs all headers, we iterate over the range and fetch headers\n // and then join them with the logs\n // Otherwise, we drive the block number iteration from the fetched logs.\n const data: FetchBlockResult<Block>[] = [];\n\n // Fetch block headers in parallel to optimize batching.\n const blockNumberResponses = [];\n if (filter.header === \"always\") {\n for (let blockNumber = fromBlock; blockNumber <= toBlock; blockNumber++) {\n blockNumberResponses.push(\n this.fetchBlockHeaderByNumberWithRetry({\n blockNumber,\n }),\n );\n }\n } else if (force && blockNumbers.length === 0) {\n blockNumberResponses.push(\n this.fetchBlockHeaderByNumberWithRetry({\n blockNumber: toBlock,\n }),\n );\n } else {\n for (const blockNumber of blockNumbers) {\n blockNumberResponses.push(\n this.fetchBlockHeaderByNumberWithRetry({\n blockNumber,\n }),\n );\n }\n }\n\n const blockNumbersWithHeader = await Promise.all(blockNumberResponses);\n for (const { blockNumber, header } of blockNumbersWithHeader) {\n const logs = logsByBlockNumber[Number(blockNumber)] ?? [];\n\n logs.sort((a, b) => a.logIndex - b.logIndex);\n\n data.push({\n cursor: undefined,\n endCursor: { orderKey: blockNumber },\n block: { header, logs },\n });\n }\n\n return { startBlock: fromBlock, endBlock: toBlock, data };\n }\n\n async fetchBlockByNumber({\n blockNumber,\n expectedParentBlockHash,\n isAtHead,\n filter,\n }: FetchBlockByNumberArgs<Filter>): Promise<FetchBlockByNumberResult<Block>> {\n // Fetch block header and check it matches the expected parent block hash.\n const { header } = await this.fetchBlockHeaderByNumberWithRetry({\n blockNumber,\n });\n\n if (header.blockHash === undefined) {\n throw new Error(`Block ${blockNumber} has no block hash`);\n }\n\n const blockInfo: BlockInfo = {\n blockNumber: header.blockNumber,\n blockHash: header.blockHash,\n parentBlockHash: header.parentBlockHash,\n };\n\n if (header.parentBlockHash !== expectedParentBlockHash) {\n return {\n status: \"reorg\",\n blockInfo,\n };\n }\n\n // Use the hash from the current block to fetch logs in a reorg-safe way.\n const { logs } = await this.fetchLogsByBlockHashWithRetry({\n blockHash: header.blockHash,\n filter,\n });\n\n logs.sort((a, b) => a.logIndex - b.logIndex);\n\n let cursor = undefined;\n if (blockNumber > 0n) {\n cursor = {\n orderKey: blockNumber - 1n,\n uniqueKey: header.parentBlockHash,\n };\n }\n const endCursor = {\n orderKey: blockNumber,\n uniqueKey: header.blockHash,\n };\n\n let block = null;\n\n const shouldSendBlock =\n filter.header === \"always\" ||\n logs.length > 0 ||\n (filter.header === \"on_data_or_on_new_block\" && isAtHead) ||\n this.options.alwaysSendAcceptedHeaders;\n\n if (shouldSendBlock) {\n block = {\n header,\n logs,\n };\n }\n\n return {\n status: \"success\",\n blockInfo,\n data: {\n cursor,\n endCursor,\n block,\n },\n };\n }\n\n private async fetchLogsForRangeWithRetry({\n fromBlock,\n toBlock,\n filter,\n }: {\n fromBlock: bigint;\n toBlock: bigint;\n filter: Filter;\n }): Promise<{ logs: Record<number, Log[]>; blockNumbers: bigint[] }> {\n // TODO: implement retry\n try {\n return await fetchLogsForRange({\n client: this.client,\n fromBlock,\n toBlock,\n filter,\n mergeGetLogs: this.options.mergeGetLogsFilter === \"always\",\n });\n } catch (error) {\n this.blockRangeOracle.handleError(error);\n throw error;\n }\n }\n\n private async fetchLogsByBlockHashWithRetry({\n blockHash,\n filter,\n }: {\n blockHash: Bytes;\n filter: Filter;\n }): Promise<{ logs: Log[] }> {\n // TODO: implement retry\n return await fetchLogsByBlockHash({\n client: this.client,\n blockHash,\n filter,\n mergeGetLogs:\n this.options.mergeGetLogsFilter === \"always\" ||\n this.options.mergeGetLogsFilter === \"accepted\",\n });\n }\n\n private async fetchBlockHeaderByNumberWithRetry({\n blockNumber,\n }: {\n blockNumber: bigint;\n }) {\n // TODO: implement retry\n const block = await this.client.request({\n method: \"eth_getBlockByNumber\",\n params: [numberToHex(blockNumber), false],\n });\n\n if (block === null) {\n throw new Error(`Block ${blockNumber} not found`);\n }\n\n return { header: rpcBlockHeaderToDna(block), blockNumber };\n }\n}\n","import {\n http,\n type HttpTransport,\n type HttpTransportConfig,\n type RpcSchema,\n} from \"viem\";\n\n/**\n * @description Creates a rate-limited HTTP transport that connects to a JSON-RPC API.\n */\nexport function rateLimitedHttp<\n rpcSchema extends RpcSchema | undefined = undefined,\n raw extends boolean = false,\n>(\n /** URL of the JSON-RPC API. Defaults to the chain's public RPC URL. */\n url?: string | undefined,\n config: HttpTransportConfig<rpcSchema, raw> & { rps?: number } = {},\n): HttpTransport<rpcSchema, raw> {\n const { onFetchRequest, onFetchResponse, ...rest } = config;\n\n const rps = config.rps ?? 10;\n\n const limiter = createRateLimiter({\n capacity: rps,\n refillRate: rps,\n });\n\n return http(url, {\n ...rest,\n async onFetchRequest(request, init) {\n await limiter.acquireOne();\n await onFetchRequest?.(request, init);\n },\n async onFetchResponse(response) {\n await onFetchResponse?.(response);\n },\n });\n}\n\nfunction createRateLimiter({\n capacity,\n refillRate,\n refillInterval: refillInterval_,\n lastRefillTime: startingRefillTime,\n}: {\n capacity: number;\n refillRate: number;\n refillInterval?: number;\n lastRefillTime?: number;\n}) {\n const refillInterval = refillInterval_ ?? 100;\n\n let tokens = capacity;\n let lastRefillTime = startingRefillTime ?? Date.now();\n\n function refill(now: number) {\n const elapsed = (now - lastRefillTime) / 1_000;\n const newTokens = elapsed * refillRate;\n tokens = Math.min(capacity, tokens + newTokens);\n lastRefillTime = now;\n }\n\n return {\n available() {\n return tokens;\n },\n // Wait for a single token to become available.\n async acquireOne(now?: number) {\n while (true) {\n refill(now ?? Date.now());\n if (tokens > 0) {\n tokens -= 1;\n return;\n }\n\n await new Promise((resolve) => setTimeout(resolve, refillInterval));\n }\n },\n };\n}\n"],"names":["isHex","hexToNumber","formatBlock","numberToHex","isAddressEqual","pad","trim","RpcStreamConfig","toHex","http"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/filter.ts","../src/transform.ts","../src/log-fetcher.ts","../src/range-oracle.ts","../src/retry.ts","../src/stream-config.ts","../src/rate-limited-http.ts"],"sourcesContent":["import type { LogFilter as DnaLogFilter, HeaderFilter } from \"@apibara/evm\";\nimport type { ValidateFilterResult } from \"@apibara/protocol/rpc\";\nimport { isHex } from \"viem\";\n\nexport type Filter = {\n header?: HeaderFilter;\n logs: LogFilter[];\n};\n\nexport type LogFilter = Pick<\n DnaLogFilter,\n \"address\" | \"topics\" | \"strict\" | \"id\"\n>;\n\nexport function validateFilter(filter: Filter): ValidateFilterResult {\n if (!filter.logs || filter.logs.length === 0) {\n return { valid: false, error: \"Missing logs filter\" };\n }\n\n let logFilterIndex = 0;\n for (const logFilter of filter.logs ?? []) {\n if (\n logFilter.address === undefined &&\n (logFilter.topics?.length ?? 0) === 0\n ) {\n return {\n valid: false,\n error: `Must provide at least one address or topic in log filter at position ${logFilterIndex}`,\n };\n }\n\n if (logFilter.address) {\n if (!isHex(logFilter.address)) {\n return {\n valid: false,\n error: \"Invalid address format. Expected 0x-prefixed hex string\",\n };\n }\n }\n\n if (logFilter.topics) {\n for (let i = 0; i < logFilter.topics.length; i++) {\n const topic = logFilter.topics[i];\n if (topic === null) {\n continue;\n }\n\n if (!isHex(topic)) {\n return {\n valid: false,\n error: `Invalid topic at index ${i}: ${topic}. Must be null or a 0x-prefixed hex string`,\n };\n }\n }\n }\n\n logFilterIndex++;\n }\n\n return { valid: true };\n}\n","import {\n type RpcBlock,\n type RpcLog,\n type Block as ViemBlock,\n formatBlock,\n hexToNumber,\n} from \"viem\";\nimport type { BlockHeader as DnaBlockHeader, Log as DnaLog } from \"./block\";\n\nexport function viemRpcLogToDna(viemLog: RpcLog): DnaLog {\n if (\n viemLog.logIndex === null ||\n viemLog.transactionIndex === null ||\n viemLog.transactionHash === null\n ) {\n throw new Error(\n \"Invalid log: missing required fields: logIndex, transactionIndex, transactionHash\",\n );\n }\n\n return {\n filterIds: [],\n logIndex: hexToNumber(viemLog.logIndex),\n address: viemLog.address,\n topics: viemLog.topics,\n data: viemLog.data,\n transactionIndex: hexToNumber(viemLog.transactionIndex),\n transactionHash: viemLog.transactionHash,\n transactionStatus: viemLog.removed ? \"reverted\" : \"succeeded\",\n };\n}\n\nexport function rpcBlockHeaderToDna(block: RpcBlock): DnaBlockHeader {\n const formattedBlock = formatBlock(block);\n return viemBlockHeaderToDna(formattedBlock);\n}\n\nexport function viemBlockHeaderToDna(viemBlock: ViemBlock): DnaBlockHeader {\n if (viemBlock.number === null || !viemBlock.hash) {\n throw new Error(\n `Invalid block: missing required fields (number: ${viemBlock.number}, hash: ${viemBlock.hash})`,\n );\n }\n\n return {\n blockNumber: viemBlock.number,\n blockHash: viemBlock.hash,\n parentBlockHash: viemBlock.parentHash,\n unclesHash: viemBlock.sha3Uncles,\n miner: viemBlock.miner ?? undefined,\n stateRoot: viemBlock.stateRoot,\n transactionsRoot: viemBlock.transactionsRoot,\n receiptsRoot: viemBlock.receiptsRoot,\n logsBloom: viemBlock.logsBloom ?? undefined,\n difficulty: viemBlock.difficulty,\n gasLimit: viemBlock.gasLimit,\n gasUsed: viemBlock.gasUsed,\n timestamp: new Date(Number(viemBlock.timestamp) * 1000),\n extraData: viemBlock.extraData,\n mixHash: viemBlock.mixHash ?? undefined,\n nonce: viemBlock.nonce ? BigInt(viemBlock.nonce) : undefined,\n baseFeePerGas: viemBlock.baseFeePerGas ?? undefined,\n withdrawalsRoot: viemBlock.withdrawalsRoot ?? undefined,\n totalDifficulty: viemBlock.totalDifficulty ?? undefined,\n blobGasUsed: viemBlock.blobGasUsed ?? undefined,\n excessBlobGas: viemBlock.excessBlobGas ?? undefined,\n parentBeaconBlockRoot: viemBlock.parentBeaconBlockRoot ?? undefined,\n requestsHash: undefined, // TODO: check\n };\n}\n","import type { LogFilter } from \"@apibara/evm\";\nimport type { Bytes } from \"@apibara/protocol\";\nimport type { RpcLog } from \"viem\";\nimport {\n hexToNumber,\n isAddressEqual,\n isHex,\n numberToHex,\n pad,\n trim,\n} from \"viem\";\nimport type { Log } from \"./block\";\nimport type { Filter } from \"./filter\";\nimport type { ViemRpcClient } from \"./stream-config\";\nimport { viemRpcLogToDna } from \"./transform\";\n\nexport async function fetchLogsByBlockHash({\n client,\n blockHash,\n filter,\n mergeGetLogs,\n}: {\n client: ViemRpcClient;\n blockHash: Bytes;\n filter: Filter;\n mergeGetLogs: boolean;\n}): Promise<{ logs: Log[] }> {\n if (!filter.logs || filter.logs.length === 0) {\n return { logs: [] };\n }\n\n const responses = mergeGetLogs\n ? await mergedGetLogsCalls({\n client,\n filter,\n blockHash,\n })\n : await standardGetLogsCalls({\n client,\n filter,\n blockHash,\n });\n\n const allLogs: Log[] = [];\n const seenLogsByIndex: Record<number, number> = {};\n\n for (const { logFilters, logs } of responses) {\n for (const log of logs) {\n if (log.blockNumber === null) {\n throw new Error(\"Log block number is null\");\n }\n\n for (const logFilter of logFilters) {\n const refinedLog = refineLog(log, logFilter);\n\n if (refinedLog) {\n const existingPosition = seenLogsByIndex[refinedLog.logIndex];\n\n if (existingPosition !== undefined) {\n const existingLog = allLogs[existingPosition];\n (existingLog.filterIds as number[]).push(logFilter.id ?? 0);\n } else {\n (refinedLog.filterIds as number[]).push(logFilter.id ?? 0);\n\n allLogs.push(refinedLog);\n seenLogsByIndex[refinedLog.logIndex] = allLogs.length - 1;\n }\n }\n }\n }\n }\n\n return { logs: allLogs };\n}\n\nexport async function fetchLogsForRange({\n client,\n fromBlock,\n toBlock,\n filter,\n mergeGetLogs,\n}: {\n client: ViemRpcClient;\n fromBlock: bigint;\n toBlock: bigint;\n filter: Filter;\n mergeGetLogs: boolean;\n}): Promise<{ logs: Record<number, Log[]>; blockNumbers: bigint[] }> {\n const logsByBlock: Record<number, Log[]> = {};\n\n if (!filter.logs || filter.logs.length === 0) {\n return { logs: logsByBlock, blockNumbers: [] };\n }\n\n const responses = mergeGetLogs\n ? await mergedGetLogsCalls({\n client,\n filter,\n fromBlock: numberToHex(fromBlock),\n toBlock: numberToHex(toBlock),\n })\n : await standardGetLogsCalls({\n client,\n filter,\n fromBlock: numberToHex(fromBlock),\n toBlock: numberToHex(toBlock),\n });\n\n const blockNumbers = new Set<bigint>();\n\n const seenLogsByBlockNumberAndIndex: Record<\n number,\n Record<number, number>\n > = {};\n\n for (const { logFilters, logs } of responses) {\n for (const log of logs) {\n if (log.blockNumber === null) {\n throw new Error(\"Log block number is null\");\n }\n\n for (const logFilter of logFilters) {\n const refinedLog = refineLog(log, logFilter);\n\n if (refinedLog) {\n const blockNumber = hexToNumber(log.blockNumber);\n blockNumbers.add(BigInt(blockNumber));\n\n if (!logsByBlock[blockNumber]) {\n logsByBlock[blockNumber] = [];\n }\n\n if (!seenLogsByBlockNumberAndIndex[blockNumber]) {\n seenLogsByBlockNumberAndIndex[blockNumber] = {};\n }\n\n const existingPosition =\n seenLogsByBlockNumberAndIndex[blockNumber][refinedLog.logIndex];\n\n if (existingPosition !== undefined) {\n const existingLog = logsByBlock[blockNumber][existingPosition];\n (existingLog.filterIds as number[]).push(logFilter.id ?? 0);\n } else {\n (refinedLog.filterIds as number[]).push(logFilter.id ?? 0);\n\n logsByBlock[blockNumber].push(refinedLog);\n seenLogsByBlockNumberAndIndex[blockNumber][refinedLog.logIndex] =\n logsByBlock[blockNumber].length - 1;\n }\n }\n }\n }\n }\n\n const sortedBlockNumbers = Array.from(blockNumbers).sort((a, b) =>\n a < b ? -1 : a > b ? 1 : 0,\n );\n\n return { logs: logsByBlock, blockNumbers: sortedBlockNumbers };\n}\n\nfunction refineLog(log: RpcLog, filter: LogFilter): Log | null {\n if (log.removed) {\n return null;\n }\n\n if (filter.address && !isAddressEqual(log.address, filter.address)) {\n return null;\n }\n\n const filterTopics = filter.topics ?? [];\n if (filter.strict && log.topics.length !== filterTopics.length) {\n return null;\n }\n\n if (filterTopics.length === 0) {\n return viemRpcLogToDna(log);\n }\n\n if (log.topics.length < filterTopics.length) {\n return null;\n }\n\n for (let i = 0; i < filterTopics.length; i++) {\n const filterTopic = filterTopics[i];\n const logTopic = log.topics[i];\n\n if (filterTopic === null) continue;\n\n if (!logTopic) return null;\n\n if (!isHex(filterTopic) || !isHex(logTopic)) {\n return null;\n }\n\n const normalizedFilter = pad(trim(filterTopic), { size: 32 });\n const normalizedLog = pad(trim(logTopic), { size: 32 });\n\n if (normalizedFilter !== normalizedLog) {\n return null;\n }\n }\n\n return viemRpcLogToDna(log);\n}\n\nasync function mergedGetLogsCalls({\n client,\n filter,\n blockHash,\n fromBlock,\n toBlock,\n}: {\n client: ViemRpcClient;\n filter: Filter;\n blockHash?: Bytes;\n fromBlock?: `0x${string}`;\n toBlock?: `0x${string}`;\n}) {\n const blockParams = blockHash ? { blockHash } : { fromBlock, toBlock };\n\n const filtersWithAddress = filter.logs.filter((f) => f.address !== undefined);\n const filtersWithoutAddress = filter.logs.filter(\n (f) => f.address === undefined,\n );\n\n const promises: Promise<{\n logs: RpcLog[];\n logFilters: typeof filter.logs;\n }>[] = [];\n\n if (filtersWithAddress.length > 0) {\n const addresses = filtersWithAddress.map((f) => f.address!);\n\n promises.push(\n client\n .request({\n method: \"eth_getLogs\",\n params: [\n {\n address: addresses,\n ...blockParams,\n },\n ],\n })\n .then((logs: RpcLog[]) => ({ logs, logFilters: filtersWithAddress })),\n );\n }\n\n if (filtersWithoutAddress.length > 0) {\n promises.push(\n client\n .request({\n method: \"eth_getLogs\",\n params: [\n {\n ...blockParams,\n },\n ],\n })\n .then((logs: RpcLog[]) => ({\n logs,\n logFilters: filtersWithoutAddress,\n })),\n );\n }\n\n return await Promise.all(promises);\n}\n\nasync function standardGetLogsCalls({\n client,\n filter,\n blockHash,\n fromBlock,\n toBlock,\n}: {\n client: ViemRpcClient;\n filter: Filter;\n blockHash?: Bytes;\n fromBlock?: `0x${string}`;\n toBlock?: `0x${string}`;\n}) {\n const blockParams = blockHash ? { blockHash } : { fromBlock, toBlock };\n return await Promise.all(\n filter.logs.map(async (logFilter) => {\n const logs = await client.request({\n method: \"eth_getLogs\",\n params: [\n {\n address: logFilter.address,\n topics:\n logFilter.topics !== undefined\n ? [...logFilter.topics]\n : undefined,\n ...blockParams,\n },\n ],\n });\n\n return { logs, logFilters: [logFilter] };\n }),\n );\n}\n","const BLOCK_RANGE_ERROR_PATTERNS = [\"invalid block range params\"] as const;\n\nexport type BlockRange = {\n start: bigint;\n end: bigint;\n};\n\nexport type BlockRangeOracle = {\n clampRange(original: BlockRange): BlockRange;\n handleSuccess(): void;\n handleError(error: unknown): { retry: boolean };\n};\n\nexport function createBlockRangeOracle({\n startingSize,\n minSize = 1n,\n maxSize = 10_000n,\n}: {\n startingSize: bigint;\n minSize?: bigint;\n maxSize?: bigint;\n}): BlockRangeOracle {\n let currentSize = startingSize;\n\n return {\n clampRange(original: BlockRange): BlockRange {\n const start = original.start;\n let end = original.end;\n\n const newEnd = start + currentSize - 1n;\n if (newEnd < end) {\n end = newEnd;\n }\n\n return { start, end };\n },\n handleSuccess(): void {\n // TODO: we can track how many successful requests and increase the size.\n // Probably want to receive the number of logs as argument and have a \"target\"\n },\n handleError(error: unknown): { retry: boolean } {\n if (error instanceof Error) {\n const message = error.message.toLowerCase();\n const isBlockRangeError = BLOCK_RANGE_ERROR_PATTERNS.some((pattern) =>\n message.includes(pattern),\n );\n\n if (isBlockRangeError) {\n if (currentSize > minSize) {\n const newSize = currentSize / 2n;\n currentSize = newSize > minSize ? newSize : minSize;\n }\n\n return { retry: true };\n }\n }\n\n return { retry: false };\n },\n };\n}\n","export async function retry<T>({\n fn,\n maxAttempts = 3,\n delay = 100,\n}: {\n fn: () => Promise<T>;\n maxAttempts?: number;\n delay?: number;\n}): Promise<T> {\n let attempts = 0;\n\n while (true) {\n try {\n return await fn();\n } catch (error) {\n attempts++;\n if (attempts >= maxAttempts) throw error;\n console.warn(`RPC error ${error}. Retrying in ${delay}ms`);\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n}\n","import type { Bytes } from \"@apibara/protocol\";\nimport {\n type BlockInfo,\n type FetchBlockByNumberArgs,\n type FetchBlockByNumberResult,\n type FetchBlockRangeArgs,\n type FetchBlockRangeResult,\n type FetchBlockResult,\n type FetchCursorArgs,\n RpcStreamConfig,\n type ValidateFilterResult,\n} from \"@apibara/protocol/rpc\";\nimport {\n type EIP1193Parameters,\n type PublicRpcSchema,\n type RpcBlock,\n formatBlock,\n numberToHex,\n toHex,\n} from \"viem\";\nimport type { Block, Log } from \"./block\";\nimport { type Filter, validateFilter } from \"./filter\";\nimport { fetchLogsByBlockHash, fetchLogsForRange } from \"./log-fetcher\";\nimport { type BlockRangeOracle, createBlockRangeOracle } from \"./range-oracle\";\nimport { retry } from \"./retry\";\nimport { rpcBlockHeaderToDna } from \"./transform\";\n\nexport type RequestParameters = EIP1193Parameters<PublicRpcSchema>;\n\nexport type RequestReturnType<method extends RequestParameters[\"method\"]> =\n Extract<PublicRpcSchema[number], { Method: method }>[\"ReturnType\"];\n\n// Require just the bare minimum from the provided viem client.\nexport type ViemRpcClient = {\n request: <TParams extends RequestParameters>(\n params: TParams,\n ) => Promise<RequestReturnType<TParams[\"method\"]>>;\n};\n\nexport type EvmRpcStreamOptions = {\n /** How many blocks to fetch in a single eth_getLogs call. */\n getLogsRangeSize?: bigint;\n /** How often to refresh the head block. */\n headRefreshIntervalMs?: number;\n /** How often to refresh the finalized block. */\n finalizedRefreshIntervalMs?: number;\n /** Force sending accepted headers even if no data matched. */\n alwaysSendAcceptedHeaders?: boolean;\n /** Merge multiple `eth_getLogs` calls into a single one, filtering data on the client. */\n mergeGetLogsFilter?: \"always\" | \"accepted\" | false;\n};\n\nexport class EvmRpcStream extends RpcStreamConfig<Filter, Block> {\n private blockRangeOracle: BlockRangeOracle;\n\n constructor(\n private client: ViemRpcClient,\n private options: EvmRpcStreamOptions = {},\n ) {\n super();\n\n this.blockRangeOracle = createBlockRangeOracle({\n startingSize: options.getLogsRangeSize ?? 1_000n,\n // Use the provided size to limit the maximum range size\n maxSize: options.getLogsRangeSize ? options.getLogsRangeSize : undefined,\n });\n }\n\n headRefreshIntervalMs(): number {\n return this.options.headRefreshIntervalMs ?? 3_000;\n }\n\n finalizedRefreshIntervalMs(): number {\n return this.options.finalizedRefreshIntervalMs ?? 30_000;\n }\n\n validateFilter(filter: Filter): ValidateFilterResult {\n return validateFilter(filter);\n }\n\n async fetchCursor(args: FetchCursorArgs): Promise<BlockInfo | null> {\n let block: RpcBlock | null = null;\n if (args.blockNumber !== undefined) {\n const blockNumber = toHex(args.blockNumber);\n block = await this.client.request({\n method: \"eth_getBlockByNumber\",\n params: [blockNumber, false],\n });\n } else if (args.blockTag) {\n block = await this.client.request({\n method: \"eth_getBlockByNumber\",\n params: [args.blockTag, false],\n });\n } else if (args.blockHash) {\n block = await this.client.request({\n method: \"eth_getBlockByHash\",\n params: [args.blockHash, false],\n });\n } else {\n throw new Error(\n \"One of blockNumber, blockHash or blockTag must be provided\",\n );\n }\n\n if (!block) {\n return null;\n }\n\n const formattedBlock = formatBlock(block);\n\n if (formattedBlock.number === null) {\n throw new Error(\"RPC block is missing required block number\");\n }\n\n if (formattedBlock.hash === null) {\n throw new Error(\"RPC block is missing required block hash\");\n }\n\n return {\n blockNumber: formattedBlock.number,\n blockHash: formattedBlock.hash,\n parentBlockHash: formattedBlock.parentHash,\n };\n }\n\n async fetchBlockRange({\n startBlock,\n finalizedBlock,\n force,\n filter,\n }: FetchBlockRangeArgs<Filter>): Promise<FetchBlockRangeResult<Block>> {\n const { start: fromBlock, end: toBlock } = this.blockRangeOracle.clampRange(\n { start: startBlock, end: finalizedBlock },\n );\n\n // console.log(\"Fetching block range\", fromBlock, toBlock, filter);\n\n const { logs: logsByBlockNumber, blockNumbers } =\n await this.fetchLogsForRangeWithRetry({\n fromBlock,\n toBlock,\n filter,\n });\n\n // If the client needs all headers, we iterate over the range and fetch headers\n // and then join them with the logs\n // Otherwise, we drive the block number iteration from the fetched logs.\n const data: FetchBlockResult<Block>[] = [];\n\n // Fetch block headers in parallel to optimize batching.\n const blockNumberResponses = [];\n if (filter.header === \"always\") {\n for (let blockNumber = fromBlock; blockNumber <= toBlock; blockNumber++) {\n blockNumberResponses.push(\n this.fetchBlockHeaderByNumberWithRetry({\n blockNumber,\n }),\n );\n }\n } else if (force && blockNumbers.length === 0) {\n blockNumberResponses.push(\n this.fetchBlockHeaderByNumberWithRetry({\n blockNumber: toBlock,\n }),\n );\n } else {\n for (const blockNumber of blockNumbers) {\n blockNumberResponses.push(\n this.fetchBlockHeaderByNumberWithRetry({\n blockNumber,\n }),\n );\n }\n }\n\n const blockNumbersWithHeader = await Promise.all(blockNumberResponses);\n for (const { blockNumber, header } of blockNumbersWithHeader) {\n const logs = logsByBlockNumber[Number(blockNumber)] ?? [];\n\n logs.sort((a, b) => a.logIndex - b.logIndex);\n\n data.push({\n cursor: undefined,\n endCursor: { orderKey: blockNumber },\n block: { header, logs },\n });\n }\n\n return { startBlock: fromBlock, endBlock: toBlock, data };\n }\n\n async fetchBlockByNumber({\n blockNumber,\n expectedParentBlockHash,\n isAtHead,\n filter,\n }: FetchBlockByNumberArgs<Filter>): Promise<FetchBlockByNumberResult<Block>> {\n // Fetch block header and check it matches the expected parent block hash.\n const { header } = await this.fetchBlockHeaderByNumberWithRetry({\n blockNumber,\n });\n\n if (header.blockHash === undefined) {\n throw new Error(`Block ${blockNumber} has no block hash`);\n }\n\n const blockInfo: BlockInfo = {\n blockNumber: header.blockNumber,\n blockHash: header.blockHash,\n parentBlockHash: header.parentBlockHash,\n };\n\n if (header.parentBlockHash !== expectedParentBlockHash) {\n return {\n status: \"reorg\",\n blockInfo,\n };\n }\n\n // Use the hash from the current block to fetch logs in a reorg-safe way.\n const { logs } = await this.fetchLogsByBlockHashWithRetry({\n blockHash: header.blockHash,\n filter,\n });\n\n logs.sort((a, b) => a.logIndex - b.logIndex);\n\n let cursor = undefined;\n if (blockNumber > 0n) {\n cursor = {\n orderKey: blockNumber - 1n,\n uniqueKey: header.parentBlockHash,\n };\n }\n const endCursor = {\n orderKey: blockNumber,\n uniqueKey: header.blockHash,\n };\n\n let block = null;\n\n const shouldSendBlock =\n filter.header === \"always\" ||\n logs.length > 0 ||\n (filter.header === \"on_data_or_on_new_block\" && isAtHead) ||\n this.options.alwaysSendAcceptedHeaders;\n\n if (shouldSendBlock) {\n block = {\n header,\n logs,\n };\n }\n\n return {\n status: \"success\",\n blockInfo,\n data: {\n cursor,\n endCursor,\n block,\n },\n };\n }\n\n private async fetchLogsForRangeWithRetry({\n fromBlock,\n toBlock,\n filter,\n }: {\n fromBlock: bigint;\n toBlock: bigint;\n filter: Filter;\n }): Promise<{ logs: Record<number, Log[]>; blockNumbers: bigint[] }> {\n try {\n return await retry({\n fn: () =>\n fetchLogsForRange({\n client: this.client,\n fromBlock,\n toBlock,\n filter,\n mergeGetLogs: this.options.mergeGetLogsFilter === \"always\",\n }),\n });\n } catch (error) {\n this.blockRangeOracle.handleError(error);\n throw error;\n }\n }\n\n private async fetchLogsByBlockHashWithRetry({\n blockHash,\n filter,\n }: {\n blockHash: Bytes;\n filter: Filter;\n }): Promise<{ logs: Log[] }> {\n return await retry({\n fn: () =>\n fetchLogsByBlockHash({\n client: this.client,\n blockHash,\n filter,\n mergeGetLogs:\n this.options.mergeGetLogsFilter === \"always\" ||\n this.options.mergeGetLogsFilter === \"accepted\",\n }),\n });\n }\n\n private async fetchBlockHeaderByNumberWithRetry({\n blockNumber,\n }: {\n blockNumber: bigint;\n }) {\n const block = await retry({\n fn: () =>\n this.client.request({\n method: \"eth_getBlockByNumber\",\n params: [numberToHex(blockNumber), false],\n }),\n });\n\n if (block === null) {\n throw new Error(`Block ${blockNumber} not found`);\n }\n\n return { header: rpcBlockHeaderToDna(block), blockNumber };\n }\n}\n","import {\n http,\n type HttpTransport,\n type HttpTransportConfig,\n type RpcSchema,\n} from \"viem\";\n\n/**\n * @description Creates a rate-limited HTTP transport that connects to a JSON-RPC API.\n */\nexport function rateLimitedHttp<\n rpcSchema extends RpcSchema | undefined = undefined,\n raw extends boolean = false,\n>(\n /** URL of the JSON-RPC API. Defaults to the chain's public RPC URL. */\n url?: string | undefined,\n config: HttpTransportConfig<rpcSchema, raw> & { rps?: number } = {},\n): HttpTransport<rpcSchema, raw> {\n const { onFetchRequest, onFetchResponse, ...rest } = config;\n\n const rps = config.rps ?? 10;\n\n const limiter = createRateLimiter({\n capacity: rps,\n refillRate: rps,\n });\n\n return http(url, {\n ...rest,\n async onFetchRequest(request, init) {\n await limiter.acquireOne();\n await onFetchRequest?.(request, init);\n },\n async onFetchResponse(response) {\n await onFetchResponse?.(response);\n },\n });\n}\n\nfunction createRateLimiter({\n capacity,\n refillRate,\n refillInterval: refillInterval_,\n lastRefillTime: startingRefillTime,\n}: {\n capacity: number;\n refillRate: number;\n refillInterval?: number;\n lastRefillTime?: number;\n}) {\n const refillInterval = refillInterval_ ?? 100;\n\n let tokens = capacity;\n let lastRefillTime = startingRefillTime ?? Date.now();\n\n function refill(now: number) {\n const elapsed = (now - lastRefillTime) / 1_000;\n const newTokens = elapsed * refillRate;\n tokens = Math.min(capacity, tokens + newTokens);\n lastRefillTime = now;\n }\n\n return {\n available() {\n return tokens;\n },\n // Wait for a single token to become available.\n async acquireOne(now?: number) {\n while (true) {\n refill(now ?? Date.now());\n if (tokens > 0) {\n tokens -= 1;\n return;\n }\n\n await new Promise((resolve) => setTimeout(resolve, refillInterval));\n }\n },\n };\n}\n"],"names":["isHex","hexToNumber","formatBlock","numberToHex","isAddressEqual","pad","trim","RpcStreamConfig","toHex","http"],"mappings":"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"}
package/dist/index.mjs CHANGED
@@ -338,6 +338,25 @@ function createBlockRangeOracle({
338
338
  };
339
339
  }
340
340
 
341
+ async function retry({
342
+ fn,
343
+ maxAttempts = 3,
344
+ delay = 100
345
+ }) {
346
+ let attempts = 0;
347
+ while (true) {
348
+ try {
349
+ return await fn();
350
+ } catch (error) {
351
+ attempts++;
352
+ if (attempts >= maxAttempts)
353
+ throw error;
354
+ console.warn(`RPC error ${error}. Retrying in ${delay}ms`);
355
+ await new Promise((resolve) => setTimeout(resolve, delay));
356
+ }
357
+ }
358
+ }
359
+
341
360
  var __defProp = Object.defineProperty;
342
361
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
343
362
  var __publicField = (obj, key, value) => {
@@ -518,12 +537,14 @@ class EvmRpcStream extends RpcStreamConfig {
518
537
  filter
519
538
  }) {
520
539
  try {
521
- return await fetchLogsForRange({
522
- client: this.client,
523
- fromBlock,
524
- toBlock,
525
- filter,
526
- mergeGetLogs: this.options.mergeGetLogsFilter === "always"
540
+ return await retry({
541
+ fn: () => fetchLogsForRange({
542
+ client: this.client,
543
+ fromBlock,
544
+ toBlock,
545
+ filter,
546
+ mergeGetLogs: this.options.mergeGetLogsFilter === "always"
547
+ })
527
548
  });
528
549
  } catch (error) {
529
550
  this.blockRangeOracle.handleError(error);
@@ -534,19 +555,23 @@ class EvmRpcStream extends RpcStreamConfig {
534
555
  blockHash,
535
556
  filter
536
557
  }) {
537
- return await fetchLogsByBlockHash({
538
- client: this.client,
539
- blockHash,
540
- filter,
541
- mergeGetLogs: this.options.mergeGetLogsFilter === "always" || this.options.mergeGetLogsFilter === "accepted"
558
+ return await retry({
559
+ fn: () => fetchLogsByBlockHash({
560
+ client: this.client,
561
+ blockHash,
562
+ filter,
563
+ mergeGetLogs: this.options.mergeGetLogsFilter === "always" || this.options.mergeGetLogsFilter === "accepted"
564
+ })
542
565
  });
543
566
  }
544
567
  async fetchBlockHeaderByNumberWithRetry({
545
568
  blockNumber
546
569
  }) {
547
- const block = await this.client.request({
548
- method: "eth_getBlockByNumber",
549
- params: [numberToHex(blockNumber), false]
570
+ const block = await retry({
571
+ fn: () => this.client.request({
572
+ method: "eth_getBlockByNumber",
573
+ params: [numberToHex(blockNumber), false]
574
+ })
550
575
  });
551
576
  if (block === null) {
552
577
  throw new Error(`Block ${blockNumber} not found`);
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../src/filter.ts","../src/transform.ts","../src/log-fetcher.ts","../src/range-oracle.ts","../src/stream-config.ts","../src/rate-limited-http.ts"],"sourcesContent":["import type { LogFilter as DnaLogFilter, HeaderFilter } from \"@apibara/evm\";\nimport type { ValidateFilterResult } from \"@apibara/protocol/rpc\";\nimport { isHex } from \"viem\";\n\nexport type Filter = {\n header?: HeaderFilter;\n logs: LogFilter[];\n};\n\nexport type LogFilter = Pick<\n DnaLogFilter,\n \"address\" | \"topics\" | \"strict\" | \"id\"\n>;\n\nexport function validateFilter(filter: Filter): ValidateFilterResult {\n if (!filter.logs || filter.logs.length === 0) {\n return { valid: false, error: \"Missing logs filter\" };\n }\n\n let logFilterIndex = 0;\n for (const logFilter of filter.logs ?? []) {\n if (\n logFilter.address === undefined &&\n (logFilter.topics?.length ?? 0) === 0\n ) {\n return {\n valid: false,\n error: `Must provide at least one address or topic in log filter at position ${logFilterIndex}`,\n };\n }\n\n if (logFilter.address) {\n if (!isHex(logFilter.address)) {\n return {\n valid: false,\n error: \"Invalid address format. Expected 0x-prefixed hex string\",\n };\n }\n }\n\n if (logFilter.topics) {\n for (let i = 0; i < logFilter.topics.length; i++) {\n const topic = logFilter.topics[i];\n if (topic === null) {\n continue;\n }\n\n if (!isHex(topic)) {\n return {\n valid: false,\n error: `Invalid topic at index ${i}: ${topic}. Must be null or a 0x-prefixed hex string`,\n };\n }\n }\n }\n\n logFilterIndex++;\n }\n\n return { valid: true };\n}\n","import {\n type RpcBlock,\n type RpcLog,\n type Block as ViemBlock,\n formatBlock,\n hexToNumber,\n} from \"viem\";\nimport type { BlockHeader as DnaBlockHeader, Log as DnaLog } from \"./block\";\n\nexport function viemRpcLogToDna(viemLog: RpcLog): DnaLog {\n if (\n viemLog.logIndex === null ||\n viemLog.transactionIndex === null ||\n viemLog.transactionHash === null\n ) {\n throw new Error(\n \"Invalid log: missing required fields: logIndex, transactionIndex, transactionHash\",\n );\n }\n\n return {\n filterIds: [],\n logIndex: hexToNumber(viemLog.logIndex),\n address: viemLog.address,\n topics: viemLog.topics,\n data: viemLog.data,\n transactionIndex: hexToNumber(viemLog.transactionIndex),\n transactionHash: viemLog.transactionHash,\n transactionStatus: viemLog.removed ? \"reverted\" : \"succeeded\",\n };\n}\n\nexport function rpcBlockHeaderToDna(block: RpcBlock): DnaBlockHeader {\n const formattedBlock = formatBlock(block);\n return viemBlockHeaderToDna(formattedBlock);\n}\n\nexport function viemBlockHeaderToDna(viemBlock: ViemBlock): DnaBlockHeader {\n if (viemBlock.number === null || !viemBlock.hash) {\n throw new Error(\n `Invalid block: missing required fields (number: ${viemBlock.number}, hash: ${viemBlock.hash})`,\n );\n }\n\n return {\n blockNumber: viemBlock.number,\n blockHash: viemBlock.hash,\n parentBlockHash: viemBlock.parentHash,\n unclesHash: viemBlock.sha3Uncles,\n miner: viemBlock.miner ?? undefined,\n stateRoot: viemBlock.stateRoot,\n transactionsRoot: viemBlock.transactionsRoot,\n receiptsRoot: viemBlock.receiptsRoot,\n logsBloom: viemBlock.logsBloom ?? undefined,\n difficulty: viemBlock.difficulty,\n gasLimit: viemBlock.gasLimit,\n gasUsed: viemBlock.gasUsed,\n timestamp: new Date(Number(viemBlock.timestamp) * 1000),\n extraData: viemBlock.extraData,\n mixHash: viemBlock.mixHash ?? undefined,\n nonce: viemBlock.nonce ? BigInt(viemBlock.nonce) : undefined,\n baseFeePerGas: viemBlock.baseFeePerGas ?? undefined,\n withdrawalsRoot: viemBlock.withdrawalsRoot ?? undefined,\n totalDifficulty: viemBlock.totalDifficulty ?? undefined,\n blobGasUsed: viemBlock.blobGasUsed ?? undefined,\n excessBlobGas: viemBlock.excessBlobGas ?? undefined,\n parentBeaconBlockRoot: viemBlock.parentBeaconBlockRoot ?? undefined,\n requestsHash: undefined, // TODO: check\n };\n}\n","import type { LogFilter } from \"@apibara/evm\";\nimport type { Bytes } from \"@apibara/protocol\";\nimport type { RpcLog } from \"viem\";\nimport {\n hexToNumber,\n isAddressEqual,\n isHex,\n numberToHex,\n pad,\n trim,\n} from \"viem\";\nimport type { Log } from \"./block\";\nimport type { Filter } from \"./filter\";\nimport type { ViemRpcClient } from \"./stream-config\";\nimport { viemRpcLogToDna } from \"./transform\";\n\nexport async function fetchLogsByBlockHash({\n client,\n blockHash,\n filter,\n mergeGetLogs,\n}: {\n client: ViemRpcClient;\n blockHash: Bytes;\n filter: Filter;\n mergeGetLogs: boolean;\n}): Promise<{ logs: Log[] }> {\n if (!filter.logs || filter.logs.length === 0) {\n return { logs: [] };\n }\n\n const responses = mergeGetLogs\n ? await mergedGetLogsCalls({\n client,\n filter,\n blockHash,\n })\n : await standardGetLogsCalls({\n client,\n filter,\n blockHash,\n });\n\n const allLogs: Log[] = [];\n const seenLogsByIndex: Record<number, number> = {};\n\n for (const { logFilters, logs } of responses) {\n for (const log of logs) {\n if (log.blockNumber === null) {\n throw new Error(\"Log block number is null\");\n }\n\n for (const logFilter of logFilters) {\n const refinedLog = refineLog(log, logFilter);\n\n if (refinedLog) {\n const existingPosition = seenLogsByIndex[refinedLog.logIndex];\n\n if (existingPosition !== undefined) {\n const existingLog = allLogs[existingPosition];\n (existingLog.filterIds as number[]).push(logFilter.id ?? 0);\n } else {\n (refinedLog.filterIds as number[]).push(logFilter.id ?? 0);\n\n allLogs.push(refinedLog);\n seenLogsByIndex[refinedLog.logIndex] = allLogs.length - 1;\n }\n }\n }\n }\n }\n\n return { logs: allLogs };\n}\n\nexport async function fetchLogsForRange({\n client,\n fromBlock,\n toBlock,\n filter,\n mergeGetLogs,\n}: {\n client: ViemRpcClient;\n fromBlock: bigint;\n toBlock: bigint;\n filter: Filter;\n mergeGetLogs: boolean;\n}): Promise<{ logs: Record<number, Log[]>; blockNumbers: bigint[] }> {\n const logsByBlock: Record<number, Log[]> = {};\n\n if (!filter.logs || filter.logs.length === 0) {\n return { logs: logsByBlock, blockNumbers: [] };\n }\n\n const responses = mergeGetLogs\n ? await mergedGetLogsCalls({\n client,\n filter,\n fromBlock: numberToHex(fromBlock),\n toBlock: numberToHex(toBlock),\n })\n : await standardGetLogsCalls({\n client,\n filter,\n fromBlock: numberToHex(fromBlock),\n toBlock: numberToHex(toBlock),\n });\n\n const blockNumbers = new Set<bigint>();\n\n const seenLogsByBlockNumberAndIndex: Record<\n number,\n Record<number, number>\n > = {};\n\n for (const { logFilters, logs } of responses) {\n for (const log of logs) {\n if (log.blockNumber === null) {\n throw new Error(\"Log block number is null\");\n }\n\n for (const logFilter of logFilters) {\n const refinedLog = refineLog(log, logFilter);\n\n if (refinedLog) {\n const blockNumber = hexToNumber(log.blockNumber);\n blockNumbers.add(BigInt(blockNumber));\n\n if (!logsByBlock[blockNumber]) {\n logsByBlock[blockNumber] = [];\n }\n\n if (!seenLogsByBlockNumberAndIndex[blockNumber]) {\n seenLogsByBlockNumberAndIndex[blockNumber] = {};\n }\n\n const existingPosition =\n seenLogsByBlockNumberAndIndex[blockNumber][refinedLog.logIndex];\n\n if (existingPosition !== undefined) {\n const existingLog = logsByBlock[blockNumber][existingPosition];\n (existingLog.filterIds as number[]).push(logFilter.id ?? 0);\n } else {\n (refinedLog.filterIds as number[]).push(logFilter.id ?? 0);\n\n logsByBlock[blockNumber].push(refinedLog);\n seenLogsByBlockNumberAndIndex[blockNumber][refinedLog.logIndex] =\n logsByBlock[blockNumber].length - 1;\n }\n }\n }\n }\n }\n\n const sortedBlockNumbers = Array.from(blockNumbers).sort((a, b) =>\n a < b ? -1 : a > b ? 1 : 0,\n );\n\n return { logs: logsByBlock, blockNumbers: sortedBlockNumbers };\n}\n\nfunction refineLog(log: RpcLog, filter: LogFilter): Log | null {\n if (log.removed) {\n return null;\n }\n\n if (filter.address && !isAddressEqual(log.address, filter.address)) {\n return null;\n }\n\n const filterTopics = filter.topics ?? [];\n if (filter.strict && log.topics.length !== filterTopics.length) {\n return null;\n }\n\n if (filterTopics.length === 0) {\n return viemRpcLogToDna(log);\n }\n\n if (log.topics.length < filterTopics.length) {\n return null;\n }\n\n for (let i = 0; i < filterTopics.length; i++) {\n const filterTopic = filterTopics[i];\n const logTopic = log.topics[i];\n\n if (filterTopic === null) continue;\n\n if (!logTopic) return null;\n\n if (!isHex(filterTopic) || !isHex(logTopic)) {\n return null;\n }\n\n const normalizedFilter = pad(trim(filterTopic), { size: 32 });\n const normalizedLog = pad(trim(logTopic), { size: 32 });\n\n if (normalizedFilter !== normalizedLog) {\n return null;\n }\n }\n\n return viemRpcLogToDna(log);\n}\n\nasync function mergedGetLogsCalls({\n client,\n filter,\n blockHash,\n fromBlock,\n toBlock,\n}: {\n client: ViemRpcClient;\n filter: Filter;\n blockHash?: Bytes;\n fromBlock?: `0x${string}`;\n toBlock?: `0x${string}`;\n}) {\n const blockParams = blockHash ? { blockHash } : { fromBlock, toBlock };\n\n const filtersWithAddress = filter.logs.filter((f) => f.address !== undefined);\n const filtersWithoutAddress = filter.logs.filter(\n (f) => f.address === undefined,\n );\n\n const promises: Promise<{\n logs: RpcLog[];\n logFilters: typeof filter.logs;\n }>[] = [];\n\n if (filtersWithAddress.length > 0) {\n const addresses = filtersWithAddress.map((f) => f.address!);\n\n promises.push(\n client\n .request({\n method: \"eth_getLogs\",\n params: [\n {\n address: addresses,\n ...blockParams,\n },\n ],\n })\n .then((logs: RpcLog[]) => ({ logs, logFilters: filtersWithAddress })),\n );\n }\n\n if (filtersWithoutAddress.length > 0) {\n promises.push(\n client\n .request({\n method: \"eth_getLogs\",\n params: [\n {\n ...blockParams,\n },\n ],\n })\n .then((logs: RpcLog[]) => ({\n logs,\n logFilters: filtersWithoutAddress,\n })),\n );\n }\n\n return await Promise.all(promises);\n}\n\nasync function standardGetLogsCalls({\n client,\n filter,\n blockHash,\n fromBlock,\n toBlock,\n}: {\n client: ViemRpcClient;\n filter: Filter;\n blockHash?: Bytes;\n fromBlock?: `0x${string}`;\n toBlock?: `0x${string}`;\n}) {\n const blockParams = blockHash ? { blockHash } : { fromBlock, toBlock };\n return await Promise.all(\n filter.logs.map(async (logFilter) => {\n const logs = await client.request({\n method: \"eth_getLogs\",\n params: [\n {\n address: logFilter.address,\n topics:\n logFilter.topics !== undefined\n ? [...logFilter.topics]\n : undefined,\n ...blockParams,\n },\n ],\n });\n\n return { logs, logFilters: [logFilter] };\n }),\n );\n}\n","const BLOCK_RANGE_ERROR_PATTERNS = [\"invalid block range params\"] as const;\n\nexport type BlockRange = {\n start: bigint;\n end: bigint;\n};\n\nexport type BlockRangeOracle = {\n clampRange(original: BlockRange): BlockRange;\n handleSuccess(): void;\n handleError(error: unknown): { retry: boolean };\n};\n\nexport function createBlockRangeOracle({\n startingSize,\n minSize = 1n,\n maxSize = 10_000n,\n}: {\n startingSize: bigint;\n minSize?: bigint;\n maxSize?: bigint;\n}): BlockRangeOracle {\n let currentSize = startingSize;\n\n return {\n clampRange(original: BlockRange): BlockRange {\n const start = original.start;\n let end = original.end;\n\n const newEnd = start + currentSize - 1n;\n if (newEnd < end) {\n end = newEnd;\n }\n\n return { start, end };\n },\n handleSuccess(): void {\n // TODO: we can track how many successful requests and increase the size.\n // Probably want to receive the number of logs as argument and have a \"target\"\n },\n handleError(error: unknown): { retry: boolean } {\n if (error instanceof Error) {\n const message = error.message.toLowerCase();\n const isBlockRangeError = BLOCK_RANGE_ERROR_PATTERNS.some((pattern) =>\n message.includes(pattern),\n );\n\n if (isBlockRangeError) {\n if (currentSize > minSize) {\n const newSize = currentSize / 2n;\n currentSize = newSize > minSize ? newSize : minSize;\n }\n\n return { retry: true };\n }\n }\n\n return { retry: false };\n },\n };\n}\n","import type { Bytes } from \"@apibara/protocol\";\nimport {\n type BlockInfo,\n type FetchBlockByNumberArgs,\n type FetchBlockByNumberResult,\n type FetchBlockRangeArgs,\n type FetchBlockRangeResult,\n type FetchBlockResult,\n type FetchCursorArgs,\n RpcStreamConfig,\n type ValidateFilterResult,\n} from \"@apibara/protocol/rpc\";\nimport {\n type EIP1193Parameters,\n type PublicRpcSchema,\n type RpcBlock,\n formatBlock,\n numberToHex,\n toHex,\n} from \"viem\";\nimport type { Block, Log } from \"./block\";\nimport { type Filter, validateFilter } from \"./filter\";\nimport { fetchLogsByBlockHash, fetchLogsForRange } from \"./log-fetcher\";\nimport { type BlockRangeOracle, createBlockRangeOracle } from \"./range-oracle\";\nimport { rpcBlockHeaderToDna } from \"./transform\";\n\nexport type RequestParameters = EIP1193Parameters<PublicRpcSchema>;\n\nexport type RequestReturnType<method extends RequestParameters[\"method\"]> =\n Extract<PublicRpcSchema[number], { Method: method }>[\"ReturnType\"];\n\n// Require just the bare minimum from the provided viem client.\nexport type ViemRpcClient = {\n request: <TParams extends RequestParameters>(\n params: TParams,\n ) => Promise<RequestReturnType<TParams[\"method\"]>>;\n};\n\nexport type EvmRpcStreamOptions = {\n /** How many blocks to fetch in a single eth_getLogs call. */\n getLogsRangeSize?: bigint;\n /** How often to refresh the head block. */\n headRefreshIntervalMs?: number;\n /** How often to refresh the finalized block. */\n finalizedRefreshIntervalMs?: number;\n /** Force sending accepted headers even if no data matched. */\n alwaysSendAcceptedHeaders?: boolean;\n /** Merge multiple `eth_getLogs` calls into a single one, filtering data on the client. */\n mergeGetLogsFilter?: \"always\" | \"accepted\" | false;\n};\n\nexport class EvmRpcStream extends RpcStreamConfig<Filter, Block> {\n private blockRangeOracle: BlockRangeOracle;\n\n constructor(\n private client: ViemRpcClient,\n private options: EvmRpcStreamOptions = {},\n ) {\n super();\n\n this.blockRangeOracle = createBlockRangeOracle({\n startingSize: options.getLogsRangeSize ?? 1_000n,\n // Use the provided size to limit the maximum range size\n maxSize: options.getLogsRangeSize ? options.getLogsRangeSize : undefined,\n });\n }\n\n headRefreshIntervalMs(): number {\n return this.options.headRefreshIntervalMs ?? 3_000;\n }\n\n finalizedRefreshIntervalMs(): number {\n return this.options.finalizedRefreshIntervalMs ?? 30_000;\n }\n\n validateFilter(filter: Filter): ValidateFilterResult {\n return validateFilter(filter);\n }\n\n async fetchCursor(args: FetchCursorArgs): Promise<BlockInfo | null> {\n let block: RpcBlock | null = null;\n if (args.blockNumber !== undefined) {\n const blockNumber = toHex(args.blockNumber);\n block = await this.client.request({\n method: \"eth_getBlockByNumber\",\n params: [blockNumber, false],\n });\n } else if (args.blockTag) {\n block = await this.client.request({\n method: \"eth_getBlockByNumber\",\n params: [args.blockTag, false],\n });\n } else if (args.blockHash) {\n block = await this.client.request({\n method: \"eth_getBlockByHash\",\n params: [args.blockHash, false],\n });\n } else {\n throw new Error(\n \"One of blockNumber, blockHash or blockTag must be provided\",\n );\n }\n\n if (!block) {\n return null;\n }\n\n const formattedBlock = formatBlock(block);\n\n if (formattedBlock.number === null) {\n throw new Error(\"RPC block is missing required block number\");\n }\n\n if (formattedBlock.hash === null) {\n throw new Error(\"RPC block is missing required block hash\");\n }\n\n return {\n blockNumber: formattedBlock.number,\n blockHash: formattedBlock.hash,\n parentBlockHash: formattedBlock.parentHash,\n };\n }\n\n async fetchBlockRange({\n startBlock,\n finalizedBlock,\n force,\n filter,\n }: FetchBlockRangeArgs<Filter>): Promise<FetchBlockRangeResult<Block>> {\n const { start: fromBlock, end: toBlock } = this.blockRangeOracle.clampRange(\n { start: startBlock, end: finalizedBlock },\n );\n\n // console.log(\"Fetching block range\", fromBlock, toBlock, filter);\n\n const { logs: logsByBlockNumber, blockNumbers } =\n await this.fetchLogsForRangeWithRetry({\n fromBlock,\n toBlock,\n filter,\n });\n\n // If the client needs all headers, we iterate over the range and fetch headers\n // and then join them with the logs\n // Otherwise, we drive the block number iteration from the fetched logs.\n const data: FetchBlockResult<Block>[] = [];\n\n // Fetch block headers in parallel to optimize batching.\n const blockNumberResponses = [];\n if (filter.header === \"always\") {\n for (let blockNumber = fromBlock; blockNumber <= toBlock; blockNumber++) {\n blockNumberResponses.push(\n this.fetchBlockHeaderByNumberWithRetry({\n blockNumber,\n }),\n );\n }\n } else if (force && blockNumbers.length === 0) {\n blockNumberResponses.push(\n this.fetchBlockHeaderByNumberWithRetry({\n blockNumber: toBlock,\n }),\n );\n } else {\n for (const blockNumber of blockNumbers) {\n blockNumberResponses.push(\n this.fetchBlockHeaderByNumberWithRetry({\n blockNumber,\n }),\n );\n }\n }\n\n const blockNumbersWithHeader = await Promise.all(blockNumberResponses);\n for (const { blockNumber, header } of blockNumbersWithHeader) {\n const logs = logsByBlockNumber[Number(blockNumber)] ?? [];\n\n logs.sort((a, b) => a.logIndex - b.logIndex);\n\n data.push({\n cursor: undefined,\n endCursor: { orderKey: blockNumber },\n block: { header, logs },\n });\n }\n\n return { startBlock: fromBlock, endBlock: toBlock, data };\n }\n\n async fetchBlockByNumber({\n blockNumber,\n expectedParentBlockHash,\n isAtHead,\n filter,\n }: FetchBlockByNumberArgs<Filter>): Promise<FetchBlockByNumberResult<Block>> {\n // Fetch block header and check it matches the expected parent block hash.\n const { header } = await this.fetchBlockHeaderByNumberWithRetry({\n blockNumber,\n });\n\n if (header.blockHash === undefined) {\n throw new Error(`Block ${blockNumber} has no block hash`);\n }\n\n const blockInfo: BlockInfo = {\n blockNumber: header.blockNumber,\n blockHash: header.blockHash,\n parentBlockHash: header.parentBlockHash,\n };\n\n if (header.parentBlockHash !== expectedParentBlockHash) {\n return {\n status: \"reorg\",\n blockInfo,\n };\n }\n\n // Use the hash from the current block to fetch logs in a reorg-safe way.\n const { logs } = await this.fetchLogsByBlockHashWithRetry({\n blockHash: header.blockHash,\n filter,\n });\n\n logs.sort((a, b) => a.logIndex - b.logIndex);\n\n let cursor = undefined;\n if (blockNumber > 0n) {\n cursor = {\n orderKey: blockNumber - 1n,\n uniqueKey: header.parentBlockHash,\n };\n }\n const endCursor = {\n orderKey: blockNumber,\n uniqueKey: header.blockHash,\n };\n\n let block = null;\n\n const shouldSendBlock =\n filter.header === \"always\" ||\n logs.length > 0 ||\n (filter.header === \"on_data_or_on_new_block\" && isAtHead) ||\n this.options.alwaysSendAcceptedHeaders;\n\n if (shouldSendBlock) {\n block = {\n header,\n logs,\n };\n }\n\n return {\n status: \"success\",\n blockInfo,\n data: {\n cursor,\n endCursor,\n block,\n },\n };\n }\n\n private async fetchLogsForRangeWithRetry({\n fromBlock,\n toBlock,\n filter,\n }: {\n fromBlock: bigint;\n toBlock: bigint;\n filter: Filter;\n }): Promise<{ logs: Record<number, Log[]>; blockNumbers: bigint[] }> {\n // TODO: implement retry\n try {\n return await fetchLogsForRange({\n client: this.client,\n fromBlock,\n toBlock,\n filter,\n mergeGetLogs: this.options.mergeGetLogsFilter === \"always\",\n });\n } catch (error) {\n this.blockRangeOracle.handleError(error);\n throw error;\n }\n }\n\n private async fetchLogsByBlockHashWithRetry({\n blockHash,\n filter,\n }: {\n blockHash: Bytes;\n filter: Filter;\n }): Promise<{ logs: Log[] }> {\n // TODO: implement retry\n return await fetchLogsByBlockHash({\n client: this.client,\n blockHash,\n filter,\n mergeGetLogs:\n this.options.mergeGetLogsFilter === \"always\" ||\n this.options.mergeGetLogsFilter === \"accepted\",\n });\n }\n\n private async fetchBlockHeaderByNumberWithRetry({\n blockNumber,\n }: {\n blockNumber: bigint;\n }) {\n // TODO: implement retry\n const block = await this.client.request({\n method: \"eth_getBlockByNumber\",\n params: [numberToHex(blockNumber), false],\n });\n\n if (block === null) {\n throw new Error(`Block ${blockNumber} not found`);\n }\n\n return { header: rpcBlockHeaderToDna(block), blockNumber };\n }\n}\n","import {\n http,\n type HttpTransport,\n type HttpTransportConfig,\n type RpcSchema,\n} from \"viem\";\n\n/**\n * @description Creates a rate-limited HTTP transport that connects to a JSON-RPC API.\n */\nexport function rateLimitedHttp<\n rpcSchema extends RpcSchema | undefined = undefined,\n raw extends boolean = false,\n>(\n /** URL of the JSON-RPC API. Defaults to the chain's public RPC URL. */\n url?: string | undefined,\n config: HttpTransportConfig<rpcSchema, raw> & { rps?: number } = {},\n): HttpTransport<rpcSchema, raw> {\n const { onFetchRequest, onFetchResponse, ...rest } = config;\n\n const rps = config.rps ?? 10;\n\n const limiter = createRateLimiter({\n capacity: rps,\n refillRate: rps,\n });\n\n return http(url, {\n ...rest,\n async onFetchRequest(request, init) {\n await limiter.acquireOne();\n await onFetchRequest?.(request, init);\n },\n async onFetchResponse(response) {\n await onFetchResponse?.(response);\n },\n });\n}\n\nfunction createRateLimiter({\n capacity,\n refillRate,\n refillInterval: refillInterval_,\n lastRefillTime: startingRefillTime,\n}: {\n capacity: number;\n refillRate: number;\n refillInterval?: number;\n lastRefillTime?: number;\n}) {\n const refillInterval = refillInterval_ ?? 100;\n\n let tokens = capacity;\n let lastRefillTime = startingRefillTime ?? Date.now();\n\n function refill(now: number) {\n const elapsed = (now - lastRefillTime) / 1_000;\n const newTokens = elapsed * refillRate;\n tokens = Math.min(capacity, tokens + newTokens);\n lastRefillTime = now;\n }\n\n return {\n available() {\n return tokens;\n },\n // Wait for a single token to become available.\n async acquireOne(now?: number) {\n while (true) {\n refill(now ?? Date.now());\n if (tokens > 0) {\n tokens -= 1;\n return;\n }\n\n await new Promise((resolve) => setTimeout(resolve, refillInterval));\n }\n },\n };\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","sources":["../src/filter.ts","../src/transform.ts","../src/log-fetcher.ts","../src/range-oracle.ts","../src/retry.ts","../src/stream-config.ts","../src/rate-limited-http.ts"],"sourcesContent":["import type { LogFilter as DnaLogFilter, HeaderFilter } from \"@apibara/evm\";\nimport type { ValidateFilterResult } from \"@apibara/protocol/rpc\";\nimport { isHex } from \"viem\";\n\nexport type Filter = {\n header?: HeaderFilter;\n logs: LogFilter[];\n};\n\nexport type LogFilter = Pick<\n DnaLogFilter,\n \"address\" | \"topics\" | \"strict\" | \"id\"\n>;\n\nexport function validateFilter(filter: Filter): ValidateFilterResult {\n if (!filter.logs || filter.logs.length === 0) {\n return { valid: false, error: \"Missing logs filter\" };\n }\n\n let logFilterIndex = 0;\n for (const logFilter of filter.logs ?? []) {\n if (\n logFilter.address === undefined &&\n (logFilter.topics?.length ?? 0) === 0\n ) {\n return {\n valid: false,\n error: `Must provide at least one address or topic in log filter at position ${logFilterIndex}`,\n };\n }\n\n if (logFilter.address) {\n if (!isHex(logFilter.address)) {\n return {\n valid: false,\n error: \"Invalid address format. Expected 0x-prefixed hex string\",\n };\n }\n }\n\n if (logFilter.topics) {\n for (let i = 0; i < logFilter.topics.length; i++) {\n const topic = logFilter.topics[i];\n if (topic === null) {\n continue;\n }\n\n if (!isHex(topic)) {\n return {\n valid: false,\n error: `Invalid topic at index ${i}: ${topic}. Must be null or a 0x-prefixed hex string`,\n };\n }\n }\n }\n\n logFilterIndex++;\n }\n\n return { valid: true };\n}\n","import {\n type RpcBlock,\n type RpcLog,\n type Block as ViemBlock,\n formatBlock,\n hexToNumber,\n} from \"viem\";\nimport type { BlockHeader as DnaBlockHeader, Log as DnaLog } from \"./block\";\n\nexport function viemRpcLogToDna(viemLog: RpcLog): DnaLog {\n if (\n viemLog.logIndex === null ||\n viemLog.transactionIndex === null ||\n viemLog.transactionHash === null\n ) {\n throw new Error(\n \"Invalid log: missing required fields: logIndex, transactionIndex, transactionHash\",\n );\n }\n\n return {\n filterIds: [],\n logIndex: hexToNumber(viemLog.logIndex),\n address: viemLog.address,\n topics: viemLog.topics,\n data: viemLog.data,\n transactionIndex: hexToNumber(viemLog.transactionIndex),\n transactionHash: viemLog.transactionHash,\n transactionStatus: viemLog.removed ? \"reverted\" : \"succeeded\",\n };\n}\n\nexport function rpcBlockHeaderToDna(block: RpcBlock): DnaBlockHeader {\n const formattedBlock = formatBlock(block);\n return viemBlockHeaderToDna(formattedBlock);\n}\n\nexport function viemBlockHeaderToDna(viemBlock: ViemBlock): DnaBlockHeader {\n if (viemBlock.number === null || !viemBlock.hash) {\n throw new Error(\n `Invalid block: missing required fields (number: ${viemBlock.number}, hash: ${viemBlock.hash})`,\n );\n }\n\n return {\n blockNumber: viemBlock.number,\n blockHash: viemBlock.hash,\n parentBlockHash: viemBlock.parentHash,\n unclesHash: viemBlock.sha3Uncles,\n miner: viemBlock.miner ?? undefined,\n stateRoot: viemBlock.stateRoot,\n transactionsRoot: viemBlock.transactionsRoot,\n receiptsRoot: viemBlock.receiptsRoot,\n logsBloom: viemBlock.logsBloom ?? undefined,\n difficulty: viemBlock.difficulty,\n gasLimit: viemBlock.gasLimit,\n gasUsed: viemBlock.gasUsed,\n timestamp: new Date(Number(viemBlock.timestamp) * 1000),\n extraData: viemBlock.extraData,\n mixHash: viemBlock.mixHash ?? undefined,\n nonce: viemBlock.nonce ? BigInt(viemBlock.nonce) : undefined,\n baseFeePerGas: viemBlock.baseFeePerGas ?? undefined,\n withdrawalsRoot: viemBlock.withdrawalsRoot ?? undefined,\n totalDifficulty: viemBlock.totalDifficulty ?? undefined,\n blobGasUsed: viemBlock.blobGasUsed ?? undefined,\n excessBlobGas: viemBlock.excessBlobGas ?? undefined,\n parentBeaconBlockRoot: viemBlock.parentBeaconBlockRoot ?? undefined,\n requestsHash: undefined, // TODO: check\n };\n}\n","import type { LogFilter } from \"@apibara/evm\";\nimport type { Bytes } from \"@apibara/protocol\";\nimport type { RpcLog } from \"viem\";\nimport {\n hexToNumber,\n isAddressEqual,\n isHex,\n numberToHex,\n pad,\n trim,\n} from \"viem\";\nimport type { Log } from \"./block\";\nimport type { Filter } from \"./filter\";\nimport type { ViemRpcClient } from \"./stream-config\";\nimport { viemRpcLogToDna } from \"./transform\";\n\nexport async function fetchLogsByBlockHash({\n client,\n blockHash,\n filter,\n mergeGetLogs,\n}: {\n client: ViemRpcClient;\n blockHash: Bytes;\n filter: Filter;\n mergeGetLogs: boolean;\n}): Promise<{ logs: Log[] }> {\n if (!filter.logs || filter.logs.length === 0) {\n return { logs: [] };\n }\n\n const responses = mergeGetLogs\n ? await mergedGetLogsCalls({\n client,\n filter,\n blockHash,\n })\n : await standardGetLogsCalls({\n client,\n filter,\n blockHash,\n });\n\n const allLogs: Log[] = [];\n const seenLogsByIndex: Record<number, number> = {};\n\n for (const { logFilters, logs } of responses) {\n for (const log of logs) {\n if (log.blockNumber === null) {\n throw new Error(\"Log block number is null\");\n }\n\n for (const logFilter of logFilters) {\n const refinedLog = refineLog(log, logFilter);\n\n if (refinedLog) {\n const existingPosition = seenLogsByIndex[refinedLog.logIndex];\n\n if (existingPosition !== undefined) {\n const existingLog = allLogs[existingPosition];\n (existingLog.filterIds as number[]).push(logFilter.id ?? 0);\n } else {\n (refinedLog.filterIds as number[]).push(logFilter.id ?? 0);\n\n allLogs.push(refinedLog);\n seenLogsByIndex[refinedLog.logIndex] = allLogs.length - 1;\n }\n }\n }\n }\n }\n\n return { logs: allLogs };\n}\n\nexport async function fetchLogsForRange({\n client,\n fromBlock,\n toBlock,\n filter,\n mergeGetLogs,\n}: {\n client: ViemRpcClient;\n fromBlock: bigint;\n toBlock: bigint;\n filter: Filter;\n mergeGetLogs: boolean;\n}): Promise<{ logs: Record<number, Log[]>; blockNumbers: bigint[] }> {\n const logsByBlock: Record<number, Log[]> = {};\n\n if (!filter.logs || filter.logs.length === 0) {\n return { logs: logsByBlock, blockNumbers: [] };\n }\n\n const responses = mergeGetLogs\n ? await mergedGetLogsCalls({\n client,\n filter,\n fromBlock: numberToHex(fromBlock),\n toBlock: numberToHex(toBlock),\n })\n : await standardGetLogsCalls({\n client,\n filter,\n fromBlock: numberToHex(fromBlock),\n toBlock: numberToHex(toBlock),\n });\n\n const blockNumbers = new Set<bigint>();\n\n const seenLogsByBlockNumberAndIndex: Record<\n number,\n Record<number, number>\n > = {};\n\n for (const { logFilters, logs } of responses) {\n for (const log of logs) {\n if (log.blockNumber === null) {\n throw new Error(\"Log block number is null\");\n }\n\n for (const logFilter of logFilters) {\n const refinedLog = refineLog(log, logFilter);\n\n if (refinedLog) {\n const blockNumber = hexToNumber(log.blockNumber);\n blockNumbers.add(BigInt(blockNumber));\n\n if (!logsByBlock[blockNumber]) {\n logsByBlock[blockNumber] = [];\n }\n\n if (!seenLogsByBlockNumberAndIndex[blockNumber]) {\n seenLogsByBlockNumberAndIndex[blockNumber] = {};\n }\n\n const existingPosition =\n seenLogsByBlockNumberAndIndex[blockNumber][refinedLog.logIndex];\n\n if (existingPosition !== undefined) {\n const existingLog = logsByBlock[blockNumber][existingPosition];\n (existingLog.filterIds as number[]).push(logFilter.id ?? 0);\n } else {\n (refinedLog.filterIds as number[]).push(logFilter.id ?? 0);\n\n logsByBlock[blockNumber].push(refinedLog);\n seenLogsByBlockNumberAndIndex[blockNumber][refinedLog.logIndex] =\n logsByBlock[blockNumber].length - 1;\n }\n }\n }\n }\n }\n\n const sortedBlockNumbers = Array.from(blockNumbers).sort((a, b) =>\n a < b ? -1 : a > b ? 1 : 0,\n );\n\n return { logs: logsByBlock, blockNumbers: sortedBlockNumbers };\n}\n\nfunction refineLog(log: RpcLog, filter: LogFilter): Log | null {\n if (log.removed) {\n return null;\n }\n\n if (filter.address && !isAddressEqual(log.address, filter.address)) {\n return null;\n }\n\n const filterTopics = filter.topics ?? [];\n if (filter.strict && log.topics.length !== filterTopics.length) {\n return null;\n }\n\n if (filterTopics.length === 0) {\n return viemRpcLogToDna(log);\n }\n\n if (log.topics.length < filterTopics.length) {\n return null;\n }\n\n for (let i = 0; i < filterTopics.length; i++) {\n const filterTopic = filterTopics[i];\n const logTopic = log.topics[i];\n\n if (filterTopic === null) continue;\n\n if (!logTopic) return null;\n\n if (!isHex(filterTopic) || !isHex(logTopic)) {\n return null;\n }\n\n const normalizedFilter = pad(trim(filterTopic), { size: 32 });\n const normalizedLog = pad(trim(logTopic), { size: 32 });\n\n if (normalizedFilter !== normalizedLog) {\n return null;\n }\n }\n\n return viemRpcLogToDna(log);\n}\n\nasync function mergedGetLogsCalls({\n client,\n filter,\n blockHash,\n fromBlock,\n toBlock,\n}: {\n client: ViemRpcClient;\n filter: Filter;\n blockHash?: Bytes;\n fromBlock?: `0x${string}`;\n toBlock?: `0x${string}`;\n}) {\n const blockParams = blockHash ? { blockHash } : { fromBlock, toBlock };\n\n const filtersWithAddress = filter.logs.filter((f) => f.address !== undefined);\n const filtersWithoutAddress = filter.logs.filter(\n (f) => f.address === undefined,\n );\n\n const promises: Promise<{\n logs: RpcLog[];\n logFilters: typeof filter.logs;\n }>[] = [];\n\n if (filtersWithAddress.length > 0) {\n const addresses = filtersWithAddress.map((f) => f.address!);\n\n promises.push(\n client\n .request({\n method: \"eth_getLogs\",\n params: [\n {\n address: addresses,\n ...blockParams,\n },\n ],\n })\n .then((logs: RpcLog[]) => ({ logs, logFilters: filtersWithAddress })),\n );\n }\n\n if (filtersWithoutAddress.length > 0) {\n promises.push(\n client\n .request({\n method: \"eth_getLogs\",\n params: [\n {\n ...blockParams,\n },\n ],\n })\n .then((logs: RpcLog[]) => ({\n logs,\n logFilters: filtersWithoutAddress,\n })),\n );\n }\n\n return await Promise.all(promises);\n}\n\nasync function standardGetLogsCalls({\n client,\n filter,\n blockHash,\n fromBlock,\n toBlock,\n}: {\n client: ViemRpcClient;\n filter: Filter;\n blockHash?: Bytes;\n fromBlock?: `0x${string}`;\n toBlock?: `0x${string}`;\n}) {\n const blockParams = blockHash ? { blockHash } : { fromBlock, toBlock };\n return await Promise.all(\n filter.logs.map(async (logFilter) => {\n const logs = await client.request({\n method: \"eth_getLogs\",\n params: [\n {\n address: logFilter.address,\n topics:\n logFilter.topics !== undefined\n ? [...logFilter.topics]\n : undefined,\n ...blockParams,\n },\n ],\n });\n\n return { logs, logFilters: [logFilter] };\n }),\n );\n}\n","const BLOCK_RANGE_ERROR_PATTERNS = [\"invalid block range params\"] as const;\n\nexport type BlockRange = {\n start: bigint;\n end: bigint;\n};\n\nexport type BlockRangeOracle = {\n clampRange(original: BlockRange): BlockRange;\n handleSuccess(): void;\n handleError(error: unknown): { retry: boolean };\n};\n\nexport function createBlockRangeOracle({\n startingSize,\n minSize = 1n,\n maxSize = 10_000n,\n}: {\n startingSize: bigint;\n minSize?: bigint;\n maxSize?: bigint;\n}): BlockRangeOracle {\n let currentSize = startingSize;\n\n return {\n clampRange(original: BlockRange): BlockRange {\n const start = original.start;\n let end = original.end;\n\n const newEnd = start + currentSize - 1n;\n if (newEnd < end) {\n end = newEnd;\n }\n\n return { start, end };\n },\n handleSuccess(): void {\n // TODO: we can track how many successful requests and increase the size.\n // Probably want to receive the number of logs as argument and have a \"target\"\n },\n handleError(error: unknown): { retry: boolean } {\n if (error instanceof Error) {\n const message = error.message.toLowerCase();\n const isBlockRangeError = BLOCK_RANGE_ERROR_PATTERNS.some((pattern) =>\n message.includes(pattern),\n );\n\n if (isBlockRangeError) {\n if (currentSize > minSize) {\n const newSize = currentSize / 2n;\n currentSize = newSize > minSize ? newSize : minSize;\n }\n\n return { retry: true };\n }\n }\n\n return { retry: false };\n },\n };\n}\n","export async function retry<T>({\n fn,\n maxAttempts = 3,\n delay = 100,\n}: {\n fn: () => Promise<T>;\n maxAttempts?: number;\n delay?: number;\n}): Promise<T> {\n let attempts = 0;\n\n while (true) {\n try {\n return await fn();\n } catch (error) {\n attempts++;\n if (attempts >= maxAttempts) throw error;\n console.warn(`RPC error ${error}. Retrying in ${delay}ms`);\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n}\n","import type { Bytes } from \"@apibara/protocol\";\nimport {\n type BlockInfo,\n type FetchBlockByNumberArgs,\n type FetchBlockByNumberResult,\n type FetchBlockRangeArgs,\n type FetchBlockRangeResult,\n type FetchBlockResult,\n type FetchCursorArgs,\n RpcStreamConfig,\n type ValidateFilterResult,\n} from \"@apibara/protocol/rpc\";\nimport {\n type EIP1193Parameters,\n type PublicRpcSchema,\n type RpcBlock,\n formatBlock,\n numberToHex,\n toHex,\n} from \"viem\";\nimport type { Block, Log } from \"./block\";\nimport { type Filter, validateFilter } from \"./filter\";\nimport { fetchLogsByBlockHash, fetchLogsForRange } from \"./log-fetcher\";\nimport { type BlockRangeOracle, createBlockRangeOracle } from \"./range-oracle\";\nimport { retry } from \"./retry\";\nimport { rpcBlockHeaderToDna } from \"./transform\";\n\nexport type RequestParameters = EIP1193Parameters<PublicRpcSchema>;\n\nexport type RequestReturnType<method extends RequestParameters[\"method\"]> =\n Extract<PublicRpcSchema[number], { Method: method }>[\"ReturnType\"];\n\n// Require just the bare minimum from the provided viem client.\nexport type ViemRpcClient = {\n request: <TParams extends RequestParameters>(\n params: TParams,\n ) => Promise<RequestReturnType<TParams[\"method\"]>>;\n};\n\nexport type EvmRpcStreamOptions = {\n /** How many blocks to fetch in a single eth_getLogs call. */\n getLogsRangeSize?: bigint;\n /** How often to refresh the head block. */\n headRefreshIntervalMs?: number;\n /** How often to refresh the finalized block. */\n finalizedRefreshIntervalMs?: number;\n /** Force sending accepted headers even if no data matched. */\n alwaysSendAcceptedHeaders?: boolean;\n /** Merge multiple `eth_getLogs` calls into a single one, filtering data on the client. */\n mergeGetLogsFilter?: \"always\" | \"accepted\" | false;\n};\n\nexport class EvmRpcStream extends RpcStreamConfig<Filter, Block> {\n private blockRangeOracle: BlockRangeOracle;\n\n constructor(\n private client: ViemRpcClient,\n private options: EvmRpcStreamOptions = {},\n ) {\n super();\n\n this.blockRangeOracle = createBlockRangeOracle({\n startingSize: options.getLogsRangeSize ?? 1_000n,\n // Use the provided size to limit the maximum range size\n maxSize: options.getLogsRangeSize ? options.getLogsRangeSize : undefined,\n });\n }\n\n headRefreshIntervalMs(): number {\n return this.options.headRefreshIntervalMs ?? 3_000;\n }\n\n finalizedRefreshIntervalMs(): number {\n return this.options.finalizedRefreshIntervalMs ?? 30_000;\n }\n\n validateFilter(filter: Filter): ValidateFilterResult {\n return validateFilter(filter);\n }\n\n async fetchCursor(args: FetchCursorArgs): Promise<BlockInfo | null> {\n let block: RpcBlock | null = null;\n if (args.blockNumber !== undefined) {\n const blockNumber = toHex(args.blockNumber);\n block = await this.client.request({\n method: \"eth_getBlockByNumber\",\n params: [blockNumber, false],\n });\n } else if (args.blockTag) {\n block = await this.client.request({\n method: \"eth_getBlockByNumber\",\n params: [args.blockTag, false],\n });\n } else if (args.blockHash) {\n block = await this.client.request({\n method: \"eth_getBlockByHash\",\n params: [args.blockHash, false],\n });\n } else {\n throw new Error(\n \"One of blockNumber, blockHash or blockTag must be provided\",\n );\n }\n\n if (!block) {\n return null;\n }\n\n const formattedBlock = formatBlock(block);\n\n if (formattedBlock.number === null) {\n throw new Error(\"RPC block is missing required block number\");\n }\n\n if (formattedBlock.hash === null) {\n throw new Error(\"RPC block is missing required block hash\");\n }\n\n return {\n blockNumber: formattedBlock.number,\n blockHash: formattedBlock.hash,\n parentBlockHash: formattedBlock.parentHash,\n };\n }\n\n async fetchBlockRange({\n startBlock,\n finalizedBlock,\n force,\n filter,\n }: FetchBlockRangeArgs<Filter>): Promise<FetchBlockRangeResult<Block>> {\n const { start: fromBlock, end: toBlock } = this.blockRangeOracle.clampRange(\n { start: startBlock, end: finalizedBlock },\n );\n\n // console.log(\"Fetching block range\", fromBlock, toBlock, filter);\n\n const { logs: logsByBlockNumber, blockNumbers } =\n await this.fetchLogsForRangeWithRetry({\n fromBlock,\n toBlock,\n filter,\n });\n\n // If the client needs all headers, we iterate over the range and fetch headers\n // and then join them with the logs\n // Otherwise, we drive the block number iteration from the fetched logs.\n const data: FetchBlockResult<Block>[] = [];\n\n // Fetch block headers in parallel to optimize batching.\n const blockNumberResponses = [];\n if (filter.header === \"always\") {\n for (let blockNumber = fromBlock; blockNumber <= toBlock; blockNumber++) {\n blockNumberResponses.push(\n this.fetchBlockHeaderByNumberWithRetry({\n blockNumber,\n }),\n );\n }\n } else if (force && blockNumbers.length === 0) {\n blockNumberResponses.push(\n this.fetchBlockHeaderByNumberWithRetry({\n blockNumber: toBlock,\n }),\n );\n } else {\n for (const blockNumber of blockNumbers) {\n blockNumberResponses.push(\n this.fetchBlockHeaderByNumberWithRetry({\n blockNumber,\n }),\n );\n }\n }\n\n const blockNumbersWithHeader = await Promise.all(blockNumberResponses);\n for (const { blockNumber, header } of blockNumbersWithHeader) {\n const logs = logsByBlockNumber[Number(blockNumber)] ?? [];\n\n logs.sort((a, b) => a.logIndex - b.logIndex);\n\n data.push({\n cursor: undefined,\n endCursor: { orderKey: blockNumber },\n block: { header, logs },\n });\n }\n\n return { startBlock: fromBlock, endBlock: toBlock, data };\n }\n\n async fetchBlockByNumber({\n blockNumber,\n expectedParentBlockHash,\n isAtHead,\n filter,\n }: FetchBlockByNumberArgs<Filter>): Promise<FetchBlockByNumberResult<Block>> {\n // Fetch block header and check it matches the expected parent block hash.\n const { header } = await this.fetchBlockHeaderByNumberWithRetry({\n blockNumber,\n });\n\n if (header.blockHash === undefined) {\n throw new Error(`Block ${blockNumber} has no block hash`);\n }\n\n const blockInfo: BlockInfo = {\n blockNumber: header.blockNumber,\n blockHash: header.blockHash,\n parentBlockHash: header.parentBlockHash,\n };\n\n if (header.parentBlockHash !== expectedParentBlockHash) {\n return {\n status: \"reorg\",\n blockInfo,\n };\n }\n\n // Use the hash from the current block to fetch logs in a reorg-safe way.\n const { logs } = await this.fetchLogsByBlockHashWithRetry({\n blockHash: header.blockHash,\n filter,\n });\n\n logs.sort((a, b) => a.logIndex - b.logIndex);\n\n let cursor = undefined;\n if (blockNumber > 0n) {\n cursor = {\n orderKey: blockNumber - 1n,\n uniqueKey: header.parentBlockHash,\n };\n }\n const endCursor = {\n orderKey: blockNumber,\n uniqueKey: header.blockHash,\n };\n\n let block = null;\n\n const shouldSendBlock =\n filter.header === \"always\" ||\n logs.length > 0 ||\n (filter.header === \"on_data_or_on_new_block\" && isAtHead) ||\n this.options.alwaysSendAcceptedHeaders;\n\n if (shouldSendBlock) {\n block = {\n header,\n logs,\n };\n }\n\n return {\n status: \"success\",\n blockInfo,\n data: {\n cursor,\n endCursor,\n block,\n },\n };\n }\n\n private async fetchLogsForRangeWithRetry({\n fromBlock,\n toBlock,\n filter,\n }: {\n fromBlock: bigint;\n toBlock: bigint;\n filter: Filter;\n }): Promise<{ logs: Record<number, Log[]>; blockNumbers: bigint[] }> {\n try {\n return await retry({\n fn: () =>\n fetchLogsForRange({\n client: this.client,\n fromBlock,\n toBlock,\n filter,\n mergeGetLogs: this.options.mergeGetLogsFilter === \"always\",\n }),\n });\n } catch (error) {\n this.blockRangeOracle.handleError(error);\n throw error;\n }\n }\n\n private async fetchLogsByBlockHashWithRetry({\n blockHash,\n filter,\n }: {\n blockHash: Bytes;\n filter: Filter;\n }): Promise<{ logs: Log[] }> {\n return await retry({\n fn: () =>\n fetchLogsByBlockHash({\n client: this.client,\n blockHash,\n filter,\n mergeGetLogs:\n this.options.mergeGetLogsFilter === \"always\" ||\n this.options.mergeGetLogsFilter === \"accepted\",\n }),\n });\n }\n\n private async fetchBlockHeaderByNumberWithRetry({\n blockNumber,\n }: {\n blockNumber: bigint;\n }) {\n const block = await retry({\n fn: () =>\n this.client.request({\n method: \"eth_getBlockByNumber\",\n params: [numberToHex(blockNumber), false],\n }),\n });\n\n if (block === null) {\n throw new Error(`Block ${blockNumber} not found`);\n }\n\n return { header: rpcBlockHeaderToDna(block), blockNumber };\n }\n}\n","import {\n http,\n type HttpTransport,\n type HttpTransportConfig,\n type RpcSchema,\n} from \"viem\";\n\n/**\n * @description Creates a rate-limited HTTP transport that connects to a JSON-RPC API.\n */\nexport function rateLimitedHttp<\n rpcSchema extends RpcSchema | undefined = undefined,\n raw extends boolean = false,\n>(\n /** URL of the JSON-RPC API. Defaults to the chain's public RPC URL. */\n url?: string | undefined,\n config: HttpTransportConfig<rpcSchema, raw> & { rps?: number } = {},\n): HttpTransport<rpcSchema, raw> {\n const { onFetchRequest, onFetchResponse, ...rest } = config;\n\n const rps = config.rps ?? 10;\n\n const limiter = createRateLimiter({\n capacity: rps,\n refillRate: rps,\n });\n\n return http(url, {\n ...rest,\n async onFetchRequest(request, init) {\n await limiter.acquireOne();\n await onFetchRequest?.(request, init);\n },\n async onFetchResponse(response) {\n await onFetchResponse?.(response);\n },\n });\n}\n\nfunction createRateLimiter({\n capacity,\n refillRate,\n refillInterval: refillInterval_,\n lastRefillTime: startingRefillTime,\n}: {\n capacity: number;\n refillRate: number;\n refillInterval?: number;\n lastRefillTime?: number;\n}) {\n const refillInterval = refillInterval_ ?? 100;\n\n let tokens = capacity;\n let lastRefillTime = startingRefillTime ?? Date.now();\n\n function refill(now: number) {\n const elapsed = (now - lastRefillTime) / 1_000;\n const newTokens = elapsed * refillRate;\n tokens = Math.min(capacity, tokens + newTokens);\n lastRefillTime = now;\n }\n\n return {\n available() {\n return tokens;\n },\n // Wait for a single token to become available.\n async acquireOne(now?: number) {\n while (true) {\n refill(now ?? Date.now());\n if (tokens > 0) {\n tokens -= 1;\n return;\n }\n\n await new Promise((resolve) => setTimeout(resolve, refillInterval));\n }\n },\n };\n}\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@apibara/evm-rpc",
3
- "version": "2.1.0-beta.50",
3
+ "version": "2.1.0-beta.52",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist",
@@ -32,8 +32,8 @@
32
32
  "vitest": "^1.6.0"
33
33
  },
34
34
  "dependencies": {
35
- "@apibara/protocol": "2.1.0-beta.50",
36
- "@apibara/evm": "2.1.0-beta.49",
35
+ "@apibara/protocol": "2.1.0-beta.52",
36
+ "@apibara/evm": "2.1.0-beta.51",
37
37
  "viem": "^2.40.3"
38
38
  }
39
39
  }
package/src/retry.ts ADDED
@@ -0,0 +1,22 @@
1
+ export async function retry<T>({
2
+ fn,
3
+ maxAttempts = 3,
4
+ delay = 100,
5
+ }: {
6
+ fn: () => Promise<T>;
7
+ maxAttempts?: number;
8
+ delay?: number;
9
+ }): Promise<T> {
10
+ let attempts = 0;
11
+
12
+ while (true) {
13
+ try {
14
+ return await fn();
15
+ } catch (error) {
16
+ attempts++;
17
+ if (attempts >= maxAttempts) throw error;
18
+ console.warn(`RPC error ${error}. Retrying in ${delay}ms`);
19
+ await new Promise((resolve) => setTimeout(resolve, delay));
20
+ }
21
+ }
22
+ }
@@ -22,6 +22,7 @@ import type { Block, Log } from "./block";
22
22
  import { type Filter, validateFilter } from "./filter";
23
23
  import { fetchLogsByBlockHash, fetchLogsForRange } from "./log-fetcher";
24
24
  import { type BlockRangeOracle, createBlockRangeOracle } from "./range-oracle";
25
+ import { retry } from "./retry";
25
26
  import { rpcBlockHeaderToDna } from "./transform";
26
27
 
27
28
  export type RequestParameters = EIP1193Parameters<PublicRpcSchema>;
@@ -271,14 +272,16 @@ export class EvmRpcStream extends RpcStreamConfig<Filter, Block> {
271
272
  toBlock: bigint;
272
273
  filter: Filter;
273
274
  }): Promise<{ logs: Record<number, Log[]>; blockNumbers: bigint[] }> {
274
- // TODO: implement retry
275
275
  try {
276
- return await fetchLogsForRange({
277
- client: this.client,
278
- fromBlock,
279
- toBlock,
280
- filter,
281
- mergeGetLogs: this.options.mergeGetLogsFilter === "always",
276
+ return await retry({
277
+ fn: () =>
278
+ fetchLogsForRange({
279
+ client: this.client,
280
+ fromBlock,
281
+ toBlock,
282
+ filter,
283
+ mergeGetLogs: this.options.mergeGetLogsFilter === "always",
284
+ }),
282
285
  });
283
286
  } catch (error) {
284
287
  this.blockRangeOracle.handleError(error);
@@ -293,14 +296,16 @@ export class EvmRpcStream extends RpcStreamConfig<Filter, Block> {
293
296
  blockHash: Bytes;
294
297
  filter: Filter;
295
298
  }): Promise<{ logs: Log[] }> {
296
- // TODO: implement retry
297
- return await fetchLogsByBlockHash({
298
- client: this.client,
299
- blockHash,
300
- filter,
301
- mergeGetLogs:
302
- this.options.mergeGetLogsFilter === "always" ||
303
- this.options.mergeGetLogsFilter === "accepted",
299
+ return await retry({
300
+ fn: () =>
301
+ fetchLogsByBlockHash({
302
+ client: this.client,
303
+ blockHash,
304
+ filter,
305
+ mergeGetLogs:
306
+ this.options.mergeGetLogsFilter === "always" ||
307
+ this.options.mergeGetLogsFilter === "accepted",
308
+ }),
304
309
  });
305
310
  }
306
311
 
@@ -309,10 +314,12 @@ export class EvmRpcStream extends RpcStreamConfig<Filter, Block> {
309
314
  }: {
310
315
  blockNumber: bigint;
311
316
  }) {
312
- // TODO: implement retry
313
- const block = await this.client.request({
314
- method: "eth_getBlockByNumber",
315
- params: [numberToHex(blockNumber), false],
317
+ const block = await retry({
318
+ fn: () =>
319
+ this.client.request({
320
+ method: "eth_getBlockByNumber",
321
+ params: [numberToHex(blockNumber), false],
322
+ }),
316
323
  });
317
324
 
318
325
  if (block === null) {