Unlock CAPPZ with a passkey, sign receipts on your device, and notarize a whole batch in one transaction
By CAPPZ.AI ·
Your CAPPZ wallet now unlocks with a fingerprint, face or PIN, using the secure hardware already in your phone or laptop. That device can sign your notarization receipts, one XRPL transaction anchors a whole batch of files, and wallet signatures verify up to 258× faster.
Phones and laptops already have secure hardware built in: the Secure Enclave on Apple devices, a TEE or StrongBox chip on Android, a TPM on Windows. Until now CAPPZ didn't use it. With this release, that hardware unlocks your wallet and signs your notarization receipts. Notarizing many files now costs one ledger transaction, and the encryption keys for your private records come from your wallet instead of from anything public. All of it is open source in the CAPPZ SDK.
Unlock with a passkey
Sign in with your recovery phrase once and CAPPZ offers to set up passkey unlock. After that, an Unlock with passkey button opens your wallet with a fingerprint, face or PIN.
Here is how it works. A passkey's authenticator can derive a secret from a key that never leaves the hardware, and it only does so after it has checked that you are you (the WebAuthn PRF extension). CAPPZ turns that secret into the key that encrypts your wallet key on the device.
- What's stored: ciphertext and a random salt. No server holds anything that can decrypt it.
- Bound to your wallet: the wallet address is sealed into the encryption, so a copy moved to another wallet won't open.
- Several devices: your phone and your laptop can each hold a passkey for the same wallet, and one prompt opens it with whichever is present.
When you add a passkey, CAPPZ checks its attestation (more on that below) and records the result. If your browser or authenticator doesn't support PRF yet, your passcode keeps working as before.
Receipts signed by your device
A notarization receipt has always proved which wallet anchored a file. Now it can also prove which enrolled device made it, and that a person unlocked that device to do so.
- Your passkey signs each receipt. A whole batch takes one prompt, not one per file.
- Each receipt carries your wallet's KeyZ declaration for the device key, so anyone can check the signature offline, with no call to CAPPZ.
- The receipt dialog tells you exactly what it found: trusted, revoked, expired, undeclared, or the specific failure (a bad signature, the wrong website, no user verification).
Notarization never waits on this. With no passkey enrolled, your file is notarized as usual and the receipt simply isn't device-signed.
One transaction for a whole batch
Previously each file needed its own XRPL transaction. Now one transaction anchors the whole batch. The files are combined into a Merkle tree, the tree's root goes on the ledger, and each file's receipt carries a short inclusion proof showing that the file belongs to that root.
The tree follows the standard used by Certificate Transparency (RFC 9162), and our implementation reproduces its published test vectors. Building the tree and every proof for 1,000 files takes about 43 ms, and checking all 1,000 proofs about 51 ms.
One detail we found while testing: inside part of a tree, the proof alone doesn't commit to how many files the batch held. File 6 of 13 and file 6 of 14 can share the same proof. So the ledger anchor states the batch size, and verification refuses any anchor that doesn't.
The price is unchanged at 2 CAPPZ per file, now paid in a single transfer, with one network fee for the batch instead of one per file.
Proving a passkey lives in real hardware
A passkey can come with an attestation: a statement, signed by the device maker's certificate chain, that the key was created inside its secure hardware. CAPPZ now verifies the five common formats: none, packed, apple, android-key and tpm.
It gives two separate answers, because they are different questions:
- Is the statement valid? Yes, or exactly what failed.
- How far is it trusted? It chains to a pinned vendor root, it's consistent but has no known root, it's signed only by the credential's own key, or there is no attestation at all.
Apple's and Google's roots are pinned from the vendors' own endpoints and cross-checked against a second, independent source. TPM and FIDO roots aren't shipped, so apps that need them pass them in.
We tested against 11 registrations captured from real authenticators, including Face ID and Touch ID, a Pixel 8a, and six Windows Hello TPM registrations. Each one verified as expected, and every tampered version (a changed challenge, website, signature or authenticator data) was refused.
Note that synced passkeys, such as those in iCloud Keychain or Google Password Manager, usually send no attestation. They are still protected by hardware on each device, but nothing proves that to a verifier.
Your private records now open only with your wallet
Some CAPPZ records used to be encrypted with keys derived from public values, like your wallet address or a file's hash. Anyone who knew those values could compute the key. That's fixed.
Each record now gets its own random data key, and that key is wrapped by a key derived from your wallet's private key. This covers agent history, calendar settings and their backup, healthcare storage, the compress-and-encrypt skill, and copies of notarized files. Your recovery phrase still opens every record on any device, and there is no extra key to keep.
Older records still open, and they are re-sealed with the new scheme the first time you open them with your wallet unlocked. One thing to know: healthcare memos already written to the ledger used the old address-derived key, so treat their contents as disclosed.
Encryption and hashing are also faster. File encryption now uses the browser's hardware AES (a 16 MB file went from about 3.2 s to 23 ms), and unlocking your wallet no longer freezes the page: the stall dropped from about 220 ms to 7 ms.
Faster signature checks
secp256k1 has no built-in browser implementation, so every wallet signature and KeyZ declaration was checked in pure JavaScript. The SDK now verifies signatures on its Rust kernels, in batches across cores.
Measured on a Snapdragon 8cx Gen 3, 256 signatures, against the previous pure JavaScript code:
| Before | WASM | Native, one core | Native, 8 cores | |
|---|---|---|---|---|
| secp256k1 (wallet and KeyZ signatures) | 272/s | 9.7× | 50× | 258× |
| Ed25519 (hello signatures) | 6,535/s | 1.5× | 2.6× | 12.6× |
The native columns apply to Node, Deno and Bun, such as CAPPZ edge nodes. In Edge and Chrome the WASM gain for secp256k1 is smaller, about 1.8×, and the browser's own Ed25519 is faster than WASM, so browsers keep using it. The Rust code uses the audited k256 and ed25519-dalek libraries and gives the same answers as the code it replaces in every test.
Try it
Passkey unlock, device-signed receipts and batch notarization are live in CAPPZ now. Developers can find the code and the full write-up in the CAPPZ SDK, in docs/HARDWARE_TRUST.md and docs/NATIVE_KERNELS.md.
Topics: passkeys, WebAuthn, notarization, XRPL, hardware security, Merkle proofs, encryption, SDK
Version 1 · recorded on the CAPPZ admin chain · content sha256 2fcb5d16a1e20fb6