Core Concepts
How Althea Works
The full eight-step protocol, end to end. Read this once and you have a complete mental model of Althea — what each piece does, what travels between them, and where personal data starts and stops existing.
1. User enters NIN or BVN + date of birth
Everything starts in your dApp. The user enters their Nigerian ID and date of birth into a form you control. This is the only point in the entire flow where the raw ID exists outside the user's head.
2. Althea backend confirms with Dojah
The SDK POSTs the inputs to the Althea backend over HTTPS. The backend calls Dojah's NIN or BVN endpoint, which talks to the canonical NIMC or CBN database. If the ID is real and the dob matches, the server continues; otherwise it returns a verification-failed error.
3. Server hashes and signs
The server computes idHash = Poseidon(idNumber), derives age from dob, builds credentialHash = Poseidon(idHash, age, idType), and signs it with the Althea EdDSA private key. It returns the SignedCredential to the SDK and discards every input.
4. SDK runs the ZK circuit
The SDK loads africazk.wasm in the browser and runs Groth16 proof generation. The circuit checks: the EdDSA signature is valid under the embedded Althea public key, the age is at least 18, and the ID type is 1 or 2. It outputs a proof and two public signals — valid and nullifier.
5. Local verification
Before submitting, the SDK runs snarkjs.groth16.verify() locally against the proof. This catches WASM corruption or tampering before a transaction is built.
6. User signs the Solana transaction
The SDK builds the Solana transaction carrying the proof and public signals, hands it to the connected wallet, and the user signs once.
7. Althea Anchor program processes
The on-chain program does, in order:
- Checks valid === 1.
- Checks Ax/Ay match the Althea public key the program stores — rejects rogue signing keys.
- Derives the NullifierRecord PDA from the nullifier and initialises it. If the PDA already exists, the transaction fails — this is the one-person-one-wallet guarantee.
- Derives the AttestationRecord PDA from the wallet pubkey and initialises it with verified=true, current timestamp, and protocol version "Althea-v1".
8. Any dApp can read the attestation
Forever afterwards, any Solana dApp can call checkAttestation(walletAddress). The PDA exists, verified is true, the user is in. The dApp never saw the NIN, never stored personal data, never had to ask.
Where personal data lives at each step
- Step 1: in the user's head and your form state.
- Step 2: traversing HTTPS to the Althea backend and from there to Dojah.
- Step 3: in the server's memory for a few milliseconds, never logged, never persisted.
- Steps 4 onwards: nowhere. The browser holds a credential that is already Poseidon-hashed at this point, then wipes that too after the proof.