Skip to main content
This page walks the modern path — SHHH wallets with a P-256 passkey. The user’s private key lives inside their platform authenticator (Secure Enclave on Apple, TPM on Windows, Android Keystore on Android). It cannot leave the device. The page also points at the legacy PRF path if you’re integrating against existing CHIPI v29 wallets.

1. Register a passkey

createShhhPasskey triggers the browser’s biometric prompt and returns the new credential’s id + public key. Call it from a button click, never on page load.
The returned publicKeyHex.x and publicKeyHex.y are the two 32-byte coordinates of the user’s new P-256 key. Pass both into your createWallet call as signerKind: "WEBAUTHN_P256" so the SHHH wallet’s first owner is this passkey.

2. Create a SHHH wallet bound to the passkey

The passkey package never talks to chipi-back directly. Hand the credential to your existing wallet-creation flow — typically useCreateWallet from @chipi-stack/chipi-react — with the right walletType + signerKind:

3. Sign a transaction with the passkey

signShhhMessage prompts the user with biometrics again, runs the WebAuthn ceremony, and returns the raw signature pieces. The backend SDK accepts these as-is — you don’t need to assemble the SHHH envelope yourself.
The wallet’s address never appears in this flow — the verifier reproduces the assertion check on chain using the WEBAUTHN_P256 verifier class registered against the wallet.

Full Next.js / React example

What happens if the user has a passkey already?

hasShhhPasskey() checks localStorage for a stored credential id, so you can branch your UI between “Sign up” and “Sign in” without prompting. If the user wipes their browser storage, the credential id is lost but the passkey itself still lives in the platform authenticator — you’ll prompt them once to re-discover it.

When biometrics aren’t available

If isWebAuthnSupported() returns false, fall back to the PIN flow described in When passkeys fail. That flow is also the right one for legacy CHIPI v29 wallets, which use a PRF-derived encryption key instead of a P-256 signature.