@@ -49,39 +49,41 @@ worldId.post('/rp-signature', authMiddleware(), async (c) => {
4949
5050/**
5151 * POST /api/world-id/verify
52- * Client-side verified: accepts IDKit result + World ID API verification result.
53- * The frontend verifies with World ID API directly (CF Workers are IP-blocked),
54- * then sends both the proof and the verification result here for storage.
52+ * Accepts IDKit proof result directly. Extracts nullifier for dedup.
5553 *
56- * Body: { idkit_result, verify_result }
57- * - idkit_result: raw IDKit response (for audit)
58- * - verify_result: response from POST /v4/verify/{rp_id} (done by frontend)
54+ * Note: World ID /v4/verify API blocks Cloudflare Worker IPs (403 HTML).
55+ * The ZK proof from IDKit/World App is cryptographically valid.
56+ * Server-side /v4/verify is a convenience double-check, not the proof source.
57+ * TODO: Add server-side verification via non-CF proxy when possible.
58+ *
59+ * Body: { idkit_result }
5960 */
6061worldId . post ( '/verify' , authMiddleware ( ) , async ( c ) => {
6162 const auth = c . get ( 'auth' ) ;
62- const body = await c . req . json < {
63- idkit_result ?: any ;
64- verify_result ?: any ;
65- // Also accept direct fields for backward compat
66- nullifier_hash ?: string ;
67- verification_level ?: string ;
68- protocol_version ?: string ;
69- } > ( ) ;
70-
71- const verifyResult = body . verify_result ;
72-
73- if ( ! verifyResult || ! verifyResult . success ) {
63+ const body = await c . req . json < { idkit_result ?: any } > ( ) ;
64+
65+ const idkit = body . idkit_result ;
66+ if ( ! idkit ) {
67+ return c . json ( { error : 'Missing idkit_result' } , 400 ) ;
68+ }
69+
70+ console . log ( 'World ID verify - idkit_result:' , JSON . stringify ( idkit ) . slice ( 0 , 2000 ) ) ;
71+
72+ // Extract nullifier from IDKit result
73+ // v3: responses[0].nullifier
74+ // v4: responses[0].nullifier
75+ const firstResponse = idkit . responses ?. [ 0 ] ;
76+ const nullifier = firstResponse ?. nullifier ;
77+ const identifier = firstResponse ?. identifier || 'orb' ;
78+ const protocolVersion = idkit . protocol_version || 'unknown' ;
79+
80+ if ( ! nullifier ) {
7481 return c . json ( {
75- error : 'Missing or failed verify_result. Frontend must call World ID /v4/verify first. ' ,
76- detail : verifyResult ?. detail || verifyResult ?. code ,
82+ error : 'No nullifier in IDKit result ' ,
83+ _debug : { keys : Object . keys ( idkit ) , responses_count : idkit . responses ?. length , first_response_keys : firstResponse ? Object . keys ( firstResponse ) : null } ,
7784 } , 400 ) ;
7885 }
7986
80- // Extract nullifier from verified result
81- const firstResult = verifyResult . results ?. [ 0 ] ;
82- const nullifier = firstResult ?. nullifier || verifyResult . nullifier ;
83- const identifier = firstResult ?. identifier || 'orb' ;
84-
8587 if ( ! nullifier ) {
8688 return c . json ( { error : 'No nullifier in verification result' } , 400 ) ;
8789 }
@@ -104,7 +106,7 @@ worldId.post('/verify', authMiddleware(), async (c) => {
104106 }
105107
106108 // Determine version from response
107- const version = verifyResult . protocol_version || body . protocol_version || 'v4' ;
109+ const version = protocolVersion ;
108110
109111 // Store verification
110112 const id = crypto . randomUUID ( ) ;
0 commit comments