Getting Started
Quick Start
Get an Althea-verified user into your Solana dApp in four steps. No backend changes. No data to store.
1. Install
Add the SDK and the Solana wallet adapter to your project.
npm install afrzk-sdk @solana/wallet-adapter-react2. Check the connected wallet
Always start with checkAttestation(). Verified users carry their attestation in their wallet, so most users will already pass after the first check and never see your verification screen again.
import { checkAttestation } from 'afrzk-sdk'
import { useWallet } from '@solana/wallet-adapter-react'
const { publicKey } = useWallet()
const status = await checkAttestation(
publicKey!.toString(),
'mainnet-beta'
)
if (status.verified) {
// User already has a valid attestation on this wallet
}3. Run the verification flow
Only if the wallet isn't already attested, kick off the three-step flow. The user enters their NIN or BVN once. Althea confirms it, generates a ZK proof inside the browser, and submits the proof to the Anchor program. You never see the NIN.
import {
verifyIdentity,
generateProof,
submitProof,
} from 'afrzk-sdk'
async function runVerification(nin: string, dob: string, wallet) {
// 1. Verify identity via Althea service
const credential = await verifyIdentity({
idType: 'NIN',
idNumber: nin,
dob,
})
// 2. Generate ZK proof in browser
// The credential is wiped from memory after this call
const proof = await generateProof(credential)
// 3. Submit to Solana - user signs the transaction
const result = await submitProof(proof, wallet, 'mainnet-beta')
return result.txSignature
}Wipe the credential immediately
The credential returned from verifyIdentity() is a signed bundle that lives in memory only. Pass it directly to generateProof() — never persist it, never log it, never send it anywhere.4. Gate your features
Wrap any verified-only route or component in a small gate. Below is a complete React component you can copy-paste. It checks the wallet on every mount and either renders the protected content or shows a link to your verification page.
'use client'
import { useEffect, useState, type ReactNode } from 'react'
import { useWallet } from '@solana/wallet-adapter-react'
import { checkAttestation } from 'afrzk-sdk'
export function VerifiedGate({ children }: { children: ReactNode }) {
const { publicKey } = useWallet()
const [verified, setVerified] = useState<boolean | null>(null)
useEffect(() => {
if (!publicKey) {
setVerified(false)
return
}
checkAttestation(publicKey.toString(), 'mainnet-beta')
.then((s) => setVerified(s.verified))
.catch(() => setVerified(false))
}, [publicKey])
if (verified === null) return <p>Checking…</p>
if (!verified) return <a href="/verify">Verify with Althea →</a>
return <>{children}</>
}That is the entire integration.
Five SDK functions, one component, one route. You are now serving verified Nigerian adults — without ever touching their personal data.Where to go next
- SDK reference — every function, every parameter, every return shape.
- Integrating with Next.js — full end-to-end guide including server-side gating.
- Privacy guarantees — what Althea does and does not see.