Observed since 20 Oct, 19:31 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
3box
Interact with user data
Install | Usage | Dapp data | Example | API Docs
This is a library which allows you to set, get, and remove private and public data associated with an ethereum account. It can be used to store identity data, user settings, etc. by dapps that use a web3 enabled browser. The data will be retrievable as long as the user has access to the private key for the used ethereum account. The data is encrypted and can not be read by any third party that the user hasn't authorized. There is one shared space for data which all authorized dapps access by default, then there are spaces which dapps have to request explicit consent to access.
Install 3box in your npm project:
$ npm install 3box
Import the 3box module
const Box = require('3box')
Import using the dist build in your html code
<script type="text/javascript" src="../dist/3box.js"></script>
Or optionally by loading remote copy from unpkg CDN.
<!-- The most recent version -->
<script src="https://unpkg.com/3box/dist/3box.js"></script>
<!-- The most recent minified version -->
<script src="https://unpkg.com/3box/dist/3box.min.js"></script>
<!-- Load specific versions by specifying the version as follows -->
<script src="https://unpkg.com/3box@<version>/dist/3box.js"></script>
3Box allows users to create a public profile. In your dapp you might have multiple ethereum addresses that you would like to display a name and picture for. The getProfile method allows you to retrieve the profile of any ethereum address (if it has one). This is a static method so you can call it directly from the Box object.
Using async/await
const profile = await Box.getProfile('0x12345abcde')
console.log(profile)
or using .then
Box.getProfile('0x12345abcde').then(profile => {
console.log(profile)
})
To get or modify data in a user's 3Box, first open their 3Box by calling the openBox method. This method prompts the user to authenticate your dapp and returns a promise with a threeBox instance. You can only set, get, and remove data of users that are currently interacting with your dapp. Below ethereumProvider refers to the object that you would get from web3.currentProvider, or window.ethereum.
Using async/await
const box = await Box.openBox('0x12345abcde', ethereumProvider)
or using .then
Box.openBox('0x12345abcde', ethereumProvider).then(box => {
// interact with 3Box data
})
When you first open the box in your dapp all data might not be synced from the network yet. You should therefore add a listener using the onSyncDone method. This will allow you to know when all the users data is available to you. We advice against setting any data before this has happened.
box.onSyncDone(yourCallbackFunction)
You can now use the box instance object to interact with data in the users private store and profile. In both the profile and the private store you use a key to set a value.
Using async/await
// use the public profile
// get
const nickname = await box.public.get('name')
console.log(nickname)
// set
await box.public.set('name', 'oed')
// remove
await box.public.remove('name')
// use the private store
// get
const email = await box.private.get('email')
console.log(email)
// set
await box.private.set('email', 'oed@email.service')
// remove
await box.private.remove('email')
or using .then
// use the public profile
// get
box.public.get('name').then(nickname => {
console.log(nickname)
// set
box.public.set('name', 'oed').then(() => {
// remove
box.public.remove('name').then(() => {
})
})
})
// use the private store
// get
box.private.get('email').then(email => {
console.log(email)
// set
box.private.set('email', 'oed@email.service').then(() => {
// remove
box.private.remove('email').then(() => {
})
})
})
Two options are available if you want to pass additional IPFS config options to the IPFS object used in the library.
First you can pass your own IPFS object, configured how you decide and then disable the iframe as well. This offers the most optionality but experiences a loss in performace without the iframe.
const IPFS_OPTIONS = {
EXPERIMENTAL: {
pubsub: true
},
... // Add your additional options, pubsub is required
}
const ipfs = new IPFS(IPFS_OPTIONS)
const box = await Box.openBox('0x12345abcde', ethereumProvider, { ipfs, iframeStore: false })
Second you can access the already initialized default IPFS object and change the IPFS configurations available after initialization. For example you can add a pinning node as follows.
const box = await Box.openBox('0x12345abcde', ethereumProvider)
box._ipfs.swarm.connect(pinningNode, () => {
...
})
Reference ipfs-js for additional options.
A space is a named section of a users 3Box. Each space has both a public and a private store, and for every space you open the user has to grant explicit consent to view that space. This means that if your dapp uses a space that no other dapp uses, only your dapp is allowed to update the data and read the private store of that particular space. To open a space called narwhal you simply call:
const space = await box.openSpace('narwhal')
Interacting with data in a space is done in the same way as interacting with box.public and box.private (see here). For example:
const config = await space.private.get('dapp-config')
Dapps can store data about users that relate to only their dapp. However we encurage dapps to share data between them for a richer web3 experience. Therefore we have created Key Conventions in order to facilitate this. Feel free to make a PR to this file to explain to the community how you use 3Box!
You can quickly run and interact with some code by looking at the files in the /example folder. You run the example with the following command:
$ npm run example:start
This runs a simple server at http://localhost:3000/ that serves the static example/index.html file. This allows it easily interact with metamask. You can edit the example/index.html file to try differnt code.
Kind: global class
ObjectObjectObjectObjectBoxBooleanPlease use the openBox method to instantiate a 3Box
Kind: instance property of Box
Properties
| Name | Type | Description |
|---|---|---|
| public | KeyValueStore | access the profile store of the users 3Box |
Kind: instance property of Box
Properties
| Name | Type | Description |
|---|---|---|
| private | KeyValueStore | access the private store of the users 3Box |
Kind: instance property of Box
Properties
| Name | Type | Description |
|---|---|---|
| verified | Verified | check and create verifications |
Kind: instance property of Box
Properties
| Name | Type | Description |
|---|---|---|
| spaces | Object | an object containing all open spaces indexed by their name. |
SpaceOpens the space with the given name in the users 3Box
Kind: instance method of Box
Returns: Space - the Space instance for the given space name
| Param | Type | Description |
|---|---|---|
| name | String | The name of the space |
| opts | Object | Optional parameters |
| opts.consentCallback | function | A function that will be called when the user has consented to opening the box |
| opts.onSyncDone | function | A function that will be called when the space has finished syncing with the pinning node |
Sets the callback function that will be called once when the db is fully synced.
Kind: instance method of Box
| Param | Type | Description |
|---|---|---|
| syncDone | function | The function that will be called |
Closes the 3box instance and clears local cache. If you call this, users will need to sign a consent message to log in the next time you call openBox.
Kind: instance method of Box
ObjectGet the public profile of a given address
Kind: static method of Box
Returns: Object - a json object with the profile for the given address
| Param | Type | Description |
|---|---|---|
| address | String | An ethereum address |
| opts | Object | Optional parameters |
| opts.addressServer | String | URL of the Address Server |
| opts.ipfs | Object | A js-ipfs ipfs object |
| opts.useCacheService | Boolean | Use 3Box API and Cache Service to fetch profile instead of OrbitDB. Default true. |
| opts.profileServer | String | URL of Profile API server |
ObjectGet a list of public profiles for given addresses. This relies on 3Box profile API.
Kind: static method of Box
Returns: Object - a json object with each key an address and value the profile
| Param | Type | Description |
|---|---|---|
| address | Array | An array of ethereum addresses |
| opts | Object | Optional parameters |
| opts.profileServer | String | URL of Profile API server |
ObjectGraphQL for 3Box profile API
Kind: static method of Box
Returns: Object - a json object with each key an address and value the profile
| Param | Type | Description |
|---|---|---|
| query | Object | A graphQL query object. |
| opts | Object | Optional parameters |
| opts.graphqlServer | String | URL of graphQL 3Box profile service |
ObjectVerifies the proofs of social accounts that is present in the profile.
Kind: static method of Box
Returns: Object - An object containing the accounts that have been verified
| Param | Type | Description |
|---|---|---|
| profile | Object | A user profile object, received from the getProfile function |
BoxOpens the 3Box associated with the given address
Kind: static method of Box
Returns: Box - the 3Box instance for the given address
| Param | Type | Description |
|---|---|---|
| address | String | An ethereum address |
| ethereumProvider | ethereumProvider | An ethereum provider |
| opts | Object | Optional parameters |
| opts.consentCallback | function | A function that will be called when the user has consented to opening the box |
| opts.pinningNode | String | A string with an ipfs multi-address to a 3box pinning node |
| opts.ipfs | Object | A js-ipfs ipfs object |
| opts.addressServer | String | URL of the Address Server |
BooleanCheck if the given address is logged in
Kind: static method of Box
Returns: Boolean - true if the user is logged in
| Param | Type | Description |
|---|---|---|
| address | String | An ethereum address |
Kind: global class
Array.<Object>StringBooleanBooleanPlease use box.public or box.private to get the instance of this class
Array.<Object>Returns array of underlying log entries. In linearized order according to their Lamport clocks. Useful for generating a complete history of all operations on store.
Kind: instance property of KeyValueStore
Returns: Array.<Object> - Array of ordered log entry objects
Example
const log = store.log
const entry = log[0]
console.log(entry)
// { op: 'PUT', key: 'Name', value: 'Botbot', timeStamp: '1538575416068' }
StringGet the value of the given key
Kind: instance method of KeyValueStore
Returns: String - the value associated with the key
| Param | Type | Description |
|---|---|---|
| key | String | the key |
BooleanSet a value for the given key
Kind: instance method of KeyValueStore
Returns: Boolean - true if successful
| Param | Type | Description |
|---|---|---|
| key | String | the key |
| value | String | the value |
BooleanRemove the value for the given key
Kind: instance method of KeyValueStore
Returns: Boolean - true if successful
| Param | Type | Description |
|---|---|---|
| key | String | the key |
Kind: global class
Please use box.openSpace to get the instance of this class
Kind: instance property of Space
Properties
| Name | Type | Description |
|---|---|---|
| public | KeyValueStore | access the profile store of the space |
Kind: instance property of Space
Properties
| Name | Type | Description |
|---|---|---|
| private | KeyValueStore | access the private store of the space |
Kind: global class
StringObjectObjectObjectObjectPlease use box.verified to get the instance of this class
StringReturns the verified DID of the user
Kind: instance method of Verified
Returns: String - The DID of the user
ObjectVerifies that the user has a valid github account Throws an error otherwise.
Kind: instance method of Verified
Returns: Object - Object containing username, and proof
ObjectAdds a github verification to the users profile Throws an error if the verification fails.
Kind: instance method of Verified
Returns: Object - Object containing username, and proof
| Param | Type | Description |
|---|---|---|
| gistUrl | Object | URL of the proof |
ObjectVerifies that the user has a valid twitter account Throws an error otherwise.
Kind: instance method of Verified
Returns: Object - Object containing username, proof, and the verifier
ObjectAdds a twitter verification to the users profile Throws an error if the verification fails.
Kind: instance method of Verified
Returns: Object - Object containing username, proof, and the verifier
| Param | Type | Description |
|---|---|---|
| claim | String | A did-JWT claim ownership of a twitter username |
Download counts and popularity will appear here as the collector receives them.
| Package / target | Requirement | Relationship |
|---|---|---|
ipfsEnvironment{
"local_name": "ipfs",
"alias": false,
"peer_metadata": null
} | ^0.33.1 | runtime |
storeEnvironment{
"local_name": "store",
"alias": false,
"peer_metadata": null
} | ^2.0.12 | runtime |
ethersEnvironment{
"local_name": "ethers",
"alias": false,
"peer_metadata": null
} | ^4.0.20 | runtime |
did-jwtEnvironment{
"local_name": "did-jwt",
"alias": false,
"peer_metadata": null
} | ^0.1.1 | runtime |
orbit-dbEnvironment{
"local_name": "orbit-db",
"alias": false,
"peer_metadata": null
} | git://github.com/orbitdb/orbit-db.git#dddb271 | runtime |
ipfs-miniEnvironment{
"local_name": "ipfs-mini",
"alias": false,
"peer_metadata": null
} | ^1.1.5 | runtime |
js-sha256Environment{
"local_name": "js-sha256",
"alias": false,
"peer_metadata": null
} | ^0.9.0 | runtime |
tweetnaclEnvironment{
"local_name": "tweetnacl",
"alias": false,
"peer_metadata": null
} | ^1.0.1 | runtime |
node-fetchEnvironment{
"local_name": "node-fetch",
"alias": false,
"peer_metadata": null
} | ^2.3.0 | runtime |
@babel/runtimeEnvironment{
"local_name": "@babel/runtime",
"alias": false,
"peer_metadata": null
} | ^7.1.2 | runtime |
tweetnacl-utilEnvironment{
"local_name": "tweetnacl-util",
"alias": false,
"peer_metadata": null
} | ^0.15.0 | runtime |
graphql-requestEnvironment{
"local_name": "graphql-request",
"alias": false,
"peer_metadata": null
} | ^1.8.2 | runtime |
https-did-resolverEnvironment{
"local_name": "https-did-resolver",
"alias": false,
"peer_metadata": null
} | ^0.1.0 | runtime |
ipfs-postmsg-proxyEnvironment{
"local_name": "ipfs-postmsg-proxy",
"alias": false,
"peer_metadata": null
} | ^3.1.1 | runtime |
muport-did-resolverEnvironment{
"local_name": "muport-did-resolver",
"alias": false,
"peer_metadata": null
} | ^0.3.0-alpha.2 | runtime |
orbit-db-cache-postmsg-proxyEnvironment{
"local_name": "orbit-db-cache-postmsg-proxy",
"alias": false,
"peer_metadata": null
} | ^0.1.1 | runtime |
jestEnvironment{
"local_name": "jest",
"alias": false,
"peer_metadata": null
} | ^23.6.0 | development |
expressEnvironment{
"local_name": "express",
"alias": false,
"peer_metadata": null
} | ^4.16.4 | development |
webpackEnvironment{
"local_name": "webpack",
"alias": false,
"peer_metadata": null
} | ^4.20.2 | development |
standardEnvironment{
"local_name": "standard",
"alias": false,
"peer_metadata": null
} | ^12.0.1 | development |
ipfsd-ctlEnvironment{
"local_name": "ipfsd-ctl",
"alias": false,
"peer_metadata": null
} | ^0.40.1 | development |
@babel/cliEnvironment{
"local_name": "@babel/cli",
"alias": false,
"peer_metadata": null
} | ^7.1.2 | development |
babel-coreEnvironment{
"local_name": "babel-core",
"alias": false,
"peer_metadata": null
} | 7.0.0-bridge.0 | development |
@babel/coreEnvironment{
"local_name": "@babel/core",
"alias": false,
"peer_metadata": null
} | ^7.1.2 | development |
ganache-cliEnvironment{
"local_name": "ganache-cli",
"alias": false,
"peer_metadata": null
} | ^6.1.0 | development |
webpack-cliEnvironment{
"local_name": "webpack-cli",
"alias": false,
"peer_metadata": null
} | ^3.1.2 | development |
babel-loaderEnvironment{
"local_name": "babel-loader",
"alias": false,
"peer_metadata": null
} | ^8.0.5 | development |
@babel/preset-envEnvironment{
"local_name": "@babel/preset-env",
"alias": false,
"peer_metadata": null
} | ^7.1.0 | development |
jsdoc-to-markdownEnvironment{
"local_name": "jsdoc-to-markdown",
"alias": false,
"peer_metadata": null
} | ^4.0.1 | development |
@babel/preset-reactEnvironment{
"local_name": "@babel/preset-react",
"alias": false,
"peer_metadata": null
} | ^7.0.0 | development |
@babel/plugin-transform-runtimeEnvironment{
"local_name": "@babel/plugin-transform-runtime",
"alias": false,
"peer_metadata": null
} | ^7.1.0 | development |
@babel/plugin-transform-modules-commonjsEnvironment{
"local_name": "@babel/plugin-transform-modules-commonjs",
"alias": false,
"peer_metadata": null
} | ^7.2.0 | development |
@babel/plugin-proposal-object-rest-spreadEnvironment{
"local_name": "@babel/plugin-proposal-object-rest-spread",
"alias": false,
"peer_metadata": null
} | ^7.0.0 | development |
Source distribution
{
"shasum": "8f8996dc48a247695dea36ad5ec87235f5e271c0",
"tarball": "https://registry.npmjs.org/3box/-/3box-1.3.0-beta.2.tgz",
"fileCount": 50,
"integrity": "sha512-vemils3NMR4FLPOyCMNC9r/BgzzvLDicdAima2Hu/ByMl8/u6lTtFZGC5o+7MIUs/goQnP3cpNRoEXnOhkt/Ew==",
"signatures": [
{
"sig": "MEUCIQCanv4I58nLez1LniYPze1pKEouISps3oyyphWYZRg8aAIge8dshrH7q/3cA84yMbNcfbhTb/yeg3+jH7ykD7Xt9Ow=",
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"
}
],
"unpackedSize": 16369671,
"npm-signature": "-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcVfIYCRA9TVsSAnZWagAADPAQAJTO9OA1wDrY/FkZuFJH\nundkaokWTQ/M3AsYMNPwUtK8wQdYZrsJrywkgLK36Tfj0IMWXOhA9NhPnIZa\nqc+Lb/qWlLk0mYvAR8q1q8AfRLNhmIuGS0I2sGvX15Aw9Sya8k2Z3+VQ1H2k\n1V835QwXPY2ipu2w4B0Rb8v+ByJvHg3+toBWHSEBLdrYi643lhQqEJZorUWV\n4GrZvDJF7/JnKKmuN8z+6ZP/bOMMLHTV7PAgTzGmqHEHOhYD1LzNcowLduSL\n/LSujS53JBfGpxbuDOnP621nn91lQ1r3wlyMkHSJVcmAU8ahtqd1FCiJIeZv\nWlpvVLL0cOV+hlBCY4Bvnrd30bOfZjRyLFxndtC+eeFm8IU+qPj4++wVBJQx\nQPvoVNF92lTYZ0v6QL93gTZj4sDZqKrOzpLj/MzxFOhjRdnDgs74+6BaLsLl\nfT5dUPqCaSyNNJI9Z8eYe/hZYOmoY2Y/MsbjnjgQpAG9E3qT7RPZ4fnJ4hZZ\nE+1XkM5XqV2xx6lyVRozvAoRx0TvhiQFrVavMpdcxZO50SWJ5PyC9o7qMNH3\ndySXbkioPEoK5ZI54WBMNYBmFtLJ5L/YgVK48bQDD1nZHGBXjHfLJcnfGx8X\nqhuSygUgetlHX3598wAam49378KZt10Ao6jRj11KRiq5GtIV8xGdctjol6px\nBCqv\r\n=n2hE\r\n-----END PGP SIGNATURE-----\r\n"
}Shared repository data · GitHub
HTTP 301 · detected 21 Oct 2026
Reported destinationObserved since 20 Oct, 19:31 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package_version:315ae38ce09dfdcd0e3b4badc8b8add659e807495b9c1315d2360e6310e8b5b0