@@ -4,13 +4,30 @@ import { getChainId, getPublicClient } from 'wagmi/actions'
44import { zAddress } from '#lib/zod'
55import { getWagmiConfig } from '#wagmi.config'
66
7+ const creationCache = new Map <
8+ string ,
9+ { blockNumber : bigint ; timestamp : bigint }
10+ > ( )
11+
712export const Route = createFileRoute ( '/api/contract/creation/$address' ) ( {
813 server : {
914 handlers : {
1015 GET : async ( { params } : { params : { address : string } } ) => {
1116 try {
1217 const address = zAddress ( ) . parse ( params . address )
1318 Address . assert ( address )
19+ const cacheKey = address . toLowerCase ( )
20+
21+ const cached = creationCache . get ( cacheKey )
22+ if ( cached ) {
23+ return Response . json ( {
24+ creation : {
25+ blockNumber : cached . blockNumber . toString ( ) ,
26+ timestamp : cached . timestamp . toString ( ) ,
27+ } ,
28+ error : null ,
29+ } )
30+ }
1431
1532 const config = getWagmiConfig ( )
1633 const chainId = getChainId ( config )
@@ -32,7 +49,7 @@ export const Route = createFileRoute('/api/contract/creation/$address')({
3249 const creationBlock = await binarySearchCreationBlock (
3350 client ,
3451 address ,
35- 0n ,
52+ 1n ,
3653 latestBlock ,
3754 )
3855
@@ -42,6 +59,11 @@ export const Route = createFileRoute('/api/contract/creation/$address')({
4259
4360 const block = await client . getBlock ( { blockNumber : creationBlock } )
4461
62+ creationCache . set ( cacheKey , {
63+ blockNumber : creationBlock ,
64+ timestamp : block . timestamp ,
65+ } )
66+
4567 return Response . json ( {
4668 creation : {
4769 blockNumber : creationBlock . toString ( ) ,
@@ -63,14 +85,14 @@ export const Route = createFileRoute('/api/contract/creation/$address')({
6385} )
6486
6587async function binarySearchCreationBlock (
66- client : ReturnType < typeof getPublicClient > ,
88+ client : NonNullable < ReturnType < typeof getPublicClient > > ,
6789 address : Address . Address ,
6890 low : bigint ,
6991 high : bigint ,
7092) : Promise < bigint | null > {
71- if ( ! client ) return null
93+ const MAX_BATCH_SIZE = 10
7294
73- while ( low < high ) {
95+ while ( high - low > BigInt ( MAX_BATCH_SIZE ) ) {
7496 const mid = ( low + high ) / 2n
7597
7698 try {
@@ -89,13 +111,29 @@ async function binarySearchCreationBlock(
89111 }
90112 }
91113
92- const finalCode = await client . getCode ( {
93- address,
94- blockNumber : low ,
95- } )
114+ const blocksToCheck = [ ]
115+ for ( let b = low ; b <= high ; b ++ ) {
116+ blocksToCheck . push ( b )
117+ }
118+
119+ const results = await Promise . all (
120+ blocksToCheck . map ( async ( blockNum ) => {
121+ try {
122+ const code = await client . getCode ( {
123+ address,
124+ blockNumber : blockNum ,
125+ } )
126+ return { blockNum, hasCode : Boolean ( code && code !== '0x' ) }
127+ } catch {
128+ return { blockNum, hasCode : false }
129+ }
130+ } ) ,
131+ )
96132
97- if ( finalCode && finalCode !== '0x' ) {
98- return low
133+ for ( const result of results ) {
134+ if ( result . hasCode ) {
135+ return result . blockNum
136+ }
99137 }
100138
101139 return null
0 commit comments