' +
38 | ''
39 | );
40 | });
41 | })
42 | .catch((err) => {
43 | console.error(err);
44 | });
45 | });
--------------------------------------------------------------------------------
/build/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holochain/docs-pages-redux/a1176e29a4feb4ec5cca4dc2a004f362aa0986f7/build/favicon.ico
--------------------------------------------------------------------------------
/build/robots.txt:
--------------------------------------------------------------------------------
1 | User-agent: *
2 | Disallow: /
--------------------------------------------------------------------------------
/build_all_tuts.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 |
4 | ~/.cargo/bin/single_source md src/tutorials/coreconcepts/hello_holo.md docs/tutorials/coreconcepts/hello_holo.md
5 | ~/.cargo/bin/single_source md src/tutorials/coreconcepts/hello_test.md docs/tutorials/coreconcepts/hello_test.md
6 | ~/.cargo/bin/single_source md src/tutorials/coreconcepts/hello_gui.md docs/tutorials/coreconcepts/hello_gui.md
7 | ~/.cargo/bin/single_source md src/tutorials/coreconcepts/hello_me.md docs/tutorials/coreconcepts/hello_me.md
8 | ~/.cargo/bin/single_source md src/tutorials/coreconcepts/hello_world.md docs/tutorials/coreconcepts/hello_world.md
9 | ~/.cargo/bin/single_source md src/tutorials/coreconcepts/simple_micro_blog.md docs/tutorials/coreconcepts/simple_micro_blog.md
10 | ~/.cargo/bin/single_source md src/install.md docs/install.md
11 |
--------------------------------------------------------------------------------
/build_api.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | releases=$( A Holochain DNA can specify who belongs to its network using **membranes**---functions which determine whether a node may join a network and gossip with other nodes. These tools can be used to screen new members or eject existing members.
4 |
5 | **Please note**: These features are still in design and development. More information when they become available!
6 |
7 | 
8 |
9 | You'll remember from the [section on validation](../7_validation) and one of its tutorials that write access can be managed with validation rules. But we didn't say anything about read access. Why is that?
10 |
11 | In a Holochain application, data is either **private** to your source chain or **public** on the DHT. This is a pretty coarse distinction; do we feel comfortable sharing our data with everyone on the network? Who's allowed into that public space anyway?
12 |
13 | Holochain was built to foster **networks of trust** between sovereign individuals. But not all kinds of trust can be created with a magical integrity algorithm. In fact, the kinds of trust that matter to most people all come from social agreements: family relationships, cultural norms, company policy, contracts, laws, and so on.
14 |
15 | Besides the 'rules of the game' for participants, we need a way to define who's allowed to play the game. In other words, we need some sort of **membrane**---a boundary that permits and restricts the flow of information and people between its inside and outside.
16 |
17 | Holochain lets you create membranes with two tools:
18 |
19 | 
20 | * A **special validation function for the agent ID entry**, which can contain extra content such as invite codes or third-party attestations of identity. This involves every participant in the screening of new entrants.
21 | * [ What is the other thing? I know it's non-deterministic, and it involves allowing agents decide for themselves who to talk to based on current state. Not available yet. ]
22 |
23 | [Tutorial: **SecureMicroBlog** >](#)
24 | [Next: **Bridging Across Multiple DNA Instances** >>](../12_bridging)
25 |
--------------------------------------------------------------------------------
/src/concepts/12_bridging.md:
--------------------------------------------------------------------------------
1 | # 12: Bridging across multiple DNA instances
2 |
3 | > A user's running DNA instances can be **bridged** to each other to allow trustable interaction between app networks, mediated by their own membership in each of those networks.
4 |
5 | 
6 |
7 | When we outlined the [architecture of a typical hApp](../2_application_architecture), we recommended that you write DNA with a small scope of responsibility, so that they can be repurposed and combined into new apps, similar to [microservices](https://en.wikipedia.org/wiki/Microservices). But in order to function together in an app, these packets of functionality often need some way of talking to each other.
8 |
9 | You can do this in two ways:
10 |
11 | * A client on the user's machine (e.g., GUI) can talk to two DNA instances to translate data from one DNA's space to another. This is flexible but loses some of the integrity provided by Holochain's trusted execution environment.
12 | * Two DNA instances on the user's machine can form a **bridge** to talk to each other directly. This creates a hard dependency between those DNAs, but allows them to guarantee the integrity of their responses.
13 |
14 | In both cases, it's the _agents themselves_ (or, rather, the software they're running) that create the bridge. They make the connection between two app DHTs by their presence in both of them. Many agents might bridge between the same two DHTs and recognise each other in both spaces, or there might only be a single user mediating a bridge. It all depends on how you design your app.
15 |
16 | A DNA can specify a bridge dependency either:
17 |
18 | * **explicitly** by its **DNA hash**, or
19 | * **implicitly** by referencing one or more **traits** that it may implement.
20 |
21 | A trait is like a [contract](https://en.wikipedia.org/wiki/Design_by_contract), [interface, or protocol](https://en.wikipedia.org/wiki/Protocol_(object-oriented_programming)) from object-oriented programming. It specifies a collection of functionality that a zome is capable of. This gives users choice over their preferred implementations of DNAs with certain traits. An example that we'll explore in the next tutorial is a currency DNA that broadcasts transaction announcements into a microblogging DNA---as a user, you could swap the microblogging dependency with any DNA that advertises the ability to post a short status message.
22 |
23 | ## Further reading
24 |
25 | * [Holochain core apps](#) (non-existent article; link does notwork), DNAs that exist on nearly every Holochain node. You can bridge to these apps from your own and even 'fork' them into private instances.
26 | * [Open-source DNA registry](#) (non-existent link; should link to a GH repo that tracks things like [HoloREA](https://github.com/holo-rea), [File Storage](https://github.com/holochain/file-storage-zome), and [HoloJS](https://github.com/ReversedK/HoloJS).
27 |
28 | Here's a short listof core apps:
29 |
30 | * [**DeepKey**](https://github.com/Holo-Host/DeepKey), for maintaining a continuous identity across devices by allowing users to create, connect, and revoke their device keys.
31 | * [**Personas & Profiles**](https://github.com/holochain/personas-profiles), for storing personal information, sharing it with other hApps, and keeping it in sync.
32 | * [**Basic Chat**](https://github.com/holochain/holochain-basic-chat), for creating chat, forum, commenting, instant messaging, or live customer support apps.
33 | * [**HCHC**](https://github.com/holochain/HCHC-rust) or Holochain of Holochains, a package manager for distributing Holochain DNA and UI bundles.
34 | * [**hApp Store**](https://github.com/holochain/HApps-Store), a directory of Holochain apps.
35 | * **Source chain backups**, for safely making redundant copies of private source chain data and restoring them to new devices.
36 |
37 | [Tutorial: **TransactionAnnouncements** >](#)
38 | [Next: **Spawning New DNA Instances From A Template** >>](#)
39 |
40 |
--------------------------------------------------------------------------------
/src/concepts/index.md:
--------------------------------------------------------------------------------
1 | title: Holochain Core Concepts - Holochain Docs
2 |
3 | # Holochain Core Concepts
4 |
5 | Welcome to Holochain Core Concepts! Here we'll introduce you to the basics of Holochain, a framework and network protocol for building secure distributed applications. Holochain is different from what you may be used to, but we'll go at a comfortable pace, building on things you already know.
6 |
7 | ## Who is this introduction for?
8 |
9 | We've written this introduction for programmers, CTOs, and other technically oriented people. It's a bit like a choose-your-own-adventure story.
10 |
11 | **If you're in a hurry**, and want to find out if Holochain is a good fit for your project, you can just read the articles---or if you're in a real hurry, read the intro paragraph at the top and the key takeaways at the bottom.
12 |
13 | **If you're a programmer** and want to see the concepts come to life, follow the [tutorials](../tutorials/coreconcepts/). Each tutorial is quick---you'll be creating a running app in anywhere from a few minutes to a few hours. Code samples are written in [Rust](https://www.rust-lang.org/).
14 |
15 | **If you want to dig deep**, each article has links to further reading from the guidebook, API documentation, or web.
16 |
17 | ## Ready? Let's get started
18 |
19 |
61 |
--------------------------------------------------------------------------------
/src/create-new-app.md:
--------------------------------------------------------------------------------
1 | # Create a New App
2 | These are the commands you will need when creating a new application.
3 |
4 | ### Initialize a new app
5 | Make sure you have completed the [Install Guide](../install).
6 |
7 | Enter the `nix-shell`
8 | ```
9 | nix-shell https://github.com/holochain/holonix/archive/release-0.0.85.tar.gz
10 | ```
11 |
12 | !!! note "Run in nix-shell"
13 | ```
14 | hc init my_new_app
15 | ```
16 |
17 | ## Run from project root
18 |
19 | !!! tip
20 | The following commands should all be run from the project root (e.g., `my_new_app/`).
21 | ```
22 | cd my_new_app
23 | ```
24 |
25 | ### Generate a new Zome
26 |
27 | !!! note "Run in nix-shell"
28 | ```
29 | hc generate zomes/my_zome rust-proc
30 | ```
31 |
32 | ### Package an app
33 |
34 | !!! note "Run in nix-shell"
35 | ```
36 | hc package
37 | ```
38 |
39 | ### Run a testing Holochain conductor
40 |
41 | !!! note "Run in nix-shell"
42 | ```
43 | hc run
44 | ```
45 |
46 | !!! note "Run in nix-shell"
47 | ```
48 | hc test
49 | ```
50 |
51 | ### Run a Holochain conductor
52 | You will need to create a config file. See the [hello_world](tutorials/coreconcepts/hello_world) tutorial for an example.
53 |
54 | !!! note "Run in nix-shell"
55 | ```
56 | holochain -c conductor-config.toml
57 | ```
58 |
59 | ### Learn more
60 |
61 | !!! note "Run in nix-shell"
62 | ```
63 | hc help
64 | holochain --help
65 | ```
66 |
67 |
68 |
--------------------------------------------------------------------------------
/src/custom/holochain-rust-releases.txt:
--------------------------------------------------------------------------------
1 | v0.0.52-alpha2,v0.0.52-alpha1,v0.0.51-alpha1,v0.0.50-alpha4,v0.0.50-alpha3,v0.0.50-alpha2,v0.0.50-alpha1,v0.0.49-alpha1,v0.0.48-alpha1,v0.0.47-alpha1,v0.0.46-alpha1,v0.0.45-alpha1,v0.0.44-alpha3,v0.0.44-alpha2,v0.0.44-alpha1,v0.0.43-alpha3,v0.0.43-alpha2,v0.0.43-alpha1,v0.0.42-alpha5,v0.0.42-alpha4,v0.0.42-alpha3,v0.0.42-alpha2,v0.0.42-alpha1,v0.0.41-alpha4,v0.0.41-alpha3,v0.0.41-alpha2,v0.0.40-alpha1,v0.0.39-alpha4,v0.0.39-alpha3,v0.0.39-alpha2,v0.0.39-alpha1,v0.0.38-alpha14,v0.0.38-alpha13,v0.0.38-alpha12,v0.0.38-alpha9,v0.0.38-alpha8,v0.0.38-alpha7,v0.0.38-alpha6,v0.0.38-alpha5,v0.0.38-alpha4,v0.0.38-alpha2,v0.0.38-alpha1,v0.0.37-alpha12,v0.0.37-alpha11,v0.0.37-alpha10,v0.0.37-alpha9,v0.0.37-alpha8,v0.0.37-alpha7,v0.0.37-alpha6,v0.0.37-alpha5,v0.0.37-alpha4,v0.0.37-alpha3,v0.0.37-alpha2,v0.0.37-alpha1,v0.0.36-alpha1,v0.0.35-alpha7,v0.0.34-alpha1,v0.0.33-alpha6,v0.0.33-alpha5,v0.0.33-alpha4,v0.0.33-alpha3,v0.0.32-alpha1,v0.0.32-alpha2,v0.0.31-alpha1,v0.0.30-alpha6,v0.0.30-alpha5,v0.0.30-alpha4,v0.0.30-alpha3,0.0.30-alpha1,0.0.30-alpha2,0.0.29-alpha1,0.0.29-alpha2,0.0.28-alpha1,0.0.27-alpha1,0.0.26-alpha1,0.0.25-alpha1,0.0.24-alpha2,0.0.24-alpha1,v0.0.23-alpha1,v0.0.22-alpha1,v0.0.21-alpha1,v0.0.20-alpha3,v0.0.19-alpha1,v0.0.18-alpha1,
--------------------------------------------------------------------------------
/src/custom/icon-apple.svg:
--------------------------------------------------------------------------------
1 |
2 |
56 |
--------------------------------------------------------------------------------
/src/custom/icon-windows.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
18 |
19 |
--------------------------------------------------------------------------------
/src/custom/prism.css:
--------------------------------------------------------------------------------
1 | /* PrismJS 1.17.1
2 | https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript+rust */
3 | /**
4 | * prism.js default theme for JavaScript, CSS and HTML
5 | * Based on dabblet (http://dabblet.com)
6 | * @author Lea Verou
7 | */
8 |
9 | code[class*="language-"],
10 | pre[class*="language-"] {
11 | color: black;
12 | background: none;
13 | text-shadow: 0 1px white;
14 | font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
15 | font-size: 1em;
16 | text-align: left;
17 | white-space: pre;
18 | word-spacing: normal;
19 | word-break: normal;
20 | word-wrap: normal;
21 | line-height: 1.5;
22 |
23 | -moz-tab-size: 4;
24 | -o-tab-size: 4;
25 | tab-size: 4;
26 |
27 | -webkit-hyphens: none;
28 | -moz-hyphens: none;
29 | -ms-hyphens: none;
30 | hyphens: none;
31 | }
32 |
33 | pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection,
34 | code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection {
35 | text-shadow: none;
36 | background: #b3d4fc;
37 | }
38 |
39 | pre[class*="language-"]::selection, pre[class*="language-"] ::selection,
40 | code[class*="language-"]::selection, code[class*="language-"] ::selection {
41 | text-shadow: none;
42 | background: #b3d4fc;
43 | }
44 |
45 | @media print {
46 | code[class*="language-"],
47 | pre[class*="language-"] {
48 | text-shadow: none;
49 | }
50 | }
51 |
52 | /* Code blocks */
53 | pre[class*="language-"] {
54 | padding: 1em;
55 | margin: .5em 0;
56 | overflow: auto;
57 | }
58 |
59 | :not(pre) > code[class*="language-"],
60 | pre[class*="language-"] {
61 | background: #f5f2f0;
62 | }
63 |
64 | /* Inline code */
65 | :not(pre) > code[class*="language-"] {
66 | padding: .1em;
67 | border-radius: .3em;
68 | white-space: normal;
69 | }
70 |
71 | .token.comment,
72 | .token.prolog,
73 | .token.doctype,
74 | .token.cdata {
75 | color: slategray;
76 | }
77 |
78 | .token.punctuation {
79 | color: #999;
80 | }
81 |
82 | .namespace {
83 | opacity: .7;
84 | }
85 |
86 | .token.property,
87 | .token.tag,
88 | .token.boolean,
89 | .token.number,
90 | .token.constant,
91 | .token.symbol,
92 | .token.deleted {
93 | color: #905;
94 | }
95 |
96 | .token.selector,
97 | .token.attr-name,
98 | .token.string,
99 | .token.char,
100 | .token.builtin,
101 | .token.inserted {
102 | color: #690;
103 | }
104 |
105 | .token.operator,
106 | .token.entity,
107 | .token.url,
108 | .language-css .token.string,
109 | .style .token.string {
110 | color: #9a6e3a;
111 | background: hsla(0, 0%, 100%, .5);
112 | }
113 |
114 | .token.atrule,
115 | .token.attr-value,
116 | .token.keyword {
117 | color: #07a;
118 | }
119 |
120 | .token.function,
121 | .token.class-name {
122 | color: #DD4A68;
123 | }
124 |
125 | .token.regex,
126 | .token.important,
127 | .token.variable {
128 | color: #e90;
129 | }
130 |
131 | .token.important,
132 | .token.bold {
133 | font-weight: bold;
134 | }
135 | .token.italic {
136 | font-style: italic;
137 | }
138 |
139 | .token.entity {
140 | cursor: help;
141 | }
142 |
143 |
--------------------------------------------------------------------------------
/src/custom/script.js:
--------------------------------------------------------------------------------
1 | if (document.location.pathname.indexOf("/concepts/") == 0) {
2 | document.body.className = "page-concepts";
3 | }
--------------------------------------------------------------------------------
/src/get-involved.md:
--------------------------------------------------------------------------------
1 | # Get Involved
2 |
3 | Regardless of your experience level as a developer, we encourage you to get involved and stay connected. Here are a few ways to start:
4 |
5 | ### Jump in and get your feet wet
6 |
7 | * Read through our [Core Concepts](../concepts/)
8 | * Start to build with one of our [Tutorials](../tutorials/coreconcepts/)
9 | * Track development progress with the weekly [Holochain Dev Pulse](https://blog.holochain.org/tag/dev-pulse/)
10 |
11 | ### Connect and contribute
12 |
13 | * Contribute to the conversation on our [Holochain Developer Forum](https://forum.holochain.org/)
14 | * Sign up for the [Holochain Blog](http://blog.holochain.org#subscribe) to stay up to date
15 | * Follow us on social media ([Facebook](https://www.facebook.com/holochain.design) and [Twitter](https://twitter.com/holochain))
--------------------------------------------------------------------------------
/src/guide/access_instance_info.md:
--------------------------------------------------------------------------------
1 | # Access Instance Info
2 |
3 | Other info about running Instances in the Conductor can be retrieved via functions on a Conductor.
4 |
5 | ### `conductor.agent_id(instanceId)` => `string`
6 |
7 | Get the agent_id for an instance, by passing an instance id.
8 |
9 | ___
10 | **Name** instanceId
11 |
12 | **Type** `string`
13 |
14 | **Description** Specifies an instance by its instanceId. This instanceId should be the equivalent to an `instanceConfig.name` which was passed to [Config.instance](./testing_configuration.md#instances). This in turn would be equivalent to the original name given to [Config.agent](./testing_configuration.md#agents), unless you overrode it when calling [Config.instance](./testing_configuration.md#instances). See more [here](./testing_configuration.md#example-2).
15 | ___
16 |
17 | #### Example
18 |
19 | ```javascript
20 | const aliceAgentId = conductor.agent_id('alice')
21 | console.log(aliceAgentId)
22 | // alice-----------------------------------------------------------------------------AAAIuDJb4M
23 | ```
24 |
25 | ### `conductor.dna_address(instanceId)` => `string`
26 |
27 | Get the address of the DNA for an instance, by passing an instance id.
28 |
29 | ___
30 | **Name** instanceId
31 |
32 | **Type** `string`
33 |
34 | **Description** Specifies an instance by its instanceId. This instanceId should be the equivalent to an `instanceConfig.name` which was passed to [Config.instance](./testing_configuration.md#instances). This in turn would be equivalent to the original name given to [Config.agent](./testing_configuration.md#agents), unless you overrode it when calling [Config.instance](./testing_configuration.md#instances). See more [here](./testing_configuration.md#example-2).
35 | ___
36 |
37 | #### Example
38 |
39 | ```javascript
40 | const dnaAddress = conductor.dna_address('alice')
41 | console.log(dnaAddress)
42 | // QmYiUmMEq1WQmSSjbM7pcLCy1GkdkfbwH5cxugGmeNZPE3
43 | ```
44 |
--------------------------------------------------------------------------------
/src/guide/agent.md:
--------------------------------------------------------------------------------
1 | # Agent
2 |
--------------------------------------------------------------------------------
/src/guide/apps_advanced_topics.md:
--------------------------------------------------------------------------------
1 | # Building Holochain Apps: Advanced Topics
2 |
--------------------------------------------------------------------------------
/src/guide/apps_user_interfaces.md:
--------------------------------------------------------------------------------
1 | # Building Holochain Apps: User Interfaces
2 |
3 | Holochain is designed to be flexible and accomodating when it comes to building user interfaces. There is not a single approach to developing user interfaces that is enforced by Holochain, though there are some approaches that have extra tooling, support and focus. First and foremost, Holochain supports APIs that make building UIs with the technologies of the web (HTML, CSS, JS, etc) easy.
4 |
5 | Put simply, it is entirely possible to build a user interface for Holochain completely in HTML, CSS, and JavaScript.
--------------------------------------------------------------------------------
/src/guide/bridging.md:
--------------------------------------------------------------------------------
1 | # Building Holochain Apps: Bridging
2 |
3 | As you saw in [Building Apps](./building_apps.md) each **DNA** has a unique hash that spawns a brand new **DHT network** and creates isolated **source chains** for each agent. Even when you change the DNA, releasing a new version of the app, it will spawn a brand new DHT network and source chains.
4 |
5 | So if every app lives in an entirely separated world how can they talk to each other? This is where **bridging** comes into play.
6 |
7 | A **bridge** is a connector between two apps (or two versions of the same app, for that matter) that allows synchronous, bidirectional transfer of information between them. It's important to note that this bridge connects two DNA instances on one machine; therefore, all function calls using this bridge are done from the perspective of the agent, not the apps as a whole.
8 |
9 | To use a bridge, right now you need to configure a [production Holochain conductor](./production_conductor.md), at least two instances configured, along the lines of the following example setup (in a **conductor-config.toml** file):
10 |
11 | ```
12 | [[instances]]
13 | id = "caller-instance"
14 | dna = "caller-dna"
15 | agent = "caller-agent"
16 | [instances.logger]
17 | type = "simple"
18 | [instances.storage]
19 | type = "memory"
20 |
21 | [[instances]]
22 | id = "target-instance"
23 | dna = target-dna"
24 | agent = "target-agent"
25 | [instances.logger]
26 | type = "simple"
27 | [instances.storage]
28 | type = "memory"
29 |
30 | [[bridges]]
31 | caller_id = "caller-instance"
32 | callee_id = "target-instance"
33 | handle = "sample-bridge"
34 | ```
35 |
36 | Then on the caller DNA you have to initiate the bridge call using `hdk::call` like this:
37 |
38 | ```rust
39 | let response = match hdk::call(
40 | "sample-bridge",
41 | "sample_zome",
42 | Address::from(PUBLIC_TOKEN.to_string()), // never mind this for now
43 | "sample_function",
44 | json!({
45 | "some_param": "some_val",
46 | }).into()
47 | ) {
48 | Ok(json) => serde_json::from_str(&json.to_string()).unwrap(), // converts the return to JSON
49 | Err(e) => return Err(e)
50 | };
51 | ```
52 |
53 | And the corresponding target / callee DNA on the other end should have a zome called "sample_zome", with a function as follows:
54 | ```rust
55 | pub fn handle_sample_function(some_param: String) -> ZomeApiResult {
56 | // do something here
57 | }
58 |
59 | define_zome! {
60 | entries: []
61 |
62 | init: || { Ok(()) }
63 |
64 | validate_agent: |validation_data : EntryValidationData::| {
65 | Ok(())
66 | }
67 |
68 | functions: [
69 | sample_function: {
70 | inputs: |some_param: String|,
71 | outputs: |result: ZomeApiResult|,
72 | handler: handle_sample_function
73 | }
74 | ]
75 |
76 | traits: {
77 | hc_public [
78 | sample_function
79 | ]
80 | }
81 | ```
82 |
83 | Remember that the **call** will block the execution of the caller DNA until the callee (target) finishes executing the call, so it's best to mind performance issues when working with bridges. Try to make contextual or incremental calls rather than all-encompassing ones.
84 |
--------------------------------------------------------------------------------
/src/guide/build_files.md:
--------------------------------------------------------------------------------
1 | # .hcbuild Files
2 |
3 | In the process of building a `.dna.json` file during packaging, here is what Holochain does:
4 | - It iterates Zome by Zome adding them to the JSON
5 | - For each Zome, it looks for any folders containing a `.hcbuild` file
6 | - For any folder with a `.hcbuild` file, it __executes one or more commands from the `.hcbuild` file to create a WASM file__
7 | - It takes that built WASM file and Base64 encodes it, then stores a key/value pair for the Zome with the key as the folder name and the encoded WASM as the value
8 |
9 | When using [`hc generate` to scaffold a Zome](./zome/adding_a_zome.md), you will have a `.hcbuild` file automatically. If you create your Zome manually however, you will need to create the file yourself. Here's the structure of a `.hcbuild` file, using a Rust Zome which builds using Cargo as an example:
10 | ```json
11 | {
12 | "steps": [
13 | {
14 | "command": "cargo",
15 | "arguments": [
16 | "build",
17 | "--release",
18 | "--target=wasm32-unknown-unknown"
19 | ]
20 | },
21 | ],
22 | "artifact": "target/wasm32-unknown-unknown/release/code.wasm"
23 | }
24 | ```
25 |
26 | The two top level properties are `steps` and `artifact`.
27 |
28 | `steps` is a list of commands which will be sequentially executed to build a WASM file.
29 |
30 | `artifact` is the expected path to the built WASM file.
31 |
32 | Under `steps`, each key refers to the bin(ary) of the command that will be executed, such as `cargo`. The value of `cargo`, the command, is an array of arguments: `build`, and the two `--` flags. In order to determine what should go here, just try running the commands yourself from a terminal, while in the directory of the Zome code.
33 |
34 | That would look, for example, like running:
35 | ```shell
36 | cargo build --release --target=wasm32-unknown-unknown
37 | ```
38 |
39 | ## Building in Rust: Rust -> WASM compilation tools
40 | If we take Zome code in Rust as an example, you will need Rust and Cargo set up appropriately to build WASM from Rust code. To enable it, run the following:
41 |
42 | ```shell
43 | $ rustup target add wasm32-unknown-unknown
44 | ```
45 |
46 | This adds WASM as a compilation target for Rust, so that you can run the previously mentioned command with `--target=wasm32-unknown-unknown`.
47 |
--------------------------------------------------------------------------------
/src/guide/building_apps.md:
--------------------------------------------------------------------------------
1 | # Building Apps
2 |
3 | If you're looking to build a Holochain app, it is important to first know what a Holochain app is.
4 |
5 | First, recall that Holochain is an engine that can run your distributed apps. That engine expects and requires your application to be in a certain format that is unique to Holochain. That format is referred to as the "DNA" of your application. The DNA of an application exists as a single file, which is mounted and executed by Holochain.
6 |
7 | Writing your application in a single file would not be feasible or desirable, however. Instead, you are supplied the tools to store your application code across a set of files within a folder, and tools to build all that code down into one file, in the DNA format.
8 |
9 | While there are lots of details to learn about Holochain and DNA, it can be useful to first look from a general perspective.
10 |
11 | ## Holochain and DNA
12 |
13 | Recall that a goal of Holochain is to enable cryptographically secured, tamper-proof peer-to-peer applications. DNA files play a fundamental role in enabling this. Imagine that we think of an application and its users as a game. When people play any game, it's important that they play by the same rules -- otherwise, they are actually playing different games. With Holochain, a DNA file contains the complete set of rules and logic for an application. Thus, when users independently run an app with identical DNA, they are playing the same game -- running the same application with cryptographic security.
14 |
15 | What this allows in technical terms is that these independent users can begin sharing data with one another and validating one anothers data. Thus, users can interact with the data in this distributed peer-to-peer system with full confidence in the integrity of that data.
16 |
17 | The key takeaway from this is that if you change the DNA (the configuration, validation rules, and application logic) and a user runs it, they are basically running a different app. If this brings up questions for you about updating your application to different versions, good catch. This concern will be addressed later in this section.
18 |
19 | Before exploring the details of Holochain DNA, take a minute to explore the different platforms that you can target with Holochain.
20 |
--------------------------------------------------------------------------------
/src/guide/building_for_android.md:
--------------------------------------------------------------------------------
1 | # Building For Android
2 |
3 | Note: These instructions for building Holochain on Android are adapted from [here](https://mozilla.github.io/firefox-browser-architecture/experiments/2017-09-21-rust-on-android.html).
4 |
5 | In order to get to libraries that can be linked against when building [HoloSqape](https://github.com/holochain/holosqape) for Android, you basically just need to setup up according targets for cargo.
6 |
7 | Given that the Android SDK is installed, here are the steps to setting things up for building:
8 |
9 | 1. Install the Android tools:
10 |
11 | a. Install [Android Studio](https://developer.android.com/studio/)
12 | b. Open Android Studio and navigate to SDK Tools:
13 | - MacOS: `Android Studio > Preferences > Appearance & Behaviour > Android SDK > SDK Tools`
14 | - Linux: `Configure (gear) > Appearance & Behavior > System Settings > Android SDK`
15 | c. Check the following options for installation and click OK:
16 | * Android SDK Tools
17 | * NDK
18 | * CMake
19 | * LLDB
20 | d. Get a beverage of your choice (or a full meal for that matter) why you wait for the lengthy download
21 |
22 | 1. Setup ANDROID_HOME env variable:
23 |
24 | On MacOS
25 |
26 | ```bash
27 | export ANDROID_HOME=/Users/$USER/Library/Android/sdk
28 | ```
29 |
30 | Linux: (assuming you used defaults when installing Android Studio)
31 |
32 | ```bash
33 | export ANDROID_HOME=$HOME/Android/Sdk
34 | ```
35 |
36 | 2. Create standalone NDKs (the commands below put the NDK in your home dir but you can put them where you like):
37 |
38 | ```bash
39 | export NDK_HOME=$ANDROID_HOME/ndk-bundle
40 | cd ~
41 | mkdir NDK
42 | ${NDK_HOME}/build/tools/make_standalone_toolchain.py --api 26 --arch arm64 --install-dir NDK/arm64
43 | ${NDK_HOME}/build/tools/make_standalone_toolchain.py --api 26 --arch arm --install-dir NDK/arm
44 | ${NDK_HOME}/build/tools/make_standalone_toolchain.py --api 26 --arch x86 --install-dir NDK/x86
45 | ```
46 |
47 | 3. Add the following lines to your ```~/.cargo/config```:
48 |
49 | ```toml
50 | [target.aarch64-linux-android]
51 | ar = "/NDK/arm64/bin/aarch64-linux-android-ar"
52 | linker = "/NDK/arm64/bin/aarch64-linux-android-clang"
53 |
54 | [target.armv7-linux-androideabi]
55 | ar = "/NDK/arm/bin/arm-linux-androideabi-ar"
56 | linker = "/NDK/arm/bin/arm-linux-androideabi-clang"
57 |
58 | [target.i686-linux-android]
59 | ar = "/NDK/x86/bin/i686-linux-android-ar"
60 | linker = "/NDK/x86/bin/i686-linux-android-clang"
61 |
62 | ```
63 | (this toml file needs absolute paths, so you need to prefix the path with your home dir).
64 |
65 | 4. Now you can add those targets to your rust installation with:
66 |
67 | ```
68 | rustup target add aarch64-linux-android armv7-linux-androideabi i686-linux-android
69 | ```
70 |
71 | Finally, should now be able to build Holochain for Android with your chosen target, e.g.:
72 |
73 | ```
74 | cd
75 | cargo build --target armv7-linux-androideabi --release
76 | ```
77 |
78 | **NOTE:** there is currently a problem in that `wabt` (which we use in testing as a dev dependency) won't compile on android, and the cargo builder compiles dev dependencies even though they aren't being used in release builds. Thus as a work around, for the cargo build command above to work, you need to manually comment out the dev dependency section in both `core/Cargo.toml` and `core_api/Cargo.toml`
--------------------------------------------------------------------------------
/src/guide/building_for_different_platforms.md:
--------------------------------------------------------------------------------
1 | # Building for Different Platforms
2 |
3 | Holochain is designed to run on many different platforms. Essentially it can run on any platform that Rust and the Rust WASM interpreter targets. Thus Holochain DNA's will be able to run on platforms ranging from Raspberry Pis to Android smartphones once the tools have been fully developed.
4 |
5 | We have experimented with C bindings that allowed us to run Holochain DNAs, in a [Qt and Qml](https://doc.qt.io/qt-5.11/qtqml-index.html) based cross-platform deployment, which besides running on desktop machines also [worked on Android](./building_for_android.md).
6 |
7 | We expect other approaches to running Holochain apps on different platforms to proliferate, including compiling Holochain directly in your native application, whether it be an Electron app, a command-line Rust based app, or an Android app.
8 |
--------------------------------------------------------------------------------
/src/guide/conductor_admin.md:
--------------------------------------------------------------------------------
1 | # Administering Conductors
2 |
3 | It is possible to dynamically configure a Conductor via a JSON-RPC interface connection. There is a powerful API that is exposed for doing so.
4 |
5 | To do this, first, recall that the `admin = true` [property needs to be set](./conductor_interfaces.md#admin-bool-optional) for the interface that should allow admin access. Second, it is helpful to review and understand the behaviours around the [`persistence_dir` property](./conductor_persistence_dir.md) for the Conductor.
6 |
7 | You can find details of the API for this functionality in the full [API reference material](https://github.com/holochain/holochain-rust/blob/1787f199b12118103cef4300dd4ebc423085d44b/crates/conductor_lib/src/interface.rs#L340). Scroll to view the `with_admin_dna_functions` comment block and the `with_admin_ui_functions` comment block. Calling these functions works exactly the same way as the other [JSON-RPC API calls](./conductor_json_rpc_api.md).
8 |
9 | As mentioned in [production Conductor](./production_conductor.md), there is a GUI in development that will cover all this functionality, so that it does not have to be done programmatically, but can be done by any user simply point and click.
10 |
--------------------------------------------------------------------------------
/src/guide/conductor_agents.md:
--------------------------------------------------------------------------------
1 | # Agents
2 |
3 | `agents` is an array of configurations for "agents". This means that you can define, and later reference, multiple distinct agents in this single config file. An "agent" has a name, ID, public address and is defined by a private key that resides in a file on their device.
4 |
5 | **Required**: `agents` is a required property in the config file. It is the ONLY required property.
6 |
7 | ### Properties
8 |
9 | #### `id`: `string`
10 | Give an ID of your choice to the agent
11 |
12 | #### `name`: `string`
13 | Give a name of your choice to the agent
14 |
15 | #### `public_address`: `string`
16 | A public address for the agent. Run ```hc keygen``` and copy the public address to this value
17 |
18 | #### `keystore_file`: `string`
19 | Path to the keystore file for this agent. Copy the path from when you ran ```hc keygen``` into this value.
20 |
21 |
22 | ### Example
23 | ```toml
24 | [[agents]]
25 | id = "test_agent2"
26 | name = "HoloTester2"
27 | public_address = "HcSCJts3fQ6Y4c4xr795Zj6inhTjecrfrsSFOrU9Jmnhnj5bdoXkoPSJivrm3wi"
28 | keystore_file = "/org.holochain.holochain/keys/HcSCJts3fQ6Y4c4xr795Zj6inhTjecrfrsSFOrU9Jmnhnj5bdoXkoPSJivrm3wi"
29 | ```
30 |
--------------------------------------------------------------------------------
/src/guide/conductor_bridges.md:
--------------------------------------------------------------------------------
1 | # Bridges
2 | `bridges` is an array of configuration instances that are configured to be able to make calls to Zome functions of another instance. You can think of this of as configuring an internal direct interface between DNA instances. The [section on bridging](./bridging.md) provides more information on how this ability is used to to compose complex applications out of many DNA instances.
3 |
4 | **Optional**
5 |
6 | ### Properties
7 |
8 | #### `caller_id`: `string`
9 | A reference to the given ID of a defined [instance](./conductor_instances.md) that calls the other one. This instance depends on the callee.
10 |
11 |
12 | #### `callee_id`: `string`
13 | A reference to the given ID of a defined [instance](./conductor_instances.md) that exposes capabilities through this bridge. This instance is used by the caller.
14 |
15 | #### `handle`: `string`
16 | The caller's local handle for this bridge and the callee. A caller can have many bridges to other DNAs and those DNAs could by bound dynamically. Callers reference callees by this arbitrary but unique local name.
17 |
18 | ### Example
19 | ```toml
20 | [[bridges]]
21 | caller_id = "app1"
22 | callee_id = "app2"
23 | handle = "happ-store"
24 | ```
25 |
--------------------------------------------------------------------------------
/src/guide/conductor_dnas.md:
--------------------------------------------------------------------------------
1 | # DNAs
2 |
3 | `dnas` is an array of configurations for "DNAs" that are available to be instantiated in the Conductor. A DNA is a packaged JSON file containing a valid DNA configuration including the WASM code for the Zomes. How to package DNA from source files can be read about [here](./packaging.md).
4 |
5 | **Optional**
6 |
7 | ### Properties
8 |
9 | #### `id`: `string`
10 | Give an ID of your choice to this DNA
11 |
12 | #### `file`: `string`
13 | Path to the packaged DNA file
14 |
15 | #### `hash`: `string` Optional
16 | A hash can optionally be provided, which could be used to validate that the DNA being installed is the DNA that was intended to be installed.
17 |
18 | ### Example
19 | ```toml
20 | [[dnas]]
21 | id = "app spec rust"
22 | file = "example-config/app_spec.dna.json"
23 | ```
24 |
--------------------------------------------------------------------------------
/src/guide/conductor_instances.md:
--------------------------------------------------------------------------------
1 | # Instances
2 |
3 | `instances` is an array of configurations of DNA instances, each of which is a running copy of a [DNA](./conductor_dnas.md), by a particular [agent](./conductor_agents.md). Based on these configurations, the Conductor will attempt to start up these instances, initializing (or resuming) a local source chain and DHT. It is possible to use the same DNA with multiple different [agents](./conductor_agents.md), but it is **not** recommended to run two instances with the same DNA and same agent. An instance has a configurable `storage` property, which can be set to save to disk, or just store temporarily in memory, which is useful for testing purposes.
4 |
5 | **Optional**
6 |
7 | ### Properties
8 |
9 | #### `id`: `string`
10 |
11 | Give an ID of your choice to this instance
12 |
13 | #### `agent`: `string`
14 |
15 | A reference to the given ID of a defined [agent](./conductor_agents.md)
16 |
17 | #### `dna`: `string`
18 |
19 | A reference to the given ID of a defined [DNA](./conductor_dnas.md)
20 |
21 | #### `storage`: `StorageConfiguration`
22 |
23 | A table for configuring the approach to storage of the local source chain and DHT for this instance
24 |
25 | #### `StorageConfiguration.type`: `enum`
26 |
27 | Select between different storage implementations. There are three so far:
28 |
29 | - `memory`: Persist actions taken in this instance only to memory. Everything will disappear when the Conductor process stops.
30 | - `file`: Persist actions taken in this instance to the disk of the device the Conductor is running on. If the Conductor process stops and then restarts, the actions taken will resume at the place in the local source chain they last were at.
31 | - `pickle` : Persists to a fast memory call which is eventually persisted to a file storage every 5 seconds. The actions taken will also resume at the place in the local source chain they were last. If an application error does occur, it will make sure to persist the latest data prior to any shutdown occurring.
32 |
33 | #### `StorageConfiguration.path`: `string`
34 |
35 | Path to the folder in which to store the data for this instance.
36 |
37 | ### Example
38 |
39 | ```toml
40 | [[instances]]
41 | id = "app spec instance 1"
42 | agent = "test agent 1"
43 | dna = "app spec rust"
44 |
45 | [instances.storage]
46 | type = "file"
47 | path = "example-config/tmp-storage"
48 | ```
49 |
--------------------------------------------------------------------------------
/src/guide/conductor_interfaces.md:
--------------------------------------------------------------------------------
1 | # Interfaces
2 | `interfaces` is an array of configurations of the channels (e.g. http or websockets) that the Conductor will use to send information to and from instances and users. Interfaces are user facing and make Zome functions, info, and optionally admin functions available to GUIs, browser based web UIs, local native UIs, and other local applications and scripts.
3 | The following implementations are already developed:
4 |
5 | - WebSockets
6 | - HTTP
7 |
8 | The instances (referenced by ID) that are to be made available via that interface should be listed.
9 | An admin flag can enable special Conductor functions for programatically changing the configuration
10 | (e.g. installing apps), which even persists back to the configuration file.
11 |
12 | **Optional**
13 |
14 | ### Properties
15 |
16 | #### `id`: `string`
17 |
18 | Give an ID of your choice to this interface
19 |
20 | #### `driver`: `InterfaceDriver`
21 |
22 | A table which should provide info regarding the protocol and port over which this interface should run
23 |
24 | #### `InterfaceDriver.type`: `enum`
25 |
26 | Select between different protocols for serving the API. There are two so far:
27 |
28 | - `websocket`: serve the API as JSON-RPC via [WebSockets](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API)
29 | - `http`: serve the API as JSON-RPC via HTTP
30 |
31 | These are discussed in great detail in [Intro to JSON-RPC Interfaces](./json_rpc_interfaces.md), and the following articles.
32 |
33 | #### `InterfaceDriver.port`: `u16`
34 |
35 | An integer value representing the port on the device to run this interface over
36 |
37 | #### `admin`: `bool` Optional
38 |
39 | Whether to expose [admin level functions](./conductor_admin.md) for dynamically administering the Conductor via this JSON-RPC interface. Defaults to false.
40 |
41 | #### `instances`: `array of InstanceReferenceConfiguration`
42 |
43 | An array of tables which should provide the IDs of [instances](./conductor_instances.md) to serve over this interface. Only the ones which are listed here will be served.
44 |
45 | #### `InstanceReferenceConfiguration.id`: `string`
46 |
47 | A reference to the given ID of a defined [instance](./conductor_instances.md)
48 |
49 | ### Example Without Admin
50 |
51 | ```toml
52 | [[interfaces]]
53 | id = "websocket interface"
54 |
55 | [[interfaces.instances]]
56 | id = "app spec instance 1"
57 |
58 | [interfaces.driver]
59 | type = "websocket"
60 | port = 4000
61 | ```
62 |
63 | ### Example With Admin
64 |
65 | ```toml
66 | [[interfaces]]
67 | id = "http interface"
68 | admin = true
69 |
70 | [[interfaces.instances]]
71 | id = "app spec instance 1"
72 |
73 | [interfaces.driver]
74 | type = "http"
75 | port = 4000
76 | ```
77 |
--------------------------------------------------------------------------------
/src/guide/conductor_json_rpc_api.md:
--------------------------------------------------------------------------------
1 | # Conductor JSON-RPC API
2 |
3 |
4 |
5 | ## Querying Running DNA Instances
6 |
7 | Holochain Conductors expose a method `info/instances`. This method returns a list of the running DNA instances in the Conductor. For each running instance, it provides the instance "ID", the name of the DNA, and the agent "id". The instance IDs will be particularly useful in other circumstances.
8 |
9 | The method `info/instances` doesn't require any input parameters, so `params` can be left off the request.
10 |
11 | ### Example
12 | **example request**
13 | ```json
14 | {
15 | "jsonrpc": "2.0",
16 | "id": "0",
17 | "method": "info/instances"
18 | }
19 | ```
20 |
21 | **example response**
22 | ```json
23 | {
24 | "jsonrpc": "2.0",
25 | "result": [{"id":"test-instance","dna":"hc-run-dna","agent":"hc-run-agent"}],
26 | "id": "0"
27 | }
28 | ```
29 |
30 | ## Calling Zome Functions
31 |
32 | The following explains the general JSON-RPC pattern for how to call a Zome function.
33 |
34 | Unlike `info/instances`, a Zome function call also expects arguments. We will need to include a JSON-RPC `args` field in our RPC call.
35 |
36 | To call a Zome function, use `"call"` as the JSON-RPC `method`, and a `params` object with four items:
37 | 1. `instance_id`: The instance ID, corresponding to the instance IDs returned by `info/instances`
38 | 2. `zome`: The name of the Zome
39 | 3. `function`: The name of the function
40 | 4. `args`: The actual parameters of the zome function call
41 |
42 | In the last example, the instance ID "test-instance" was returned, which can be used here as the instance ID. Say there was a Zome in a DNA called "blogs", this is the Zome name. That Zome has a function called "create_blog", that is the function name.
43 |
44 | > Any top level keys of the `args` field should correspond **exactly** with the name of an argument expected by the Zome method being called.
45 |
46 | **Example Zome Function Arguments**
47 |
48 | ```json
49 | { "blog": { "content": "sample content" }}
50 | ```
51 |
52 | ### Example Request
53 |
54 | **example request**
55 | ```json
56 | {
57 | "jsonrpc": "2.0",
58 | "id": "0",
59 | "method": "call",
60 | "params": {
61 | "instance_id": "test-instance",
62 | "zome": "blog",
63 | "function": "create_blog",
64 | "args": {
65 | "blog": {
66 | "content": "sample content"
67 | }
68 | }
69 | }
70 | }
71 | ```
72 |
73 | **example response**
74 | ```json
75 | {
76 | "jsonrpc": "2.0",
77 | "result": "{\"Ok\":\"QmUwoQAtmg7frBjcn1GZX5fwcPf3ENiiMhPPro6DBM4V19\"}",
78 | "id": "0"
79 | }
80 | ```
81 |
82 | This response suggests that the function call was successful ("Ok") and provides the DHT address of the freshly committed blog entry ("QmU...").
83 |
84 |
--------------------------------------------------------------------------------
/src/guide/conductor_logging.md:
--------------------------------------------------------------------------------
1 | # Logging
2 |
3 | `logger` is a table for the configuration of how logging should behave in the Conductor. Select between types of loggers and setup rules for nicer display of the logs. There is only one logger per Conductor.
4 |
5 | **Optional**
6 |
7 | ### Properties
8 |
9 | #### `type`: `enum` Optional
10 |
11 | Select which type of logger to use for the Conductor. If you leave this off, "simple" logging is the default
12 |
13 | - `debug`: enables more sophisticated logging with color coding and filters
14 | - `simple`: a most minimal logger, no color coding or filtering
15 |
16 | #### `rules`: `LogRules` Optional
17 |
18 | A table for optionally adding a set of rules to the logger
19 |
20 | #### `LogRules.rules`: `LogRule`
21 |
22 | An array of tables containing the rules for the logger
23 |
24 | #### `LogRule.pattern`: `Regex string`
25 |
26 | A Regex pattern as a string to match a log message against, to see whether this rule should apply to it.
27 |
28 | #### `LogRule.exclude`: `bool` Optional
29 |
30 | Whether to use this pattern to exclude things that match from the logs. Defaults to `false`. This option is useful for when the logs seem noisy.
31 |
32 | #### `LogRule.color`: `enum` Optional
33 |
34 | What color to use in the terminal output for logs that match this pattern. Options:
35 |
36 | ```text
37 | black, red, green, yellow, blue, magenta, cyan, white
38 | ```
39 |
40 | ### Example
41 |
42 | ```toml
43 | [logger]
44 | type = "debug"
45 | [[logger.rules.rules]]
46 | color = "red"
47 | exclude = false
48 | pattern = "^err/"
49 |
50 | [[logger.rules.rules]]
51 | color = "white"
52 | exclude = false
53 | pattern = "^debug/dna"
54 |
55 | [[logger.rules.rules]]
56 | exclude = true
57 | pattern = "^debug/reduce"
58 |
59 | [[logger.rules.rules]]
60 | exclude = false
61 | pattern = ".*"
62 | ```
63 |
--------------------------------------------------------------------------------
/src/guide/conductor_networking.md:
--------------------------------------------------------------------------------
1 | # Networking
2 |
3 | `network` is a table for the configuration of how networking should behave in the Conductor. The Conductor currently uses mock networking by default. To network with other nodes Holochain will automatically setup the [n3h networking component](https://github.com/holochain/n3h). How `n3h` behaves can be configured with the following properties in a Conductor configuration file.
4 |
5 | **Optional**
6 |
7 | ### Properties
8 |
9 | #### `n3h_persistence_path`: `string`
10 | Absolute path to the directory that n3h uses to store persisted data. Each Conductor should have a separate folder that `n3h_persistence_path` should be set to, because each should be assigned a custom network ID which will be persisted within that folder, thus they need to be distinct.
11 |
12 | #### `bootstrap_nodes`: `array of string` Optional
13 | List of URIs that point to other nodes to bootstrap p2p connections.
14 |
15 | #### `n3h_log_level`: `char`
16 | Set the logging level used globally by N3H. Must be one of the following: 't', 'd', 'i', 'w', 'e'
17 | Each value corresponding to the industry standard log level: Trace, Debug, Info, Warning, Error.
18 |
19 | #### `n3h_ipc_uri`: `string` Optional
20 | URI pointing to an n3h process that is already running and not managed by this
21 | Conductor. If this is set the Conductor does not spawn n3h itself and ignores the path configs above. Default is this value is empty.
22 |
23 | ### Example
24 | ```toml
25 | [network]
26 | type = "n3h"
27 | n3h_persistence_path = "./c1_network_files"
28 | bootstrap_nodes = []
29 | ```
30 |
31 |
32 |
--------------------------------------------------------------------------------
/src/guide/conductor_persistence_dir.md:
--------------------------------------------------------------------------------
1 | # Persistence Directory
2 |
3 | This is a simple key/value pair specifying a directory on the device to persist the config file, DNAs, and UI bundles, if changes are made dynamically over the JSON-RPC admin API. This is only relevant if you are running one of the [interfaces](./conductor_interfaces.md) with `admin = true`. The default value is in a subdirectory of the $HOME directory, `$HOME/.holochain/conductor`.
4 |
5 | **Optional**
6 |
7 | If you start a Conductor that has this value set, but then make no changes via the JSON-RPC admin interface, the persistence directory will not be utilized and the Conductor config file you started with will not be moved into that directory. On the other hand, if you do make any changes to the configuration by calling one of the [dynamic admin functions](./conductor_admin.md) then whatever the value of the `persistence_dir` is for that Conductor config, it will create that directory, and then persist the modified Conductor configuration file there. It would then be wise to utilize **that** Conductor config in the future, instead of the original.
8 |
9 | Within this `persistence_dir` that is now on the device, there are a number of possible files and folders.
10 |
11 | `conductor-config.toml` is the new configuration file, which will be repeatedly written to with any further dynamic updates. This is useful so that when the Conductor is stopped, or if it dies for some reason, when you restart it will behave the same as before.
12 |
13 | `storage` is a directory used for persisting the data for [instances](./conductor_instances.md), in particular when new instances are added via the `admin/instance/add` admin function.
14 |
15 | `dna` is a directory used for copying [DNA](./conductor_dnas.md) package files into if the `admin/dna/install_from_file` admin function is called.
16 |
17 | `static` is a directory used for copying [UI Bundle](./conductor_ui_bundles.md) files into if the `admin/ui/install` admin function is called.
18 |
19 | ### Example
20 | ```toml
21 | persistence_dir = "/home/user/my_holochain"
22 | ```
23 |
24 |
25 |
--------------------------------------------------------------------------------
/src/guide/conductor_ui_bundles.md:
--------------------------------------------------------------------------------
1 | # UI Bundles
2 |
3 | `ui_bundles` is an array of configurations of folders containing static assets, like HTML, CSS, and Javascript files, that will be accessed through a browser and used as a user interface for one or more DNA instances. These are served via [UI Interfaces](./conductor_ui_interfaces.md), which is covered next.
4 |
5 | **Optional**
6 |
7 | ### Properties
8 |
9 | #### `id`: `string`
10 | Give an ID of your choice to this UI Bundle
11 |
12 | #### `root_dir`: `string`
13 | Path to the folder containing the static files to serve
14 |
15 | #### `hash`: `string` Optional
16 | A hash can optionally be provided, which could be used to validate that the UI being installed is the UI bundle that was intended to be installed.
17 |
18 | ### Example
19 | ```toml
20 | [[ui_bundles]]
21 | id = "bundle1"
22 | root_dir = "ui"
23 | ```
24 |
--------------------------------------------------------------------------------
/src/guide/conductor_ui_interfaces.md:
--------------------------------------------------------------------------------
1 | # UI Interfaces
2 | `ui_interfaces` is an array of configurations for "UI Interfaces", meaning there can be multiple within one Conductor. UI Interfaces serve [UI Bundles](./conductor_ui_bundles.md) over HTTP.
3 |
4 | **Optional**
5 |
6 | ### Properties
7 |
8 | #### `id`: `string`
9 | Give an ID of your choice to this UI Interface
10 |
11 | #### `bundle`: `string`
12 | A reference to the given ID of a defined [ui_bundle](./conductor_ui_bundles.md) to serve over this interface
13 |
14 | #### `port`: `u16`
15 | An integer value representing the port on the device to run this interface over. Must not conflict with any of the [interface](./conductor_interfaces.md) ports, nor another UI Interface port.
16 |
17 | #### `dna_interface`: `string` Optional
18 | A reference to the given ID of a defined [interface](./conductor_interfaces.md) this UI is allowed to make calls to. This is used to set the CORS headers and also to provide an extra virtual file endpoint at /_dna_config/ that allows [hc-web-client](https://github.com/holochain/hc-web-client) or another solution to redirect Holochain calls to the correct ip/port/protocol
19 |
20 | ### Example
21 | ```toml
22 | [[ui_interfaces]]
23 | id = "ui-interface-1"
24 | bundle = "bundle1"
25 | port = 3000
26 | dna_interface = "websocket_interface"
27 | ```
--------------------------------------------------------------------------------
/src/guide/conductors.md:
--------------------------------------------------------------------------------
1 | # Running Holochain Apps: Conductors
2 |
3 | To introduce Conductors, it is useful to zoom out for a moment to the level of how Holochain runs on devices.
4 |
5 | Holochain was designed to be highly platform and system compatible. The core logic that runs a DNA instance was written in such a way that it could be included into many different codebases as a library, thus making it easier to build different implementations on the same platform as well as across platforms (MacOSX, Linux, Windows, Android, iOS, and more). Architecturally, Holochain DNAs are intended to be small composable units that provide bits of distributed data integrity functionality. Thus most Holochain based applications will actually be assemblages of many "bridged" DNA instances. For this to work we needed a distinct layer that orchestrates the data flow (i.e. zome function call requests and responses), between the transport layer (i.e. HTTP, Websockets, Unix domain sockets, etc) and the DNA instances. We call the layer that performs these two crucial functions, the *Conductor*, and we have written a `conductor_api` library to make it easy to build actual Conductor implementations.
6 |
7 | Conductors play quite a number of important roles:
8 |
9 | - installing, uninstalling, configuring, starting and stopping instances of DNA
10 | - exposing APIs to securely make function calls into the Zome functions of DNA instances
11 | - accepting information concerning the cryptographic keys and agent info to be used for identity and signing, and passing it into Holochain
12 | - establishing "bridging" between DNA instances
13 | - serving files for web based user interfaces that connect to these DNA instances over the interfaces
14 |
15 | Those are the basic functions of a Conductor, but in addition to that, a Conductor also allows for the configuration of the networking module for Holochain, enables logging, and if you choose to, exposes APIs at a special 'admin' level that allows for the dynamic configuration of the Conductor while it runs. By default, configuration of the Conductor is done via a static configuration file, written in [TOML](https://github.com/toml-lang/toml).
16 |
17 |
18 | In regards to the Zome functions APIs, Conductors can implement a diversity of interfaces to perform these function calls, creating an abundance of opportunity. Another way to build Holochain into an application is to use language bindings from the Rust built version of the Conductor, to another language, that then allows for the direct use of Holochain in that language.
19 |
20 | There are currently three Conductor implementations:
21 | - [Nodejs](./intro_to_holochain_nodejs.md)
22 | - this is built using the language bindings approach, using [neon](https://github.com/neon-bindings/neon)
23 | - [hc run](./development_conductor.md)
24 | - this is a zero config quick Conductor for development
25 | - [`holochain` executable](./production_conductor.md)
26 | - this is a highly configurable sophisticated Conductor for running DNA instances long term
27 |
28 | The articles that follow discuss these different Conductors in greater detail.
29 |
30 | > What is now known as a "Conductor" used to be called a "Container", so if you see the language of Container from other versions know that these refer to the same thing. Fun fact: because this component has such a variety of functions, there was some difficulty in naming it. The word "Conductor" was finally chosen because it actually implies multiple metaphors, each of which resonates with an aspect of what the Conductor does. Like an orchestra conductor, it helps several parts work together as a whole. Like a train conductor, it oversees and instructs how the engine runs. Like an electricity conductor, it allows information to pass through it.
31 |
--------------------------------------------------------------------------------
/src/guide/configuration_alternatives.md:
--------------------------------------------------------------------------------
1 | # Configuration Alternatives
2 |
3 | It is possible to use the same configuration as you would for the [`holochain` Conductor](./production_conductor.md), and pass it to the constructor for `Conductor`. The configuration may be a string of valid TOML, or a JavaScript object with the equivalent structure. To review the configuration, [go here](./intro_to_toml_config.md).
4 |
5 | To see some examples of what these configuration files can look like, you can check out [this folder on GitHub](https://github.com/holochain/holochain-rust/tree/develop/conductor/example-config).
6 |
7 | #### Using a Plain Old Javascript Object
8 |
9 | ```javascript
10 | const { Conductor } = require('@holochain/holochain-nodejs')
11 | const conductor = new Conductor({
12 | agents: [],
13 | dnas: [],
14 | instances: [],
15 | bridges: [],
16 | // etc...
17 | })
18 | ```
19 |
20 | #### Using TOML
21 |
22 | ```javascript
23 | const { Conductor } = require('@holochain/holochain-nodejs')
24 | const toml = `
25 | [[agents]]
26 |
27 |
28 | [[dnas]]
29 |
30 |
31 | [[instances]]
32 | ...etc...
33 | `
34 | const conductor = new Conductor(toml)
35 | ```
36 |
37 |
--------------------------------------------------------------------------------
/src/guide/core_api.md:
--------------------------------------------------------------------------------
1 | # Core API
2 |
--------------------------------------------------------------------------------
/src/guide/creating_versioned_releases.md:
--------------------------------------------------------------------------------
1 | # Creating Versioned Releases
2 |
--------------------------------------------------------------------------------
/src/guide/development_conductor.md:
--------------------------------------------------------------------------------
1 | # Development Conductor
2 |
3 | The easiest Conductor to run is built right into the [development command line tools](./intro_to_command_line_tools.md). It has no required configuration and is launched via the `hc run` command. Meant primarily for accelerating the development process it is useful for testing APIs or prototyping user interfaces. The `hc run` command expects to be executed from inside a directory with valid DNA source files: The command is simply:
4 | ```shell
5 | hc run
6 | ```
7 |
8 | This will start the DNA instance in a Conductor and open, by default, a WebSocket JSON-RPC server on port `8888`. You can find more details on how to use the API in your UI in the [JSON-RPC interfaces article](./json_rpc_interfaces.md).
9 |
10 | The following are the options for configuring `hc run`, should you need something besides the defaults.
11 |
12 | ### Packaging
13 |
14 | `-b`/`--package`
15 |
16 | Package your DNA before running it. Recall that to [package]() is to build the `yourapp.dna.json` file from the source files. `hc run` always looks for a DNA package file in the root of your DNA folder that should have the same name as the directory itself with suffix: `.dna.json`, so make sure that one exists there when trying to use it. `hc run --package` will do this, or run `hc package` beforehand.
17 |
18 | **example**
19 | ```shell
20 | hc run --package
21 | ```
22 |
23 | ### Storage
24 |
25 | `--persist`
26 |
27 | Persist source chain and DHT data onto the file system. By default, none of the data being written to the source chain gets persisted beyond the running of the server. This will store data in the same directory as your DNA source code, in a hidden folder called `.hc`.
28 |
29 | **example**
30 | ```shell
31 | hc run --persist
32 | ```
33 |
34 | ### Interfaces
35 |
36 | `--interface`
37 |
38 | Select a particular JSON-RPC interface to serve your DNA instance over.
39 |
40 | The JSON-RPC interface will expose, via a port on your device, a WebSocket or an HTTP server. It can be used to make function calls to the Zomes of a DNA instance. These are covered in depth in the [JSON-RPC interfaces article](./json_rpc_interfaces.md).
41 |
42 | The default interface is `websocket`.
43 |
44 | **examples**
45 | To run it as HTTP, run:
46 | ```shell
47 | hc run --interface http
48 | ```
49 |
50 | To explicitly run it as WebSockets, run:
51 | ```shell
52 | hc run --interface websocket
53 | ```
54 |
55 | ### Port
56 |
57 | `-p`/`--port`
58 |
59 | Customize the port number that the server runs on.
60 |
61 | **example**
62 | ```shell
63 | hc run --port 3400
64 | ```
65 |
66 | ### Networking
67 |
68 | `--networked`
69 |
70 | Select whether the Conductor should network with other nodes that are running instances of the same DNA. By default this does not occur, instead the instance runs in isolation from the network, allowing only the developer to locally access it.
71 |
72 | This option requires more configuration, which can be read about in the
73 | [configuring networking article](./hc_configuring_networking.md).
74 |
75 | ### Stopping the Server
76 | Once you are done with the server, to quit type `exit` then press `Enter`, or press `Ctrl-C`.
77 |
--------------------------------------------------------------------------------
/src/guide/distributed_hash_table.md:
--------------------------------------------------------------------------------
1 | # Distributed Hash Table
2 |
3 | ## Local Hash Table
4 |
5 | ### implementation details
6 |
7 | First, read about [state actors](/state/actors.html).
8 |
9 | The 1:1 API implementation between actors and their inner table is achieved by
10 | internally blocking on an `ask` from riker patterns.
11 |
12 | https://github.com/riker-rs/riker-patterns
13 |
14 | The actor ref methods implementing `HashTable` sends messages to itself.
15 |
16 | Calling `table_actor_ref.commit(entry)` looks like this:
17 |
18 | 0. the actor ref constructs a `Protocol::PutPair` message including the entry
19 | 0. the actor ref calls its own `ask` method, which builds a future using riker's `ask`
20 | 0. the actor ref blocks on its internal future
21 | 0. the referenced actor receives the `Commit` message and matches/destructures this into the entry
22 | 0. the entry is passed to the `commit()` method of the inner table
23 | 0. the actor's inner table, implementing `HashTable`, does something with commit (e.g. MemTable inserts into a standard Rust, in-memory `HashMap`)
24 | 0. the return value of the inner table `commit` is inserted into a `CommitResult` message
25 | 0. the `CommitResult` message is sent by the actor back to the actor ref's internal future
26 | 0. the actor ref stops blocking
27 | 0. the `CommitResult` message is destructured by the actor ref so that the return of `commit` satisfies the `HashTable` trait implementation
28 |
29 | Riker `ask` returns a future from the futures `0.2.2` crate.
30 |
31 | `table_actor.block_on_ask()` calls `block_on` and `unwrap` against this ask.
32 |
33 | Both the block and the unwrap should be handled better in the future.
34 |
--------------------------------------------------------------------------------
/src/guide/dna.md:
--------------------------------------------------------------------------------
1 | # DNA
2 |
--------------------------------------------------------------------------------
/src/guide/embedding_holochain.md:
--------------------------------------------------------------------------------
1 | # Embedding Holochain
2 |
3 | Core API is a library for embedding a Holochain instance (an hApp) in your own code. So this is for the use case of writing your own software that runs hApps. A common use case might be "glueing" several hApps together or adding centralized services, like file storage, on top of a hApp.
--------------------------------------------------------------------------------
/src/guide/extending_holochain.md:
--------------------------------------------------------------------------------
1 | # Extending Holochain
2 |
--------------------------------------------------------------------------------
/src/guide/glossary.md:
--------------------------------------------------------------------------------
1 | # Glossary
2 |
--------------------------------------------------------------------------------
/src/guide/handling_async.md:
--------------------------------------------------------------------------------
1 | # Handling Asynchronous Network Effects
2 |
3 | In the previous example, we used `alice.call()` to call a zome function. This returns immediately with a value, even though the test network created by the conductor is still running, sending messages back and forth between agents for purposes of validation and replication, etc. In many test cases, you will want to wait until all of this network activity has died down to advance to the next step.
4 |
5 | For instance, take the very common scenario as an example:
6 |
7 | 1. Alice runs a zome function which commits an entry, then adds a link to that entry
8 | 2. Bob runs a zome function which attempt to get links, which should include the link added by alice
9 |
10 | If the test just uses `call()` to call that zome function, there is no guarantee that the entries committed by `alice.call` will be available on the DHT by the time `bob.call` is started. Therefore, two other functions are available.
11 |
12 | **`alice.callSync`** returns a Promise instead of a simple value. The promise does not resolve until network activity has completed.
13 | **`alice.callWithPromise`** is a slightly lower-level version of the same thing. It splits the value apart from the promise into a tuple `[value, promise]`, so that the value can be acted on immediately and the promise waited upon separately.
14 |
15 | ```javascript
16 | // If we make the closure `async`, we can use `await` syntax to keep things cleaner
17 | scenario.run(async (stop, {alice, bob}) => {
18 | tape("test something", t => {
19 | // we can await on `callSync` immediately, causing it
20 | // to block until network activity has died down
21 | const result1 = await alice.callSync('zome', 'do_something_that_adds_links', {})
22 | // now bob can be sure he has access to the latest data
23 | const result2 = bob.call('zome', 'get_those_links', {})
24 | t.equal(result, 'expected value')
25 | // the following two steps were not necessary when using runTape:
26 | t.end() // end the test
27 | stop() // use this injected function to stop the conductor
28 | })
29 | })
30 | ```
31 |
32 | Even though we can't solve the eventual consistency problem in real life networks, we can solve them in tests when we have total knowledge about what each agent is doing.
33 |
--------------------------------------------------------------------------------
/src/guide/hc_configuring_networking.md:
--------------------------------------------------------------------------------
1 | # Configuring Networking for `hc run`
2 |
3 | `hc run` uses mock networking by default and therefore doesn't talk to any other nodes.
4 |
5 | In order to have `hc run` spawn a real network instance, start it with the `--networked` option:
6 | ```shell
7 | hc run --networked
8 | ```
9 |
10 | You should see something like this:
11 | ```shell
12 | Network spawned with bindings:
13 | - ipc: wss://127.0.0.1:64518/
14 | - p2p: ["wss://192.168.0.11:64519/?a=hkYW7TrZUS1hy-i374iRu5VbZP1sSw2mLxP4TSe_YI1H2BJM3v_LgAQnpmWA_iR1W5k-8_UoA1BNjzBSUTVNDSIcz9UG0uaM"]
15 | ...
16 | ```
17 |
18 | ### Starting A Second Node
19 |
20 | Starting up a second node is a little bit more work:
21 |
22 | #### Step 1
23 | Set the `HC_N3H_BOOTSTRAP_NODE` environment variable to the external p2p bound address listed by the first node. Copy-paste it from the string from the terminal log of the first node, the one that starts with "wss://192.168".
24 |
25 | #### Step 2
26 | Specify a different agent id than the first node, by setting the `HC_AGENT` environment variable. Since the first agent by default will be `testAgent`, `testAgent2` is suitable.
27 |
28 | #### Step 3
29 | Specify a different port than the first node to run on. Since the port for the first node by default will be `8888`, `8889` is suitable.
30 |
31 | Running the command could look like this:
32 | ``` shell
33 | HC_AGENT=testAgent2 HC_N3H_BOOTSTRAP_NODE=wss://192.168.0.11:64519/?a=hkYW7TrZUS1hy-i374iRu5VbZP1sSw2mLxP4TSe_YI1H2BJM3v_LgAQnpmWA_iR1W5k-8_UoA1BNjzBSUTVNDSIcz9UG0uaM hc run --port 8889
34 | ```
35 |
36 | In the terminal logs that follow, you should see:
37 | ```shell
38 | (libp2p) [i] QmUmUF..V71C new peer QmeDpQLchA9xeLDJ2jyXBwpe1JaQhFRrnWC2JfyyET2AAM
39 | (libp2p) [i] QmUmUF..V71C found QmeDpQLchA9xeLDJ2jyXBwpe1JaQhFRrnWC2JfyyET2AAM in 14 ms
40 | (libp2p) [i] QmUmUF..V71C ping round trip 37 ms
41 | (libp2p) [i] QmUmUF..V71C got ping, sending pong
42 | ```
43 |
44 | This means that the nodes are able to communicate! Watch the logs for gossip, as you take actions (that alter the source chain) in either node.
45 |
46 |
--------------------------------------------------------------------------------
/src/guide/hcignore_files.md:
--------------------------------------------------------------------------------
1 | # Ignoring Files Using A .hcignore File
2 |
3 | Sometimes, you'll want to exclude files and folders in your project directory to get a straight `.dna.json` file that can be understood by Holochain. In order to do that, just create a `.hcignore` file. It has a similar structure to `.gitignore` files:
4 |
5 | ```
6 | README.md
7 | dist
8 | .DS_Store
9 | ```
10 |
11 | The `hc package` command includes patterns inside `.gitignore` files automatically, so you don't have to write everything twice. Also *hidden* files are ignored by default as well.
12 |
13 | Because `hc package` will attempt to package everything in the directory that is not explicitly ignored, Holochain will return an error if the DNA package is malformed. It is a common mistake to forget to exclude files or folders in the .hcignore file, so that your DNA will be valid.
14 |
--------------------------------------------------------------------------------
/src/guide/intro_to_command_line_tools.md:
--------------------------------------------------------------------------------
1 | # Intro to Command Line Tools
2 |
3 | There are a set of custom-designed tools for working with Holochain that can be installed as utilities to your command line to simplify and accelerate the process of Holochain app development. These command line tools are required if you wish to be able to attempt what you are reading about as you continue through the articles on building an app.
4 |
5 | However, the command line tools are automatically installed when setting up a development environment, as detailed in the [quick start installation guide](https://redux.developer.holochain.org/start.html).
6 |
7 | In addition to the installation instructions, there is also an [architectural overview](https://github.com/holochain/holochain-rust/blob/develop/doc/architecture/README.md) of the different functions of the command line tools. You will also learn these organically just by proceeding through the other articles in this chapter and the ones that follow.
8 |
--------------------------------------------------------------------------------
/src/guide/intro_to_dna_code.md:
--------------------------------------------------------------------------------
1 | # Intro to DNA: Code
2 |
3 | The functionality of Holochain applications is written as a collection of logical modules called "Zomes".
4 |
5 | Zomes are created inside a folder called `zomes`, and each Zome should have its own sub-folder within that, in which the configuration and code for that particular Zome should be placed.
6 |
7 | These Zomes can call and access the functionality of the others, but they are written independently.
8 |
9 | When the DNA file is being packaged, the code for these Zomes is encoded using Base64 encoding and combined with the configuration file associated with the Zome.
10 |
11 | The configuration file should be a JSON file, stored in the Zome folder. The file can be named anything, but the default is `zome.json`.
12 |
13 | This Zome file is extremely simplistic at this point, and contains only a `description` property, which is a human readable property that describes what the Zome is for.
14 |
15 | The only coding language that Holochain knows how to execute is WebAssembly. However, it is unlikely that you'll want to write WebAssembly code by hand. Instead, most people will write their Zomes' code in [a language that can compile to WebAssembly](https://github.com/appcypher/awesome-wasm-langs), such as Rust or Assemblyscript, and then define a build step in which it is compiled to WebAssembly. There is already a large, and growing, number of languages that compile to WebAssembly.
16 |
17 | If this is sounding complex, don't worry. There are tools supplied to make this easy, and you'll be writing in a language that's familiar, or easy to learn.
18 |
19 | With this overview in mind, the details of app development can be explored.
20 |
--------------------------------------------------------------------------------
/src/guide/intro_to_dna_config.md:
--------------------------------------------------------------------------------
1 | # Introduction to DNA: Configuration
2 |
3 | As a developer, you won't have to interact directly with the contents of a DNA file that often. However, it is quite important to grasp its role and structure.
4 |
5 | Holochain DNA files are written in a data format known as JSON. It stores sets of key-value pairs, and allows a nested tree structure. It looks like this:
6 |
7 | ```json
8 | {
9 | "property_name": "property_value",
10 | "nest_name": {
11 | "nested_property_name": "nested_property_value"
12 | }
13 | }
14 | ```
15 |
16 | JSON is usually used for configuration and static data, but in the case of Holochain, these DNA files also contain compiled code, which is executable by Holochain.
17 |
18 | As previously mentioned, you do not need to edit this "main" DNA file directly. Holochain command line tools can be used to build it from your raw files.
19 |
20 | [Learn more about the package command which fulfills this function](https://github.com/holochain/holochain-rust/tree/develop/cli#usage)
21 |
22 | ## Configuration
23 |
24 | For the configuration-related parts of your DNA, they will come from actual JSON files stored in your application folder. There will be multiple JSON files nested in the folder structure. An application folder should have a file in its root called `app.json`.
25 |
26 | This file should define various properties of your application. Some of these properties Holochain fully expects and will not work without, others can be customised to your application.
27 |
28 | ### app.json Properties
29 |
30 | A default `app.json` file looks roughly like this:
31 |
32 | ```json
33 | {
34 | "name": "Holochain App Name",
35 | "description": "A Holochain app",
36 | "authors": [
37 | {
38 | "identifier": "Author Name ",
39 | "public_key_source": "",
40 | "signature": ""
41 | }
42 | ],
43 | "version": "0.0.1",
44 | "dht": {},
45 | "properties": null
46 | }
47 | ```
48 |
--------------------------------------------------------------------------------
/src/guide/intro_to_holochain_nodejs.md:
--------------------------------------------------------------------------------
1 | # Intro to holochain-nodejs
2 |
3 | The purpose of the [holochain-nodejs](https://www.npmjs.com/package/@holochain/holochain-nodejs) module is to make integration tests and scenario tests able to be written simply and with as little boilerplate as possible. However, the module also provides even more basic functionality, making it possible to build tests with whatever tradeoff between convenience and customization is right for your project.
4 |
5 | There are two primary capabilities of the module, which are introduced below.
6 |
7 | ## Simple, Single Node Integration Tests
8 |
9 | The point of this mode of testing is simply to call Zome functions, and ensure that they produce the result you expect. It is discussed further in [calling zome functions](./nodejs_calling_zome_functions.md) and [checking results](./testing_checking_results.md).
10 |
11 | ## Scenario Tests
12 |
13 | The point of this mode of testing is to launch multiple instances, call functions in one, then another, and to ensure that processes involving multiple agents play out as intended. The module conveniently provides a way to sandbox the execution of these scenarios as well, so that you can test multiple without worrying about side effects. This is discussed further in [scenario testing](./scenario_testing.md).
--------------------------------------------------------------------------------
/src/guide/intro_to_testing.md:
--------------------------------------------------------------------------------
1 | # Building Holochain Apps: Testing
2 |
3 | In order to provide a familiar testing framework, a [nodejs](https://nodejs.org) version of the Holochain framework has been compiled using Rust to nodejs bindings. It is called ["holochain-nodejs"](https://www.npmjs.com/package/@holochain/holochain-nodejs) and is a publicly installable package on the NPM package manager for nodejs. It enables the execution of Holochain and DNA instances from nodejs.
4 |
5 | At a basic level, here is how testing the Holochain DNA you are developing works:
6 | - Use the `hc test` command to run a series of steps optimal for testing
7 | - call a JS file containing tests
8 | - In the JS file, import the nodejs Holochain Conductor
9 | - load your packaged DNA into the Conductor, and otherwise configure it
10 | - use exposed methods on the Conductor to make function calls to the DNA
11 | - check that the results are what you expect them to be
12 |
13 | For checking the results, a basic JavaScript test framework called [Tape](https://github.com/substack/tape) has received priority support thus far, but other test frameworks can be used.
14 |
15 | You have the flexibility to write tests in quite a variety of ways, open to you to explore. This chapter will overview how to approach testing Holochain DNA.
--------------------------------------------------------------------------------
/src/guide/intro_to_toml_config.md:
--------------------------------------------------------------------------------
1 | # Intro to TOML Config Files
2 |
3 | To configure the `holochain` Conductor, a configuration file format called TOML is used. It stands for "Tom's Obvious Minimal Language" and was created by Tom Preston-Werner, one of the original founders of GitHub. The [documentation on GitHub](https://github.com/toml-lang/toml) for it is very good.
4 |
5 | `holochain` configuration files make heavy use of [tables](https://github.com/toml-lang/toml#table) and [arrays of tables](https://github.com/toml-lang/toml#array-of-tables).
6 |
7 | A table is actually a collection of key/value pairs, and it looks like this:
8 | ```toml
9 | [table-1]
10 | key1 = "some string"
11 | key2 = 123
12 | ```
13 |
14 | An array of tables looks like this:
15 | ```toml
16 | [[products]]
17 | name = "Hammer"
18 | sku = 738594937
19 |
20 | [[products]]
21 | name = "Nail"
22 | sku = 284758393
23 | color = "gray"
24 | ```
25 | This represents two "product" items in an array.
26 |
27 | In the following articles, how to configure the various properties of the `holochain` Conductor using these will be expanded on. First, knowing how to reference the configuration file for use by `holochain` will be covered below.
28 |
29 | ## `holochain` Config Files
30 |
31 | `holochain` requires a configuration file to run, which must exist in the default location, or be provided as an explicit argument. `holochain` will return an error if neither is given. The default location for the configuration file is in a subdirectory of the HOME directory on a device, at the path:
32 | ```toml
33 | # Unix (Mac & Linux)
34 | $HOME/.holochain/conductor/conductor-config.toml
35 |
36 | # Windows
37 | %HOME%\.holochain\conductor\conductor-config.toml
38 | ```
39 |
40 | When executing `holochain` in a terminal, a path to a configuration file can be given. This can be done with the following option:
41 | ```
42 | --config
43 | ```
44 | or for short
45 | ```
46 | -c
47 | ```
48 |
49 | This could look like:
50 | ```shell
51 | holochain -c ./conductor-config.toml
52 | ```
53 |
54 | > The [holochain-nodejs Conductor](./configuration_alternatives.md) also accepts the same TOML based configuration.
55 |
56 | ## Examples
57 | To jump ahead into what these configuration files can look like, you can check out [this folder on GitHub](https://github.com/holochain/holochain-rust/tree/develop/conductor/example-config) which has a number of examples. Otherwise, read on to understand each part.
58 |
--------------------------------------------------------------------------------
/src/guide/json_rpc_http.md:
--------------------------------------------------------------------------------
1 | # HTTP
2 |
3 | Any coding language, or tool, which can make HTTP requests can make requests to a running DNA instance. Based on the API exposed by Holochain, these must be `POST` requests, use the "application/json" Content-Type, and follow the JSON-RPC standard.
4 |
5 | The HTTP example below will demonstrate how easy it is to make calls to a running DNA instance, just using the cURL tool for HTTP requests from a terminal.
6 |
7 | Any of these methods could be similarly called from whatever client you are using, whether that is JS in the browser, nodejs, Ruby or any other language. For maximum ease of use, we recommend searching for a JSON-RPC helper library for your language of choice, there are lots of good ones out there.
8 |
9 | ## Starting an HTTP Server with `hc run`
10 |
11 | `hc run --interface http`
12 |
13 | ## Starting an HTTP Server with `holochain`
14 |
15 | To review how to start an HTTP Server with `holochain`, review the [interfaces](./conductor_interfaces.md#interfacedrivertype-enum) article.
16 |
17 | ## HTTP Example
18 |
19 | This whole example assumes that one of the methods listed above has been used to start an HTTP server on port 8888 with a valid DNA instance running in it.
20 |
21 | ### info/instances
22 | The following is a starter example, where a special utility function of Holochain is called, which accepts no parameters, and returns an array of the instances which are available on the HTTP server.
23 |
24 | In another terminal besides the server, we could run the following cURL command:
25 | `curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0","id": "0","method": "info/instances"}' http://localhost:8888`
26 |
27 | A response something like the following might be returned:
28 | ```json
29 | {
30 | "jsonrpc": "2.0",
31 | "result": [{"id":"test-instance","dna":"hc-run-dna","agent":"hc-run-agent"}],
32 | "id": "0"
33 | }
34 | ```
35 |
36 | ### Calling Zome Functions
37 |
38 | The following discusses how to use cURL (and thus HTTP generally) to make calls to Zome functions.
39 |
40 | The JSON-RPC "method" to use is simply "call".
41 |
42 | The instance ID (as seen in the `info/instances` example), the Zome name, and the function name all need to be given as values in the "params" value of the JSON-RPC, in addition to the arguments to pass that function. This part of the "params" object might look like this:
43 | `{"instance_id": "test-instance", "zome": "blog", "function": "create_post"}`
44 |
45 | Unlike `info/instances`, Zome functions usually expect arguments. To give arguments, a JSON object should be constructed, and given as `"args"` key of the "params" value. It may look like the following:
46 | `"args": {"content": "sample content"}`
47 |
48 | Combining these, a request like the following could be made via cURL from a terminal:
49 | `curl -X POST -H "Content-Type: application/json" -d '{"id": "0", "jsonrpc": "2.0", "method": "call", "params": {"instance_id": "test-instance", "zome": "blog", "function": "create_post", "args": { "content": "sample content"} }}' http://127.0.0.1:8888`
50 |
51 | A response like the following might be returned:
52 | ```json
53 | {
54 | "jsonrpc": "2.0",
55 | "result": "{\"Ok\":\"QmUwoQAtmg7frBjcn1GZX5fwcPf3ENiiMhPPro6DBM4V19\"}",
56 | "id": "0"
57 | }
58 | ```
59 |
60 | This response suggests that the function call was successful ("Ok") and provides the DHT address of the freshly committed blog entry ("QmU...").
61 |
62 | This demonstrates how easy it is to call into Zome function from clients and user interfaces!
63 |
--------------------------------------------------------------------------------
/src/guide/json_rpc_interfaces.md:
--------------------------------------------------------------------------------
1 | # Intro to JSON-RPC Interfaces
2 |
3 | The JSON-RPC interface will expose, via a port on your device, a WebSocket or an HTTP server, via which you can make function calls to the Zomes of your DNA.
4 |
5 | ## JSON-RPC
6 | JSON-RPC is a specification for using the JSON data format in a particular way, that follows the ["Remote Procedure Call"](https://en.wikipedia.org/wiki/Remote_procedure_call) pattern. Holochain uses the [Version 2 specification](https://www.jsonrpc.org/specification) of JSON-RPC. You can see general examples of JSON-RPC [here](https://www.jsonrpc.org/specification#examples).
7 |
8 | The format for the JSON-RPC request/response pattern is really simple. A request is a JSON object with just a few mandatory values which must be passed.
9 |
10 | `jsonrpc`: specifies the JSON-RPC spec this request follows. The JSON-RPC spec used by Holochain Conductors is `2.0`.
11 |
12 | `id`: specifies the ID for this particular request. This is so that the request and response can be matched, even if they get transmitted out of order.
13 |
14 | `method`: specifies the method on the "remote" (Holochain) to call.
15 |
16 | `params`: (optional) contains a JSON object which holds the data to be given as arguments to the method being called, if the method expects them.
--------------------------------------------------------------------------------
/src/guide/keys.md:
--------------------------------------------------------------------------------
1 | # Keys
2 |
--------------------------------------------------------------------------------
/src/guide/lifecycle_of_an_entry.md:
--------------------------------------------------------------------------------
1 | # Lifecycle of an Entry
2 |
3 | ## Commit
4 |
5 | ```
6 | New entry
7 | Validate commit
8 | Commit to source chain
9 | ```
10 |
11 | Entries must be committed to the local source chain before they can be broadcast
12 | to the DHT.
13 |
14 | Every entry must pass a ValidateCommit lifecycle function check before it can be
15 | committed.
16 |
17 | If ValidateCommit is not implemented for the zome committing the entry then this
18 | is treated as a pass and the entry will be committed.
19 |
--------------------------------------------------------------------------------
/src/guide/links/get_links.md:
--------------------------------------------------------------------------------
1 | # Get Links
2 | Get Links allows the zome developer to query links from the DHT. The call accepts an options parameter to customize the query behavior. The parameters of the get_links are :
3 |
4 | `base` : address of the entry on which to query for links
5 | `LinkType Link Match` : a match enum which is either a regex or an exact match specifier on link_type
6 | `Tag Link Match` : a match enum which is either a regex or an exact match specifier on link's tag
7 | `Options` : a struct (see below) that you can use to specify different options to apply when executing the query.
8 |
9 | # Options
10 | `Timeout` : The timeout variable on the options specifies how long the query process should wait befor a response before it timesout
11 | `LinksStatusRequest` : This is a variable in which you can specify 3 modes, `All`,`Live`,`Delete`. This allows you to query the links based on crud_status in which `All` will return everything will `Live` will only return live links and `Delete` as such.
12 | `Headers`: boolean value which if set to true indicates that the link headers should also be returned.```
13 |
14 |
15 | # Link Results
16 |
17 | A successful get_links call returns a set of links [(base,link_type,tag,target)] as well as meta data associated with it which is the headers and crud_status if requested in the `Options`.
18 |
19 |
--------------------------------------------------------------------------------
/src/guide/links/links_entries.md:
--------------------------------------------------------------------------------
1 | # Links Entries
2 |
3 | A link consists of 4 parts :
4 | `Base` - the address of the entry on which the links will be stored in the DHT.
5 | `Link Type` - a String that corresponds to a value that we would use to give the link a type
6 | `Tag` - an arbitrary string which can be added to link when it is created. This s accessible to the validation callback and can be used when retrieving links to filter by regex.
7 | `Target` - that address of the entry to be linked to from the base
8 |
9 | The process of `linking` in holochain is done through the `link_entries` function in the HDK, this will allow the zome developer to connect different kinds of data. All data that is linked is stored in our `EAV storage`(see holochain-persistance-api for more details on how this works). The `EAV` is the backbone of our storage mechanism when it comes to our linking process and addition and retrival of links is done using it.
10 |
11 | # Validation
12 |
13 | `System Validation`
14 | They are two layers of validation when it comes to linking. One layer happens at the system level and this executes every time a link is added and uses validation rules which are defined by the system. The primary validation is to ensure that the base address exists. Since this corresponds to real data on the DHT we have to make sure that the hash we are giving it is correct and corresponds to something.
15 |
16 | `Zome Validation`
17 | Links also allow for the Zome Developer to define what rules to be checked before a link will be added to the DHT. The Zome Developer can define these rules by utilizing the `LinkValidationData` parameter in the link validation section of the zome. The Link Validation Data exposes the link data through an enum as well as lifecycle and package data.
18 |
19 |
--------------------------------------------------------------------------------
/src/guide/links/remove_link.md:
--------------------------------------------------------------------------------
1 | # Remove Link
2 |
3 | `Recommended` : read link_entries documentation before reading this documentation.
4 |
5 | Remove Link is the process of marking a link as deleted in the DHT. For this process to happen, the remove_link first has to get all like hashes that share the same base,tag,link type and target. The remove link process will then mark all of these links as deleted in the process. The reason for this is that links that share the same base, tag, link_type and target do not necesarrily produce the same link hash. In order for the delete to work all corresponding link hashes would have to be marked as deleted in the DHT
6 | # Validation
7 |
8 | `System Validation`
9 |
10 | A system validation also takes place when a remove_link is executed. Before a remove_link is executed, we have to make sure that the link base address exists. This takes place in the system validation, after the system validation is complete, zome validation runs, see below.
11 |
12 | `Zome Validation`
13 |
14 | A Zome Validation always takes place on each remove_link that is executed after it passes the system validation. These are rules that can be defined by the zome. Thus, the Zome Developer can choose approve link deletion using their defined criteria.
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/guide/live_hc_apps.md:
--------------------------------------------------------------------------------
1 | # Going Live with Holochain Apps
2 |
--------------------------------------------------------------------------------
/src/guide/managing_the_conductor.md:
--------------------------------------------------------------------------------
1 | # Managing the Conductor
2 |
3 | `Conductor` is a class that is exported from `holochain-nodejs`, and can be imported into your code.
4 | It is mostly used internally in the library, but can be useful in some of your own use cases.
5 |
6 | #### Import Example
7 | ```javascript
8 | const { Conductor } = require('@holochain/holochain-nodejs')
9 | ```
10 |
11 | ## Simple Use
12 |
13 | ### `Conductor.run(conductorConfig, runner)` => `Promise`
14 |
15 | Spin up a Conductor with a [Conductor configuration](./testing_configuration.md). When you're done with it, call `stop`, a function injected into the closure.
16 |
17 | ___
18 | **Name** conductorConfig
19 |
20 | **Type** `string` or `object`
21 |
22 | **Description** should be a TOML configuration string, as described [here](./configuration_alternatives.md) or an equivalent JavaScript object constructed manually, or setup using the `Config` helper functions described [here](./testing_configuration.md).
23 | ___
24 | **Name** runner
25 |
26 | **Type** `function`
27 |
28 | **Description** `runner` is a closure: (stop, conductor) => { (code to run) }
29 | - `stop` is a function that shuts down the Conductor and must be called in the closure body
30 | - `conductor` is a Conductor instance, from which one can make [Instances](./nodejs_instances.md) and thus Zome calls.
31 | ___
32 |
33 | #### Example
34 | ```javascript
35 | // ...
36 | Conductor.run(Config.conductor([
37 | instanceAlice,
38 | instanceBob,
39 | instanceCarol,
40 | ]), (stop, conductor) => {
41 | doStuffWith(conductor)
42 | stop()
43 | })
44 | ```
45 |
46 | ## Manually Instantiating a Conductor
47 |
48 | ### `constructor(conductorConfig)` => `Conductor`
49 |
50 | Instantiate a Conductor with a full [Conductor configuration](./testing_configuration.md).
51 |
52 | ___
53 | **Name** conductorConfig
54 |
55 | **Type** `string` or `object`
56 |
57 | **Description** should be a TOML configuration string, as described [here](./configuration_alternatives.md) or an equivalent JavaScript object constructed manually, or setup using the `Config` helper functions described [here](./testing_configuration.md).
58 | ___
59 |
60 | #### Example
61 | ```javascript
62 | // config var can be defined using the Config helper functions
63 | const conductor = new Conductor(config)
64 | ```
65 |
66 | ## Manually Starting and Stopping a Conductor
67 |
68 | ### `conductor.start()` => null
69 |
70 | Start running all instances. No Zome functions can be called within an instance if the instance is not started, so this must be called beforehand.
71 |
72 | #### Example
73 | ```javascript
74 | conductor.start()
75 | ```
76 |
77 | ### `conductor.stop()` => `Promise`
78 |
79 | Stop all running instances configured for the conductor. This function **should** be called after all desired Zome calls have been made, otherwise the conductor instances will continue running as processes in the background.
80 |
81 | Returns a Promise that you can optionally wait on to ensure that internal cleanup is complete.
82 |
83 | #### Example
84 | ```javascript
85 | conductor.stop()
86 | ```
87 |
--------------------------------------------------------------------------------
/src/guide/meta/version.md:
--------------------------------------------------------------------------------
1 | # Version
2 | You are able to call `hdk::version()` on the hdk and it is able to tell you which version of the hdk you are using. This information is based on the last tag that was applied to the holochain release and corresponds with our releases. The basis of this information comes from a `git describe` command.
--------------------------------------------------------------------------------
/src/guide/naming_conventions.md:
--------------------------------------------------------------------------------
1 | # Naming things
2 |
3 | > There are only two hard things in Computer Science: cache invalidation and naming things.
4 |
5 | ## Rust naming conventions
6 |
7 | If in doubt refer to the Rust conventions.
8 |
9 | https://doc.rust-lang.org/1.0.0/style/style/naming/README.html
10 |
11 | ## Holochain naming conventions
12 |
13 | There are gaps where the Rust conventions are either silent or following them
14 | would make things too ambiguous.
15 |
16 | ### Actions & reducers
17 |
18 | - `Action` is `VerbNoun` or `Verb` if there is no available noun and matches the underlying function e.g. `GetEntry`
19 | - `ActionResponse` is `ActionName` e.g. `Action::QueryEntry` results in `ActionResponse::GetEntry`
20 | - reducer name is `reduce_action_name` e.g. `reduce_get_entry`
21 |
22 | ### Actors & protocols
23 |
24 | - Actor `Protocol` is `VerbNoun` or `Verb` if there is no available noun and matches the underlying function e.g. `PutEntry` or `Setup`
25 | - Result of a `Protocol` is `VerbNounResult` or `VerbResult` e.g. `PutEntryResult` or `SetupResult`
26 |
27 | ### Method names
28 |
29 | - method names that access something directly "for free" are the name of the thing being accessed, e.g. `entry()`
30 | - method names that have side effects or an expensive lookup are `verb_noun()` e.g. `put_entry()`
31 |
32 | ### Short names
33 |
34 | avoid micro names like `t`, `e`, `h` when `table`, `entry`, `header` is clearer.
35 |
36 | avoid shorthand names like `table` when `table_actor` is clearer.
37 |
38 | in the long run the legibility and unambiguity saves orders of magnitude more time than the typing costs.
39 |
--------------------------------------------------------------------------------
/src/guide/new_project.md:
--------------------------------------------------------------------------------
1 | # Create A New Project
2 |
3 | The command line tools discussed in the last article can be used to easily create a new folder on your computer, that contains all the initial folders and files needed for a Holochain application.
4 |
5 | You will typically want to create a new project folder for a Holochain application this way. This one approach will suit the creation of a new Holochain app or implementing an existing app with Holochain instead.
6 |
7 | In your terminal, change directories to one where you wish to initialize a new Holochain app. The command will create a new folder within the current directory for your app.
8 |
9 | Come up with a name for your application, or at least for your project folder.
10 |
11 | Copy or type the command below into your terminal, except replace `your_app_name` with the name you came up with. Press `Enter` to execute the command.
12 |
13 | Again, make sure you have followed the [quick start guide](https://redux.developer.holochain.org/start.html).
14 |
15 | ```shell
16 | $ nix-shell https://github.com/holochain/holonix/archive/release-0.0.85.tar.gz
17 | # snip
18 | [nix-shell:~]$ hc init your_app_name
19 | Created new Holochain project at: "your_app_name"
20 | ```
21 |
22 | `hc` specifies that you wish to use the Holochain command line tools. `init` specifies to use the command for initializing a new project folder. `your_app_name` is an argument you supply as the app, and folder name.
23 |
24 | This has created a new folder in which you have the beginnings of a Holochain app.
25 |
26 | Check out the next article to see what the contents of a DNA source code folder looks like.
27 |
--------------------------------------------------------------------------------
/src/guide/nodejs_calling_zome_functions.md:
--------------------------------------------------------------------------------
1 | # Calling Zome Functions
2 |
3 | ### `dnaInstance.call(zomeName, functionName, callParams)` => `object`
4 |
5 | A `DnaInstance` can use the `Conductor` in which it's running to make calls to the custom functions defined in its Zomes.
6 | This is necessary in order to be able to test them. It calls synchronously and returns the result that the Zome function provides. An error could also be thrown, or returned.
7 |
8 | Note that Holochain has to serialize the actual arguments for the
9 | function call into JSON strings, which the Conductor will handle for you automatically. It also parses the result from a JSON string into an object.
10 |
11 | This function will only succeed if `conductor.start()` has been called for the Conductor in which the DnaInstance is running.
12 | ___
13 | **Name** zomeName
14 |
15 | **Type** `string`
16 |
17 | **Description** The name of the Zome within that instance being called into
18 | ___
19 | **Name** functionName
20 |
21 | **Type** `string`
22 |
23 | **Description** The name of the custom function in the Zome to call
24 | ___
25 | **Name** callParams
26 |
27 | **Type** `object`
28 |
29 | **Description** An object which will get stringified to a JSON string, before being passed into the Zome function. The keys of this object must match one-to-one with the names of the arguments expected by the Zome function, or an error will occur.
30 | ___
31 |
32 | #### Example
33 | ```javascript
34 | // ...
35 | scenario.runTape("test something", (t, runner) => {
36 | const alice = runner.alice
37 | // scenario.run and scenario.runTape both inject instances
38 | const callResult = alice.call('people', 'create_person', {name: 'Franklin'})
39 | })
40 | ```
41 |
42 | > Note that there are some cases where, for the purposes of testing, you may wish to wait for the results of calling a
43 | function in one instance, in terms of chain actions like commits and linking, to propogate to the other instances. For this,
44 | extra ways of performing calls have been added as utilities. Check them out in [handling asynchronous network effects](./handling_async.md).
45 |
46 |
--------------------------------------------------------------------------------
/src/guide/nodejs_dna_instances.md:
--------------------------------------------------------------------------------
1 | # DNA Instances
2 |
3 | `DnaInstance` is a class that is exported from `holochain-nodejs` and can be imported into your code.
4 | This class is used externally and instances of it are built automatically for you to use, so you typically should not have to construct a `DnaInstance` yourself.
5 |
6 | A `DnaInstance` represents a running version of a DNA package by a particular agent. This means that the agent has a source chain for this DNA.
7 | In addition to these basic properties on a DnaInstance that are covered below, the following articles cover [how to make function calls into the Zomes](./nodejs_calling_zome_functions.md).
8 |
9 | #### Import Example
10 | ```javascript
11 | const { DnaInstance } = require('@holochain/holochain-nodejs')
12 | ```
13 |
14 | ## Instantiate A DnaInstance
15 |
16 | ### `constructor(instanceId, conductor)` => `DnaInstance`
17 |
18 | Instantiate a `DnaInstance` based on an instanceId, and the conductor where an instance with that id is running.
19 | Calling this manually is not typically necessary, since the `Scenario` testing returns these natively.
20 | A `DnaInstance` can make calls via that Conductor into Zome functions.
21 |
22 | ___
23 | **Name** instanceId
24 |
25 | **Type** `string`
26 |
27 | **Description** The instance id of the DnaInstance as specified in the configuration of `conductor`.
28 | Note that when using the [Config.instance](./testing_configuration.md#instances) helper, the instance ID defaults to the agent name (as specified in [Config.agent](./testing_configuration.md#agents)) if not explicitly passed as a third argument.
29 | ___
30 | **Name** conductor
31 |
32 | **Type** `Conductor`
33 |
34 | **Description** A valid, and running Conductor instance
35 | ___
36 |
37 | #### Example
38 | ```javascript
39 |
40 | const aliceInstance = new DnaInstance('alice', conductor)
41 | ```
42 |
43 | ## DnaInstance Attributes
44 |
45 | ### `dnaInstance.agentId`
46 |
47 | The agentId for an instance.
48 |
49 | #### Example
50 | ```javascript
51 | console.log(alice.agentId)
52 | // alice-----------------------------------------------------------------------------AAAIuDJb4M
53 | ```
54 |
55 | ### `dnaInstance.dnaAddress`
56 |
57 | The address of the DNA for an instance.
58 |
59 | #### Example
60 | ```javascript
61 | console.log(alice.dnaAddress)
62 | // QmYiUmMEq1WQmSSjbM7pcLCy1GkdkfbwH5cxugGmeNZPE3
63 | ```
64 |
--------------------------------------------------------------------------------
/src/guide/nodejs_instances.md:
--------------------------------------------------------------------------------
1 | # Instances
2 |
--------------------------------------------------------------------------------
/src/guide/other_test_harnesses.md:
--------------------------------------------------------------------------------
1 | # Other Test Harnesses
2 |
3 | Only [tape](https://github.com/substack/tape) is currently supported as a fully integrated test harness, but you can also run tests with more manual control using `scenario.run`. Using `run` allows you to manage the test yourself, only providing you with the basic help of starting and stopping a fresh Conductor instance.
4 |
5 | The example does still use `tape` to show how it compares to using `runTape`, but it could use any test harness, like Jest or Mocha. In fact, `runTape` simply calls `run` internally.
6 |
7 | ### `scenario.run(runner)` => `null`
8 |
9 | Each invocation of `scenario.run` does the following:
10 |
11 | 1. Starts a fresh Conductor based on the configuration used to construct `scenario`
12 | 2. Injects the values needed for the test into a closure you provide
13 |
14 | ___
15 | **Name** runner
16 |
17 | **Type** `function`
18 |
19 | **Description** `runner` is a closure: `(stop, runner) => { (code to run) }`.
20 | - `stop` is a function that shuts down the Conductor and must be called in the closure body
21 | - `runner` is an object containing an interface into each Instance specified in the config. The Instances are keyed by "name", as taken from the optional third parameter of [Config.instance](./testing_configuration.md#instances), which itself defaults to what was given in [Config.agent](./testing_configuration.md#agents).
22 | ___
23 |
24 | #### Example
25 | This example does also use `tape` as an illustration, but each test harness would have its own particular way
26 | ```javascript
27 | const tape = require('tape')
28 |
29 | // Create a scenario object in the same fashion as in other examples
30 | const scenario = new Scenario([instanceAlice, instanceBob])
31 |
32 | // scenario.run only manages the Conductor for us now, but we have to manage the test itself
33 | scenario.run((stop, runner) => {
34 | const alice = runner.alice
35 | const bob = runner.bob
36 | tape("test something", t => {
37 | const result = alice.call('zome', 'function', {params: 'go here'})
38 | t.equal(result, 'expected value')
39 | // the following two steps were not necessary when using runTape:
40 | t.end() // end the test
41 | stop() // use this injected function to stop the conductor
42 | })
43 | })
44 |
45 | // This example uses destructuring to show a clean and simple way to get the Instances
46 | scenario.run((stop, {alice, bob}) => {
47 | tape("test something else", t => {
48 | // write more tests in the same fashion
49 | t.equal(2 + 2, 4)
50 | t.end()
51 | stop() // but don't forget to stop the conductor when it's done!
52 | })
53 | })
54 | ```
55 |
--------------------------------------------------------------------------------
/src/guide/overview.md:
--------------------------------------------------------------------------------
1 | # Overview
2 |
3 | Depending on whether your interest is specific, or general, you may wish to read it front to back, or skip to specific sections of the book. If the summary of a section describes you, then it's a section for you!
4 |
5 | ### Planning a dApp
6 | **Readers:** You can't put the horse before the cart. First things first: understanding the landscape of decentralized apps. What are the mechanics of a functioning decentralized app? You have an idea of what you want to build, and you need to get a grasp on what it's going to take. You need to know what your blind spots are, and what are the common pitfalls. You need to know which of your assumptions to hold on to, and which to let go.
7 |
8 | **Writing:** General Audience
9 |
10 | ### Building Holochain Apps
11 |
12 | **Readers:** Whether you're a seasoned developer, or just starting out, you're in it to write code. You've either got an app project (or five) on the go, or you're in it to experiment and test the limits. You need to know what you need to know. You want to talk Holochain's language. You're an intrepid explorer of technical documentation.
13 |
14 | **Writing:** Technical, Explanatory & How-to
15 |
16 | ### Going Live with Holochain Apps
17 |
18 | **Readers:** You're involved in the conception, development, or design of a Holochain app, and you've got to know how to get your app out into the world, into the hands of the people who need it. You've got questions like "How do updates to the app work?", "How do I track performance of the app?", "What are best practices for security?"
19 |
20 | **Writing:** General Audience
21 |
22 | ### Extending the Holochain Platform
23 |
24 | **Readers:** You want to look at Holochain itself, not what you can build with it, but to see what you can tweak, or contribute. You've got ideas for Holochain and got skills to pull them off. You're reading the Holochain source code, or source documentation. Maybe you want to enable app development in a whole other language not available yet, or maybe to run Holochain on a device or platform not supported yet. You can make sense of terse technical language, and direct yourself well.
25 |
26 | **Writing:** Technical, Explanatory & How-to
27 |
28 |
29 |
--------------------------------------------------------------------------------
/src/guide/packaging.md:
--------------------------------------------------------------------------------
1 | # Building Holochain Apps: Packaging
2 |
3 | The `hc package` command will automate the process of compiling your Zome code, encoding it, and inserting into the `.dna.json` file. In order to get these benefits, you just need to make sure that you have the right compilation tools installed on the machine you are using the command line tools from, and that you have the proper configuration files in your Zome folders.
4 |
5 | `hc package` works with two special files called [`.hcignore` files](./hcignore_files.md) and [`.hcbuild` files](./build_files.md).
6 |
--------------------------------------------------------------------------------
/src/guide/production_conductor.md:
--------------------------------------------------------------------------------
1 | # Production Conductor
2 |
3 | In addition to the zero config development Conductor using `hc run`, there is a highly configurable sophisticated Conductor for running DNA instances long term.
4 |
5 | This Conductor will play an important role in making the use of Holochain truly easy for end users, because it supports all the functionality that those users are likely to want, in terms of managing their Holochain apps, or hApps, just on a low level. On that note, a graphical user interface that exposes all the functionality of this Conductor to users is under development.
6 |
7 | For now, use of this Conductor must happen mostly manually, and by tech-savvy users or developers.
8 |
9 | This Conductor is simply a command line tool called `holochain`. Its only function is to boot a Conductor based on a configuration file, and optionally, the ability to write changes back to that file. Within that Conductor many DNA instances can be run for one or more agents, multiple types of interfaces to the APIs can be exposed, UI file bundles can be served, and logs from all of that can be accessed.
10 |
11 | The first step to using `holochain` is of course installing it. Instructions for installation can be found in its [README](https://github.com/holochain/holochain-rust/tree/develop/conductor#install). If you wish to attempt any of the things you read in this chapter while going through it, you will need to have installed the executable.
12 |
13 | Like Holochain core, this particular Conductor is written in Rust. View it on GitHub [here](https://github.com/holochain/holochain-rust/tree/develop/conductor).
14 |
15 | To understand how to configure the `holochain` Conductor, check out the [next article](./intro_to_toml_config.md).
16 |
--------------------------------------------------------------------------------
/src/guide/project_source_folders.md:
--------------------------------------------------------------------------------
1 | # Project Source Folders
2 |
3 | The source code folder for a Holochain DNA project looks something like this, where the ellipses (...) indicate a folder
4 | - test
5 | - ...
6 | - zomes
7 | - ...
8 | - .gitignore
9 | - .hcignore
10 | - app.json
11 |
12 | `test` contains some starter code for writing tests.
13 |
14 | `zomes` will contain sub-folders, each of which represents a "Zome", which can be thought of as a submodule of the source code of your DNA.
15 |
16 | `.gitignore` contains useful defaults for ignoring files when using GIT version control.
17 |
18 | `.hcignore` is utilized by the packaging commands of the `hc` command line tools
19 |
20 | `app.json` is the top level configuration of your DNA.
21 |
22 | Carry on to the next article to see about making changes to the configuration of a new project.
23 |
24 |
--------------------------------------------------------------------------------
/src/guide/running_tests.md:
--------------------------------------------------------------------------------
1 | # Running Tests
2 |
3 | By default, when you use `hc init` to [create a new project folder](./new_project.md), it creates a sub-directory called `test`. The files in that folder are equipped for testing your project. The contents of the folder represent a simple nodejs package (in that they have a `index.js` file and a `package.json` file).
4 |
5 | Tools to help with testing are also built right into the [development command line tools](./intro_to_command_line_tools.md).
6 |
7 | ## hc test
8 |
9 | Once you have a project folder initiated, you can run `hc test` to execute your tests. This combines the following steps:
10 | 1. Packaging your files into a DNA file, located at `dist/your.dna.json`. This step will fail if your packaging step fails.
11 | 2. Installing build and testing dependencies, if they're not installed (`npm install`)
12 | 3. Executing the test file found at `test/index.js` (`node test/index.js`)
13 |
14 | The tests can of course be called manually using nodejs, but you will find that using the convenience of the `hc test` command makes the process much smoother, since it includes the packaging step for when you change the DNA source files.
15 |
16 | `hc test` also has some configurable options.
17 |
18 | If you want to run it without repackaging the DNA, run it with
19 | ```shell
20 | hc test --skip-package
21 | ```
22 |
23 | If your tests are in a different folder than `test`, run it with
24 | ```shell
25 | hc test --dir tests
26 | ```
27 | where `tests` is the name of the folder.
28 |
29 | If the file you wish to actually execute is somewhere besides `test/index.js` then run it with
30 | ```shell
31 | hc test --testfile test/test.js
32 | ```
33 | where `test/test.js` is the path of the file.
34 |
--------------------------------------------------------------------------------
/src/guide/scenario_testing.md:
--------------------------------------------------------------------------------
1 | # Scenario Testing
2 |
3 | `Scenario` is a class that is exported from `holochain-nodejs` and can be imported into your code.
4 | It can be used to run tests individually for a single node, or to orchestrate multi-node tests, which is why it
5 | is called `Scenario`. It does all the work of starting and stopping conductors and integrating with various test harnesses.
6 |
7 | #### Import Example
8 | ```javascript
9 | const { Scenario } = require('@holochain/holochain-nodejs')
10 | ```
--------------------------------------------------------------------------------
/src/guide/scenario_testing_running_tape.md:
--------------------------------------------------------------------------------
1 | ## Run Tests With Tape
2 |
3 | ### `scenario.runTape(description, runner)` => `null`
4 |
5 | Each invocation of `scenario.runTape` does the following:
6 |
7 | 1. Starts a fresh Conductor based on the configuration used to construct `scenario`
8 | 2. Starts a new `tape` test
9 | 3. Injects the values needed for the test into a closure you provide
10 | 4. Automatically ends the test and stops the conductor when the closure is done running
11 |
12 | It will error if you have not called [Scenario.setTape](./scenario_testing_setup.md#scenariosettapetape--null) first.
13 |
14 | ___
15 | **Name** description
16 |
17 | **Type** `string`
18 |
19 | **Description** Will be used to initialize the tape test, and should describe that which is being tested in this scenario
20 | ___
21 | **Name** runner
22 |
23 | **Type** `function`
24 |
25 | **Description** `runner` is a closure: `(t, runner) => { (code to run) }`. When this function ends, the test is automatically ended, and the inner Conductor is stopped.
26 | - `t` is the object that tape tests use
27 | - `runner` is an object containing an interface into each Instance specified in the config. The Instances are keyed by "name", as taken from the optional third parameter of [Config.instance](./testing_configuration.md#instances), which itself defaults to what was given in [Config.agent](./testing_configuration.md#agents).
28 | ___
29 |
30 | #### Example
31 | ```javascript
32 | scenario.runTape("test something", (t, runner) => {
33 | const alice = runner.alice
34 | const bob = runner.bob
35 | // fire zome function calls from both agents
36 | const result1 = alice.call('zome', 'function', {params: 'go here'})
37 | const result2 = bob.call('zome', 'function', {params: 'go here'})
38 | // make some tape assertions
39 | t.ok(result1)
40 | t.equal(result2, 'expected value')
41 | })
42 |
43 | // Run another test in a freshly created Conductor
44 | // This example uses destructuring to show a clean and simple way to get the Instances
45 | scenario.runTape("test something else", (t, {alice, bob}) => {
46 | // write more tests in the same fashion
47 | })
48 | ```
49 |
50 |
51 |
--------------------------------------------------------------------------------
/src/guide/scenario_testing_setup.md:
--------------------------------------------------------------------------------
1 | # Scenario Testing Setup
2 |
3 | ### `constructor(instancesArray, conductorOptions)` => `Scenario`
4 |
5 | Instantiate a Scenario with an array of instance configurations and some optional configuration overrides. Note that this function
6 | has the same signature as [Config.conductor](./testing_configuration.md#full-conductor-configuration).
7 |
8 | ___
9 | **Name** instancesArray
10 |
11 | **Type** `array`
12 |
13 | **Description** Pass in an array of instance configuration objects generated by [Config.instance](./testing_configuration.md#instances) to have them within the
14 | final configuration to be instantiated by the Conductor
15 | ___
16 | **Name** conductorOptions *Optional*
17 |
18 | **Type** `object`
19 |
20 | **Description** *conductorOptions.debugLog* `boolean` Enables debug logging. The logger produces nice, colorful output of the internal workings of Holochain.
21 |
22 | **Default** `{ debugLog: false }`
23 | ___
24 |
25 | #### Example
26 | ```javascript
27 | const dna = Config.dna("path/to/happ.dna.json")
28 | const instanceAlice = Config.instance(Config.agent("alice"), dna)
29 | const instanceBob = Config.instance(Config.agent("bob"), dna)
30 | const scenario = new Scenario([instanceAlice])
31 | ```
32 |
33 | #### With conductorOptions Example
34 | ```javascript
35 | const dna = Config.dna("path/to/happ.dna.json")
36 | const instanceAlice = Config.instance(Config.agent("alice"), dna)
37 | const instanceBob = Config.instance(Config.agent("bob"), dna)
38 | const scenario = new Scenario([instanceAlice], { debugLog: true })
39 | ```
40 |
41 | ## Inject Tape Version
42 |
43 | ### `Scenario.setTape(tape)` => `null`
44 |
45 | `setTape` should be called prior to usage of the `Scenario` class, if you intend to use `tape` as your testing framework. It sets a reference internally to the version of tape, since there are many variations, that you wish to use. It is used in conjunction with [Scenario.runTape](./scenario_testing_running_tape.md).
46 |
47 | ___
48 | **Name** tape
49 |
50 | **Type** `object`
51 |
52 | **Description** A reference to the imported `tape` package you wish to use as your test framework.
53 | ___
54 |
55 | #### Example
56 | ```javascript
57 | const { Config, Scenario } = require('@holochain/holochain-nodejs')
58 |
59 | Scenario.setTape(require('tape'))
60 | ```
61 |
62 | ## Full Multiple Instances Example
63 | The following example shows the simplest, most convenient way to start writing scenario tests with this module. We'll set up an environment for running tests against two instances of one DNA, using the [tape](https://github.com/substack/tape) test harness:
64 | ```javascript
65 | const { Config, Scenario } = require('@holochain/holochain-nodejs')
66 |
67 | Scenario.setTape(require('tape'))
68 |
69 | // specify two agents...
70 | const agentAlice = Config.agent("alice")
71 | const agentBob = Config.agent("bob")
72 | // ...and one DNA...
73 | const dna = Config.dna("path/to/happ.dna.json")
74 | // ...then make instances out of them...
75 | const instanceAlice = Config.instance(agentAlice, dna)
76 | const instanceBob = Config.instance(agentBob, dna)
77 |
78 | // Now we can construct a `scenario` object which lets us run as many scenario tests as we want involving the two instances we set up:
79 | const scenario = new Scenario([instanceAlice, instanceBob])
80 | ```
81 |
--------------------------------------------------------------------------------
/src/guide/source_chain.md:
--------------------------------------------------------------------------------
1 | # Source Chain
2 |
--------------------------------------------------------------------------------
/src/guide/state/actions.md:
--------------------------------------------------------------------------------
1 | @TODO
2 | @see https://github.com/holochain/holochain-rust/issues/176
3 |
--------------------------------------------------------------------------------
/src/guide/state/actors.md:
--------------------------------------------------------------------------------
1 | # Internal actors
2 |
3 | Actors are discussed in two contexts:
4 |
5 | - Each Holochain agent as an actor in a networking context
6 | - Riker actors as an implemenation detail in the Holochain core lib
7 |
8 | This article is about the latter.
9 |
10 | ## Actor model
11 |
12 | The [actor model](https://en.wikipedia.org/wiki/Actor_model) is a relatively safe approach to co-ordinating concurrency.
13 |
14 | At a high level:
15 |
16 | - An actor is the "primitive", like objects are the primitive of the OO paradigm
17 | - Actors are stateful but this state is never exposed to the rest of the system
18 | - Actors manage their internal state
19 | - Actors maintain a message queue or "inbox"
20 | - Messages can be received concurrently but must be processed sequentially in FIFO order
21 | - The messages have a preset format
22 | - Actors update their internal state in response to messages
23 | - Actors can send messages to each other
24 | - Messages are always processed at most once
25 | - Actors can "supervise" each other to create a fault tolerent system
26 | - A supervisor can restart or stop a failed actor, or escalate the decision to another supervisor
27 |
28 | The guarantees provided by the message queue allow actors to use stateful logic
29 | that would not be safe otherwise in a concurrent context.
30 |
31 | For example, we can implement logic that reads/writes to the file system without
32 | locks or other co-ordination. Then put an actor in front of this logic and only
33 | interact with the file system through the relevant actor.
34 |
35 | ## Riker
36 |
37 | [Riker](http://riker.rs/) is an actor library for Rust.
38 |
39 | The actor implementation in Riker has a few key concepts:
40 |
41 | - protocol: a set of valid messages that can be sent (e.g. an enum)
42 | - actor system: manages and co-ordinates all actors
43 | - actor: anything implementing the `Actor` trait to create new actor instances and handle receiving messages
44 | - actor instance: an instance of the actor struct that has internal state and is tracked by the actor system
45 | - actor ref(erence): an ActorRef that can tell messages to the actor instance it references via. the actor system
46 |
47 | The actor reference is a "killer feature" of Riker for us.
48 |
49 | - known size at compile, safe as properties of structs/enums
50 | - small size, almost free to clone
51 | - safe to share across threads and copy, no Arc reference counting, no locks, etc.
52 | - safe to drop (the actor system maintains a URI style lookup)
53 | - known type, no onerous generic trait handling
54 | - no onerous lifetimes
55 |
--------------------------------------------------------------------------------
/src/guide/testing_checking_results.md:
--------------------------------------------------------------------------------
1 | # (E) Checking Results
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/guide/wasm.md:
--------------------------------------------------------------------------------
1 | # WASM
2 |
--------------------------------------------------------------------------------
/src/guide/webassembly.md:
--------------------------------------------------------------------------------
1 | # WebAssembly
2 |
--------------------------------------------------------------------------------
/src/guide/welcome.md:
--------------------------------------------------------------------------------
1 | # Holochain Guidebook
2 |
3 | !!! attention "Please Note"
4 | We are currently revamping our developer documentation and have plans for a new guidebook. Please feel free to use the current guidebook, but note that it will be replaced in the future.
5 |
6 | **This documentation is a work in progress. Articles which have content in them appear normally in the chapter navigation. Articles which are incomplete appear with a (E) next to their name, indicating it is an empty unwritten article.**
7 |
8 | Hi there! You've discovered the comprehensive Holochain guidebook.
9 |
10 | Holochain is an open source software library that provides a way for businesses, communities,
11 | and other groups to build and run applications which are hosted and validated by the "users" themselves.
12 | Doing so provides a superior level of agency and autonomy over heavy reliance on the so-called "cloud" and other third parties.
13 |
14 | These applications are known more widely as peer-to-peer, decentralized applications, or dApps. To distinguish between dApps built on Blockchains and those built on Holochain, we preemptively call the latter "hApps". A more detailed comparison between Blockchain dApps and Holochain hApps is available [here](https://medium.com/holochain/beyond-blockchain-simple-scalable-cryptocurrencies-1eb7aebac6ae).
15 |
16 | Holochain provides a cross-platform framework for the development and execution of these applications.
17 | By running these kinds of applications, "users" cease to merely "use". They become "user-participants" who are also responsible for hosting and validating the network's data. Applications can be developed utilizing any of the major operating systems, and run on virtually any device.
18 |
19 | The many benefits and opportunities associated with peer-to-peer dApps (e.g. offloaded server costs, elimination of single points of failure, and flexible governance structures) are made available, and often amplified through the Holochain hApp architecture, on desktops, laptops, and Android (arm64) devices.
20 |
21 | This book provides an in-depth explanation of Holochain's functions, from data validation to data propagation,
22 | so that you can get to work straightaway on developing applications that will serve your business, community, or otherwise.
23 |
24 |
25 |
--------------------------------------------------------------------------------
/src/guide/zome.md:
--------------------------------------------------------------------------------
1 | # Zome
2 |
--------------------------------------------------------------------------------
/src/guide/zome/assemblyscript.md:
--------------------------------------------------------------------------------
1 | # Writing in Assemblyscript
2 |
3 | As mentioned in [writing in Rust](./rust.md) Assemblyscript is a language based off of Typescript, which is designed to compile to WebAssembly. It is hoped that Assemblyscript will soon be mature enough, and have the necessary features, to be able to have an HDK for it. Work on an HDK for Assemblyscript commenced mid 2018, but hit roadblocks.
4 |
5 | Updates on this should appear in a number of places:
6 | - [the Holochain medium publication](https://medium.com/holochain)
7 | - [the hdk-assemblyscript repository](https://github.com/holochain/hdk-assemblyscript)
--------------------------------------------------------------------------------
/src/guide/zome/bundling.md:
--------------------------------------------------------------------------------
1 | # Bundling
2 |
--------------------------------------------------------------------------------
/src/guide/zome/calling_other_zomes.md:
--------------------------------------------------------------------------------
1 | # Calling Other Zomes
2 |
--------------------------------------------------------------------------------
/src/guide/zome/capabilities.md:
--------------------------------------------------------------------------------
1 | # Capabilities
2 |
3 | ## Overview
4 | Holochain uses a modified version of the [capabilities](https://en.wikipedia.org/wiki/Capability-based_security) security model. Holochain DNA instances will grant revokable, cryptographic capability tokens which are shared as access credentials. Appropriate access credentials must be used to access functions and private data.
5 |
6 | This enables us to use a single security pattern for:
7 |
8 | - connecting end-user UIs,
9 | - calls across zomes within a DNA,
10 | - bridging calls between different DNAs,
11 | - and providing selective users of a DNA the ability to query private entries on the local chain via send/receive.
12 |
13 | Each capability grant gets recorded as a private entry on the grantor’s chain. The hash (i.e. address) of that entry is then serves as the capability token usable by the grantee when making zome function call, because the grantor simply verifies the existence of that grant in it's chain. Thus, all zome functions calls include a capability request object which contains: public key of the grantee and signature of the parameters being used to call the function, along with the capability token being used as the access credential.
14 |
15 | ## Using Capabilities
16 |
17 | ### Public Capabilities
18 | You can declare some functions as "public" using the special `hc_public` marker trait in your `define_zome!` call. Functions in that trait will be added to the public capability grant which gets auto-committed during init. Like this:
19 |
20 | ```
21 | define_zome! {
22 |
23 | ...
24 |
25 | traits: {
26 | hc_public [read_post, write_post]
27 | }
28 |
29 | ...
30 |
31 | }
32 | ```
33 |
34 | ### Grant Capabilities
35 |
36 | You can use the `commit_capability_grant` HDK function to create a custom capability grant. For example, imaging a blogging use-case where you want to grant friends the ability to call the `create_post` function in a `blog` zome. Assuming the function `is_my_friend(addr)` correctly examines the provenance in CAPABILITY_REQ global which always holds the capability request of the current zome call, then the following code is an example of how you might call `hdk::commit_capability_grant`:
37 |
38 | ``` rust
39 | pub fn handle_request_post_grant() -> ZomeApiResult