hdk/
lib.rs

1//! The Holochain Development Kit (HDK) provides high and low level functions for writing Holochain applications.
2//!
3//! Holochain is built as a client-server architecture. The Conductor, Holochain's runtime, acts as the server.
4//! Its [Conductor API](https://docs.rs/holochain_conductor_api/latest/holochain_conductor_api) can be queried
5//! by a client to manage hApps and send requests to hApp functions.
6//! [Read more on Holochain's architecture.](https://developer.holochain.org/concepts/2_application_architecture)
7//!
8//! Functions of a hApp are organized into reusable components. In Holochain terminology these components are called "zomes".
9//! One or multiple zomes are compiled into WebAssembly (WASM) binaries and bundled into a file referred to as a DNA. All of the DNAs of an application are bundled to a hApp.
10//! In short, the structure is __hApp -> DNA -> zome -> function__.
11//!
12//! hApps can be developed using the HDK. See the [Holochain Quick Start Guide](https://developer.holochain.org/quick-start)
13//! to get started with hApp development.
14//!
15//! # Example zomes 🍭
16//!
17//! There are numerous example/test WASMs on many aspects of hApp development that can be browsed
18//! [on Github](https://github.com/holochain/holochain/tree/develop/crates/test_utils/wasm/wasm_workspace).
19//!
20//! Each example WASM is a minimal demonstration of specific HDK functionality, such as generating random data, creating entries or defining validation callbacks.
21//! Some of the examples are very contrived, none are intended as production grade hApp examples, but do highlight key functionality.
22//!
23//! # Zomes are separated into data model and domain logic
24//!
25//! hApps are required to produce and validate data deterministically. There's a data model and a domain logic part to each hApp. In Holochain, the
26//! data model is defined in integrity zomes and the domain logic is written in coordinator zomes.
27//!
28//! ## Integrity zomes 📐
29//!
30//! Integrity zomes describe a hApp's domain model by defining a set of entry and link types and providing a validation callback
31//! function that checks the integrity of any operations that manipulate data of those types.
32//! Additionally, a genesis self-check callback can be implemented for basic verification
33//! of the data that allows an agent to join a network before they attempt to join it.
34//!
35//! The wasm workspace contains examples of integrity zomes like this:
36//! <https://github.com/holochain/holochain/blob/develop/crates/test_utils/wasm/wasm_workspace/integrity_zome/src/lib.rs>
37//!
38//! Refer to the [HDI crate](crate::prelude::hdi) for more information on the integrity layer.
39//!
40//! ## Coordinator zomes 🐜
41//!
42//! Coordinator zomes are the counterpart of integrity zomes in a DNA. They contain the domain logic of how data is read and written.
43//! Whereas data is defined and validated in integrity zomes, functions to manipulate data are implemented in coordinator zomes.
44//!
45//! An example coordinator zome can be found in the wasm workspace of the Holochain repository:
46//! <https://github.com/holochain/holochain/blob/develop/crates/test_utils/wasm/wasm_workspace/coordinator_zome/src/lib.rs>.
47//!
48//! # HDK structure 🧱
49//!
50//! HDK implements several key features:
51//!
52//! - Base HDKT trait for standardisation, mocking, unit testing support: [`hdk`] module
53//! - Capabilities and function level access control: [`capability`] module
54//! - [Holochain Deterministic Integrity (HDI)]
55//! - Application data and entry definitions for the source chain and DHT: [`entry`]
56//!   module and [entry_types] callback
57//! - Referencing/linking entries on the DHT together into a graph structure: [`link`] module
58//! - Defining tree-like structures out of links and entries for discoverability and scalability: [`hash_path`] module
59//! - Create, read, update, delete (CRUD) operations on the above
60//! - Libsodium compatible symmetric/secret (secretbox) and asymmetric/keypair (box) encryption: [`x_salsa20_poly1305`] module
61//! - Ed25519 signing and verification of data: [`ed25519`] module
62//! - Exposing information about the current execution context such as zome name: [`info`] module
63//! - Other utility functions provided by the host such as generating randomness and timestamps that are impossible in WASM: utility module
64//! - Exposing functions to external processes and callbacks to the host: [`hdk_extern!`](macro@crate::prelude::hdk_extern) and [`map_extern!`](macro@crate::prelude::map_extern) macros
65//! - Integration with the Rust [tracing](https://docs.rs/tracing/0.1.23/tracing/) crate
66//! - Exposing a [`prelude`] of common types and functions for convenience
67//!
68//! Generally these features are structured logically into modules but there are some affordances to the layering of abstractions.
69//!
70//!
71//! # HDK is based on callbacks 👂
72//!
73//! The only way to execute logic inside WASM is by having the conductor (host) call a function that is marked as an `extern` by the zome (guest).
74//!
75//! > Note: From the perspective of hApp development in WASM, the "guest" is the WASM and the "host" is the running Holochain conductor.
76//! > The host is _not_ the "host operating system" in this context.
77//!
78//! Similarly, the only way for the guest to do anything other than process data and calculations is to call functions the host provides to it at runtime.
79//!
80//! Host functions are all defined by the Holochain conductor and implemented by HDK for you, but the guest functions need to all be defined by your application.
81//!
82//! > Any WASM that does _not_ use the HDK will need to define placeholders for and the interface to the host functions.
83//!
84//! All host functions can be called directly as:
85//!
86//! ```ignore
87//! use crate::prelude::*;
88//! let _output: HDK.with(|h| h.borrow().host_fn(input));
89//! ```
90//!
91//! And every host function defined by Holochain has a convenience wrapper in HDK that does the type juggling for you.
92//!
93//! Low-level communication between the conductor and WASM binaries, like typing and serialization of data, is abstracted by the HDK.
94//! Using the HDK, hApp developers can focus on their application's logic. [Learn more about WASM in Holochain.](https://github.com/holochain/holochain/blob/develop/crates/hdk/ON-WASM.md)
95//!
96//! ## External callbacks = Zome functions
97//!
98//! To extend a Rust function so that it can be called by the host, add the [`hdk_extern!`](macro@crate::prelude::hdk_extern) attribute.
99//!
100//! - The function may take _none_ or _one_ argument that, if provided, must implement `serde::Serialize + std::fmt::Debug`.
101//! - The function must return an `ExternResult` where the success value implements `serde::Serialize + std::fmt::Debug`
102//! - The function must have a unique name across all externs as they share a global namespace in WASM
103//! - Everything inside the function is Rust-as-usual including `?` to interact with `ExternResult` that fails as `WasmError`
104//! - Use the [`wasm_error!`](crate::prelude::wasm_error) macro along with the
105//!   [`WasmErrorInner::Guest`](crate::prelude::WasmErrorInner::Guest) variant for failure conditions that the host or
106//!   external processes need to be aware of
107//! - Externed functions can be called as normal by other functions inside the same WASM
108//!
109//! For example:
110//!
111//! ```ignore
112//! use crate::prelude::*;
113//!
114//! // This function can be called by any external process that can provide and accept messagepack serialized u32 integers.
115//! #[hdk_extern]
116//! pub fn increment(u: u32) -> ExternResult<u32> {
117//!   Ok(u + 1)
118//! }
119//!
120//! // Extern functions can be called as normal by other rust code.
121//! assert_eq!(2, increment(1));
122//! ```
123//!
124//! Most externs are simply available to external processes and must be called explicitly e.g. via RPC over websockets.
125//! The external process only needs to ensure the input and output data is handled correctly as messagepack.
126//!
127//! ## Internal callbacks
128//!
129//! Some externs act as callbacks the host will call at key points in Holochain internal system workflows.
130//! These callbacks allow the guest to define how the host proceeds at those decision points. They are defined in zomes like
131//! extern callbacks above, but have reserved names listed below.
132//!
133//! Callbacks are simply called by name and they are "sparse" in that they are matched incrementally from the most specific
134//! name to the least specific name. For example, the `validate_{{ create|update|delete }}_{{ agent|entry }}` callbacks will
135//! all match and all run during validation. All function components with multiple options are optional, e.g. `validate` will execute and so will `validate_create`.
136//!
137//! Holochain will merge multiple callback results for the same callback in a context sensitive manner. For example, the host will consider initialization failed if _any_ init callback fails.
138//!
139//! The callbacks are (see above for examples):
140//!
141//! - `fn entry_defs() -> ExternResult<EntryDefsCallbackResult>`:
142//!   - Typically implemented automatically by macros in the HDK so does NOT
143//!     require writing the extern for it manually.
144//!   - `EntryDefs` is a vector defining all entries used by this app.
145//!   - All zomes in a DNA define all their entries at the same time for the host.
146//!   - All entry defs are combined into a single ordered list per zome and exposed to tooling such as DNA generation.
147//!   - Entry defs are referenced by `u8` numerical position externally and in DHT actions, and by id/name e.g. "post" in sparse callbacks.
148//! - `fn genesis_self_check(_: GenesisSelfCheckData) -> ExternResult<ValidateCallbackResult>`:
149//!   - Allows each agent to validate itself before attempting to join the
150//!     network.
151//!   - Receives `GenesisSelfCheckData` that includes DNA information, the agent
152//!     key for the candidate source chain and the membrane proof.
153//!   - Runs _before the agent exists on the network_ so has no ability to use
154//!     the network and generally only has access to deterministic HDK functions.
155//! - `fn init() -> ExternResult<InitCallbackResult>`:
156//!   - Allows the guest to pass/fail/retry initialization with [`InitCallbackResult`](crate::prelude::holochain_zome_types::init::InitCallbackResult).
157//!   - Lazy execution - only runs when any zome of the DNA is first called.
158//!   - All zomes in a DNA init at the same time.
159//!   - Any zome failure fails initialization for the DNA, any zome retry (missing dependencies) causes the DNA to retry.
160//!   - Failure overrides retry.
161//!   - See [`create_cap_grant`](crate::capability::create_cap_grant) for an explanation of how to set up capabilities in `init`.
162//! - `fn migrate_agent_{{ open|close }} -> ExternResult<MigrateAgentCallbackResult>`:
163//!   - Allows the guest to pass/fail a migration attempt to/from another DNA.
164//!   - Open runs when an agent is starting a new source chain from an old one.
165//!   - Close runs when an agent is deprecating an old source chain in favour of a new one.
166//!   - All zomes in a DNA migrate at the same time.
167//!   - Any failure fails the migration.
168//! - `fn recv_remote_signal(signal: ExternIO) -> ExternResult<()>`:
169//!   - Allows the guest to receive remote signals sent from other agents via the [`send_remote_signal`](crate::p2p::send_remote_signal) host function.
170//!   - Only receives signals that have been sent from a coordinator zome of the same name in the remote agent's cell.
171//!   - As with all zome functions and callbacks, the single input parameter of this callback can be an arbitrary type with a `serde::Deserialize + std::fmt::Debug` implementation, rather than [`ExternIO`](crate::prelude::ExternIO). If you choose to do this, deserialization will be handled by the HDK and the call will fail if deserialization fails.
172//!   - This is a regular zome function, so in order for remote agents to send signals to this zome, a [capability grant](crate::capability::create_cap_grant) (e.g., with [`CapAccess::Unrestricted`](crate::prelude::CapAccess::Unrestricted)) must be created for the appropriate agent(s).
173//! - `fn post_commit(actions: Vec<SignedActionHashed>)`:
174//!   - Executes after the WASM call that originated the commits so not bound by the original atomic transaction.
175//!   - Input is all the action hashes that were committed.
176//!   - The zome that originated the commits is called.
177//! - `fn validate(op: Op) -> ExternResult<ValidateCallbackResult>`:
178//!   - Allows the guest to pass/fail/retry any operation.
179//!   - Only the originating zome is called.
180//!   - Failure overrides retry.
181//!
182//! # HDK has layers 🧅
183//!
184//! HDK is designed in layers so that there is some kind of 80/20 rule.
185//! The code is not strictly organised this way but you'll get a feel for it as you write your own hApps.
186//!
187//! Roughly speaking, 80% of your apps can be production ready using just 20% of the HDK features and code.
188//! These are the 'high level' functions such as [`crate::entry::create_entry`] and macros like [`hdk_extern!`](macro@crate::prelude::hdk_extern).
189//! Every Holochain function is available with a typed and documented wrapper and there is a set of macros for exposing functions and defining entries.
190//!
191//! The 20% of the time that you need to go deeper there is another layer followng its own 80/20 rule.
192//! 80% of the time you can fill the gaps from the layer above with `host_call` or by writing your own entry definition logic.
193//! For example you may want to implement generic type interfaces or combinations of structs and enums for entries that isn't handled out of the box.
194//!
195//! If you need to go deeper still, the next layer is the `holochain_wasmer_guest`, `holochain_zome_types` and `holochain_serialization` crates.
196//! Here you can customise exactly how your externally facing functions are called and how they serialize data and memory.
197//! Ideally you never need to go this far but there are rare situations that may require it.
198//! For example, you may need to accept data from an external source that cannot be messagepack serialized (e.g. json), or you may want to customise the tracing tooling and error handling.
199//!
200//! The lowest layer is the structs and serialization that define how the host and the guest communicate.
201//! You cannot change this but you can reimplement it in your language of choice (e.g. Haskell?) by referencing the Rust zome types and extern function signatures.
202//!
203//!
204//! # HDK is atomic on the source chain ⚛
205//!
206//! [Read up on what the source chain is in Holochain.](https://developer.holochain.org/concepts/3_source_chain)
207//!
208//! All writes to the source chain are atomic within a single extern/callback call.
209//!
210//! This means __all data will validate and be written together or nothing will__.
211//!
212//! There are no such guarantees for other side effects. Notably we cannot control anything over the network or outside the Holochain database.
213//!
214//! Remote calls will be atomic on the recipients device but could complete successfully while the local agent subsequently errors and rolls back their chain.
215//! This means you should not rely on data existing _between_ agents unless you have another source of integrity such as cryptographic countersignatures.
216//!
217//! Use a post commit hook and signals or remote calls if you need to notify other agents about completed commits.
218//!
219//!
220//! # HDK should be pinned 📌
221//!
222//! The basic functionality of the HDK is to communicate with the Holochain conductor using a specific typed interface.
223//!
224//! If any of the following change relative to the conductor your WASM _will_ have bugs:
225//!
226//! - Shared types used by the host and guest to communicate
227//! - Serialization logic that generates bytes used by cryptographic algorithms
228//! - Negotiating shared memory between the host and guest
229//! - Functions available to be called by the guest on the host
230//! - Callbacks the guest needs to provide to the host
231//!
232//! For this reason we have dedicated crates for serialization and memory handling that rarely change.
233//! HDK references these crates with `=x.y.z` syntax in Cargo.toml to be explicit about this.
234//!
235//! HDK itself has a slower release cycle than the Holochain conductor by design to make it easier to pin and track changes.
236//!
237//! You should pin your dependency on HDK using the `=x.y.z` syntax too!
238//!
239//! You do _not_ need to pin _all_ your Rust dependencies, just those that take part in defining the host/guest interface.
240//!
241//!
242//! # HDK is integrated with rust tracing for better debugging 🐛
243//!
244//! Every extern defined with the [`hdk_extern!`](macro@crate::prelude::hdk_extern) attribute registers a [tracing subscriber](https://crates.io/crates/tracing-subscriber) that works in WASM.
245//!
246//! All the basic tracing macros `trace!`, `debug!`, `warn!`, `error!` are implemented.
247//!
248//! However, tracing spans currently do _not_ work, if you attempt to `#[instrument]`, you will likely panic your WASM.
249//!
250//! WASM tracing can be filtered at runtime using the `WASM_LOG` environment variable that works exactly as `RUST_LOG` does for the Holochain conductor and other Rust binaries.
251//!
252//! The most common internal errors, such as invalid deserialization between WASM and external processes, are traced as `error!` by default.
253//!
254//!
255//! # HDK requires explicit error handling between the guest and host ⚠
256//!
257//! All calls to functions provided by the host can fail to execute cleanly, at the least serialization could always fail.
258//!
259//! There are many other possibilities for failure, such as a corrupt database or attempting cryptographic operations without a key.
260//!
261//! When the host encounters a failure `Result`, it will __serialize the error and pass it back to the WASM guest__.
262//! The __guest must handle this error__ and either return it back to the host which _then_ rolls back writes (see above), or implement some kind of graceful failure or retry logic.
263//!
264//! The `Result` from the host in the case of host calls indicates whether the execution _completed_ successfully and is _in addition to_ other Result-like enums.
265//! For example, a remote call can be `Ok` from the host's perspective but contain an
266//! [`ZomeCallResponse::Unauthorized`](crate::prelude::ZomeCallResponse::Unauthorized) "failure" enum variant from the remote agent.
267//! Both need to be handled in context.
268
269pub use hdi::HDI_VERSION;
270
271/// Current HDK rust crate version.
272pub const HDK_VERSION: &str = env!("CARGO_PKG_VERSION");
273
274#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
275const ERAND_INTERNAL: u16 = 1;
276
277#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
278const ERAND_TOO_LONG: u16 = 2;
279
280#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
281fn wasm_getrandom(buf: &mut [u8]) -> Result<(), getrandom::Error> {
282    if buf.len() > u32::MAX as usize {
283        return Err(getrandom::Error::new_custom(ERAND_TOO_LONG));
284    }
285    let number_of_bytes = buf.len() as u32;
286    match crate::hdk::HDK.with(|h| h.borrow().random_bytes(number_of_bytes)) {
287        Err(_) => {
288            return Err(getrandom::Error::new_custom(ERAND_INTERNAL));
289        }
290        Ok(bytes) => {
291            if bytes.len() != buf.len() {
292                return Err(getrandom::Error::new_custom(ERAND_INTERNAL));
293            }
294            buf.copy_from_slice(&bytes);
295        }
296    }
297    Ok(())
298}
299
300#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
301#[no_mangle]
302unsafe extern "Rust" fn __getrandom_v03_custom(
303    dest: *mut u8,
304    len: usize,
305) -> Result<(), getrandom::Error> {
306    wasm_getrandom(std::slice::from_raw_parts_mut(dest, len))
307}
308
309/// Capability claims and grants.
310///
311/// Every exposed function in Holochain uses capability grants/claims to secure
312/// access.Capability grants are system entries committed to the source chain
313/// that define access. Capability claims are system entries that reference a
314/// grant on a source chain.
315///
316/// # Examples
317/// <https://github.com/holochain/holochain/blob/develop/crates/test_utils/wasm/wasm_workspace/capability/src/coordinator.rs>
318///
319/// 0. When Alice wants Bob to be able to call a function on her running conductor she commits a grant for Bob.
320/// 0. Bob commits the grant as a claim on his source chain.
321/// 0. When Bob wants to call Alice's function he sends the claim back to Alice along with the function call information.
322/// 0. Alice cross references Bob's claim against her grant, e.g. to check it is still valid, before granting access.
323///
324/// There are four types of capability grant:
325///
326/// - Author: The author of the local source chain provides their agent key as a claim and has full access to all functions.
327/// - Unrestricted: Anyone can call this function without providing a claim.
328/// - Unassigned: Anyone with the randomly generated secret associated with the grant can call this function.
329/// - Assigned: The specific named agents can call this function if they provide the associated secret.
330///
331/// Capability grants and claims reference each other by a shared, unique, unpredictable secret.
332/// The security properties of a capability secret are roughly the same as an API key for a server.
333///
334/// - If an attacker knows or guesses the secret they can call Unassigned functions
335/// - An attacker cannot call Assigned functions even if they know or guess the secret
336/// - If a secret is compromised the grant can be deleted and new claims can be distributed
337/// - The secret only grants access to live function calls against a running conductor reachable on the network
338/// - Holochain compares capability secrets using constant time equality checks to mitigate timing attacks
339/// - Grant secrets are stored in WASM memory so are NOT as secure as a dedicated keystore
340///
341/// Grant secrets are less sensitive than cryptographic keys but are not intended to be public data.
342/// Don't store them to the DHT in plaintext, or commit them to Github repositories, etc!
343///
344/// For best security, assign grants to specific agents if you can as the assignment check _does_ cryptographically validate the caller.
345///
346// @todo in the future grant secrets may be moved to lair somehow.
347pub mod capability;
348
349/// Signing a single chain entry between multiple participants.
350///
351/// The basic goal is to enable a kind of atomicity across multiple source chains
352/// in an environment where countersigners trust each other in some ways but not
353/// entirely. Countersigning provides several trust models, including nominating
354/// a single party to gather signatures, M of N signers, majority signing buckets,
355/// etc.
356///
357/// The integrity layer enforces very little other than the structure of a
358/// countersigned entry, to define the session parameters and uniqueness and final
359/// signature set. Implementations are expected to drive countersigning sessions
360/// through coordinator zomes based on understanding both the expected network
361/// topologies and trust between peers on the network.
362///
363/// As various models for driving and finalising systems on the network are
364/// defined and implemented they all end up in the countersigning crate.
365///
366/// This is a network level implementation of countersigning which has pros and
367/// cons. There are also cryptographic methods of countersigning such as
368/// threshold signatures that produce a single proof between multiple
369/// participants, which are NOT included in this crate.
370#[cfg(feature = "unstable-countersigning")]
371pub mod countersigning;
372
373/// Working with app and system entries.
374///
375/// Most Holochain applications will define their own app entry types.
376///
377/// App entries are all entries that are not system entries.
378/// Definitions of entry types belong in the integrity zomes of a DNA. In contrast, operations
379/// for manipulating entries go into coordinator zomes.
380///
381/// # Examples
382///
383/// Refer to the WASM workspace in the Holochain repository for examples.
384/// Here's a simple example of an entry definition:
385/// <https://github.com/holochain/holochain/blob/develop/crates/test_utils/wasm/wasm_workspace/entry_defs/src/integrity.rs>
386///
387/// An example of a coordinator zome with functions to manipulate entries:
388/// <https://github.com/holochain/holochain/blob/develop/crates/test_utils/wasm/wasm_workspace/coordinator_zome/src/lib.rs>
389///
390/// # CRUD
391///
392/// CRUD in Holochain is represented as a graph/tree of Records referencing each other (via Action hashes), representing new states of a shared identity.
393/// Because the network is always subject to the possibility of partitions, there is no way to assert an objective truth about the 'current' or 'real' value that all participants will agree on.
394/// This is a key difference between Holochain and blockchains.
395/// Where blockchains define a consensus algorithm that brings all participants as close as possible to a single value, while Holochain lets each participant discover their own truth.
396///
397/// The practical implication of this is that agents fetch as much information as they can from the network, then follow an algorithm to 'walk' or 'reduce' the revisions and discover 'current' for themselves.
398///
399/// In Holochain terms, blockchain consensus is walking all the known 'updates' (blocks) that pass validation, then walking/reducing down them to disover the 'chain with the most work' or similar.
400/// For example, to implement a blockchain in Holochain, attach a proof of work to each update and then follow the updates with the most work to the end.
401///
402/// There are many other ways to discover the correct path through updates, for example a friendly game of chess between two players could involve consensual re-orgs or 'undos' of moves by countersigning a different update higher up the tree, to branch out a new revision history.
403///
404/// Two agents with the same information may even disagree on the 'correct' path through updates and this may be valid for a particular application.
405/// For example, an agent could choose to 'block' another agent and ignore all their updates.
406pub mod entry;
407
408pub use hdi;
409pub use hdi::entry_types;
410
411pub mod hash;
412
413pub mod hash_path;
414
415/// Maps a Rust function to an extern that WASM can expose to the Holochain host.
416///
417/// Annotate any compatible function with [`hdk_extern!`] to expose it to Holochain as a WASM extern.
418/// The [`map_extern!`](crate::map_extern!) macro is used internally by the [`hdk_extern!`] attribute.
419///
420/// Compatible functions:
421///
422/// - Have a globally unique name
423/// - Accept `serde::Serialize + std::fmt::Debug` input
424/// - Return `Result<O, WasmError>` (`ExternResult`) output where `O: serde::Serialize + std::fmt::Debug`
425///
426/// This module only defines macros so check the HDK crate root to see more documentation.
427///
428/// A _new_ extern function is created with the same name as the function with the [`hdk_extern!`] attribute.
429/// The new extern is placed in a child module of the current scope.
430/// This new extern is hoisted by WASM to share a global namespace with all other externs so names must be globally unique even if the base function is scoped.
431///
432/// The new extern handles:
433///
434/// - Extern syntax for Rust
435/// - Receiving the serialized bytes from the host at a memory pointer specified by the guest
436/// - Setting the HDK WASM tracing subscriber as the global default
437/// - Deserializing the input from the host
438/// - Calling the function annotated with [`hdk_extern!`]
439/// - Serializing the result
440/// - Converting the serialized result to a memory pointer for the host
441/// - Error handling for all the above
442///
443/// If you want to do something different to the default you will need to understand and reimplement all the above.
444///
445/// [`hdk_extern!`]: hdk_derive::hdk_extern
446pub mod map_extern;
447
448/// Exports common types and functions according to the Rust prelude pattern.
449pub mod prelude;
450
451/// Encryption and decryption using the (secret)box algorithms popularised by Libsodium.
452///
453/// Libsodium defines and implements two encryption functions `secretbox` and `box`.
454/// The former implements shared secret encryption and the latter does the same but with a DH key exchange to generate the shared secret.
455/// This has the effect of being able to encrypt data so that only the intended recipient can read it.
456/// This is also repudiable so both participants know the data must have been encrypted by the other (because they didn't encrypt it themselves) but cannot prove this to anybody else (because they _could have_ encrypted it themselves).
457/// If repudiability is not something you want, you need to use a different approach.
458///
459/// Note that the secrets are located within the secure lair keystore and never touch WASM memory.
460// @todo actually secretbox puts the secret in WASM, but this will be fixed soon
461/// The WASM must provide either the public key for box or an opaque _reference_ to the secret key so that lair can encrypt or decrypt as required.
462//
463// @todo implement a way to export/send an encrypted shared secret for a peer from lair
464///
465/// Note that even though the elliptic curve is the same as is used by ed25519, the keypairs cannot be shared because the curve is mathematically translated in the signing vs. encryption algorithms.
466/// In theory the keypairs could also be translated to move between the two algorithms but Holochain doesn't offer a way to do this (yet?).
467/// Create new keypairs for encryption and save the associated public key to your local source chain, and send it to peers you want to interact with.
468pub mod x_salsa20_poly1305;
469
470/// Rexporting the paste macro as it is used internally and may help structure downstream code.
471pub use paste;
472
473/// Tools to interrogate source chains.
474///
475/// Interacting with a source chain is very different to the DHT.
476///
477/// - Source chains have a linear history guaranteed by action hashes
478/// - Source chains have a single owner/author signing every chain record
479/// - Source chains can be iterated over from most recent back to genesis by following the action hashes as references
480/// - Source chains contain interspersed system and application entries
481/// - Source chains contain both private (local only) and public (broadcast to DHT) records
482///
483/// There is a small DSL provided by `query` that allows for inspecting the current agent's local source chain.
484/// Typically it will be faster, more direct and efficient to query local data than dial out to the network.
485/// It is also possible to query local private entries.
486///
487/// Agent activity for any other agent on the network can be fetched.
488/// The agent activity is _only the actions_ of the remote agent's source chain.
489/// Agent activity allows efficient building of the history of an agent.
490/// Agent activity is retrieved from a dedicated neighbourhood near the agent.
491/// The agent's neighbourhood also maintains a passive security net that guards against attempted chain forks and/or rollbacks.
492/// The same query DSL for local chain queries is used to filter remote agent activity actions.
493pub mod chain;
494
495/// Create and verify signatures for serializable Rust structures and raw binary data.
496///
497/// The signatures are always created with the [Ed25519](https://en.wikipedia.org/wiki/EdDSA) algorithm by the secure keystore (lair).
498///
499/// Agent public keys that identify agents are the public half of a signing keypair.
500/// The private half of the signing keypair never leaves the secure keystore and certainly never touches WASM.
501///
502/// If a signature is requested for a public key that has no corresponding private key in lair, the signing will fail.
503///
504/// Signatures can always be verified with the public key alone so can be done remotely (by other agents) and offline, etc.
505///
506/// The elliptic curve used by the signing algorithm is the same as the curve used by the encryption algorithms but is _not_ constant time (because signature verification doesn't need to be).
507///
508/// In general it is __not a good idea to reuse signing keys for encryption__ even if the curve is the same, without mathematically translating the keypair, and even then it's dubious to do so.
509pub mod ed25519;
510
511/// Request contextual information from the Holochain host.
512///
513/// The Holochain host has additional runtime context that the WASM may find useful and cannot produce for itself including:
514///
515/// - The calling agent
516/// - The current app (bundle of DNAs)
517/// - The current DNA
518/// - The current Zome
519/// - The function call itself
520pub mod info;
521
522/// Links in Holochain are analogous to a join table in a traditional SQL schema.
523///
524/// Links embody navigable graph structures between entires in a more general format than CRUD trees.
525///
526/// At a high level:
527///
528/// - Can implement direct or indirect circular references
529/// - Reference data by its hash
530/// - Have a base and target entry, action or external hash
531/// - Can either exist or be deleted (i.e. there is no revision history, deleting removes a link permanently)
532/// - Many links can point from/to the same hash
533/// - Links reference entry hashes not actions
534///
535/// Links are retrived from the DHT by performing [`link::get_links`] or [`link::get_links_details`] against the _base_ of a link.
536///
537/// Links also support short (about 500 bytes) binary data to encode contextual data on a domain specific basis.
538///
539/// __Links are not entries__, there is only an action with no associated entry, so links cannot reference other links or maintain or participate in a revision history.
540pub mod link;
541
542/// Methods for interacting with peers in the same DHT network.
543///
544/// Data on the DHT generally propagates at the speed of gossip and must be explicitly polled and retrieved.
545///
546/// Often we want more responsive and direct interactions between peers.
547/// These interactions come in two flavours, RPC style function calls and notification style 'signals'.
548///
549/// All function calls use capability grants and claims to authenticate and authorize.
550/// Signals simply forward information about the introduction of new data on the DHT so that agents can push updates to each other rather than relying purely on polling.
551//
552// @todo introduce a pubsub mechanism
553pub mod p2p;
554
555/// Integrates HDK with the Rust tracing crate.
556///
557/// The functions and structs in this module do _not_ need to be used directly.
558/// The [`hdk_extern!`] attribute on functions exposed externally all set the `WasmSubscriber` as the global default.
559///
560/// This module defines a [`trace::WasmSubscriber`] that forwards all tracing macro calls to another subscriber on the host.
561/// The logging level can be changed for the host at runtime using the `WASM_LOG` environment variable that works exactly as `RUST_LOG` for other tracing.
562///
563/// [`hdk_extern!`]: hdk_derive::hdk_extern
564pub mod trace;
565
566/// Everything related to inspecting or responding to time.
567///
568/// Currently only fetching the host's opinion of the local time is supported.
569//
570// @todo implement scheduled execution and sleeping
571pub mod time;
572
573/// Generate cryptographic strength random data
574///
575/// The host provides the random bytes because any/all WASM implementations of randomness is flawed and insecure.
576pub mod random;
577
578/// The interface between the host and guest is implemented as an `HdkT` trait.
579///
580/// The `set_hdk` function globally sets a `RefCell` to track the current HDK implementation.
581/// When the `mock` feature is set then this will default to an HDK that always errors, else a WASM host is assumed to exist.
582/// The `mockall` crate (in prelude with `mock` feature) can be used to generate compatible mocks for unit testing.
583/// See mocking examples in the test WASMs crate, such as `agent_info`.
584pub mod hdk;
585
586/// Create and manage clone cells in the current app.
587///
588/// Clone cells are a way to create a new cell that is a copy of an existing cell. They are based on the DNA of an existing cell, and run
589/// with the same agent key, but have a unique name or properties that distinguish them from the original cell.
590pub mod clone;
591
592/// Tools for working with migrations from one DNA to another.
593mod migrate;
594
595/// Look up validation receipts for actions that a local agent has authored.
596pub mod validation_receipt;