Fullstack vouch Github Prover Tutorial
This guide demonstrates how to use vlayer's vouch service in a fullstack Next.js application to verify GitHub contributions.
Architecture Overview
The application follows a webhook-based architecture:
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ Browser │ ───> │ vouch │ ───> │ vlayer │ │ │
│ (Client) │ <─── │ │ │ Web │ ───> │ Your App │
│ │ │ │ │ Prover │ │ Webhook │
└──────────┘ └──────────┘ └──────────┘ └──────────┘
│ │
└───────────────── Fetch proof ────────────────────────┘Usage
-
Enter GitHub repository details
- GitHub owner (organization or username)
- Repository name
- Your GitHub username to verify
-
Click "Start Verification"
The app will redirect you to vouch, which handles the proof generation process.
-
vouch processes the verification
vouch generates a web proof of your GitHub contributions and sends it to your webhook endpoint.
-
View your verified contributions
After vouch redirects back to your app, the verified proof is displayed.
Prerequisites
- Node.js 20+
- PostgreSQL database (we recommend Neon for serverless Postgres)
- vouch datasource ID and customer ID
Installation
Clone the repository and install dependencies:
git clone https://github.com/vlayer-xyz/vouch-github-verifier.git
cd vouch-github-verifier
npm installStart Development Server
npm run devVisit http://localhost:3000 to see the application.
Frontend: Initiating Verification
The frontend orchestrates the verification flow using the vouch SDK. View the complete implementation at app/page.tsx.
Key Components
1. Installing vouch SDK
npm install @getvouch/sdk2. Generating a Request ID
import { Vouch } from '@getvouch/sdk';
const startVerification = () => {
const vouch = new Vouch();
const requestId = window.crypto.randomUUID();
// Store requestId for later retrieval
localStorage.setItem('lastRequestId', requestId);
// ... continue with vouch setup
};The requestId is a UUID that links the webhook callback to the user's session. This allows your app to retrieve the correct proof after vouch redirects back.
3. Constructing the vouch URL
const webhookBaseUrl = process.env.NEXT_PUBLIC_WEBHOOK_URL || window.location.origin;
const verificationUrl = vouch.getStartUrl({
requestId: requestId,
datasourceId: "ee72bdf7-cf47-424a-9705-75a96e39153e",
customerId: "1be03be8-5014-413c-835a-feddf4020da2",
redirectBackUrl: `${window.location.origin}?requestId=${requestId}`,
webhookUrl: `${webhookBaseUrl}/api/web-proof`,
inputs: {
github_owner: githubOwner,
github_repo: githubRepo,
github_username: githubUsername
}
});
window.location.href = verificationUrl.toString();Parameter breakdown:
requestId- Your unique identifier for this verification sessiondatasourceId- vouch datasource ID for GitHub contributorscustomerId- Your vouch customer IDredirectBackUrl- Where vouch redirects after verification (includesrequestIdas query param)webhookUrl- Your HTTPS endpoint to receive the proofinputs- Custom data passed to the datasource (GitHub details in this case)
The webhookUrl must be publicly accessible via HTTPS. For local development, use a service like ngrok or deploy to Vercel.
4. Fetching the Proof After Redirect
const searchParams = useSearchParams();
const requestId = searchParams?.get('requestId');
useEffect(() => {
const fetchProof = async () => {
if (!requestId) return;
setLoading(true);
try {
const response = await fetch(`/api/web-proof/${requestId}`);
if (response.ok) {
const data = await response.json();
setProof(data);
} else {
setError('Proof not found yet. It may still be processing.');
}
} catch (err) {
setError('Failed to fetch proof');
} finally {
setLoading(false);
}
};
fetchProof();
}, [requestId]);When vouch redirects back, the requestId is in the URL query parameters. The frontend uses it to fetch the proof from your database.
Backend: Webhook Endpoint
The webhook endpoint receives proofs from vouch and stores them in the database. View the complete implementation at app/api/web-proof/route.ts.
import { prisma } from '@/lib/prisma';
import { NextRequest, NextResponse } from 'next/server';
export async function POST(request: NextRequest) {
try {
const payload = await request.json();
// Extract requestId from payload
const requestId = payload.requestId || payload.request_id || null;
// Store the proof in the database using upsert
await prisma.webProof.upsert({
where: { proofId: payload.proofId || '' },
update: {
requestId: requestId,
payload: payload,
},
create: {
proofId: payload.proofId || '',
requestId: requestId,
payload: payload,
},
});
return NextResponse.json({ success: true }, { status: 200 });
} catch (error) {
console.error('Error storing web proof:', error);
return NextResponse.json(
{ error: 'Failed to store web proof' },
{ status: 500 }
);
}
}Next Steps
Now that you understand the vouch integration, you can:
- Customize the UI - Build your own proof display components
- Add more datasources - vouch supports multiple data sources beyond GitHub
- Implement proof verification - Add on-chain verification of the proofs
- Build custom workflows - Use proofs for access control, airdrops, or reputation systems
- Analytics and monitoring - Track verification patterns and user behavior