ClojureScript library for OrbitDB.
OrbitDB requires a running IPFS node, compatible with IPFS version > 5.x.x and with the EXPERIMENTAL pub-sub featured turned on an.
Here's how you can run an ipfs node using a docker container:
docker run --name ipfs-daemon -v /home/$USER/ipfs-docker:/data/ipfs -p 8080:8080 -p 5001:5001 ipfs/go-ipfs:latest daemon --enable-pubsub-experiment
Alternatively you can use docker-compose:
version: "3"
services:
ipfs-daemon:
image: ipfs/go-ipfs:v0.5.1
command: ["daemon", "--enable-pubsub-experiment"]
container_name: ipfs-daemon
volumes:
- /home/$USER/ipfs-docker:/data/ipfs
ports:
- 8080:8080
- 5001:5001
This will expose nodes ports 5001 and 8080 to the hosts.
Use create-instance
function from orbitdb.core
namespace:
(create-instance {:ipfs-host "http://localhost:5001"})
This funciton returns a js/Promise which evaluates to an OrbitDB object representing the instance.
First, choose the data model you want to use. The available data models are:
- keyvalue: A key-value store.
- eventlog: Immutable (append only) database.
- feed: a mutable log database.
- docstore: a documents database. Useful for structured data.
- counter: Useful for storing count data.
You can use a general-purpose create-database
function from the orbitdb.core
namespace or a function from a namespace which corresponds to that specific database.
Here's how you would create an eventlog database instance:
(create-database orbitdb-instance {:name "my-eventlog"
:type :eventlog
:opts {:directory "./orbitdb/my.eventlog"}})
Alternatively, using the eventlog
function in orbitdb.eventlog
namespace:
(eventlog orbitdb-instance {:name "my-eventlog"
:opts {:directory "./orbitdb/my.eventlog"}})
Here is how you can persist some data using add-event
function in orbitdb.eventlog
namespace:
(add-event eventlog-instance {:fu "bar"})
This function returns a js/Promise which evaluates to the hash of the persisted entry. Other database types have corresponding functions in their respective namespaces.
Note
OrbitDB does not automatically pin content to IPFS. To pin the entry, pass the optional { pin: true }
in the options:
(add-event eventlog-instance {:fu "bar"} {:pin true})
You can specify the peers that have write-access to a database or write a custom access controller.
Note
OrbitDB currently supports only dynamically adding write-access, meaning that write-access cannot be revoked once added
If you simply want to specify a whitelist for write access, you can do it by passing a vector of of public keys when creating the database.
This example gives write priviledges to the node's public key (your key) and to another peer identified by the public key starting with 042c...
:
(create-database orbitdb-instance {:name "creatures"
:type :eventlog
:opts {:accessController {:write [(-> ^js orbitdb-instance .-identity .-id)
042c07044e7ea51a489c02854db5e09f0191690dc59db0afd95328c9db614a2976e088cab7c86d7e48183191258fc59dc699653508ce25bf0369d67f33d5d77839]}}})
If you want to create a database with a public access you can do so by passing a wildcard:
(eventlog orbitdb-instance {:name "my-eventlog"
:opts {:accessController {:write ["*"]}}})
You can also create a custom access controller, which regulates who and what can be written to your database, with a predicate function with two arguments:
entry
: the persisted entryidentity-provider
: an instance of the IdentityProvider
The functions for creating and managing custom access controllers are in the orbitdb.access-controllers
namespace.
Here is how you can create an access controller:
(def my-controller (create-access-controller {:type "mytype"
:can-append? (fn [entry identity-provider]
(and (= "bar" (:fu entry))
(= (-> ^js orbitdb-instance .-identity .-id) (-> ^js identity-provider .-id))))}))
Next you need to add it:
(def access-controllers (add-access-controller my-controller))
The add-access-controller
function returns the instance of AccessControllers object, which is a singleton. You need to pass it in the options map when creating an instance of the OrbitDB:
orbitdb-instance (orbitdb/create-instance {:ipfs-host "http://localhost:5001"
:opts {:AccessControllers access-controllers}})
To use the controller with a database, specify it when creating that database:
(create-database orbitdb-instance {:name "creatures"
:type :eventlog
:opts {:accessController {:type ["my-type"]}}})