Build a Discussion App

A 30-minute tutorial using 3Box threads

Build 3Chat: A fully-featured decentralized discussion app

In this 30-minute tutorial we will build 3Chat, a react web app for decentralized discussions that leverages the 3Box SDK, 3Box Messaging API, and an Ethereum smart contract deployed on the Rinkeby test network. You will not need to write or interact with Solidity in this demo, though.

If you follow along, you will learn how to build a dapp that uses 3Box threads.

Before getting started, give 3Chat a try here

For simplicity, 3Chat is an unpolished implementation of a 3Box-enabled react app. Please forgive us for any sluggishness in reactivity or small hiccups in the UX/UI.

Although use of Ethereum smart contracts is not explicitly required for 3Box threads, in this case we are using a smart contract as a public registration and discovery mechanism for message threads which enables them to be shared across various application interfaces. In many cases applications that use 3Box message threads would handle them in other ways without Ethereum, including in the application logic itself.

What you will learn

This tutorial will teach you how to use the following 3Box functionality:

  • Install 3Box in your app

  • Display user profiles

  • Authenticate users

  • Create message threads

  • Add posts to a thread

  • Display posts in a thread

  • Add members and moderators to a thread

  • Display members and moderators of a thread

Running the application

This project was bootstrapped with Create React App.

1. Navigate to the tutorial repo on Github.

2. Download the repo to your computer.

To do this, click the green "Clone or Download" button in the upper right hand corner of the Github page.

3. Run the application in the project directory, using npm start .

This will runs the app in development mode.

4. Open http://localhost:3000 to view the app in the browser.

The page will reload if you make edits. You will also see any lint errors in the console.

Workshop steps

The 3Chat application contains logic for threaded conversations, and the only thing missing from the app that you just installed is 3Box functionality, which we will now implement. If you are unsure of anything during this tutorial, don't hesitate to look through the API docs or reach out to us on Discord.

Step 1: Create a 3Box profile for your Ethereum account

This step is optional but the tutorial will look and work better if you have a recognizable 3Box profile to provide social context to your Ethereum account within the 3Chat application. Create or edit your profile here.

Step 2: Ensure you have Rinkeby ETH in your Ethereum account

You will need Rinkeby ETH to create new threads in the 3Chat app!

The 3Chat smart contract used to register and discover threads is deployed on the Rinkeby Ethereum test network. You will need Rinkeby ETH to create new topics within the 3Chat app.

Go to the Rinkeby ETH faucet to get some rETH.

Step 3: Basic get profile of current user

Open the file src/App.jsx, import 3Box, and call getProfile in the correct locations.

import Box from '3box'
const myProfile = await Box.getProfile(myAddress);

Step 4: Authenticate user

In the handleLogin function, we can now add the code needed to authenticate the user to the 3chat space.

box = await Box.openBox(myAddress, window.ethereum, {})
await box.syncDone
const chatSpace = await box.openSpace('3chat')
const myDid = chatSpace.DID;

Step 5: Display posts in topic

When a user clicks on a topic name in the left side of the panel we want to display the posts of that topic. Open the src/ui/views/Chat.jsx file and add the following at the appropriate location in the handleViewTopic function.

const thread = await chatSpace.joinThread(topic, { firstModerator: owner, members });
thread.onUpdate(() => this.updateThreadPosts());
thread.onNewCapabilities(() => this.updateThreadCapabilities());

To actually display the posts we need to edit the updateThreadPosts function with a call to getPosts.

const posts = await activeTopic.getPosts();

Step 6: Display members and moderators

To display the moderators and members of a topic we need to modify the updateThreadCapabilities function by adding the two following calls:

const members = await activeTopic.listMembers();
const moderators = await activeTopic.listModerators();

Step 7: Get profile of authors, moderators, and members

Note: The members call has to be surrounded with a try/catch.

Repeat Step 1 but in the src/ui/components/ProfilePicture.jsx file. Use this.props.did instead of myAddress in the getProfile call.

Next, we add profile hovers to the members list. First import the library:

import ProfileHover from 'profile-hover';

Now we just wrap the profileTile with the following tag:

<ProfileHover noTheme address={ethAddr} orientation="left">
<!--content-->
</ProfileHover>

Step 8: Add members and mods

To add the ability to add new moderators and members, open the src/ui/views/AppModals.jsx file.

In the handleAddThreadMember function, add the following call:

await activeTopic.addMember(threadMember);

In the handleAddThreadMod function, add the following call:

await activeTopic.addModerator(threadMod);

Step 9: Add posts to a thread

To add the ability to make posts, open the src/ui/components/Dialogue.jsx file.

In the postThread function, add the following call:

await activeTopic.post(postMsg);