Guides

Integrating with React

Althea's SDK is framework-agnostic — works in any modern React app. This guide covers Vite-based setups; Create React App works identically.

1. Install

terminal
npm install \
  @africazk/identity \
  @solana/wallet-adapter-react \
  @solana/wallet-adapter-react-ui \
  @solana/wallet-adapter-wallets \
  @solana/web3.js

2. Mount the providers

src/App.tsx
import {
  ConnectionProvider,
  WalletProvider,
} from '@solana/wallet-adapter-react'
import { WalletModalProvider } from '@solana/wallet-adapter-react-ui'
import { PhantomWalletAdapter } from '@solana/wallet-adapter-wallets'
import '@solana/wallet-adapter-react-ui/styles.css'
import { useMemo } from 'react'
import { VerifyView } from './VerifyView'

const RPC = 'https://api.mainnet-beta.solana.com'

export default function App() {
  const wallets = useMemo(() => [new PhantomWalletAdapter()], [])
  return (
    <ConnectionProvider endpoint={RPC}>
      <WalletProvider wallets={wallets} autoConnect>
        <WalletModalProvider>
          <VerifyView />
        </WalletModalProvider>
      </WalletProvider>
    </ConnectionProvider>
  )
}

3. Build the verify view

src/VerifyView.tsx
import { useEffect, useState } from 'react'
import { useWallet } from '@solana/wallet-adapter-react'
import { WalletMultiButton } from '@solana/wallet-adapter-react-ui'
import {
  checkAttestation,
  verifyIdentity,
  generateProof,
  submitProof,
  type AttestationStatus,
} from '@africazk/identity'

export function VerifyView() {
  const wallet = useWallet()
  const [status, setStatus] = useState<AttestationStatus | null>(null)
  const [nin, setNin] = useState('')
  const [dob, setDob] = useState('')
  const [pending, setPending] = useState(false)

  useEffect(() => {
    if (!wallet.publicKey) return
    checkAttestation(wallet.publicKey.toString(), 'mainnet-beta').then(setStatus)
  }, [wallet.publicKey])

  if (status?.verified) return <p>Verified ✓</p>

  return (
    <div>
      <WalletMultiButton />
      {wallet.publicKey && (
        <form
          onSubmit={async (e) => {
            e.preventDefault()
            setPending(true)
            const cred = await verifyIdentity({ idType: 'NIN', idNumber: nin, dob })
            const proof = await generateProof(cred)
            await submitProof(proof, wallet, 'mainnet-beta')
            const fresh = await checkAttestation(
              wallet.publicKey!.toString(),
              'mainnet-beta'
            )
            setStatus(fresh)
            setPending(false)
          }}
        >
          <input value={nin} onChange={(e) => setNin(e.target.value)} placeholder="NIN" />
          <input type="date" value={dob} onChange={(e) => setDob(e.target.value)} />
          <button type="submit" disabled={pending}>Verify</button>
        </form>
      )}
    </div>
  )
}

No SSR, no problem

Everything in this guide is client-only. The SDK does not need any server-side setup — the Althea backend is hosted, and the on-chain program is read directly via your chosen RPC.

Bundler notes

  • Vite — works out of the box. The SDK ships modern ESM and the WASM is loaded via new URL(..., import.meta.url).
  • CRA — needs a small Webpack override to enable async WebAssembly. Use craco with experiments.asyncWebAssembly = true.
  • RSpack / Rsbuild — works out of the box.