Skip to content

Need a controlled medication in any country? No problem TravelScript has you covered.

Notifications You must be signed in to change notification settings

Hoblayerta/TravelScript

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

5 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ₯ TravelScript

International Prescription Validation with Dual-Doctor Zero-Knowledge Proofs on Flare

Flare EVVM FDC Semaphore

Enabling trustless international healthcare through zero-knowledge proofs and decentralized verification on Flare Network


🎯 The Problem

When patients travel internationally, their medical prescriptions face critical challenges:

  • 🚫 Not Recognized: Prescriptions from home countries aren't accepted abroad
  • ⚠️ No Verification: Pharmacies can't verify foreign prescriptions' authenticity
  • πŸ”“ Privacy Concerns: Traditional verification exposes sensitive medical data
  • πŸ“ Manual Processes: Paper-based systems prone to fraud and errors
  • 🌍 Regulatory Gaps: No international standard for cross-border prescriptions

Real Impact: Millions of travelers annually face medication access problems, leading to health risks and emergency room visits.


πŸ’‘ The Solution

TravelScript creates a decentralized, privacy-preserving prescription validation system using:

Core Innovation: Dual-Doctor ZK Proof System

Doctor 1 (Home Country)    β†’  Creates prescription with ZK proof
        ↓
Doctor 2 (Destination)     β†’  Validates prescription with ZK proof
        ↓
Flare FDC                  β†’  Attests prescription metadata on-chain
        ↓
Pharmacy (Anywhere)        β†’  Verifies and dispenses medication safely

Key Benefits:

  • βœ… Privacy-First: Doctors prove credentials without revealing identity
  • βœ… Trustless: No central authority, verified on Flare blockchain
  • βœ… International: Works across borders with local doctor validation
  • βœ… Fraud-Proof: ZK proofs + nullifier system prevents double-signing
  • βœ… Transparent: All verifications immutably recorded on-chain

πŸ—οΈ Architecture & Integrations

Technology Stack Overview

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    FRONTEND (Next.js 14)                        β”‚
β”‚  β€’ Doctor Registration Portal                                  β”‚
β”‚  β€’ Prescription Creation Interface                             β”‚
β”‚  β€’ Validation Dashboard                                        β”‚
β”‚  β€’ Pharmacy Verification Portal                                β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                         β”‚
                         ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                 INTEGRATION LAYER (TypeScript)                  β”‚
β”‚                                                                 β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚ FDC Client   β”‚  β”‚ EVVM         β”‚  β”‚ Semaphore ZK        β”‚ β”‚
β”‚  β”‚              β”‚  β”‚ Processor    β”‚  β”‚ Proof Generator     β”‚ β”‚
β”‚  β”‚ β€’ Request    β”‚  β”‚ β€’ Create Rx  β”‚  β”‚ β€’ Identity Gen      β”‚ β”‚
β”‚  β”‚ β€’ Verify     β”‚  β”‚ β€’ Validate   β”‚  β”‚ β€’ Proof Gen         β”‚ β”‚
β”‚  β”‚ β€’ Attest     β”‚  β”‚ β€’ Attest     β”‚  β”‚ β€’ Nullifier Track   β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚         β”‚                  β”‚                      β”‚             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
          β”‚                  β”‚                      β”‚
          ↓                  ↓                      ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚               FLARE COSTON2 BLOCKCHAIN                          β”‚
β”‚                                                                 β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚  PrescriptionHub.sol (0x6fB0ce...CBCC2E3)                β”‚  β”‚
β”‚  β”‚  βœ“ Dual-doctor verification                              β”‚  β”‚
β”‚  β”‚  βœ“ Semaphore ZK proof validation                         β”‚  β”‚
β”‚  β”‚  βœ“ Nullifier-based fraud prevention                      β”‚  β”‚
β”‚  β”‚  βœ“ FDC attestation storage                               β”‚  β”‚
β”‚  β”‚  βœ“ Pharmacy verification queries                         β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                                                                 β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚  EVVM (0x37628b...EC74)                                  β”‚  β”‚
β”‚  β”‚  βœ“ Custom chain support                                  β”‚  β”‚
β”‚  β”‚  βœ“ Gasless transactions (future)                         β”‚  β”‚
β”‚  β”‚  βœ“ Enhanced transaction processing                       β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                                                                 β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚  FDC Hub (0x1c78A0...B55b)                               β”‚  β”‚
β”‚  β”‚  βœ“ Metadata attestations                                 β”‚  β”‚
β”‚  β”‚  βœ“ Data availability layer                               β”‚  β”‚
β”‚  β”‚  βœ“ Cryptographic proof verification                      β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                                                                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ”— Technical Integration: EVVM + FDC + Semaphore

The Three-Layer Architecture

TravelScript uniquely combines three cutting-edge technologies to create a privacy-preserving, trustless prescription system:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  LAYER 1: SEMAPHORE (Privacy Layer)                            β”‚
β”‚  β€’ Zero-Knowledge Proofs                                        β”‚
β”‚  β€’ Anonymous Doctor Authentication                             β”‚
β”‚  β€’ Nullifier-Based Fraud Prevention                            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                     β”‚ ZK Proofs
                     ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  LAYER 2: EVVM (Execution Layer)                               β”‚
β”‚  β€’ Smart Contract Deployment (PrescriptionHub)                 β”‚
β”‚  β€’ On-Chain Verification Logic                                 β”‚
β”‚  β€’ Event Emission & State Management                           β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                     β”‚ Attestation Hash
                     ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  LAYER 3: FDC (Data Availability Layer)                        β”‚
