From d1112c486e9a73ffbe0c3c11395ce63bb8edd000 Mon Sep 17 00:00:00 2001 From: sajjad21990 Date: Fri, 31 Oct 2025 18:38:21 +0530 Subject: [PATCH 1/3] JS docs update --- content/docs/js-sdk/api-reference.mdx | 472 ++++++++++++ content/docs/js-sdk/backend-verification.mdx | 356 +++++++++ content/docs/js-sdk/client-integration.mdx | 136 ++++ content/docs/js-sdk/index.mdx | 255 +++++++ content/docs/js-sdk/installation.mdx | 188 +++++ content/docs/js-sdk/meta.json | 12 + content/docs/js-sdk/quickstart.mdx | 654 ++++++++++++++++ .../docs/js-sdk/recommended-setup/index.mdx | 360 +++++++++ .../docs/js-sdk/recommended-setup/meta.json | 8 + .../docs/js-sdk/recommended-setup/nextjs.mdx | 603 +++++++++++++++ .../docs/js-sdk/recommended-setup/nodejs.mdx | 617 +++++++++++++++ .../docs/js-sdk/recommended-setup/python.mdx | 705 ++++++++++++++++++ content/docs/js-sdk/troubleshooting.mdx | 627 ++++++++++++++++ content/docs/meta.json | 1 + content/docs/web/index.mdx | 18 + 15 files changed, 5012 insertions(+) create mode 100644 content/docs/js-sdk/api-reference.mdx create mode 100644 content/docs/js-sdk/backend-verification.mdx create mode 100644 content/docs/js-sdk/client-integration.mdx create mode 100644 content/docs/js-sdk/index.mdx create mode 100644 content/docs/js-sdk/installation.mdx create mode 100644 content/docs/js-sdk/meta.json create mode 100644 content/docs/js-sdk/quickstart.mdx create mode 100644 content/docs/js-sdk/recommended-setup/index.mdx create mode 100644 content/docs/js-sdk/recommended-setup/meta.json create mode 100644 content/docs/js-sdk/recommended-setup/nextjs.mdx create mode 100644 content/docs/js-sdk/recommended-setup/nodejs.mdx create mode 100644 content/docs/js-sdk/recommended-setup/python.mdx create mode 100644 content/docs/js-sdk/troubleshooting.mdx diff --git a/content/docs/js-sdk/api-reference.mdx b/content/docs/js-sdk/api-reference.mdx new file mode 100644 index 0000000..5a9347e --- /dev/null +++ b/content/docs/js-sdk/api-reference.mdx @@ -0,0 +1,472 @@ +--- +title: API Reference +description: Complete API documentation for the Reclaim JavaScript SDK +--- + +## Overview + +This page documents all classes, methods, and types available in the Reclaim JavaScript SDK. + +## Installation + +```bash +npm install @reclaimprotocol/js-sdk +``` + +## Import + +```javascript +import { ReclaimProofRequest, verifyProof } from '@reclaimprotocol/js-sdk'; +``` + +--- + +## ReclaimProofRequest Class + +The main class for creating and managing proof requests. + +### Static Methods + +#### `ReclaimProofRequest.init(appId, appSecret, providerId)` + +Initialize a new proof request with your API credentials. + +**Parameters:** +- `appId` (string, required): Your application ID from the Reclaim Developer Portal +- `appSecret` (string, required): Your application secret +- `providerId` (string, required): The provider ID to verify against + +**Returns:** `Promise` + +**Example:** +```javascript +const reclaimProofRequest = await ReclaimProofRequest.init( + 'your-app-id', + 'your-app-secret', + 'your-provider-id' +); +``` + + +**Security**: Initialize from backend only in production. Never expose `appSecret` in client-side code. + + +#### `ReclaimProofRequest.fromJsonString(configString)` + +Reconstruct a proof request from a JSON configuration string (typically generated on the backend). + +**Parameters:** +- `configString` (string, required): JSON string from `toJsonString()` + +**Returns:** `Promise` + +**Example:** +```javascript +// Backend generates config +const config = reclaimProofRequest.toJsonString(); + +// Frontend reconstructs from config +const reconstructed = await ReclaimProofRequest.fromJsonString(config); +``` + +--- + +### Instance Methods + +#### `getRequestUrl()` + +Generate a verification request URL for manual display (QR codes, links, etc.). + +**Returns:** `Promise` - The verification request URL + +**Example:** +```javascript +const requestUrl = await reclaimProofRequest.getRequestUrl(); +console.log('Verification URL:', requestUrl); +// Display as QR code or clickable link +``` + +#### `getStatusUrl()` + +Get the status polling URL for checking verification progress. + +**Returns:** `string` - The status URL + +**Example:** +```javascript +const statusUrl = reclaimProofRequest.getStatusUrl(); +console.log('Status URL:', statusUrl); +``` + +#### `triggerReclaimFlow(options?)` + +Automatically trigger the optimal verification flow based on user's platform. Shows QR code modal on desktop, redirects to App Clip/Instant App on mobile, or uses browser extension if available. + +**Parameters:** +- `options` (object, optional): Configuration options for the flow + +**Options Object:** +- `theme` (string): `'light'` or `'dark'` - Modal theme (default: `'light'`) +- `modalTitle` (string): Custom title for the QR modal +- `modalSubtitle` (string): Custom subtitle for the QR modal +- `autoCloseModal` (boolean): Auto-close modal after successful verification (default: `false`) +- `autoCloseDelay` (number): Delay in ms before auto-closing (default: `3000`) +- `showExtensionPrompt` (boolean): Show browser extension install prompt if not installed (default: `true`) +- `onModalOpen` (function): Callback when modal opens +- `onModalClose` (function): Callback when modal closes + +**Returns:** `Promise` + +**Example:** +```javascript +await reclaimProofRequest.triggerReclaimFlow({ + theme: 'dark', + modalTitle: 'Verify Your Account', + autoCloseModal: true, + autoCloseDelay: 2000, + onModalOpen: () => console.log('Modal opened'), + onModalClose: () => console.log('Modal closed') +}); +``` + +#### `startSession(callbacks)` + +Start listening for proof submissions. Must be called after generating request URL or triggering flow. + +**Parameters:** +- `callbacks` (object, required): Callback functions + +**Callbacks Object:** +- `onSuccess` (function, required): Called when proof is successfully generated + - Receives: `(proofs: Proof) => void` +- `onError` (function, required): Called when verification fails + - Receives: `(error: Error) => void` + +**Returns:** `Promise` + +**Example:** +```javascript +await reclaimProofRequest.startSession({ + onSuccess: (proofs) => { + console.log('Verification successful!', proofs); + // Process the proofs + }, + onError: (error) => { + console.error('Verification failed:', error); + // Handle error + } +}); +``` + +#### `setAppCallbackUrl(url)` + +Set a callback URL where Reclaim will send proofs after verification (for backend processing). + +**Parameters:** +- `url` (string, required): Your backend callback URL (must be publicly accessible) + +**Returns:** `void` + +**Example:** +```javascript +reclaimProofRequest.setAppCallbackUrl('https://yourapp.com/api/reclaim/callback'); +``` + +#### `toJsonString()` + +Serialize the proof request to a JSON string (safe to send to frontend, excludes secrets). + +**Returns:** `string` - JSON configuration string + +**Example:** +```javascript +// Backend +const config = reclaimProofRequest.toJsonString(); +res.json({ reclaimProofRequestConfig: config }); + +// Frontend receives and reconstructs +const reconstructed = await ReclaimProofRequest.fromJsonString(config); +``` + +#### `isBrowserExtensionAvailable()` + +Check if the Reclaim browser extension is installed and available. + +**Returns:** `Promise` + +**Example:** +```javascript +const hasExtension = await reclaimProofRequest.isBrowserExtensionAvailable(); + +if (hasExtension) { + console.log('Extension available - will use in-browser verification'); +} else { + console.log('No extension - will show QR code'); +} +``` + +--- + +## Standalone Functions + +### `verifyProof(proof)` + +Cryptographically verify a proof received from Reclaim Protocol. + +**Parameters:** +- `proof` (Proof object, required): The proof to verify + +**Returns:** `Promise` - `true` if proof is valid, `false` otherwise + +**Example:** +```javascript +import { verifyProof } from '@reclaimprotocol/js-sdk'; + +app.post('/api/reclaim/callback', async (req, res) => { + const proof = parseProof(req.body); + + const isValid = await verifyProof(proof); + + if (isValid) { + console.log('✅ Proof is valid'); + // Process verified data + } else { + console.log('❌ Proof verification failed'); + } + + res.sendStatus(200); +}); +``` + + +**Best Practice**: Always verify proofs on your backend before trusting the data. Never rely solely on client-side verification. + + +--- + +## Type Definitions + +### Proof Object + +The proof object received after successful verification: + +```typescript +interface Proof { + identifier: string; // Unique proof identifier + claimData: ClaimData; // Claim details + signatures: string[]; // Cryptographic signatures + witnesses: Witness[]; // Witness attestations + timestampS: number; // Unix timestamp in seconds +} + +interface ClaimData { + provider: string; // Provider name (e.g., "google") + parameters: string; // JSON string of provider parameters + context: string; // JSON string of context data +} + +interface Witness { + address: string; // Witness address + signature: string; // Witness signature +} +``` + +**Example Proof:** +```json +{ + "identifier": "0x1234567890abcdef...", + "claimData": { + "provider": "google", + "parameters": "{\"email\":\"user@example.com\"}", + "context": "{\"extractedParameters\":{\"providerName\":\"google\"}}" + }, + "signatures": ["0xabcdef..."], + "witnesses": [ + { + "address": "0x789...", + "signature": "0xdef..." + } + ], + "timestampS": 1234567890 +} +``` + +### Accessing Proof Data + +```javascript +// Extract provider name +const context = JSON.parse(proof.claimData.context); +const providerName = context.extractedParameters.providerName; + +// Extract parameters (varies by provider) +const parameters = JSON.parse(proof.claimData.parameters); + +// Get verification timestamp +const verifiedAt = new Date(proof.timestampS * 1000); +``` + +--- + +## Error Handling + +### Common Errors + +#### Invalid Credentials Error + +```javascript +try { + await ReclaimProofRequest.init(appId, appSecret, providerId); +} catch (error) { + if (error.message.includes('Invalid credentials')) { + console.error('Check your APP_ID and APP_SECRET'); + } +} +``` + +#### Provider Not Found Error + +```javascript +try { + await ReclaimProofRequest.init(appId, appSecret, providerId); +} catch (error) { + if (error.message.includes('Provider')) { + console.error('Verify your PROVIDER_ID is correct'); + } +} +``` + +#### Verification Timeout + +```javascript +await reclaimProofRequest.startSession({ + onError: (error) => { + if (error.message.includes('timeout')) { + console.error('Verification timed out - user may have abandoned flow'); + } + } +}); +``` + +--- + +## Usage Patterns + +### Pattern 1: Backend Initialization (Recommended) + +```javascript +// Backend +app.get('/api/reclaim/config', async (req, res) => { + const reclaimProofRequest = await ReclaimProofRequest.init( + process.env.RECLAIM_APP_ID, + process.env.RECLAIM_APP_SECRET, + process.env.RECLAIM_PROVIDER_ID + ); + + reclaimProofRequest.setAppCallbackUrl(`${BASE_URL}/api/reclaim/callback`); + const config = reclaimProofRequest.toJsonString(); + + res.json({ reclaimProofRequestConfig: config }); +}); + +// Frontend +const response = await fetch('/api/reclaim/config'); +const { reclaimProofRequestConfig } = await response.json(); + +const reclaimProofRequest = await ReclaimProofRequest.fromJsonString( + reclaimProofRequestConfig +); + +await reclaimProofRequest.triggerReclaimFlow(); +await reclaimProofRequest.startSession({ onSuccess, onError }); +``` + +### Pattern 2: Client-Side Only (Development Only) + +```javascript +// ⚠️ Not for production - exposes APP_SECRET +const reclaimProofRequest = await ReclaimProofRequest.init( + 'your-app-id', + 'your-app-secret', // Exposed! + 'your-provider-id' +); + +await reclaimProofRequest.triggerReclaimFlow(); + +await reclaimProofRequest.startSession({ + onSuccess: (proofs) => console.log('Success:', proofs), + onError: (error) => console.error('Error:', error) +}); +``` + +### Pattern 3: Manual URL Display + +```javascript +const reclaimProofRequest = await ReclaimProofRequest.fromJsonString(config); +const requestUrl = await reclaimProofRequest.getRequestUrl(); + +// Display QR code +renderQRCode(requestUrl); + +// Start listening +await reclaimProofRequest.startSession({ onSuccess, onError }); +``` + +--- + +## Platform Detection + +The SDK automatically detects the user's platform and provides the best experience: + +| Platform | Detection Method | Verification Flow | +|----------|-----------------|-------------------| +| Desktop Chrome/Edge | User agent | QR code modal or extension | +| Desktop Safari/Firefox | User agent | QR code modal | +| iOS Safari | User agent + touch | App Clip redirect | +| Android Chrome | User agent + touch | Instant App redirect | +| Mobile browsers | Touch capability | Deep link or QR | + +--- + +## Browser Compatibility + +- ✅ Chrome 93+ +- ✅ Edge 93+ +- ✅ Safari 14+ +- ✅ Firefox 90+ +- ✅ Opera 79+ +- ✅ Mobile browsers (iOS Safari 14+, Chrome Mobile) + +--- + +## TypeScript Support + +The SDK includes TypeScript definitions out of the box: + +```typescript +import { ReclaimProofRequest, Proof } from '@reclaimprotocol/js-sdk'; + +const reclaimProofRequest: ReclaimProofRequest = await ReclaimProofRequest.init( + appId, + appSecret, + providerId +); + +const handleSuccess = (proofs: Proof): void => { + console.log('Proof received:', proofs.identifier); +}; +``` + +--- + +## Next Steps + +- **[Installation →](/js-sdk/installation)** - Install the SDK +- **[Quickstart →](/js-sdk/quickstart)** - Quick integration guide +- **[Recommended Setup →](/js-sdk/recommended-setup)** - Production-ready setup +- **[Troubleshooting →](/js-sdk/troubleshooting)** - Common issues and solutions + +## Need Help? + +- 💬 [Community Discord](https://discord.gg/reclaim) +- 🐛 [GitHub Issues](https://github.com/reclaimprotocol/reclaim-js-sdk/issues) +- 📚 [GitHub Repository](https://github.com/reclaimprotocol/reclaim-js-sdk) diff --git a/content/docs/js-sdk/backend-verification.mdx b/content/docs/js-sdk/backend-verification.mdx new file mode 100644 index 0000000..3f32202 --- /dev/null +++ b/content/docs/js-sdk/backend-verification.mdx @@ -0,0 +1,356 @@ +--- +title: Backend Verification +description: Server-side proof verification patterns and best practices +--- + +## Overview + +Backend verification is the process of cryptographically validating proofs received from the Reclaim Protocol after users complete verification. This ensures the authenticity and integrity of the verified data before using it in your application. + + +**Why Backend Verification is Critical** + +Always verify proofs on your backend before trusting the data. Client-side verification alone can be bypassed, but cryptographic verification on your server ensures authenticity. + + +## Quick Start + +For complete backend verification implementations, see: + +- **[Node.js / Express Setup →](/js-sdk/recommended-setup/nodejs)** - Complete backend with Express.js +- **[Next.js Setup →](/js-sdk/recommended-setup/nextjs)** - API routes and verification +- **[Python Setup →](/js-sdk/recommended-setup/python)** - FastAPI and Django examples + +## Verification Process + +### 1. Receive Proof + +Proofs are sent to your callback URL as URL-encoded JSON: + +```javascript +// Express.js +app.use(express.text({ type: '*/*', limit: '50mb' })); + +app.post('/api/reclaim/callback', async (req, res) => { + const decodedBody = decodeURIComponent(req.body); + const proof = JSON.parse(decodedBody); + // ... +}); +``` + +### 2. Verify Proof + +Use the `verifyProof()` function to cryptographically verify: + +```javascript +import { verifyProof } from '@reclaimprotocol/js-sdk'; + +const isValid = await verifyProof(proof); + +if (isValid) { + console.log('✅ Proof is valid'); + // Process verified data +} else { + console.log('❌ Proof verification failed'); + // Reject the proof +} +``` + +### 3. Extract Data + +Once verified, extract the data you need: + +```javascript +if (isValid) { + const verifiedData = { + identifier: proof.identifier, + provider: JSON.parse(proof.claimData.context).extractedParameters.providerName, + timestamp: new Date(proof.timestampS * 1000), + // Extract more fields based on your provider + }; + + // YOUR BUSINESS LOGIC HERE + // - Save to database + // - Update user status + // - Trigger workflows +} +``` + +## Complete Example (Node.js) + +```javascript +const express = require('express'); +const { ReclaimProofRequest, verifyProof } = require('@reclaimprotocol/js-sdk'); + +const app = express(); +app.use(express.text({ type: '*/*', limit: '50mb' })); + +// Callback endpoint +app.post('/api/reclaim/callback', async (req, res) => { + try { + // Parse proof + const decodedBody = decodeURIComponent(req.body); + const proof = JSON.parse(decodedBody); + + console.log('📨 Received proof:', proof.identifier); + + // Verify proof + const isValid = await verifyProof(proof); + + if (!isValid) { + console.error('❌ Proof verification failed'); + return res.status(400).json({ error: 'Invalid proof' }); + } + + console.log('✅ Proof verified successfully'); + + // Extract verified data + const context = JSON.parse(proof.claimData.context); + const verifiedData = { + proofId: proof.identifier, + provider: context.extractedParameters.providerName, + verifiedAt: new Date(proof.timestampS * 1000), + }; + + // Save to database (example) + // await db.verifications.create(verifiedData); + + // Update user status (example) + // await db.users.update({ verified: true }); + + return res.json({ success: true }); + } catch (error) { + console.error('❌ Error processing proof:', error); + return res.status(500).json({ error: 'Internal server error' }); + } +}); + +app.listen(3000, () => { + console.log('Server running on port 3000'); +}); +``` + +## Complete Example (Python) + +```python +from fastapi import FastAPI, Request +from reclaim_python_sdk import verify_proof, Proof +import json +from urllib.parse import unquote + +app = FastAPI() + +@app.post("/api/reclaim/callback") +async def receive_proofs(request: Request): + try: + # Parse proof + body = await request.body() + body_str = body.decode('utf-8') + body_str = unquote(body_str) + parsed_data = json.loads(body_str) + + print(f"📨 Received proof: {parsed_data.get('identifier')}") + + # Convert to Proof object + proof = Proof.from_json(parsed_data) + + # Verify proof + is_valid = await verify_proof(proof) + + if not is_valid: + print("❌ Proof verification failed") + return {"error": "Invalid proof"}, 400 + + print("✅ Proof verified successfully") + + # Extract verified data + verified_data = { + "proof_id": proof.identifier, + "provider": proof.claimData.provider, + "verified_at": datetime.fromtimestamp(proof.timestampS) + } + + # Save to database (example) + # await db.verifications.create(verified_data) + + return {"success": True} + + except Exception as error: + print(f"❌ Error: {error}") + return {"error": "Internal server error"}, 500 +``` + +## Proof Structure + +Understanding the proof object structure: + +```typescript +{ + identifier: string; // Unique proof ID + claimData: { + provider: string; // Provider name + parameters: string; // JSON string of parameters + context: string; // JSON string with metadata + }; + signatures: string[]; // Cryptographic signatures + witnesses: [{ // Witness attestations + address: string; + signature: string; + }]; + timestampS: number; // Unix timestamp (seconds) +} +``` + +## Security Best Practices + + +**Critical Security Requirements** + +1. **Always verify on backend** - Never trust client-side verification alone +2. **Validate proof structure** - Check all required fields exist +3. **Store proofs securely** - Use encrypted database storage +4. **Check timestamps** - Reject old proofs (set expiration time) +5. **Rate limit callbacks** - Prevent spam/DOS attacks +6. **Use HTTPS** - Secure data in transit + + +### Timestamp Validation + +```javascript +const MAX_AGE_SECONDS = 300; // 5 minutes + +const isValid = await verifyProof(proof); +const proofAge = Date.now() / 1000 - proof.timestampS; + +if (isValid && proofAge <= MAX_AGE_SECONDS) { + // Proof is valid and recent +} else if (proofAge > MAX_AGE_SECONDS) { + console.log('⚠️ Proof is too old'); +} +``` + +### Proof Deduplication + +```javascript +// Check if proof was already processed +const existingProof = await db.proofs.findOne({ + identifier: proof.identifier +}); + +if (existingProof) { + console.log('⚠️ Proof already processed'); + return res.status(409).json({ error: 'Proof already processed' }); +} + +// Process and save new proof +await db.proofs.create({ identifier: proof.identifier, ... }); +``` + +## Database Integration + +### Save Verified Proofs + +```javascript +// Mongoose/MongoDB example +const Verification = mongoose.model('Verification', { + proofId: { type: String, unique: true }, + userId: String, + provider: String, + verifiedAt: Date, + proofData: Object +}); + +// In callback +if (isValid) { + await Verification.create({ + proofId: proof.identifier, + userId: extractUserId(proof), + provider: extractProvider(proof), + verifiedAt: new Date(proof.timestampS * 1000), + proofData: proof + }); +} +``` + +## Error Handling + +```javascript +app.post('/api/reclaim/callback', async (req, res) => { + try { + const proof = parseProof(req.body); + + // Validate structure + if (!proof || !proof.identifier || !proof.claimData) { + return res.status(400).json({ error: 'Invalid proof structure' }); + } + + // Verify cryptographically + const isValid = await verifyProof(proof); + + if (!isValid) { + return res.status(400).json({ error: 'Proof verification failed' }); + } + + // Process proof + // ... + + res.json({ success: true }); + } catch (error) { + if (error instanceof SyntaxError) { + return res.status(400).json({ error: 'Invalid JSON' }); + } + + console.error('Error:', error); + res.status(500).json({ error: 'Internal server error' }); + } +}); +``` + +## Testing + +### Manual Testing + +```bash +# Test your callback endpoint +curl -X POST https://yourapp.com/api/reclaim/callback \ + -H "Content-Type: application/x-www-form-urlencoded" \ + -d '{"identifier":"test","claimData":{},"signatures":[],"witnesses":[],"timestampS":1234567890}' +``` + +### Automated Testing + +```javascript +// Jest example +describe('Proof Verification', () => { + it('should verify valid proof', async () => { + const mockProof = { + identifier: 'test-proof-id', + claimData: { ... }, + signatures: ['...'], + witnesses: [{ ... }], + timestampS: Date.now() / 1000 + }; + + const response = await request(app) + .post('/api/reclaim/callback') + .send(encodeURIComponent(JSON.stringify(mockProof))); + + expect(response.status).toBe(200); + }); +}); +``` + +## Next Steps + +For complete implementation examples: + +- **[Node.js Setup →](/js-sdk/recommended-setup/nodejs)** - Full Express.js backend +- **[Next.js Setup →](/js-sdk/recommended-setup/nextjs)** - API routes implementation +- **[Python Setup →](/js-sdk/recommended-setup/python)** - FastAPI/Django examples +- **[API Reference →](/js-sdk/api-reference)** - Complete SDK documentation +- **[Troubleshooting →](/js-sdk/troubleshooting)** - Common issues + +## Need Help? + +- 💬 [Community Discord](https://discord.gg/reclaim) +- 🐛 [GitHub Issues](https://github.com/reclaimprotocol/reclaim-js-sdk/issues) diff --git a/content/docs/js-sdk/client-integration.mdx b/content/docs/js-sdk/client-integration.mdx new file mode 100644 index 0000000..84024fd --- /dev/null +++ b/content/docs/js-sdk/client-integration.mdx @@ -0,0 +1,136 @@ +--- +title: Client Integration +description: Advanced client-side integration patterns and framework-specific guides +--- + +## Overview + +This section covers advanced client-side integration patterns for different frameworks and use cases. + +For most use cases, the [Quickstart](/js-sdk/quickstart) and [Recommended Setup](/js-sdk/recommended-setup) guides provide everything you need. This section is for advanced customization and framework-specific optimizations. + +## Available Guides + +### React Integration + +For React-specific patterns, hooks, and components, see: +- [Quickstart with React](/js-sdk/quickstart/react) - Basic integration +- [Recommended Setup with React](/js-sdk/recommended-setup/nodejs) - Production patterns + +### Next.js Integration + +For Next.js with App Router or Pages Router: +- [Next.js Recommended Setup](/js-sdk/recommended-setup/nextjs) - Complete full-stack guide + +### Vanilla JavaScript + +For framework-agnostic integration: +- [Vanilla JS Quickstart](/js-sdk/quickstart/vanilla-js) - Pure JavaScript implementation + +## Common Integration Patterns + +### Custom Hooks (React) + +Create reusable hooks for verification: + +```javascript +// hooks/useReclaim.js +import { useState, useCallback } from 'react'; +import { ReclaimProofRequest } from '@reclaimprotocol/js-sdk'; + +export function useReclaim() { + const [proofs, setProofs] = useState(null); + const [isLoading, setIsLoading] = useState(false); + const [error, setError] = useState(null); + + const startVerification = useCallback(async () => { + try { + setIsLoading(true); + setError(null); + + // Fetch config from backend + const response = await fetch('/api/reclaim/config'); + const { reclaimProofRequestConfig } = await response.json(); + + const reclaimProofRequest = await ReclaimProofRequest.fromJsonString( + reclaimProofRequestConfig + ); + + await reclaimProofRequest.triggerReclaimFlow(); + + await reclaimProofRequest.startSession({ + onSuccess: (proofs) => { + setProofs(proofs); + setIsLoading(false); + }, + onError: (err) => { + setError(err.message); + setIsLoading(false); + } + }); + } catch (err) { + setError(err.message); + setIsLoading(false); + } + }, []); + + return { proofs, isLoading, error, startVerification }; +} +``` + +### Composables (Vue 3) + +```javascript +// composables/useReclaim.js +import { ref } from 'vue'; +import { ReclaimProofRequest } from '@reclaimprotocol/js-sdk'; + +export function useReclaim() { + const proofs = ref(null); + const isLoading = ref(false); + const error = ref(null); + + const startVerification = async () => { + try { + isLoading.value = true; + error.value = null; + + const response = await fetch('/api/reclaim/config'); + const { reclaimProofRequestConfig } = await response.json(); + + const reclaimProofRequest = await ReclaimProofRequest.fromJsonString( + reclaimProofRequestConfig + ); + + await reclaimProofRequest.triggerReclaimFlow(); + + await reclaimProofRequest.startSession({ + onSuccess: (proof) => { + proofs.value = proof; + isLoading.value = false; + }, + onError: (err) => { + error.value = err.message; + isLoading.value = false; + } + }); + } catch (err) { + error.value = err.message; + isLoading.value = false; + } + }; + + return { + proofs, + isLoading, + error, + startVerification + }; +} +``` + +## Next Steps + +- **[Recommended Setup →](/js-sdk/recommended-setup)** - Production-ready patterns +- **[API Reference →](/js-sdk/api-reference)** - Complete SDK documentation +- **[Troubleshooting →](/js-sdk/troubleshooting)** - Common issues and solutions diff --git a/content/docs/js-sdk/index.mdx b/content/docs/js-sdk/index.mdx new file mode 100644 index 0000000..e59986b --- /dev/null +++ b/content/docs/js-sdk/index.mdx @@ -0,0 +1,255 @@ +--- +title: JavaScript SDK +description: Official JavaScript SDK for integrating Reclaim Protocol proof generation and verification into web applications, Node.js backends, and React Native apps +--- + +## Overview + +The Reclaim JavaScript SDK enables you to integrate cryptographic proof generation and verification into your applications. Users can generate zero-knowledge proofs of their online data without exposing sensitive information, and your backend can verify these proofs securely. + +### Key Features + +- 🚀 **Multi-Platform Support**: Works in browsers, Node.js, React Native, and mobile webviews +- 🔐 **Zero-Knowledge Proofs**: Verify user data without accessing sensitive information +- 🎯 **Smart Platform Detection**: Automatically selects optimal verification flow (QR code, App Clip, Instant App, Browser Extension) +- ⚡ **Simple Integration**: One-line `triggerReclaimFlow()` handles the entire verification process +- 🛡️ **Backend Verification**: Cryptographically verify proofs on your server +- 🎨 **Customizable UI**: Configure modal appearance, themes, and callbacks +- 📱 **Mobile-First**: Native support for iOS App Clips and Android Instant Apps + +## Two Integration Approaches + +### 1. Client-Side Only (Development & Prototyping) + +**Quick setup for development** - Initialize and handle everything in the browser: + +- Initialize SDK directly in frontend +- Start verification session +- Receive proofs in frontend +- Save/process proofs client-side + +**Use cases**: Development, prototyping, learning, proof-of-concept demos + + +**Security Note**: Use this approach for **development purposes only**. + +If using client-side initialization: + +- Store `APP_ID` and `APP_SECRET` in `.env` file (never hardcode) +- Never commit credentials to version control +- **Do not deploy to production** with this approach + +**Recommended**: Always initialize from backend in production environments to keep `APP_SECRET` secure. + + + +[Try Client-Side Quickstart →](/js-sdk/quickstart) + +### 2. Backend Integration (Production-Ready) ⭐ + +**Secure full-stack approach** - Initialize from backend, verify proofs server-side: + +**Flow**: + +1. **Backend**: Initialize SDK with `APP_SECRET` (secure in `.env`) +2. **Backend**: Generate verification config/URL +3. **Frontend**: Start verification session with config from backend +4. **User**: Complete verification on mobile/extension +5. **Backend**: Receive proof via callback URL +6. **Backend**: Verify proof cryptographically +7. **Backend**: Process verified data and update your database + +**Benefits**: + +- ✅ `APP_SECRET` never exposed to client +- ✅ Proofs verified server-side before use +- ✅ Direct proof delivery to your backend via callback URL +- ✅ Production-ready and secure + + + **Best Practice**: This is the recommended approach for all production applications. The callback URL allows Reclaim to send proofs + directly to your backend for verification, ensuring data integrity. + + +[See Backend Integration Guide →](/js-sdk/recommended-setup) + +## How It Works + +The Reclaim Protocol verification flow follows these steps: + +```mermaid +sequenceDiagram + participant Frontend + participant Backend + participant User + participant Reclaim + + Frontend->>Backend: Request verification config + Backend->>Backend: Initialize SDK with APP_SECRET + Backend->>Frontend: Return secure config + Frontend->>User: Display QR code / trigger flow + User->>Reclaim: Complete verification on mobile + Reclaim->>Frontend: Proof generated + Frontend->>Backend: Submit proof + Backend->>Backend: Verify proof cryptographically + Backend->>Frontend: Verification result +``` + +### Workflow Steps + +1. **Backend Initialization**: Your server initializes the SDK with `APP_ID` and `APP_SECRET` (kept secure) +2. **Request Generation**: Backend creates a verification request URL and returns config to frontend +3. **User Verification**: Frontend displays QR code or triggers appropriate flow based on device +4. **Proof Generation**: User completes verification via mobile (App Clip/Instant App) or browser extension +5. **Proof Submission**: Frontend receives the cryptographic proof and sends to backend +6. **Backend Verification**: Server verifies the proof's cryptographic signature and extracts verified data + +## Platform Detection & Verification Methods + +The SDK automatically detects the user's platform and chooses the best verification method: + +| Platform | Verification Method | User Experience | +| ---------------------------- | ----------------------------- | -------------------------------- | +| **Desktop Browser** | QR Code + Mobile verification | User scans QR with mobile device | +| **iOS Safari** | App Clip integration | Seamless in-app verification | +| **Android Chrome** | Instant App | Seamless in-app verification | +| **Desktop (with extension)** | Browser Extension | In-browser verification | + +The `triggerReclaimFlow()` method handles all platform detection automatically. + + + **Note on Android**: Google is discontinuing Instant Apps support in December 2025. Reclaim Protocol has transitioned to deep linking for + Android, providing a seamless verification experience without app installation. [Learn more + →](https://blog.reclaimprotocol.org/posts/moving-beyond-google-play-instant) + + +## Advanced Configuration & Customization + +The SDK provides extensive customization options for the verification flow and UI. All features from the [Reclaim JS SDK](https://github.com/reclaimprotocol/reclaim-js-sdk#advanced-configuration) can be used: + +### Modal Customization + +Configure the QR code modal appearance and behavior: + +```javascript +reclaimProofRequest.setModalOptions({ + // Theme + darkTheme: true, // Enable dark mode + + // Text customization + title: "Verify Your Account", + description: "Scan QR code with your mobile device", + + // Behavior + modalPopupTimer: 5, // Auto-close after 5 minutes + + // Browser extension + showExtensionInstallButton: true, // Show extension install prompt + extensionUrl: "custom-extension-url", + + // Callbacks + onClose: () => { + console.log("Modal closed by user"); + }, +}); +``` + +### Context Addition + +Add custom context/metadata to your proof requests: + +```javascript +reclaimProofRequest.addContext("0x00000000000", "Custom context message or metadata"); +``` + +### Browser Extension Configuration + +Configure browser extension behavior during initialization: + +```javascript +const reclaimProofRequest = await ReclaimProofRequest.init(APP_ID, APP_SECRET, PROVIDER_ID, { + useBrowserExtension: true, // Enable/disable extension (default: true) + extensionID: "custom-extension-id", // Custom extension identifier +}); +``` + +### Check Extension Availability + +Conditionally show UI based on extension availability: + +```javascript +const hasExtension = await reclaimProofRequest.isBrowserExtensionAvailable(); + +if (hasExtension) { + // Show "Verify with Extension" button +} else { + // Show "Scan QR Code" message +} +``` + +### Session Callbacks + +Handle verification results with detailed callbacks: + +```javascript +await reclaimProofRequest.startSession({ + onSuccess: (proofs) => { + // Handle successful verification + // proofs can be either a string message or proof object + console.log("Verification successful:", proofs); + }, + onFailure: (error) => { + // Handle verification errors + console.error("Verification failed:", error); + }, +}); +``` + +For complete configuration options and examples, see the [Advanced Configuration documentation](https://github.com/reclaimprotocol/reclaim-js-sdk#advanced-configuration). + +## Framework Support + +The SDK works seamlessly with popular frameworks: + +- ✅ **React** - Hooks and components +- ✅ **Next.js** - API routes + frontend integration +- ✅ **Vue.js** - Composables and reactive integration +- ✅ **Vanilla JavaScript** - Framework-agnostic +- ✅ **React Native** - Mobile app integration +- ✅ **Node.js** - Express, Fastify, NestJS +- ✅ **Python** - FastAPI, Django, Flask + +## Security Best Practices + + + +**Critical Security Requirements** + +1. **Never expose APP_SECRET in frontend code** - Always initialize from backend +2. **Use environment variables** - Store credentials in `.env` files +3. **Verify proofs on backend** - Never trust client-side verification alone +4. **Use HTTPS** - Protect data in transit +5. **Validate proof structure** - Check all required fields before processing + + + +## Next Steps + +Choose your integration path: + +1. **[Installation](/js-sdk/installation)** - Install the SDK via npm or yarn +2. **[Quickstart](/js-sdk/quickstart)** - Quick client-side demo for learning (dev only) +3. **[Recommended Setup](/js-sdk/recommended-setup)** - Production-ready backend initialization ⭐ +4. **[API Reference](/js-sdk/api-reference)** - Complete SDK documentation +5. **[Troubleshooting](/js-sdk/troubleshooting)** - Common issues and solutions + +## Get API Credentials + +Before integrating, you'll need API credentials (`APP_ID`, `APP_SECRET`, and `PROVIDER_ID`). Follow the [Get API Key guide](/api-key) to set up your Reclaim Protocol project. + +## Need Help? + +- 📖 [Complete API Reference](/js-sdk/api-reference) +- 🐛 [Troubleshooting Guide](/js-sdk/troubleshooting) +- 💬 [Community Discord](https://discord.gg/reclaim) +- 🔗 [GitHub Repository](https://github.com/reclaimprotocol/reclaim-js-sdk) diff --git a/content/docs/js-sdk/installation.mdx b/content/docs/js-sdk/installation.mdx new file mode 100644 index 0000000..98754ad --- /dev/null +++ b/content/docs/js-sdk/installation.mdx @@ -0,0 +1,188 @@ +--- +title: Installation +description: Install the Reclaim JavaScript SDK and start integrating proof generation and verification +--- + +import { Tab, Tabs } from 'fumadocs-ui/components/tabs'; + +## Prerequisites + +- **Node.js**: 14.x or later +- **Package Manager**: npm 6.x+, yarn 1.22.x+, or pnpm +- **Project**: Initialized with `package.json` + +## Installation + + +```bash tab="npm" +npm install @reclaimprotocol/js-sdk +``` + +```bash tab="yarn" +yarn add @reclaimprotocol/js-sdk +``` + +```bash tab="pnpm" +pnpm add @reclaimprotocol/js-sdk +``` + + +## Import + + +```javascript tab="ES Modules" +import { ReclaimProofRequest } from '@reclaimprotocol/js-sdk'; +``` + +```javascript tab="CommonJS" +const { ReclaimProofRequest } = require('@reclaimprotocol/js-sdk'); +``` + +```typescript tab="TypeScript" +import { ReclaimProofRequest, Proof } from '@reclaimprotocol/js-sdk'; +``` + + +## Get API Credentials + +Before using the SDK, obtain your credentials from the [Reclaim Developer Portal](/api-key): + +- `APP_ID` - Your application identifier +- `APP_SECRET` - Your application secret (keep secure!) +- `PROVIDER_ID` - The provider you want to verify against + +## Environment Setup + + +**Security**: Never hardcode credentials in your code or commit them to version control. Always use environment variables. + + +Create a `.env` file in your project root: + +```bash +# .env +RECLAIM_APP_ID=your_app_id_here +RECLAIM_APP_SECRET=your_app_secret_here +RECLAIM_PROVIDER_ID=your_provider_id_here +``` + +Add `.env` to your `.gitignore`: + +``` +# .gitignore +.env +.env.local +.env.*.local +``` + +### Load Environment Variables + + +```javascript tab="Node.js" +// Install dotenv +// npm install dotenv + +// Load at the top of your file +require('dotenv').config(); + +// Access variables +const APP_ID = process.env.RECLAIM_APP_ID; +``` + +```javascript tab="Next.js" +// Next.js loads .env.local automatically +// Create .env.local file with your credentials + +// Access in API routes or server components +const APP_ID = process.env.RECLAIM_APP_ID; + +// Note: Use NEXT_PUBLIC_ prefix only for client-side vars +// Never use NEXT_PUBLIC_ for APP_SECRET +``` + +```javascript tab="Vite" +// Vite loads .env automatically +// Prefix with VITE_ for client-side access + +// .env +VITE_RECLAIM_APP_ID=your_app_id + +// Access in code +const APP_ID = import.meta.env.VITE_RECLAIM_APP_ID; + +// For backend/server-side only (no VITE_ prefix) +RECLAIM_APP_SECRET=your_secret +``` + + + +**Critical**: Never expose `APP_SECRET` to the client. Keep it server-side only. Frontend environment variables (like `REACT_APP_*`, `NEXT_PUBLIC_*`, `VITE_*`) are bundled into your JavaScript and visible to users. + + +## Verify Installation + +Create a test file to verify the SDK is installed correctly: + +```javascript +// test-install.js +import { ReclaimProofRequest } from '@reclaimprotocol/js-sdk'; + +console.log('✅ Reclaim SDK imported successfully!'); +console.log('ReclaimProofRequest:', typeof ReclaimProofRequest); +``` + +Run the test: + +```bash +node test-install.js +``` + +Expected output: +``` +✅ Reclaim SDK imported successfully! +ReclaimProofRequest: function +``` + +## Troubleshooting + +### Module Not Found + +If you see `Cannot find module '@reclaimprotocol/js-sdk'`: + +```bash +# Verify installation +npm list @reclaimprotocol/js-sdk + +# Reinstall if needed +npm install @reclaimprotocol/js-sdk +``` + +### TypeScript Errors + +Ensure TypeScript 4.0+ and check `tsconfig.json`: + +```json +{ + "compilerOptions": { + "moduleResolution": "node", + "esModuleInterop": true + } +} +``` + +### Environment Variables Not Loading + +- Ensure `.env` file is in project root +- Restart your development server after changes +- Check for typos in variable names +- Verify no spaces around `=` in `.env` file + +## Next Steps + +Choose your integration approach: + +- **[Quickstart →](/js-sdk/quickstart)** - Client-side demo for learning (dev only) +- **[Backend Integration →](/js-sdk/recommended-setup)** - Production-ready setup ⭐ +- **[API Reference →](/js-sdk/api-reference)** - Complete SDK documentation + +Get started with your [first integration →](/js-sdk/quickstart) diff --git a/content/docs/js-sdk/meta.json b/content/docs/js-sdk/meta.json new file mode 100644 index 0000000..7b9652f --- /dev/null +++ b/content/docs/js-sdk/meta.json @@ -0,0 +1,12 @@ +{ + "title": "JavaScript SDK", + "pages": [ + "installation", + "quickstart", + "recommended-setup", + "client-integration", + "backend-verification", + "api-reference", + "troubleshooting" + ] +} diff --git a/content/docs/js-sdk/quickstart.mdx b/content/docs/js-sdk/quickstart.mdx new file mode 100644 index 0000000..60da3a8 --- /dev/null +++ b/content/docs/js-sdk/quickstart.mdx @@ -0,0 +1,654 @@ +--- +title: Quickstart +description: Get started quickly with client-side Reclaim SDK integration for prototyping and learning +--- + +import { Tab, Tabs } from 'fumadocs-ui/components/tabs'; + + +**⚠️ Development Only - Not for Production** + +This quickstart guide shows **client-side initialization** which exposes your `APP_SECRET` in the browser. This approach is only suitable for: +- Learning and prototyping +- Local development +- Proof-of-concept demos + +**Never deploy this to production.** For production applications, use the [Backend Integration](/js-sdk/recommended-setup) with secure backend initialization. + + +## Overview + +The quickstart approach lets you experience the Reclaim verification flow in minutes by initializing the SDK directly in your frontend code. This is the fastest way to understand how the SDK works, but it's not secure for production use. + +## Prerequisites + +- ✅ Installed the SDK following the [Installation guide](/js-sdk/installation) +- ✅ Obtained your `APP_ID`, `APP_SECRET`, and `PROVIDER_ID` from the [API Key guide](/api-key) +- ✅ A React or vanilla JavaScript project set up + +## Two Integration Methods + +There are two ways to trigger verification in your frontend: + +### Method 1: triggerReclaimFlow() (Recommended) + +The `triggerReclaimFlow()` method automatically detects the user's platform and provides the optimal verification experience. This is the simplest approach. + +**What it does**: +- Automatically shows QR code modal on desktop +- Redirects to App Clip on iOS +- Redirects to deep link on Android +- Uses browser extension if available + +### Method 2: getRequestUrl() (Manual Control) + +The `getRequestUrl()` method gives you the verification URL to display however you want. Use this when you need custom UI or specific flow control. + +**What it does**: +- Returns a verification URL +- You handle displaying it (QR code, link, button, etc.) +- More control over the user experience + +--- + +## React Implementation + +### Method 1: Using triggerReclaimFlow() + + +```jsx tab="Complete Example" +import { useState } from 'react'; +import { ReclaimProofRequest } from '@reclaimprotocol/js-sdk'; + +function ReclaimDemo() { + const [proofs, setProofs] = useState(null); + const [isLoading, setIsLoading] = useState(false); + const [error, setError] = useState(null); + + const handleVerification = async () => { + try { + setIsLoading(true); + setError(null); + + // ⚠️ CLIENT-SIDE ONLY - NOT FOR PRODUCTION + const APP_ID = 'YOUR_APPLICATION_ID'; + const APP_SECRET = 'YOUR_APPLICATION_SECRET'; + const PROVIDER_ID = 'YOUR_PROVIDER_ID'; + + // Initialize the Reclaim SDK + const reclaimProofRequest = await ReclaimProofRequest.init( + APP_ID, + APP_SECRET, + PROVIDER_ID + ); + + // Trigger the verification flow (automatic platform detection) + await reclaimProofRequest.triggerReclaimFlow(); + + // Start listening for proof submissions + await reclaimProofRequest.startSession({ + onSuccess: (proofs) => { + console.log('Verification successful:', proofs); + setProofs(proofs); + setIsLoading(false); + }, + onError: (error) => { + console.error('Verification failed:', error); + setError(error.message); + setIsLoading(false); + }, + }); + } catch (error) { + console.error('Error starting verification:', error); + setError(error.message); + setIsLoading(false); + } + }; + + return ( +
+

