@loess/keys
Where a device's own keys and a passkey's signatures come from. The recovery phrase is in protocol. The sdk turns these into a key member of an identity.
import { createDeviceKeys, indexedDbDeviceKeyStore } from '@loess/keys/device';
const store = indexedDbDeviceKeyStore('loess');
const kept = yield * createDeviceKeys(store); // the first time; later, `yield* store.read`Interface
./device:createDeviceKeysmakes an Ed25519 key pair that can't be exported and a sealer secret, and keeps them (DeviceKeys) in aDeviceKeyStore, whichindexedDbDeviceKeyStoregives in a browser. The sealer comes from a secret kept beside the key pair, because Safari's IndexedDB loses a stored X25519 key. It fails withexistswhen the store holds keys, so two tabs never both keep keys. A device's private keys never leave the device../passkey:webAuthnAuthenticator(Authenticator,PasskeyAssertion) creates a passkey over WebAuthn that signs with ES256 or RS256 and asks it for assertions, with the PRF output when the passkey has PRF. A passkey's signature is a WebAuthn assertion whose challenge is the hash of the signed bytes../memory:memoryDeviceKeyStoreis a device key store, andmemoryAuthenticatoris a software passkey authenticator whose assertions have the WebAuthn layout.- Every failure is a
KeyErrorwith areasona screen can act on, such asrefusedfor a cancelled prompt orexistsfor kept keys.
Not built: a crypto wallet, which needs a small library to check secp256k1 since WebCrypto doesn't have it, and email recovery, which is only safe with a delay that every other owner can stop. The passkey authenticator is tested with the simulated one, not a real browser.
Place in the stack
It imports @loess/protocol only, and runs on devices.