β”‚  β€’ Metadata Attestation                                         β”‚
β”‚  β€’ Cryptographic Proof Generation                              β”‚
β”‚  β€’ Decentralized Data Verification                             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ”„ Complete Technical Flow

Step-by-Step Integration Breakdown

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  PHASE 1: DOCTOR 1 CREATES PRESCRIPTION                              β”‚
β”‚  Integration: SEMAPHORE β†’ EVVM                                       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

1️⃣ SEMAPHORE: Generate Doctor Identity
   β”œβ”€ Doctor connects wallet (0xDoctor1...)
   β”œβ”€ Frontend calls: createDoctorIdentity(walletAddress)
   β”‚  └─ Creates Semaphore identity
   β”‚     β€’ Commitment: Hash of identity secret
   β”‚     β€’ Private key: Exported for storage
   β”œβ”€ Store locally: { commitment, wallet, country, license }
   └─ βœ… Doctor registered anonymously

2️⃣ SEMAPHORE: Generate ZK Proof for Prescription
   β”œβ”€ Doctor fills prescription form (medication, dosage, etc.)
   β”œβ”€ Hash prescription data: keccak256(prescriptionData)
   β”œβ”€ Generate ZK proof:
   β”‚  Input:
   β”‚  β€’ Identity (private - stays in browser)
   β”‚  β€’ Prescription hash (public)
   β”‚  β€’ Group ID (1 = doctors group)
   β”‚  Output:
   β”‚  β€’ Proof array: uint256[8]
   β”‚  β€’ Nullifier: bytes32 (unique per prescription + doctor)
   β”‚  β€’ Merkle root: bytes32
   └─ βœ… Proof generated (proves doctor credentials without revealing identity)

3️⃣ EVVM: Submit to Blockchain
   β”œβ”€ Frontend calls: EVVMProcessor.createPrescription()
   β”œβ”€ Encodes prescription data:
   β”‚  └─ ABI.encode([patientName, medication, dosage, frequency, duration, notes])
   β”œβ”€ Submits transaction to PrescriptionHub contract:
   β”‚  └─ createPrescription(
   β”‚       prescriptionId: "RX-AR-20241123-001",
   β”‚       prescriptionData: encoded_data,
   β”‚       doctor1Proof: [uint256[8]],
   β”‚       doctor1Nullifier: 0xabc123...,
   β”‚       patientAddress: 0xPatient...
   β”‚     )
   β”œβ”€ SMART CONTRACT EXECUTES:
   β”‚  β”œβ”€ Verify prescription doesn't exist
   β”‚  β”œβ”€ Verify nullifier not used (prevents double-signing)
   β”‚  β”œβ”€ Call Semaphore.verifyProof() - ZK VERIFICATION
   β”‚  β”‚  └─ If proof invalid β†’ REVERT
   β”‚  β”œβ”€ Store prescription:
   β”‚  β”‚  └─ prescriptions[id] = Prescription({
   β”‚  β”‚       prescriptionHash: keccak256(data),
   β”‚  β”‚       doctor1Nullifier: 0xabc123...,
   β”‚  β”‚       doctor2Nullifier: 0x0,
   β”‚  β”‚       patientAddress: 0xPatient...,
   β”‚  β”‚       timestamp: block.timestamp,
   β”‚  β”‚       validated: false,
   β”‚  β”‚       active: true,
   β”‚  β”‚       fdcAttestationHash: 0x0
   β”‚  β”‚     })
   β”‚  β”œβ”€ Mark nullifier as used:
   β”‚  β”‚  └─ usedNullifiers[0xabc123...] = true
   β”‚  └─ Emit event:
   β”‚     └─ PrescriptionCreated(prescriptionId, hash, nullifier, patient)
   └─ βœ… Transaction confirmed on Flare Coston2
      └─ Gas paid in C2FLR
      └─ Block explorer: https://coston2-explorer.flare.network/tx/0x...

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  PHASE 2: DOCTOR 2 VALIDATES PRESCRIPTION                            β”‚
β”‚  Integration: SEMAPHORE β†’ EVVM                                       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

1️⃣ SEMAPHORE: Second Doctor Identity
   β”œβ”€ Different doctor connects (0xDoctor2...)
   β”œβ”€ Registers Semaphore identity (different commitment)
   └─ βœ… Second doctor registered

