Skip to content

Passkeys

Understand WebAuthn user presence, PRF-derived material, RP ID scope, and passkey recovery boundaries.

Passkeys

Passkeys provide WebAuthn user presence and, where available, PRF-derived holder-side material.

Role in the model

Passkeys can:

  1. prove local user presence;
  2. derive or unlock holder-side material;
  3. step up expired or exhausted Wallet Session quotas;
  4. authorize sensitive operations when policy requires a cryptographic factor.

Passkeys do not make app sessions into signing authority. Passkey results are normalized into the same lane, Wallet Session/quota, capability-grant, and policy model as other auth methods.

Register with a passkey

The React integration keeps registration results typed by capability and provisioning state.

Runnable React example
tsx
import type { RegistrationFlowEvent } from '@seams/wallet';
import { useSeams } from '@seams/wallet/react';

export function CreateWalletButton() {
  const { registerPasskey, seams } = useSeams();

  const onCreateWallet = async (): Promise<void> => {
    const result = await registerPasskey({
      onEvent: (event: RegistrationFlowEvent) =>
        console.log(event.phase, event.status, event.message),
    });
    if (!result.success) {
      console.error('Registration failed:', result.error);
      return;
    }
    // `walletId` is the stable identifier for every later wallet operation.
    console.log(`Wallet ${result.walletId} registered (${result.kind})`);

    // A mixed registration returns before NEAR provisioning finishes, so the
    // result carries no NEAR account id yet. Wait for one before signing NEAR.
    if (result.kind === 'ecdsa_wallet_registered_near_pending') {
      const near = await seams.registration.awaitNearReady({ walletId: result.walletId });
      console.log('NEAR provisioning finished:', near.kind);
    }
  };

  return <button onClick={() => void onCreateWallet()}>Create wallet</button>;
}