SolidusIdentity
Create Your DID

What Actually Happens When You Register a did:solidus

Your private key is generated in your browser, signs the registration transaction there, and is never sent to us. Our server relays a transaction you already signed.

That first claim is the kind that is usually just asserted, so the rest of this page is how you can check it, including by not using our server at all.

The sequence

  1. The browser generates an Ed25519 keypair. The private key goes into browser storage.
  2. The browser builds a DidCreate transaction and signs it locally.
  3. It POSTs the signed transaction, and only the signed transaction, to /v1/onboarding/register.
  4. Our backend shape-checks it: the payload must carry a 32-byte public key and a 32-byte sender key, or you get a 400.
  5. Our backend relays it to the chain and waits for the receipt, with a 12-second ceiling.
  6. The chain decides. Our backend's own comment says it plainly: "The chain enforces the full invariant set; this code just rejects obvious malformed input before going over the wire."
  7. On success we store a row: your identifier, your public key, and a display name.

What the chain actually enforces

Read in the consensus source rather than taken from a spec:

  • An all-zero public key is rejected.
  • The address derived from the public key must equal the transaction's sender address. If it does not, the transaction fails with a mismatch error. This is what makes registration self-certifying: you cannot register a key you do not hold, because holding it is what produced the address.
  • An identifier that already has a document cannot be created again.

That third-party-proof property is the whole point. Our backend could be malicious and it still could not register a key it does not control, because the chain checks the derivation and our backend does not get a vote.

You do not have to use our server, and we would rather you verified that than believed it

The chain's transaction-submit method is public. Probed on 2026-07-31, with controls that make the answer meaningful:

$ curl -s -X POST https://rpc.solidus.network -H 'Content-Type: application/json' \
    -d '{"jsonrpc":"2.0","method":"solidus_sendTransaction","params":[],"id":1}'
  → {"error":{"code":-32602,"message":"Invalid params","data":"No more params"}}   ← METHOD EXISTS

$ ... "method":"solidus_zzzNotAMethod" ...
  → {"error":{"code":-32601,"message":"Method not found"}}                          ← control

A parameter error and a missing-method error are different answers, and the second one is what a name we invented returns. So the first is real: you can build and submit your own DidCreate without our backend in the path at all.

We are not a chokepoint for identifier creation, and that is checkable in one command.

The bound on that, because one satisfying curl is not the whole story

The node answering it is ours. There is one node operator on this network, us, and we know of no second public endpoint. "Permissionless to submit" and "independent of Solidus" are not the same sentence. If we stopped running it, the fact that the method takes anyone's transaction would stop mattering.

The right way to hold this: the design does not require trusting us, and the deployment currently does. Those are different problems and only one of them is solved.

Registration is free, and nothing on the chain rate-limits it

DidCreate is fee-exempt. So are identifier updates, deactivation, recovery, and credential issuance and revocation. There is a structural reason: the address a DID anchors at is value-free by construction and cannot hold a balance, so charging it a fee would make registration impossible for exactly the party that needs it.

Since the submit method is public, the relayer is skippable.

The cost of client-side keys, stated as a cost

The key never reaching our server is genuinely good. It also means:

  • It lives in browser storage, which is readable by any script running on that origin. A cross-site scripting flaw on our domain reads it. That is a real exposure, not a theoretical one, and it is the standard trade for browser-held keys: we are naming it rather than selling around it.
  • Losing it is losing the identifier. There is no reset on our side because there is nothing on our side to reset.
  • Clearing site data clears the key. Users do that by accident.

We would rather you understand that trade before you make it than discover it afterwards.

What we store

Your identifier, your public key, and a display name. The identifier column is unique, so one account holds one identifier, which also means that identifier is the handle everything else on this product hangs off. What that implies for privacy is on can anyone look up your DID, and the answer there is yes.

What you cannot check yourself

The registration endpoint is part of a signup flow, so the end-to-end path is not something a stranger can exercise without creating an account. The two claims that matter most are checkable anyway: the submit method's existence, above, and the source of the enforcement rules, which is public code. The rest of this page is code-read evidence and we are grading it as such.

Our content plan calls this page /create-a-did. That route is not live: it returns 404, and so does a deliberately fake path.

Keep reading

What Actually Happens When You Register a did:solidus · Solidus — Solidus Identity