Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V7 Release #208

Merged
merged 67 commits into from
Nov 2, 2022
Merged

V7 Release #208

merged 67 commits into from
Nov 2, 2022

Conversation

neekolas
Copy link
Contributor

@neekolas neekolas commented Nov 2, 2022

Version 7.0.0 Release Notes

New Features

Improved participant privacy

In prior versions of the SDK, both the topic names and the message headers of DMs indicated the likely participants. Topic names were of the form dm-$address1-$address2. Only the participants in the conversation could verify the authenticity of these messages (they might be invalid messages spoofed by a third party), but a passive attacker could get a reasonable guess as to who was talking to whom and how often.

With V7, we have implemented Negotiated Topics. All identifying metadata has been removed from DMs and the conversation topic name is now a 32-byte random alphanumeric string, such as m-AhUFyewKxM1pxr1JmJJkDK3tDn3gQ0Op. This is accomplished by first sending an encrypted invitation to a well-known topic for all participants in the conversation which includes the randomly generated topic name and encryption key to be used in subsequent communication.

With this change, only the two parties in a DM conversation can know which conversation a given message relates to. Invitations are still publicly associated with known blockchain addresses, although only the participants can decrypt and verify the authenticity of those invitations. As always, message contents are end to end encrypted.

Conversation IDs

A longstanding feature request has been the ability to scope conversations to a particular application or identifier. For example, some developers may want to only display messages coming from their own application and not other apps on the XMTP network. Other developers may want to group messages based on other criteria (for example, an NFT marketplace may want to have messages grouped by NFT ID). Conversation IDs provide the building blocks needed for developers to have multiple conversations with the same blockchain address, grouped by an identifier.

You can learn more about how to use Conversation IDs here.

Conversation Metadata

In addition to conversation IDs, which are used for grouping messages, we also allow you to attach an arbitrary Map<string, string> of metadata to any conversation at the time of creation. Maybe you want to give a conversation a title or header image. Maybe you want to include some more information to link a conversation with an entity in your application.

Metadata is immutable and can only be set the first time conversations.newConversation(...) is run for a unique combination of blockchain address and conversationId.

Migration path

There are now two types of Conversation (ConversationV1 and ConversationV2). The APIs are identical to application developers, but only ConversationV2 receives the privacy benefits outlined above. Applications using SDK Version <7.0.0 can only send/receive messages from ConversationV1.

When client.conversations.newConversation(...) is called, you may receive either a ConversationV1 or ConversationV2 instance depending on the following criteria:

  • If a conversationId is specified, we will either find an existing V2 conversation based on the conversation ID/address combination or create a new one if none exist.
  • If no conversationId is specified, but there is a pre-existing V1 conversation, we will return that conversation
  • If no conversationId is specified and there is no pre-existing V1 conversation, the decision to create a V1 or V2 conversation will depend on whether the address you are attempting to communicate with has ever used a XMTP SDK version of 7.1 or greater. If they have, a V2 conversation will be created. If not, a V1 conversation will be created.

This ensures that both parties will be able to see messages sent from >7.x versions of the SDK whenever possible, even as different applications upgrade at different times.

In a future release we may decide to allow one party to upgrade legacy V1 conversations to V2, once v7 adoption of the SDK is sufficiently high.

Breaking Changes

  • The message type exposed to clients has a new name. Anywhere in your code you see import { Message } from '@xmtp/xmtp-js' you will need to replace it with import { DecodedMessage } from '@xmtp/xmtp-js'. The fields available on this new type are compatible with the previous version, so in most cases you will only need to update your import. DecodedMessage has replaced many optional fields from Message with required fields with the same name, so you may be able to remove some null checks from your code.
  • client.conversations.list() may now return multiple conversations with the same blockchain address (but different conversation IDs). To get the same results you would receive with the 6.x version of the SDK, replace any instance of const conversations = await client.conversations.list() with
const conversations = (await client.conversations.list()).filter(
  (conversation) => !conversation.context?.conversationId
);

There will be at most one conversation per blockchain address without a conversation ID.

  • The LocalStorageStore has been removed. If you have been initializing your SDK with the option { keyStoreType: KeyStoreType.localStorage } you will need to replace it with a different store (such as networkTopicStoreV1)
  • The following methods have been removed from the Client class: sendMessage, publishEnvelope, encodeMessage, decodeMessage, streamIntroductionMessages, streamConversationMessages, listMessages, listConversationMessages, listIntroductionMessages. Equivalent functionality can be found using client.conversations.
  • In prior versions of the SDK, await client.conversations.newConversation(...) would not perform any network requests and would return almost instantly. In V7 and above that method must check if a pre-existing conversation exists. Because of this change, the method is more expensive/slower. If you are repeatedly creating conversations for the same address using newConversation, you should refactor to re-use the returned conversation instance.

neekolas and others added 30 commits September 6, 2022 15:30
* feat: negotiated topics

* Client maintains both V1 and V2 private key bundles (`keys` vs `legacyKeys`), still publishing V1 only
* Client supports  reading both V1 and V2 peer contact bundles
* Client keeps publishing V1 contact bundle by default (tests can make it publish V2 contact)
* MessageV1/V2 classes to support header differences
* Both Message classes support `senderAddress()` & `sent`; 
  `recipientAddress` not supported by V2 and should be abandoned 
  (we could make it work in 1:1 convos if we link messages back to their conversations,
  but it won't work in group chat context)
* Stream generalized to support both message versions (streamAllMessages yet to be fixed in a follow up)
* ConversationV1/V2 classes to support different semantics
* ConversationV2 implements MessageV2 encoding/decoding (Client retains V1 version of that)
* listing/streaming conversations reads both the intro and invite topics and creates both kinds of conversations
* creating V2 conversation sends invites to both the sender and the recipient
* see below for the expanded behavior of `newConversation`

BREAKING CHANGE:

* `Message` is now `MessageV1 | MessageV2`
* `Conversation` is now `ConversationV1 | ConversationV2`
* Many of the `Client` methods are now restricted to `MessageV1` only
  as they are only pertinent to the V1 protocol;
  analogous V2 functionality can be found on `Conversation(s)`
* `Client.publishEnvelope()` is replaced by `Client.publishEnvelopes()`
  (not meant for general use)

* feat: get invites and intros in parallel

Co-authored-by: Nicholas Molnar <[email protected]>
@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Nov 2, 2022

Deploying with  Cloudflare Pages  Cloudflare Pages

Latest commit: 907acb7
Status: ✅  Deploy successful!
Preview URL: https://62d8476d.xmtp-js.pages.dev
Branch Preview URL: https://beta.xmtp-js.pages.dev

View logs

Copy link
Contributor

@mkobetic mkobetic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚀 🌔

@mkobetic mkobetic mentioned this pull request Nov 2, 2022
10 tasks
@neekolas neekolas marked this pull request as ready for review November 2, 2022 17:31
Copy link
Contributor

@mkobetic mkobetic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great to me.

@neekolas neekolas merged commit 4e4bdbc into main Nov 2, 2022
@github-actions
Copy link
Contributor

github-actions bot commented Nov 2, 2022

🎉 This PR is included in version 7.0.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants