1. Requirements
| Linux | macOS | |
|---|---|---|
| Platform | x86_64 (Ubuntu 22.04+, Debian 12+, or any modern distro) | Apple Silicon or Intel (macOS 13+) |
| RAM | 2 GB minimum | |
| Disk | 20 GB | |
| Network | Port 30303/tcp open inbound | |
| Stake | 10 DOLI per bond (to produce blocks) | |
2. Install
The install script detects your platform and installs doli-node and doli from
GitHub Releases.
# One-line install (auto-detects OS and architecture)
curl -sSfL https://doli.network/install.sh | sh
After installation, both commands are available system-wide:
| Binary | Purpose | Linux path | macOS path |
|---|---|---|---|
| doli | Wallet CLI | /usr/bin/doli | /usr/local/bin/doli |
| doli-node | Full node | /usr/bin/doli-node | /usr/local/bin/doli-node |
To upgrade later, run the same command. It replaces both binaries with the latest release.
3. Create a Wallet
# Create a new wallet with a 24-word recovery phrase
doli new
# Verify your wallet was created doli info # Check your balance doli balance
If you already have a seed phrase, restore your wallet instead:
# Restore from a 24-word seed phrase
doli restore
The default wallet location is ~/.doli/wallet.json. You can use a custom path with -w:
# Use a wallet at a custom path
doli -w /path/to/my-wallet.json info
4. Start the Node
Quick start (foreground)
# Start syncing to chain tip (Ctrl+C to stop)
doli-node run
Linux Persistent service with systemd
# Create the service file sudo tee /etc/systemd/system/doli-node.service > /dev/null <<EOF [Unit] Description=DOLI Node After=network-online.target Wants=network-online.target [Service] Type=simple User=$USER ExecStart=/usr/bin/doli-node run Restart=always RestartSec=5 LimitNOFILE=65536 [Install] WantedBy=multi-user.target EOF # Enable and start sudo systemctl daemon-reload sudo systemctl enable doli-node sudo systemctl start doli-node # Follow logs sudo journalctl -u doli-node -f
macOS Persistent service with launchd
# Create the plist cat > ~/Library/LaunchAgents/network.doli.node.plist <<EOF <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>network.doli.node</string> <key>ProgramArguments</key> <array> <string>/usr/local/bin/doli-node</string> <string>run</string> </array> <key>RunAtLoad</key> <true/> <key>KeepAlive</key> <true/> <key>StandardOutPath</key> <string>/tmp/doli-node.log</string> <key>StandardErrorPath</key> <string>/tmp/doli-node.log</string> </dict> </plist> EOF # Load and start launchctl load ~/Library/LaunchAgents/network.doli.node.plist # Follow logs tail -f /tmp/doli-node.log
Wait until the node is fully synced. Check sync progress:
curl -s -X POST http://127.0.0.1:8545 \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","method":"getChainInfo","params":{},"id":1}' | jq .
When bestHeight matches the network tip and syncing is false, your node is ready.
5. Become a Block Producer
Block production requires three steps: add a BLS attestation key, register as a producer, and restart the node in producer mode.
Step 1 — Add BLS key
BLS keys are required for liveness attestations. This is a one-time operation:
# Add BLS attestation key to your wallet
doli add-bls
Step 2 — Register
Registration requires at least 10 DOLI per bond. You can register with one or more bonds:
# Register as a producer with 1 bond (10 DOLI) doli producer register --bonds 1 # Check registration status doli producer status
Step 3 — Restart node in producer mode
Stop your sync-only node and restart it with producer flags.
Linux
# Stop the sync-only service sudo systemctl stop doli-node # Update the service to produce blocks sudo tee /etc/systemd/system/doli-node.service > /dev/null <<EOF [Unit] Description=DOLI Producer Node After=network-online.target Wants=network-online.target [Service] Type=simple User=$USER ExecStart=/usr/bin/doli-node run --producer --producer-key /home/$USER/.doli/wallet.json Restart=always RestartSec=5 LimitNOFILE=65536 [Install] WantedBy=multi-user.target EOF # Reload and restart sudo systemctl daemon-reload sudo systemctl start doli-node
macOS
# Stop the sync-only service launchctl unload ~/Library/LaunchAgents/network.doli.node.plist # Update the plist to produce blocks cat > ~/Library/LaunchAgents/network.doli.node.plist <<EOF <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>network.doli.node</string> <key>ProgramArguments</key> <array> <string>/usr/local/bin/doli-node</string> <string>run</string> <string>--producer</string> <string>--producer-key</string> <string>/Users/YOUR_USERNAME/.doli/wallet.json</string> </array> <key>RunAtLoad</key> <true/> <key>KeepAlive</key> <true/> <key>StandardOutPath</key> <string>/tmp/doli-node.log</string> <key>StandardErrorPath</key> <string>/tmp/doli-node.log</string> </dict> </plist> EOF # Replace YOUR_USERNAME with your macOS username, then load launchctl load ~/Library/LaunchAgents/network.doli.node.plist
6. Bond Stacking
More bonds mean more block slots. Each bond costs 10 DOLI and adds one ticket to the round-robin rotation.
# Add 5 more bonds (requires 50 DOLI) doli producer add-bond --count 5 # View per-bond vesting details doli producer bonds # Withdraw bonds (instant, FIFO order, vesting penalty may apply) doli producer request-withdrawal --count 2 # Dry run — see penalties before withdrawing doli producer simulate-withdrawal --count 2
7. Firewall
Linux
# UFW (Ubuntu/Debian) sudo ufw allow 30303/tcp # firewalld (RHEL/Fedora) sudo firewall-cmd --permanent --add-port=30303/tcp sudo firewall-cmd --reload
macOS
macOS firewall is off by default. If you enabled it, allow incoming connections for doli-node:
System Settings → Network → Firewall → Options → add /usr/local/bin/doli-node and set to Allow incoming connections.
8. Upgrade
# Re-run the install script (replaces both binaries)
curl -sSfL https://doli.network/install.sh | sh
Or use the built-in upgrade command:
# Self-upgrade from GitHub Releases
doli upgrade
Linux Restart after upgrade
sudo systemctl restart doli-node
macOS Restart after upgrade
launchctl unload ~/Library/LaunchAgents/network.doli.node.plist launchctl load ~/Library/LaunchAgents/network.doli.node.plist
9. Common Commands
| Command | Description |
|---|---|
| doli info | Show wallet address and public key |
| doli balance | Check balance (confirmed, immature, bonded) |
| doli send doli1... 20 | Send 20 DOLI to an address |
| doli history | Transaction history |
| doli chain | Chain info (height, slot, epoch, hash) |
| doli add-bls | Add BLS attestation key (required for producers) |
| doli producer status | Producer registration and bond status |
| doli producer list | List all active producers |
| doli producer bonds | Per-bond vesting details |
| doli producer add-bond --count N | Stake N more bonds (10 DOLI each) |
| doli producer request-withdrawal --count N | Withdraw N bonds (FIFO, penalty may apply) |
| doli producer simulate-withdrawal --count N | Dry run — preview penalties before withdrawal |
| doli upgrade | Self-upgrade to latest release |
| doli wipe | Wipe chain data for a fresh resync (preserves keys) |
Use -w /path/to/wallet.json to specify a non-default wallet. Use -n testnet for testnet operations (tdoli1 addresses, port 18545).
10. Troubleshooting
Node not syncing
Check that port 30303 is reachable and your node has peers:
Linux
sudo journalctl -u doli-node --no-pager -n 50 | grep -i "peer\|connect\|error"
macOS
tail -100 /tmp/doli-node.log | grep -i "peer\|connect\|error"
Wipe and resync
If the node is stuck or forked, use the built-in wipe command (preserves your wallet and keys):
# Stop the node first # Linux sudo systemctl stop doli-node # macOS launchctl unload ~/Library/LaunchAgents/network.doli.node.plist # Wipe chain data doli wipe # Then restart the node
Producer not producing
- Confirm registration:
doli producer status - Check BLS key:
doli info— should show a BLS public key - Check the node is running in producer mode: look for
--producerin the service - Check epoch: new registrations activate at the next epoch boundary