Introduction to AegisCare

๐Ÿ›ก๏ธ What is AegisCare?

AegisCare is a revolutionary clinical trial matching platform that uses Fully Homomorphic Encryption (FHE) to enable privacy-preserving patient-trial matching. Unlike traditional systems, AegisCare performs eligibility computations on encrypted data, ensuring zero plaintext leakage.

๐Ÿ”’ Privacy Guarantee:

  • Medical data never leaves the browser in plaintext
  • Eligibility computed entirely in the encrypted domain
  • Only the patient can decrypt their own results
  • Trial sponsors never see patient medical data

โœจ Key Features

  • Client-Side Encryption: All medical data encrypted before submission
  • FHE Operations: Computations on encrypted data only
  • Private Decryption: EIP-712 signatures for secure access
  • Zero Knowledge: Trial sponsors learn nothing about patient data
  • Testnet Deployed: Live on Sepolia at 0x3DB49a1Ca0d72740e54f5FB06Ccc69576c4192F7

๐Ÿ”Ž Live Deployments โ€” Open in Explorer

AegisCare is already deployed. Inspect both contracts directly in their block explorers before you start.

๐Ÿ“˜ Complete User Guide

๐ŸŽ“ New to AegisCare? Start Here!

Everything you need to know about privacy-preserving clinical trial matching

NEWComprehensive User Guide Available

We've created a complete, in-depth user guide to help you understand and use AegisCare. Whether you're a patient, trial sponsor, developer, or just curious about FHE technology, this guide has everything you need.

๐Ÿ“– Read Complete User Guide โ†’

What's Inside the User Guide

1
What is AegisCare?

Simple explanation of the platform and why it matters

2
Why Do We Need It?

Real-world problems AegisCare solves

3
How Does It Work?

Step-by-step process explanation with diagrams

4
Key Concepts Explained

FHE, EIP-712, ACLs made simple

5
Technology Stack

All technologies used and why

6
Getting Started Tutorial

5-minute quick start walkthrough

Perfect For:
๐Ÿ‘คPatients - Protect your privacy while joining trials
๐ŸขTrial Sponsors - Zero-knowledge trial matching
๐Ÿ’ปDevelopers - Explore FHE technology
๐ŸŽ“Students - Study privacy-preserving apps

๐Ÿ”‘ Key Highlights from the User Guide

๐Ÿ”’ Privacy-First Architecture

Learn how AegisCare ensures your medical data never leaves your device in plaintext form. All data is encrypted using FHE before being sent to the blockchain, and only you can decrypt your eligibility results.

โšก FHE Technology Explained

Understand Fully Homomorphic Encryption - how it allows computations on encrypted data without ever decrypting it. This breakthrough technology enables zero-knowledge trial matching.

๐ŸŽฏ Real-World Use Cases

Explore practical scenarios: diabetes trials, mental health studies, rare disease research. See how AegisCare solves real privacy concerns in clinical trial recruitment.

๐Ÿš€ Step-by-Step Tutorial

Follow our detailed 5-minute quick start guide. Learn how to connect your wallet, register as a patient, create trials, and check eligibility - all with privacy preserved.

๐Ÿ“Š Comprehensive FAQ

Over 50 frequently asked questions answered. From "Can trial sponsors see my data?" to "How does FHE work?" - find answers to all your questions.

Ready to dive deeper into privacy-preserving clinical trials?

๐Ÿ“– Read the Complete User Guide โ†’

500+ lines of comprehensive documentation โ€ข 10 major sections โ€ข Perfect for beginners

๐Ÿ“Š Test Data Guide

Use these pre-configured test patients and trials to explore the platform without entering real medical data.

Quick Test Scenarios

โœ… Perfect Match

Patient: John (Age 45, Diabetes E11, BMI 28.5)

Trial: Diabetes Study (Age 18-65, E11, BMI 18.5-35)

Result: ELIGIBLE โœ…

โŒ Age Mismatch

Patient: Jane (Age 75, Diabetes E11, BMI 22.0)

Trial: Diabetes Study (Age 18-65, E11, BMI 18.5-35)

Result: NOT ELIGIBLE (too old)

โš ๏ธ Condition Mismatch

Patient: Bob (Age 50, No Condition, BMI 25.0)

Trial: Diabetes Study (Requires E11, Age 18-65)

Result: NOT ELIGIBLE (no diabetes)

โœ… Healthy Trial Match

