| name | sui-passkey |
| description | Use when implementing WebAuthn passkeys or biometric authentication (Face ID, fingerprint, hardware keys) on SUI. Triggers on "passkey", "WebAuthn", "biometric login", "Face ID", "fingerprint auth", "FIDO2", or passwordless auth that uses device authenticators instead of seed phrases. Different from zkLogin (which uses OAuth providers). |
| metadata | {"author":"first-mover-tw"} |
SUI Passkey Integration
Passwordless authentication using WebAuthn and device biometrics.
Overview
Passkey provides:
- Biometric authentication (Face ID, Touch ID, Windows Hello)
- No passwords or seed phrases
- Hardware-backed security
- Cross-device sync (via iCloud, Google)
Use Cases
- Consumer apps requiring easy login
- Mobile-first applications
- Security-critical applications
- Enterprise SUI apps
Quick Start
Register Passkey
import { PasskeyProvider } from '@mysten/wallet-standard';
async function registerPasskey(username: string) {
const provider = new PasskeyProvider();
const credential = await navigator.credentials.create({
publicKey: {
challenge: new Uint8Array(32),
rp: {
name: 'My SUI App',
id: window.location.hostname
},
user: {
id: new Uint8Array(16),
name: username,
displayName: username
},
pubKeyCredParams: [{ alg: -7, type: 'public-key' }],
authenticatorSelection: {
authenticatorAttachment: 'platform',
userVerification: 'required'
}
}
});
const address = provider.getAddress(credential);
return { credential, address };
}
Authenticate with Passkey
async function authenticatePasskey() {
const credential = await navigator.credentials.get({
publicKey: {
challenge: new Uint8Array(32),
rpId: window.location.hostname,
userVerification: 'required'
}
});
return credential;
}
Sign Transaction
async function signWithPasskey(tx: Transaction) {
const provider = new PasskeyProvider();
const credential = await authenticatePasskey();
const signature = await provider.signTransaction(tx, credential);
return signature;
}
React Hook
function usePasskey() {
const [address, setAddress] = useState<string | null>(null);
const [isRegistered, setIsRegistered] = useState(false);
const register = async (username: string) => {
const { credential, address } = await registerPasskey(username);
localStorage.setItem('passkey_credential_id', credential.id);
localStorage.setItem('passkey_address', address);
setAddress(address);
setIsRegistered(true);
};
const authenticate = async () => {
const credential = await authenticatePasskey();
if (credential) {
const storedAddress = localStorage.getItem('passkey_address');
setAddress(storedAddress);
}
};
const signTransaction = async (tx: Transaction) => {
(tx);
};
{ address, isRegistered, register, authenticate, signTransaction };
}
Move Contract
// Passkey addresses are regular SUI addresses
// No special Move code needed!
public fun create_profile(
name: String,
ctx: &mut TxContext
) {
let user = tx_context::sender(ctx); // Works with passkey!
// ...
}
Best Practices
- Check WebAuthn browser support
- Fallback to traditional wallet
- Handle credential loss scenarios
- Test on multiple devices
- Provide backup authentication
Browser Compatibility
- ✅ Chrome/Edge (Windows, macOS, Android)
- ✅ Safari (macOS, iOS)
- ✅ Firefox (Windows, macOS)
- ⚠️ Check mobile browser support
Common Mistakes
❌ Not checking WebAuthn browser support
- Problem: App crashes on unsupported browsers
- Fix: Check
window.PublicKeyCredential before registering passkey
❌ No fallback authentication method
- Problem: Users locked out if passkey device is lost
- Fix: Offer traditional wallet connection as fallback
❌ Storing credential ID without encryption
- Problem: XSS attacks can steal credential reference
- Fix: Encrypt credential ID before localStorage, or use sessionStorage
❌ Not handling "user cancelled" flow
- Problem: App stuck in loading state
- Fix: Catch AbortError, show "Authentication cancelled" message
❌ Using wrong authenticator attachment
- Problem: Requires USB key instead of platform biometrics
- Fix: Set
authenticatorAttachment: 'platform' for Face ID/Touch ID
❌ Not testing on multiple devices
- Problem: Works on desktop, fails on mobile
- Fix: Test registration and authentication on iOS, Android, desktop
❌ Missing user verification requirement
- Problem: Security risk, no biometric check
- Fix: Set
userVerification: 'required' for all operations
❌ Not providing credential recovery flow
- Problem: Users lose access if they reset device
- Fix: Implement account recovery via email or backup passkey
Query Passkey docs:
const passkeyInfo = await sui_docs_query({
type: "github",
target: "sui-core",
query: "passkey WebAuthn implementation examples"
});
Secure, user-friendly authentication with no passwords!
Converted and distributed by TomeVault — claim your Tome and manage your conversions.