Documentation Index
Fetch the complete documentation index at: https://docs.chipipay.com/llms.txt
Use this file to discover all available pages before exploring further.
Overview
WebAuthn passkeys replace PINs with biometric authentication (Face ID, Touch ID, Windows Hello). No PINs to remember or store.
Prerequisites
- Modern browser with WebAuthn support (Chrome, Safari, Firefox, Edge)
- Biometric hardware (fingerprint, face recognition)
- Chipi React SDK installed
Installation
npm install @chipi-stack/chipi-passkey
Basic Implementation
Create wallet with passkey
import { usePasskeySetup } from "@chipi-stack/chipi-passkey/hooks";
Authenticate with passkey
import { usePasskeyAuth } from "@chipi-stack/chipi-passkey/hooks";
Migrate existing wallet (optional)
If users already have a PIN-based wallet, they can migrate to passkey:import { useMigrateWalletToPasskey } from "@chipi-stack/chipi-react";
Example
Create Wallet
Transfer with Passkey
Migrate to Passkey
import { useCreateWallet, Chain } from '@chipi-stack/chipi-react';
import { usePasskeySetup } from '@chipi-stack/chipi-passkey/hooks';
import { useState } from 'react';
export function CreateWalletWithPasskey() {
const { createWalletAsync, isLoading, error } = useCreateWallet();
const { setupPasskey } = usePasskeySetup();
const [wallet, setWallet] = useState(null);
const handleCreate = async () => {
try {
// Triggers biometric prompt
const passkeyResult = await setupPasskey('user-123', 'User Name');
const encryptKey = passkeyResult.encryptKey;
const result = await createWalletAsync({
params: {
encryptKey,
usePasskey: true,
externalUserId: 'user-123',
},
bearerToken: 'your-jwt-token',
});
localStorage.setItem('wallet', JSON.stringify(result));
setWallet(result);
} catch (err) {
console.error(err);
}
};
return (
<div>
<button onClick={handleCreate} disabled={isLoading}>
{isLoading ? 'Creating...' : 'Create Wallet with Passkey'}
</button>
{error && <p>Error: {error.message}</p>}
{wallet && <p>Wallet created: {wallet.publicKey}</p>}
</div>
);
}
import { useTransfer, ChainToken } from '@chipi-stack/chipi-react';
import { usePasskeyAuth } from '@chipi-stack/chipi-passkey/hooks';
import { useState } from 'react';
export function TransferWithPasskey() {
const { transferAsync, isLoading } = useTransfer();
const { authenticate } = usePasskeyAuth();
const [recipient, setRecipient] = useState('');
const [amount, setAmount] = useState('');
const handleTransfer = async () => {
try {
// Triggers biometric prompt — returns null if user cancels
const encryptKey = await authenticate();
if (!encryptKey) return;
const wallet = JSON.parse(localStorage.getItem('wallet')!);
const txHash = await transferAsync({
params: {
encryptKey,
usePasskey: true,
wallet,
token: 'USDC',
recipient,
amount: Number(amount),
},
bearerToken: 'your-jwt-token',
});
alert(`Transfer complete: ${txHash}`);
} catch (err) {
console.error(err);
}
};
return (
<div>
<input
placeholder="Recipient address"
value={recipient}
onChange={(e) => setRecipient(e.target.value)}
/>
<input
placeholder="Amount"
value={amount}
onChange={(e) => setAmount(e.target.value)}
type="number"
/>
<button onClick={handleTransfer} disabled={isLoading}>
{isLoading ? 'Sending...' : 'Send with Passkey'}
</button>
</div>
);
}
import { useMigrateWalletToPasskey } from '@chipi-stack/chipi-react';
import { useState } from 'react';
export function MigrateToPasskey() {
const { migrateWalletToPasskeyAsync, isLoading } = useMigrateWalletToPasskey();
const [currentPin, setCurrentPin] = useState('');
const handleMigrate = async () => {
try {
const wallet = JSON.parse(localStorage.getItem('wallet')!);
// The hook handles passkey creation internally —
// just pass the old PIN and it re-encrypts with passkey
await migrateWalletToPasskeyAsync({
wallet,
oldEncryptKey: currentPin,
externalUserId: 'user-123',
bearerToken: 'your-jwt-token',
});
alert('Successfully migrated to passkey!');
} catch (err) {
console.error(err);
}
};
return (
<div>
<input
type="password"
placeholder="Current PIN"
value={currentPin}
onChange={(e) => setCurrentPin(e.target.value)}
/>
<button onClick={handleMigrate} disabled={isLoading}>
{isLoading ? 'Migrating...' : 'Migrate to Passkey'}
</button>
</div>
);
}
Hooks Reference
| Hook | Purpose |
|---|
usePasskeySetup | Create new passkey |
usePasskeyAuth | Authenticate with existing passkey |
usePasskeyStatus | Check passkey support & status |
useMigrateWalletToPasskey | Migrate from PIN to passkey |
Browser Support
- ✅ Chrome 67+ (Desktop & Android)
- ✅ Safari 14+ (iOS 14+, macOS)
- ✅ Firefox 60+ (Desktop)
- ✅ Edge 18+ (Desktop)
Passkeys are stored in the browser and synced via platform (iCloud Keychain, Google Password Manager).
Security Benefits
- No PINs stored - Keys derived on-demand from biometric
- Platform-level security - Hardware-backed authentication
- Phishing resistant - Domain-bound credentials
- User convenience - One tap authentication
Next Steps