Patient: Jane (Age 30, No Condition, BMI 22.0)

Trial: Wellness Study (Age 18-65, No Condition, BMI 18.5-30)

Result: ELIGIBLE โœ…

Sample Patient Data

Patient 1John Doe - Diabetes Patient

{
  "name": "John Doe",
  "age": 45,
  "gender": 1,
  "bmiScore": 28.5,
  "hasMedicalCondition": true,
  "conditionCode": "E11",
  "description": "Type 2 Diabetes, age 45, BMI 28.5 (overweight)"
}

Matches:

  • โœ… Diabetes Treatment Study 2025

Patient 2Jane Smith - Healthy Adult

{
  "name": "Jane Smith",
  "age": 32,
  "gender": 2,
  "bmiScore": 22.1,
  "hasMedicalCondition": false,
  "conditionCode": "Z00",
  "description": "Healthy adult, age 32, normal BMI"
}

Matches:

  • โœ… General Wellness Study

Patient 3Bob Johnson - Hypertension Patient

{
  "name": "Bob Johnson",
  "age": 58,
  "gender": 1,
  "bmiScore": 31.2,
  "hasMedicalCondition": true,
  "conditionCode": "I10",
  "description": "Hypertension, age 58, BMI 31.2 (obese)"
}

Matches:

  • โœ… Cardiovascular Health Research

Sample Trial Data

Trial 1: Diabetes Treatment Study 2025

{
  "trialName": "Diabetes Treatment Study 2025",
  "description": "Testing new treatment for Type 2 diabetes in adults",
  "criteria": {
    "minAge": 18,
    "maxAge": 65,
    "requiredGender": 0,
    "minBMIScore": 18.5,
    "maxBMIScore": 35,
    "hasSpecificCondition": true,
    "conditionCode": "E11"
  }
}

๐Ÿ“Š Eligible Patients:

  • John Doe (Age 45, BMI 28.5, E11)

Trial 2: Cardiovascular Health Research

{
  "trialName": "Cardiovascular Health Research",
  "description": "Study on heart health in adults 40-70",
  "criteria": {
    "minAge": 40,
    "maxAge": 70,
    "requiredGender": 0,
    "minBMIScore": 20,
    "maxBMIScore": 40,
    "hasSpecificCondition": true,
    "conditionCode": "I10"
  }
}

๐Ÿ“Š Eligible Patients:

  • Bob Johnson (Age 58, BMI 31.2, I10)

Trial 3: General Wellness Study

{
  "trialName": "General Wellness Study",
  "description": "Open study for healthy adults",
  "criteria": {
    "minAge": 18,
    "maxAge": 65,
    "requiredGender": 0,
    "minBMIScore": 18.5,
    "maxBMIScore": 30,
    "hasSpecificCondition": false,
    "conditionCode": "Z00"
  }
}

๐Ÿ“Š Eligible Patients:

  • Jane Smith (Age 32, BMI 22.1, Z00)
  • John Doe (if no diabetes - but he has E11, so no match)

Medical Codes Reference

CodeDescriptionCategory
E11Type 2 diabetes mellitusEndocrine
E10Type 1 diabetes mellitusEndocrine
I10Essential (primary) hypertensionCirculatory
I50Heart failureCirculatory
J45AsthmaRespiratory
M54Dorsalgia (back pain)Musculoskeletal
Z00General medical examination (healthy)Health
Z01Special examinations and investigationsHealth

Gender Codes

CodeDescription
0All genders (no preference)
1Male
2Female
3Other / Prefer not to say

๐Ÿš€ How It Works

Patient Workflow

1

Register Medical Data

Enter your medical information on the patient dashboard

2

Client-Side Encryption ๐Ÿ”’

Your data is encrypted in the browser using FHE before being sent

3

Blockchain Registration

Encrypted data stored on Sepolia testnet via smart contract

4

Check Eligibility

Select a trial and trigger encrypted eligibility computation

5

Private Decryption ๐Ÿ”‘

Only YOU can decrypt your result with your private key

Trial Sponsor Workflow

1

Create Trial

Define trial name, description, and eligibility criteria

2

Encrypt Criteria ๐Ÿ”’

Trial criteria encrypted before being sent to blockchain

3

Smart Contract Storage

Encrypted trial stored on Sepolia testnet

4

Wait for Patients

Patients can now check their eligibility against your trial

๐Ÿ—๏ธ Architecture Overview

