| LICENSE | ||
| README.md | ||
DIDWeWriteHistory
About
DIDWeWriteHistory is an open DID (Decentralised Identifier) module, which can store previous versions, and the ID as a signed UUID. Other (major) elements it stores are a primary server, mirrors. The entire document is signed with Ed25519 except for mirrors. Because of this, it also stores the public key. It is up to the client or server handling the DID on how to store the private key. Without the private key, the DID can not be changed anymore, and mirrors or other server should not accept any public key changes without providing the old one. This is why in the identity field, the old public key can be set. If it remains the same, it should not be set. The signature found in the identity field is signed with both the new public key, and the old public key. In any new DID changes after the public key changes, the new public key can be used going forward.
Format
It uses JSON formatting to store the DID document. Here is an example of a first, unchanged version:
{
"id": "did:wwh:e62d9d35-4ebb-47aa-a636-8308f5e76331",
"dwwh_module_version": 1,
"version": 1,
"createdAt": "2026-01-01T00:00:00Z",
"updatedAt": "2026-01-01T00:00:00Z",
"primaryServer": "https://example.com",
"name": "example",
"identity": {
"publicKey": "Q1w+lfhwAqtvo9dJWqrXGylozNO7B2qfLjHeyAC1aC0=",
"signature": "sig"
},
"mirrors": [
"https://example.org",
"https://example.net"
],
}
id defines the UUID of the DID.
dwwh_module_version defines the current DWHH module version (this goes up by one each module spec change).
version defines the current version of the current version of the DID document.
createdAt defines when the first version of the document created with a timestamp.
updatedAt defines when the latest, current version of the document was updated with a timestamp.
primaryServer defines where the current server lives. (changeable)
name defines the current name linked to the DID. It is up to the server to decide what namiing convention they want to use. This could be a username, for example. (changeable)
identity stores the public key, if changed the old public key, and a signature of the entire document except for mirrors.
identity.publicKey stores the current public key that can verify the signature.
identity.oldPublicKey stores the old public key, if it was changed since the last version.
identity.signature defines the current signature of the entire document, except for mirrors.
identity.oldSignature stores the signature of the document signed with the old public key.
mirrors contains strings of the mirrors the current primary server trusts.
Format if the DID changed
Here is an example of the case when the first DID edit was to change primary servers, and the second one was to change username. The signatures will be prefilled with "sig" and then the version number to make it easier.
{
"id": "did:wwh:e62d9d35-4ebb-47aa-a636-8308f5e76331",
"dwwh_module_version": 1,
"version": 3,
"createdAt": "2026-01-01T00:00:00Z",
"updatedAt": "2026-03-03T03:03:03Z",
"primaryServer": "https://example.edu",
"name": "example_new",
"identity": {
"publicKey": "Q1w+lfhwAqtvo9dJWqrXGylozNO7B2qfLjHeyAC1aC0=",
"signature": "sig3"
},
"mirrors": [
"https://example.org",
"https://example.net"
],
"versions": [
{
"id": "did:wwh:e62d9d35-4ebb-47aa-a636-8308f5e76331",
"dwwh_module_version": 1,
"version": 1,
"createdAt": "2026-01-01T00:00:00Z",
"updatedAt": "2026-01-01T00:00:00Z",
"primaryServer": "https://example.com",
"name": "example",
"identity": {
"publicKey": "Q1w+lfhwAqtvo9dJWqrXGylozNO7B2qfLjHeyAC1aC0=",
"signature": "sig1"
},
"mirrors": [
"https://example.org",
"https://example.net"
],
},
{
"id": "did:wwh:e62d9d35-4ebb-47aa-a636-8308f5e76331",
"dwwh_module_version": 1,
"version": 2,
"createdAt": "2026-01-01T00:00:00Z",
"updatedAt": "2026-02-02T02:02:02Z",
"primaryServer": "https://example.edu",
"name": "example",
"identity": {
"publicKey": "Q1w+lfhwAqtvo9dJWqrXGylozNO7B2qfLjHeyAC1aC0=",
"signature": "sig2"
},
"mirrors": [
"https://example.org",
"https://example.net"
],
}
]
}
Format if the public key changed
Here is an example of the case when the public key changes. The signatures will be prefilled with "sig" (same with public keys, but for "pub") and then then a "_new" or "_old" suffix for simplicity..
{
"id": "did:wwh:e62d9d35-4ebb-47aa-a636-8308f5e76331",
"dwwh_module_version": 1,
"version": 2,
"createdAt": "2026-01-01T00:00:00Z",
"updatedAt": "2026-02-02T02:02:02Z",
"primaryServer": "https://example.com",
"name": "example",
"identity": {
"publicKey": "pub_new",
"oldPublicKey": "pub_old",
"signature": "sig_new",
"oldSignature": "sig_with_old_pubkey"
},
"mirrors": [
"https://example.org",
"https://example.net"
],
"versions": [
{
"id": "did:wwh:e62d9d35-4ebb-47aa-a636-8308f5e76331",
"dwwh_module_version": 1,
"version": 1,
"createdAt": "2026-01-01T00:00:00Z",
"updatedAt": "2026-01-01T00:00:00Z",
"primaryServer": "https://example.com",
"name": "example",
"identity": {
"publicKey": "pub_old",
"signature": "sid_old"
},
"mirrors": [
"https://example.org",
"https://example.net"
],
}
]
}
Format if the public key changed, and then something else changed
Here is an example of the public key changing, and then in a seperate change the username changes.
{
"id": "did:wwh:e62d9d35-4ebb-47aa-a636-8308f5e76331",
"dwwh_module_version": 1,
"version": 3,
"createdAt": "2026-01-01T00:00:00Z",
"updatedAt": "2026-03-03T03:03:03Z",
"primaryServer": "https://example.com",
"name": "example_new",
"identity": {
"publicKey": "pub_new",
"signature": "sig_new",
},
"mirrors": [
"https://example.org",
"https://example.net"
],
"versions": [
{
"id": "did:wwh:e62d9d35-4ebb-47aa-a636-8308f5e76331",
"dwwh_module_version": 1,
"version": 1,
"createdAt": "2026-01-01T00:00:00Z",
"updatedAt": "2026-01-01T00:00:00Z",
"primaryServer": "https://example.com",
"name": "example",
"identity": {
"publicKey": "pub_old",
"signature": "sid_old"
},
"mirrors": [
"https://example.org",
"https://example.net"
],
},
{
"id": "did:wwh:e62d9d35-4ebb-47aa-a636-8308f5e76331",
"dwwh_module_version": 1,
"version": 2,
"createdAt": "2026-01-01T00:00:00Z",
"updatedAt": "2026-02-02T02:02:02Z",
"primaryServer": "https://example.com",
"name": "example",
"identity": {
"publicKey": "pub_new",
"oldPublicKey": "pub_old",
"signature": "sid_old",
"oldSignature": "sig_with_old_pubkey"
},
"mirrors": [
"https://example.org",
"https://example.net"
],
}
]
}
API
Optionally, services can also host an API to get only parts of the DID. (Work in progress, if this changes, the module version itself won't change.)