Installing the Node
This guide focuses on the fastest and easiest operator path: install a network-compatible exrpd release, then bootstrap from a snapshot.
It covers Mainnet, Testnet, and Devnet, and includes the following run stacks:
systemctldockercosmovisor- installation with raw binaries
- installation from source
If you specifically need full historical replay from block 0, use Sync from Genesis.
Network reference
| Network | Chain ID | Current Version | Genesis |
|---|---|---|---|
| Mainnet | xrplevm_1440000-1 | v10.0.2 | Genesis |
| Testnet | xrplevm_1449000-1 | v10.0.1 | Genesis |
| Devnet | xrplevm_1449900-1 | v9.0.3 | Genesis |
Recommended flow (snapshot-first)
- Install
exrpd(raw binary or from source). - Initialize and configure your node for the target network.
- Restore snapshot data (when available).
- Run the node with
systemctl,cosmovisor, ordocker.
Public snapshot providers are currently listed for Mainnet and Testnet in Snapshots. If a Devnet snapshot is not published, use State Sync or Sync from Genesis.
1) Install exrpd
Prerequisites
Install required tools first:
sudo apt-get update
sudo apt-get install -y curl wget jq lz4 build-essential git rsyncMethod A: Raw binary (recommended for most operators)
cd /tmp
TARGET_TAG=<target-tag>
wget "https://github.com/xrplevm/node/releases/download/${TARGET_TAG}/node_${TARGET_TAG#v}_Linux_amd64.tar.gz"
tar -xzf "node_${TARGET_TAG#v}_Linux_amd64.tar.gz"
sudo mv bin/exrpd /usr/local/bin/exrpd
sudo chmod +x /usr/local/bin/exrpd
exrpd versionSet <target-tag> from Networks for your network:
- Mainnet:
v10.0.2 - Testnet:
v10.0.1 - Devnet:
v9.0.3
Method B: Build from source
If you build from source, check the required Go version in upstream go.mod before compiling:
REQUIRED_GO=$(curl -fsSL https://raw.githubusercontent.com/xrplevm/node/main/go.mod | awk '/^go /{print $2; exit}')
echo "Required Go: ${REQUIRED_GO}"
go versionIf your installed Go version is older than REQUIRED_GO, upgrade Go before compiling.
sudo apt-get update
sudo apt-get install -y golang-go
git clone https://github.com/xrplevm/node.git
cd node
make build
sudo mv build/exrpd /usr/local/bin/exrpd
sudo chmod +x /usr/local/bin/exrpd
exrpd version2) Initialize and configure for your network
Before starting the node, set evm-chain-id under [evm] in app.toml:
- Mainnet:
evm-chain-id = "1440000" - Testnet:
evm-chain-id = "1449000"
File path (depending on your node home): ~/.exrpd/config/app.toml or /var/lib/exrpd/.exrpd/config/app.toml.
If this node is an active validator signer, do not re-run exrpd init on an existing signer home and do not replace signer state from snapshots. Use one active signer only and preserve ~/.exrpd/data/priv_validator_state.json.
exrpd config set client chain-id xrplevm_1440000-1
exrpd init <moniker> --chain-id xrplevm_1440000-1
wget -O ~/.exrpd/config/genesis.json https://raw.githubusercontent.com/xrplevm/networks/refs/heads/main/mainnet/genesis.json
PEERS=$(curl -sL https://raw.githubusercontent.com/xrplevm/networks/main/mainnet/peers.txt | sort -R | head -n 10 | paste -sd, -)
sed -i.bak -e "s/^seeds *=.*/seeds = \"${PEERS}\"/" ~/.exrpd/config/config.toml3) Restore snapshot data
Snapshot restore is for bootstrapping non-signing nodes (or fresh replacement nodes) only. For active validator signer nodes, do not overwrite chain state with snapshot restore.
Use any provider from Snapshots and extract into ~/.exrpd:
cd ~/.exrpd
wget -O exrpd.tar.lz4 https://evm-sidechain-snapshots-mainnet.s3.us-east-1.amazonaws.com/exrpd.tar.lz4
tar -xI lz4 -f exrpd.tar.lz4If this URL is temporarily unavailable, use another provider from Snapshots and follow that provider's archive format (.tar.lz4 or .tar.zst) and extraction command.
4) Run the node
Option A: systemctl (recommended)
Create a dedicated runtime user (recommended):
sudo useradd --system --home /var/lib/exrpd --create-home --shell /usr/sbin/nologin exrpd || true
sudo mkdir -p /var/lib/exrpd/.exrpd
sudo chown -R exrpd:exrpd /var/lib/exrpdThen move your initialized node home to the service path:
sudo rsync -a ~/.exrpd/ /var/lib/exrpd/.exrpd/
sudo chown -R exrpd:exrpd /var/lib/exrpd/.exrpdCreate /etc/systemd/system/exrpd.service:
[Unit]
Description=XRPL EVM Node (exrpd)
After=network-online.target
[Service]
User=exrpd
Group=exrpd
WorkingDirectory=/var/lib/exrpd
Environment="HOME=/var/lib/exrpd"
ExecStart=/usr/local/bin/exrpd start --home /var/lib/exrpd/.exrpd
Restart=always
RestartSec=3
LimitNOFILE=65535
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=full
[Install]
WantedBy=multi-user.targetStart it:
sudo systemctl daemon-reload
sudo systemctl enable exrpd
sudo systemctl start exrpd
sudo journalctl -u exrpd -fOption B: cosmovisor + systemctl
Install Go first (required for go install):
sudo apt-get update
sudo apt-get install -y golang-goInstall and prepare layout:
sudo env GOBIN=/usr/local/bin go install cosmossdk.io/tools/cosmovisor/cmd/cosmovisor@latest
sudo mkdir -p /var/lib/exrpd/.exrpd/cosmovisor/genesis/bin
sudo cp /usr/local/bin/exrpd /var/lib/exrpd/.exrpd/cosmovisor/genesis/bin/exrpd
sudo chmod +x /var/lib/exrpd/.exrpd/cosmovisor/genesis/bin/exrpd
sudo ln -sfn /var/lib/exrpd/.exrpd/cosmovisor/genesis /var/lib/exrpd/.exrpd/cosmovisor/current
sudo chown -R exrpd:exrpd /var/lib/exrpd/.exrpdIf your restored data includes upgrade-info.json, pre-stage the binary for that upgrade name before starting Cosmovisor:
UPGRADE_NAME=$(jq -r '.name // empty' /var/lib/exrpd/.exrpd/data/upgrade-info.json 2>/dev/null || true)
if [ -n "$UPGRADE_NAME" ]; then
sudo mkdir -p "/var/lib/exrpd/.exrpd/cosmovisor/upgrades/${UPGRADE_NAME}/bin"
sudo cp /usr/local/bin/exrpd "/var/lib/exrpd/.exrpd/cosmovisor/upgrades/${UPGRADE_NAME}/bin/exrpd"
sudo chmod +x "/var/lib/exrpd/.exrpd/cosmovisor/upgrades/${UPGRADE_NAME}/bin/exrpd"
sudo chown -R exrpd:exrpd /var/lib/exrpd/.exrpd/cosmovisor/upgrades
fiCreate /etc/systemd/system/cosmovisor-exrpd.service:
[Unit]
Description=XRPL EVM Node (Cosmovisor)
After=network-online.target
[Service]
User=exrpd
Group=exrpd
WorkingDirectory=/var/lib/exrpd
Environment="DAEMON_NAME=exrpd"
Environment="DAEMON_HOME=/var/lib/exrpd/.exrpd"
Environment="DAEMON_RESTART_AFTER_UPGRADE=true"
Environment="UNSAFE_SKIP_BACKUP=false"
Environment="DAEMON_ALLOW_DOWNLOAD_BINARIES=false"
Environment="HOME=/var/lib/exrpd"
ExecStart=/usr/local/bin/cosmovisor run start --home /var/lib/exrpd/.exrpd
Restart=always
RestartSec=3
LimitNOFILE=65535
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=full
[Install]
WantedBy=multi-user.targetStart it:
sudo systemctl daemon-reload
sudo systemctl enable cosmovisor-exrpd
sudo systemctl start cosmovisor-exrpd
sudo journalctl -u cosmovisor-exrpd -fWith UNSAFE_SKIP_BACKUP=false, first start may take several minutes while Cosmovisor creates a full data backup before restart.
For upgrade operations and safer backup settings, follow Upgrading your node.
Option C: docker
Install Docker first if it is not available:
sudo apt-get update
sudo apt-get install -y docker.io
sudo systemctl enable --now dockerTARGET_TAG=<target-tag>
# Make RPC reachable through -p 26657:26657
# Note: this RPC listener is in config.toml ([rpc].laddr), not app.toml.
sed -i.bak -E 's#^laddr = "tcp://127.0.0.1:26657"#laddr = "tcp://0.0.0.0:26657"#' ~/.exrpd/config/config.toml
docker run -d \
--name xrplevm-node \
--restart unless-stopped \
-p 26657:26657 \
-v /root/.exrpd:/root/.exrpd \
--entrypoint exrpd \
peersyst/exrp:${TARGET_TAG} \
start
docker logs -f xrplevm-nodeUse the exact <target-tag> from Networks (for example, Mainnet v10.0.2).
Validation
exrpd status
curl -s localhost:26657/status | jq .result.sync_infoIf this node is a validator signer, keep a single active validator signer only. Never run two active instances with the same ~/.exrpd/config/priv_validator_key.json, and never roll back ~/.exrpd/data/priv_validator_state.json.
For signer nodes, avoid exrpd unsafe-reset-all, snapshot overwrite on active signer data, and parallel runtime stacks (for example systemctl plus docker) using the same validator key.