System Architecture

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚           Patient Browser                 โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚
โ”‚  โ”‚ Medical Data (Plaintext)         โ”‚   โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚
โ”‚               โ”‚                          โ”‚
โ”‚               โ–ผ                          โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚
โ”‚  โ”‚ FHE Encryption (Client-Side)    โ”‚   โ”‚
โ”‚  โ”‚ โ€ข Zama RelayerSDK v0.3.0-8      โ”‚   โ”‚
โ”‚  โ”‚ โ€ข Encrypted handles + proofs     โ”‚   โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                โ”‚
                โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚     Ethereum Sepolia Testnet            โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚
โ”‚  โ”‚ AegisCare Smart Contract          โ”‚   โ”‚
โ”‚  โ”‚ 0x3DB49...76c4192F7             โ”‚   โ”‚
โ”‚  โ”‚                                  โ”‚   โ”‚
โ”‚  โ”‚ โ€ข Encrypted Patient Data         โ”‚   โ”‚
โ”‚  โ”‚ โ€ข Encrypted Trial Criteria       โ”‚   โ”‚
โ”‚  โ”‚ โ€ข FHE Eligibility Computation    โ”‚   โ”‚
โ”‚  โ”‚ โ€ข Encrypted Results Storage      โ”‚   โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                โ”‚
                โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚      EIP-712 Private Decryption         โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚
โ”‚  โ”‚ Patient Signs EIP-712 Message   โ”‚   โ”‚
โ”‚  โ”‚ โ†’ Private Key Decrypts Result   โ”‚   โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                โ”‚
                โ–ผ
         โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
         โ”‚ ELIGIBLE โ”‚
         โ”‚ YES / NO โ”‚
         โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

โ”€โ”€ Parallel, anonymized AI advisor path โ”€โ”€

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  anonymized   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚   Browser    โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บ โ”‚  GenLayer StudioNet          โ”‚
โ”‚ (no PHI sent)โ”‚   buckets /   โ”‚  AegisCareAdvisor (Python)   โ”‚
โ”‚              โ”‚   summary     โ”‚  โ€ข generate_explanation      โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜               โ”‚  โ€ข recommend_trials          โ”‚
                               โ”‚  โ€ข validate_trial (ICD-10)   โ”‚
                               โ”‚  โ€ข check_eligibility         โ”‚
                               โ”‚  leader โ†’ validators โ†’ store โ”‚
                               โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Key Components:

  • Frontend: Next.js 16, React 19, TypeScript, TailwindCSS 4
  • FHE SDK: Zama RelayerSDK v0.3.0-8 for client-side encryption
  • Web3: ethers.js v6, Wagmi for wallet connection
  • Blockchain: Solidity 0.8.27, fhEVM, Sepolia testnet
  • AI Advisor: GenLayer AegisCareAdvisor (Python) on StudioNet โ€” LLM consensus, ICD-10 web validation, PII screening
  • Smart Contract: AegisCare.sol with FHE operations

๐Ÿง  GenLayer AI Advisor

AegisCareAdvisor is a Python Intelligent Contract on GenLayer that adds an AI reasoning layer on top of the FHE matching engine. It explains results, recommends trials, validates registrations, and checks external-registry eligibility โ€” all settled on-chain through Optimistic Democracy consensus.

๐ŸŽฏ The core idea

FHE is great at deterministic, confidential math, but it cannot explain a result, recommend a trial from free text, or validate a registration against a live medical reference. Those need judgment โ€” so they run on GenLayer, on anonymized inputs only, with leader/validator consensus so the result is trustless.

What is GenLayer?

GenLayer is an AI-native blockchain. Its smart contracts โ€” Intelligent Contracts, written in Python โ€” can natively call LLMs and read the live web from inside contract execution. Because that output is non-deterministic, GenLayer settles it with Optimistic Democracy consensus: a randomly chosen leader proposes a result, independent validators re-run the same logic, and the value commits only when validators agree on its meaning โ€” not on exact bytes. The result is AI reasoning that is trustless and verifiable on-chain, with no centralized oracle and no single model deciding the outcome.

๐Ÿค– LLM in the contract

gl.nondet.exec_prompt() runs a model as a first-class on-chain operation.

๐ŸŒ Live web access

gl.nondet.web.render() reads real sources (e.g. WHO ICD-10) at execution time.

โš–๏ธ Consensus on meaning

