High-level TypeScript client library for zk-passport with WebRTC and smart contract integration.
- 🔐 Zero-Knowledge Proofs: Registration and query proof support
- 🌐 WebRTC Communication: Seamless desktop-mobile connection via
@grndd-systems/zk-proof-rtc - 📱 QR Code Generation: Built-in session payload for easy mobile scanning
- ⚡ Smart Contract Integration: Uses ethers.js for contract interactions
- ⚛️ React Hooks: Optional React integration for easy UI development
- 📦 Tree-Shakeable: ESM/CJS dual output with zero runtime dependencies in core
- 🎯 Type-Safe: Full TypeScript support with strict mode
npm install @grndd-systems/zk-passport-client @grndd-systems/zk-proof-rtc ethersimport { ZkPassportClient } from '@grndd-systems/zk-passport-client';
import { ethers } from 'ethers';
// Setup ethers provider
const provider = new ethers.JsonRpcProvider('https://rpc.ankr.com/eth');
// Initialize client
const client = new ZkPassportClient({
firebase: {
apiKey: 'your-api-key',
authDomain: 'your-project.firebaseapp.com',
databaseURL: 'https://your-project.firebaseio.com',
projectId: 'your-project-id',
},
contracts: {
registration: '0x...',
queryProofExecutor: '0x...',
stateKeeper: '0x...',
},
provider,
debug: true,
});
// Create a proof session
const session = await client.createProofSession({
type: 'age_check',
userAddress: '0x1234567890123456789012345678901234567890',
conditions: {
minAge: 18,
},
});
// Display QR code to user
console.log('Scan this QR code:', session.qrCodeUrl);
// Wait for mobile app to send proof
const transaction = await session.waitForTransaction();
// Sign and send transaction
const signer = new ethers.Wallet(privateKey, provider);
const tx = await signer.sendTransaction(transaction);
await tx.wait();
console.log('Transaction confirmed:', tx.hash);
// Cleanup
session.close();
client.close();import { useZkPassportClient } from '@grndd-systems/zk-passport-client/react';
import { ethers } from 'ethers';
import QRCode from 'react-qr-code';
function PassportVerification() {
const provider = new ethers.BrowserProvider(window.ethereum);
const { sessionState, createSession, waitForTransaction } = useZkPassportClient({
firebase: {
apiKey: 'your-api-key',
authDomain: 'your-project.firebaseapp.com',
databaseURL: 'https://your-project.firebaseio.com',
projectId: 'your-project-id',
},
contracts: {
registration: '0x...',
queryProofExecutor: '0x...',
stateKeeper: '0x...',
},
provider,
});
const handleVerify = async () => {
// Create session
await createSession({
type: 'age_check',
userAddress: await signer.getAddress(),
conditions: { minAge: 18 },
});
// Wait for proof from mobile
const tx = await waitForTransaction();
// Send transaction
if (tx) {
const signer = await provider.getSigner();
const result = await signer.sendTransaction(tx);
await result.wait();
console.log('Verified!', result.hash);
}
};
return (
<div>
<button onClick={handleVerify}>Start Verification</button>
{sessionState.qrCodeUrl && (
<div>
<h3>Scan with mobile app:</h3>
<QRCode value={sessionState.qrCodeUrl} />
</div>
)}
<div>
<p>State: {sessionState.state}</p>
{sessionState.isConnected && <p>✅ Mobile connected</p>}
{sessionState.isReady && <p>✅ Transaction ready</p>}
{sessionState.error && <p>❌ Error: {sessionState.error.message}</p>}
</div>
</div>
);
}Main client class for creating proof sessions.
new ZkPassportClient(config: ZkPassportClientConfig)Config Options:
firebase: Firebase configuration for WebRTC signalingcontracts: Smart contract addressesregistration: Registration contract addressqueryProofExecutor: Query proof executor contract addressstateKeeper: State keeper contract address
provider: Ethers.js provider for reading contract statedebug?: Enable debug logging (default:false)
Create a new proof session.
Options:
type: Proof type ('registration'|'age_check'|'disclosure')userAddress: User's wallet addressconditions?: Additional proof conditionsminAge?: Minimum age requirementallowedCountries?: Array of allowed country codesfields?: Array of fields to disclose
Returns: ProofSession instance
Close all active sessions and cleanup resources.
Represents a single proof session.
state: Current session statepeerId: Peer ID for QR codeqrCodeUrl: Data URL containing session payload for QR codeerror: Last error if any
Wait for mobile app to send proof data and return ready-to-sign transaction.
Close the session and cleanup resources.
state:change: Session state changedmobile:connected: Mobile device connectedproof:received: Proof data receivedtransaction:ready: Transaction ready to signerror: Error occurred
React hook wrapper for ZkPassportClient.
function useZkPassportClient(options: UseZkPassportClientOptions): UseZkPassportClientReturnOptions: Same as ZkPassportClientConfig plus:
autoCleanup?: Auto-cleanup client on unmount (default:true)
Returns:
sessionState: Current session statesession: Active session instancestate: Session stateqrCodeUrl: QR code URLpeerId: Peer IDerror: Error if anytransaction: Ready transactionisConnected: Mobile connectedisReady: Transaction ready
createSession(options): Create new sessionwaitForTransaction(): Wait for transactioncloseSession(): Close current sessioncloseClient(): Close entire client
Register a new passport on-chain.
await client.createProofSession({
type: 'registration',
userAddress: '0x...',
});Verify user's age without revealing exact birth date.
await client.createProofSession({
type: 'age_check',
userAddress: '0x...',
conditions: {
minAge: 18,
},
});Reveal specific passport fields.
await client.createProofSession({
type: 'disclosure',
userAddress: '0x...',
conditions: {
fields: ['citizenship', 'birthDate'],
},
});┌─────────────────┐
│ Your App │
│ (Web/React) │
└────────┬────────┘
│
├─ ZkPassportClient
│ └─ ProofSession
│ ├─ WebRTCConnection (@grndd-systems/zk-proof-rtc)
│ │ └─ FirebaseSignalingClient
│ └─ ContractClient (ethers.js)
│
├─ Firebase Realtime DB (WebRTC signaling)
│
└─ Smart Contracts (Ethereum)
├─ Registration
├─ QueryProofExecutor
└─ StateKeeper
- Initialize: Create client with Firebase and contract config
- Create Session: Call
createProofSession()with proof type - Display QR Code: Show
session.qrCodeUrlto user - Mobile Scans: User scans QR with mobile app
- WebRTC Connect: Desktop and mobile establish P2P connection
- Proof Transfer: Mobile generates and sends proof via WebRTC
- Transaction Build: Client builds transaction from proof data
- Sign & Send: Your app signs and submits transaction
try {
const session = await client.createProofSession({
type: 'age_check',
userAddress: address,
});
session.on('error', ({ error }) => {
console.error('Session error:', error);
});
const tx = await session.waitForTransaction();
// ... send transaction
} catch (error) {
console.error('Failed to create session:', error);
}Enable debug logging to troubleshoot issues:
const client = new ZkPassportClient({
// ... config
debug: true,
});This will log:
- Client initialization
- Session creation
- WebRTC connection events
- Proof data reception
- Transaction building
MIT
- @grndd-systems/zk-proof-rtc - WebRTC communication library