Prerequisites
You need the following installed before starting:- Node.js v18 or later and yarn
- Go 1.21 or later (for building go-livepeer)
- git
- An Ethereum wallet with a private key (for Hardhat, the default accounts are pre-funded — no setup needed)
Deploy the protocol contracts
Compile the contracts
contracts/ using the compiler version specified in hardhat.config.ts. Output goes to artifacts/.Start a local Hardhat node
Open a separate terminal and leave this running for the duration of your development session.Hardhat starts a local JSON-RPC node at
http://127.0.0.1:8545 with chain ID 31337. It pre-funds 20 accounts with 10,000 ETH each and prints their private keys to stdout.Deploy all contracts
In your original terminal, run the deploy script against the local node:The
On completion, contract addresses are written to
gethDev network config (from deploy/migrations.config.ts) sets short round lengths and unlock periods suitable for local testing:| Parameter | Value |
|---|---|
roundLength | 50 blocks |
unbondingPeriod | 7 rounds |
unlockPeriod | 50 blocks |
faucet.requestAmount | 10 LPT |
faucet.requestWait | 1 hour |
deployments/gethDev/. The deployer account is set as Controller owner and Governor owner. The faucet is seeded with 6,343,700 LPT (genesis.crowdSupply) and the deployer receives 500,000 LPT (genesis.companySupply).What gets deployed
The deploy script (deploy/deploy_contracts.ts) deploys and registers the following contracts automatically. All proxy contracts are registered in the Controller.
| Contract | Notes |
|---|---|
| Controller | Central registry. Owner set to Governor after deployment. |
| Minter | Inflation schedule. Granted MINTER_ROLE on LivepeerToken. |
| LivepeerToken | ERC-20. Deployed fresh for non-Arbitrum networks. |
| LivepeerTokenFaucet | Test LPT distribution. Seeded with crowdSupply. |
| TicketBroker | Proxy + target. Also registered as JobsManager for legacy Minter compatibility. |
| BondingManager | Proxy + target. Linked with SortedDoublyLL library. |
| BondingVotes | Proxy + target. Checkpoint store for governance voting power. |
| RoundsManager | Deployed as AdjustableRoundsManager on non-live networks, allowing round length to be changed programmatically in tests. |
| ServiceRegistry | Proxy + target. |
| MerkleSnapshot | Registered in Controller. |
| Governor | Ownership transferred to deployer account (or governance multisig on mainnet). |
| Treasury | OpenZeppelin TimelockController. |
| LivepeerGovernor | Proxy + target. Initialised with voting parameters from migrations.config.ts. |
LivepeerTokenFaucet is the only contract that is skipped on production networks (mainnet, arbitrumMainnet). The deploy script gates it with if (!isProdNetwork(hre.network.name)).Connect go-livepeer to your local contracts
With contracts deployed, you can run go-livepeer nodes against your local stack.Start an orchestrator node
Replace The key flags for local contract targeting:
<CONTROLLER_ADDRESS> with the address from the previous step and <KEYSTORE_PATH> with a path to an Ethereum keystore file (you can export one of the Hardhat accounts).| Flag | Purpose |
|---|---|
-network offchain | Disables built-in network configs so -ethController is used directly |
-ethUrl | JSON-RPC endpoint of your local Hardhat node |
-ethController | Address of the Controller contract from your deployment |
-initializeRound | Automatically initialises a new round when needed; essential for local testing |
Start a gateway node
In a separate terminal, using a different keystore account:Using
-orchAddr directly bypasses the ServiceRegistry lookup and connects the gateway to your local orchestrator immediately.Request test LPT from the faucet
The faucet address is in Each call transfers 10 LPT to the caller. The rate limit is 1 hour between requests, but whitelisted addresses bypass it entirely. Add your test addresses to the whitelist by calling
deployments/gethDev/LivepeerTokenFaucet.json. Call request() directly using cast or the go-livepeer CLI:addToWhitelist(address) from the deployer account.Deploying to Arbitrum Sepolia
The same deploy script targets Arbitrum Sepolia with a different network name. You need a funded Sepolia wallet (Sepolia ETH from a faucet) and an Arbitrum Sepolia RPC URL.arbitrumSepolia entry to hardhat.config.ts pointing at your RPC URL, then use the defaultConfig from migrations.config.ts as your parameter baseline. The faucet deploys and is seeded the same as local — crowdSupply worth of test LPT.
Related pages
Blockchain Contracts
Full technical reference for every protocol contract: purpose, key functions, and source code.
Contract Addresses
Current and historical mainnet contract addresses across Arbitrum One and Ethereum Mainnet.
Protocol repo on GitHub
Source code, deploy scripts, and migration configs for the Livepeer protocol.
go-livepeer on GitHub
Node implementation. Build from source or use pre-built binaries.