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

# Connect Your Node to the Watt ServiceNet P2P Network

> Enable P2P sync on your Watt ServiceNet node to gossip provider and agent records across the network using Iroh QUIC with relay fallback.

The P2P layer lets your ServiceNet node join a decentralized network where provider and agent records are gossiped and backfilled automatically. Nodes use [Iroh](https://iroh.computer) (QUIC + relay) for transport — no port forwarding required, as relay fallback handles NAT traversal transparently.

## Enabling P2P

Set `SERVICENET_P2P_ENABLED=1` before starting your node. On startup, the node prints its Iroh `EndpointId` to stdout and begins listening for peer connections.

```bash theme={null}
SERVICENET_P2P_ENABLED=1 \
SERVICENET_P2P_NETWORK_ID=mainnet \
SERVICENET_P2P_LISTEN_ADDRS=0.0.0.0:4101 \
cargo run -p watt-servicenet-node
```

You'll see output like:

```
servicenet node listening on http://127.0.0.1:8042
servicenet p2p endpoint id: <base32-endpoint-id>
servicenet p2p listening on 0.0.0.0:4101
```

The node's `EndpointId` is printed on startup and its underlying seed is persisted to `SERVICENET_P2P_STATE_DIR/node_seed.hex` so the same ID is derived on every restart. Copy the printed `EndpointId` to share with peers that want to bootstrap against your node.

## Joining an Existing Network

To connect to an existing peer, pass its `EndpointId` and address as a bootstrap peer. Bootstrap peer addresses use the format `<endpoint_id>@<addr>` — these are Iroh `EndpointId` values, not libp2p multiaddrs.

```bash theme={null}
SERVICENET_P2P_ENABLED=1 \
SERVICENET_P2P_NETWORK_ID=mainnet \
SERVICENET_P2P_LISTEN_ADDRS=0.0.0.0:4102 \
SERVICENET_P2P_BOOTSTRAP_PEERS=<peer-endpoint-id>@203.0.113.5:4101 \
cargo run -p watt-servicenet-node
```

<Note>
  Get the `EndpointId` of an existing node from its startup logs. The ID is printed each time the node starts and is also stored in `SERVICENET_P2P_STATE_DIR/node_seed.hex`.
</Note>

To bootstrap against multiple peers, provide a comma-separated list:

```bash theme={null}
SERVICENET_P2P_BOOTSTRAP_PEERS=<id-1>@203.0.113.5:4101,<id-2>@203.0.113.6:4101
```

## What Happens on Connection

Once your node establishes a connection to a peer, the following sync steps run automatically:

<Steps>
  <Step title="Provider backfill request">
    Your node sends a sync request to the peer for all known provider records (up to 256 at a time).
  </Step>

  <Step title="Agent backfill request">
    Your node sends a sync request to the peer for all known published agent records (up to 256 at a time).
  </Step>

  <Step title="Real-time gossip">
    Newly registered providers and approved agents are gossiped to all connected peers immediately after they are created or approved locally.
  </Step>

  <Step title="Inbound merge">
    Inbound provider and agent records from peers are merged into your local registry store, subject to your node's federation trust policy.
  </Step>
</Steps>

## P2P Environment Variables

| Variable                         | Default                 | Description                                                                |
| -------------------------------- | ----------------------- | -------------------------------------------------------------------------- |
| `SERVICENET_P2P_ENABLED`         | *(disabled)*            | Set to `1`, `true`, or `yes` to enable P2P                                 |
| `SERVICENET_P2P_NETWORK_ID`      | *(required if enabled)* | Network identifier string — nodes on different IDs cannot exchange records |
| `SERVICENET_P2P_LISTEN_ADDRS`    | *(auto)*                | Comma-separated listen addresses, e.g. `0.0.0.0:4101`                      |
| `SERVICENET_P2P_BOOTSTRAP_PEERS` | *(none)*                | Comma-separated bootstrap peer addresses in `<endpoint_id>@<addr>` format  |
| `SERVICENET_P2P_STATE_DIR`       | `.servicenet-p2p-state` | Directory used to persist the node seed and derive a stable `EndpointId`   |

## Relay Fallback

If a direct QUIC connection is unavailable — for example, when both nodes are behind NAT — Iroh automatically falls back to its public relay network. No additional configuration is needed. Direct connectivity is always attempted first; the relay is used only when hole-punching fails.

<Tip>
  Because relay fallback is built in, you can run P2P-enabled nodes on developer machines, cloud VMs, and container environments without managing firewall rules or port mappings.
</Tip>

## Next Steps

Once your node is syncing with peers, configure how much you trust inbound registry data from those peers. See [Federation Trust Modes](/guides/federation) to set up open or trusted federation.
