# Intercom

## Example App: `intercom/` (Built on `trac-peer`)

`intercom/` is a reference “real app” built on top of the `trac-peer` runtime.

It’s useful if you want to see what a production-ish subnet app repo looks like: a runner that boots MSB + peer, a contract/protocol pair, and a couple of optional features (sidechannels, timer).

### What Intercom demonstrates

* **How to ship an app**: a repo that depends on `trac-peer` and wires up `Protocol + Contract + Features`.
* **How to run multi-peer subnets**: bootstrap an “app network”, then join more peers.
* **Roles**: admin, writers, and indexers (durability vs cost/ops).
* **Sidechannels**: fast, ephemeral P2P messaging alongside the contract state machine.

### Get Intercom

Clone the repo:

```sh
git clone https://github.com/Trac-Systems/intercom
```

### Prerequisites

* **Node.js**: Intercom is intended to run on **Node 22+** (prefer 22/23; avoid 24 if you hit Pear/native issues).
* **Pear runtime**:

```sh
npm install -g pear
pear -v
```

### Install

```sh
cd ../intercom
npm install
```

For full Intercom operational guidance (first-run decisions, security defaults, etc.), also read [`../intercom/SKILL.md`](https://github.com/Trac-Systems/intercom/blob/main/SKILL.md).

### Create a new Intercom subnet (bootstrap / admin peer)

Pick a subnet channel name (this is the app’s rendezvous string) and start the first peer:

```sh
cd ../intercom
pear run . admin --subnet-channel my-intercom-app
```

On startup, Intercom prints the important bits you’ll need later:

* `Peer subnet bootstrap: <hex32>` — share this with joiners (also persisted to `stores/admin/subnet-bootstrap.hex`)
* `Peer pubkey (hex): <hex32>` — this is the admin peer’s public key (used for `/add_admin`)
* `Peer writer key (hex): <hex32>` — the admin peer’s writer key (used for `/add_writer` / `/add_indexer`)
* `MSB network bootstrap: <hex32>` + `MSB channel: <string>` — the embedded MSB node identifiers Intercom is using

#### First-time admin setup (required on new subnets)

On a brand-new subnet, you must set the subnet admin once, on the bootstrap node:

```txt
/add_admin --address "<ADMIN_PEER_PUBLICKEY_HEX32>"
```

Verify:

```txt
/get --key admin --confirmed false
```

### Start joiners (alice + bob)

Joiners must use the same subnet channel and the bootstrap’s subnet bootstrap hex:

```sh
cd ../intercom
pear run . alice --subnet-channel my-intercom-app --subnet-bootstrap <ADMIN_SUBNET_BOOTSTRAP_HEX32>
pear run . bob   --subnet-channel my-intercom-app --subnet-bootstrap <ADMIN_SUBNET_BOOTSTRAP_HEX32>
```

Each joiner prints its own:

* `Peer pubkey (hex)` (identity)
* `Peer writer key (hex)` (what the admin approves as writer/indexer)

### Writers and indexers (recommended guidance)

Intercom itself is a non-financial app example. Rule of thumb:

* **Non-financial apps**: 1 indexer can be enough.
* **Financial / “value” apps**: run **3 indexers**, ideally operated by different parties and in different locations.
* The **first indexer is usually the admin** peer.

#### Gated (default): admin approves writers/indexers

On the admin peer:

```txt
/add_writer --key "<JOINER_WRITER_KEY_HEX32>"
```

To make a peer an indexer (durable availability for reads / indexing):

```txt
/add_indexer --key "<JOINER_WRITER_KEY_HEX32>"
```

#### Open apps: auto-add writers

On the admin peer:

```txt
/set_auto_add_writers --enabled 1
```

### Sidechannels (fast P2P messaging)

Intercom always joins the **entry channel**:

```txt
0000intercom
```

You can join additional channels at runtime:

```txt
/sc_join --channel "team-room"
```

Send:

```txt
/sc_send --channel "team-room" --message "hello from alice"
```

Inspect:

```txt
/sc_stats
```

#### Sidechannel flags supported by Intercom’s runner

Intercom’s `index.js` supports (via flags or env):

* `--sidechannels "a,b,c"` (or `--sidechannel "a,b,c"`) — join extra channels at startup (entry channel is always joined)
* `--sidechannel-debug 1` — verbose logs
* `--sidechannel-max-bytes <n>` — payload size guard
* `--sidechannel-allow-remote-open 0|1` — accept/reject remote open requests (default: on)
* `--sidechannel-auto-join 0|1` — auto-join requested channels (default: off)

Example:

```sh
pear run . alice --subnet-channel my-intercom-app --subnet-bootstrap <ADMIN_SUBNET_BOOTSTRAP_HEX32> \
  --sidechannels "team-room,alerts" \
  --sidechannel-debug 1
```

### RPC (wallet / dApp connectivity)

Intercom is a **terminal-first** reference app. Its runner (`../intercom/index.js`) starts the interactive terminal and sidechannels, but it does **not** expose the `trac-peer` HTTP RPC server by default.

If you want an app that wallets/dApps can talk to over HTTP:

* follow the `trac-peer` RPC docs (`docs/04-rpc.md`, `docs/16-peer-rpc-reference.md`)
* add RPC wiring to your app runner (similar to how `trac-peer/scripts/run-peer.mjs` does it)

### Using your local `trac-peer/` checkout (optional, for contributors)

Intercom pins `trac-peer` by commit. If you want Intercom to use *your local* `trac-peer/` checkout while developing:

1. Edit `../intercom/package.json`:
   * change the `trac-peer` dependency to `file:../trac-peer`
2. Reinstall:

```sh
cd ../intercom
rm -rf node_modules package-lock.json
npm install
```

### Where to look in code (Intercom repo)

* Runner: [`intercom/index.js`](https://github.com/Trac-Systems/intercom/blob/main/index.js)
* Protocol: [`intercom/contract/protocol.js`](https://github.com/Trac-Systems/intercom/blob/main/contract/protocol.js)
* Contract: [`intercom/contract/contract.js`](https://github.com/Trac-Systems/intercom/blob/main/contract/contract.js)
* Sidechannels: [`intercom/features/sidechannel/index.js`](https://github.com/Trac-Systems/intercom/blob/main/features/sidechannel/index.js)
* Timer feature example: [`intercom/features/timer/index.js`](https://github.com/Trac-Systems/intercom/blob/main/features/timer/index.js)

Intercom’s own guide:

* [`intercom/SKILL.md`](https://github.com/Trac-Systems/intercom/blob/main/SKILL.md)
