Standardization web3 messaging

With Heiko’s post dm3-decentralized-messaging-for-web3 from August 22, we started the discussion on web3 messaging and interoperability of web3 messaging protocols, services, and applications in the community.

Since then,

  • The first iteration of the dm3-specification draft was published and we received a lot of feedback.
  • Discussions with a lot of different teams have been held to evaluate requirements and standardized approaches that will enable the web3 world to do much better than the web2 world - being interoperable and giving the decision which app to use and how to manage personal communication data to the user - without building new separated data silos.
  • We incorporated the feedback.

Now the new version (0.3) of the dm3 message transport protocol is published. Thanks to all for contributing to it with their feedback.

The current specification draft can be found at

The following major changes have been included:

  • HASH: we replaced all Keccak hashes with SHA256 hashes
    As SHA-256 is more common (Keccak is more Ethereum-focused), it might be easier for non-Ethereum-based applications to adopt it.
  • MESSAGE TYPES: There is a variety of types possible that might or might not be supported by a messenger. We set most of the types optional, which means dm3 compatible apps can decide whether to support it or not. The user’s settings (readable from mutableProfileExtensionUrl) can now return a list of not supported message types. A sending client needs to check the receiver’s settings and must not send a message type not supported by the receiver.
    Another service message type needed to be added (RESEND_REQUEST). With this service message and a hash referencing the message, the sender can ask to resend a historical or lost message.
  • MESSAGE ENCODING: The encoding of the message text must be plain text (UTF-8), optionally flavored with Markdown highlightings. If other application-specific encodings are to be used, they are provided as an attachment. The plain text representation must be available, too. A client able to interpret the encoded attachment may show this instead of the message text.
  • DELIVERY SERVICE PROPERTIES: The delivery service got an additional API function: dm3_getDeliveryServiceProperties. It returns a list of properties relevant to the delivery service.
    messageTTL: This is an optional parameter. It defines the minimum time an undelivered message will be stored by the delivery service. This parameter might be important for a delivery service to manage resources (otherwise, a delivery service will store all messages until they are picked up.) With this property set, the delivery service can purge its storage, if necessary, in a coordinated way.
    sizeLimit: The delivery service can define the maximum size of a received message to be accepted. As a delivery service can be a gateway to another protocol or app, it might be important to have a harder restriction
  • DELIVERY SERVICE DESCRIPTION: added an appendix to explain delivery service models in detail. In particular, delivery services can act as a gateway to other services/protocols to receive a dm3 message and include it in the ecosystem.

Next steps:

We are again asking for feedback and trying to have in-detail discussions with you. We especially want to open a community discussion on possible integration scenarios of dm3 in applications, protocols, or services. The goal is to have a variety of messaging applications in the web3 space but those solutions are able to interop.

Also, in the next iteration, we want to discuss in more detail the general registry based on ENS, as this is one of the crucial parts of interoperability between different applications and protocols → a standardized way to get information from the receiver (like public keys and how to deliver messages). Using ENS for this registry is a no-brainer. By using CCIP (Cross Chain Interoperability Protocol, based on EIP3668) the integration of Layer-2 registries, registries on sidechains or other chains, and even centralized services is possible as well.

The result of the next iteration should be a proposal of a basic protocol that fits well for a big variety of protocols, services, and dApps as a way to accomplish interoperability without giving up on security or features relevant to that ecosystem.

Steffen Kux


This is looking really good! Is there anywhere to leave granular feedback on the spec on a paragraph-by-paragraph basis?

1 Like Step 1: Preparation of the Message and Envelope

Get dm3 profile

  1. Read the eth.dm3.profile text record of the receiver’s ENS name.

If you are starting from an ENS name (“I want to send a message to nick.eth”) then cool. What if the sender app only has an ETH account to work with? (“I want to send a message to 0xb8c2C29ee19D8307cb7255e1Cd9CbDE883A267d5”)

In that case, would it be correct to first resolve the Primary Name / Reverse Record for the ETH account? So something like:

Get dm3 profile

  1. The sender app may accept either an ENS name or an ETH account as the receiver. If the receiver is an ENS name, move to Step 2. If the receiver is an ETH account, resolve the ENS Primary Name for the account, and verify that it forward-resolves to the account address. If no ENS Primary Name is found, or it does not resolve to the receiver’s ETH account, the message cannot be delivered. It has to stay with the sender until the potential receiver sets an ENS primary name and publishes their profile.

  2. Read the eth.dm3.profile text record of the receiver’s ENS name.


One other question I had is, how exactly does a recipient pick up a message from a delivery service?

If the delivery service integrates with some other service/protocol to auto-deliver to the recipient then all is well. But what about when the delivery service is not acting as such a gateway?

In the API I see dm3_submitMessage and dm3_getDeliveryServiceProperties, but what would the receiver’s app call to:

  • Check whether there are any new messages received (in the case where the delivery service does not send notifications, or the notification was dropped/lost/missed)
  • Retrieve messages from the delivery service
    • One at a time? Bulk retrieve? Retrieve a specific message by hash or timestamp?

Yes, you can download the pdf-version (left-bottom corner): and add comments there and send it directly to me.

