@hyperauth/contracts
v0.2.3
Published
HyperAuth smart contract ABIs, deployment addresses, and KV sync tooling
Readme
HyperAuth Contracts
Smart contract wallet powered by passkeys. ERC-4337 account abstraction with P-256 signature verification via the RIP-7212 precompile, rotatable owner keys with guardian recovery, ephemeral agent session keys, a non-custodial gas paymaster, an on-chain bundler stake/identity layer, and soulbound session tokens.
Architecture
| Contract | Description |
|----------|-------------|
| HyperAuthAccount | ERC-4337 smart account — validates passkey (P-256) signatures via LibP256/RIP-7212. Owner key is rotatable (48h guardian timelock recovery); also authorizes ephemeral secp256k1 session keys for AI-agent UserOps. Supports CREATE2 and EIP-7702 via initialize |
| HyperAuthFactory | Deterministic CREATE2 deployment from passkey public keys (X, Y). Init code is key-free, so the address is identical cross-chain and survives key rotation; injects the email relayer as each account's recovery guardian |
| Bundler | On-chain stake + identity layer for the off-chain bundler service. Holds the EntryPoint stake and is the single source of truth (isAuthorized) gating the paymaster and session minting; supports an emergency pause |
| Paymaster | Non-custodial ERC-4337 v0.7 paymaster. App operators self-fund their own gas-sponsorship balance; sponsorship is gated on the registered bundler. Owner can never touch operator balances |
| DIDRegistry | On-chain DID anchor — maps W3C DIDs to controller accounts with metadata CID, with human-readable aliases protected by a re-registration cooldown |
| AccountHelper | Lens contract — single eth_call to fetch nonce, DID, pubkey, and deployment status |
| SessionSBT | Soulbound ERC-721 — non-transferable session tokens with mint/revoke lifecycle and per-session UCAN capability anchors |
| LibP256 | Library — reusable P-256 signature verification via RIP-7212 precompile at 0x100 |
Prerequisites
Installation
git clone https://github.com/hyperauth-org/contracts.git
cd contracts
forge installBuild
forge buildTest
forge test -vvvFormat
forge fmtDeploy
script/Deploy.s.sol (DeployGenesis) deploys the full stack — SessionSBT, DIDRegistry, AccountHelper, HyperAuthFactory, Bundler, and Paymaster — then wires them together (bundler.registerBundler(...), sbt.setBundlerRegistry(...)). The ERC-4337 EntryPoint (v0.7, 0x0000000071727De22E5E9d8BAf0edAc6f37da032) is hardcoded.
Required environment variables
| Variable | Required | Description |
|----------|----------|-------------|
| PRIVATE_KEY | yes | Deployer private key |
| AUTHORIZED_BUNDLER | yes | Off-chain bundler service EOA, registered on the Bundler contract |
| HYPERAUTH_TREASURY | yes | Protocol fee recipient passed to the Paymaster |
| EMAIL_RELAYER | yes | Email relayer injected as the recovery guardian of every account |
| PROTOCOL_FEE_BPS | no (default 0) | Paymaster protocol fee in basis points (max 2000 = 20%) |
export PRIVATE_KEY=<your_private_key>
export AUTHORIZED_BUNDLER=<bundler_service_eoa>
export HYPERAUTH_TREASURY=<fee_recipient_address>
export EMAIL_RELAYER=<email_relayer_address>
export PROTOCOL_FEE_BPS=0 # optional
# Deploy to Base Sepolia
forge script script/Deploy.s.sol --rpc-url https://sepolia.base.org --broadcastEmitted outputs (for backend bring-up)
DeployGenesis emits the deployed addresses two ways so the walletbases/backend
orchestrator can consume them after the deploy:
deployments/<chainId>.json— machine-readable, keyed by the exactorchestrator/.envvariable names. Example (deployments/84532.json, Base Sepolia):{ "ACCOUNT_HELPER_ADDRESS": "0x…", "BUNDLER_ADDRESS": "0x…", "CHAIN_ID": 84532, "DID_REGISTRY_ADDRESS": "0x…", "ENTRY_POINT_ADDRESS": "0x0000000071727De22E5E9d8BAf0edAc6f37da032", "HYPERAUTH_FACTORY_ADDRESS": "0x…", "PAYMASTER_ADDRESS": "0x…", "SESSION_SBT_ADDRESS": "0x…" }A printed
=== orchestrator/.env (copy these) ===block on stdout at the end of the run, for quick copy-paste.
The orchestrator (orchestrator/.env) requires these three:
| Output | Source contract |
|--------|-----------------|
| HYPERAUTH_FACTORY_ADDRESS | HyperAuthFactory |
| SESSION_SBT_ADDRESS | SessionSBT |
| ACCOUNT_HELPER_ADDRESS | AccountHelper |
ENTRY_POINT_ADDRESS is the canonical ERC-4337 v0.7 singleton
0x0000000071727De22E5E9d8BAf0edAc6f37da032 (not deployed by this repo).
Identity handshake.
AUTHORIZED_BUNDLERandEMAIL_RELAYERare backend-owned EOAs that must be finalized before runningDeployGenesis— the deploy registers them on-chain (Bundler.registerBundler, factory recovery guardian). The bundler signer Rundler uses must equalAUTHORIZED_BUNDLERexactly, or sponsored UserOps revert in paymaster validation. See the backend README "Deploying with the contracts repo" for the full ordered sequence.
After deploying, regenerate the TypeScript SDK so ts/deployments.ts reflects the new addresses:
npm run generateIndexer
A Cloudflare Worker that indexes on-chain events (DIDRegistered, DIDUpdated, DIDDeactivated, AliasRegistered, AccountCreated) into Postgres. Runs on a cron schedule and writes to Neon (serverless Postgres) in production.
Neon DB Setup
- Create a free project at neon.tech
- Copy the connection string (looks like
postgresql://user:[email protected]/neondb?sslmode=require) - Run the migration against your Neon database:
psql "$DATABASE_URL" -f db/migrations/001_did_registration_schema.sqlLocal Development
For local development, Postgres runs via Docker and the schema is auto-applied on startup:
# Start local Postgres (schema auto-migrates via docker-entrypoint-initdb.d)
docker compose up postgres -d
# Install indexer dependencies
cd indexer && npm install
# Create a .dev.vars file with your secrets
cat > .dev.vars <<EOF
DATABASE_URL=postgresql://hyperauth:password@localhost:5432/hyperauth_local
RPC_URL=https://sepolia.base.org
EOF
# Run the indexer locally (triggers on HTTP, not cron)
npm run dev
# Trigger a manual indexing run
curl http://localhost:8787/run
# Health check
curl http://localhost:8787/healthDeploy to Cloudflare
cd indexer
# Set secrets (one-time)
wrangler secret put DATABASE_URL # Neon connection string
wrangler secret put RPC_URL # Base Sepolia RPC endpoint
# Deploy
npm run deploy
# Tail logs
npm run tailThe worker runs every minute and indexes up to 2,000 blocks per contract per invocation. Progress is tracked in the indexer_cursors table so it resumes from where it left off.
License
MIT
