Skip to main content

Overview

WebAuthn passkeys replace PINs with biometric authentication (Face ID, Touch ID, Windows Hello). No PINs to remember or store.

Prerequisites

  • Next.js 13+ with App Router
  • Modern browser with WebAuthn support
  • Biometric hardware (fingerprint, face recognition)
  • Chipi Next.js SDK installed

Installation

npm install @chipi-stack/chipi-passkey

Basic Implementation

1

Create wallet with passkey

"use client";
import { usePasskeySetup } from "@chipi-stack/nextjs";
2

Authenticate with passkey

"use client";
import { usePasskeyAuth } from "@chipi-stack/nextjs";
3

Migrate existing wallet (optional)

If users already have a PIN-based wallet, they can migrate to passkey:
"use client";
import { useMigrateWalletToPasskey } from "@chipi-stack/nextjs";

Example

"use client";

import { useCreateWallet } from '@chipi-stack/nextjs';
import { usePasskeySetup } from '@chipi-stack/nextjs';
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 encryptKey = await setupPasskey();
      
      const result = await createWalletAsync({
        params: {
          encryptKey,
          usePasskey: true,
          externalUserId: 'user-123',
        },
        bearerToken: 'your-jwt-token',
      });
      
      localStorage.setItem('wallet', JSON.stringify(result.wallet));
      setWallet(result);
    } catch (err) {
      console.error(err);
    }
  };

  return (
    <div className="p-6 bg-white rounded-lg shadow">
      <button 
        onClick={handleCreate} 
        disabled={isLoading}
        className="px-4 py-2 bg-green-600 text-white rounded disabled:bg-gray-400"
      >
        {isLoading ? 'Creating...' : 'Create Wallet with Passkey'}
      </button>
      {error && <p className="text-red-600 mt-2">Error: {error.message}</p>}
      {wallet && (
        <p className="text-sm mt-4 font-mono">
          Wallet created: {wallet.wallet.publicKey}
        </p>
      )}
    </div>
  );
}

Hooks Reference

HookPurpose
usePasskeySetupCreate new passkey
usePasskeyAuthAuthenticate with existing passkey
usePasskeyStatusCheck passkey support & status
useMigrateWalletToPasskeyMigrate 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