UNPKG

@moonwell-fi/moonwell-sdk

Version:

TypeScript Interface for Moonwell

56 lines 2.2 kB
/** * Safety cap on interpolation iterations. With near-linear `ts(block)` the search * converges in ~3–5 reads; 8 leaves headroom for chains with variable block times * (e.g. Moonbeam) without unbounded RPC fan-out on pathological inputs. */ const MAX_ITERATIONS = 8; /** * Find the block number on a chain whose timestamp is the latest one ≤ the target unix timestamp. * * Uses interpolation search anchored on the latest block and block 1: each iteration * narrows the range by reading one block and projecting the target via the slope of the * remaining range. Converges in ~3–5 RPC calls even on chains with variable block times. * * Assumes block 1 exists on the chain — true for every EVM chain Moonwell supports. * * Returns the latest block if `targetTimestamp` is at or after the head, and block 1 * if it is before block 1's timestamp. On a chain with only block 0, returns block 0. */ export async function getBlockNumberAtTimestamp(publicClient, targetTimestamp) { const latest = await publicClient.getBlock({ blockTag: "latest" }); if (targetTimestamp >= latest.timestamp) return latest.number; if (latest.number === 0n) return latest.number; const first = await publicClient.getBlock({ blockNumber: 1n }); if (targetTimestamp <= first.timestamp) return first.number; let lo = first.number; let loTs = first.timestamp; let hi = latest.number; let hiTs = latest.timestamp; for (let i = 0; i < MAX_ITERATIONS; i += 1) { if (hi - lo <= 1n) break; const tsRange = hiTs - loTs; if (tsRange <= 0n) break; const offset = ((targetTimestamp - loTs) * (hi - lo)) / tsRange; let mid = lo + offset; if (mid <= lo) mid = lo + 1n; if (mid >= hi) mid = hi - 1n; const block = await publicClient.getBlock({ blockNumber: mid }); if (block.timestamp <= targetTimestamp) { lo = mid; loTs = block.timestamp; } else { hi = mid; hiTs = block.timestamp; } } return lo; } //# sourceMappingURL=getBlockNumberAtTimestamp.js.map