@@ -16,6 +16,7 @@ import type { NetworkType } from '@fairco.in/rpc-client'
1616/** Inclusive bounds for any list `limit` query parameter. */
1717export const MIN_LIMIT = 1
1818export const MAX_LIMIT = 100
19+ export const MAX_BLOCK_OFFSET = 10_000
1920const DEFAULT_LIMIT = 20
2021
2122const NETWORKS = [ 'mainnet' , 'testnet' ] as const
@@ -69,8 +70,7 @@ export function parseLimit(value: unknown): number {
6970}
7071
7172/**
72- * Coerce the `offset` query parameter into a non-negative integer (no upper
73- * bound — callers may legitimately page far back into the chain). Returns 0
73+ * Coerce the `offset` query parameter into a non-negative integer. Returns 0
7474 * when absent or non-numeric; clamps negatives to 0.
7575 */
7676export function parseOffset ( value : unknown ) : number {
@@ -80,6 +80,15 @@ export function parseOffset(value: unknown): number {
8080 return Math . max ( 0 , result . data )
8181}
8282
83+ /**
84+ * Coerce the public block-list `offset` into a bounded range. Block windows are
85+ * expensive to materialize on cache misses, so keeping this edge-bounded limits
86+ * attacker-controlled recent-block cache keys and RPC walks.
87+ */
88+ export function parseBlockOffset ( value : unknown ) : number {
89+ return Math . min ( MAX_BLOCK_OFFSET , parseOffset ( value ) )
90+ }
91+
8392/** Escape a string for safe interpolation into a MongoDB `$regex` pattern. */
8493export function escapeRegex ( value : string ) : string {
8594 return value . replace ( / [ . * + ? ^ $ { } ( ) | [ \] \\ ] / g, '\\$&' )
0 commit comments