Pattern β : Bob hasn't done the initial DMTP setup
Until Bob finishes the initial setup, the messages to Bob are encrypted with the shared key (Alice & DMTP) and stored. At this time, the messages are not E2EE and we (DMTP) can see the messages.
Once Bob finishes the initial setup and generates keys, DMTP encrypts the messages with the shared key (Bob & DMTP) and delivers it to Bob. Bob re-encrypts the messages with the shared key (Alice & Bob). Finally, those messages are stored in DB and others encrypted with the DMTP shared key are deleted. This makes them E2EE and no one can decrypt them. even later.
Now let's take a look at the detailed flow
Sending Messages

DMTP server verifies the signature and prove that DMTP key pair haven't been manipulated.
Alice client retrieves
DMTP's pubKeyfrom the DBAlice decrypts
Alice’s DMTP_priKeywith her wallet.Alice generates the
combined secretfromAlice’s DMTP_priKeyandDMTP’s DMTP_pubKeyAlice encrypts messages with
combined key (Alice & DMTP)Store the
encrypted messagesin the DB and IPFSThe data to be stored will look something like this.
{ "messages":"ENCRYPTED_MESSAGE_WITH_COMBINE_ALICE_AND_DMTP", "sender": "SENDER_WALLET_ADDRESS", "receiver": "RECEIVER_WALLET_ADDRESS", "timestamp": "TIMESTAMP" }The CID of message data is stored in
Messagetable in DB andCIDtable in DB【Messages Table】 ⇒ CID
【CIDs Table】 ⇒ [CID, CID, CID, CID, CID, CID]
The Message table is stored in
Processing Chatsin 【Users Table】【Users Table】⇒
Processing Chats[ Room ID, Room ID, Room ID]Periodically, sync all data in
CIDtable to IPFS and get CIDAll CIDs are stored in this file
{ "ROOM_ID_A": ["CID", "CID", "CID", "CID", "CID"], "ROOM_ID_B": ["CID", "CID", "CID", "CID", "CID"], "ROOM_ID_C": ["CID", "CID", "CID", "CID", "CID"], }This CID is stored in the blockchain (Polygon)
string[] cids; function storeCID(string memory _cid) public onlyOwner{ cids.push(_cid); }
After Bob's initial DMTP setup is complete

Once Bob's initial DMTP setup is complete, DMTP server retrieves all message data and Bob's DMTP_pubKey
DMTP server verifies the signature and prove that DMTP key pair haven't been manipulated.
DMTP server generates the combined key from
DMTP’s priKeyandAlice's DMTP_pubKeyand decrypts all messages with that.DMTP server generates the combined key from
DMTP’s priKey&Bob's DMTP_pubKey,and encrypts all messages with that. The encrypted message is updated in DBBob client retrieves the encrypted message (DMTP & Bob) & DMTP key pair
Decrypts
the encrypted DMTP_priKeywithBob’s priKeyGenerates
the combine secretfromBob’s DMTP_prikey&DMTP’s DMTP_pubKeyUse
the combined secret(Bob & DMTP)to decrypt all messagesGenerates
the combine secretfromBob’s DMTP_prikey&Alice’s DMTP_pubKeyUse
the combined secret (Alice & Bob)to decrypt all messages
Update message data stored in DB
Store new message data in IPFS and get CID
Store CID in DB
Periodically, sync all data in
CIDtable to IPFS and get CIDAll CIDs are stored in this file
{ "ROOM_ID_A": ["CID", "CID", "CID", "CID", "CID"], "ROOM_ID_B": ["CID", "CID", "CID", "CID", "CID"], "ROOM_ID_C": ["CID", "CID", "CID", "CID", "CID"], }This CID is stored in the blockchain (Polygon)
string[] cids; function storeCID(string memory _cid) public onlyOwner{ cids.push(_cid); }
Last updated