Reclaim Verification Demo

+ + + + {error && ( +
+

Error: {error}

+
+ )} + + {proofs && ( +
+

✅ Verification Successful!

+
{JSON.stringify(proofs, null, 2)}
+
+ )} +
+ ); +} + +export default ReclaimDemo; +``` + +```jsx tab="Key Code" +// Initialize SDK +const reclaimProofRequest = await ReclaimProofRequest.init( + APP_ID, + APP_SECRET, + PROVIDER_ID +); + +// Trigger flow (auto platform detection) +await reclaimProofRequest.triggerReclaimFlow(); + +// Listen for results +await reclaimProofRequest.startSession({ + onSuccess: (proofs) => { + console.log('Success:', proofs); + }, + onError: (error) => { + console.error('Error:', error); + } +}); +``` +
+ +### Method 2: Using getRequestUrl() + + +```jsx tab="Complete Example" +import { useState } from 'react'; +import QRCode from 'react-qr-code'; +import { ReclaimProofRequest } from '@reclaimprotocol/js-sdk'; + +function ReclaimCustomDemo() { + const [requestUrl, setRequestUrl] = useState(''); + const [proofs, setProofs] = useState(null); + const [isLoading, setIsLoading] = useState(false); + + const generateVerificationRequest = async () => { + try { + setIsLoading(true); + + // ⚠️ CLIENT-SIDE ONLY - NOT FOR PRODUCTION + const APP_ID = 'YOUR_APPLICATION_ID'; + const APP_SECRET = 'YOUR_APPLICATION_SECRET'; + const PROVIDER_ID = 'YOUR_PROVIDER_ID'; + + // Initialize the SDK + const reclaimProofRequest = await ReclaimProofRequest.init( + APP_ID, + APP_SECRET, + PROVIDER_ID + ); + + // Generate the verification request URL + const requestUrl = await reclaimProofRequest.getRequestUrl(); + setRequestUrl(requestUrl); + setIsLoading(false); + + // Start listening for proof submissions + await reclaimProofRequest.startSession({ + onSuccess: (proofs) => { + console.log('Verification successful:', proofs); + setProofs(proofs); + }, + onError: (error) => { + console.error('Verification failed:', error); + }, + }); + } catch (error) { + console.error('Error generating request:', error); + setIsLoading(false); + } + }; + + return ( +
+

