1- import { NextApiRequest , NextApiResponse } from 'next' ;
2- import { config } from '../../../lib/config' ;
3- import prisma from '../../../lib/prisma' ;
4- import { validateTraits } from '../../../lib/trait-validator' ;
5-
6- export default async function handler ( req : NextApiRequest , res : NextApiResponse ) {
7- if ( req . method !== 'POST' ) {
8- return res . status ( 405 ) . json ( { error : 'Method not allowed' } ) ;
1+ import { NextApiRequest , NextApiResponse } from "next" ;
2+ import { config } from "../../../lib/config" ;
3+ import prisma from "../../../lib/prisma" ;
4+ import { validateTraits } from "../../../lib/trait-validator" ;
5+
6+ export default async function handler (
7+ req : NextApiRequest ,
8+ res : NextApiResponse
9+ ) {
10+ if ( req . method !== "POST" ) {
11+ return res . status ( 405 ) . json ( { error : "Method not allowed" } ) ;
912 }
1013
1114 try {
@@ -14,34 +17,33 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
1417 // Validate required parameters
1518 if ( ! signature || ! message ) {
1619 return res . status ( 400 ) . json ( {
17- error : ' Missing required parameters: signature and message'
20+ error : " Missing required parameters: signature and message" ,
1821 } ) ;
1922 }
2023
2124 // Define expected trait requirements for Coinbase verification
2225 // This MUST match what the frontend generates
2326 const expectedTraits = {
24- 'coinbase_one_active' : 'true' ,
25- 'country' : 'in:US,CA,MX'
27+ coinbase_one_active : "true" ,
2628 } ;
2729
2830 // Validate that the message contains the expected trait requirements
29- const validation = validateTraits ( message , ' coinbase' , expectedTraits ) ;
30-
31+ const validation = validateTraits ( message , " coinbase" , expectedTraits ) ;
32+
3133 if ( ! validation . valid ) {
32- console . error ( ' Trait validation failed:' , validation . error ) ;
33- console . error ( ' Expected traits:' , validation . expectedTraits ) ;
34- console . error ( ' Found traits:' , validation . foundTraits ) ;
35-
34+ console . error ( " Trait validation failed:" , validation . error ) ;
35+ console . error ( " Expected traits:" , validation . expectedTraits ) ;
36+ console . error ( " Found traits:" , validation . foundTraits ) ;
37+
3638 return res . status ( 400 ) . json ( {
37- error : ' Invalid trait requirements in message' ,
38- details : validation . error
39+ error : " Invalid trait requirements in message" ,
40+ details : validation . error ,
3941 } ) ;
4042 }
4143
4244 const requestBody : any = {
4345 signature,
44- message
46+ message,
4547 } ;
4648
4749 if ( code && codeVerifier ) {
@@ -50,39 +52,44 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
5052 }
5153
5254 // Call the base-verify-api to verify the signature
53- const uri = `${ config . baseVerifyApiUrl } /base_verify_token`
55+ const uri = `${ config . baseVerifyApiUrl } /base_verify_token` ;
5456 const verifyResponse = await fetch ( uri , {
55- method : ' POST' ,
57+ method : " POST" ,
5658 headers : {
57- ' Content-Type' : ' application/json' ,
58- ' Authorization' : `Bearer ${ config . baseVerifySecretKey } `
59+ " Content-Type" : " application/json" ,
60+ Authorization : `Bearer ${ config . baseVerifySecretKey } ` ,
5961 } ,
60- body : JSON . stringify ( requestBody )
62+ body : JSON . stringify ( requestBody ) ,
6163 } ) ;
6264
6365 const responseBody = await verifyResponse . clone ( ) . text ( ) ;
64- console . log ( ' Request URI:' , uri ) ;
65- console . log ( ' Base verify API response body:' , responseBody ) ;
66+ console . log ( " Request URI:" , uri ) ;
67+ console . log ( " Base verify API response body:" , responseBody ) ;
6668
6769 if ( ! verifyResponse . ok ) {
68- console . error ( 'Base verify API error:' , verifyResponse . status , verifyResponse . statusText ) ;
70+ console . error (
71+ "Base verify API error:" ,
72+ verifyResponse . status ,
73+ verifyResponse . statusText
74+ ) ;
6975
7076 // Handle specific case where Coinbase account verification traits are not satisfied
7177 if ( verifyResponse . status === 400 ) {
7278 try {
7379 const errorData = JSON . parse ( responseBody ) ;
74- if ( errorData . message === ' verification_traits_not_satisfied' ) {
80+ if ( errorData . message === " verification_traits_not_satisfied" ) {
7581 return res . status ( 412 ) . json ( {
76- error : 'Coinbase account does not satisfy verification requirements.'
82+ error :
83+ "Coinbase account does not satisfy verification requirements." ,
7784 } ) ;
7885 }
7986 } catch ( parseError ) {
80- console . error ( ' Error parsing response body:' , parseError ) ;
87+ console . error ( " Error parsing response body:" , parseError ) ;
8188 }
8289 }
8390
8491 return res . status ( verifyResponse . status ) . json ( {
85- error : ' Failed to verify signature with base-verify-api'
92+ error : " Failed to verify signature with base-verify-api" ,
8693 } ) ;
8794 }
8895
@@ -91,82 +98,85 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
9198
9299 // Extract the base verify token from response (support a few possible shapes)
93100 const baseVerifyToken : string | undefined =
94- verificationData ?. token ||
95- verificationData ?. data ?. token ;
101+ verificationData ?. token || verificationData ?. data ?. token ;
96102
97- if ( ! baseVerifyToken || typeof baseVerifyToken !== ' string' ) {
103+ if ( ! baseVerifyToken || typeof baseVerifyToken !== " string" ) {
98104 return res . status ( 500 ) . json ( {
99- error : ' Verification token missing from Base Verify response'
105+ error : " Verification token missing from Base Verify response" ,
100106 } ) ;
101107 }
102108
103109 // Store the verification data in the database
104110 try {
105111 // Extract user data from verification response
106112 const addressMatch = message . match ( / 0 x [ a - f A - F 0 - 9 ] { 40 } / ) ;
107- const walletAddress = addressMatch ? addressMatch [ 0 ] : '' ;
113+ const walletAddress = addressMatch ? addressMatch [ 0 ] : "" ;
108114
109- console . log ( ' Extracted wallet address:' , walletAddress ) ;
115+ console . log ( " Extracted wallet address:" , walletAddress ) ;
110116
111117 if ( ! walletAddress ) {
112- console . error ( 'Failed to extract wallet address from message:' , message ) ;
118+ console . error (
119+ "Failed to extract wallet address from message:" ,
120+ message
121+ ) ;
113122 return res . status ( 400 ) . json ( {
114- error : ' Could not extract wallet address from message'
123+ error : " Could not extract wallet address from message" ,
115124 } ) ;
116125 }
117126
118- console . log ( ' Attempting to store user in database:' , walletAddress ) ;
127+ console . log ( " Attempting to store user in database:" , walletAddress ) ;
119128
120129 // Enforce uniqueness of the base verify token before writing
121130 const existingByToken = await prisma . coinbaseVerifiedUser . findUnique ( {
122- where : { baseVerifyToken }
131+ where : { baseVerifyToken } ,
123132 } ) ;
124133 if ( existingByToken ) {
125134 return res . status ( 409 ) . json ( {
126- error : ' This verification token has already been used.'
135+ error : " This verification token has already been used." ,
127136 } ) ;
128137 }
129138
130139 const result = await prisma . coinbaseVerifiedUser . upsert ( {
131140 where : { address : walletAddress } ,
132141 update : {
133142 updatedAt : new Date ( ) ,
134- baseVerifyToken
143+ baseVerifyToken,
135144 } ,
136145 create : {
137146 address : walletAddress ,
138147 updatedAt : new Date ( ) ,
139- baseVerifyToken
140- }
148+ baseVerifyToken,
149+ } ,
141150 } ) ;
142151
143- console . log ( 'Database operation successful:' , result ) ;
144-
152+ console . log ( "Database operation successful:" , result ) ;
145153 } catch ( dbError ) {
146- console . error ( ' Error storing verification in database:' , dbError ) ;
147- console . error ( ' Database error details:' , {
154+ console . error ( " Error storing verification in database:" , dbError ) ;
155+ console . error ( " Database error details:" , {
148156 message : ( dbError as Error ) . message ,
149- stack : ( dbError as Error ) . stack
157+ stack : ( dbError as Error ) . stack ,
150158 } ) ;
151159
152160 // Fail the request if database storage fails - this is important for verification integrity
153161 return res . status ( 500 ) . json ( {
154- error : 'Failed to store verification in database' ,
155- details : process . env . NODE_ENV === 'development' ? ( dbError as Error ) . message : undefined
162+ error : "Failed to store verification in database" ,
163+ details :
164+ process . env . NODE_ENV === "development"
165+ ? ( dbError as Error ) . message
166+ : undefined ,
156167 } ) ;
157168 }
158169
159170 // Return 200 OK with the verification data
160171 return res . status ( 200 ) . json ( {
161172 success : true ,
162173 verification : verificationData ,
163- message : ' Airdrop claimed successfully'
174+ message : " Airdrop claimed successfully" ,
164175 } ) ;
165-
166176 } catch ( error ) {
167- console . error ( ' Error in verify-token route:' , error ) ;
177+ console . error ( " Error in verify-token route:" , error ) ;
168178 return res . status ( 500 ) . json ( {
169- error : ' Internal server error'
179+ error : " Internal server error" ,
170180 } ) ;
171181 }
172182}
0 commit comments