Skip to content

Instantly share code, notes, and snippets.

@elmariachi111
Created May 29, 2021 00:07
Show Gist options
  • Save elmariachi111/ce5d39b52db2c1dc12a689c9cb23791f to your computer and use it in GitHub Desktop.
Save elmariachi111/ce5d39b52db2c1dc12a689c9cb23791f to your computer and use it in GitHub Desktop.
Web3Weekend idea: decentralized "email" on top of Ceramic Protocol / IPFS, ENS & maybe SMTP

CeMail

An SMTP compat "mail" client that uses Ceramic documents to sync & relay mail-like messages between identities. Roughly related to did-comm.

some fundamentals

The fundamental idea of a self sovereign identity is the "DID", a decentralized identifier, looking like did:key:zkmanycharacters. DIDs are uniquely identified by key material of an user, derived by some random seed only the user knows. DIDs can be resolved / expanded to DID documents that contain information about the public keys a user uses for communication and authentication purposes.

At its core, the Ceramic protocol uses DIDs to represent identities that are interacting with documents, atm did:3 and did:key are supported: https://developers.ceramic.network/learn/overview/#authentication. On top of Ceramic, IDX is adding a layer of well formed documents that contain additional information about the user, e.g. an user "profile".

Ceramic is a "smart" document protocol that allows users to collaboratively documents' contents. A document actually is the result of applying many CRDT based change sets in the right order. It's the job of Ceramic nodes and the Ceramic network (Clay) to keep track of the changeset ordering and anchoring them on arbitrary blockchains / pinning their content on IPFS. Ceramic nodes make use of a cryptographically modified DAG component in IPFS (dag-jose) to create DID-crypto compatible IPLD relations between changesets. This all leads to one fundamental concept: each document gets one unique key after its creation ("genesis doc") and is modified by a sequence of change logs applied to it. Since a ceramic client enforces documents to adhere to predefined schemas and definitions, document types can contain logic that's applied when users are making changes to / reading those documents. Hence they call them "smart".

An "email" like messaging protocol on top of Ceramic

First, without "SMTP" integration.

A user runs a local "mail" client that's nothing but a client connected to a ceramic node (thereby connected to IPFS & blockchains which are hidden technical details of the ceramic protocol).

To interact with a ceramic node, a ceramic client must identify itself with a DID (see client initialization code).

A user can create a mail message, containing recipient subject payload

These fields are wrapped into a new dispatchable ceramic document that's controlled by the sending party, roughly using this schematics:

recipient: did:key:...
payload: __encrypted by (did:key:sender#encryption-key):__
  sender: did:key:sender...
  recipient: did:key...
  subject:...
  payload:...
__/encrypted__

The recipient can be any DID that's resolveable by the ceramic protocol (did:3 / did:key)

Upon sending I'm encrypting the message's content with the recipients public encryption key (think this can be safely done inside ceramic already).

By adding the "message" document to ceramic it gets a unique ceramic document id like ceramic://bafyfsdifsduifh.

Relaying

Every user / DID creates a relay document that's world writeable (or writeable by DIDs the user trusts but that's another story.) that uses a schema like:

{inbox: [Message]}
...

Every user is *listening* locally on his relay document for updates. 

To "send" a mail to another user, the sender updates the recipient's relay document by adding his message document **id** to its inbox field, e.g.:

{ inbox: [ "ceramic://bafysomeidofanotherguy", "ceramic://bafythemessageiwanttosend", //<-- ... ] }

Since the recipient gets a notification about changes on his relay document he can fetch the content of ceramic://bafythemessageiwanttosend using the ceramic protocol on his machine, decrypt the payload with his private key and store the decrypted message locally (not necessary, it's only mandatory to list them)

"nice to haves"

If the relay documents are publicly writeable, every user might delete entry for every other user. That's not good ;) A custom Ceramic DocType should be perfectly able to allow only the creator (i.e. the owner) to remove entries and every other user to add entries.

To avoid "spam", a user might set controllers for his relay document (controllers are DIDs) so only Identities known to the user might send him mails.

(Extension 1, totally unexplained here: all users who want to send "blind" emails must add some token stake that the recipient will pay back after marking the message as "not spam")

ENS / Nice names

of course it'll be much nicer if we could not only send mails to a DID (did:key:zk21323zwuhsef) but rather using a "readable" address: elamariachi@cemail.eth. We can use ENS to make that happen!

Someone (we) registers cemail.eth. We set 1 TXT record that contains a ceramic document id which represents the global email address registry. It's world writeable and lets each IDX DID define a name they want to be aliased with (did:keyzk98ur89289 || ceramic://bafyanidxdocumentindex => elmariachi).

A sender can use that email address in his client.

Our dispatching backend first resolves the ceramic registry document and then looks up a the IDX document id / DID of the recipient.

(Alternative, maybe simpler: each user registers an "ENS root" we can send messages to, that resolves e.g. *@elmariachi.eth)

SMTP gateway

ideally this whole thing (sending side!) works without a dedicated "sending" frontend. Instead, we're using commonly used desktop smtp clients like "Outlook" (find the simplest option here for demo).

Our account is "did:key:zkourdidkey", respectively "something@our.eth" / "elmariachi@cemail.eth" when using ENS aliases

we don't need a password / any password will do / the private key's passphrase (we're not using passwords here)

Each user is running a small "smtp" server on his own machine. That one is configured with a the private key (derived by a seed that's "safely" stored on disk) for the ceramic identity that matches the account name.

to relay mails for that account, the mail client is using this "smtp" server.

the server behaves like an SMTP server but under the hood it'll create / relay messages as written above

Reading frontend

There's a simple (React) frontend that users can use to fetch / read messages. Of course this could be built with an POP/IMAP interface but that will likely lead too far.

It's just displaying a chronological message list on the left & a reading pane on the right.

slight UX addons

Recipients can mark a mail as "read". To do so, they're modifying the "read" status of the message document. To be able to do so, a sender (or the ceramic doc type) must allow the recipient to change the message doc content (esp. the "read" field).

@alzinging
Copy link

I was planning on using IPFS to try and create / learn about the Merkledag "resolution" process to create/find locations based on something like a PGP key and other authentication credentials. We need "a standard" for saving passwords in a tree trunk structure where the credentials for things like social networks and remote storage solutions are PGP secured along with something like an Eth/Metramask identity.

I have "other plans" to integrate github/confederated document storage and source/contribution control and management with the same kind of identity. I like the Ceramic name, it reminds me of Haphaestus and his Creo-Mia-Gaian "actual mythological source of things like the Washington Monumental Laughter of [forrests in Love and [with stairways away from] Life.

Are you happy now? Sometimes walkways have two divergents ... sometimes there's a "best practice" and we all start with GPG-FROSTBRITE ...

https://en.wikipedia.org/wiki/Bifr%C3%B6st
https://en.wikipedia.org/wiki/Chenab_Rail_Bridge

CORNAVorosLOau

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment