Skip to content

Latest commit

 

History

History
461 lines (434 loc) · 23.5 KB

File metadata and controls

461 lines (434 loc) · 23.5 KB

On-Chain Badge System - Architecture Flow

🏗️ System Architecture

┌─────────────────────────────────────────────────────────────────┐
│                         LANCEPAY FRONTEND                        │
│                                                                  │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐          │
│  │ Badge Gallery│  │ Profile Page │  │ Verification │          │
│  │   Component  │  │   Component  │  │    Widget    │          │
│  └──────┬───────┘  └──────┬───────┘  └──────┬───────┘          │
│         │                 │                   │                  │
└─────────┼─────────────────┼───────────────────┼──────────────────┘
          │                 │                   │
          │ Auth Token      │ Auth Token        │ No Auth
          │                 │                   │
┌─────────▼─────────────────▼───────────────────▼──────────────────┐
│                      API LAYER (Next.js)                          │
│                                                                   │
│  ┌────────────────────────────────────────────────────────────┐  │
│  │           /api/routes-d/reputation/                        │  │
│  │                                                            │  │
│  │  🔒 GET  /badges          → Get all badges + eligibility  │  │
│  │  🔒 POST /badges          → Claim a badge                 │  │
│  │  🌐 GET  /badges/verify   → Public verification          │  │
│  │  🌐 GET  /profile/:userId → Public badge profile         │  │
│  └────────────────────────────────────────────────────────────┘  │
│                                                                   │
│                            ↓                                      │
│                                                                   │
│  ┌────────────────────────────────────────────────────────────┐  │
│  │                   BUSINESS LOGIC                           │  │
│  │                                                            │  │
│  │  lib/badges.ts:                                           │  │
│  │  • checkBadgeEligibility()  → Evaluate criteria          │  │
│  │  • getUserBadgeStatus()     → Get user's badges          │  │
│  │  • seedPredefinedBadges()   → Initialize system          │  │
│  │                                                            │  │
│  │  lib/stellar.ts:                                          │  │
│  │  • issueSoulboundBadge()    → Mint on Stellar           │  │
│  │  • configureBadgeIssuer()   → Setup issuer               │  │
│  │  • hasBadge()               → Verify ownership           │  │
│  └────────────────────────────────────────────────────────────┘  │
└───────────────────────────┬──────────────────┬────────────────────┘
                            │                  │
                    ┌───────▼──────┐   ┌──────▼──────┐
                    │  PostgreSQL  │   │   Stellar   │
                    │   Database   │   │  Blockchain │
                    └──────────────┘   └─────────────┘

🔄 Badge Claiming Flow

┌─────────┐
│  User   │
│ Requests│
│  Badge  │
└────┬────┘
     │
     ▼
┌─────────────────────────────────────┐
│ 1️⃣  Authentication Check            │
│    • Verify auth token              │
│    • Get user from database         │
└────┬────────────────────────────────┘
     │ ✅ Valid
     ▼
┌─────────────────────────────────────┐
│ 2️⃣  Badge Validation                │
│    • Badge exists?                  │
│    • Badge is active?               │
│    • Already claimed?               │
└────┬────────────────────────────────┘
     │ ✅ Valid
     ▼
┌─────────────────────────────────────┐
│ 3️⃣  Eligibility Check               │
│    • Evaluate criteria type         │
│    • Query user's data              │
│    • Calculate metrics              │
│    • Compare vs requirements        │
└────┬────────────────────────────────┘
     │ ✅ Eligible
     ▼
┌─────────────────────────────────────┐
│ 4️⃣  Wallet Verification             │
│    • User has wallet?               │
│    • Wallet address valid?          │
└────┬────────────────────────────────┘
     │ ✅ Has Wallet
     ▼
┌─────────────────────────────────────┐
│ 5️⃣  Stellar Soulbound Minting       │
│    • Create trustline (limit: 1)   │
│    • Send 1 badge token             │
│    • Record transaction hash        │
└────┬────────────────────────────────┘
     │ ✅ Minted
     ▼
┌─────────────────────────────────────┐
│ 6️⃣  Database Recording              │
│    • Create UserBadge record        │
│    • Store stellar TX hash          │
│    • Mark as issued                 │
└────┬────────────────────────────────┘
     │ ✅ Recorded
     ▼
┌─────────────────────────────────────┐
│ 7️⃣  Response to User                │
│    • Return badge details           │
│    • Include TX hash                │
│    • Provide explorer link          │
└─────────────────────────────────────┘

🎯 Eligibility Evaluation Flow

