Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ live in [`docs.json`](./docs.json).
## Source & accuracy

Content is rebuilt from first principles based on the Livepeer v2 docs at
<https://docs.livepeer.org>. Network values (inflation, unbonding period, active-set size,
[docs.livepeer.org](https://docs.livepeer.org). Network values (inflation, unbonding period, active-set size,
contract addresses) are governance-controlled and change over time — the Reference pages carry a
"last verified" date from on-chain reads, and you can always re-verify against the
[Livepeer Explorer](https://explorer.livepeer.org) and on-chain state. Run `npm run check` to
Expand Down
124 changes: 103 additions & 21 deletions network/guides/orchestrator-activate.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ fund the wallet, stake LPT, activate on-chain, and confirm reward calling.

## 1. Point at a reliable Arbitrum RPC

`-ethUrl` connects the node to Arbitrum One. Free tiers from **Alchemy** (300M compute units/mo) or
**Infura** (100K req/day) work for most operators. Public endpoints like `arb1.arbitrum.io/rpc` are
for testing only — a dropped connection during round initialization can forfeit that round's reward.
`-ethUrl` connects the node to Arbitrum One. The community-run [LiveInfra SPE](https://liveinfraspe.com/)
endpoint is free for verified orchestrators. Free tiers from **Alchemy** (300M compute units/mo) or
**Infura** (100K req/day) also work for most operators. Public endpoints like `arb1.arbitrum.io/rpc`
are for testing only — a dropped connection during round initialization can forfeit that round's reward.

Verify the endpoint is actually Arbitrum One:

Expand All @@ -27,18 +28,21 @@ curl -s -X POST -H "Content-Type: application/json" \
# Expect "result":"0xa4b1" (42161). "0x1" means you're on Ethereum L1 — switch endpoints.
```

## 2. Identify and back up the wallet
## 2. Choose your orchestrator wallet

On first start, `go-livepeer` creates an account and prints the address in the logs. Record it — this
address receives ETH fees and holds your staked LPT.
The orchestrator wallet holds your staked LPT and receives fees. **It never needs to run on the
node** — you only use it to update orchestrator settings, move funds, and vote. Use a hardware wallet
or a [Safe](https://safe.global) multisig.

Alternatively, `go-livepeer` creates an account on first start and prints the address in the logs:

```bash
docker compose logs 2>&1 | grep -i "account\|address"
```

<Warning>
The private key lives at `~/.lpData/arbitrum-one-mainnet/keystore`. **Back it up offline now.**
Losing the keystore means permanent loss of the account and all bonded LPT.
If you use this keystore, its private key lives at `~/.lpData/arbitrum-one-mainnet/keystore`.
**Back it up offline now.** Losing it means permanent loss of the account and all bonded LPT.
</Warning>

## 3. Fund the wallet with ETH on Arbitrum
Expand All @@ -52,14 +56,21 @@ withdrawing from an exchange that supports Arbitrum, or bridging from L1 at

LPT bonded to your address is what puts you in the active set (top orchestrators by total stake).
Check the current threshold on the [Explorer](https://explorer.livepeer.org/orchestrators) before
deciding how much to acquire. Then open the CLI and bond:
deciding how much to acquire. The orchestrator itself only needs a 1 LPT self-bond. **Stake the rest by
delegating from a hardware wallet** rather than bonding it all from a keystore. Self-bond on the
[Explorer](https://explorer.livepeer.org), or in the CLI if the keystore is on the node:

```bash
docker exec -it livepeer-orchestrator livepeer_cli
```

Select the bond/stake option and enter an amount. Two transactions are submitted — `approve`, then
`bond`. Wait for both to confirm.
<Warning>
Transactions in `livepeer_cli` require the node to be started with `-enableCliTxRoutes`. Add it for
these steps only and remove it afterwards. Keep `-cliAddr` on `127.0.0.1:7935` and never expose
port 7935 to the internet.
</Warning>

Either way, two transactions are submitted — `approve`, then `bond`. Wait for both to confirm.

## 5. Activate on-chain

Expand All @@ -71,6 +82,11 @@ In `livepeer_cli`, select **"Invoke multi-step 'become an orchestrator'"** and s
| Fee Cut | `95` | % of ETH fees you keep (95% → delegators get 5%) |
| Service address | `YOUR_PUBLIC_IP:8935` | Must match `-serviceAddr` exactly |

Without a keystore on the node, make the same two calls from your wallet: `transcoder` on the
[`BondingManager`](/network/reference/contracts) and `setServiceURI` on the
[`ServiceRegistry`](/network/reference/contracts), or on the
[`AIServiceRegistry`](/network/reference/contracts) if you serve AI.

<Warning>
**The Explorer displays Fee Cut inverted, as "Fee Share."** Set Fee Cut `95` here and your profile
will show **Fee Share 5%** — the portion passed to delegators. That's the same setting, not a
Expand All @@ -85,36 +101,102 @@ In `livepeer_cli`, select **"Invoke multi-step 'become an orchestrator'"** and s
See [Economics](/network/explanation/economics) for how these two settings affect both your earnings and your
appeal to delegators.

## 6. Confirm reward calling
## 6. Run the node on a throwaway wallet

The machine doing the work is your exposed surface. **Never run it with the orchestrator key.** Start
the node with a fresh `-dataDir` so it generates a new account, send that address a little ETH for
gas, and point it at your orchestrator:

| Flag | Value | Purpose |
| --- | --- | --- |
| `-ethAcctAddr` | throwaway address | Signs for the node, redeems tickets, and can be the reward caller (step 7) |
| `-ethOrchAddr` | your orchestrator address | Fees and rewards accrue here |

<Warning>
If you activated from a keystore on this machine, finish step 7, then move it to cold storage and
delete it from the node. A compromised machine then yields a near-empty wallet, not your stake.
</Warning>

`go-livepeer` calls `reward()` automatically each round by default. Make sure it isn't disabled:
## 7. Set up a reward caller

Delegate reward calling to a separate, low-privilege wallet. It can only call `reward()` — not move
funds, unbond, change settings, or vote — so the orchestrator wallet stays in cold storage
([LIP-118](https://github.com/livepeer/LIPs/blob/master/LIPs/LIP-118.md)).

**Choose the caller:**

<Tabs>
<Tab title="go-livepeer">
The throwaway wallet from step 6. The node reads the on-chain mapping and calls reward for
`-ethOrchAddr` itself — no extra flags.
</Tab>
<Tab title="Standalone caller">
The wallet of a [livepeer-reward-caller](https://github.com/rickstaa/livepeer-reward-caller)
you run yourself — a single static binary with its own keystore. Start the node with
`-reward=false`.
</Tab>
<Tab title="Shared caller">
The community [livepeer.bot caller](https://forum.livepeer.org/t/livepeer-bot-put-your-orchestrator-keys-in-cold-storage-a-shared-lip-118-reward-caller-live-on-arbitrum-one/3330),
which calls reward for every orchestrator that authorizes its address. Nothing to run. Start the
node with `-reward=false`.
</Tab>
</Tabs>

**Authorize it** from your orchestrator wallet — with [`cast`](https://getfoundry.sh/cast/overview)
against the [`BondingManager`](/network/reference/contracts), or with **"Set reward caller"** in
`livepeer_cli` if the keystore is on the node:

```bash
cast send 0x35Bcf3c30594191d53231E4FF333E8A770453e40 \
"setRewardCaller(address)" <REWARD_CALLER_ADDR> \
--rpc-url <ARBITRUM_RPC_URL> \
--keystore <ORCHESTRATOR_KEYSTORE>
```

Set it to `0x0000000000000000000000000000000000000000` to revoke. Arbiscan does not show this method
on the proxy page yet, but it is live on-chain.

## 8. Confirm reward calling

After the next round starts (~22h), your orchestrator's page on the
[Explorer](https://explorer.livepeer.org/orchestrators) shows the reward call. With a standalone or
shared caller, its wallet on Arbiscan shows it too. With go-livepeer, the node logs do:

```bash
docker compose logs 2>&1 | grep -i reward
```

The startup command should **not** include `-reward=false`. A missed round forfeits that round's LPT
permanently — there is no catch-up.
A missed round forfeits that round's LPT permanently — there is no catch-up.

<Note>
**Exception for very low stake:** if reward-call gas costs more than the LPT you'd earn, disabling
automatic calling and calling manually until your stake grows can be the rational choice. Reward
calls use ~350k–450k gas (cents at typical Arbitrum prices).
</Note>

## 7. Verify
<Tip>
A caller that quietly stops looks exactly like one that is working. Send
`/subscribe <orchestrator address>` to [@OrchestratorWatcherBot](https://t.me/OrchestratorWatcherBot)
on Telegram for alerts on missed reward calls, and see
[Monitor your orchestrator](/network/guides/orchestrator-monitor).
</Tip>

## 9. Verify

On [explorer.livepeer.org/orchestrators](https://explorer.livepeer.org/orchestrators), search your
address and confirm **Status**, **Service URI**, **Stake**, **Reward Cut**, and **Fee Cut**. Then
confirm external reachability:
address and confirm **Status**, **Stake**, **Reward Cut**, and **Fee Cut**. The Explorer does not show
the service URI — read it from the [`ServiceRegistry`](/network/reference/contracts), then confirm
external reachability:

```bash
cast call 0xC92d3A360b8f9e083bA64DE15d95Cf8180897431 \
"getServiceURI(address)(string)" <ORCHESTRATOR_ADDR> --rpc-url <ARBITRUM_RPC_URL>
curl -k https://YOUR_PUBLIC_IP:8935/status
```

If the Service URI is wrong or unreachable, update it in `livepeer_cli` (this costs gas). A bad or
unreachable service address is the most common reason an active node still receives no jobs — see the
[FAQ](/network/reference/faq).
If the service URI is wrong or unreachable, update it in `livepeer_cli` or via `setServiceURI` on the
contract (this costs gas). A bad or unreachable service address is the most common reason an active
node still receives no jobs — see the [FAQ](/network/reference/faq).

## Next

Expand Down
7 changes: 6 additions & 1 deletion network/guides/orchestrator-monitor.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ livepeer \
The metrics are served at **`http://localhost:7935/metrics`** — the same port as the go-livepeer CLI;
`-monitor` just activates the `/metrics` path on it.

<Warning>
Port 7935 is the node's private CLI port. Keep `-cliAddr` on loopback and scrape it locally or over
a private network — never expose it to the internet.
</Warning>

| Flag | What it does |
| --- | --- |
| `-monitor` | Enables `/metrics`. Required for any Prometheus scraping. |
Expand Down Expand Up @@ -102,7 +107,7 @@ The metrics you'll actually act on:
<Warning>
The single highest-value alert: **a missed `reward()` call.** Miss a round and that round's LPT is
gone permanently — there's no catch-up. Alert on it, and keep enough ETH on Arbitrum for gas. See
[Activate on Arbitrum](/network/guides/orchestrator-activate#6-confirm-reward-calling).
[Activate on Arbitrum](/network/guides/orchestrator-activate#8-confirm-reward-calling).
</Warning>

## 4. Monitor the AI runner (if you serve AI)
Expand Down
9 changes: 7 additions & 2 deletions network/reference/cli-flags.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ for how to choose values.
| --- | --- | --- |
| `-network` | `arbitrum-one-mainnet` | Network to join (default `offchain` does not participate) |
| `-ethUrl` | RPC URL | Arbitrum One endpoint for on-chain reads/writes |
| `-ethAcctAddr` | ETH address | Orchestrator identity; holds stake, receives fees. Omit to create a new account |
| `-ethAcctAddr` | ETH address | Account the node signs with. Omit to create a new account. With `-ethOrchAddr` this can be a throwaway holding only gas |
| `-ethOrchAddr` | ETH address | Registered orchestrator this node works and calls reward for. Fees and rewards accrue here. See [Activate on Arbitrum](/network/guides/orchestrator-activate#6-run-the-node-on-a-throwaway-wallet) |
| `-serviceAddr` | `ip:port` | Public address gateways use to reach the node |
| `-dataDir` | path | Where keystore and node data are stored (default `~/.lpData`) |

Expand Down Expand Up @@ -58,6 +59,8 @@ for how to choose values.
| Flag | Value | Purpose |
| --- | --- | --- |
| `-reward` | bool | Call `reward()` automatically each round (default `true`) |
| `-cliAddr` | `ip:port` | Where the CLI/metrics server listens (default `127.0.0.1:7935`). Never bind it to a public interface |
| `-enableCliTxRoutes` | bool | Enable transaction, signing, and gas-control routes on the CLI port (default `false`). Turn on only for one-time setup, then remove |
| `-v` | level | Log verbosity (`6` is useful while setting up) |

<Note>
Expand All @@ -70,7 +73,9 @@ for how to choose values.

`livepeer_cli` is an interactive tool that connects to a running node for one-off on-chain actions —
activating as an orchestrator, staking/bonding LPT, updating price, updating the service URI, and
viewing node status. It does **not** need to stay running; only the `livepeer` daemon does.
viewing node status. It does **not** need to stay running; only the `livepeer` daemon does. Read-only
status works out of the box. Any action that sends a transaction requires the node to run with
`-enableCliTxRoutes`.

```bash
# Against a Docker node:
Expand Down
Loading