Custom Reclaim Verification

+ + + + {requestUrl && ( +
+

Scan QR Code to Verify

+ + +
+

On mobile? Click the link:

+ + Open Verification + +
+
+ )} + + {proofs && ( +
+

✅ Verification Complete!

+
{JSON.stringify(proofs, null, 2)}
+
+ )} +
+ ); +} + +export default ReclaimCustomDemo; +``` + +```jsx tab="Key Code" +// Initialize SDK +const reclaimProofRequest = await ReclaimProofRequest.init( + APP_ID, + APP_SECRET, + PROVIDER_ID +); + +// Get verification URL +const requestUrl = await reclaimProofRequest.getRequestUrl(); + +// Display QR code with your own implementation + + +// Listen for results +await reclaimProofRequest.startSession({ + onSuccess: (proofs) => console.log('Success:', proofs), + onError: (error) => console.error('Error:', error) +}); +``` +
+ + +**QR Code Library**: Install `react-qr-code` for Method 2: +```bash +npm install react-qr-code +``` + + +--- + +## Vanilla JavaScript Implementation + +### Method 1: Using triggerReclaimFlow() + + +```html tab="Complete Example" + + + + + + Reclaim Verification Demo + + + +

Reclaim Verification Demo

+

Click the button to start verification

+ + +
+
+ + + + +``` + +```javascript tab="Key Code" +import { ReclaimProofRequest } from '@reclaimprotocol/js-sdk'; + +// Initialize SDK +const reclaimProofRequest = await ReclaimProofRequest.init( + APP_ID, + APP_SECRET, + PROVIDER_ID +); + +// Trigger flow (auto platform detection) +await reclaimProofRequest.triggerReclaimFlow(); + +// Listen for results +await reclaimProofRequest.startSession({ + onSuccess: (proofs) => { + console.log('Success:', proofs); + }, + onError: (error) => { + console.error('Error:', error); + } +}); +``` +
+ +### Method 2: Using getRequestUrl() + + +```html tab="Complete Example" + + + + + + Custom Reclaim Verification + + + +

Custom Reclaim Verification

+ + + + + +
+ + + + + + + +``` + +```javascript tab="Key Code" +import { ReclaimProofRequest } from '@reclaimprotocol/js-sdk'; + +// Initialize SDK +const reclaimProofRequest = await ReclaimProofRequest.init( + APP_ID, + APP_SECRET, + PROVIDER_ID +); + +// Get verification URL +const requestUrl = await reclaimProofRequest.getRequestUrl(); + +// Display QR code with QRCode library +new QRCode(element, { + text: requestUrl, + width: 256, + height: 256 +}); + +// Listen for results +await reclaimProofRequest.startSession({ + onSuccess: (proofs) => console.log('Success:', proofs), + onError: (error) => console.error('Error:', error) +}); +``` +
+ +--- + +## Security Considerations + + +**Why This Isn't Production-Ready** + +When you initialize the SDK in the browser: + +1. **APP_SECRET is exposed** - Anyone can view your secret in the browser's DevTools +2. **No backend verification** - Proofs aren't verified server-side before use +3. **Client can be tampered** - Users could potentially modify the verification flow +4. **Credentials can be stolen** - Your API credentials are visible in the source code + +**The Fix**: Use [backend initialization](/js-sdk/recommended-setup) to keep `APP_SECRET` secure on your server. + + +## What's Next? + +After experimenting with the quickstart: + +1. **[Backend Integration →](/js-sdk/recommended-setup)** - Learn how to securely initialize from your backend ⭐ +2. **[Backend Verification →](/js-sdk/backend-verification)** - Verify proofs server-side +3. **[API Reference →](/js-sdk/api-reference)** - Explore all SDK methods + +## Common Issues + +### Modal Doesn't Appear + +**Issue**: Nothing happens when calling `triggerReclaimFlow()` + +**Solution**: Check browser console for errors. Ensure you're calling it from a user interaction (button click). + +### QR Code Not Loading + +**Issue**: QR code is blank or shows an error + +**Solution**: Verify your credentials are correct and the provider ID is valid. + +### Mobile Verification Fails + +**Issue**: App Clip or deep link doesn't launch on mobile + +**Solution**: Test on an actual mobile device. Simulators may not support App Clips or deep links. + +For more help, see the [Troubleshooting Guide](/js-sdk/troubleshooting). diff --git a/content/docs/js-sdk/recommended-setup/index.mdx b/content/docs/js-sdk/recommended-setup/index.mdx new file mode 100644 index 0000000..5966fbe --- /dev/null +++ b/content/docs/js-sdk/recommended-setup/index.mdx @@ -0,0 +1,360 @@ +--- +title: Recommended Setup +description: Production-ready Reclaim Protocol integration with secure backend initialization +--- + + +**✅ Production-Ready Approach** + +This is the **recommended way** to integrate Reclaim Protocol in production applications. Your `APP_SECRET` stays secure on your backend, never exposed to the client. + + + +**SDK Installation Required** + +You need to install the appropriate SDK for your backend: + +- **Node.js/JavaScript**: Install `@reclaimprotocol/js-sdk` + ```bash + npm install @reclaimprotocol/js-sdk + ``` + +- **Python**: Install `reclaim-python-sdk` + ```bash + pip install reclaim-python-sdk + ``` + +Each setup guide below includes detailed installation instructions. + + +## Overview + +The recommended setup separates sensitive operations (SDK initialization with `APP_SECRET`) from client-side operations (UI and proof display). This architecture ensures: + +- ✅ **APP_SECRET stays secure** - Never exposed in browser code +- ✅ **Backend verification** - Proofs are verified server-side before use +- ✅ **Scalability** - Centralized configuration management +- ✅ **Auditability** - All verifications logged on your server + +## Architecture + +```mermaid +sequenceDiagram + participant Frontend + participant Backend + participant User + participant Reclaim + + Frontend->>Backend: GET /api/reclaim/config + Note over Backend: Initialize SDK with APP_SECRET
(secure, server-side) + Backend->>Backend: ReclaimProofRequest.init() + Backend->>Backend: Generate request URL + Backend->>Frontend: Return config (no secrets) + + Frontend->>User: Display verification UI + User->>Reclaim: Complete verification (mobile/extension) + Reclaim->>Backend: POST /api/reclaim/callback (proof) + + Note over Backend: Verify proof cryptographically + Backend->>Backend: verifyProof() + + Reclaim->>Frontend: Proof success event + Frontend->>Backend: GET /api/user/status + Backend->>Frontend: Verified data +``` + +## How It Works + +### Step 1: Backend Initialization (Secure) + +Your backend initializes the SDK with `APP_SECRET` from environment variables: + +```javascript +// Backend: Initialize SDK securely +const reclaimProofRequest = await ReclaimProofRequest.init( + process.env.RECLAIM_APP_ID, // From .env - secure + process.env.RECLAIM_APP_SECRET, // From .env - NEVER exposed + process.env.RECLAIM_PROVIDER_ID // From .env - secure +); +``` + +### Step 2: Generate Configuration + +Backend generates a configuration object that's safe to send to the frontend: + +```javascript +// Set callback URL for proof verification +reclaimProofRequest.setAppCallbackUrl('https://yourapp.com/api/reclaim/callback'); + +// Convert to JSON string (no secrets included) +const config = reclaimProofRequest.toJsonString(); + +// Send to frontend +res.json({ reclaimProofRequestConfig: config }); +``` + +### Step 3: Frontend Reconstruction + +Frontend receives the config and reconstructs the proof request: + +```javascript +// Frontend: Reconstruct from config +const reclaimProofRequest = await ReclaimProofRequest.fromJsonString(config); + +// Trigger verification flow +await reclaimProofRequest.triggerReclaimFlow(); +``` + +### Step 4: Backend Verification + +When the user completes verification, Reclaim sends the proof to your callback URL: + +```javascript +// Backend: Verify the proof +const isValid = await verifyProof(proof); + +if (isValid) { + // Process verified data, update database, etc. +} +``` + +## Security Best Practices + + +**Critical Security Requirements** + +1. **Never expose APP_SECRET** - Always keep it on the backend in environment variables +2. **Use HTTPS** - All production deployments must use HTTPS +3. **Verify proofs backend-side** - Never trust client-side verification alone +4. **Set callback URL** - Let Reclaim send proofs directly to your server +5. **Validate proof structure** - Check all required fields before processing +6. **Use environment variables** - Never hardcode credentials + + +## Environment Setup + +### .env File (Backend Only) + +```bash +# .env - Backend only, never commit to git +RECLAIM_APP_ID=your_app_id_here +RECLAIM_APP_SECRET=your_app_secret_here +RECLAIM_PROVIDER_ID=your_provider_id_here + +# Your app's base URL +BASE_URL=https://yourapp.com + +# For local development with ngrok +# BASE_URL=https://abc123.ngrok.io +``` + +### .gitignore + +Ensure credentials are never committed: + +```bash +# .gitignore +.env +.env.local +.env.*.local +``` + +## Implementation by Framework + +Choose your backend framework to see detailed implementation: + + + +## Key API Endpoints + +### 1. Generate Config Endpoint + +**Purpose**: Securely initialize SDK and return safe config to frontend + +``` +GET /api/reclaim/config +``` + +**Response**: +```json +{ + "reclaimProofRequestConfig": "{...safe config without secrets...}" +} +``` + +### 2. Receive Proofs Endpoint (Callback) + +**Purpose**: Receive and verify proofs from Reclaim Protocol + +``` +POST /api/reclaim/callback +``` + +**Request Body**: URL-encoded proof object + +**Response**: 200 OK if verification succeeds + +## Local Development with ngrok + +When developing locally, you need a public URL for the callback endpoint: + +### Install ngrok + +```bash +# macOS (Homebrew) +brew install ngrok + +# Or download from https://ngrok.com/download +``` + +### Start ngrok Tunnel + +```bash +# Tunnel to your local server (e.g., port 3000) +ngrok http 3000 +``` + +You'll see output like: + +``` +Forwarding https://abc123.ngrok.io -> http://localhost:3000 +``` + +### Update Your .env + +```bash +BASE_URL=https://abc123.ngrok.io +``` + + +**ngrok Tip**: The free tier generates a new URL each time. Consider using the paid tier for a persistent domain during development, or use ngrok's configuration to set a custom subdomain. + + +## Testing the Integration + +### 1. Test Config Generation + +```bash +curl https://yourapp.com/api/reclaim/config +``` + +Should return: +```json +{ + "reclaimProofRequestConfig": "{...}" +} +``` + +### 2. Test Callback Endpoint + +You can manually test the callback with a mock proof: + +```bash +curl -X POST https://yourapp.com/api/reclaim/callback \ + -H "Content-Type: application/x-www-form-urlencoded" \ + -d '{"identifier":"test","claimData":{}}' +``` + +## Error Handling + +### Backend Initialization Errors + +```javascript +app.get('/api/reclaim/config', async (req, res) => { + try { + const reclaimProofRequest = await ReclaimProofRequest.init( + process.env.RECLAIM_APP_ID, + process.env.RECLAIM_APP_SECRET, + process.env.RECLAIM_PROVIDER_ID + ); + + // ... rest of code + } catch (error) { + console.error('SDK initialization failed:', error); + + if (error.message.includes('Invalid credentials')) { + return res.status(401).json({ error: 'Invalid API credentials' }); + } + + if (error.message.includes('Provider not found')) { + return res.status(404).json({ error: 'Provider not configured' }); + } + + return res.status(500).json({ error: 'Failed to initialize SDK' }); + } +}); +``` + +### Proof Verification Errors + +```javascript +app.post('/api/reclaim/callback', async (req, res) => { + try { + const proof = parseProof(req.body); + + if (!proof || !proof.identifier) { + return res.status(400).json({ error: 'Invalid proof format' }); + } + + const isValid = await verifyProof(proof); + + if (!isValid) { + console.warn('Proof verification failed:', proof.identifier); + return res.status(400).json({ error: 'Proof verification failed' }); + } + + // Process valid proof + res.sendStatus(200); + } catch (error) { + console.error('Error processing proof:', error); + res.status(500).json({ error: 'Internal server error' }); + } +}); +``` + +## Production Checklist + +Before deploying to production: + +- [ ] APP_SECRET is in environment variables (never in code) +- [ ] .env file is in .gitignore +- [ ] HTTPS is enabled for all endpoints +- [ ] Callback URL is publicly accessible +- [ ] Backend verifies all proofs before processing +- [ ] Error handling is implemented +- [ ] Logging is set up for audit trail +- [ ] Rate limiting is configured +- [ ] Database stores verification results +- [ ] User sessions/authentication is integrated + +## Next Steps + +1. **Choose your framework** and follow the detailed guide: + - [Node.js / Express →](/js-sdk/recommended-setup/nodejs) + - [Next.js →](/js-sdk/recommended-setup/nextjs) + - [Python →](/js-sdk/recommended-setup/python) + +2. **[Backend Verification →](/js-sdk/backend-verification)** - Deep dive into proof verification + +3. **[API Reference →](/js-sdk/api-reference)** - Complete SDK documentation + +## Need Help? + +- 📖 [Troubleshooting Guide](/js-sdk/troubleshooting) +- 💬 [Community Discord](https://discord.gg/reclaim) +- 🐛 [GitHub Issues](https://github.com/reclaimprotocol/reclaim-js-sdk/issues) diff --git a/content/docs/js-sdk/recommended-setup/meta.json b/content/docs/js-sdk/recommended-setup/meta.json new file mode 100644 index 0000000..8e0fc99 --- /dev/null +++ b/content/docs/js-sdk/recommended-setup/meta.json @@ -0,0 +1,8 @@ +{ + "title": "Recommended Setup", + "pages": [ + "nodejs", + "nextjs", + "python" + ] +} diff --git a/content/docs/js-sdk/recommended-setup/nextjs.mdx b/content/docs/js-sdk/recommended-setup/nextjs.mdx new file mode 100644 index 0000000..9a5dcd2 --- /dev/null +++ b/content/docs/js-sdk/recommended-setup/nextjs.mdx @@ -0,0 +1,603 @@ +--- +title: Next.js Setup +description: Production-ready Reclaim Protocol integration with Next.js App Router and API routes +--- + + +**✅ Full-Stack Next.js Integration** + +Leverage Next.js API routes for secure backend initialization while keeping your frontend code clean and simple. Perfect for modern full-stack applications. + + +## Prerequisites + +- Next.js 13+ (App Router or Pages Router) +- API credentials from [Reclaim Developer Portal](/api-key) + +## Installation + +Install the Reclaim JavaScript SDK: + +import { Tab, Tabs } from 'fumadocs-ui/components/tabs'; + + +```bash tab="npm" +npm install @reclaimprotocol/js-sdk +``` + +```bash tab="yarn" +yarn add @reclaimprotocol/js-sdk +``` + +```bash tab="pnpm" +pnpm add @reclaimprotocol/js-sdk +``` + + +## Project Structure + +``` +nextjs-reclaim-app/ +├── .env.local # Environment variables (not in git!) +├── app/ # App Router (Next.js 13+) +│ ├── api/ +│ │ └── reclaim/ +│ │ ├── config/ +│ │ │ └── route.js +│ │ └── callback/ +│ │ └── route.js +│ ├── verify/ +│ │ └── page.jsx +│ └── layout.jsx +└── components/ + └── ReclaimButton.jsx +``` + +Or for Pages Router: + +``` +nextjs-reclaim-app/ +├── .env.local +├── pages/ +│ ├── api/ +│ │ └── reclaim/ +│ │ ├── config.js +│ │ └── callback.js +│ └── verify.jsx +└── components/ + └── ReclaimButton.jsx +``` + +## Environment Setup + +Create `.env.local` in your project root: + +```bash +# .env.local - Never commit this file! +RECLAIM_APP_ID=your_app_id_here +RECLAIM_APP_SECRET=your_app_secret_here +RECLAIM_PROVIDER_ID=your_provider_id_here + +# For local development +NEXT_PUBLIC_BASE_URL=http://localhost:3000 + +# For production (Vercel automatically sets this) +# NEXT_PUBLIC_BASE_URL=https://yourapp.com +``` + + +**Next.js Environment Variables** + +- Variables without `NEXT_PUBLIC_` prefix are server-side only (perfect for secrets!) +- Variables with `NEXT_PUBLIC_` prefix are exposed to the browser +- Never add `NEXT_PUBLIC_` to `RECLAIM_APP_SECRET` + + +## Backend API Routes + +### App Router (Next.js 13+) + +#### Config Route: `app/api/reclaim/config/route.js` + +```javascript +import { NextResponse } from 'next/server'; +import { ReclaimProofRequest } from '@reclaimprotocol/js-sdk'; + +export async function GET(request) { + try { + // Initialize SDK with server-side environment variables (secure) + const reclaimProofRequest = await ReclaimProofRequest.init( + process.env.RECLAIM_APP_ID, + process.env.RECLAIM_APP_SECRET, + process.env.RECLAIM_PROVIDER_ID + ); + + // Get base URL (Vercel sets this automatically in production) + const baseUrl = process.env.NEXT_PUBLIC_BASE_URL || + process.env.VERCEL_URL ? `https://${process.env.VERCEL_URL}` : + 'http://localhost:3000'; + + // Set callback URL + reclaimProofRequest.setAppCallbackUrl(`${baseUrl}/api/reclaim/callback`); + + // Convert to JSON string (safe for client) + const config = reclaimProofRequest.toJsonString(); + + return NextResponse.json({ + success: true, + reclaimProofRequestConfig: config + }); + } catch (error) { + console.error('Error generating config:', error); + + return NextResponse.json( + { + success: false, + error: error.message || 'Failed to generate config' + }, + { status: 500 } + ); + } +} +``` + +#### Callback Route: `app/api/reclaim/callback/route.js` + +```javascript +import { NextResponse } from 'next/server'; +import { verifyProof } from '@reclaimprotocol/js-sdk'; + +export async function POST(request) { + try { + // Get the raw body as text + const body = await request.text(); + + // Decode and parse the proof + const decodedBody = decodeURIComponent(body); + const proof = JSON.parse(decodedBody); + + console.log('Received proof:', proof.identifier); + + // Verify the proof cryptographically + const isValid = await verifyProof(proof); + + if (!isValid) { + console.error('Proof verification failed'); + return NextResponse.json( + { success: false, error: 'Proof verification failed' }, + { status: 400 } + ); + } + + console.log('✅ Proof verified successfully'); + + // YOUR BUSINESS LOGIC HERE + // Examples: + // - Save to database + // - Update user record + // - Trigger webhooks + + // Example with database (pseudo-code): + // await db.verifications.create({ + // proofId: proof.identifier, + // verifiedAt: new Date(proof.timestampS * 1000), + // proofData: proof + // }); + + return NextResponse.json({ + success: true, + message: 'Proof verified successfully' + }); + } catch (error) { + console.error('Error processing proof:', error); + + return NextResponse.json( + { success: false, error: 'Failed to process proof' }, + { status: 500 } + ); + } +} +``` + +### Pages Router (Next.js 12 and earlier) + +#### Config API: `pages/api/reclaim/config.js` + +```javascript +import { ReclaimProofRequest } from '@reclaimprotocol/js-sdk'; + +export default async function handler(req, res) { + if (req.method !== 'GET') { + return res.status(405).json({ error: 'Method not allowed' }); + } + + try { + const reclaimProofRequest = await ReclaimProofRequest.init( + process.env.RECLAIM_APP_ID, + process.env.RECLAIM_APP_SECRET, + process.env.RECLAIM_PROVIDER_ID + ); + + const baseUrl = process.env.NEXT_PUBLIC_BASE_URL || + `https://${req.headers.host}`; + + reclaimProofRequest.setAppCallbackUrl(`${baseUrl}/api/reclaim/callback`); + + const config = reclaimProofRequest.toJsonString(); + + return res.status(200).json({ + success: true, + reclaimProofRequestConfig: config + }); + } catch (error) { + console.error('Error generating config:', error); + return res.status(500).json({ + success: false, + error: error.message || 'Failed to generate config' + }); + } +} +``` + +#### Callback API: `pages/api/reclaim/callback.js` + +```javascript +import { verifyProof } from '@reclaimprotocol/js-sdk'; + +export const config = { + api: { + bodyParser: false, // Disable default body parser + }, +}; + +export default async function handler(req, res) { + if (req.method !== 'POST') { + return res.status(405).json({ error: 'Method not allowed' }); + } + + try { + // Read raw body + const chunks = []; + for await (const chunk of req) { + chunks.push(chunk); + } + const body = Buffer.concat(chunks).toString(); + + // Decode and parse + const decodedBody = decodeURIComponent(body); + const proof = JSON.parse(decodedBody); + + console.log('Received proof:', proof.identifier); + + // Verify proof + const isValid = await verifyProof(proof); + + if (!isValid) { + return res.status(400).json({ + success: false, + error: 'Proof verification failed' + }); + } + + console.log('✅ Proof verified'); + + // YOUR BUSINESS LOGIC HERE + + return res.status(200).json({ + success: true, + message: 'Proof verified successfully' + }); + } catch (error) { + console.error('Error processing proof:', error); + return res.status(500).json({ + success: false, + error: 'Failed to process proof' + }); + } +} +``` + +## Frontend Components + +### Reusable Verification Component + +Create `components/ReclaimButton.jsx`: + +```jsx +'use client'; // Required for App Router + +import { useState } from 'react'; +import { ReclaimProofRequest } from '@reclaimprotocol/js-sdk'; + +export default function ReclaimButton({ onSuccess, onError }) { + const [isLoading, setIsLoading] = useState(false); + + const handleVerification = async () => { + try { + setIsLoading(true); + + // Fetch config from our API route + const response = await fetch('/api/reclaim/config'); + + if (!response.ok) { + throw new Error('Failed to fetch config'); + } + + const { reclaimProofRequestConfig } = await response.json(); + + // Reconstruct proof request + const reclaimProofRequest = await ReclaimProofRequest.fromJsonString( + reclaimProofRequestConfig + ); + + // Trigger verification flow + await reclaimProofRequest.triggerReclaimFlow(); + + // Listen for results + await reclaimProofRequest.startSession({ + onSuccess: (proofs) => { + console.log('Verification successful:', proofs); + setIsLoading(false); + onSuccess?.(proofs); + }, + onError: (error) => { + console.error('Verification failed:', error); + setIsLoading(false); + onError?.(error); + }, + }); + } catch (error) { + console.error('Error:', error); + setIsLoading(false); + onError?.(error); + } + }; + + return ( + + ); +} +``` + +### Verification Page + +#### App Router: `app/verify/page.jsx` + +```jsx +'use client'; + +import { useState } from 'react'; +import ReclaimButton from '@/components/ReclaimButton'; + +export default function VerifyPage() { + const [proof, setProof] = useState(null); + const [error, setError] = useState(null); + + const handleSuccess = (proofs) => { + setProof(proofs); + setError(null); + }; + + const handleError = (err) => { + setError(err.message || 'Verification failed'); + setProof(null); + }; + + return ( +
+
+

Verify Your Identity

+

+ Use Reclaim Protocol to verify your credentials securely +

+ + + + {error && ( +
+

❌ {error}

+
+ )} + + {proof && ( +
+

+ ✅ Verification Successful! +

+

+ Proof ID: {proof.identifier} +

+
+ + View full proof + +
+                {JSON.stringify(proof, null, 2)}
+              
+
+
+ )} +
+
+ ); +} +``` + +#### Pages Router: `pages/verify.jsx` + +```jsx +import { useState } from 'react'; +import ReclaimButton from '@/components/ReclaimButton'; + +export default function VerifyPage() { + const [proof, setProof] = useState(null); + const [error, setError] = useState(null); + + // Same implementation as App Router version + // ... + + return ( + // Same JSX as App Router version + ); +} +``` + +## Local Development + +### 1. Install Dependencies + +```bash +npm install @reclaimprotocol/js-sdk +``` + +### 2. Set Up Environment Variables + +Create `.env.local` with your credentials (see Environment Setup above). + +### 3. Run Development Server + +```bash +npm run dev +``` + +### 4. Set Up ngrok (for callback testing) + +```bash +ngrok http 3000 +``` + +Update `.env.local` with ngrok URL: + +```bash +NEXT_PUBLIC_BASE_URL=https://abc123.ngrok.io +``` + +Restart your dev server to pick up the new URL. + +### 5. Test the Integration + +Visit `http://localhost:3000/verify` and click the verification button. + +## Deployment (Vercel) + +### 1. Push to GitHub + +```bash +git add . +git commit -m "Add Reclaim integration" +git push origin main +``` + +### 2. Deploy to Vercel + +1. Go to [vercel.com](https://vercel.com) and import your repository +2. Add environment variables in Vercel dashboard: + - `RECLAIM_APP_ID` + - `RECLAIM_APP_SECRET` + - `RECLAIM_PROVIDER_ID` + - `NEXT_PUBLIC_BASE_URL` (your Vercel URL) + +3. Deploy! + + +**Vercel Auto-Configuration** + +Vercel automatically sets `VERCEL_URL` which can be used to construct your callback URL. The code examples above handle this automatically. + + +## Database Integration Example + +### With Prisma + +```javascript +// app/api/reclaim/callback/route.js +import { NextResponse } from 'next/server'; +import { verifyProof } from '@reclaimprotocol/js-sdk'; +import { prisma } from '@/lib/prisma'; + +export async function POST(request) { + try { + const body = await request.text(); + const proof = JSON.parse(decodeURIComponent(body)); + + const isValid = await verifyProof(proof); + + if (!isValid) { + return NextResponse.json( + { error: 'Invalid proof' }, + { status: 400 } + ); + } + + // Save to database + await prisma.verification.create({ + data: { + proofId: proof.identifier, + provider: JSON.parse(proof.claimData.context).extractedParameters.providerName, + verifiedAt: new Date(proof.timestampS * 1000), + proofData: proof, + }, + }); + + return NextResponse.json({ success: true }); + } catch (error) { + console.error('Error:', error); + return NextResponse.json( + { error: 'Internal server error' }, + { status: 500 } + ); + } +} +``` + +## Common Issues + +### 1. Environment Variables Not Loading + +**Problem**: `process.env.RECLAIM_APP_ID` is undefined. + +**Solution**: +- Ensure file is named `.env.local` (not `.env`) +- Restart dev server after changing `.env.local` +- For server-side vars, don't use `NEXT_PUBLIC_` prefix + +### 2. Callback Route Not Receiving Data + +**Problem**: Callback endpoint returns 404 or doesn't process proof. + +**Solutions**: +- Verify route file location matches URL structure +- For App Router: `app/api/reclaim/callback/route.js` +- For Pages Router: `pages/api/reclaim/callback.js` +- Check `bodyParser` is disabled for Pages Router +- Use ngrok for local development + +### 3. CORS Issues + +**Problem**: Frontend can't call API routes. + +**Solution**: Next.js API routes automatically handle CORS for same-origin requests. If calling from external domain, add CORS headers: + +```javascript +export async function GET(request) { + const response = NextResponse.json({ data }); + + response.headers.set('Access-Control-Allow-Origin', '*'); + response.headers.set('Access-Control-Allow-Methods', 'GET, POST'); + + return response; +} +``` + +## Next Steps + +- **[Client Integration →](/js-sdk/client-integration/nextjs)** - Advanced patterns and hooks +- **[Backend Verification →](/js-sdk/backend-verification/nodejs)** - Deep dive into verification +- **[API Reference →](/js-sdk/api-reference)** - Complete SDK documentation +- **[Troubleshooting →](/js-sdk/troubleshooting)** - Common issues and solutions diff --git a/content/docs/js-sdk/recommended-setup/nodejs.mdx b/content/docs/js-sdk/recommended-setup/nodejs.mdx new file mode 100644 index 0000000..16a4c40 --- /dev/null +++ b/content/docs/js-sdk/recommended-setup/nodejs.mdx @@ -0,0 +1,617 @@ +--- +title: Node.js / Express Setup +description: Production-ready Reclaim Protocol integration with Node.js/Express backend and React frontend +--- + + +**✅ Production-Ready Full-Stack Example** + +This guide shows a complete implementation with Express.js backend (secure SDK initialization) and React frontend (UI and verification flow). + + +## Prerequisites + +- Node.js 14.x or later +- Express.js project set up +- API credentials from [Reclaim Developer Portal](/api-key) + +## Installation + +Install the Reclaim JavaScript SDK in your backend: + +import { Tab, Tabs } from 'fumadocs-ui/components/tabs'; + + +```bash tab="npm" +npm install @reclaimprotocol/js-sdk +``` + +```bash tab="yarn" +yarn add @reclaimprotocol/js-sdk +``` + +```bash tab="pnpm" +pnpm add @reclaimprotocol/js-sdk +``` + + +## Project Structure + +``` +your-app/ +├── backend/ +│ ├── server.js # Express server +│ ├── .env # Environment variables (not in git!) +│ └── package.json +└── frontend/ + ├── src/ + │ ├── components/ + │ │ └── ReclaimVerify.jsx + │ └── App.jsx + └── package.json +``` + +## Backend Implementation + +### Step 1: Environment Setup + +Create `.env` file in your backend directory: + +```bash +# .env +RECLAIM_APP_ID=your_app_id_here +RECLAIM_APP_SECRET=your_app_secret_here +RECLAIM_PROVIDER_ID=your_provider_id_here + +# Your backend base URL (use ngrok for local development) +BASE_URL=https://yourapp.com +# For local development: +# BASE_URL=https:// 123abc.ngrok.io + +PORT=3000 +``` + +### Step 2: Install Dependencies + +```bash +cd backend +npm install express dotenv @reclaimprotocol/js-sdk cors +``` + +### Step 3: Complete Express Server + +Create `server.js`: + +```javascript +const express = require('express'); +const cors = require('cors'); +const { ReclaimProofRequest, verifyProof } = require('@reclaimprotocol/js-sdk'); +require('dotenv').config(); + +const app = express(); +const PORT = process.env.PORT || 3000; +const BASE_URL = process.env.BASE_URL; + +// Middleware +app.use(cors()); +app.use(express.json()); + +// IMPORTANT: Use express.text() to parse the URL-encoded proof from callback +app.use(express.text({ type: '*/*', limit: '50mb' })); + +// Health check endpoint +app.get('/health', (req, res) => { + res.json({ status: 'ok', timestamp: new Date().toISOString() }); +}); + +/** + * Endpoint 1: Generate SDK Configuration + * Purpose: Initialize SDK securely on backend and return safe config to frontend + */ +app.get('/api/reclaim/config', async (req, res) => { + try { + // Initialize SDK with credentials from environment (secure) + const reclaimProofRequest = await ReclaimProofRequest.init( + process.env.RECLAIM_APP_ID, + process.env.RECLAIM_APP_SECRET, + process.env.RECLAIM_PROVIDER_ID + ); + + // Set the callback URL where proofs will be sent + reclaimProofRequest.setAppCallbackUrl(`${BASE_URL}/api/reclaim/callback`); + + // Convert to JSON string (safe to send to frontend - no secrets) + const reclaimProofRequestConfig = reclaimProofRequest.toJsonString(); + + console.log('✅ Generated Reclaim config for frontend'); + + return res.json({ + success: true, + reclaimProofRequestConfig + }); + } catch (error) { + console.error('❌ Error generating request config:', error); + + if (error.message.includes('Invalid credentials')) { + return res.status(401).json({ + success: false, + error: 'Invalid API credentials. Check your .env file.' + }); + } + + if (error.message.includes('Provider')) { + return res.status(404).json({ + success: false, + error: 'Provider not found. Verify PROVIDER_ID in your .env file.' + }); + } + + return res.status(500).json({ + success: false, + error: 'Failed to generate request config' + }); + } +}); + +/** + * Endpoint 2: Receive and Verify Proofs (Callback) + * Purpose: Receive proofs from Reclaim Protocol and verify them + * Called by Reclaim Protocol after user completes verification + */ +app.post('/api/reclaim/callback', async (req, res) => { + try { + // Decode the URL-encoded proof object + const decodedBody = decodeURIComponent(req.body); + const proof = JSON.parse(decodedBody); + + console.log('📨 Received proof from Reclaim:', proof.identifier); + + // Verify the proof cryptographically + const isValid = await verifyProof(proof); + + if (!isValid) { + console.error('❌ Proof verification failed:', proof.identifier); + return res.status(400).json({ + success: false, + error: 'Invalid proof - verification failed' + }); + } + + console.log('✅ Proof verified successfully:', proof.identifier); + + // Extract verified data from proof + const verifiedData = { + identifier: proof.identifier, + provider: JSON.parse(proof.claimData.context).extractedParameters.providerName, + timestamp: proof.timestampS, + // Add more fields as needed based on your provider + }; + + console.log('📦 Verified data:', verifiedData); + + // ✅ YOUR BUSINESS LOGIC HERE + // Examples: + // - Save proof to database + // - Update user verification status + // - Trigger downstream workflows + // - Send notifications + + // Example: Save to database (pseudo-code) + // await db.verifications.create({ + // userId: extractUserIdFromProof(proof), + // proofId: proof.identifier, + // provider: verifiedData.provider, + // verifiedAt: new Date(proof.timestampS * 1000), + // proofData: proof + // }); + + return res.status(200).json({ + success: true, + message: 'Proof verified and processed' + }); + } catch (error) { + console.error('❌ Error processing proof:', error); + + if (error instanceof SyntaxError) { + return res.status(400).json({ + success: false, + error: 'Invalid proof format - JSON parsing failed' + }); + } + + return res.status(500).json({ + success: false, + error: 'Internal server error while processing proof' + }); + } +}); + +// Start server +app.listen(PORT, () => { + console.log(`🚀 Reclaim backend server running on port ${PORT}`); + console.log(`📍 Base URL: ${BASE_URL}`); + console.log(`🔗 Config endpoint: ${BASE_URL}/api/reclaim/config`); + console.log(`🔗 Callback endpoint: ${BASE_URL}/api/reclaim/callback`); + + // Validate environment variables + if (!process.env.RECLAIM_APP_ID || !process.env.RECLAIM_APP_SECRET) { + console.error('⚠️ WARNING: Missing RECLAIM_APP_ID or RECLAIM_APP_SECRET in .env'); + } +}); +``` + + +**Important Middleware Notes** + +1. **Do NOT use `express.urlencoded()`** - It conflicts with `express.text()` and prevents proper proof parsing +2. **Use `express.text()`** - The proof from Reclaim is sent as URL-encoded text +3. Order matters - `express.text()` must come after `express.json()` if you need both + + +### Step 4: Run the Backend + +```bash +node server.js +``` + +You should see: +``` +🚀 Reclaim backend server running on port 3000 +📍 Base URL: https://yourapp.com +🔗 Config endpoint: https://yourapp.com/api/reclaim/config +🔗 Callback endpoint: https://yourapp.com/api/reclaim/callback +``` + +## Frontend Implementation (React) + +### Step 1: Create Verification Component + +Create `frontend/src/components/ReclaimVerify.jsx`: + +```jsx +import { useState } from 'react'; +import { ReclaimProofRequest } from '@reclaimprotocol/js-sdk'; +import './ReclaimVerify.css'; // Optional styling + +const BACKEND_URL = 'http://localhost:3000'; // Change for production + +function ReclaimVerify() { + const [proofs, setProofs] = useState(null); + const [isLoading, setIsLoading] = useState(false); + const [error, setError] = useState(null); + + const handleVerification = async () => { + try { + setIsLoading(true); + setError(null); + setProofs(null); + + console.log('🔄 Fetching config from backend...'); + + // Step 1: Fetch secure configuration from backend + const response = await fetch(`${BACKEND_URL}/api/reclaim/config`); + + if (!response.ok) { + throw new Error('Failed to fetch config from backend'); + } + + const { reclaimProofRequestConfig } = await response.json(); + + console.log('✅ Config received, initializing SDK...'); + + // Step 2: Reconstruct ReclaimProofRequest from config + const reclaimProofRequest = await ReclaimProofRequest.fromJsonString( + reclaimProofRequestConfig + ); + + console.log('🚀 Triggering verification flow...'); + + // Step 3: Trigger the verification flow + // This automatically shows QR code on desktop or redirects on mobile + await reclaimProofRequest.triggerReclaimFlow(); + + console.log('👂 Listening for proof...'); + + // Step 4: Start session and listen for proof + await reclaimProofRequest.startSession({ + onSuccess: (proofs) => { + console.log('✅ Verification successful!', proofs); + setProofs(proofs); + setIsLoading(false); + + // Note: Proof is also sent to your backend callback + // You can poll your backend API to check verification status + }, + onError: (error) => { + console.error('❌ Verification failed:', error); + setError(error.message || 'Verification failed'); + setIsLoading(false); + }, + }); + } catch (error) { + console.error('❌ Error:', error); + setError(error.message || 'An error occurred'); + setIsLoading(false); + } + }; + + return ( +
+

Verify with Reclaim Protocol

+

Click the button below to start verification

+ + + + {error && ( +
+

❌ Error

+

{error}

+
+ )} + + {proofs && ( +
+

✅ Verification Successful!

+
+

Proof ID: {proofs.identifier}

+

Timestamp: {new Date(proofs.timestampS * 1000).toLocaleString()}

+ +
+ View Full Proof +
{JSON.stringify(proofs, null, 2)}
+
+
+
+ )} +
+ ); +} + +export default ReclaimVerify; +``` + +### Step 2: Optional Styling + +Create `frontend/src/components/ReclaimVerify.css`: + +```css +.reclaim-verify { + max-width: 600px; + margin: 0 auto; + padding: 2rem; + font-family: system-ui, -apple-system, sans-serif; +} + +.verify-button { + background: #0070f3; + color: white; + padding: 14px 28px; + border: none; + border-radius: 8px; + font-size: 16px; + font-weight: 600; + cursor: pointer; + transition: all 0.2s; + margin: 1rem 0; +} + +.verify-button:hover:not(:disabled) { + background: #0051cc; + transform: translateY(-1px); +} + +.verify-button:disabled { + background: #ccc; + cursor: not-allowed; + transform: none; +} + +.error-message { + background: #fee; + border: 2px solid #fcc; + padding: 1rem; + border-radius: 8px; + color: #c33; + margin-top: 1rem; +} + +.success-message { + background: #efe; + border: 2px solid #cfc; + padding: 1rem; + border-radius: 8px; + margin-top: 1rem; +} + +.proof-details { + margin-top: 1rem; +} + +.proof-details p { + margin: 0.5rem 0; +} + +.proof-details pre { + background: white; + padding: 1rem; + border-radius: 4px; + overflow-x: auto; + font-size: 12px; + max-height: 400px; + overflow-y: auto; +} + +details { + margin-top: 1rem; + cursor: pointer; +} + +summary { + font-weight: 600; + padding: 0.5rem; + background: rgba(0, 0, 0, 0.05); + border-radius: 4px; +} +``` + +### Step 3: Use in Your App + +```jsx +// frontend/src/App.jsx +import ReclaimVerify from './components/ReclaimVerify'; + +function App() { + return ( +
+

My App with Reclaim Verification

+ +
+ ); +} + +export default App; +``` + +## Local Development Setup + +### 1. Start Backend with ngrok + +Terminal 1 - Start Express server: +```bash +cd backend +node server.js +``` + +Terminal 2 - Start ngrok tunnel: +```bash +ngrok http 3000 +``` + +Copy the ngrok URL (e.g., `https://abc123.ngrok.io`) and update your `.env`: + +```bash +BASE_URL=https://abc123.ngrok.io +``` + +Restart your Express server to pick up the new BASE_URL. + +### 2. Start Frontend + +Terminal 3: +```bash +cd frontend +npm start +``` + +Your app should open at `http://localhost:3000` (or another port if 3000 is taken). + +## Testing the Integration + +### 1. Test Backend Config Endpoint + +```bash +curl http://localhost:3000/api/reclaim/config +``` + +Expected response: +```json +{ + "success": true, + "reclaimProofRequestConfig": "{...}" +} +``` + +### 2. Test Full Flow + +1. Open your React app in browser +2. Click "Start Verification" +3. On desktop: QR code modal should appear +4. Scan with mobile device and complete verification +5. Check backend logs for proof reception +6. Frontend should show success message + +## Production Deployment + +### Environment Variables + +For production, set these environment variables on your hosting platform: + +```bash +RECLAIM_APP_ID=your_production_app_id +RECLAIM_APP_SECRET=your_production_app_secret +RECLAIM_PROVIDER_ID=your_provider_id +BASE_URL=https://api.yourapp.com +PORT=3000 +NODE_ENV=production +``` + +### Frontend API URL + +Update the BACKEND_URL in your React component: + +```jsx +const BACKEND_URL = process.env.REACT_APP_BACKEND_URL || 'http://localhost:3000'; +``` + +Set in `.env.production`: +```bash +REACT_APP_BACKEND_URL=https://api.yourapp.com +``` + +## Common Issues + +### 1. CORS Errors + +**Problem**: Frontend can't reach backend due to CORS. + +**Solution**: Ensure CORS is properly configured: + +```javascript +const cors = require('cors'); + +app.use(cors({ + origin: process.env.NODE_ENV === 'production' + ? 'https://yourapp.com' + : 'http://localhost:3000', + credentials: true +})); +``` + +### 2. Callback Not Reached + +**Problem**: Backend callback endpoint not receiving proofs. + +**Solutions**: +- Verify `BASE_URL` is publicly accessible (use ngrok for local dev) +- Check ngrok tunnel is running +- Ensure callback URL doesn't have trailing slash +- Check server logs for incoming requests + +### 3. Proof Parsing Fails + +**Problem**: `JSON.parse()` fails in callback endpoint. + +**Solution**: Ensure you're using `express.text()` middleware and decoding properly: + +```javascript +app.use(express.text({ type: '*/*', limit: '50mb' })); + +app.post('/api/reclaim/callback', async (req, res) => { + const decodedBody = decodeURIComponent(req.body); + const proof = JSON.parse(decodedBody); + // ... +}); +``` + +## Next Steps + +- **[Backend Verification →](/js-sdk/backend-verification/nodejs)** - Deep dive into proof verification +- **[Client Integration →](/js-sdk/client-integration/react)** - Advanced frontend patterns +- **[API Reference →](/js-sdk/api-reference)** - Complete SDK documentation +- **[Troubleshooting →](/js-sdk/troubleshooting)** - Common issues and solutions diff --git a/content/docs/js-sdk/recommended-setup/python.mdx b/content/docs/js-sdk/recommended-setup/python.mdx new file mode 100644 index 0000000..5ad409d --- /dev/null +++ b/content/docs/js-sdk/recommended-setup/python.mdx @@ -0,0 +1,705 @@ +--- +title: Python Setup +description: Production-ready Reclaim Protocol integration with Python backend (FastAPI/Django) and JavaScript frontend +--- + + +**✅ Python Backend Integration** + +Use Python for backend verification while leveraging the JavaScript SDK on the frontend. Perfect for Python-based applications and data science workflows. + + +## Prerequisites + +- Python 3.8 or later +- pip or pip3 package manager +- JavaScript SDK for frontend +- API credentials from [Reclaim Developer Portal](/api-key) + +## Installation + +Install the Reclaim Python SDK for your backend: + +```bash +pip install reclaim-python-sdk +``` + +## Project Structure + +``` +python-reclaim-app/ +├── backend/ +│ ├── main.py # FastAPI app +│ ├── requirements.txt +│ └── .env # Environment variables (not in git!) +└── frontend/ + ├── index.html + ├── app.js + └── package.json +``` + +## Backend Implementation (FastAPI) + +### Step 1: Install Dependencies + +```bash +pip install fastapi uvicorn reclaim-python-sdk python-dotenv +``` + +Create `requirements.txt`: + +``` +fastapi>=0.104.0 +uvicorn>=0.24.0 +reclaim-python-sdk>=0.1.0 +python-dotenv>=1.0.0 +``` + +### Step 2: Environment Setup + +Create `.env` file: + +```bash +# .env - Never commit this file! +RECLAIM_APP_ID=your_app_id_here +RECLAIM_APP_SECRET=your_app_secret_here +RECLAIM_PROVIDER_ID=your_provider_id_here + +# Your backend base URL (use ngrok for local development) +BASE_URL=https://yourapp.com +# For local: BASE_URL=https://abc123.ngrok.io + +PORT=8000 +``` + +### Step 3: Complete FastAPI Server + +Create `main.py`: + +```python +from fastapi import FastAPI, Request +from fastapi.middleware.cors import CORSMiddleware +from reclaim_python_sdk import ReclaimProofRequest, verify_proof, Proof +import uvicorn +import os +import json +from urllib.parse import unquote +from dotenv import load_dotenv + +# Load environment variables +load_dotenv() + +app = FastAPI( + title="Reclaim Protocol API", + description="Backend for Reclaim Protocol verification", + version="1.0.0" +) + +# CORS middleware (configure for your frontend domain) +app.add_middleware( + CORSMiddleware, + allow_origins=[ + "http://localhost:3000", + "http://localhost:5173", # Vite default + os.getenv("FRONTEND_URL", "*") + ], + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], +) + +# Environment variables +RECLAIM_APP_ID = os.getenv("RECLAIM_APP_ID") +RECLAIM_APP_SECRET = os.getenv("RECLAIM_APP_SECRET") +RECLAIM_PROVIDER_ID = os.getenv("RECLAIM_PROVIDER_ID") +BASE_URL = os.getenv("BASE_URL", "http://localhost:8000") + +@app.get("/health") +async def health_check(): + """Health check endpoint""" + return { + "status": "ok", + "service": "reclaim-backend", + "base_url": BASE_URL + } + +@app.get("/api/reclaim/config") +async def generate_config(): + """ + Generate SDK configuration for frontend + Initializes SDK securely on backend and returns safe config + """ + try: + # Validate environment variables + if not all([RECLAIM_APP_ID, RECLAIM_APP_SECRET, RECLAIM_PROVIDER_ID]): + return { + "success": False, + "error": "Missing required environment variables" + }, 500 + + # Initialize SDK with credentials (secure - server-side only) + reclaim_proof_request = await ReclaimProofRequest.init( + RECLAIM_APP_ID, + RECLAIM_APP_SECRET, + RECLAIM_PROVIDER_ID + ) + + # Set callback URL where proofs will be sent + reclaim_proof_request.set_app_callback_url( + f"{BASE_URL}/api/reclaim/callback" + ) + + # Convert to JSON string (safe for frontend - no secrets) + config = reclaim_proof_request.to_json_string() + + print(f"✅ Generated Reclaim config for frontend") + + return { + "success": True, + "reclaimProofRequestConfig": config + } + + except Exception as error: + print(f"❌ Error generating request config: {error}") + + if "credentials" in str(error).lower(): + return { + "success": False, + "error": "Invalid API credentials. Check your .env file." + }, 401 + + if "provider" in str(error).lower(): + return { + "success": False, + "error": "Provider not found. Verify PROVIDER_ID in .env file." + }, 404 + + return { + "success": False, + "error": "Failed to generate request config" + }, 500 + +@app.post("/api/reclaim/callback") +async def receive_proofs(request: Request): + """ + Receive and verify proofs from Reclaim Protocol + Called by Reclaim Protocol after user completes verification + """ + try: + # Get raw body content + body = await request.body() + + # Decode bytes to string + body_str = body.decode('utf-8') + + # URL decode + body_str = unquote(body_str) + + # Parse JSON + parsed_data = json.loads(body_str) + + print(f"📨 Received proof: {parsed_data.get('identifier', 'unknown')}") + + # Convert to Proof object + proof = Proof.from_json(parsed_data) + + # Verify the proof cryptographically + result = await verify_proof(proof) + + if not result: + print(f"❌ Proof verification failed") + return { + "status": "failed", + "message": "Proof verification failed" + }, 400 + + print(f"✅ Proof verified successfully") + + # Extract verified data from proof + verified_data = { + "identifier": proof.identifier, + "timestamp": proof.timestampS, + "provider": proof.claimData.provider, + # Add more fields as needed + } + + print(f"📦 Verified data: {verified_data}") + + # ✅ YOUR BUSINESS LOGIC HERE + # Examples: + # - Save proof to database + # - Update user verification status + # - Trigger downstream workflows + # - Send notifications + + # Example: Save to database (pseudo-code) + # await db.verifications.create({ + # "proof_id": proof.identifier, + # "verified_at": datetime.fromtimestamp(proof.timestampS), + # "proof_data": parsed_data + # }) + + return { + "status": "success", + "message": "Proof verified and processed" + } + + except json.JSONDecodeError as error: + print(f"❌ JSON parsing error: {error}") + return { + "status": "failed", + "message": "Invalid proof format - JSON parsing failed" + }, 400 + + except Exception as error: + print(f"❌ Error processing proof: {error}") + return { + "status": "failed", + "message": "Internal server error while processing proof" + }, 500 + +if __name__ == "__main__": + port = int(os.getenv("PORT", 8000)) + + print(f"🚀 Starting Reclaim backend server on port {port}") + print(f"📍 Base URL: {BASE_URL}") + print(f"🔗 Config endpoint: {BASE_URL}/api/reclaim/config") + print(f"🔗 Callback endpoint: {BASE_URL}/api/reclaim/callback") + + if not all([RECLAIM_APP_ID, RECLAIM_APP_SECRET]): + print("⚠️ WARNING: Missing RECLAIM_APP_ID or RECLAIM_APP_SECRET in .env") + + uvicorn.run( + "main:app", + host="0.0.0.0", + port=port, + reload=True # Disable in production + ) +``` + +### Step 4: Run the Server + +```bash +python main.py +``` + +Or with uvicorn directly: + +```bash +uvicorn main:app --reload --port 8000 +``` + +You should see: + +``` +🚀 Starting Reclaim backend server on port 8000 +📍 Base URL: https://yourapp.com +🔗 Config endpoint: https://yourapp.com/api/reclaim/config +🔗 Callback endpoint: https://yourapp.com/api/reclaim/callback +INFO: Uvicorn running on http://0.0.0.0:8000 +``` + +## Backend Implementation (Django) + +### Step 1: Install Dependencies + +```bash +pip install django reclaim-python-sdk python-dotenv djangorestframework +``` + +### Step 2: Create Django Views + +Create `views.py`: + +```python +from django.http import JsonResponse +from django.views.decorators.csrf import csrf_exempt +from django.views.decorators.http import require_http_methods +from reclaim_python_sdk import ReclaimProofRequest, verify_proof, Proof +import json +import os +from urllib.parse import unquote +from dotenv import load_dotenv + +load_dotenv() + +RECLAIM_APP_ID = os.getenv("RECLAIM_APP_ID") +RECLAIM_APP_SECRET = os.getenv("RECLAIM_APP_SECRET") +RECLAIM_PROVIDER_ID = os.getenv("RECLAIM_PROVIDER_ID") +BASE_URL = os.getenv("BASE_URL", "http://localhost:8000") + +@require_http_methods(["GET"]) +async def generate_config(request): + """Generate SDK configuration for frontend""" + try: + reclaim_proof_request = await ReclaimProofRequest.init( + RECLAIM_APP_ID, + RECLAIM_APP_SECRET, + RECLAIM_PROVIDER_ID + ) + + reclaim_proof_request.set_app_callback_url( + f"{BASE_URL}/api/reclaim/callback" + ) + + config = reclaim_proof_request.to_json_string() + + return JsonResponse({ + "success": True, + "reclaimProofRequestConfig": config + }) + + except Exception as error: + return JsonResponse({ + "success": False, + "error": str(error) + }, status=500) + +@csrf_exempt +@require_http_methods(["POST"]) +async def receive_proofs(request): + """Receive and verify proofs from Reclaim Protocol""" + try: + body_str = request.body.decode('utf-8') + body_str = unquote(body_str) + parsed_data = json.loads(body_str) + + proof = Proof.from_json(parsed_data) + + result = await verify_proof(proof) + + if not result: + return JsonResponse({ + "status": "failed", + "message": "Proof verification failed" + }, status=400) + + # YOUR BUSINESS LOGIC HERE + + return JsonResponse({ + "status": "success", + "message": "Proof verified successfully" + }) + + except Exception as error: + return JsonResponse({ + "status": "failed", + "message": str(error) + }, status=500) +``` + +### Step 3: Configure URLs + +Add to `urls.py`: + +```python +from django.urls import path +from . import views + +urlpatterns = [ + path('api/reclaim/config', views.generate_config, name='reclaim_config'), + path('api/reclaim/callback', views.receive_proofs, name='reclaim_callback'), +] +``` + +## Frontend Implementation + +### JavaScript Frontend (Vanilla JS) + +Create `frontend/index.html`: + +```html + + + + + + Reclaim Verification + + + +

