11import { PlainMessage , toPlainMessage } from '@bufbuild/protobuf'
2- import { useQuery } from '@tanstack/react-query'
3- import { AuctionWithStats , ListTopAuctionsRequest } from '@uniswap/client-data-api/dist/data/v1/auction_pb'
2+ import { useQueries , useQuery } from '@tanstack/react-query'
3+ import {
4+ AuctionWithStats ,
5+ GetAuctionRequest ,
6+ ListTopAuctionsRequest ,
7+ } from '@uniswap/client-data-api/dist/data/v1/auction_pb'
48import { DynamicConfigs , useDynamicConfigValue , VerifiedAuctionsConfigKey } from '@universe/gating'
59import { useMemo } from 'react'
610import { useSelector } from 'react-redux'
@@ -69,28 +73,82 @@ export function useTopAuctions(): {
6973
7074 const { data : topAuctions , isLoading, isError } = useQuery ( auctionQueries . listTopAuctions ( { params } ) )
7175
76+ // Parse verified IDs ("chainId_address") and filter by URL chain when present.
77+ // GetAuction is used as a fallback so verified auctions outside the top-N (e.g. not-yet-started
78+ // ones with zero bid volume) still surface in the verified section.
79+ const verifiedAuctionParams = useMemo < { chainId : number ; address : string } [ ] > (
80+ ( ) =>
81+ verifiedAuctionIds
82+ . map ( ( id ) => {
83+ const sepIndex = id . indexOf ( '_' )
84+ if ( sepIndex < 0 ) {
85+ return undefined
86+ }
87+ const parsedChainId = Number ( id . slice ( 0 , sepIndex ) )
88+ const address = id . slice ( sepIndex + 1 )
89+ if ( ! Number . isFinite ( parsedChainId ) || ! address ) {
90+ return undefined
91+ }
92+ return { chainId : parsedChainId , address }
93+ } )
94+ . filter ( ( p ) : p is { chainId : number ; address : string } => p !== undefined )
95+ . filter ( ( p ) => ! chainId || p . chainId === chainId ) ,
96+ [ verifiedAuctionIds , chainId ] ,
97+ )
98+
99+ const topAuctionIdSet = useMemo (
100+ ( ) =>
101+ new Set (
102+ ( topAuctions ?. auctions ?? [ ] ) . map ( ( a ) => a . auction ?. auctionId ) . filter ( ( id ) : id is string => id !== undefined ) ,
103+ ) ,
104+ [ topAuctions ?. auctions ] ,
105+ )
106+
107+ const missingVerifiedParams = useMemo (
108+ ( ) => verifiedAuctionParams . filter ( ( p ) => ! topAuctionIdSet . has ( `${ p . chainId } _${ p . address } ` ) ) ,
109+ [ verifiedAuctionParams , topAuctionIdSet ] ,
110+ )
111+
112+ const missingVerifiedQueries = useQueries ( {
113+ queries : missingVerifiedParams . map ( ( p ) => auctionQueries . getAuction ( { params : new GetAuctionRequest ( p ) } ) ) ,
114+ } )
115+
116+ // Merge ListTopAuctions results with any verified auctions fetched individually via GetAuction.
117+ // The verified-only entries are appended with empty totalBidVolume so they sort to the end via
118+ // auctionCommittedVolumeComparator (USD volume missing/zero).
119+ const mergedAuctions = useMemo < AuctionWithStats [ ] > ( ( ) => {
120+ const base = topAuctions ?. auctions ?? [ ]
121+ const extras : AuctionWithStats [ ] = [ ]
122+ for ( const q of missingVerifiedQueries ) {
123+ const auction = q . data ?. auctions [ 0 ]
124+ if ( auction ) {
125+ extras . push ( new AuctionWithStats ( { auction, totalBidVolume : '' } ) )
126+ }
127+ }
128+ return extras . length > 0 ? [ ...base , ...extras ] : base
129+ } , [ topAuctions ?. auctions , missingVerifiedQueries ] )
130+
131+ const verifiedFallbackLoading = missingVerifiedQueries . some ( ( q ) => q . isLoading )
132+
72133 const currencyIds = useMemo (
73134 ( ) =>
74- ( topAuctions ?. auctions ?? [ ] )
135+ mergedAuctions
75136 . map ( ( auction ) =>
76137 auction . auction ? buildCurrencyId ( auction . auction . chainId , auction . auction . tokenAddress ) : undefined ,
77138 )
78139 . filter ( ( id ) : id is string => id !== undefined ) ,
79- [ topAuctions ?. auctions ] ,
140+ [ mergedAuctions ] ,
80141 )
81142 const currencyInfos = useCurrencyInfos ( currencyIds , {
82- skip : ! topAuctions ?. auctions || topAuctions . auctions . length === 0 ,
143+ skip : mergedAuctions . length === 0 ,
83144 } )
84145
85146 // Extract unique chain IDs from auctions to minimize RPC calls
86147 const auctionChainIds = useMemo ( ( ) => {
87- if ( ! topAuctions ?. auctions ) {
88- return new Set < EVMUniverseChainId > ( )
89- }
90148 return new Set (
91- topAuctions . auctions . map ( ( a ) => a . auction ?. chainId ) . filter ( ( id ) : id is EVMUniverseChainId => id !== undefined ) ,
149+ mergedAuctions . map ( ( a ) => a . auction ?. chainId ) . filter ( ( id ) : id is EVMUniverseChainId => id !== undefined ) ,
92150 )
93- } , [ topAuctions ?. auctions ] )
151+ } , [ mergedAuctions ] )
94152
95153 // Fetch current block numbers and timestamps for chains that have auctions
96154 const blocksByChain = useMultiChainBlockInfo ( auctionChainIds )
@@ -103,11 +161,7 @@ export function useTopAuctions(): {
103161
104162 // Build requests for block timestamps - extract endBlock values from auctions
105163 const blockTimestampRequests = useMemo < BlockTimestampRequest [ ] > ( ( ) => {
106- if ( ! topAuctions ?. auctions ) {
107- return [ ]
108- }
109-
110- return topAuctions . auctions
164+ return mergedAuctions
111165 . map ( ( auctionWithStats ) => {
112166 const auction = auctionWithStats . auction
113167 // Only create request if both chainId and endBlock are valid
@@ -134,18 +188,18 @@ export function useTopAuctions(): {
134188 } )
135189 . flat ( )
136190 . filter ( ( req ) : req is BlockTimestampRequest => req !== null )
137- } , [ topAuctions ?. auctions ] )
191+ } , [ mergedAuctions ] )
138192
139193 const getBlockTimestamp = useGetBlockTimestamps ( blockTimestampRequests , blocksByChain )
140194
141195 const auctionsWithCurrencyInfo = useMemo < EnrichedAuction [ ] > ( ( ) => {
142- if ( ! topAuctions ?. auctions ) {
196+ if ( mergedAuctions . length === 0 ) {
143197 return [ ]
144198 }
145199
146200 const verifiedSet = new Set ( verifiedAuctionIds )
147201
148- return topAuctions . auctions
202+ return mergedAuctions
149203 . map ( ( auction , index ) => {
150204 const coreAuction = auction . auction
151205 const currencyInfo = currencyInfos [ index ]
@@ -193,11 +247,11 @@ export function useTopAuctions(): {
193247 const chainId = auctionWithInfo . auction ?. chainId
194248 return chainId !== undefined && ( isTestnetModeEnabled || ! isTestnetChain ( chainId ) )
195249 } )
196- } , [ topAuctions ?. auctions , verifiedAuctionIds , isTestnetModeEnabled , getBlockTimestamp , currencyInfos , blocksByChain ] )
250+ } , [ mergedAuctions , verifiedAuctionIds , isTestnetModeEnabled , getBlockTimestamp , currencyInfos , blocksByChain ] )
197251
198252 return {
199253 auctions : auctionsWithCurrencyInfo ,
200- isLoading : isLoading || ! areBlocksLoaded ,
254+ isLoading : isLoading || verifiedFallbackLoading || ! areBlocksLoaded ,
201255 isError,
202256 }
203257}
0 commit comments