Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

46 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Veryfy — On-Chain License Verification Protocol

A full-stack, decentralised license verification system built on Solana. Issuers mint tamper-proof, on-chain licenses tied to off-chain assets; anyone can verify them in seconds without trusting a central authority.


Table of Contents


Overview

Veryfy solves the problem of digital license forgery. Traditional licensing platforms store license data in centralised databases — which can be manipulated, lost, or taken offline. Veryfy records every license directly on the Solana blockchain, making each one:

  • Immutable — once issued, the record cannot be silently altered.
  • Publicly verifiable — anyone with a license identifier can confirm its validity without contacting the issuer.
  • Permissioned — only registered issuers can create or revoke licenses; revocation is also recorded on-chain.

Smart Contract (contract/)

Built with Anchor 0.32.1 on Solana. The program ID is:

F2NmTxchnwJJTbCLCAkFa3c8RYXE8PL5ToZwoao8jvD3

On-Chain Accounts

Account Seeds Fields
Issuer ["issuer", authority_pubkey] authority, name (≤64 chars), issued_count, bump
License ["license", asset_hash] holder, issuer, status, expiry, asset_hash, bump

License Status Lifecycle

register_issuer()
        │
        ▼
   [Issuer PDA]
        │
   issue_license()
        │
        ▼
   Active  ──── revoke_license() ──▶  Revoked
     │
   (expiry timestamp reached)
     │
     ▼
   Expired

Instructions

Instruction Signer Description
register_issuer(name) Payer Creates an Issuer PDA for the calling wallet
issue_license(asset_hash, expiry) Payer (authority) Mints a License PDA linked to a 32-byte asset hash; expiry = 0 means never expires
revoke_license(asset_hash) Authority Marks an existing license as Revoked; only the original issuing authority may call this
renew_license Authority (In development) Extends the expiry of an existing license

Events

Event Emitted When
LicenseIssued A new license is successfully created

Custom Errors

Code Message Trigger
UnauthorizedIssuer Unauthorized issuer Signer does not match the authority stored on the Issuer account
MathOverflow Math overflow issued_count arithmetic would overflow
NotImplemented Feature not yet implemented Stub instruction placeholders

REST API (api/)

A lightweight Go HTTP server with no external framework dependencies. It provides a JSON bridge for clients that cannot interact directly with Solana RPC.

Module: github.com/odingaval/veryfy/api
Go version: 1.26+

Middleware Stack (applied in order)

  1. Recover — catches panics and returns 500 with structured JSON.
  2. RequestLogger — structured slog request/response logging.
  3. CORS — configurable allowed origins.
  4. Timeout — per-request deadline enforcement.

Service Layer

Service Responsibility
HashService Deterministic SHA-256 hashing of asset content / URLs to produce the 32-byte asset_hash
LicenseService Issue, verify, and revoke licenses; delegates to repository
IssuerService Register issuers; delegates to repository

Repository

MemoryRepository provides a thread-safe, in-memory store suitable for development and testing. It can be replaced by a database-backed implementation without changing the service or handler layers (interface-driven design).


Web Frontend (web/)

A React 18 + Vite 6 single-page application styled with Tailwind CSS v4 and shadcn/ui (Radix UI primitives).

Pages

Route (in-app state) Component Purpose
landing Landing.tsx Hero section, feature overview, navigation CTAs
issue IssuerDashboard.tsx Connect wallet, upload asset, issue / revoke on-chain licenses
verify PublicVerify.tsx Paste a license ID or asset hash; fetches and displays on-chain status

Key Dependencies

Package Purpose
@coral-xyz/anchor ^0.32.1 Type-safe Anchor client for on-chain instruction calls
@solana/wallet-adapter-* Multi-wallet connection (Phantom, Solflare, etc.)
@solana/web3.js ^1.98 Core Solana RPC interactions
react-router 7 Client-side navigation
recharts Analytics charts in the Issuer Dashboard
sonner Toast notifications
motion Framer-Motion-compatible animations
lucide-react Icon library

Getting Started

Prerequisites

Tool Version Install
Rust stable rustup install stable
Solana CLI ≥ 1.18 docs.solana.com/cli/install
Anchor CLI 0.32.1 cargo install --git https://github.com/coral-xyz/anchor avm --locked && avm install 0.32.1
Go ≥ 1.26 go.dev/dl
Node.js ≥ 20 nvm install 20
pnpm ≥ 9 npm i -g pnpm

Running the Smart Contract

cd contract

# 1. Start a local validator
solana-test-validator --reset &

# 2. Set Solana CLI to localnet
solana config set --url localhost

# 3. Build the Anchor program
anchor build

# 4. Deploy to localnet
anchor deploy

# 5. Run integration tests
anchor test --skip-local-validator

Running the API

cd api

# Copy and edit environment config (see internal/config for supported vars)
cp .env.example .env   # or set env vars directly

# Run the server
go run ./cmd/server

# Default: listens on :8080
# Health check:
curl http://localhost:8080/health

Environment Variables

Variable Default Description
PORT 8080 HTTP listen port
ALLOWED_ORIGINS * Comma-separated CORS origins
REQUEST_TIMEOUT 30s Per-request deadline

Running the Web App

cd web

# Install dependencies
pnpm install

# Start the dev server
pnpm dev
# → http://localhost:5173

To build for production:

pnpm build

API Reference

All responses use the envelope { "data": ... } on success and { "error": { "code": "...", "message": "..." } } on failure.

GET /health

Returns server uptime and readiness status.

{
  "data": {
    "status": "ok",
    "service": "veryfy-api",
    "uptimeSec": 42
  }
}

POST /issuers/register

Register a new issuer.

Request

{ "name": "Acme Corp", "authority": "<solana-pubkey>" }

POST /licenses/issue

Issue a new license for an asset.

Request

{
  "assetUrl": "https://example.com/asset.pdf",
  "holderAddress": "<solana-pubkey>",
  "expiryTimestamp": 1893456000
}

POST /licenses/verify

Verify whether a license is active.

Request

{ "assetHash": "<hex-encoded-32-byte-hash>" }

POST /licenses/revoke

Revoke an existing license.

Request

{ "assetHash": "<hex-encoded-32-byte-hash>", "authority": "<solana-pubkey>" }

Tech Stack

Layer Technology
Blockchain Solana
Smart Contract Rust · Anchor 0.32.1
Backend API Go 1.26 · net/http
Frontend React 18 · TypeScript · Vite 6
Styling Tailwind CSS v4 · shadcn/ui · Radix UI
Wallet Solana Wallet Adapter
State Management React useState / custom hooks
Testing Mocha (contract) · Go testing package (API)

Contributing

  1. Fork the repository and create a feature branch: git checkout -b feat/your-feature.
  2. Follow the existing code style — rustfmt for Rust, gofmt for Go, ESLint/Prettier for TypeScript.
  3. Add or update tests for any new behaviour.
  4. Open a pull request with a clear description of the change.

License

This project is MIT licensed. See LICENSE for details.

About

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages