11import { NextRequest , NextResponse } from "next/server" ;
2+ import { GAMMA_API_URL } from "@/constants/api" ;
23
3- const GAMMA_API = "https://gamma-api.polymarket.com" ;
4+ const MIN_LIQUIDITY_USD = 1000 ;
5+ const MIN_LIQUIDITY_NON_EVERGREEN_USD = 5000 ;
6+
7+ const EVERGREEN_TAG_IDS = [ 2 , 21 , 120 , 596 , 1401 , 100265 , 100639 ] ;
48
59export async function GET ( request : NextRequest ) {
610 const searchParams = request . nextUrl . searchParams ;
711 const limit = searchParams . get ( "limit" ) || "10" ;
12+ const tagId = searchParams . get ( "tag_id" ) ;
813
914 try {
1015 const fetchLimit = parseInt ( limit ) * 5 ;
1116
12- const response = await fetch (
13- `${ GAMMA_API } /markets?limit=${ fetchLimit } &offset=0&active=true&closed=false&order=volume24hr&ascending=false` ,
14- {
15- headers : { "Content-Type" : "application/json" } ,
16- next : { revalidate : 60 } ,
17- }
18- ) ;
17+ let url = `${ GAMMA_API_URL } /events?closed=false&order=volume24hr&ascending=false&limit=${ fetchLimit } &offset=0` ;
18+
19+ if ( tagId ) {
20+ url += `&tag_id=${ tagId } &related_tags=true` ;
21+ }
22+
23+ const response = await fetch ( url , {
24+ headers : { "Content-Type" : "application/json" } ,
25+ next : { revalidate : 60 } ,
26+ } ) ;
1927
2028 if ( ! response . ok ) {
2129 console . error ( "Gamma API error:" , response . status ) ;
2230 throw new Error ( `Gamma API error: ${ response . status } ` ) ;
2331 }
2432
25- const markets = await response . json ( ) ;
33+ const events = await response . json ( ) ;
2634
27- if ( ! Array . isArray ( markets ) ) {
28- console . error ( "Invalid response structure:" , markets ) ;
35+ if ( ! Array . isArray ( events ) ) {
36+ console . error ( "Invalid response structure:" , events ) ;
2937 return NextResponse . json (
3038 { error : "Invalid API response" } ,
3139 { status : 500 }
3240 ) ;
3341 }
3442
35- const validMarkets = markets . filter ( ( market : any ) => {
36- if ( market . events && market . events . length > 0 ) {
37- const hasEndedEvent = market . events . some (
38- ( event : any ) =>
39- event . ended === true ||
40- event . live === false ||
41- event . finishedTimestamp
42- ) ;
43- if ( hasEndedEvent ) return false ;
43+ const allMarkets : any [ ] = [ ] ;
44+
45+ for ( const event of events ) {
46+ if ( event . ended || event . closed || ! event . active ) continue ;
47+
48+ const markets = event . markets || [ ] ;
49+
50+ for ( const market of markets ) {
51+ allMarkets . push ( {
52+ ...market ,
53+ eventTitle : event . title ,
54+ eventSlug : event . slug ,
55+ eventId : event . id ,
56+ eventIcon : event . image || event . icon ,
57+ negRisk : event . negRisk || false ,
58+ } ) ;
4459 }
60+ }
4561
62+ const validMarkets = allMarkets . filter ( ( market : any ) => {
4663 if ( market . acceptingOrders === false ) return false ;
64+ if ( market . closed === true ) return false ;
4765 if ( ! market . clobTokenIds ) return false ;
66+
4867 if ( market . outcomePrices ) {
4968 try {
5069 const prices = JSON . parse ( market . outcomePrices ) ;
@@ -53,41 +72,34 @@ export async function GET(request: NextRequest) {
5372 return priceNum >= 0.05 && priceNum <= 0.95 ;
5473 } ) ;
5574 if ( ! hasTradeablePrice ) return false ;
56- } catch ( e ) {
75+ } catch {
5776 return false ;
5877 }
5978 }
6079
61- const evergreenTags = [
62- "crypto" ,
63- "politics" ,
64- "sports" ,
65- "technology" ,
66- "business" ,
67- "entertainment" ,
68- "science" ,
69- "ai" ,
70- "pop-culture" ,
71- ] ;
72-
73- const marketTags =
74- market . tags ?. map ( ( t : any ) => t . slug . toLowerCase ( ) ) || [ ] ;
75- const hasEvergreenTag = evergreenTags . some ( ( tag ) =>
76- marketTags . includes ( tag )
80+ const marketTagIds =
81+ market . tags ?. map ( ( t : any ) => parseInt ( t . id ) ) || [ ] ;
82+ const hasEvergreenTag = EVERGREEN_TAG_IDS . some ( ( id ) =>
83+ marketTagIds . includes ( id )
7784 ) ;
7885
7986 const liquidity = parseFloat ( market . liquidity || "0" ) ;
80- if ( ! hasEvergreenTag && liquidity < 5000 ) return false ;
81- if ( liquidity < 1000 ) return false ;
87+
88+ if ( ! hasEvergreenTag && liquidity < MIN_LIQUIDITY_NON_EVERGREEN_USD ) {
89+ return false ;
90+ }
91+ if ( liquidity < MIN_LIQUIDITY_USD ) return false ;
8292
8393 return true ;
8494 } ) ;
8595
8696 const sortedMarkets = validMarkets . sort ( ( a : any , b : any ) => {
8797 const aScore =
88- parseFloat ( a . liquidity || "0" ) + parseFloat ( a . volume || "0" ) ;
98+ parseFloat ( a . liquidity || "0" ) +
99+ parseFloat ( a . volume24hr || a . volume || "0" ) ;
89100 const bScore =
90- parseFloat ( b . liquidity || "0" ) + parseFloat ( b . volume || "0" ) ;
101+ parseFloat ( b . liquidity || "0" ) +
102+ parseFloat ( b . volume24hr || b . volume || "0" ) ;
91103 return bScore - aScore ;
92104 } ) ;
93105
0 commit comments