2️⃣ SEMAPHORE: Generate Validation Proof
   β”œβ”€ Doctor 2 enters prescription ID: "RX-AR-20241123-001"
   β”œβ”€ Query blockchain: getPrescriptionFromChain(id)
   β”œβ”€ Reviews prescription data
   β”œβ”€ Generates ZK proof for SAME prescription hash:
   β”‚  Input:
   β”‚  β€’ Different identity (Doctor 2's secret)
   β”‚  β€’ Same prescription hash (from blockchain)
   β”‚  β€’ Same group ID (1)
   β”‚  Output:
   β”‚  β€’ Different proof array
   β”‚  β€’ Different nullifier: 0xdef456...
   └─ βœ… Second proof generated (different doctor, same prescription)

3️⃣ EVVM: Submit Validation
   β”œβ”€ Frontend calls: EVVMProcessor.validatePrescription()
   β”œβ”€ Submits transaction:
   β”‚  └─ validatePrescription(
   β”‚       prescriptionId: "RX-AR-20241123-001",
   β”‚       doctor2Proof: [uint256[8]],
   β”‚       doctor2Nullifier: 0xdef456...
   β”‚     )
   β”œβ”€ SMART CONTRACT EXECUTES:
   β”‚  β”œβ”€ Load prescription from storage
   β”‚  β”œβ”€ Verify prescription exists
   β”‚  β”œβ”€ Verify not already validated
   β”‚  β”œβ”€ Verify nullifier not used (different from doctor 1)
   β”‚  β”œβ”€ Call Semaphore.verifyProof() with prescription hash
   β”‚  β”‚  └─ Verifies Doctor 2 is authorized AND different from Doctor 1
   β”‚  β”œβ”€ Update prescription:
   β”‚  β”‚  └─ prescription.doctor2Nullifier = 0xdef456...
   β”‚  β”‚  └─ prescription.validated = true
   β”‚  β”œβ”€ Mark nullifier as used:
   β”‚  β”‚  └─ usedNullifiers[0xdef456...] = true
   β”‚  └─ Emit event:
   β”‚     └─ PrescriptionValidated(prescriptionId, nullifier)
   └─ βœ… Prescription now validated by TWO doctors
      └─ Both proofs verified
      └─ Both nullifiers unique

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  PHASE 3: FDC ATTESTATION (AUTOMATIC)                                β”‚
β”‚  Integration: EVVM β†’ FDC β†’ EVVM                                      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

1️⃣ PREPARE METADATA
   β”œβ”€ Frontend reads prescription from blockchain
   β”œβ”€ Constructs metadata object:
   β”‚  └─ {
   β”‚       prescriptionId: "RX-AR-20241123-001",
   β”‚       prescriptionHash: "0x789abc...",
   β”‚       issuer: {
   β”‚         commitment: "0xabc123...",
   β”‚         walletAddress: "0xDoctor1...",
   β”‚         country: "Argentina",
   β”‚         timestamp: 1700000000
   β”‚       },
   β”‚       validator: {
   β”‚         commitment: "0xdef456...",
   β”‚         walletAddress: "0xDoctor2...",
   β”‚         country: "USA",
   β”‚         timestamp: 1700003600
   β”‚       },
   β”‚       data: {
   β”‚         patientName: "MarΓ­a GarcΓ­a",
   β”‚         medication: "Amoxicillin 500mg",
   β”‚         dosage: "1 tablet",
   β”‚         frequency: "Every 8 hours",
   β”‚         duration: "7 days"
   β”‚       }
   β”‚     }
   └─ βœ… Metadata prepared

2️⃣ FDC: Upload to Public URL
   β”œβ”€ Store metadata in browser localStorage (MVP)
   β”‚  └─ localStorage.setItem(`prescription-${id}`, JSON.stringify(metadata))
   β”œβ”€ Generate public URL:
   β”‚  └─ https://api.travelscript.health/prescription/RX-AR-20241123-001
   β”‚  └─ (In production: IPFS hash or real API endpoint)
   └─ βœ… Metadata publicly accessible

3️⃣ FDC: Request Attestation
   β”œβ”€ Frontend calls: FDCClient.requestAttestation(metadataUrl)
   β”œβ”€ Prepare FDC request:
   β”‚  └─ {
   β”‚       attestationType: "0x4a736f6e417069..." (bytes32 of "JsonApi"),
   β”‚       sourceId: "0x74726176656c73..." (bytes32 of "travelscript"),
   β”‚       requestBody: {
   β”‚         url: "https://api.travelscript.health/prescription/...",
   β”‚         jq_transformation: "." (return full JSON)
   β”‚       }
   β”‚     }
   β”œβ”€ POST to FDC Verifiers:
   β”‚  └─ POST https://fdc-verifiers-testnet.flare.network/
   β”‚     Headers: { "Content-Type": "application/json" }
   β”‚     Body: FDC request
   β”œβ”€ FDC VERIFIER NETWORK PROCESSES:
   β”‚  β”œβ”€ Multiple verifiers fetch the URL
   β”‚  β”œβ”€ Verify data matches expected format
   β”‚  β”œβ”€ Start voting round
   β”‚  └─ Response: {
   β”‚       status: "VALID",
   β”‚       response: {
   β”‚         attestationType: "JsonApi",
   β”‚         sourceId: "travelscript",
   β”‚         votingRound: "12345",
   β”‚         lowestUsedTimestamp: "1700003600",
   β”‚         requestBody: {...},
   β”‚         responseBody: { metadata }
   β”‚       }
   β”‚     }
   └─ βœ… Attestation request accepted
      └─ Voting Round: 12345 started

4️⃣ FDC: Wait for Finalization
   β”œβ”€ Round duration: 90 seconds
   β”œβ”€ FDC network reaches consensus
   β”œβ”€ Frontend polls or waits:
   β”‚  └─ await new Promise(resolve => setTimeout(resolve, 90000))
   └─ βœ… Round finalized

5️⃣ FDC: Retrieve Proof from DAL
   β”œβ”€ Frontend calls: FDCClient.getProofFromDAL(votingRound, prescriptionId)
   β”œβ”€ GET request:
   β”‚  └─ GET https://fdc-dal-testnet.flare.network/proof/12345/travelscript/RX-AR-20241123-001
   β”œβ”€ DAL RETURNS MERKLE PROOF:
   β”‚  └─ {
   β”‚       merkleProof: [
   β”‚         "0xhash1...",
   β”‚         "0xhash2...",
   β”‚         "0xhash3..."
   β”‚       ],
   β”‚       data: {
   β”‚         attestationType: "JsonApi",
   β”‚         sourceId: "travelscript",
   β”‚         votingRound: "12345",
   β”‚         lowestUsedTimestamp: "1700003600",
   β”‚         requestBody: {...},
   β”‚         responseBody: {...}
   β”‚       }
   β”‚     }
   └─ βœ… Cryptographic proof obtained

6️⃣ FDC: Verify Proof On-Chain
   β”œβ”€ Frontend calls: FDCClient.verifyProofOnChain(proof, provider)
   β”œβ”€ Encode proof for contract:
   β”‚  └─ ABI.encode(['merkleProof', 'data'], proof)
   β”œβ”€ Call FDC Hub contract:
   β”‚  └─ FDCHub.verifyAttestation(
   β”‚       attestationType: bytes32,
   β”‚       sourceId: bytes32,
   β”‚       encodedProof: bytes
   β”‚     )
   β”œβ”€ FDC HUB CONTRACT EXECUTES:
   β”‚  β”œβ”€ Verify Merkle proof against stored root
   β”‚  β”œβ”€ Verify voting round is finalized
   β”‚  β”œβ”€ Verify data integrity
   β”‚  └─ Return: true (proof valid) or false (invalid)
   └─ βœ… Proof verified on-chain

7️⃣ EVVM: Store Attestation Hash
   β”œβ”€ Calculate attestation hash:
   β”‚  └─ attestationHash = keccak256(JSON.stringify(attestationResponse))
   β”‚     └─ 0xjkl012...
   β”œβ”€ Frontend calls: EVVMProcessor.attestPrescription()
   β”œβ”€ Submit transaction:
   β”‚  └─ PrescriptionHub.attestPrescription(
   β”‚       prescriptionId: "RX-AR-20241123-001",
   β”‚       fdcAttestationHash: 0xjkl012...
   β”‚     )
   β”œβ”€ SMART CONTRACT EXECUTES:
   β”‚  β”œβ”€ Load prescription from storage
   β”‚  β”œβ”€ Verify prescription exists
   β”‚  β”œβ”€ Verify prescription is validated (2 doctors)
   β”‚  β”œβ”€ Verify not already attested
   β”‚  β”œβ”€ Store FDC hash:
   β”‚  β”‚  └─ prescription.fdcAttestationHash = 0xjkl012...
   β”‚  └─ Emit event:
   β”‚     └─ PrescriptionAttested(prescriptionId, fdcAttestationHash)
   └─ βœ… FDC attestation permanently stored on blockchain

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  PHASE 4: PHARMACY VERIFICATION                                      β”‚
β”‚  Integration: EVVM Query                                             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

1️⃣ EVVM: Query Prescription
   β”œβ”€ Pharmacist enters prescription ID
   β”œβ”€ Frontend calls: EVVMProcessor.canFillPrescription(id)
   β”œβ”€ Query smart contract (read-only, no gas):
   β”‚  └─ PrescriptionHub.canFillPrescription("RX-AR-20241123-001")
   β”œβ”€ SMART CONTRACT LOGIC:
   β”‚  └─ function canFillPrescription(string calldata prescriptionId)
   β”‚       external view returns (bool canFill, string memory reason)
   β”‚     {
   β”‚       Prescription memory rx = prescriptions[prescriptionId];
   β”‚
   β”‚       if (rx.timestamp == 0) {
   β”‚         return (false, "Prescription does not exist");
   β”‚       }
   β”‚
   β”‚       if (!rx.active) {
   β”‚         return (false, "Prescription revoked");
   β”‚       }
   β”‚
   β”‚       if (!rx.validated) {
   β”‚         return (false, "Not validated by second doctor");
   β”‚       }
   β”‚
   β”‚       if (rx.fdcAttestationHash == bytes32(0)) {
   β”‚         return (false, "Not attested by FDC");
   β”‚       }
   β”‚
   β”‚       return (true, "Valid - both doctors verified via ZK proof");
   β”‚     }
   β”œβ”€ Response:
   β”‚  └─ canFill: true
   β”‚  └─ reason: "Valid - both doctors verified via ZK proof"
   └─ βœ… Prescription verified safe to dispense

2️⃣ Display Full Prescription Data
   β”œβ”€ Query: getPrescriptionFromChain(id)
   β”œβ”€ Returns:
   β”‚  └─ {
   β”‚       prescriptionHash: "0x789abc...",
   β”‚       doctor1Nullifier: "0xabc123...", ← Proves Doctor 1 signed
   β”‚       doctor2Nullifier: "0xdef456...", ← Proves Doctor 2 validated
   β”‚       patientAddress: "0xPatient...",
   β”‚       timestamp: 1700000000,
   β”‚       validated: true, ← Both doctors approved
   β”‚       active: true, ← Not revoked
   β”‚       fdcAttestationHash: "0xjkl012..." ← FDC verified metadata
   β”‚     }
   β”œβ”€ Decode prescription data from chain/localStorage
   └─ βœ… Pharmacist sees full verified prescription

3️⃣ Dispense Medication
   β”œβ”€ Pharmacist confirms all checks pass:
   β”‚  βœ… Two doctor signatures (verified via ZK)
   β”‚  βœ… FDC attestation (metadata verified)
   β”‚  βœ… Active prescription (not revoked)
   β”‚  βœ… Valid patient address
   └─ βœ… Medication dispensed safely

πŸ” Why This Integration is Unique

1. Semaphore solves the privacy problem

  • Without Semaphore: Doctors' identities exposed on-chain
  • With Semaphore: Only commitments (numbers) stored, true identity hidden
  • Benefit: HIPAA/GDPR compliant, doctors maintain anonymity

2. EVVM solves the execution problem

  • Without EVVM: Need multiple blockchains, complex bridging
  • With EVVM: Single deployment on Flare with enhanced capabilities
  • Benefit: Simplified architecture, lower gas costs, future gasless tx

3. FDC solves the data availability problem

  • Without FDC: Metadata only in frontend (can be lost/manipulated)
  • With FDC: Cryptographically proven metadata, decentralized storage
  • Benefit: Tamper-proof prescription details, always accessible

How They Work Together

SEMAPHORE                    EVVM                      FDC
   ↓                          ↓                         ↓
ZK Proof      ──────────►  Smart Contract  ──────►  Attestation
(Who signed)              (What was signed)        (Proof of data)
   β”‚                          β”‚                         β”‚
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                              β”‚
                    Complete Verification
                    (Who + What + Proof)

Result:

  • βœ… Privacy-preserving (Semaphore)
  • βœ… On-chain verification (EVVM)
  • βœ… Data integrity (FDC)
  • βœ… Trustless (No intermediaries)
  • βœ… International (Works anywhere)

2️⃣ EVVM (Ethereum Virtual Machine) Integration

Purpose: Deploy custom PrescriptionHub contract with enhanced transaction capabilities

Implementation: lib/evvm/processor.ts

class EVVMProcessor {
  // Create prescription on-chain (Doctor 1)
  async createPrescription(prescription, semaphoreProof, patientAddress) {
    // Encodes prescription data
    // Submits to PrescriptionHub contract
    // Emits PrescriptionCreated event
  }

  // Validate prescription (Doctor 2)
  async validatePrescription(prescriptionId, semaphoreProof) {
    // Verifies second ZK proof
    // Marks prescription as validated
    // Emits PrescriptionValidated event
  }

  // Attest with FDC (automatic)
  async attestPrescription(prescription) {
    // Calls FDC client to request attestation
    // Stores attestation hash on-chain
    // Emits PrescriptionAttested event
  }
}

Smart Contract: contracts/PrescriptionHub.sol

contract PrescriptionHub {
    struct Prescription {
        bytes32 prescriptionHash;      // Hash of medication data
        bytes32 doctor1Nullifier;      // First doctor's ZK nullifier
        bytes32 doctor2Nullifier;      // Second doctor's ZK nullifier
        address patientAddress;        // Patient's wallet
        uint256 timestamp;             // Creation time
        bool validated;                // Second doctor validated
        bool active;                   // Not revoked
        bytes32 fdcAttestationHash;    // FDC proof hash
    }

    // Doctor 1 creates prescription with ZK proof
    function createPrescription(
        string calldata prescriptionId,
        bytes calldata prescriptionData,
        uint256[8] calldata doctor1Proof,
        bytes32 doctor1Nullifier,
        address patientAddress
    ) external;

    // Doctor 2 validates with ZK proof
    function validatePrescription(
        string calldata prescriptionId,
        uint256[8] calldata doctor2Proof,
        bytes32 doctor2Nullifier
    ) external;

    // Store FDC attestation hash
    function attestPrescription(
        string calldata prescriptionId,
        bytes32 fdcAttestationHash
    ) external;

    // Pharmacy verifies prescription
    function canFillPrescription(string calldata prescriptionId)
        external view returns (bool canFill, string memory reason);
}

Deployment:


3️⃣ Semaphore ZK Proofs Integration

Purpose: Privacy-preserving doctor authentication using zero-knowledge proofs

Implementation: lib/semaphore.ts

// Create doctor's Semaphore identity
function createDoctorIdentity(walletAddress: string) {
  const identity = new Identity();
  const commitment = identity.commitment.toString();
  const privateKey = identity.export();

  return { identity, commitment, privateKey };
}

// Generate ZK proof for prescription signing
function generateSemaphoreProof(
  identity: Identity,
  groupId: bigint,
  message: bigint
) {
  // Generates zero-knowledge proof
  // Proves: "I'm a registered doctor" without revealing which one
  // Produces nullifier to prevent double-signing

  return { proof, nullifier, merkleTreeRoot };
}

How It Works:

Doctor Registration:
1. Doctor connects wallet
2. Generate Semaphore identity (commitment)
3. Store commitment + wallet address
   β†’ No personal info on-chain
   β†’ Identity is just a number (commitment)

Prescription Signing:
1. Doctor creates/validates prescription
2. Generate ZK proof:
   β€’ Input: Identity + prescription hash
   β€’ Output: Proof + nullifier
3. Submit to smart contract
   β†’ Contract verifies proof
   β†’ Contract checks nullifier not used
   β†’ Prescription signed anonymously

Privacy Guarantees:

  • βœ… Anonymity: No one knows which doctor signed (except the doctor)
  • βœ… Unlinkability: Can't link multiple prescriptions to same doctor
  • βœ… Fraud Prevention: Nullifier prevents same doctor signing twice
  • βœ… Verifiability: Anyone can verify the proof is valid

Nullifier System:

mapping(bytes32 => bool) public usedNullifiers;

function createPrescription(..., bytes32 nullifier) {
    require(!usedNullifiers[nullifier], "Already signed");
    usedNullifiers[nullifier] = true;
    // Doctor can't sign same prescription again
}

πŸ”„ Complete Workflow

End-to-End Flow: Argentina Patient Traveling to USA

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  STEP 1: DOCTOR 1 CREATES PRESCRIPTION (Argentina)              β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  1. Dr. Juan PΓ©rez (Argentina) connects wallet                 β”‚
β”‚  2. Registers Semaphore identity                               β”‚
β”‚     β€’ Commitment: 0xabc123...                                  β”‚
β”‚     β€’ Country: Argentina                                        β”‚
β”‚  3. Patient: MarΓ­a GarcΓ­a needs Amoxicillin                    β”‚
β”‚  4. Creates prescription:                                       β”‚
β”‚     β€’ Medication: Amoxicillin 500mg                            β”‚
β”‚     β€’ Duration: 7 days                                          β”‚
β”‚  5. Generates ZK proof:                                         β”‚
β”‚     β€’ Proves: "I'm a registered doctor"                        β”‚
β”‚     β€’ Nullifier: 0xdef456... (prevents double-sign)            β”‚
β”‚  6. Submit to blockchain:                                       β”‚
β”‚     PrescriptionHub.createPrescription()                        β”‚
β”‚     βœ… Event: PrescriptionCreated                              β”‚
β”‚  7. Prescription ID: RX-AR-20241123-001                        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                              ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  STEP 2: DOCTOR 2 VALIDATES PRESCRIPTION (USA)                  β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  1. Patient travels to USA, needs medication                   β”‚
β”‚  2. Dr. Sarah Johnson (USA) connects wallet                    β”‚
β”‚  3. Registers Semaphore identity                               β”‚
β”‚     β€’ Commitment: 0x789xyz...                                  β”‚
β”‚     β€’ Country: USA                                              β”‚
β”‚  4. Enters prescription ID: RX-AR-20241123-001                 β”‚
β”‚  5. Reviews prescription details                               β”‚
β”‚  6. Generates ZK proof:                                         β”‚
β”‚     β€’ Proves: "I'm a different registered doctor"              β”‚
β”‚     β€’ Nullifier: 0xghi789... (unique, prevents reuse)          β”‚
β”‚  7. Submit validation to blockchain:                           β”‚
β”‚     PrescriptionHub.validatePrescription()                      β”‚
β”‚     βœ… Event: PrescriptionValidated                            β”‚
β”‚  8. Status: Validated by 2 doctors βœ“                           β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                              ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  STEP 3: FDC ATTESTATION (Automatic)                            β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  1. Prescription metadata prepared:                             β”‚
β”‚     {                                                           β”‚
β”‚       prescriptionId: "RX-AR-20241123-001",                    β”‚
β”‚       issuer: { country: "Argentina", timestamp: ... },        β”‚
β”‚       validator: { country: "USA", timestamp: ... },           β”‚
β”‚       medication: "Amoxicillin 500mg"                          β”‚
β”‚     }                                                           β”‚
β”‚  2. Upload to public URL (IPFS/API)                            β”‚
β”‚     URL: https://api.travelscript.health/rx/RX-AR-...         β”‚
β”‚  3. Request FDC attestation:                                    β”‚
β”‚     POST https://fdc-verifiers-testnet.flare.network/          β”‚
β”‚     βœ… Voting Round: 12345 started                             β”‚
β”‚  4. Wait for finalization (~90 seconds)                        β”‚
β”‚     β€’ FDC verifiers validate data                              β”‚
β”‚     β€’ Consensus reached                                         β”‚
β”‚  5. Retrieve proof from DAL:                                    β”‚
β”‚     GET https://fdc-dal-testnet.flare.network/proof/12345/... β”‚
β”‚     βœ… Cryptographic proof obtained                            β”‚
β”‚  6. Verify proof on FDC Hub:                                    β”‚
β”‚     FDCHub.verifyAttestation(proof)                            β”‚
β”‚     βœ… Proof valid                                             β”‚
β”‚  7. Store attestation hash on PrescriptionHub:                 β”‚
β”‚     PrescriptionHub.attestPrescription(attestationHash)         β”‚
β”‚     βœ… Event: PrescriptionAttested                             β”‚
β”‚  8. Hash: 0xjkl012...                                          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                              ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  STEP 4: PHARMACY VERIFICATION (USA)                            β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  1. Patient arrives at pharmacy with ID: RX-AR-20241123-001    β”‚
β”‚  2. Pharmacist enters prescription ID in portal                β”‚
β”‚  3. Query blockchain:                                           β”‚
β”‚     PrescriptionHub.canFillPrescription("RX-AR-20241123-001")  β”‚
β”‚  4. Smart contract checks:                                      β”‚
β”‚     βœ… Prescription exists                                     β”‚
β”‚     βœ… Doctor 1 signed (ZK proof verified)                     β”‚
β”‚     βœ… Doctor 2 validated (ZK proof verified)                  β”‚
β”‚     βœ… FDC attested (metadata verified)                        β”‚
β”‚     βœ… Not revoked                                             β”‚
β”‚     βœ… Active prescription                                     β”‚
β”‚  5. Response: "Valid - both doctors verified via ZK proof"     β”‚
β”‚  6. Pharmacist reviews:                                         β”‚
β”‚     β€’ Medication: Amoxicillin 500mg                            β”‚
β”‚     β€’ Issuer: Argentina doctor βœ“                               β”‚
β”‚     β€’ Validator: USA doctor βœ“                                  β”‚
β”‚     β€’ FDC: Attested βœ“                                          β”‚
β”‚  7. Dispense medication safely                                 β”‚
β”‚  8. βœ… Patient receives treatment                              β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

🎯 Key Features & Benefits

For Patients

  • βœ… Travel Freely: Prescriptions work internationally
  • βœ… Fast Access: No bureaucracy or delays
  • βœ… Privacy: Medical data stays private with ZK proofs
  • βœ… Control: Can revoke prescriptions anytime

For Doctors

  • βœ… Anonymous Signing: Privacy-preserving with ZK proofs
  • βœ… International Recognition: Cross-border validity
  • βœ… Fraud Prevention: Nullifier prevents double-signing
  • βœ… Audit Trail: All actions recorded on-chain

For Pharmacies

  • βœ… Instant Verification: Real-time blockchain queries
  • βœ… Trustless: No central authority needed
  • βœ… Compliance: Cryptographic proof of validation
  • βœ… Transparency: Complete audit trail

For Healthcare System

  • βœ… Reduced Fraud: ZK proofs + nullifiers prevent tampering
  • βœ… Lower Costs: No intermediaries or paperwork
  • βœ… Better Data: Analytics without compromising privacy
  • βœ… Global Standard: Works across all countries

πŸš€ Getting Started

Prerequisites

# 1. Install Foundry
curl -L https://foundry.paradigm.xyz | bash
foundryup

# 2. Install Node.js 18+
node --version

# 3. Get C2FLR testnet tokens
# Visit: https://faucet.flare.network/coston2

Quick Start

# 1. Clone repository
git clone https://github.com/yourusername/travelscript
cd travelscript

# 2. Deploy smart contract (if needed)
cd evvm-deployment
cp .env.example .env
# Add your PRIVATE_KEY
forge build
make deploy
# Contract deployed at: 0x6fB0ce1685Fcfa6EeDdDFc4607a9ccbd5CBCC2E3

# 3. Configure frontend
cd ../travelscript-app
cp .env.example .env.local
# Add NEXT_PUBLIC_PRESCRIPTION_HUB_ADDRESS
# Add NEXT_PUBLIC_PROJECT_ID (from cloud.reown.com)

# 4. Install and run
npm install
npm run dev

# 5. Open browser
# http://localhost:3000

Testing the Flow

Test Scenario: Argentina β†’ USA

  1. Doctor 1 (Argentina):

    • Visit /doctor
    • Register: Dr. Juan PΓ©rez, Argentina
    • Create prescription for patient
    • Copy Prescription ID
  2. Doctor 2 (USA):

    • New incognito window (different wallet)
    • Visit /doctor/validate
    • Register: Dr. Sarah Johnson, USA
    • Enter Prescription ID
    • Validate prescription
    • Wait ~90 seconds for FDC attestation
  3. Pharmacy (USA):

    • Visit /pharmacy
    • Enter Prescription ID
    • See: βœ… Valid - both doctors verified
    • Dispense medication

πŸ› οΈ Project Structure

travelscript/
β”œβ”€β”€ contracts/                          # Smart contracts
β”‚   └── PrescriptionHub.sol            # Main prescription contract
β”‚
β”œβ”€β”€ evvm-deployment/                    # Foundry deployment
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   └── PrescriptionHub.sol        # Contract for deployment
β”‚   β”œβ”€β”€ script/
β”‚   β”‚   └── DeployPrescriptionHub.s.sol # Deployment script
β”‚   β”œβ”€β”€ .env.example                   # Environment template
β”‚   └── Makefile                       # Deployment commands
β”‚
β”œβ”€β”€ travelscript-app/                  # Next.js frontend
β”‚   β”œβ”€β”€ app/
β”‚   β”‚   β”œβ”€β”€ doctor/                    # Doctor registration & creation
β”‚   β”‚   β”‚   β”œβ”€β”€ page.tsx              # Registration portal
β”‚   β”‚   β”‚   └── validate/
β”‚   β”‚   β”‚       └── page.tsx          # Validation interface
β”‚   β”‚   β”œβ”€β”€ pharmacy/
β”‚   β”‚   β”‚   └── page.tsx              # Pharmacy verification
β”‚   β”‚   └── layout.tsx                # Root layout with AppKit
β”‚   β”‚
β”‚   β”œβ”€β”€ lib/
β”‚   β”‚   β”œβ”€β”€ fdc/
β”‚   β”‚   β”‚   β”œβ”€β”€ client.ts             # FDC client implementation
β”‚   β”‚   β”‚   └── attestation-service.ts # FDC service layer
β”‚   β”‚   β”œβ”€β”€ evvm/
β”‚   β”‚   β”‚   β”œβ”€β”€ processor.ts          # EVVM blockchain processor
β”‚   β”‚   β”‚   └── prescription-contract.ts # Contract interface
β”‚   β”‚   β”œβ”€β”€ config/
β”‚   β”‚   β”‚   β”œβ”€β”€ constants.ts          # App configuration
β”‚   β”‚   β”‚   └── flare-network.ts      # Network config
β”‚   β”‚   └── semaphore.ts              # ZK proof generation
β”‚   β”‚
β”‚   β”œβ”€β”€ types/
β”‚   β”‚   └── prescription.ts           # TypeScript types
β”‚   β”‚
β”‚   β”œβ”€β”€ context/
β”‚   β”‚   └── index.tsx                 # AppKit configuration
β”‚   β”‚
β”‚   └── .env.example                  # Environment template
β”‚
β”œβ”€β”€ README.md                          # This file
β”œβ”€β”€ DEPLOYMENT_GUIDE.md                # Complete deployment guide
β”œβ”€β”€ DEPLOYMENT_SUCCESS.md              # Deployment status
β”œβ”€β”€ QUICKSTART.md                      # 5-minute quick start
└── DEPLOYMENT_CHECKLIST.txt          # Deployment checklist

πŸ”’ Security Features

Zero-Knowledge Proofs (Semaphore)

  • What: Cryptographic proofs that verify statements without revealing data
  • How: Doctors prove credentials without exposing identity
  • Why: Privacy-preserving authentication
  • Benefit: GDPR-compliant, medical privacy protected

Nullifier System

  • What: Unique identifier preventing double-use of same proof
  • How: Each prescription signature generates unique nullifier
  • Why: Prevents fraud and double-signing
  • Benefit: Each doctor can only sign once per prescription

On-Chain Verification

  • What: All verifications recorded on Flare blockchain
  • How: Smart contract validates and stores all signatures
  • Why: Immutable audit trail
  • Benefit: Complete transparency, tamper-proof records

FDC Attestations

  • What: Cryptographic proofs of prescription metadata
  • How: Flare Data Connector verifies and attests data
  • Why: Ensures data integrity and availability
  • Benefit: Trustless metadata verification

🌐 Deployed Contracts

Flare Coston2 Testnet

All contracts deployed and verified on Flare Coston2 Testnet (Chain ID: 114)

TravelScript Contracts

PrescriptionHub (Main Application Contract)

  • Address: 0x6fB0ce1685Fcfa6EeDdDFc4607a9ccbd5CBCC2E3
  • Explorer: https://coston2-explorer.flare.network/address/0x6fB0ce1685Fcfa6EeDdDFc4607a9ccbd5CBCC2E3
  • Purpose: Dual-doctor prescription verification with ZK proofs
  • Functions:
    • createPrescription() - Doctor 1 creates prescription
    • validatePrescription() - Doctor 2 validates prescription
    • attestPrescription() - Store FDC attestation hash
    • canFillPrescription() - Pharmacy verification
    • revokePrescription() - Patient revocation
  • Events:
    • PrescriptionCreated(prescriptionId, hash, nullifier, patient)
    • PrescriptionValidated(prescriptionId, nullifier)
    • PrescriptionAttested(prescriptionId, fdcAttestationHash)

EVVM Infrastructure Contracts

EVVM Core (Custom EVM Execution)

Staking Contract

Estimator Contract

NameService Contract

Treasury Contract

P2PSwap Contract

AdvancedStrings Library

Flare Network Contracts

FDC Hub (Flare Data Connector)

Administrative Addresses

Admin/GoldenFisher/Activator

  • Address: 0x61643d97e10E681d5EA76218abC29036Ef3463Cc
  • Role: System administrator and governance
  • Permissions: Contract management, system upgrades

Deployment Information

Network: Flare Coston2 Testnet Chain ID: 114 RPC URL: https://coston2-api.flare.network/ext/C/rpc Explorer: https://coston2-explorer.flare.network Faucet: https://faucet.flare.network/coston2

Gas Used:

  • EVVM Infrastructure: ~19,782,857 gas
  • PrescriptionHub: ~973,343 gas
  • Total Estimated: ~20,756,200 gas

Deployment Cost:

  • EVVM Infrastructure: ~1.73 C2FLR
  • PrescriptionHub: ~0.024 C2FLR
  • Total: ~1.754 C2FLR

Deployment Date: November 23, 2024

Contract Interactions:

PrescriptionHub ──► EVVM ──► Staking
                β”‚
                └──► FDC Hub ──► Attestation Verification
                β”‚
                └──► NameService ──► Identity Resolution
                β”‚
                └──► Treasury ──► Fund Management

🎬 Demo Video

Coming soon: Full demonstration of the complete flow

What we'll show:

  1. Doctor 1 (Argentina) creates prescription
  2. Doctor 2 (USA) validates prescription
  3. FDC attestation process (~90 seconds)
  4. Pharmacy verification and dispensing
  5. Blockchain explorer showing all events
  6. Zero-knowledge proofs in action

πŸ›£οΈ Roadmap

Phase 1: MVP (Current) βœ…

  • Smart contract development
  • Dual-doctor ZK proof system
  • FDC integration
  • Basic frontend
  • Deployment to Coston2

Phase 2: Enhancement

  • IPFS metadata storage (replace localStorage)
  • Mobile application (React Native)
  • Prescription expiration logic
  • Email/SMS notifications

Phase 3: Production

  • Mainnet deployment
  • Pharmacy licensing verification
  • Insurance integration
  • Multi-language support (Spanish, Portuguese, etc.)
  • Regulatory compliance (HIPAA, GDPR)
  • Medical standards integration (ICD-10)

Phase 4: Scaling

  • Support for more countries
  • Integration with EHR systems
  • Real-time prescription tracking
  • Analytics dashboard
  • Mobile doctor verification
  • Telemedicine integration

🀝 Contributing

Contributions welcome! Please:

  1. Fork the repository
  2. Create feature branch (git checkout -b feature/amazing)
  3. Commit changes (git commit -m 'Add amazing feature')
  4. Push to branch (git push origin feature/amazing)
  5. Open Pull Request

Development Guidelines

  • Follow TypeScript best practices
  • Write comprehensive tests
  • Document all functions
  • Maintain security standards
  • Update README for new features

πŸ“„ License

MIT License - see LICENSE file


πŸ™ Acknowledgments

  • Flare Network - For infrastructure and FDC technology
  • **EVVM ** - For EVVM infrastructure and technology
  • Semaphore Protocol - For zero-knowledge proof system
  • OpenZeppelin - For smart contract libraries
  • Reown (WalletConnect) - For wallet integration
  • Next.js Team - For the amazing React framework

🌟 Star History

If this project helped you, please give it a ⭐!


πŸ“Š Statistics

  • Smart Contracts: 1 (PrescriptionHub)
  • Lines of Code: ~3,000+
  • Integrations: 3 (EVVM, FDC, Semaphore)
  • Frontend Pages: 4 (Doctor, Validate, Pharmacy, Home)
  • Zero-Knowledge Proofs: ∞ (unlimited privacy-preserving signatures)

Built with ❀️ for the ETH Global Hackathon

Enabling trustless international healthcare through zero-knowledge proofs and decentralized verification

Ready to deploy. Ready to scale. Ready to change healthcare. πŸš€


Β© 2024 TravelScript. All rights reserved.

About

Need a controlled medication in any country? No problem TravelScript has you covered.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published