┌────────────────────┐
│ Badge Criteria     │
│ (from JSON)        │
└────────┬───────────┘
         │
         ▼
    ┌────────────┐
    │ Type Check │
    └─┬──┬──┬──┬─┘
      │  │  │  │
  ┌───┘  │  │  └───┐
  │      │  │      │
  ▼      ▼  ▼      ▼
┌───────────────────────────────────────────────────────────────┐
│                                                               │
│  REVENUE        INVOICES     ZERO_DISPUTES   COMPLETION_RATE │
│                                                               │
│  Query total    Query paid   Query invoice   Calculate %     │
│  transaction    invoice      + dispute       completion      │
│  amounts        count        count           rate            │
│                                                               │
│  Compare to     Compare to   Check both      Compare to      │
│  minRevenue     minInvoices  criteria        minRate         │
│                                                               │
└───────┬─────────────┬─────────────┬─────────────┬────────────┘
        │             │             │             │
        └─────────────┴─────────────┴─────────────┘
                       │
                       ▼
              ┌─────────────────┐
              │  Eligible: Y/N  │
              │  Reason: string │
              └─────────────────┘

🔐 Soulbound Token Implementation

                      ┌─────────────────┐
                      │  Badge Issuer   │
                      │  (Platform)     │
                      └────────┬────────┘
                               │
                               │ Issues Badge Asset
                               │
         ┌─────────────────────┼─────────────────────┐
         │                     │                     │
         ▼                     ▼                     ▼
    ┌─────────┐         ┌─────────┐         ┌─────────┐
    │ User A  │         │ User B  │         │ User C  │
    │ (Earned)│         │ (Earned)│         │(Pending)│
    └─────────┘         └─────────┘         └─────────┘
         │                     │
         │                     │
         ▼                     ▼
    Can view in           Can view in
    Stellar wallet        Stellar wallet
         │                     │
         ├─────────────────────┤
         │                     │
         ▼                     ▼
    ❌ CANNOT TRANSFER    ❌ CANNOT TRANSFER

    Why? 
    1. Trustline limited to 1 badge
    2. Issuer doesn't authorize new holders
    3. Stellar network enforces restrictions

📊 Database Schema Relationships

┌──────────────────┐
│      User        │
│──────────────────│
│ id (PK)          │◄─────┐
│ privyId          │      │
│ email            │      │
│ name             │      │
└──────────────────┘      │
         ▲                │
         │                │
         │                │
┌────────┴──────────┐     │
│    UserBadge       │     │
│────────────────────│     │
│ id (PK)            │     │
│ userId (FK) ───────┼─────┘
│ badgeId (FK) ──────┼─────┐
│ stellarTxHash      │     │
│ issuedAt           │     │
└────────────────────┘     │
                           │
                           │
             ┌─────────────┘
             │
             ▼
┌────────────────────────┐
│   BadgeDefinition      │
│────────────────────────│
│ id (PK)                │
│ name                   │
│ description            │
│ criteriaJson           │
│ stellarAssetCode       │
│ imageUrl               │
│ isActive               │
└────────────────────────┘

🌐 Public Verification Flow

┌────────────────────────┐
│  External Website      │
│  (LinkedIn, Portfolio) │
└───────────┬────────────┘
            │
            │ Embed verification URL
            │ ?userId=xxx&badgeId=yyy
            ▼
┌──────────────────────────────────┐
│  GET /badges/verify              │
│  (No authentication required)    │
└───────────┬──────────────────────┘
            │
            ▼
┌──────────────────────────────────┐
│  1. Query UserBadge in DB        │
└───────────┬──────────────────────┘
            │ Found
            ▼
┌──────────────────────────────────┐
│  2. Get user's wallet address    │
└───────────┬──────────────────────┘
            │
            ▼
┌──────────────────────────────────┐
│  3. Check Stellar blockchain     │
│     hasBadge(wallet, assetCode)  │
└───────────┬──────────────────────┘
            │
            ▼
┌──────────────────────────────────┐
│  4. Return verification result   │
│     • verified: true/false       │
│     • badge details              │
│     • user info                  │
│     • stellar TX hash            │
│     • explorer link              │
└──────────────────────────────────┘

🔄 System Initialization

┌─────────────────────┐
│  setup-badges.sh    │
│  (or manual steps)  │
└──────────┬──────────┘
           │
           ▼
┌─────────────────────────────────────┐
│ 1. npx prisma generate              │
│    → Generate Prisma client         │
└──────────┬──────────────────────────┘
           │
           ▼
