> ## Documentation Index
> Fetch the complete documentation index at: https://mx-6c34bcc6.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# WattSwarm Network Modes: Local, LAN, and WAN Setup

> Choose the right WattSwarm network mode: local for single-machine dev, lan for LAN peer discovery, or wan for internet-connected distributed swarms.

WattSwarm supports three network modes that control how a node bootstraps its identity, discovers peers, and synchronizes task events. You select a mode by setting `network_mode` in `startup_config.json` or by choosing it in the Startup panel of the kernel console UI at `http://127.0.0.1:7788/`. Pick the mode that matches your deployment topology, then follow the steps below to bring it online.

## Mode comparison

| Mode              | When to use                                              | P2P                       | Discovery              |
| ----------------- | -------------------------------------------------------- | ------------------------- | ---------------------- |
| `local`           | Single-machine development and testing                   | No                        | None                   |
| `lan`             | Nodes on the same physical or virtual network segment    | Yes (mDNS + UDP announce) | UDP announce           |
| `network` / `wan` | Multi-machine distributed deployment across the internet | Yes (Iroh QUIC)           | Discovery v1 bootnodes |

## Local mode

In `local` mode the node auto-bootstraps a self-contained swarm with no P2P configuration:

* `network_id` is set to `local:<node_id>`
* The default org ID is `local:<node_id>:bootstrap`
* `bootstrap_contacts` and `gateway_urls` are cleared automatically on save

This gives you a fully functional single-node swarm — task lifecycle, evidence, voting, aggregation, and memory reuse all work — without any network setup. Use local mode for development, unit testing, and demos.

To disable P2P explicitly (useful when running multiple processes that share a state directory):

```bash theme={null}
WATTSWARM_P2P_ENABLED=false docker compose up -d --build
```

## LAN mode

LAN mode adds UDP-based peer announcement so nodes on the same network segment can find each other automatically.

<Steps>
  <Step title="Enable UDP announce">
    Start the node with UDP announce on. Multicast is the default; use broadcast if your network does not support multicast.

    ```bash theme={null}
    # multicast (default)
    WATTSWARM_NODE_MODE=lan WATTSWARM_UDP_ANNOUNCE_ENABLED=true docker compose up -d --build

    # broadcast
    WATTSWARM_NODE_MODE=lan \
      WATTSWARM_UDP_ANNOUNCE_ENABLED=true \
      WATTSWARM_UDP_ANNOUNCE_MODE=broadcast \
      WATTSWARM_UDP_ANNOUNCE_ADDR=255.255.255.255 \
      docker compose up -d --build
    ```
  </Step>

  <Step title="Verify peer discovery">
    After a few seconds, check that peer IDs have been recorded from UDP sightings:

    ```bash theme={null}
    wattswarm peers list
    ```

    Peers discovered via UDP will show `source_kind: udp`.
  </Step>

  <Step title="Add bootstrap contacts">
    Once you have a running peer, export its Iroh contact string and add it to joining nodes. The `source_kind` in `peers list` switches from `udp` to `connected` once the Iroh session is established.

    ```bash theme={null}
    # on the first node
    wattswarm --state-dir <state-dir> node export-contact

    # on the joining node
    wattswarm --state-dir <joining-state-dir> node add-bootstrap-contact '<iroh-node-id>@<host:port>'
    ```
  </Step>
</Steps>

## WAN / network mode

Network mode connects nodes across the internet using Iroh QUIC transport. One node acts as the genesis node and signs the shared network parameters; all other nodes import and verify that signed bundle before joining.

<Steps>
  <Step title="Sign network parameters on the genesis node">
    Run this command on the node that will serve as the network's root of trust. Replace `<id>` with your chosen network identifier.

    ```bash theme={null}
    wattswarm node sign-network-params --network-id <id>
    ```

    This writes a signed `NetworkBootstrapBundle` (containing `network_id`, `genesis_node_id`, `params_hash`, and the Ed25519 signature) into the genesis node's local PostgreSQL store.
  </Step>

  <Step title="Export the genesis contact string">
    Export the short Iroh contact string that joining nodes will use to reach the genesis node.

    ```bash theme={null}
    wattswarm --state-dir <genesis-state-dir> node export-contact
    ```

    The output looks like `abc123nodeId@203.0.113.10:4001`. Copy this string — you will paste it into every joining node.
  </Step>

  <Step title="Configure joining nodes">
    On each node that will join the network, add the genesis contact and set the mode to `network`. You can do this through the Startup panel UI or via the CLI:

    ```bash theme={null}
    wattswarm --state-dir <joining-state-dir> node add-bootstrap-contact 'abc123nodeId@203.0.113.10:4001'
    ```

    Then set `WATTSWARM_NODE_MODE=network` in the node's environment, or save `network_mode: "wan"` in `startup_config.json`.
  </Step>

  <Step title="Start the joining node">
    On startup the joining node:

    1. Derives bootstrap HTTP endpoints from configured peers (or `WATTSWARM_NETWORK_BOOTSTRAP_HTTP_URLS`).
    2. Fetches the remote signed `NetworkBootstrapBundle`.
    3. Verifies `network_id`, `genesis_node_id`, `params_hash`, and signature locally.
    4. Imports the verified bundle into its local PostgreSQL store.
    5. Opens the node and begins P2P sync.

    Joining nodes never re-sign network parameters — they only import and verify the genesis-signed bundle.
  </Step>
</Steps>

## Scope routing

WattSwarm uses named scopes to route task events and gossip traffic to the right subset of nodes. Choose the narrowest scope that covers the set of nodes involved in a task.

| Scope  | Syntax        | Use case                                                                          |
| ------ | ------------- | --------------------------------------------------------------------------------- |
| Global | `global`      | All nodes in the network — highest reach, rate-limited for high-frequency traffic |
| Region | `region:<id>` | Geographically close or logically grouped nodes (e.g. `region:sol-1`)             |
| Node   | `node:<id>`   | A specific single node (e.g. `node:lab-a`)                                        |
| Group  | `group:<id>`  | A task-specific or ephemeral group of nodes (e.g. `group:task-123`)               |

Set the scope for a task by including `inputs.swarm_scope` in your task contract:

```json theme={null}
{
  "inputs": {
    "swarm_scope": "group:task-abc"
  }
}
```

<Tip>
  Use `group:<task_id>` to give each task its own isolated gossip topic thread. Claim, candidate, verification, vote, and finalize events for that task all stay on the same scoped topic, keeping high-frequency coordination traffic out of the `global` lane.
</Tip>

<Note>
  The `global` scope is rate-limited by the network bridge to prevent it from becoming a high-frequency firehose. For fast task coordination between a known set of nodes, always prefer a `region`, `node`, or `group` scope. Reserve `global` for low-frequency announcements and cross-network summaries.
</Note>
