3Box Profile Edit Plugin 📝

Simple plugin to add an edit profile screen to your app

The 3box-profile-edit-react node package is a drop-in React component that provides web developers with UI and logic for editing user profiles directly from inside your Ethereum application.

In addition to allowing users to use their existing 3Box profile or to create an app-specific profile for use with your app, Profile Edit also allows developers to easily add customizable input fields that are relevant and contextual your app. These are available as text, textarea, and select (dropdown) style inputs.

Try the demo here

How it Works

Architecture

Profile Edit is built using the 3Box SDK, Profiles and Spaces APIs, and infrastructure.

The Profile Edit plugin implements simple set and get methods on both the Profiles API and the Spaces API for standard fields (name, image, coverPhoto, emoji, description) depending on which profile the user chooses as their default (3Box or App). The component only uses the Spaces API for custom fields added by the developer, which are passed as a prop to the component. Both APIs are made available via the 3Box.js SDK.

After a user has set which default profile they'd like to use, by setting a boolean to the key isAppProfileDefault in the space's public store, the dapp should appropriately fetch and display that profile elsewhere throughout the app. See Step 4 in getting started below for more information on how to properly fetch and display profiles.

Authentication

Prior to first render of the Profile Edit component, the app should have already authenticated the user's 3Box and their app's space using the code below, and then have passed both the box and space objects as props to the component.

const box = await Box.openBox(userAddress, ethereumProvider)
const space = await box.openSpace(spaceName)

Getting Started

  1. Usage

1. Install the component

npm i -S 3box-profile-edit-react

2. Configure app settings and component props

First, choose a name for your application's 3Box space.

Although you are free to choose whichever name you'd like for your app's space, we recommend using the name of your app. If your application already has a 3Box space, you are welcome to use that same one for Profile Edit.

Then, configure the custom fields you'd like to add to the component.

The Profile Edit component comes standard with basic profile data, including: name, image , coverPhoto , emoji, and description fields.

Out of the box, the component defaults to using the 3Box profile for the basic profile information above, since the isAppProfileDefault boolean is still undefined. If the user chooses to instead create an app-specific profile, then the isAppProfileDefault boolean is updated to true and their newly entered profile information is saved to your space. However, it should be noted that custom fields passed to customFields will always be saved to your app's space.

The customFields prop must receive an array of any number of objects in the following structures:

{ // for a field with a text input
inputType: 'text',
key: 'backupAddress', // the key used to save the value
field: 'Backup Address' // how to display the key in the UI
},
{ // for a field with a textarea input
inputType: 'textarea',
key: 'spiritCryptoKitty',
field: 'Spirit CryptoKitty'
},
{ // for a field with a dropdown input
inputType: 'dropdown',
key: 'preferredCoin',
field: 'Preferred Coin',
options: [{ // dropdown input requires an array of objects
value: 'eth', // value passed after selection
display: 'Ethereum' // what the user will see in the dropdown
}, {
value: 'btc',
display: 'Bitcoin'
}, {
value: 'ltc',
display: 'Litecoin'
}]
}

3. Usage

The Profile Edit component can be used in any way you'd like, though we recommend that you use it on a dedicated edit profile page or in a popup modal (not included).

Authentication

As mentioned above, you must first authenticate both the user's 3Box and your app's space before this component can be used, since both the box and space instance must be passed to the component before it mounts. We recommend doing this on login.

const box = await Box.openBox(userAddress, ethereumProvider)
const space = await box.openSpace(spaceName)

Example Usage

import EditProfile from '3box-profile-edit-react';
const MyComponent = ({ customFields, box, space, myAddress, myProfile, redirectFn }) => (
<EditProfile
// required
box={box}
space={space}
currentUserAddr={myAddress}
// optional
customFields={customFields}
currentUser3BoxProfile={myProfile}
redirectFn={redirectFn}
/>
);

Prop Types

Property

Type

Required

Description

box

Object

True

The box instance returned from running await Box.openBox(address, web3) somewhere in your dApp.

space

Object

True

The space instance returned from running await box.openSpace(spaceName) somewhere in your dApp.

currentUserAddr

String (Ethereum Address)

True

The current user's Ethereum address. Used to fetch the user's profile if it's not provided and for other various uses in the component.

customFields

Array

An array of any amount of objects structured in one of three ways outlined above.

currentUser3BoxProfile

Object

If passed, it must be the object returned from calling const currentUser3BoxProfile = await Box.getProfile(myAddress);. If this is not passed, the component runs the same static method using the currentUserAddr prop

redirectFn

Function

A function that runs after saving the fields in the UI is complete, or when a user hits cancel. The user's ethereum address will be passed as a param in the event that the dapp uses this in the route

4. Display correct profiles in your app

Once a user selects a default profile (3Box or app), the decision should be reflected throughout your app.

When fetching profiles to display, you should check the isAppProfileDefault flag and then call get on the respective profile for fields name, image, coverPhoto, emoji, and description. Custom fields added to the component are all saved to the application profile in the space used by your dapp and you should get from there.

Checking and getting from the appropriate default profile should look something like this:

const isAppProfileDefault = await space.public.get('isAppProfileDefault');
let profile;
if (isAppProfileDefault) {
profile = await Box.getProfile(currentUserAddr);
} else {
profile = await space.public.all();
}
this.setState({
name: profile.name,
image: profile.image,
coverPhoto: profile.coverPhoto,
emoji: profile.emoji,
description: profile.description,
})

License

MIT