Reclaim Verification

+ +
+ + + + +``` + +## Local Development Setup + +### 1. Start Python Backend with ngrok + +Terminal 1 - Start FastAPI server: + +```bash +cd backend +python main.py +``` + +Terminal 2 - Start ngrok tunnel: + +```bash +ngrok http 8000 +``` + +Copy the ngrok URL and update `.env`: + +```bash +BASE_URL=https://abc123.ngrok.io +``` + +Restart your Python server. + +### 2. Start Frontend + +Terminal 3: + +```bash +cd frontend +python -m http.server 3000 +# or +npx http-server -p 3000 +``` + +Visit `http://localhost:3000` and test the verification. + +## Testing the Integration + +### Test Backend Config Endpoint + +```bash +curl http://localhost:8000/api/reclaim/config +``` + +Expected response: + +```json +{ + "success": true, + "reclaimProofRequestConfig": "{...}" +} +``` + +### Test Health Endpoint + +```bash +curl http://localhost:8000/health +``` + +## Production Deployment + +### Deploy on Railway/Render + +1. Add `requirements.txt` to your project +2. Create `Procfile`: + +``` +web: uvicorn main:app --host 0.0.0.0 --port $PORT +``` + +3. Set environment variables in platform dashboard: + - `RECLAIM_APP_ID` + - `RECLAIM_APP_SECRET` + - `RECLAIM_PROVIDER_ID` + - `BASE_URL` + +4. Deploy! + +### Deploy with Docker + +Create `Dockerfile`: + +```dockerfile +FROM python:3.11-slim + +WORKDIR /app + +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt + +COPY . . + +EXPOSE 8000 + +CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"] +``` + +Build and run: + +```bash +docker build -t reclaim-backend . +docker run -p 8000:8000 --env-file .env reclaim-backend +``` + +## Database Integration Example + +### With SQLAlchemy (FastAPI) + +```python +from sqlalchemy import create_engine, Column, String, DateTime, JSON +from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy.orm import sessionmaker +from datetime import datetime + +Base = declarative_base() + +class Verification(Base): + __tablename__ = "verifications" + + id = Column(String, primary_key=True) + proof_id = Column(String, unique=True) + verified_at = Column(DateTime, default=datetime.utcnow) + proof_data = Column(JSON) + +# In your callback endpoint: +@app.post("/api/reclaim/callback") +async def receive_proofs(request: Request): + # ... verification code ... + + if result: + # Save to database + db = SessionLocal() + verification = Verification( + id=str(uuid.uuid4()), + proof_id=proof.identifier, + verified_at=datetime.fromtimestamp(proof.timestampS), + proof_data=parsed_data + ) + db.add(verification) + db.commit() + db.close() + + return {"status": "success"} +``` + +## Common Issues + +### 1. ImportError: No module named 'reclaim_python_sdk' + +**Solution**: + +```bash +pip install reclaim-python-sdk +``` + +### 2. CORS Errors + +**Solution**: Configure CORS middleware properly: + +```python +app.add_middleware( + CORSMiddleware, + allow_origins=["http://localhost:3000"], # Your frontend URL + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], +) +``` + +### 3. Callback Not Receiving Data + +**Solutions**: +- Ensure `BASE_URL` is publicly accessible (use ngrok for local dev) +- Check ngrok tunnel is running +- Verify FastAPI server is running on the correct port +- Check server logs for incoming requests + +## Next Steps + +- **[Backend Verification →](/js-sdk/backend-verification/python)** - Deep dive into Python verification +- **[API Reference →](/js-sdk/api-reference)** - Complete SDK documentation +- **[Troubleshooting →](/js-sdk/troubleshooting)** - Common issues and solutions diff --git a/content/docs/js-sdk/troubleshooting.mdx b/content/docs/js-sdk/troubleshooting.mdx new file mode 100644 index 0000000..1494518 --- /dev/null +++ b/content/docs/js-sdk/troubleshooting.mdx @@ -0,0 +1,627 @@ +--- +title: Troubleshooting +description: Common issues and solutions when integrating the Reclaim JavaScript SDK +--- + +## Common Issues + +This guide covers the most common issues developers encounter when integrating the Reclaim JavaScript SDK and their solutions. + +--- + +## Installation Issues + +### Module Not Found Error + +**Problem**: `Cannot find module '@reclaimprotocol/js-sdk'` + +**Solutions**: + +1. Verify the package is installed: + ```bash + npm list @reclaimprotocol/js-sdk + ``` + +2. Reinstall the package: + ```bash + npm install @reclaimprotocol/js-sdk + ``` + +3. Clear cache and reinstall: + ```bash + rm -rf node_modules package-lock.json + npm install + ``` + +4. Check your `package.json` includes the dependency: + ```json + { + "dependencies": { + "@reclaimprotocol/js-sdk": "^latest" + } + } + ``` + +### TypeScript Type Errors + +**Problem**: TypeScript can't find type definitions + +**Solutions**: + +1. Ensure TypeScript 4.0 or later: + ```bash + npm install --save-dev typescript@latest + ``` + +2. Check `tsconfig.json` settings: + ```json + { + "compilerOptions": { + "moduleResolution": "node", + "esModuleInterop": true, + "allowSyntheticDefaultImports": true + } + } + ``` + +3. Import types explicitly: + ```typescript + import { ReclaimProofRequest, Proof } from '@reclaimprotocol/js-sdk'; + ``` + +--- + +## Initialization Issues + +### Invalid Credentials Error + +**Problem**: `Invalid credentials` or `401 Unauthorized` when initializing SDK + +**Solutions**: + +1. Verify your credentials are correct: + - Check `APP_ID` matches the one in Reclaim Developer Portal + - Verify `APP_SECRET` is correct (copy-paste to avoid typos) + - Confirm `PROVIDER_ID` is from the same application + +2. Check environment variables are loaded: + ```javascript + console.log('APP_ID:', process.env.RECLAIM_APP_ID); + console.log('APP_SECRET exists:', !!process.env.RECLAIM_APP_SECRET); + ``` + +3. Ensure `.env` file is in the correct location (project root for most frameworks) + +4. Restart your development server after changing `.env` files + +### Provider Not Found Error + +**Problem**: `Provider not found` or `404` error + +**Solutions**: + +1. Verify the provider is added to your application in the [Reclaim Developer Portal](https://dev.reclaimprotocol.org) + +2. Check the `PROVIDER_ID` matches exactly (case-sensitive) + +3. Ensure the provider is active and not disabled + +--- + +## Frontend Issues + +### Modal Doesn't Appear + +**Problem**: Calling `triggerReclaimFlow()` but nothing shows up + +**Solutions**: + +1. Ensure you're calling it from a user interaction (button click): + ```javascript + // ✅ Correct - from user interaction + button.addEventListener('click', async () => { + await reclaimProofRequest.triggerReclaimFlow(); + }); + + // ❌ Wrong - auto-triggered on page load + await reclaimProofRequest.triggerReclaimFlow(); // Browser may block + ``` + +2. Check browser console for errors + +3. Verify SDK initialization completed before triggering flow + +4. Test in a different browser (some ad blockers may interfere) + +### QR Code Not Loading + +**Problem**: QR code is blank or shows an error + +**Solutions**: + +1. Verify `getRequestUrl()` returns a valid URL: + ```javascript + const url = await reclaimProofRequest.getRequestUrl(); + console.log('Request URL:', url); // Should be a valid https:// URL + ``` + +2. Check QR code library is installed (if using custom QR): + ```bash + npm install react-qr-code + # or + npm install qrcode.react + ``` + +3. Ensure request URL is not too long (if it is, provider config may be invalid) + +### Proofs Not Received (onSuccess Never Called) + +**Problem**: User completes verification but `onSuccess` callback doesn't fire + +**Solutions**: + +1. Ensure `startSession()` is called BEFORE user completes verification: + ```javascript + // ✅ Correct order + await reclaimProofRequest.triggerReclaimFlow(); + await reclaimProofRequest.startSession({ onSuccess, onError }); + + // ❌ Wrong order + await reclaimProofRequest.startSession({ onSuccess, onError }); + await reclaimProofRequest.triggerReclaimFlow(); // Too late + ``` + +2. Check network connection (proofs are delivered via WebSocket) + +3. Look for WebSocket errors in browser console + +4. Verify callback functions are defined: + ```javascript + await reclaimProofRequest.startSession({ + onSuccess: (proofs) => { + console.log('✅ This should fire', proofs); + }, + onError: (error) => { + console.log('❌ Or this should fire', error); + } + }); + ``` + +### Mobile Verification Fails + +**Problem**: App Clip or Instant App doesn't launch on mobile + +**Solutions**: + +1. Test on an actual mobile device (simulators may not support App Clips/Instant Apps) + +2. Ensure you're testing on supported platforms: + - iOS 14+ for App Clips + - Android 6.0+ (API 23+) for Instant Apps + +3. Check that you're using a real mobile browser (not desktop browser in mobile mode) + +4. Verify the request URL is accessible from the mobile device + +--- + +## Backend Issues + +### CORS Errors + +**Problem**: `Access to fetch blocked by CORS policy` + +**Solutions**: + +1. **Express.js**: Install and configure CORS middleware: + ```javascript + const cors = require('cors'); + + app.use(cors({ + origin: process.env.NODE_ENV === 'production' + ? 'https://yourapp.com' + : 'http://localhost:3000', + credentials: true + })); + ``` + +2. **Next.js API Routes**: CORS is handled automatically for same-origin requests. For cross-origin: + ```javascript + export async function GET(request) { + const response = NextResponse.json({ data }); + response.headers.set('Access-Control-Allow-Origin', '*'); + return response; + } + ``` + +3. **FastAPI**: + ```python + from fastapi.middleware.cors import CORSMiddleware + + app.add_middleware( + CORSMiddleware, + allow_origins=["http://localhost:3000"], + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], + ) + ``` + +### Callback Endpoint Not Reached + +**Problem**: Backend callback URL is never called after verification + +**Solutions**: + +1. **Verify callback URL is publicly accessible**: + ```bash + # Test from external service + curl https://yourapp.com/api/reclaim/callback + ``` + +2. **For local development, use ngrok**: + ```bash + ngrok http 3000 + # Update BASE_URL in .env to ngrok URL + ``` + +3. **Check ngrok is running** and tunnel is active + +4. **Verify BASE_URL in environment variables**: + ```javascript + console.log('Callback URL:', `${process.env.BASE_URL}/api/reclaim/callback`); + ``` + +5. **Check for trailing slashes** - ensure consistency: + ```javascript + // ✅ Correct + setAppCallbackUrl(`${BASE_URL}/api/reclaim/callback`); + + // ❌ May cause issues + setAppCallbackUrl(`${BASE_URL}//api/reclaim/callback`); // Double slash + ``` + +6. **Monitor server logs** for incoming requests + +### Proof Parsing Fails + +**Problem**: `JSON.parse()` fails when processing proof in callback + +**Solutions**: + +1. **Express.js**: Use `express.text()` middleware: + ```javascript + app.use(express.text({ type: '*/*', limit: '50mb' })); + + app.post('/api/reclaim/callback', async (req, res) => { + const decodedBody = decodeURIComponent(req.body); + const proof = JSON.parse(decodedBody); + // ... + }); + ``` + +2. **Next.js (Pages Router)**: Disable body parser: + ```javascript + export const config = { + api: { + bodyParser: false, + }, + }; + ``` + +3. **Next.js (App Router)**: Read raw text: + ```javascript + const body = await request.text(); + const decodedBody = decodeURIComponent(body); + const proof = JSON.parse(decodedBody); + ``` + +4. **FastAPI**: + ```python + body = await request.body() + body_str = body.decode('utf-8') + body_str = unquote(body_str) + proof = json.loads(body_str) + ``` + +### Environment Variables Not Loading + +**Problem**: `process.env.RECLAIM_APP_ID` is `undefined` + +**Solutions**: + +1. **Node.js**: Install and use dotenv: + ```javascript + require('dotenv').config(); // At the very top of your file + ``` + +2. **Next.js**: Ensure file is named `.env.local` and restart dev server + +3. **Verify file location**: `.env` should be in project root + +4. **Check .env syntax**: + ```bash + # ✅ Correct + RECLAIM_APP_ID=your_app_id + + # ❌ Wrong + RECLAIM_APP_ID = your_app_id # No spaces around = + RECLAIM_APP_ID="your_app_id" # No quotes needed + ``` + +5. **Restart server** after modifying `.env` files + +--- + +## Verification Issues + +### Proof Verification Fails + +**Problem**: `verifyProof()` returns `false` + +**Solutions**: + +1. **Ensure proof structure is correct**: + ```javascript + console.log('Proof structure:', { + hasIdentifier: !!proof.identifier, + hasClaimData: !!proof.claimData, + hasSignatures: Array.isArray(proof.signatures), + hasWitnesses: Array.isArray(proof.witnesses) + }); + ``` + +2. **Check proof hasn't been tampered with** during transmission + +3. **Verify proof is from the correct provider** + +4. **Ensure SDK versions match** between frontend and backend + +### Timeout Errors + +**Problem**: Verification times out or takes too long + +**Solutions**: + +1. **Check network connectivity** on mobile device + +2. **Verify provider is responding**: + - Some providers may be temporarily unavailable + - Try a different provider to test + +3. **Increase timeout** if needed (though default should be sufficient) + +4. **Check user completed the flow** - they may have abandoned it + +--- + +## Development Environment Issues + +### Hot Reload Issues + +**Problem**: Changes to code aren't reflected after saving + +**Solutions**: + +1. **Hard refresh browser**: Ctrl+Shift+R (Windows/Linux) or Cmd+Shift+R (Mac) + +2. **Clear browser cache and reload** + +3. **Restart development server** + +4. **Check build tool console** for errors + +### Build Errors + +**Problem**: Build fails with SDK-related errors + +**Solutions**: + +1. **Next.js**: If encountering SSR issues, use dynamic imports: + ```javascript + const { ReclaimProofRequest } = await import('@reclaimprotocol/js-sdk'); + ``` + +2. **Vite**: Ensure SDK is not being pre-bundled incorrectly: + ```javascript + // vite.config.js + export default { + optimizeDeps: { + include: ['@reclaimprotocol/js-sdk'] + } + } + ``` + +3. **Webpack**: Check module resolution settings + +### ngrok Issues + +**Problem**: ngrok tunnel not working or disconnecting + +**Solutions**: + +1. **Verify ngrok is running**: Check terminal where ngrok was started + +2. **ngrok free tier limitations**: + - URL changes on each restart + - Session timeout after inactivity + - Consider paid tier for persistent URL + +3. **Update BASE_URL** after restarting ngrok + +4. **Alternative**: Use other tunneling tools like: + - localtunnel: `npx localtunnel --port 3000` + - CloudFlare Tunnel + - serveo.net + +--- + +## Production Issues + +### Vercel Deployment Issues + +**Problem**: Works locally but fails on Vercel + +**Solutions**: + +1. **Set environment variables** in Vercel dashboard: + - Go to Project Settings → Environment Variables + - Add all required variables + +2. **Check BASE_URL** is set correctly: + ```javascript + const baseUrl = process.env.VERCEL_URL + ? `https://${process.env.VERCEL_URL}` + : process.env.NEXT_PUBLIC_BASE_URL; + ``` + +3. **Verify API routes** are in correct location for deployment + +4. **Check function logs** in Vercel dashboard for errors + +### Heroku/Railway Deployment Issues + +**Problem**: Callback not working on Heroku/Railway + +**Solutions**: + +1. **Use dynamic PORT**: + ```javascript + const PORT = process.env.PORT || 3000; + ``` + +2. **Set BASE_URL to your app URL**: + ```bash + # On Heroku + heroku config:set BASE_URL=https://yourapp.herokuapp.com + ``` + +3. **Check dyno/service logs** for errors + +--- + +## Security Issues + +### APP_SECRET Exposed + +**Problem**: `APP_SECRET` was accidentally committed to git + +**Solutions**: + +1. **Immediately rotate your credentials** in Reclaim Developer Portal + +2. **Remove from git history**: + ```bash + # Use git filter-branch or BFG Repo-Cleaner + # Or delete and recreate repository if necessary + ``` + +3. **Add to .gitignore**: + ``` + .env + .env.local + .env.*.local + ``` + +4. **Audit code** to ensure no other secrets are exposed + +--- + +## Getting Help + +If you've tried the solutions above and still experiencing issues: + +### Before Asking for Help + +1. **Check browser console** for error messages +2. **Check server logs** for backend errors +3. **Verify all credentials** are correct +4. **Test with a minimal example** to isolate the issue +5. **Check SDK version** is up to date: + ```bash + npm update @reclaimprotocol/js-sdk + ``` + +### Where to Get Help + +- 💬 **[Community Discord](https://discord.gg/reclaim)** - Fastest support from community +- 🐛 **[GitHub Issues](https://github.com/reclaimprotocol/reclaim-js-sdk/issues)** - Report bugs +- 📧 **[Email Support](mailto:support@reclaimprotocol.org)** - For sensitive issues +- 📚 **[Documentation](/js-sdk)** - Review guides and examples + +### Providing Information + +When asking for help, include: + +1. **SDK version**: Check `package.json` +2. **Framework and version**: React 18, Next.js 14, etc. +3. **Error messages**: Full error from console/logs +4. **Code snippet**: Minimal reproducible example +5. **Environment**: Browser, OS, Node.js version +6. **Steps to reproduce**: What you did before the error + +--- + +## Debugging Tips + +### Enable Verbose Logging + +```javascript +// Add detailed logging +const reclaimProofRequest = await ReclaimProofRequest.init(...); + +console.log('Initialized:', reclaimProofRequest); + +const requestUrl = await reclaimProofRequest.getRequestUrl(); +console.log('Request URL:', requestUrl); + +await reclaimProofRequest.startSession({ + onSuccess: (proofs) => { + console.log('✅ Success:', JSON.stringify(proofs, null, 2)); + }, + onError: (error) => { + console.error('❌ Error:', error); + console.error('Error stack:', error.stack); + } +}); +``` + +### Test in Isolation + +Create a minimal test file to isolate the issue: + +```javascript +// test-reclaim.js +import { ReclaimProofRequest } from '@reclaimprotocol/js-sdk'; + +async function test() { + try { + console.log('Step 1: Initializing...'); + const request = await ReclaimProofRequest.init( + process.env.RECLAIM_APP_ID, + process.env.RECLAIM_APP_SECRET, + process.env.RECLAIM_PROVIDER_ID + ); + console.log('✅ Initialized'); + + console.log('Step 2: Getting URL...'); + const url = await request.getRequestUrl(); + console.log('✅ URL:', url); + + // Continue testing... + } catch (error) { + console.error('❌ Failed:', error); + } +} + +test(); +``` + +--- + +## Next Steps + +- **[API Reference →](/js-sdk/api-reference)** - Complete SDK documentation +- **[Installation →](/js-sdk/installation)** - Setup guide +- **[Recommended Setup →](/js-sdk/recommended-setup)** - Production patterns +- **[Community Discord →](https://discord.gg/reclaim)** - Get live support diff --git a/content/docs/meta.json b/content/docs/meta.json index 342483a..cc77081 100644 --- a/content/docs/meta.json +++ b/content/docs/meta.json @@ -3,6 +3,7 @@ "pages": [ "index", "api-key", + "js-sdk", "web", "browser-extension", "react-native", diff --git a/content/docs/web/index.mdx b/content/docs/web/index.mdx index 49edacc..5e5b04f 100644 --- a/content/docs/web/index.mdx +++ b/content/docs/web/index.mdx @@ -3,6 +3,24 @@ title: Web SDK description: Integrate Reclaim Protocol into your webapp using our JS and Python SDKs. --- + +**⚠️ Documentation Deprecated** + +These Web SDK docs are being deprecated in favor of the new, improved documentation structure. + +Please use the new documentation: +- **[JavaScript SDK →](/js-sdk)** - For JavaScript/TypeScript web applications (recommended) +- **Backend verification examples** - Now includes both Node.js and Python + +The new docs feature: +- Better organization and structure +- More framework examples (React, Next.js, Vue, Vanilla JS) +- Clearer security guidance +- Production-ready patterns +- Comprehensive API reference + +Existing code using these docs will continue to work, but we recommend migrating to the new structure for better documentation and examples. + ## Understanding the WebSDKs workflow From ee26b4106b60a49022a6d2ce9829f2bcbec49df7 Mon Sep 17 00:00:00 2001 From: sajjad21990 Date: Fri, 31 Oct 2025 19:08:28 +0530 Subject: [PATCH 2/3] few browser extenson sdk changes --- .../extension-integration/index.mdx | 17 ++++- .../extension-integration/setup.mdx | 18 ++++- .../extension-integration/usage.mdx | 16 ++++- content/docs/browser-extension/index.mdx | 69 +++++-------------- .../docs/browser-extension/installation.mdx | 21 +++++- .../web-integration/index.mdx | 18 ++++- .../web-integration/setup.mdx | 18 ++++- .../web-integration/usage.mdx | 16 ++++- 8 files changed, 132 insertions(+), 61 deletions(-) diff --git a/content/docs/browser-extension/extension-integration/index.mdx b/content/docs/browser-extension/extension-integration/index.mdx index fdbd0cd..83d3fc0 100644 --- a/content/docs/browser-extension/extension-integration/index.mdx +++ b/content/docs/browser-extension/extension-integration/index.mdx @@ -105,11 +105,26 @@ Use the SDK's API in your popup or panel to trigger verification and handle resu Before starting, ensure you have: - ✅ Completed the [Installation guide](/browser-extension/installation) -- ✅ Obtained API credentials from the [API Key guide](/api-key) - ✅ Basic understanding of Chrome extension development - ✅ Familiarity with JavaScript Promises and async/await - ✅ A Chrome extension project with Manifest V3 +## Get Your API Credentials + + +**🔑 Required: Get Your API Credentials First** + +Before you proceed with any integration steps, you **must** obtain your API credentials. These credentials (`APP_ID` and `APP_SECRET`) are essential for initializing the SDK and creating verification requests. + +**[Get Your API Credentials Now →](/api-key)** + +You'll need: +- **`APP_ID`**: Your unique application identifier +- **`APP_SECRET`**: Your application secret key (keep secure!) + +Without these credentials, you cannot complete the integration steps below. + + ## Security Considerations ### Content Security Policy diff --git a/content/docs/browser-extension/extension-integration/setup.mdx b/content/docs/browser-extension/extension-integration/setup.mdx index 985f125..eb224ac 100644 --- a/content/docs/browser-extension/extension-integration/setup.mdx +++ b/content/docs/browser-extension/extension-integration/setup.mdx @@ -3,9 +3,25 @@ title: Setup description: Initialize the SDK in your browser extension's background and content scripts --- +## Get Your API Credentials First + + +**🔑 Required Before Setup** + +Before you can initialize the SDK, you **must** have your API credentials (`APP_ID` and `APP_SECRET`). These are required to create verification requests. + +**[Get Your API Credentials →](/api-key)** + +You'll need: +- **`APP_ID`**: Your unique application identifier +- **`APP_SECRET`**: Your application secret key + +Keep these credentials secure and never expose them in client-side code for production applications. + + ## Overview -After configuring your manifest, you need to initialize the SDK in two places: +After configuring your manifest and obtaining your API credentials, you need to initialize the SDK in two places: 1. **Background Service Worker**: Manages offscreen documents and verification orchestration 2. **Content Script Loading**: Bridges communication (optional if using static manifest registration) diff --git a/content/docs/browser-extension/extension-integration/usage.mdx b/content/docs/browser-extension/extension-integration/usage.mdx index def0cf1..d6cf221 100644 --- a/content/docs/browser-extension/extension-integration/usage.mdx +++ b/content/docs/browser-extension/extension-integration/usage.mdx @@ -7,13 +7,27 @@ description: Implement Reclaim verification flows in your browser extension popu With the SDK initialized and configured, you can now implement verification flows in your extension's user interface. This guide covers implementing verification in popups, side panels, and handling the complete verification lifecycle. +## Get Your API Credentials + + +**🔑 Required: API Credentials** + +Before implementing verification, make sure you have your API credentials (`APP_ID` and `APP_SECRET`). All code examples below require these credentials. + +**[Get Your API Credentials →](/api-key)** + +You'll need: +- **`APP_ID`**: Your unique application identifier +- **`APP_SECRET`**: Your application secret key + + ## Prerequisites Before implementing verification flows, ensure you have: - ✅ Completed [Manifest Configuration](/browser-extension/extension-integration/manifest-configuration) - ✅ Completed [Background Setup](/browser-extension/extension-integration/setup) -- ✅ Obtained API credentials from the [API Key guide](/api-key) +- ✅ **Obtained your API credentials** (`APP_ID` and `APP_SECRET`) from the [API Key guide](/api-key) ## Basic Popup Implementation diff --git a/content/docs/browser-extension/index.mdx b/content/docs/browser-extension/index.mdx index 87ade05..05b84ff 100644 --- a/content/docs/browser-extension/index.mdx +++ b/content/docs/browser-extension/index.mdx @@ -1,78 +1,41 @@ --- title: Browser Extension SDK -description: Lightweight SDK for integrating Reclaim verification flows into browser extensions and websites with Chrome Manifest V3 support +description: Seamlessly integrate Reclaim Protocol verification into your Chrome browser extension --- ## Overview -Lightweight SDK for integrating Reclaim verification into browser extensions and websites. Handles content-background communication, provider tab management, WebAssembly proof generation, and completion events. +Build browser extensions with Reclaim Protocol verification capabilities. This SDK handles Chrome extension architecture (MV3, service workers, offscreen documents), WebAssembly proof generation, and provider tab management. ### Key Features -- 🔌 **Dual Integration**: Build extensions or integrate from web apps - 🛡️ **Manifest V3 Compatible**: Full Chrome MV3 support - ⚡ **WebAssembly Proofs**: High-performance cryptographic proof generation - 🔄 **Event-Driven**: Real-time updates via clean event API - 📦 **Pre-built Bundles**: No re-bundling required -- 🎯 **Auto Provider Management**: Automatic tab orchestration -- 🔐 **Network Monitoring**: Built-in request interception ## Two Integration Paths -### 1. Extension Integration (Primary) +### 1. Extension Integration (Standalone) -**Build a browser extension** with Reclaim verification in popup/sidepanel: -- Users trigger verification from your extension UI +**Build a standalone browser extension** with Reclaim verification: + +- Complete extension that users install from Chrome Web Store +- Users trigger verification directly from your extension popup/sidepanel +- No website required - extension works independently - Full control over extension experience - SDK handles all Chrome extension complexity -- Manifest V3, offscreen documents, service workers [Get Started with Extension Integration →](/browser-extension/extension-integration) -### 2. Web Integration (Optional) - -**Trigger verification from your website** through a compatible extension: -- For websites that want to use an extension built with this SDK -- Users verify without leaving your site -- Extension handles verification, you control website UI -- Requires users to install compatible extension - -[Learn About Web Integration →](/browser-extension/web-integration) - -## How It Works - -Multi-layer architecture for secure verification: - -1. **Content Script Bridge** - Communication between pages and extension -2. **Background Service Worker** - Manages offscreen docs and provider tabs -3. **Offscreen Document** - WebAssembly proof generation -4. **Network Interceptor** - Captures network requests during verification +### 2. Web Integration (Website + Extension) -```mermaid -graph LR - A[Web Page / Extension Popup] --> B[Content Script] - B --> C[Background Service Worker] - C --> D[Offscreen Document] - C --> E[Provider Tab] - D --> F[WebAssembly Proof Generation] - E --> G[Network Interceptor] -``` +**Trigger verification from your website** using a compatible extension: -## Compatibility +- Requires BOTH: your website + a compatible extension installed by users +- Users verify directly on your website without leaving the page +- Extension (built with this SDK) handles verification in background +- Website maintains control over UI/UX +- Users must install the extension first -**Browsers**: Chrome 93+, Edge 93+, Brave, Opera (Chromium-based) - -**Requirements**: Node.js 14.x+, npm 6.x+ or yarn 1.22.x+, Manifest V3 - -## Next Steps - -Choose your integration path: - -1. **[Installation](/browser-extension/installation)** - Install the SDK and set up assets -2. **[Extension Integration](/browser-extension/extension-integration)** - Build a browser extension with Reclaim -3. **[Web Integration](/browser-extension/web-integration)** - Integrate from your website -4. **[Troubleshooting](/browser-extension/troubleshooting)** - Common issues and solutions - -## Get an API Key - -Before integrating, you'll need API credentials. Follow the [Get API Key guide](/api-key) to set up your Reclaim Protocol project. +[Learn About Web Integration →](/browser-extension/web-integration) diff --git a/content/docs/browser-extension/installation.mdx b/content/docs/browser-extension/installation.mdx index 26f7166..d27a65e 100644 --- a/content/docs/browser-extension/installation.mdx +++ b/content/docs/browser-extension/installation.mdx @@ -104,11 +104,28 @@ rm -rf node_modules package-lock.json && npm install - Ensure SDK assets are in `public/`, not imported in your code - Reference via manifest configuration (see next steps) +## Get Your API Credentials + + +**⚠️ Required Before Proceeding** + +Before you can use the SDK, you **must** obtain your API credentials (`APP_ID` and `APP_SECRET`) from the Reclaim Protocol dashboard. These credentials are required for all integrations. + +**[Get Your API Credentials Now →](/api-key)** + + +Without API credentials, you won't be able to initialize the SDK or create verification requests. This is the most important step after installation. + +### What You'll Get + +- **`APP_ID`**: Your unique application identifier +- **`APP_SECRET`**: Your application secret key (keep this secure!) + +You'll need both of these credentials in the next steps for any integration path you choose. + ## Next Steps Choose your integration path: - **[Extension Integration →](/browser-extension/extension-integration)** - Build a browser extension - **[Web Integration →](/browser-extension/web-integration)** - Integrate from a website - -Get your [API credentials →](/api-key) before proceeding. diff --git a/content/docs/browser-extension/web-integration/index.mdx b/content/docs/browser-extension/web-integration/index.mdx index 49bd062..a48503b 100644 --- a/content/docs/browser-extension/web-integration/index.mdx +++ b/content/docs/browser-extension/web-integration/index.mdx @@ -43,12 +43,28 @@ graph LR 5. **Provider Tab**: Handles authentication 6. **Proofs Returned**: Sent back to your website +## Get Your API Credentials First + + +**🔑 Required: Get Your API Credentials Before Integration** + +Before you can integrate Reclaim verification into your website, you **must** obtain your API credentials. These credentials (`APP_ID` and `APP_SECRET`) are essential for creating verification requests. + +**[Get Your API Credentials Now →](/api-key)** + +You'll need: +- **`APP_ID`**: Your unique application identifier +- **`APP_SECRET`**: Your application secret key (keep secure!) + +Without these credentials, you cannot initialize the SDK or start verification flows. + + ## Prerequisites Before integrating, ensure you have: - ✅ Completed the [Installation guide](/browser-extension/installation) -- ✅ Obtained API credentials from the [API Key guide](/api-key) +- ✅ **Obtained your API credentials (`APP_ID` and `APP_SECRET`)** from the [API Key guide](/api-key) - ✅ Access to a Reclaim-compatible browser extension (or built one using [Extension Integration](/browser-extension/extension-integration)) - ✅ A web application (React, Vue, vanilla JavaScript, etc.) diff --git a/content/docs/browser-extension/web-integration/setup.mdx b/content/docs/browser-extension/web-integration/setup.mdx index b9642de..cfde941 100644 --- a/content/docs/browser-extension/web-integration/setup.mdx +++ b/content/docs/browser-extension/web-integration/setup.mdx @@ -5,10 +5,26 @@ description: Configure the Reclaim Browser Extension SDK in your web application import { Tab, Tabs } from "fumadocs-ui/components/tabs"; +## Get Your API Credentials First + + +**🔑 Required: Get Your API Credentials Before Setup** + +The first and most important step is obtaining your API credentials. You'll need `APP_ID` and `APP_SECRET` to create verification requests in the steps below. + +**[Get Your API Credentials Now →](/api-key)** + +What you'll get: +- **`APP_ID`**: Your unique application identifier +- **`APP_SECRET`**: Your application secret key (keep secure!) + +These credentials are essential for all the code examples in this guide. + + ## Prerequisites - ✅ [Installation guide](/browser-extension/installation) completed -- ✅ [API credentials](/api-key) obtained +- ✅ **[API credentials](/api-key) obtained** (`APP_ID` and `APP_SECRET`) - ✅ Extension ID of the Reclaim-compatible extension - ✅ Web application (React, Vue, vanilla JS) diff --git a/content/docs/browser-extension/web-integration/usage.mdx b/content/docs/browser-extension/web-integration/usage.mdx index 7d0cfa7..12c663d 100644 --- a/content/docs/browser-extension/web-integration/usage.mdx +++ b/content/docs/browser-extension/web-integration/usage.mdx @@ -7,12 +7,26 @@ description: Implement Reclaim verification flows in your web application This guide demonstrates how to implement complete verification flows in your web application, including initialization, event handling, UI states, and error management. +## Get Your API Credentials + + +**🔑 Required: API Credentials** + +Before implementing verification, ensure you have your API credentials (`APP_ID` and `APP_SECRET`). All code examples below require these credentials. + +**[Get Your API Credentials →](/api-key)** + +You'll need: +- **`APP_ID`**: Your unique application identifier +- **`APP_SECRET`**: Your application secret key (keep secure!) + + ## Prerequisites - ✅ Completed [Installation](/browser-extension/installation) - ✅ Completed [Setup](/browser-extension/web-integration/setup) - ✅ Extension installed and extension ID configured -- ✅ API credentials from [API Key guide](/api-key) +- ✅ **Obtained your API credentials** (`APP_ID` and `APP_SECRET`) from [API Key guide](/api-key) ## Basic Implementation From 73cf8600e1cca34b8a29b23be6a0c770e381d5f2 Mon Sep 17 00:00:00 2001 From: sajjad21990 Date: Fri, 31 Oct 2025 19:49:51 +0530 Subject: [PATCH 3/3] updated docs --- content/docs/js-sdk/api-reference.mdx | 567 +++++++++++++++--- content/docs/js-sdk/client-integration.mdx | 6 + content/docs/js-sdk/index.mdx | 254 +++++--- content/docs/js-sdk/quickstart.mdx | 8 + .../docs/js-sdk/recommended-setup/index.mdx | 2 + content/docs/meta.json | 1 - 6 files changed, 675 insertions(+), 163 deletions(-) diff --git a/content/docs/js-sdk/api-reference.mdx b/content/docs/js-sdk/api-reference.mdx index 5a9347e..4cee384 100644 --- a/content/docs/js-sdk/api-reference.mdx +++ b/content/docs/js-sdk/api-reference.mdx @@ -1,6 +1,6 @@ --- -title: API Reference -description: Complete API documentation for the Reclaim JavaScript SDK +title: API Reference & Advanced Configuration +description: Complete API documentation and advanced configuration options for the Reclaim JavaScript SDK --- ## Overview @@ -16,7 +16,7 @@ npm install @reclaimprotocol/js-sdk ## Import ```javascript -import { ReclaimProofRequest, verifyProof } from '@reclaimprotocol/js-sdk'; +import { ReclaimProofRequest, verifyProof } from "@reclaimprotocol/js-sdk"; ``` --- @@ -32,6 +32,7 @@ The main class for creating and managing proof requests. Initialize a new proof request with your API credentials. **Parameters:** + - `appId` (string, required): Your application ID from the Reclaim Developer Portal - `appSecret` (string, required): Your application secret - `providerId` (string, required): The provider ID to verify against @@ -39,28 +40,25 @@ Initialize a new proof request with your API credentials. **Returns:** `Promise` **Example:** + ```javascript -const reclaimProofRequest = await ReclaimProofRequest.init( - 'your-app-id', - 'your-app-secret', - 'your-provider-id' -); +const reclaimProofRequest = await ReclaimProofRequest.init("your-app-id", "your-app-secret", "your-provider-id"); ``` - -**Security**: Initialize from backend only in production. Never expose `appSecret` in client-side code. - +**Security**: Initialize from backend only in production. Never expose `appSecret` in client-side code. #### `ReclaimProofRequest.fromJsonString(configString)` Reconstruct a proof request from a JSON configuration string (typically generated on the backend). **Parameters:** + - `configString` (string, required): JSON string from `toJsonString()` **Returns:** `Promise` **Example:** + ```javascript // Backend generates config const config = reclaimProofRequest.toJsonString(); @@ -80,9 +78,10 @@ Generate a verification request URL for manual display (QR codes, links, etc.). **Returns:** `Promise` - The verification request URL **Example:** + ```javascript const requestUrl = await reclaimProofRequest.getRequestUrl(); -console.log('Verification URL:', requestUrl); +console.log("Verification URL:", requestUrl); // Display as QR code or clickable link ``` @@ -93,9 +92,10 @@ Get the status polling URL for checking verification progress. **Returns:** `string` - The status URL **Example:** + ```javascript const statusUrl = reclaimProofRequest.getStatusUrl(); -console.log('Status URL:', statusUrl); +console.log("Status URL:", statusUrl); ``` #### `triggerReclaimFlow(options?)` @@ -103,9 +103,11 @@ console.log('Status URL:', statusUrl); Automatically trigger the optimal verification flow based on user's platform. Shows QR code modal on desktop, redirects to App Clip/Instant App on mobile, or uses browser extension if available. **Parameters:** + - `options` (object, optional): Configuration options for the flow **Options Object:** + - `theme` (string): `'light'` or `'dark'` - Modal theme (default: `'light'`) - `modalTitle` (string): Custom title for the QR modal - `modalSubtitle` (string): Custom subtitle for the QR modal @@ -118,14 +120,15 @@ Automatically trigger the optimal verification flow based on user's platform. Sh **Returns:** `Promise` **Example:** + ```javascript await reclaimProofRequest.triggerReclaimFlow({ - theme: 'dark', - modalTitle: 'Verify Your Account', + theme: "dark", + modalTitle: "Verify Your Account", autoCloseModal: true, autoCloseDelay: 2000, - onModalOpen: () => console.log('Modal opened'), - onModalClose: () => console.log('Modal closed') + onModalOpen: () => console.log("Modal opened"), + onModalClose: () => console.log("Modal closed"), }); ``` @@ -134,9 +137,11 @@ await reclaimProofRequest.triggerReclaimFlow({ Start listening for proof submissions. Must be called after generating request URL or triggering flow. **Parameters:** + - `callbacks` (object, required): Callback functions **Callbacks Object:** + - `onSuccess` (function, required): Called when proof is successfully generated - Receives: `(proofs: Proof) => void` - `onError` (function, required): Called when verification fails @@ -145,16 +150,17 @@ Start listening for proof submissions. Must be called after generating request U **Returns:** `Promise` **Example:** + ```javascript await reclaimProofRequest.startSession({ onSuccess: (proofs) => { - console.log('Verification successful!', proofs); + console.log("Verification successful!", proofs); // Process the proofs }, onError: (error) => { - console.error('Verification failed:', error); + console.error("Verification failed:", error); // Handle error - } + }, }); ``` @@ -163,13 +169,15 @@ await reclaimProofRequest.startSession({ Set a callback URL where Reclaim will send proofs after verification (for backend processing). **Parameters:** + - `url` (string, required): Your backend callback URL (must be publicly accessible) **Returns:** `void` **Example:** + ```javascript -reclaimProofRequest.setAppCallbackUrl('https://yourapp.com/api/reclaim/callback'); +reclaimProofRequest.setAppCallbackUrl("https://yourapp.com/api/reclaim/callback"); ``` #### `toJsonString()` @@ -179,6 +187,7 @@ Serialize the proof request to a JSON string (safe to send to frontend, excludes **Returns:** `string` - JSON configuration string **Example:** + ```javascript // Backend const config = reclaimProofRequest.toJsonString(); @@ -195,18 +204,441 @@ Check if the Reclaim browser extension is installed and available. **Returns:** `Promise` **Example:** + ```javascript const hasExtension = await reclaimProofRequest.isBrowserExtensionAvailable(); if (hasExtension) { - console.log('Extension available - will use in-browser verification'); + console.log("Extension available - will use in-browser verification"); } else { - console.log('No extension - will show QR code'); + console.log("No extension - will show QR code"); } ``` --- +## Advanced Configuration + + +**Customization Options** + +The SDK provides extensive customization options for the verification flow, UI appearance, and behavior. Jump to any section: + +- [🎨 Modal Customization](#modal-customization) - Configure QR modal appearance and behavior +- [⚙️ Custom Parameters](#custom-parameters) - Add metadata with `setParams()` +- [📝 Context Addition](#context-addition) - Add signed context with `addContext()` +- [🧩 Browser Extension](#browser-extension-configuration) - Configure extension behavior +- [🔗 Callback URLs](#callback-urls) - Set backend callback endpoints +- [🔀 Custom Redirects](#custom-redirects) - Configure post-verification redirects +- [🎯 Session Callbacks](#session-callbacks) - Handle `onSuccess`/`onFailure` events +- [💡 Complete Example](#complete-configuration-example) - See all features together + + + +--- + +### 🎨 Modal Customization + +#### `setModalOptions(options)` + +Configure the QR code modal appearance, behavior, and callbacks. + +**Parameters:** + +- `options` (object, required): Configuration object for the modal + +**Options Object:** + +- `darkTheme` (boolean): Enable dark mode styling (default: `false`) +- `title` (string): Custom modal title +- `description` (string): Custom modal description text +- `modalPopupTimer` (number): Auto-close timer in minutes (0 = no auto-close) +- `showExtensionInstallButton` (boolean): Show browser extension install prompt +- `extensionUrl` (string): Custom extension URL for install button +- `onClose` (function): Callback function when modal is closed by user + +**Returns:** `void` + +**Example:** + +```javascript +reclaimProofRequest.setModalOptions({ + // Theme + darkTheme: true, + + // Text customization + title: "Verify Your Account", + description: "Scan this QR code with your mobile device to continue", + + // Behavior + modalPopupTimer: 5, // Auto-close after 5 minutes of inactivity + + // Browser extension + showExtensionInstallButton: true, + extensionUrl: "https://chrome.google.com/webstore/...", + + // Callbacks + onClose: () => { + console.log("User closed the verification modal"); + // Handle modal closure (e.g., show alternative flow) + }, +}); +``` + +**Use Cases:** + +- Match your app's theme (light/dark mode) +- Provide context-specific instructions +- Handle user abandonment with `onClose` callback +- Promote browser extension installation + +--- + +### ⚙️ Custom Parameters + +#### `setParams(params)` + +Add custom key-value parameters to the proof request. These parameters will be included in the verified proof and can be used for application-specific metadata. + +**Parameters:** + +- `params` (object, required): Key-value pairs of custom data + +**Returns:** `void` + +**Example:** + +```javascript +reclaimProofRequest.setParams({ + userId: "user_12345", + action: "account_verification", + tier: "premium", + timestamp: Date.now(), + sessionId: "abc-def-ghi", +}); +``` + +**Access in Proof:** + +```javascript +// The parameters are included in the proof +await reclaimProofRequest.startSession({ + onSuccess: (proofs) => { + const parameters = JSON.parse(proofs.claimData.parameters); + }, +}); +``` + +--- + +### 📝 Context Addition + +#### `addContext(address, message)` + +Add custom context or metadata to the proof request. Context is signed and included in the cryptographic proof. + +**Parameters:** + +- `address` (string, required): Context identifier (e.g., wallet address, user ID) +- `message` (string, required): Context message or metadata + +**Returns:** `void` + +**Example:** + +```javascript +// Add wallet address context +reclaimProofRequest.addContext("0x1234567890abcdef1234567890abcdef12345678", "Verification for DeFi platform access"); + +// Or add any custom context +reclaimProofRequest.addContext("user_id_12345", "Email verification for premium tier upgrade"); +``` + +**Access in Proof:** + +```javascript +await reclaimProofRequest.startSession({ + onSuccess: (proofs) => { + const context = JSON.parse(proofs.claimData.context); + console.log("Context:", context); + }, +}); +``` + +**Use Cases:** + +- Link verification to blockchain addresses +- Add tamper-proof metadata +- Include application-specific identifiers +- Create auditable verification records + +--- + +### 🧩 Browser Extension Configuration + +#### Extension Initialization Options + +Configure browser extension behavior when initializing the proof request. + +**Parameters (in `init()` fourth argument):** + +- `useBrowserExtension` (boolean): Enable/disable extension detection (default: `true`) +- `extensionID` (string): Custom browser extension identifier + +**Example:** + +```javascript +// Enable extension with custom ID +const reclaimProofRequest = await ReclaimProofRequest.init(APP_ID, APP_SECRET, PROVIDER_ID, { + useBrowserExtension: true, + extensionID: "your-custom-extension-id", +}); + +// Disable extension (always use QR/mobile flow) +const reclaimProofRequest = await ReclaimProofRequest.init(APP_ID, APP_SECRET, PROVIDER_ID, { + useBrowserExtension: false, +}); +``` + +#### Check Extension Availability + +Use `isBrowserExtensionAvailable()` to conditionally render UI based on extension presence: + +**Example:** + +```javascript +const hasExtension = await reclaimProofRequest.isBrowserExtensionAvailable(); + +if (hasExtension) { + // Show "Verify with Extension" button + showExtensionButton(); +} else { + // Show "Scan QR Code" instructions + showQRCodeInstructions(); +} +``` + +**Use Cases:** + +- Provide different UI for extension vs non-extension users +- Show extension install prompts strategically +- Optimize verification flow based on capabilities + +--- + +### 🔗 Callback URLs + +#### `setAppCallbackUrl(url)` + +Set a backend callback URL where Reclaim Protocol will POST proofs directly after verification. This enables secure backend proof processing without relying on frontend delivery. + +**Parameters:** + +- `url` (string, required): Your publicly accessible backend endpoint + +**Returns:** `void` + +**Example:** + +```javascript +// Backend receives proofs directly from Reclaim +reclaimProofRequest.setAppCallbackUrl("https://yourapp.com/api/reclaim/callback"); + +// Backend endpoint +app.post("/api/reclaim/callback", async (req, res) => { + const proof = req.body; // Proof sent directly by Reclaim + + // Verify proof + const isValid = await verifyProof(proof); + + if (isValid) { + // Process verified data + await updateUserRecord(proof); + } + + res.sendStatus(200); // Acknowledge receipt +}); +``` + +**Requirements:** + +- URL must be publicly accessible (not localhost) +- Endpoint should return 200 OK response +- Implement proof verification on backend + +**Benefits:** + +- ✅ Proofs delivered directly to your backend (more secure) +- ✅ No dependency on frontend proof handling +- ✅ Backend can process async without user waiting +- ✅ Automatic retry on delivery failure + +--- + +### 🔀 Custom Redirects + +#### `setRedirectUrl(url)` + +Set a custom redirect URL where users will be sent after completing verification on mobile (App Clip, Instant App, deep link). + +**Parameters:** + +- `url` (string, required): Your app's redirect destination + +**Returns:** `void` + +**Example:** + +```javascript +// Redirect to success page after verification +reclaimProofRequest.setRedirectUrl("https://yourapp.com/verification/success"); + +// Or deep link back to your mobile app +reclaimProofRequest.setRedirectUrl("yourapp://verification-complete"); +``` + +**Use Cases:** + +- Guide users back to your app after mobile verification +- Show custom success/thank you pages +- Deep link into specific app sections +- Track verification completion + +--- + +### 🎯 Session Callbacks + +#### Enhanced `startSession()` Callbacks + +The `startSession()` method provides detailed callbacks for handling verification results. + +**Callback Signatures:** + +```typescript +interface SessionCallbacks { + onSuccess: (proofs: Proof | string) => void; + onFailure: (error: Error) => void; +} +``` + +**Detailed Example:** + +```javascript +await reclaimProofRequest.startSession({ + onSuccess: (proofs) => { + console.log('✅ Verification successful!'); + + // Proofs can be either object or string message + if (typeof proofs === 'string') { + console.log('Message:', proofs); + } else { + console.log('Proof ID:', proofs.identifier); + console.log('Provider:', proofs.claimData.provider); + console.log('Timestamp:', new Date(proofs.timestampS * 1000)); + + // Extract verified data + const parameters = JSON.parse(proofs.claimData.parameters); + console.log('Verified data:', parameters); + + // Send to backend for processing + await fetch('/api/verify', { + method: 'POST', + body: JSON.stringify(proofs), + headers: { 'Content-Type': 'application/json' } + }); + } + }, + + onFailure: (error) => { + console.error('❌ Verification failed:', error); + + // Handle specific error types + if (error.message.includes('timeout')) { + showTimeoutMessage(); + } else if (error.message.includes('cancelled')) { + showCancelledMessage(); + } else { + showGenericErrorMessage(); + } + + // Log for debugging + logVerificationFailure(error); + } +}); +``` + +**Error Scenarios Handled:** + +- User cancels verification +- Verification timeout +- Network connectivity issues +- Invalid provider configuration +- Backend callback failures + +--- + +### 💡 Complete Configuration Example + +Here's a comprehensive example using multiple advanced features: + +```javascript +// Initialize with extension config +const reclaimProofRequest = await ReclaimProofRequest.init(APP_ID, APP_SECRET, PROVIDER_ID, { + useBrowserExtension: true, + extensionID: "custom-extension-id", +}); + +// Set backend callback for proof delivery +reclaimProofRequest.setAppCallbackUrl("https://yourapp.com/api/reclaim/callback"); + +// Add custom parameters +reclaimProofRequest.setParams({ + userId: "user_12345", + action: "premium_verification", + timestamp: Date.now(), +}); + +// Add context +reclaimProofRequest.addContext("0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb2", "DeFi platform verification"); + +// Set custom redirect +reclaimProofRequest.setRedirectUrl("https://yourapp.com/verification/complete"); + +// Configure modal appearance +reclaimProofRequest.setModalOptions({ + darkTheme: true, + title: "Verify Your Premium Account", + description: "Scan with your mobile device", + modalPopupTimer: 10, + showExtensionInstallButton: true, + onClose: () => { + console.log("Modal closed by user"); + trackEvent("verification_abandoned"); + }, +}); + +// Check for extension +const hasExtension = await reclaimProofRequest.isBrowserExtensionAvailable(); +console.log("Extension available:", hasExtension); + +// Trigger verification flow +await reclaimProofRequest.triggerReclaimFlow(); + +// Handle results +await reclaimProofRequest.startSession({ + onSuccess: async (proofs) => { + console.log("Verification successful!"); + await processProof(proofs); + }, + onFailure: (error) => { + console.error("Verification failed:", error); + handleVerificationError(error); + }, +}); +``` + +--- + ## Standalone Functions ### `verifyProof(proof)` @@ -214,24 +646,26 @@ if (hasExtension) { Cryptographically verify a proof received from Reclaim Protocol. **Parameters:** + - `proof` (Proof object, required): The proof to verify **Returns:** `Promise` - `true` if proof is valid, `false` otherwise **Example:** + ```javascript -import { verifyProof } from '@reclaimprotocol/js-sdk'; +import { verifyProof } from "@reclaimprotocol/js-sdk"; -app.post('/api/reclaim/callback', async (req, res) => { +app.post("/api/reclaim/callback", async (req, res) => { const proof = parseProof(req.body); const isValid = await verifyProof(proof); if (isValid) { - console.log('✅ Proof is valid'); + console.log("✅ Proof is valid"); // Process verified data } else { - console.log('❌ Proof verification failed'); + console.log("❌ Proof verification failed"); } res.sendStatus(200); @@ -239,7 +673,7 @@ app.post('/api/reclaim/callback', async (req, res) => { ``` -**Best Practice**: Always verify proofs on your backend before trusting the data. Never rely solely on client-side verification. + **Best Practice**: Always verify proofs on your backend before trusting the data. Never rely solely on client-side verification. --- @@ -252,26 +686,27 @@ The proof object received after successful verification: ```typescript interface Proof { - identifier: string; // Unique proof identifier - claimData: ClaimData; // Claim details - signatures: string[]; // Cryptographic signatures - witnesses: Witness[]; // Witness attestations - timestampS: number; // Unix timestamp in seconds + identifier: string; // Unique proof identifier + claimData: ClaimData; // Claim details + signatures: string[]; // Cryptographic signatures + witnesses: Witness[]; // Witness attestations + timestampS: number; // Unix timestamp in seconds } interface ClaimData { - provider: string; // Provider name (e.g., "google") - parameters: string; // JSON string of provider parameters - context: string; // JSON string of context data + provider: string; // Provider name (e.g., "google") + parameters: string; // JSON string of provider parameters + context: string; // JSON string of context data } interface Witness { - address: string; // Witness address - signature: string; // Witness signature + address: string; // Witness address + signature: string; // Witness signature } ``` **Example Proof:** + ```json { "identifier": "0x1234567890abcdef...", @@ -317,8 +752,8 @@ const verifiedAt = new Date(proof.timestampS * 1000); try { await ReclaimProofRequest.init(appId, appSecret, providerId); } catch (error) { - if (error.message.includes('Invalid credentials')) { - console.error('Check your APP_ID and APP_SECRET'); + if (error.message.includes("Invalid credentials")) { + console.error("Check your APP_ID and APP_SECRET"); } } ``` @@ -329,8 +764,8 @@ try { try { await ReclaimProofRequest.init(appId, appSecret, providerId); } catch (error) { - if (error.message.includes('Provider')) { - console.error('Verify your PROVIDER_ID is correct'); + if (error.message.includes("Provider")) { + console.error("Verify your PROVIDER_ID is correct"); } } ``` @@ -340,10 +775,10 @@ try { ```javascript await reclaimProofRequest.startSession({ onError: (error) => { - if (error.message.includes('timeout')) { - console.error('Verification timed out - user may have abandoned flow'); + if (error.message.includes("timeout")) { + console.error("Verification timed out - user may have abandoned flow"); } - } + }, }); ``` @@ -355,7 +790,7 @@ await reclaimProofRequest.startSession({ ```javascript // Backend -app.get('/api/reclaim/config', async (req, res) => { +app.get("/api/reclaim/config", async (req, res) => { const reclaimProofRequest = await ReclaimProofRequest.init( process.env.RECLAIM_APP_ID, process.env.RECLAIM_APP_SECRET, @@ -369,12 +804,10 @@ app.get('/api/reclaim/config', async (req, res) => { }); // Frontend -const response = await fetch('/api/reclaim/config'); +const response = await fetch("/api/reclaim/config"); const { reclaimProofRequestConfig } = await response.json(); -const reclaimProofRequest = await ReclaimProofRequest.fromJsonString( - reclaimProofRequestConfig -); +const reclaimProofRequest = await ReclaimProofRequest.fromJsonString(reclaimProofRequestConfig); await reclaimProofRequest.triggerReclaimFlow(); await reclaimProofRequest.startSession({ onSuccess, onError }); @@ -385,16 +818,16 @@ await reclaimProofRequest.startSession({ onSuccess, onError }); ```javascript // ⚠️ Not for production - exposes APP_SECRET const reclaimProofRequest = await ReclaimProofRequest.init( - 'your-app-id', - 'your-app-secret', // Exposed! - 'your-provider-id' + "your-app-id", + "your-app-secret", // Exposed! + "your-provider-id" ); await reclaimProofRequest.triggerReclaimFlow(); await reclaimProofRequest.startSession({ - onSuccess: (proofs) => console.log('Success:', proofs), - onError: (error) => console.error('Error:', error) + onSuccess: (proofs) => console.log("Success:", proofs), + onError: (error) => console.error("Error:", error), }); ``` @@ -417,13 +850,13 @@ await reclaimProofRequest.startSession({ onSuccess, onError }); The SDK automatically detects the user's platform and provides the best experience: -| Platform | Detection Method | Verification Flow | -|----------|-----------------|-------------------| -| Desktop Chrome/Edge | User agent | QR code modal or extension | -| Desktop Safari/Firefox | User agent | QR code modal | -| iOS Safari | User agent + touch | App Clip redirect | -| Android Chrome | User agent + touch | Instant App redirect | -| Mobile browsers | Touch capability | Deep link or QR | +| Platform | Detection Method | Verification Flow | +| ---------------------- | ------------------ | -------------------------- | +| Desktop Chrome/Edge | User agent | QR code modal or extension | +| Desktop Safari/Firefox | User agent | QR code modal | +| iOS Safari | User agent + touch | App Clip redirect | +| Android Chrome | User agent + touch | Instant App redirect | +| Mobile browsers | Touch capability | Deep link or QR | --- @@ -443,16 +876,12 @@ The SDK automatically detects the user's platform and provides the best experien The SDK includes TypeScript definitions out of the box: ```typescript -import { ReclaimProofRequest, Proof } from '@reclaimprotocol/js-sdk'; +import { ReclaimProofRequest, Proof } from "@reclaimprotocol/js-sdk"; -const reclaimProofRequest: ReclaimProofRequest = await ReclaimProofRequest.init( - appId, - appSecret, - providerId -); +const reclaimProofRequest: ReclaimProofRequest = await ReclaimProofRequest.init(appId, appSecret, providerId); const handleSuccess = (proofs: Proof): void => { - console.log('Proof received:', proofs.identifier); + console.log("Proof received:", proofs.identifier); }; ``` diff --git a/content/docs/js-sdk/client-integration.mdx b/content/docs/js-sdk/client-integration.mdx index 84024fd..6bc23a7 100644 --- a/content/docs/js-sdk/client-integration.mdx +++ b/content/docs/js-sdk/client-integration.mdx @@ -9,6 +9,12 @@ This section covers advanced client-side integration patterns for different fram For most use cases, the [Quickstart](/js-sdk/quickstart) and [Recommended Setup](/js-sdk/recommended-setup) guides provide everything you need. This section is for advanced customization and framework-specific optimizations. + +**Advanced Configuration Options** + +Looking for modal customization, callback URLs, custom parameters, or extension configuration? See the [API Reference → Advanced Configuration](/js-sdk/api-reference#advanced-configuration) section for complete documentation. + + ## Available Guides ### React Integration diff --git a/content/docs/js-sdk/index.mdx b/content/docs/js-sdk/index.mdx index e59986b..f595f05 100644 --- a/content/docs/js-sdk/index.mdx +++ b/content/docs/js-sdk/index.mdx @@ -17,11 +17,157 @@ The Reclaim JavaScript SDK enables you to integrate cryptographic proof generati - 🎨 **Customizable UI**: Configure modal appearance, themes, and callbacks - 📱 **Mobile-First**: Native support for iOS App Clips and Android Instant Apps +## Get Your API Credentials + + +**🔑 Required: Get Your API Credentials First** + +Before you can use the SDK, you **must** obtain your API credentials from the Reclaim Protocol dashboard. + +**[Get Your API Credentials Now →](/api-key)** + +You'll need: +- **`APP_ID`**: Your unique application identifier +- **`APP_SECRET`**: Your application secret key (keep secure!) +- **`PROVIDER_ID`**: The data provider you want to verify (e.g., "google-login") + +These credentials are required for all code examples below. + + +## Quick Start + +Want to see it in action? Here's a practical React example to get started: + + +**⚠️ Development Only** + +This example initializes the SDK client-side for quick testing and learning. **Never use this approach in production** as it exposes your `APP_SECRET` in the frontend code. + +**For production apps:** See [Recommended Setup →](/js-sdk/recommended-setup) below. + + +### Installation + +First, install the SDK: + +```bash +npm install @reclaimprotocol/js-sdk +``` + +### React Example + +```jsx +import React, { useState, useEffect } from 'react'; +import { ReclaimProofRequest } from '@reclaimprotocol/js-sdk'; + +function App() { + const [reclaimProofRequest, setReclaimProofRequest] = useState(null); + const [proofs, setProofs] = useState(null); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(null); + + // Initialize the SDK + useEffect(() => { + async function initializeReclaim() { + try { + const proofRequest = await ReclaimProofRequest.init( + 'YOUR_APP_ID', + 'YOUR_APP_SECRET', + 'YOUR_PROVIDER_ID' + ); + setReclaimProofRequest(proofRequest); + } catch (err) { + setError('Failed to initialize SDK: ' + err.message); + } + } + initializeReclaim(); + }, []); + + // Handle verification + async function handleVerification() { + if (!reclaimProofRequest) return; + + setLoading(true); + setError(null); + + try { + // Trigger the verification flow (auto-detects platform) + await reclaimProofRequest.triggerReclaimFlow(); + + // Start session and handle results + await reclaimProofRequest.startSession({ + onSuccess: (proofs) => { + console.log('Verification successful:', proofs); + setProofs(proofs); + setLoading(false); + }, + onFailure: (error) => { + console.error('Verification failed:', error); + setError(error.message || 'Verification failed'); + setLoading(false); + }, + }); + } catch (err) { + setError(err.message || 'Failed to start verification'); + setLoading(false); + } + } + + return ( +
+

