Holochain Client JS

repository·main·Indexed 42 days ago

https://github.com/holochain/holochain-client-js

A JavaScript client for the Holochain Conductor API, compatible with browsers and Node.js. It provides interfaces for managing applications via AdminWebsocket and interacting with zomes via AppWebsocket using WebSockets or Tauri IPC.

Tokens
104K
Snippets
558
Records
703
Agent score
53%

What's inside Holochain Client JS

  1. What is a Role in @holochain/client?

    main

    In the context of Holochain, a Role is an application-defined identifier used during countersigning sessions. It is an opaque value to the subconscious (the underlying system), meaning the application is responsible for defining and managing what these roles represent. A Role is represented as a number.

    export type Role = number;
  2. Understand Decoded Signals and App Signals

    main

    When listening for signals in Holochain, you will receive DecodedSignal objects.

    • System Signals: Pass through the client unchanged.
    • App Signals: These carry a DecodedAppSignal.

    Unlike a raw Signal where the payload is a msgpack-encoded byte string, a DecodedAppSignal has already been decoded by the client. This means the signal field contains the actual type produced by the emitting zome, making it directly usable in your application logic.

  3. Handle Timestamps in Holochain

    main

    A Timestamp is a microsecond-precision UTC timestamp (serialized as a bare i64 representing microseconds from the UNIX Epoch).

    Critical Precautions:

    • Untrustworthy Data: Timestamps are assumed to be untrustworthy and may contain offsets from the UNIX epoch across the full +/- i64 range.
    • Avoid Chrono/Core Time Panics: Many timestamps are not representable by chrono::DateTime<Utc> or core::time::Duration. Attempting to convert these directly into standard library time types can cause panics. Use caution when performing arithmetic or conversions on DHT Action information.
  4. Understand AdminRequest and AdminResponse patterns

    main

    The AdminRequest and AdminResponse types are used to interact with conductor functions via an admin interface.

    • Naming Convention: AdminRequest variants follow a verb_noun convention (e.g., list_apps), whereas AdminResponse variants follow a noun_verb convention (e.g., app_listed).
    • Error Handling: If a request fails, it returns an AdminResponse::Error containing the reason for failure.
    • Serialization: AdminResponse serializes as an object with the enum variant on a type key and the payload on a data key.

    Example Serialization:

    { "type": "app_interface_attached", "data": { "port": 4000 } }
  5. Use TauriAppTransport for in-process Holochain conductors

    main

    When building a Tauri application where the Holochain conductor runs in the same process as the app, use TauriAppTransport instead of a websocket. This class carries the App API over Tauri IPC (Inter-Process Communication) rather than over a network socket.

    TauriAppTransport is a drop-in replacement for WsClient. It implements the AppClientTransport interface, meaning it exposes the same request method and acts as an Emittery for signal events. If you are already using AppWebsocket, your code will work unchanged; only the transport layer changes.

    Key differences from WebSockets:

    • Payloads: It uses the same msgpack-encoded { type, value } payloads.
    • Communication: Payloads are sent through the plugin:<name>|app_request command via Tauri IPC.
    • Authentication: No app_id is sent. The conductor automatically scopes each request to the calling window on the Rust side, replacing the need for a per-app websocket auth token.
    // Conceptually, it is used as a drop-in for WsClient in AppWebsocket
    // The interface remains the same:
    // transport.request(request) -> Promise<response>
    // transport.on('signal', callback)
  6. Parse JsonDump from StateDump

    main
    When performing a state dump, the resulting JsonDump contains the structured cell state. Due to the JSON serialization of the StateDump, you must treat byte-bearing fields (hashes, signatures, etc.) as number[] rather than Uint8Array when parsing the string manually.
  7. Understand ValidationStatus and validation lifecycle

    main

    The ValidationStatus represents the current state of validation for an operation or record. Much of this process occurs in the 'subconscious'.

    An entry missing validation dependencies may cycle through a Pending state multiple times before it eventually reaches a final validation state or is abandoned.

  8. Understand the DnaModifiers type

    main

    The DnaModifiers type represents the metadata that modifies a DNA hash computation, distinct from the actual DNA code itself. These modifiers include the network seed, specific properties, and the origin time. When computing a DNA hash, these values are factored in alongside the DNA code.

    export type DnaModifiers = {
        network_seed: NetworkSeed;
        properties: Uint8Array;
    };
  9. Understand AppRequest and AppResponse patterns

    main

    The AppRequest and AppResponse types facilitate calling conductor functions over an app interface.

    • Workflow: An AppRequest results in a corresponding AppResponse message being sent back over the interface connection.
    • Error Handling: If a request fails, it returns an AppResponse::Error containing the reason for failure.
    • Payloads: Both request and response types use associated payload types (AppRequestPayload and AppResponsePayload) which may be void if the variant carries no data.
  10. Connect from a Tauri app with an in-process conductor

    main

    If your UI runs inside a Tauri webview using tauri-plugin-holochain, AppWebsocket.connect() automatically detects the environment and uses a TauriAppTransport via Tauri IPC instead of a standard WebSocket.

    Key details:

    • No code changes required: callZome, appInfo, and signals work exactly as they do with WebSockets.
    • Security: The conductor derives the app ID from the calling window's label (not a JS argument), and Tauri's permission system gates the app_request command.
    • Signing: Zome calls are signed by the in-process keystore via the host signer; no signing keys are exposed to the webview.
    // Inside a tauri-plugin-holochain webview, this returns an AppWebsocket backed
    // by a TauriAppTransport rather than a WsClient. callZome, appInfo, signals, 
    // clone cells, etc. all work unchanged.
    const appWs = await AppWebsocket.connect();
  11. Understand the ZomeIndex type

    main

    The ZomeIndex is a number type used as an internal reference within the Holochain client. It serves as a canonical ordering mechanism for zome initialization.

    Note: You should not manually invent these values; they should be auto-generated from the Zome Bundle definition to ensure correct initialization order and reference integrity.

    export type ZomeIndex = number;