Password Manager with 3Box
Build a ReactJS app using 3Box APIs
What we are building
We will be creating a ReactJS app that integrates with several of the 3Box APIs. It’s intended to be used as a password manager, but the app can also be used to store, get, or delete any “secret” key-value pair associated with any of your spaces.
3Box is an open-source, decentralized identity layer built on IPFS and OrbitDB.
With 3Box, DApp developers do not need to maintain a centralized back end service or store data on the blockchain.
With 3Box, end-users control their data, allowing them to decide what data to share and with whom they’d like to share it.
3Box profiles are ultimately a collection of IPFS hashes mapped to OrbitDB, which then maps to the user’s blockchain account through their 3ID (3Box identity system). 3Box runs an IPFS pinning node to ensure the retention of important CID.
The documentation covers the architecture in detail.
3Box Profiles allow DApp developers to store information that is intended to be shared across apps, such as names, profile pictures, and social verifications. The Profiles API can be used anywhere developers want access to general info about users, or to incorporate a human touch instead of defaulting to a hexadecimal value.
A subset of the Profiles API is the Profile Hover plugin, a lightweight drop-in component that augments a user’s hexadecimal code by displaying their social info. Profile Hover is highly customizable and allows for a more welcoming, personal user interaction. We will use it in this app to display the authenticated user.
3Box Storage allows DApp developers to perform various operations on users’ spaces, including getting, setting, and deleting both public and private information. Each user has a data store for both public and private data.
Storage is a sandboxed key-value data store that houses information related to a specific application or context. It uses IPFS for decentralized storage and OrbitDB for database structuring.
The Storage API can be used for storing any key-value pair, including preferences, settings, and sensitive information. It can also be used to store IPFS hashes that point to more complex files like images or Word docs.
- Store data with the user on IPFS and not on the blockchain when not necessary
- See a person and not a hexadecimal value
- Build UX-friendly DApps with a suite of out-of-the-box tools
- Auth and Profile experience similar to already-familiar web2 apps
- Users take ownership of their data
This tutorial does include a couple of libraries that may be outside the scope of a basic ReactJS app — mainly, Router and SCSS. More information on both can be found in the documentation below:
git clone https://github.com/ryanpedersen42/s3cretkeep3er.git
Below is the directory structure of the app.
🏗How it works
We will go into detail on the 3Box-specific actions in the app below. You can follow along in your IDE.
This function handles the authentication process for your app. In just a few lines of code, we confirm the user’s web3 account and use the result to take action across several 3Box APIs.
We start by prompting the user to log in with their web3 provider; we will use the returned address to start our actions with 3Box.
openBox() is a static method that authenticates the user of a given ethereum address into 3box and returns the
box instance of the associated address. This
box instance will be saved in
this.state and will be used later to change between spaces.
The Promise on line 11 awaits confirmation that the users 3Box DB is fully synced before continuing on to actions on the intended 3Box Storage Space. Once confirmed, we open up the s3cretkeep3r space and set the associated
dappSpace variable to
The number of signatures required during authentication depends on the user’s prior activity in 3Box. The first time a user logs in, they will need to provide three signatures: one to create an account, one to open the box, and one to open the space.
2. Profile Hover
profile-hover on main-page.jsx as an out-of-the-box implementation of the Profiles API. If you want to build a custom Profile instead, there are ample resources to help — try the Builder Series on Profiles and Profiles API docs to start.
You can also take a look at the Profile Object like this:
3. Add new key-value pair
space.private.set() takes two strings — input key and input value — to
put into our s3cretkeep3r space. The
.private indicates that the key and value will be encrypted. The end-user needs to sign to access their private spaces for each session they open.
put a public key-value pair, we would use
.public instead of
For more information on the encryption of private data, documentation can be viewed here.
4. Get key-value pair
space.private.get() function works similarly to the
space.private.set() function, but it
gets the value of the string that is passed in. If there is no such key, it returns
5. Delete key-value pair
This function takes in a string and removes the value of the associated key. It returns
Boolean — true if successful.
6. Log Out
box.logout() clears the local cache and logs the user out. If this is called, the user will need to sign a consent message the next time you call
💭 Using These Tools
The tools listed above should be applicable to a variety of apps, so whether you are building a decentralized Reddit, Twitter, or an Action DApp, feel free to plug and play. Full documentation here.
Bonus: miscellaneous errors
TypeError: Cannot read property ‘ciphertext' of null
>Make sure you have error handling for the returned values as some may be
undefined. (More info here)
Uncaught(in promise) TypeError: Cannot read property 'sendAsync' of undefined
>Comes from the sendEth function in index.js of 3Box-js. Check to make sure you are passing in the right value to