Reclaim Protocol Demo

+ + + + {error && ( +
+ Error: {error} +
+ )} + + {proofs && ( +
+

✅ Verification Successful!

+
+            {JSON.stringify(proofs, null, 2)}
+          
+
+ )} +
+ ); +} + +export default App; +``` + +**Try other frameworks?** See [Quickstart Guide →](/js-sdk/quickstart) for vanilla JavaScript, Vue, and more examples. + +**Ready for production?** Check out our [Recommended Setup →](/js-sdk/recommended-setup) with secure backend integration. + ## Two Integration Approaches ### 1. Client-Side Only (Development & Prototyping) -**Quick setup for development** - Initialize and handle everything in the browser: +**Quick setup for development** - Initialize and handle everything in the browser (like the example above): - Initialize SDK directly in frontend - Start verification session @@ -31,19 +177,16 @@ The Reclaim JavaScript SDK enables you to integrate cryptographic proof generati **Use cases**: Development, prototyping, learning, proof-of-concept demos -**Security Note**: Use this approach for **development purposes only**. - -If using client-side initialization: +**Security Note**: This approach is for **development purposes only**. - Store `APP_ID` and `APP_SECRET` in `.env` file (never hardcode) - Never commit credentials to version control - **Do not deploy to production** with this approach **Recommended**: Always initialize from backend in production environments to keep `APP_SECRET` secure. - -[Try Client-Side Quickstart →](/js-sdk/quickstart) +[See More Client-Side Examples →](/js-sdk/quickstart) ### 2. Backend Integration (Production-Ready) ⭐ @@ -123,89 +266,18 @@ The `triggerReclaimFlow()` method handles all platform detection automatically. →](https://blog.reclaimprotocol.org/posts/moving-beyond-google-play-instant) -## Advanced Configuration & Customization - -The SDK provides extensive customization options for the verification flow and UI. All features from the [Reclaim JS SDK](https://github.com/reclaimprotocol/reclaim-js-sdk#advanced-configuration) can be used: - -### Modal Customization - -Configure the QR code modal appearance and behavior: - -```javascript -reclaimProofRequest.setModalOptions({ - // Theme - darkTheme: true, // Enable dark mode - - // Text customization - title: "Verify Your Account", - description: "Scan QR code with your mobile device", - - // Behavior - modalPopupTimer: 5, // Auto-close after 5 minutes - - // Browser extension - showExtensionInstallButton: true, // Show extension install prompt - extensionUrl: "custom-extension-url", - - // Callbacks - onClose: () => { - console.log("Modal closed by user"); - }, -}); -``` - -### Context Addition - -Add custom context/metadata to your proof requests: - -```javascript -reclaimProofRequest.addContext("0x00000000000", "Custom context message or metadata"); -``` - -### Browser Extension Configuration +## Advanced Configuration -Configure browser extension behavior during initialization: - -```javascript -const reclaimProofRequest = await ReclaimProofRequest.init(APP_ID, APP_SECRET, PROVIDER_ID, { - useBrowserExtension: true, // Enable/disable extension (default: true) - extensionID: "custom-extension-id", // Custom extension identifier -}); -``` +The SDK provides extensive customization options for the verification flow and UI: -### Check Extension Availability +- **Modal Customization**: Configure QR code modal appearance, themes, and behavior +- **Custom Parameters**: Add metadata with `setParams()` and `addContext()` +- **Browser Extension**: Configure extension detection and behavior +- **Callback URLs**: Set backend callback URLs for direct proof delivery +- **Custom Redirects**: Configure post-verification redirect URLs +- **Session Callbacks**: Handle `onSuccess` and `onFailure` events -Conditionally show UI based on extension availability: - -```javascript -const hasExtension = await reclaimProofRequest.isBrowserExtensionAvailable(); - -if (hasExtension) { - // Show "Verify with Extension" button -} else { - // Show "Scan QR Code" message -} -``` - -### Session Callbacks - -Handle verification results with detailed callbacks: - -```javascript -await reclaimProofRequest.startSession({ - onSuccess: (proofs) => { - // Handle successful verification - // proofs can be either a string message or proof object - console.log("Verification successful:", proofs); - }, - onFailure: (error) => { - // Handle verification errors - console.error("Verification failed:", error); - }, -}); -``` - -For complete configuration options and examples, see the [Advanced Configuration documentation](https://github.com/reclaimprotocol/reclaim-js-sdk#advanced-configuration). +For complete configuration options, methods, and code examples, see the **[API Reference →](/js-sdk/api-reference#advanced-configuration)** ## Framework Support @@ -238,15 +310,11 @@ The SDK works seamlessly with popular frameworks: Choose your integration path: 1. **[Installation](/js-sdk/installation)** - Install the SDK via npm or yarn -2. **[Quickstart](/js-sdk/quickstart)** - Quick client-side demo for learning (dev only) -3. **[Recommended Setup](/js-sdk/recommended-setup)** - Production-ready backend initialization ⭐ -4. **[API Reference](/js-sdk/api-reference)** - Complete SDK documentation +2. **[Quickstart](/js-sdk/quickstart)** - More client-side examples (vanilla JS, Vue, etc.) +3. **[Recommended Setup](/js-sdk/recommended-setup)** - Production-ready backend integration ⭐ +4. **[API Reference](/js-sdk/api-reference)** - Complete SDK documentation & advanced config 5. **[Troubleshooting](/js-sdk/troubleshooting)** - Common issues and solutions -## Get API Credentials - -Before integrating, you'll need API credentials (`APP_ID`, `APP_SECRET`, and `PROVIDER_ID`). Follow the [Get API Key guide](/api-key) to set up your Reclaim Protocol project. - ## Need Help? - 📖 [Complete API Reference](/js-sdk/api-reference) diff --git a/content/docs/js-sdk/quickstart.mdx b/content/docs/js-sdk/quickstart.mdx index 60da3a8..164bf47 100644 --- a/content/docs/js-sdk/quickstart.mdx +++ b/content/docs/js-sdk/quickstart.mdx @@ -20,6 +20,14 @@ This quickstart guide shows **client-side initialization** which exposes your `A The quickstart approach lets you experience the Reclaim verification flow in minutes by initializing the SDK directly in your frontend code. This is the fastest way to understand how the SDK works, but it's not secure for production use. + +**Quick Example Available** + +Looking for a simple React example to try immediately? Check out the [Quick Start section on the main JS SDK page](/js-sdk#quick-start) for a practical React component you can use right away. + +This page provides additional examples for vanilla JavaScript, Vue, and alternative integration methods. + + ## Prerequisites - ✅ Installed the SDK following the [Installation guide](/js-sdk/installation) diff --git a/content/docs/js-sdk/recommended-setup/index.mdx b/content/docs/js-sdk/recommended-setup/index.mdx index 5966fbe..01df26a 100644 --- a/content/docs/js-sdk/recommended-setup/index.mdx +++ b/content/docs/js-sdk/recommended-setup/index.mdx @@ -353,6 +353,8 @@ Before deploying to production: 3. **[API Reference →](/js-sdk/api-reference)** - Complete SDK documentation +4. **[Advanced Configuration →](/js-sdk/api-reference#advanced-configuration)** - Modal customization, callbacks, parameters, and more + ## Need Help? - 📖 [Troubleshooting Guide](/js-sdk/troubleshooting) diff --git a/content/docs/meta.json b/content/docs/meta.json index cc77081..113f149 100644 --- a/content/docs/meta.json +++ b/content/docs/meta.json @@ -4,7 +4,6 @@ "index", "api-key", "js-sdk", - "web", "browser-extension", "react-native", "ios-swift",