Confidential Threads API

Private messaging for DMs, group chat, and private lists

Michael Sena
3Box Labs
Published in
6 min readFeb 14, 2020

--

Since we launched the first version of 3Box threads almost a year ago, developers have been asking for increased privacy for their users’ messages. Today we’re excited to finally lift the curtain on our brand new Confidential Threads API. Confidential threads enable private, encrypted, peer-to-peer messaging between one or many participants.

Unlike 3Box open threads, which are publicly readable by everyone, confidential threads are only readable by a designated subset of users. Use confidential threads anytime you don’t want outsiders to be able to read the contents of your stream.

Confidential threads are perfect for adding direct messages, group chats, or private lists to your application.

Continue reading to more about use cases and how to add confidential threads to your application.

👉 Read the Docs 👈

Types of Confidential Threads

3Box supports two primary types of threads. Persistent threads persist messages in an OrbitDB feed store where they remain unless removed by the original author or a moderator, while Ghost threads are more ephemeral and only exist in the memory of online peers, and do not use OrbitDB. If all peers go offline, then the message history of a ghost thread is lost.

Confidential threads are a type of persistent thread with two varieties: Members Confidential and Personal Confidential.

The first terms Members and Personal describe the write permissions on the thread, while the second term Confidential indicates that read access is restricted to those who can write. Read access control restrictions are implemented using asymmetric encryption with the user’s 3ID.

Below, see the two confidential thread options in relation to other persistent thread types offered by 3Box:

Persistent thread types supported by 3Box

As you can see, 3Box also offers non-confidential thread types. Explore the docs for Open, Members Open, or Personal Open threads to learn more.

Use Cases for Confidential Threads

Private Messaging and Data Sharing

Since members confidential threads restrict write and read access to the same subset of users, they are great for direct messages between two users, group chats between 3+ users, and private shared data feeds/streams between 2+ users.

Private Personal Lists

Since personal confidential threads restrict write and read access to a single user, they are great for creating private personal lists or content streams that can be read and modified by only the author. Example use cases include private shopping carts, to-do lists, contact lists, playlists, photo albums, and more.

Build with Confidential Threads

Below we will walk through how to create and use confidential threads with the 3Box APIs made available via 3Box.js. Full documentation is available here.

  1. Install 3Box SDK
  2. Configure your threads
  3. Create a new confidential thread
  4. Join an existing thread
  5. View posts
  6. Add posts

1. Install 3Box SDK

Add 3Box to your project using npm:

npm i 3box

2. Configure your threads

Before getting started, you should consider a few configuration options for your persistent threads, which will make later steps more simple.

You only need to perform this step if you are creating a new persistent thread. If you want to join an existing thread, then proceed to Step 4 (join an existing thread).

First, choose a name for your space.
Persistent threads are stored in OrbitDB feed stores, and references to these threads are stored in your application’s space. These spaces are created and exist inside the 3Box of each user that joins the thread, not in one single global space. You should choose a name for the space that you will use to store your app’s thread references.

In most cases, the name of the space should be the name of your application. We recommend simply using the name of your application for this threads space, unless you want your application’s threads kept in a different space for some reason. This space is an OrbitDB key-value store, so you can also keep other information and data related to your application inside it.

For example, if your application is called SuperRare we would recommend calling your space SuperRare.

Then, choose a naming convention for your individual threads.
For thread name, we recommend creating some standard convention that allows your application to easily create and manage many threads. While you can decide what this convention is, you may consider using the page URL, a topic, or something else unique.

3. Create a new confidential thread

Now that you have decided on the configuration options for your persistent threads, the next step in actually adding them to your application is allowing users to create new confidential threads.

**Note: To perform interactive operations on threads, such as creating a thread, joining a thread, posting messages, removing messages, adding moderators, and adding members, you must first authenticate the space wherein the thread is stored.

Create a Members Confidential or Personal Confidential Thread

To create a members confidential or personal confidential thread, use the createConfidentialThread method.

const thread = await space.createConfidentialThread('myConfThread')

For a members confidential thread, you will likely want to add other members around the time of creation so they can read from and write messages to the thread. Use the addMember method to allow moderators to add members to this thread. Note this is performed on the thread object.

await thread.addMember(<ethereum-address or 3id>)

For a personal confidential thread, you will not add additional members to the thread.

4. Join an existing thread

Persistent threads are identified within the 3Box network in two ways: by a unique thread address, or by a unique set of configuration options. While either can be used to join an existing thread, we recommend joining by the thread address.

Join Thread by Address

To join an existing thread, the easiest way is by its address using the joinThreadByAddress() method.

const thread = await space.joinThreadByAddress('/orbitdb/zdpuAp5QpBKR4BBVTvqe3KXVcNgo4z8Rkp9C5eK38iuEZj3jq/3box.thread.testSpace.testThread')

For members confidential and personal confidential threads, joining the thread will not allow you to read messages or post new messages unless you have first been added by a moderator.

Discover Thread Address

Users can discover the thread address in many ways depending on the app’s implementation of thread discovery, however users within the thread can use the code below to get the thread address and send it to new users in whatever way they choose.

An address of a thread can be found as follows once joined.

const threadAddress = thread.address

5. View posts

There are three options to getting the messages in a thread, but only one works for confidential threads since the user needs to first authenticate to decrypt and read the message they have permission to.

First authenticate the user, then call thread.getPosts()

This option for getting messages in a thread is appropriate when:

  • you may not know the address or configurations of the thread
  • you have already authenticated a user using the openBox and openSpace methods
  • the user has already joined the thread
  • you want to dynamically display updates to the thread

To get all posts in a thread, use thread.getPosts()

const posts = await thread.getPosts()console.log(posts)// you can also specify a number of posts you wantconst posts = await thread.getPosts(20)console.log(posts)

Listen for new updates

After you have gotten posts in a thread, you will likely want to listen for updates to the thread so you can update your application’s UI. To listen for updates to a thread, such as new posts, use thread.onUpdate(). This will allow you to immediately display new messages posted to the thread in your application.

thread.onUpdate(myCallbackFunction)

6. Add posts

To post in a thread, a user must first either create or join the thread using the steps above. After they have joined a thread, they can add a message to the thread using the thread.post() method. The author of the message will be the user's 3ID (3Box DID). Everyone who has permission to read the thread will have access to the message.

await thread.post('hello world')

Want to add confidential threads to your project?

We’re always online and available to chat in Discord if you have any questions about building with confidential threads or anything else. You can also read the full docs here.

#BuildBetter 3️⃣

--

--

Michael Sena
3Box Labs

Breaking down digital silos @ceramic. Helping developers #BuildBetter apps @3box. Happy contributor to the decentralized web. Fair data advocate.