Validators agree the result is equivalent, so non-deterministic output still settles deterministically.

How GenLayer Contributes & the Problems It Solves

FHE makes the eligibility decision private and correct, but a raw boolean isn't enough for real users. GenLayer adds the reasoning layer FHE cannot โ€” and does it without ever weakening the privacy guarantee. Each row below is a concrete gap the advisor closes.

ProblemWhy FHE alone can'tGenLayer's contribution
"Why am I (not) eligible?"FHE returns a 1/0 โ€” it can't produce natural language.generate_explanation turns the result into a plain-language reason, validated to never leak patient values.
Finding the right trial among manyRanking free-text trial descriptions needs semantic judgment, not arithmetic.recommend_trials picks 1โ€“3 best matches from an anonymized profile, with validators bounding the picks to the candidate set.
Garbage / fake trial dataA contract can't tell if an ICD-10 code is real or a description is coherent.validate_trial fetches live WHO ICD-10 data on-chain and validates the registration before it's trusted.
Eligibility for off-chain trialsReal trials live on external registries the FHE contract never sees.check_eligibility reads a registry URL and assesses a PII-screened summary against it.
Trusting an AI answerA normal LLM/oracle is a centralized black box โ€” one model, no recourse.Leader + validator consensus means every AI result is independently re-derived and agreed before it's stored.

The division of labor: Zama fhEVM keeps medical data private and computes the decision under encryption; GenLayer makes the AI reasoning on top of that decision trustless. Neither layer ever sees the other's secrets โ€” the advisor receives only anonymized, de-identified inputs.

Advisor Capabilities

1. Eligibility explainer ยท generate_explanation

Turns the binary FHE eligibility result into a plain-language explanation for the patient. The validator enforces the explanation names the correct status, references a criterion boundary, stays within 50โ€“400 characters, and never echoes specific patient values.

2. Trial recommender ยท recommend_trials

Suggests the best 1โ€“3 trials from a candidate list using an anonymized profile (age bucket + condition category + profile hash). The validator confirms the picked IDs are within the candidate set and the count is valid.

3. Trial validator ยท validate_trial

Fetches the live WHO ICD-10 reference on-chain via GenLayer's web access and checks that a trial registration is coherent and its condition code is real. The validator re-runs the leader and agrees only on the boolean outcome.

4. Registry eligibility checker ยท check_eligibility

Assesses eligibility against an external trial-registry URL from a PII-screened anonymized summary. Returns ELIGIBLE / NOT_ELIGIBLE / UNCLEAR with matched and failed criteria. The validator agrees on the verdict class.

Consensus & Equivalence

Every write method follows the same pattern โ€” a leader proposes, validators independently evaluate, and only equivalent results settle. Because LLM and web output are non-deterministic, validators agree on meaning, not exact bytes.

leader_fn()
  โ†’ calls gl.nondet.exec_prompt() / gl.nondet.web.render()
  โ†’ parses + validates JSON defensively (prefix: LLM_ERROR / EXPECTED)
  โ†’ returns structured calldata

validator_fn(leaders_res)
  โ†’ re-runs leader_fn() independently
  โ†’ checks leaders_res is gl.vm.Return
  โ†’ compares on the DECIDED field (status / verdict / boolean)
  โ†’ True  โ‡’ accept
  โ†’ False โ‡’ reject

gl.vm.run_nondet_unsafe(leader_fn, validator_fn)
  โ†’ only an accepted result is written to contract storage

โœ… Equivalence on meaning

Two validators may phrase an explanation differently, but they agree it conveys the right status โ€” so the result is trustworthy.

๐Ÿ›ก๏ธ Defensive LLM handling

JSON is parsed defensively; malformed output, wrong types, and missing fields are classified with deterministic prefixes so failures are reproducible, not silent.

Privacy Boundary

The advisor is strictly additive and isolated. It never receives raw or encrypted patient medical data โ€” only anonymized, de-identified inputs.

InputForm
Patient ageCoarse bucket (e.g. "30-40")
ConditionCategory code, not free-text history
Patient summaryPre-screened, length-bounded (20โ€“2000 chars), regex-checked for email / phone / ID runs
EligibilityA boolean computed under FHE, not the raw values

Enforced twice. The same PII/length rules run client-side in lib/genLayerClient.ts (fast failure) and again in the contract (authoritative). Unsafe input never reaches consensus.

Advisor Contract API

GenVM dispatch uses snake_case methods with kwargs. Names mirror the deployed schema in config/genLayerContracts.ts.

MethodTypeReturns
generate_explanationwritestores explanation keyed by trial + patient
get_explanationviewstr
recommend_trialswritestores trial_ids + reasoning keyed by profile hash
get_recommendationsviewRecommendation
validate_trialwritestores ValidationResult keyed by trial
get_validationviewValidationResult
check_eligibilitywritestores EligibilityCheck keyed by check_id
get_eligibility_checkviewEligibilityCheck

Stored data structures

View methods return these dataclasses from contract storage. List-valued fields are stored as JSON strings โ€” decode them client-side with parseCriteria().

@dataclass
class ValidationResult:        # get_validation(trial_id)
    valid: bool                #   true only if coherent AND real ICD-10 code
    reason: str                #   required when valid=false
    suggestions: str           #   JSON-encoded list[str]

@dataclass
class Recommendation:          # get_recommendations(profile_hash)
    trial_ids: str             #   JSON-encoded list[int], 1-3 picks
    reasoning: str

@dataclass
class EligibilityCheck:        # get_eligibility_check(check_id)
    trial_registry_url: str
    anonymized_summary: str    #   20-2000 chars, PII-screened
    result: str                #   'ELIGIBLE' | 'NOT_ELIGIBLE' | 'UNCLEAR'
    reasoning: str
    matched_criteria: str      #   JSON-encoded list[str]
    failed_criteria: str       #   JSON-encoded list[str]

# Storage layout (on-chain TreeMaps):
#   explanations:       u32 trial_id -> (str patient_address -> str)
#   recommendations:    str profile_hash -> Recommendation
#   validations:        u32 trial_id -> ValidationResult
#   eligibility_checks: str check_id -> EligibilityCheck

On-chain web sources

Web reads run inside the leader via gl.nondet.web.render(url, mode="text") and are length-bounded so the prompt stays deterministic across validators.

MethodSourceCap
validate_trialWHO ICD-10 ยท icd.who.int/browse103,000 chars
check_eligibilityCaller-supplied trial-registry URL5,000 chars

Write: generate an explanation

import { generateExplanation } from '@/lib/genLayerClient';

await generateExplanation({
  trialId: 1,
  patientAddress: '0x...',
  isEligible: true,           // computed under FHE by AegisCare.sol
  trialName: 'Diabetes Treatment Study 2025',
  minAge: 18, maxAge: 65,
  conditionCode: 'E11',
  minBmi: '18.5', maxBmi: '35',
});

Read: fetch the stored eligibility check

import { getEligibilityCheck, parseCriteria } from '@/lib/genLayerClient';

const check = await getEligibilityCheck('check-001');
// check.result  -> 'ELIGIBLE' | 'NOT_ELIGIBLE' | 'UNCLEAR'
// parseCriteria(check.matched_criteria) -> string[]
// parseCriteria(check.failed_criteria)  -> string[]

Deploying the Advisor

The advisor is deployed independently on GenLayer StudioNet (gasless). Lint before deploy, then wire the returned address into the frontend.

# 1. Lint the Intelligent Contract (fix errors first)
genvm-lint check contracts/aegiscare_advisor.py --json

# 2. Deploy on GenLayer StudioNet
genlayer deploy --contract contracts/aegiscare_advisor.py

# 3. Inspect the deployed schema
genlayer schema <advisor-address>

# 4. Put the address into .env
NEXT_PUBLIC_ADVISOR_ADDRESS=0x...
NEXT_PUBLIC_GENLAYER_CHAIN_ID=studionet

Current deployment: 0x7feFc3d155c5c268E3e104e6620d71C0A4ebe4e3 on GenLayer StudioNet. The frontend guards against a missing address (assertAdvisorConfigured), so a misconfigured deploy fails loudly instead of sending transactions to address(0).

๐Ÿง  Open the deployed Advisor on GenLayer Explorer โ†’

๐Ÿ“š API Reference

FHE Client API

Client-side encryption utilities in lib/fheClient.ts

Encrypt Patient Data

import { encryptPatientData } from '@/lib/fheClient';

const encryptedData = await encryptPatientData({
  age: 45,
  gender: 1,  // 1=male, 2=female, 3=other
  bmiScore: 28.5,
  hasMedicalCondition: true,
  conditionCode: "E11"  // ICD-10 code
});

// Returns:
// {
//   age: { handle: "0x...", ... },
//   ageProof: "0x...",
//   gender: { handle: "0x...", ... },
//   genderProof: "0x...",
//   ...
// }

Encrypt Trial Criteria

import { encryptTrialCriteria } from '@/lib/fheClient';

const encryptedCriteria = await encryptTrialCriteria({
  trialName: "Diabetes Study 2025",
  description: "Testing new treatment",
  minAge: 18,
  maxAge: 65,
  requiredGender: 0,
  minBMIScore: 18.5,
  maxBMIScore: 35,
  hasSpecificCondition: true,
  conditionCode: "E11"
});

Decrypt Eligibility Result

import { decryptEligibilityResult } from '@/lib/fheClient';

const isEligible = await decryptEligibilityResult(
  encryptedResult,
  contractAddress,
  signer
);

console.log(isEligible); // true or false

Web3 Client API

Blockchain interaction utilities in lib/web3Client.ts

Register Patient

import { registerPatient } from '@/lib/web3Client';

await registerPatient(signer, encryptedData, publicKeyHash);

Register Trial

import { registerTrial } from '@/lib/web3Client';

await registerTrial(
  signer,
  trialName,
  description,
  encryptedCriteria
);

Compute Eligibility

import { computeEligibility } from '@/lib/web3Client';

await computeEligibility(signer, trialId, patientAddress);

Smart Contract API

Contract deployed at 0x3DB49a1Ca0d72740e54f5FB06Ccc69576c4192F7 on Sepolia

registerPatient

Register a patient with encrypted medical data

function registerPatient(
    bytes32 ageHandle,
    bytes32 ageProof,
    bytes32 genderHandle,
    bytes32 genderProof,
    bytes32 bmiScoreHandle,
    bytes32 bmiProof,
    bytes32 hasMedicalConditionHandle,
    bytes32 conditionProof,
    bytes32 conditionCodeHandle,
    bytes32 codeProof,
    bytes32 publicKeyHash
) external

registerTrial

Create a new clinical trial (owner only)

function registerTrial(
    string memory trialName,
    string memory description,
    bytes32 minAgeHandle,
    bytes32 minAgeProof,
    // ... (14 more encrypted parameters)
) external onlyOwner

computeEligibility

Compute eligibility on encrypted data

function computeEligibility(
    uint256 _trialId,
    address _patientAddress
) external

getEligibilityResult

Get encrypted result (patient only)

function getEligibilityResult(
    uint256 _trialId,
    address _patientAddress
) external view returns (bytes32)

๐Ÿ› Troubleshooting

Common Issues

"Cannot connect to wallet"

Ensure MetaMask is installed and you're on Sepolia testnet

Solution: Refresh page, check MetaMask, verify network

"Transaction failed"

Not enough ETH for gas fees

Solution: Get free Sepolia ETH from sepoliafaucet.com

"FHE initialization failed"

Zama FHE SDK still loading

Solution: Wait 5-10 seconds, check internet connection, refresh page

"Eligibility computation failed"

Patient or trial not registered

Solution: Ensure you're registered and the trial exists

"Cannot decrypt result"

Only patients can decrypt their own results

Solution: Use the correct wallet address, sign EIP-712 message

๐Ÿ”’ Security & Privacy

Privacy Guarantees

  • โœ… Zero Knowledge: Trial sponsors learn NOTHING about patient data
  • โœ… Encrypted Computation: All operations on encrypted data
  • โœ… Private Decryption: Only patients can decrypt their results
  • โœ… No Plaintext Storage: Only encrypted data on-chain
  • โœ… Pausable Contract: Emergency stop functionality

Compliance:

  • HIPAA Compliant: No PHI disclosure without patient consent
  • GDPR Compliant: Data protection by design and default
  • Regulatory Friendly: Privacy-first architecture

๐Ÿšข Deployment

Current Deployment

Network: Sepolia Testnet

Contract: 0x3DB49a1Ca0d72740e54f5FB06Ccc69576c4192F7

Chain ID: 11155111

View on Etherscan: sepolia.etherscan.io

Local Deployment

# Deploy to local network
npm run deploy:local

# Deploy to Sepolia
npm run deploy:sepolia

# Run tests
npm test

# Compile contracts
npx hardhat compile

Built with โค๏ธ using Zama FHEVM

Privacy-Preserving Clinical Trial Matching

Homeโ€ขPatientโ€ขTrial Admin