LogoPear Docs
How ToManage identity

Create a portable identity with Keet identity keys

Derive a portable identity from a mnemonic, attest a per-device key, then sign and verify data with it — the Pear/Bare logic, no UI required.

This guide focuses on the Pear/Bare logic. It shows keet-identity-key on its own — no Electron, no UI. For the same identity wired into a full desktop chat app, see the worked example pear-chat-identity and its walkthrough, Add Keet identity to a chat app.

A Hypercore key identifies a log, not a person. keet-identity-key gives you a portable identity: a key derived from a 24-word mnemonic that stays the same across devices and reinstalls. Each device generates its own throwaway key pair, which the identity attests — so you can sign data on any device and anyone can verify it was authored by the same person, without ever copying the identity's secret onto that device.

Without the identity, you would need to share a secret between devices to sign data — and that secret would need to be copied onto each device. With the identity, you can sign data on any device and anyone can verify it was authored by the same person, without ever copying the identity's secret onto that device.

This is purely Pear-end logic: it runs in a Bare worker (or any Bare/Node process) and never touches a UI.

The model

ConceptWhat it is
Mnemonic24 words. The root secret — back it up like a wallet seed.
IdentityDerived from the mnemonic. Its identityPublicKey is stable everywhere.
Device key pairA fresh, per-device key. Never leaves the device.
Device proofThe identity's signature attesting that the device key speaks for it.
Data proofA signature over a payload, made with the device key, anchored to the identity.

Add the dependencies

npm install keet-identity-key hypercore-crypto

Derive the identity and attest a device

Generate (or load) a mnemonic, derive the identity, then bootstrap this device:

import Identity from 'keet-identity-key'
import crypto from 'hypercore-crypto'

// Generate once and persist it somewhere safe (treat it like a wallet seed).
const mnemonic = Identity.generateMnemonic()

const identity = await Identity.from({ mnemonic })
// identity.identityPublicKey is the same on every device that loads this mnemonic.

// Each device gets its own ephemeral key pair, attested by the identity.
const deviceKeyPair = crypto.keyPair()
const deviceProof = await identity.bootstrap(deviceKeyPair.publicKey)

Persist the mnemonic, not the device key — a new device re-derives the identity from the same mnemonic and bootstraps a fresh device key of its own.

Sign data

Attest a payload with the device key. The resulting proof carries the chain back to the identity:

const payload = Buffer.from('hello from this device')
const proof = Identity.attestData(payload, deviceKeyPair, deviceProof)

Attach proof to whatever you append to your Hypercore/Autobase alongside the payload.

Verify data

Any peer replicating the data can verify it was authored by the expected identity — no shared secret needed:

const ok = Identity.verify(proof, payload, {
  expectedIdentity: identity.identityPublicKey
})
// ok is truthy when the proof is valid for that identity.

Because verification only needs the public identityPublicKey, you can stamp every message with a proof and let every reader confirm authorship across reinstalls and across machines.

See also

On this page