For the complete documentation index, see llms.txt. The full corpus is available at llms-full.txt. This page is also available as Markdown by appending
.mdto the URL.
Reading the history
Every version of an identity that has ever been published is kept, and every version is signed. The chain proves order and authorship. Bitcoin timestamps prove time. Together they mean nobody can rewrite the past quietly, including us.
The chain
Section titled “The chain”Each manifest carries two fields inside the signed payload:
seq: its place in line. The first version is 0, and each new one adds 1.prev:base64url(SHA-256(...))of the previous version’s JWS.
Because prev is covered by the signature, editing any old version changes its hash, which breaks the link every later version depends on. The history is append-only, and it is append-only as a matter of arithmetic rather than policy.
Fetch the whole thing, oldest first:
GET https://realhandles.com/<handle>/realhandles-chain.jsonWhat a valid chain means
Section titled “What a valid chain means”verifyChain in @realhandles/verify checks all of it:
- Every entry’s signature verifies against the public key inside it.
seqstarts at 0 and increments by 1, with no gaps.- Each
prevequals the hash of the entry before it. - The signing key stays the same, unless an entry carries a key change that was properly authorized.
On a key change it checks the authorization the same way the server did: either the previous key signed the handoff, or enough keys the identity had already published as recovery keys signed it. The recovery policy it judges against is the one in force before that entry, never the one the entry declares about itself. See Recovery and rotation.
If you pin a key, pin the genesis key. The chain then proves the current key from it, which is exactly the property that lets someone follow you through a rotation without having to be told.
Reading the outcomes
Section titled “Reading the outcomes”| What you see | What it means |
|---|---|
| Chain valid, same key throughout | Nothing has changed hands. |
| Chain valid, key changed with a handoff signed by the old key | An ordinary rotation. Same person, new key. |
| Chain valid, key changed with enough designated recovery signatures | A recovery. The identity came back through keys named in advance. |
| Key changed with no authorization in the entry | Do not trust it. The chain says so, in the entry itself. |
| Key differs from the one you saw before, and no handoff anywhere in the history | The identity you are looking at is not the one you saw before, whatever the handle says. |
Bitcoin timestamps
Section titled “Bitcoin timestamps”The chain proves order and authorship, but it does not prove when, and every entry in it lives in our database. An operator with database access could in principle fabricate a whole consistent history and date it to last year. Nothing inside the chain would contradict that.
OpenTimestamps closes it. The SHA-256 of each version’s JWS is submitted to public calendars and committed into the Bitcoin blockchain. That digest is the same one the next version records as its prev, so a timestamp on one entry transitively pins everything before it. Free, and no coins involved.
GET https://realhandles.com/<handle>/realhandles.otsTimestamping runs on a schedule rather than at the moment you publish, because nothing about saving your own signed manifest should depend on a third party being up. The honest consequence: a proof attests “existed no later than this block”, a little after you pressed publish. An upper bound on the date is what a timestamp proves anyway.
A version showing as pending simply has not made it into a block yet. It does not mean anything is wrong.
Auditing an identity yourself
Section titled “Auditing an identity yourself”- Fetch
realhandles-chain.jsonand runverifyChainover it. - Compare the resulting key to whatever you pinned last time. If you have never seen this identity before, pin the genesis key now.
- Fetch
realhandles.otsand check it with the standardotsCLI against the corresponding JWS.
Step 3 is the one that matters if you do not want to take our word for anything. What the dashboard shows about Bitcoin status is us reporting on ourselves. The .ots file is checkable without us, and we deliberately do not verify the Bitcoin attestation for you: doing that properly needs a block header source, and handing it to your own OpenTimestamps tooling is the more honest answer.
Finding an identity to read
Section titled “Finding an identity to read”
The directory lists published identities. Every profile it links to serves its own manifest and history at fixed paths, so anything here can be audited by the steps above without asking this site to vouch for it.
In the Android app
Section titled “In the Android app”Your own history is Identity > Data > Signed history. Somebody else’s is the Check tab, which is a different job on a different tab for exactly the reason this page exists: reading a history is how you decide whether to trust a stranger.
Your own history
Section titled “Your own history”Every published version, in order, with what changed at each one written out in words: a handle change, an account added or removed, an anchor moved, a recovery policy published or removed, and a key change with whether the handoff was authorized.
Check this history runs steps 1 and 2 of the audit above on the phone. Every signature and every link is checked on the device, and the result says so plainly, “Checked on this phone”, rather than reporting what a server concluded.
Step 3 is not done for you, deliberately. The app does not fetch the .ots file and never asks a Bitcoin node anything, so a version reading as confirmed is RealHandles reporting on RealHandles, and the app words it that way. Check the proof file with any OpenTimestamps tool if you want the date to rest on something other than our word.
Checking somebody else
Section titled “Checking somebody else”The Check tab takes a handle, fetches the proof, and verifies the signature and the whole chain on the device.
It also does the pinning this page recommends, without being asked. The genesis key of every handle you check is remembered, listed on the Keys tab, and compared on every later check. If the key signing a handle now is not the one you trusted before, and nothing in the history authorizes the change, the app stops and says the name is being held by a stranger until that is explained. An authorized rotation passes through quietly, which is the property that lets you follow somebody through a key change without being told.