owned this note
owned this note
Published
Linked with GitHub
# Specifications for Holochain Web Container and Holo.js
The current proposal for a holochain web container is one that operates as a daemon running on the local machine and exposes functionality to the users browser through either HTTP or web sockets.
This document aims to specify the communication between the code running in the browser and the web container to facilitate the design of the connection abstraction on the browser side (holo.js) and the container (node server using holochain-nodejs?)
## Function calls
Following the example of web3 I propse we implement [JSON-RPC 2.0 standard](https://www.jsonrpc.org/specification) for making holochain functions calls from the browser. As the standard is transport agnostic it can be reused to make calls over http, websockets or any other protocols we care to use (IPC?).
All JSON-RPC 2.0 calls have the following structure:
```jsonld=
{
"jsonrpc":"2.0",
"method":"<method name>",
"params": <any valid json as params>,
"id": <some id to identify this call>
}
```
and response
```jsonld=
{
"jsonrpc": "2.0",
"result": <any valid json as result>
"id": <same id as call>,
}
```
There are plenty of node/browser modules for abstracting the creation of JSON-RPC servers/clients over HTTP, WS or IPC.
### Container Functions
The container itself should expose functions for the following
- `getApps()` Retrive the list of installed apps, their names and DNA hash
- `getDna(dnaHash)` Retrieve the dna of an installed app (only the zomes/capabilities not the actual code)
- `bridgeApps(from, to)` Enable bridging between two apps
- ... what else?
> [name=Michael Dougherty] Seems like `bridgeApps` should be more of a declarative config thing than an imperative function call.
These will be base level methods in the JSON-RPC server. As these functions will be included in every node they can be baked in to holo.js
### Zome Functions
The container should allow calling of all public zome functions. These should be namespaced by app and by zome in the method field of the JSON-RPC object e.g.
```json=
{
"method": "<appDNA>.<zome>.<functionName",
...
}
```
The container will register the RPC server to accept these calls by inspecting the DNA of installed apps.
holo.js will not know about these by default. A constructor must be called with the app dna as a parameter so it can generate a helper object for generating these calls with promises etc. e.g.
```javascript=
const dna = Holo.getDna(hash)
const app = Holo.connect(dna)
app.myZome.myFunc({params}).then(hash => console.log(hash))
```
### Callbacks
The major advantage of moving to a websockets based connection is the possibility of registering callbacks for holochain based events such as receiving a direct message, observing a change in data at a particular hash, app requests to bridge etc.
This will require coordination with core team to expose this functiality in a way that can be accessed by the web container.
On the Holo.js side some syntax would have to be defined for registering for callbacks. Inspired by web3:
```javascript=
const dna = Holo.getDna(hash)
const app = Holo.connect(dna)
app.register("directMessage", {"from": friendKeyHash}, (payload) => {
// function to be called on messages from friend
})
```
Behind the scenes this would be constructing a JSON-RPC call to something like "app.onDirectMessage" which would be responsible for subscribing on the server side. Holo.js would configure the callback on the client side.
## Holo interop
Another layer of abstraction that Holo.js can handle is the difference between interacting with a local Holochain Web Container and interacting with a Holo-hosted web service connecting the client to a network of Holo hosts. Not only does this entail talking to someone other than localhost, but a slew of other responsibilities, including but not limited to:
* Communicating with the tranche service to find hosts to talk to
* Browser-side key management
* This includes both ephemeral keypairs for anonymous browsing of Holo sites as well as more lasting keypairs once the user needs their source chain persisted on a Host.
* Passing credentials along with requests
* Signing entries (since Hosts only host the chain but don't get access to private keys)
Some of these, like passing credentials and signatures, would be tightly coupled with the normal request/response cycle, but others like talking to the tranche service could easily be pulled out into its own library. Perhaps holo.js can be built with a number of lifecycle hooks to accommodate this extra Holo functionality, and then a plugin can be written specifically for Holo. Those hooks may be useful for other developers for other unknown reasons. Also, it feels icky to build Holo stuff directly into a pure Holochain context.