@@ -4,86 +4,83 @@ const GRAPHQL_ENDPOINT = 'https://tokenlogic-data.ddn.hasura.app/graphql';
44const API_KEY = process . env . TOKENLOGIC_API_KEY ;
55
66type SGhoRatesData = {
7- blockHour : string ;
8- apr : number ;
7+ blockHour : string ;
8+ apr : number ;
99} ;
1010
1111type GraphQLResponse = {
12- data ?: {
13- aaveV3RatesSgho : SGhoRatesData [ ] ;
14- } ;
15- errors ?: Array < {
16- message : string ;
17- locations ?: Array < { line : number ; column : number } > ;
18- path ?: string [ ] ;
19- } > ;
12+ data ?: {
13+ aaveV3RatesSgho : SGhoRatesData [ ] ;
14+ } ;
15+ errors ?: Array < {
16+ message : string ;
17+ locations ?: Array < { line : number ; column : number } > ;
18+ path ?: string [ ] ;
19+ } > ;
2020} ;
2121
2222type ApiResponse = {
23- data ?: Array < {
24- day : { value : string } ;
25- merit_apy : number ;
26- } > ;
27- error ?: string ;
23+ data ?: Array < {
24+ day : { value : string } ;
25+ merit_apy : number ;
26+ } > ;
27+ error ?: string ;
2828} ;
2929
3030/**
3131 * Transform GraphQL data to the format expected by the frontend
3232 */
3333const transformGraphQLData = ( graphqlData : SGhoRatesData [ ] ) => {
34- return graphqlData . map ( ( item ) => {
35- // Convert blockHour (ISO datetime) to date string (YYYY-MM-DD)
36- const date = new Date ( item . blockHour ) ;
37- const dateString = date . toISOString ( ) . split ( 'T' ) [ 0 ] ;
38-
39- return {
40- day : {
41- value : dateString ,
42- } ,
43- merit_apy : item . apr ,
44- } ;
45- } ) ;
34+ return graphqlData . map ( ( item ) => {
35+ // Convert blockHour (ISO datetime) to date string (YYYY-MM-DD)
36+ const date = new Date ( item . blockHour ) ;
37+ const dateString = date . toISOString ( ) . split ( 'T' ) [ 0 ] ;
38+
39+ return {
40+ day : {
41+ value : dateString ,
42+ } ,
43+ merit_apy : item . apr ,
44+ } ;
45+ } ) ;
4646} ;
4747
4848/**
4949 * Next.js API route to fetch sGHO APY data from TokenLogic GraphQL API
50- *
50+ *
5151 * GET /api/sgho-apy
5252 * Query parameters:
5353 * - limit: number (optional, default: 100) - Number of records to fetch
5454 * - startDate: string (optional) - Start date for filtering (ISO format)
5555 * - endDate: string (optional) - End date for filtering (ISO format)
5656 */
57- export default async function handler (
58- req : NextApiRequest ,
59- res : NextApiResponse < ApiResponse >
60- ) {
61- // Only allow GET requests
62- if ( req . method !== 'GET' ) {
63- return res . status ( 405 ) . json ( { error : 'Method not allowed' } ) ;
57+ export default async function handler ( req : NextApiRequest , res : NextApiResponse < ApiResponse > ) {
58+ // Only allow GET requests
59+ if ( req . method !== 'GET' ) {
60+ return res . status ( 405 ) . json ( { error : 'Method not allowed' } ) ;
61+ }
62+
63+ try {
64+ // Check if API key is configured
65+ if ( ! API_KEY ) {
66+ console . error ( 'TOKENLOGIC_API_KEY environment variable not set' ) ;
67+ return res . status ( 500 ) . json ( {
68+ error : 'Server configuration error' ,
69+ } ) ;
6470 }
6571
66- try {
67- // Check if API key is configured
68- if ( ! API_KEY ) {
69- console . error ( 'TOKENLOGIC_API_KEY environment variable not set' ) ;
70- return res . status ( 500 ) . json ( {
71- error : 'Server configuration error'
72- } ) ;
73- }
74-
75- // Parse query parameters
76- const limit = parseInt ( req . query . limit as string ) || 100 ;
77- const startDate = req . query . startDate as string ;
78- const endDate = req . query . endDate as string ;
72+ // Parse query parameters
73+ const limit = parseInt ( req . query . limit as string ) || 100 ;
74+ const startDate = req . query . startDate as string ;
75+ const endDate = req . query . endDate as string ;
7976
80- // Build GraphQL query based on parameters
81- let graphqlQuery : string ;
82- let variables : Record < string , any > ;
77+ // Build GraphQL query based on parameters
78+ let graphqlQuery : string ;
79+ let variables : Record < string , string > ;
8380
84- if ( startDate && endDate ) {
85- // Query with date range
86- graphqlQuery = `
81+ if ( startDate && endDate ) {
82+ // Query with date range
83+ graphqlQuery = `
8784 query GetSGhoApyHistoryDateRange($startDate: timestamptz!, $endDate: timestamptz!, $limit: Int!) {
8885 aaveV3RatesSgho(
8986 limit: $limit,
@@ -99,75 +96,74 @@ export default async function handler(
9996 }
10097 }
10198 ` ;
102- variables = { startDate, endDate, limit } ;
103- } else {
104- // Query for recent data
105- graphqlQuery = `
99+ variables = { startDate, endDate, limit } ;
100+ } else {
101+ // Query for recent data
102+ graphqlQuery = `
106103 query GetSGhoApyHistory($limit: Int!) {
107104 aaveV3RatesSgho(limit: $limit) {
108105 blockHour
109106 apr
110107 }
111108 }
112109 ` ;
113- variables = { limit } ;
114- }
110+ variables = { limit } ;
111+ }
115112
116- // Make GraphQL request
117- const response = await fetch ( GRAPHQL_ENDPOINT , {
118- method : 'POST' ,
119- headers : {
120- 'Content-Type' : 'application/json' ,
121- 'x-api-key' : API_KEY ,
122- } ,
123- body : JSON . stringify ( {
124- query : graphqlQuery ,
125- variables,
126- } ) ,
127- } ) ;
128-
129- if ( ! response . ok ) {
130- console . error ( `GraphQL HTTP error: ${ response . status } ` ) ;
131- return res . status ( response . status ) . json ( {
132- error : `Failed to fetch data: ${ response . statusText } `
133- } ) ;
134- }
113+ // Make GraphQL request
114+ const response = await fetch ( GRAPHQL_ENDPOINT , {
115+ method : 'POST' ,
116+ headers : {
117+ 'Content-Type' : 'application/json' ,
118+ 'x-api-key' : API_KEY ,
119+ } ,
120+ body : JSON . stringify ( {
121+ query : graphqlQuery ,
122+ variables,
123+ } ) ,
124+ } ) ;
135125
136- const result : GraphQLResponse = await response . json ( ) ;
126+ if ( ! response . ok ) {
127+ console . error ( `GraphQL HTTP error: ${ response . status } ` ) ;
128+ return res . status ( response . status ) . json ( {
129+ error : `Failed to fetch data: ${ response . statusText } ` ,
130+ } ) ;
131+ }
137132
138- // Check for GraphQL errors
139- if ( result . errors && result . errors . length > 0 ) {
140- console . error ( 'GraphQL errors:' , result . errors ) ;
141- return res . status ( 400 ) . json ( {
142- error : `GraphQL error: ${ result . errors . map ( e => e . message ) . join ( ', ' ) } `
143- } ) ;
144- }
133+ const result : GraphQLResponse = await response . json ( ) ;
145134
146- // Validate response structure
147- if ( ! result . data ?. aaveV3RatesSgho || ! Array . isArray ( result . data . aaveV3RatesSgho ) ) {
148- console . error ( 'Invalid GraphQL response format :' , result ) ;
149- return res . status ( 500 ) . json ( {
150- error : 'Invalid response format from data source'
151- } ) ;
152- }
135+ // Check for GraphQL errors
136+ if ( result . errors && result . errors . length > 0 ) {
137+ console . error ( 'GraphQL errors :' , result . errors ) ;
138+ return res . status ( 400 ) . json ( {
139+ error : `GraphQL error: ${ result . errors . map ( ( e ) => e . message ) . join ( ', ' ) } ` ,
140+ } ) ;
141+ }
153142
154- // Transform and sort data
155- const transformedData = transformGraphQLData ( result . data . aaveV3RatesSgho ) ;
143+ // Validate response structure
144+ if ( ! result . data ?. aaveV3RatesSgho || ! Array . isArray ( result . data . aaveV3RatesSgho ) ) {
145+ console . error ( 'Invalid GraphQL response format:' , result ) ;
146+ return res . status ( 500 ) . json ( {
147+ error : 'Invalid response format from data source' ,
148+ } ) ;
149+ }
156150
157- // Sort by date (oldest first) since we removed ordering from GraphQL query
158- const sortedData = transformedData . sort ( ( a , b ) => {
159- const dateA = new Date ( a . day . value ) ;
160- const dateB = new Date ( b . day . value ) ;
161- return dateA . getTime ( ) - dateB . getTime ( ) ;
162- } ) ;
151+ // Transform and sort data
152+ const transformedData = transformGraphQLData ( result . data . aaveV3RatesSgho ) ;
163153
164- // Return successful response
165- res . status ( 200 ) . json ( { data : sortedData } ) ;
154+ // Sort by date (oldest first) since we removed ordering from GraphQL query
155+ const sortedData = transformedData . sort ( ( a , b ) => {
156+ const dateA = new Date ( a . day . value ) ;
157+ const dateB = new Date ( b . day . value ) ;
158+ return dateA . getTime ( ) - dateB . getTime ( ) ;
159+ } ) ;
166160
167- } catch ( error ) {
168- console . error ( 'API route error:' , error ) ;
169- res . status ( 500 ) . json ( {
170- error : 'Internal server error'
171- } ) ;
172- }
173- }
161+ // Return successful response
162+ res . status ( 200 ) . json ( { data : sortedData } ) ;
163+ } catch ( error ) {
164+ console . error ( 'API route error:' , error ) ;
165+ res . status ( 500 ) . json ( {
166+ error : 'Internal server error' ,
167+ } ) ;
168+ }
169+ }
0 commit comments