Replies: 3 comments 5 replies
-
I really love the vision and excellent work, here are a few thoughts of mine: MetadataStandardmetadata, in theory, is just a lump of data the user wishes to attach to a conversation, I like how you're allowing them to pass in the metadata like this but would it be nice to set a metadata standard XMTP for this? XMTP is a single place MANY UIs can build and consume, I can make a UI allowing people to see all their messages and someone in the US can do this a million times over, what this means is imagine you didn't have a standard, and my UI sets "titles" another UI sets "displayName" another UI sets "header", in theory they mean the same thing but now the UIs won't be in sync with each other, UI 1 will show no title and UI 2 will. Standards solve this. What I propose is you flesh out this interface: metadata: {
[k: string]: string
} Into a standard required interface (everything can be optional) but your setting the standards for developers which you can keep building on. Without a standard, it could become a huge mess and UIs won't be able to just build and inherit each other. As a user, if I find another cool UI and it didn't have all my state would I use it? maybe not. Changing metadata"Conversation metadata cannot be changed after the conversation has been initiated" I think this is fine for 1<>1 DMs naturally you do not name it and naturally, you use the person you talking to profile pic but when you start doing group chats changing this metadata IMO would be super important. Like WhatsApp, a subset of users has admin permission to change that stuff can come later for sure but just flagging. FilteringI think is 100% fine to filter based on a naming standard you set. I am happy with the interface with the way you did I would also entertain the idea if you already have this info to pass in the conversation context it would be very useful, only if you have it at this point you may not. type IdFilter = (conversationId: string, convo: Convo) => boolean You can imagine this being useful in terms of making sure the from user still owns the identity for example a lens profile or not but you can of course do this a step after but could be useful to have that info (even if you don't have the entire convo and just have the Other thoughts
overall super happy with this think it solves a lot of things, great work guys! |
Beta Was this translation helpful? Give feedback.
-
@joshstevens19 appreciate the thoughtful comments. Metadata
Definitely something I've been concerned about as well. I don't think the standards can come top-down, or in advance of real-world usage of the feature. If I try and dream up what fields developers are going to need, I am 100% going to be wrong. I'd love to see standards evolve around actual implementations of the protocol. This is V1 of the invitation protocol, and I'm inclined to leave it with maximum flexibility. The XIP Process feels like the right way to elevate developer conventions into first-class citizens on the invite as structured fields for V2. Changing metadata
100% agree. As part of enabling group chat, we are going to need some more flexible ways of mutating ongoing conversations (to support adding and removing members). The goal would be to fold metadata updates into that framework once it's available. Filtering
Great suggestion. I can totally see the use-case for asynchronous filtering. That should be workable. The performance concerns (waiting for the event loop) should be manageable given this is not an operation that has to run very frequently and that can be batched with
We do have all the information since we have already downloaded the invites at the point we are running the filters. At least for the
We support paging for messages today. Paging for conversations is a "maybe". The reason being that we may have to do a pre-fetch of all the invites in order to support grouping together multiple invites for the same conversation (to handle topic/key rotations). Definitely a hot topic internally right now. |
Beta Was this translation helpful? Give feedback.
-
A few quick questions/thoughts. One imminently useful standard would be something like a "default conversation id". Or maybe it could make sense for XMTP to "officially recommend" creating conversations without conversation ids unless there is some good reason to do so. If every new XMTP application developer creates conversations with A related but different question is: is the Last, less related question: It looks like the conversation filtering might not have made it into |
Beta Was this translation helpful? Give feedback.
-
We are working on adding a much-requested feature to the XMTP protocol, and wanted to get developer feedback on our proposed solution. Many developers have asked us how they can group or filter messages in a particular context. Some examples:
While developers can use metadata in a custom content type to filter messages after they have been retrieved from our nodes, this can lead to inefficient performance (they have to retrieve all messages and then ignore the ones that don't match). It's also a worse developer experience (all the filtering logic lives in the application).
Traditional methods of server-side filtering aren't an option for us since messages are end-to-end encrypted and the nodes are unaware of the contents developers might want to use as predicates of a filter. So, we have developed a solution to this problem that does not compromise user privacy.
Proposed solution
We propose several changes to the Conversations API that will allow for developers to add an identifier to conversations, attach metadata to a conversation, and to filter conversations based on the identifier.
The exact API is still being iterated on, and anything below may change before release.
Here's a code example to illustrate how this might work for an app that wants to offer two types of conversations: one for "foo" messages and one for "bar" messages.
How it works
Before digging in to how this new system works, it'll be helpful to understand how XMTP works today.
XMTP Today
Topics
All messages on XMTP are stored on a topic. Topics are public. Conversations are initiated by sending a message to 3 different topics:
intro-walletA
intro-walletB
dm-walletA-walletB
Subsequent messages are sent to the conversation topic only. There can be multiple introductory messages from the same sender in a recipient's intro topic. All further communication after the initial message in a user session will go into the same conversation topic as it is strictly tied to participants' wallet addresses.
Messages
Conversation messages include a plain text header identifying the sender's and recipient's public key bundle used to encrypt the message. The header aids decryption by either party. The payload is encrypted.
Upcoming changes
In order to facilitate conversation tagging and enhance user privacy we are introducing a new way of handling introductions and message encryption.
Invite topics
Replace the intro topics with invite topics. Messages in the invite topics will carry an invitation from the initiator of the conversation which will include:
randomly generated topic name that will be used for the conversation
randomly generated bytes used as the key material for encryption of messages in this conversation
The invitation message is encrypted using the X3DH scheme we use for messages currently.
The initiator still sends the invitation to their own invite topic as well to have a record of the the topic and key material. The invitation message would be identical, i.e. the sender is still the initiator, which can be useful to distinguish own invitations from others.
Invitations include a
context
field that contains theconversationId
andmetadata
about the invitation. That data is used by the client to filter invitations, which then returns a filtered list of topics that can be used to query the nodes.Conversation Topics
Topic name is determined by the invitation that initiated it (expected to be a random string). Messages in the topic will omit the sender/recipient pub key bundles from the message header. The payload is encrypted using the scheme indicated by the invitation (e.g. AES256-GCM-HKDF-SHA256). The key material from the invitation is used as the input into the scheme's key derivation function (e.g. HKDF).
The omitted sender header is replaced with a new
SignedContent
wrapper that will embedEncodedContent
and will be encrypted insideCiphertext.payload
.The signature signs a digest of concatenated message timestamp, topic name and the content bytes using the sender's pre-key.
Caveats
conversationIds
s. We suggest that developers use a URI as a convention, but are not able to enforce restrictions as theconversationId
only exists inside an encrypted payload. Collisions ofconversationId
are possible if multiple developers send messages using the same type between the same two addresses, and it will be up to the application developer to handle any unexpected messages resulting from those collisions.conversationId
s andmetadata
to enable interoperability between applicationsMap<string, string>
valuesQuestions for developers
conversation_id
metadata
Beta Was this translation helpful? Give feedback.
All reactions