┌─────────────────────────────────────┐
│ 2. npx prisma migrate dev           │
│    → Create BadgeDefinition         │
│    → Create UserBadge               │
│    → Add indexes                    │
└──────────┬──────────────────────────┘
           │
           ▼
┌─────────────────────────────────────┐
│ 3. Generate Stellar keypair         │
│    → Public key = issuer address    │
│    → Secret key = BADGE_ISSUER_KEY  │
└──────────┬──────────────────────────┘
           │
           ▼
┌─────────────────────────────────────┐
│ 4. Fund issuer account              │
│    → Send XLM for transaction fees  │
└──────────┬──────────────────────────┘
           │
           ▼
┌─────────────────────────────────────┐
│ 5. npx tsx scripts/init-badges.ts   │
│    → Seed 5 predefined badges       │
│    → Configure issuer flags         │
└──────────┬──────────────────────────┘
           │
           ▼
┌─────────────────────────────────────┐
│ ✅ System Ready                     │
│    Users can now claim badges!      │
└─────────────────────────────────────┘

🎮 User Journey

┌──────────────┐
│ Freelancer   │
│ signs up     │
└──────┬───────┘
       │
       ▼
┌──────────────────────┐
│ Completes work       │
│ • Creates invoices   │
│ • Gets paid          │
│ • Builds reputation  │
└──────┬───────────────┘
       │
       ▼
┌──────────────────────────────┐
│ Views badge gallery          │
│ • Sees 5 available badges    │
│ • Checks eligibility status  │
│ • Some locked, some unlocked │
└──────┬───────────────────────┘
       │
       ▼
┌───────────────────────────────────┐
│ Meets criteria for badge          │
│ Example: 10+ paid invoices        │
│ Badge shows "Eligible - Claim!"   │
└──────┬────────────────────────────┘
       │
       ▼
┌───────────────────────────────────┐
│ Clicks "Claim Badge"              │
│ • Server validates eligibility    │
│ • Mints soulbound token           │
│ • Records in database             │
└──────┬────────────────────────────┘
       │
       ▼
┌───────────────────────────────────┐
│ Badge appears in wallet           │
│ • Visible on Stellar Expert       │
│ • Cannot be transferred           │
│ • Permanent credential            │
└──────┬────────────────────────────┘
       │
       ▼
┌───────────────────────────────────┐
│ Shares on LinkedIn/Portfolio      │
│ • Uses verification URL           │
│ • Anyone can verify authenticity  │
│ • Links to blockchain proof       │
└───────────────────────────────────┘

🛡️ Security Layers

┌─────────────────────────────────────────┐
│          Security Layer 1                │
│         Authentication Required          │
│  • JWT token validation (Privy)         │
│  • User must be logged in               │
└───────────────┬─────────────────────────┘
                │
                ▼
┌─────────────────────────────────────────┐
│          Security Layer 2                │
│        Server-Side Validation            │
│  • Eligibility checked against real DB  │
│  • No client-side criteria bypass       │
└───────────────┬─────────────────────────┘
                │
                ▼
┌─────────────────────────────────────────┐
│          Security Layer 3                │
│         Database Constraints             │
│  • UNIQUE (userId, badgeId)             │
│  • Prevents duplicate claims            │
└───────────────┬─────────────────────────┘
                │
                ▼
┌─────────────────────────────────────────┐
│          Security Layer 4                │
│      Blockchain Immutability             │
│  • Stellar enforces soulbound property  │
│  • Transaction hash = proof              │
│  • Cannot be revoked or altered         │
└─────────────────────────────────────────┘

📈 Performance Considerations

Operation                    | Expected Time | Optimization
─────────────────────────────|──────────────|─────────────────
GET /badges (list)           | < 500ms      | Index on userId
POST /badges (claim)         | 3-8s         | Stellar network
Eligibility calculation      | < 200ms      | DB query optimization
Public verification          | < 300ms      | Cache badge definitions
Stellar block confirmation   | 5-10s        | Network dependent

🔗 External Integrations

┌──────────────┐
│   LancePay   │
└──────┬───────┘
       │
       ├────────────► Stellar Network
       │              • Badge minting
       │              • On-chain storage
       │              • Transaction verification
       │
       ├────────────► PostgreSQL
       │              • User data
       │              • Badge definitions
       │              • Earned badges
       │
       ├────────────► Privy
       │              • Authentication
       │              • User management
       │
       └────────────► Stellar Expert
                      • Block explorer
                      • Public verification

Visual Architecture Guide On-Chain Badge System for LancePay Last Updated: January 27, 2026