Alternatively, you can add comments on GitHub directly: GitHub - corpus-ventures/dm3-spec: White paper, protocol spec, ..., e.g., as pull request.

If you feel more comfortable adding comments to a gdoc, I could provide it, too.

Let me give you some answers to your questions:

If the user has no ENS name to register his/her profile, (s)he needs to register one to publish the contact information (public keys, delivery service). The best approach would be to register a name as a subdomain based on the address, like .dm3.eth - in your case 0xb8c2C29ee19D8307cb7255e1Cd9CbDE883A267d5.dm3.eth. We plan to do this as layer2 connected and verifiable using CCIP. Other domains can offer this in the same way as dm3.

To your proposal for the “Get dm3 profile”-text:
This is exactly the way a client app should work. If as receiver an address is given, the ENS name should be resolved. The approach above is an additional way.
We will add an explanation as you proposed in the spec to make it clear.

This will be specified in the protocol extension: Message Access Specification
As a gateway to another service/protocol doesn’t need to implement this, it is not part of the base protocol (the dm3 Message Transport Protocol). This specification is in work but has not yet been published as we focus at the moment on that part of the protocol which is needed for interoperability.

A few thoughts on the current spec:

  • The registry spec says that text records must contain either the DM3 JSON, or a URL to it. Why not specify that data: URIs must be supported, and thus remove the need for discriminating between the two formats? In the case of data URIs, the requirement to include a hash can be dropped.
  • The registry spec doesn’t specify how public keys should be encoded (eg, key component ordering and representation, ASCII encoding, etc).
  • Listing not supported message types is an odd way to do it, and leads to the assumption that any new message types are supported by default. It probably makes sense to list supported message types intead.
  • You probably want to specify a format for third-party message types, such as using reverse ENS names in the same fashion as you do for text record names.
  • You may want to specify that clients should respect the ENS TTL when looking up user or delivery service profiles; with gateways likely to be sending a lot of messages this could improve latency significantly, especially for delivery service lookups.
  • The choice of UTF-16 for message bodies is rather unusual. Why not UTF-8?
  • You should probably specify a standardised means to add extra metadata to the message and envelope objects.
  • The envelope metadata should contain information on the encryption and signing algorithms used. There’s only one option for now, but that will not be the case indefinitely.
  • For attachments you could also specify that they are URIs, with data as a supported scheme.
  • There’s only one ‘m’ in ‘incoming’.

Hi Nick, thank you very much for your feedback. Please find below some quick answers:

This is a good idea. We will change this.

You are right. We will add this in more detail to the spec.

We discussed this a lot. Actually, there is no perfect solution. If you opt-in (list supported messages), the user (or his/her client) has always to provide this information otherwise nothing would be supported. While this mutableProfileExtension was meant to be optional only, a positive list would not work that well. We are right now in discussions to this topic and will propose a better solution soon.

Did I miss this at one place? Yes, we already changed it to UFT-8.

We will add this as optional field.

Yes, we already have this information included (for the encryption). The receiver’s client could ask for another encryption as default. If the sender supports this, it is fine. We will check, if some info is missing in the data structures.
We will add this for signatures as well.

Good point. We will change this as well.

As it depends on the implementation of a client or delivery service, if such information is cached, we will add the notice that in case of caching, the ENS TTL needs to be respected.

Can you give more info on this topic? I don’t really understand what is your intension for this.

1 Like


Thank you very much for the latest feedback after releasing the last version (0.3) of the specification of the dm3 protocol (see Standardization web3 messaging). A lot of important reasonable enhancements are incorporated now. Also, more teams working on web3 messaging solutions are now involved.

Also, thanks to all who voted for our proposal at ENS Small Grants (ENS Small Grants). This motivates us, even more, to work on dm3 as an interoperability protocol for web3 messaging.

The following major changes have been incorporated:

  • URIs for profile entries: Now, the profile entries are URIs (DATA, HTTPS, IPFS).
  • URIs for attachments: Attachments are URIs, too. This simplified attachment handling.
  • Metadata for Message and Envelope: We added metadata fields to the message and envelope structure. All describing attributes are moved to the metadata (making the message and the envelope structure simpler). Metadata structures can be extended if needed (e.g., for protocol extensions or application-specific info).
  • getProfileExtension as RPC-Method of the delivery service instead of a link in the profile: We changed the optional mutableProfileExtension which was a link to this info presented in the dm3 profile to an RPC method of the delivery service. Each delivery service can be asked for the info for an ENS name, which uses this delivery service. Some settings (e.g., spam reduction settings) may be different for each delivery service. If a user uses different delivery services (as recommended), this information will be delivered by the selected delivery service.
  • Positive List of supported message types: with the change above, we changed to a positive list, which message types are supported. Only NEW is mandatory, other types are optional. What is supported depends on the user’s client.
  • Added additional details to the spec to make some aspects clearer.

The current version of the specification document can be found at

In case you have seen the preceding version, make certain to reload your browser for the newest iteration!

Next steps: We always appreciate comments and will communicate with those who express interest. Also, we are right now finalizing the reference implementation of the current version of the protocol to showcase how it works.
A special focus for the next steps is also to discuss the delivery service architectures and extend the spec if needed (We have already received some feedback suggesting that we should be more explicit in our specification of the delivery services).

In the ongoing coordination process regarding interoperability, it will continue to be interesting to discuss with other protocols/applications how dm3 compatibility can be integrated so that the first protocols are interoperable with each other and to work out what requirements are important from their point of view for the protocol…


DM3 UPDATE (12/2022)

As the year is already coming to an end, we would like to give an update on the current status of the dm3 specification.

Again, we have received some feedback and incorporated it. This results in a few small changes:

  • Error Values for API: All API functions of the JSON-RPC interface must return defined error codes (according to JSON-RPC specification 2.0), some application-defined codes are defined, too.
  • Spam protection settings moved: Spam protection settings for the delivery service are moved from the basic MTP (message transfer protocol) to an optional protocol extension (as this is not mandatory for the base protocol to work - subtraction :slight_smile:). A delivery service might implement it (highly recommended, but is free to do it not, too)
  • Minor adjustments: In some places the specification has been sharpened.

The reference implementation of the current version is finished, too. Partners who are currently implementing the specification in their protocols/applications can access it.

The current version of the specification document can be found at

In case you have seen the preceding version, make certain to reload your browser for the newest iteration!

Next steps: If no significant changes are required, we will set this version as version 1.0 of the protocol in a timely manner. Partners who have already planned the implementation of dm3 compatibility can then proceed on this basis.

Of course, in the coming year, we will continue to push forward with alignment and consolidation in particular and are still very interested in detailed discussions to get the protocol to the point where many can use it and it can bring the desired interoperability to the web3 messaging ecosystem.

1 Like

DM3 UPDATE (01/2023)

After publishing the last version of the specification right before Christmas last year, we are now publishing version 1.0 of the dm3 protocol. A lot of feedback from many contributors is incorporated now.

Besides some cosmetical fixes, one relevant change was done:

  • Name of the profiles: The name of the text-record for the dm3 profile is changed to “dm3.profile” (instead of “eth.dm3.profile”) and the name of the delivery service’ profile is changed to “dm3.deliveryService” (instead of “eth.dm3.deliveryService”).
    This change was done to better support cross-chain and layer-2 interoperability, where local registries are used and integrated into the ENS main registry as subdomains using CCIP (the “eth” prefix does not fit then)
  • Minor adjustments: In some places the specification has been sharpened.

The reference implementation of the current version is finished, too. Partners who are currently implementing the specification in their protocols/applications can access it.
The current version of the specification document can be found at:

In case you have seen the preceding version, make certain to reload your browser for the newest iteration!

Next steps: The first implementations of dm3 compatibility start beginning of February. We will also start a monthly coordination call to align with all interested parties to discuss enhancements and needed changes. After the first implementations of the dm3 compatibility are finished, we will summarize and publish the experience gained from them. We are also working on layer-2 integration, and cross-chain integration, with the target to establish ENS as the central registry for communication info, also referencing layer-2, cross-chain information, and also potential information of centralized services.
The embedded widgets for easy integration of communication, based on dm3, into any dApp are updated to the current spec, too.

We will continue to push forward with alignment and consolidation and are still very open to detailed discussions to get the protocol to the point where many can use it and it can bring the desired interoperability to the web3 messaging ecosystem.

We invite every web3 messaging solution to join the interoperability initiative.

For more detailed information, please refer to the protocol’s website, too


Good to see continuing progress!

If you don’t want to use .eth, can you use a different DNS TLD that you own instead? Using something that you exclusively own is important in ensuring there can’t be collisions in the naming cheme.


I understand your point. We could use the TLD “network” which would make the text record name quite long: network.dm3.profile. The reason for dm3.profile was, that it is actually not a property for our application but the communication profile for all dm3 compatible apps as dm3 is the interoperability protocol and not the application. If accepted and implemented from many other solutions it is more like “email” than for instance the twitter-handle (which belongs to this platform only).

DM3 UPDATE (03/2023)

After finalizing version 1.0 of the Message Transport Protocol (the core component of the dm3 protocol) in January we made only add one change:

  • Name of the profiles: the text record is now called “network.dm3.profile” instead of the shortened version proclaimed in the last update.

The reference implementation is now finalized with the full specification implemented. You can find/test it at

Also, we worked on the Optimism-Resolver to store information (like the dm3 profiles) on Layer-2 and link it using CCIP. The OP-Resolver is fully trustless (utilizing Merkle proofs for all used slots). It can be accessed at GitHub - corpus-io/Optimism-Resolver. The contracts (for L1 and L2) are not yet audited.

With the first app/services/protocols starting to implement dm3 compatibility, we will soon provide an “interoperability guide” and tooling (packaged, configuration tools,…) to reduce the effort to become dm3 compatible.

Next steps: We will continue to support the integration of services/protocols to become dm3 compatible and will push forward with alignment and consolidation and are still very open to detailed discussions to get the protocol to the point where many can use it and it can bring the desired interoperability to the web3 messaging ecosystem.

Layer-2 and cross-chain integration (ENS) are still in focus as well as more protocol extensions.