vlayer docs

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

  1. Enter GitHub repository details

    • GitHub owner (organization or username)
    • Repository name
    • Your GitHub username to verify
  2. Click "Start Verification"

    The app will redirect you to vouch, which handles the proof generation process.

  3. vouch processes the verification

    vouch generates a web proof of your GitHub contributions and sends it to your webhook endpoint.

  4. 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 install

Start Development Server

npm run dev

Visit 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/sdk

2. 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 session
  • datasourceId - vouch datasource ID for GitHub contributors
  • customerId - Your vouch customer ID
  • redirectBackUrl - Where vouch redirects after verification (includes requestId as query param)
  • webhookUrl - Your HTTPS endpoint to receive the proof
  • inputs - 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:

  1. Customize the UI - Build your own proof display components
  2. Add more datasources - vouch supports multiple data sources beyond GitHub
  3. Implement proof verification - Add on-chain verification of the proofs
  4. Build custom workflows - Use proofs for access control, airdrops, or reputation systems
  5. Analytics and monitoring - Track verification patterns and user behavior