Testnet Setup
Testnet Setup
Complete procedure for wiping and setting up the testnet from scratch. This covers node deployment, genesis, and treasury distribution into multisig wallets.
Prerequisites
- SSH access to all 5 nodes (3 bootstrap as root, 2 providers as ubuntu)
- Go 1.24+ for building binaries and running setup scripts
- The genesis treasury seed (stored offline)
Node inventory
Role
Host
SSH
API
Bootstrap
ldn.test.network
root@ldn.test.network
https://ldn.core.test.network
Bootstrap
ffm.test.network
root@ffm.test.network
https://ffm.core.test.network
Bootstrap
nyc.test.network
root@nyc.test.network
https://nyc.core.test.network
Provider
189.1.171.51
ubuntu@189.1.171.51
—
Provider
67.213.117.123
ubuntu@67.213.117.123
—
Step 1: Build
cd ~/workspace/xe-poc-2/core
GOOS=linux GOARCH=amd64 go build \
-ldflags "-X main.version=$(git describe --tags --always)" \
-o /tmp/xe ./cmd/xe/Step 2: Stop all nodes
# Bootstrap nodes (pm2)
for host in ldn.test.network ffm.test.network nyc.test.network; do
ssh root@$host "pm2 stop xe-node"
done
# Provider nodes (systemd)
ssh ubuntu@189.1.171.51 "sudo systemctl stop xe-node"
ssh ubuntu@67.213.117.123 "sudo systemctl stop xe-node"Step 3: Deploy binary and wipe data
# Bootstrap nodes
for host in ldn.test.network ffm.test.network nyc.test.network; do
scp /tmp/xe root@$host:/usr/local/bin/xe-node
ssh root@$host "rm -rf /var/lib/xe-node/ledger"
done
# Provider nodes
for host in 189.1.171.51 67.213.117.123; do
scp /tmp/xe ubuntu@$host:/tmp/xe-node
ssh ubuntu@$host "sudo cp /tmp/xe-node /usr/local/bin/xe-node && \
sudo chmod +x /usr/local/bin/xe-node && \
sudo rm -rf /var/lib/xe-node/ledger"
done[!WARNING] Data wipe deletes libp2p keys If you also delete
/var/lib/xe-node/host.key, new peer IDs will be generated on startup and you must update all dial configurations. Only delete theledger/subdirectory to preserve peer IDs.
Step 4: Start nodes
# Bootstrap nodes
for host in ldn.test.network ffm.test.network nyc.test.network; do
ssh root@$host "pm2 start xe-node"
done
# Provider nodes
ssh ubuntu@189.1.171.51 "sudo systemctl start xe-node"
ssh ubuntu@67.213.117.123 "sudo systemctl start xe-node"Step 5: Verify genesis
Each node auto-applies the embedded genesis block on first boot, minting 100,000,000 XE to the treasury account.
for api in ldn.core.test.network ffm.core.test.network nyc.core.test.network; do
echo -n "$api: "
curl -s "https://$api/frontiers" | python3 -c \
"import sys,json; d=json.load(sys.stdin); print(len(d), 'accounts')"
doneAll nodes should show 1 account (the genesis treasury).
Step 6: Treasury distribution
The genesis block mints to a single-key account. The setup script distributes the supply into four 2-of-3 multisig wallets:
Wallet
Amount
Purpose
Treasury-A
50,000,000 XE
Primary reserve
Treasury-B
30,000,000 XE
Operations
Treasury-C
10,000,000 XE
Grants / ecosystem
Treasury-D
10,000,000 XE
Emergency reserve
cd ~/workspace/xe-poc-2/core
go run ./scripts/setup-treasury/ <genesis-seed-hex>The script:
- Opens 4 multisig accounts (
multisig_open, 2-of-3 threshold) - Sends XE from genesis to each wallet
- Receives on each multisig wallet (1-of-N)
- Verifies all balances
- Prints key material for offline storage
Keys are deterministically derived from the genesis seed, so rerunning after a testnet wipe produces the same addresses.
[!DANGER] Save key material The script prints private seeds for all 12 multisig keys. Save these offline immediately. They are not stored anywhere else.
Optional: custom API endpoint
go run ./scripts/setup-treasury/ <genesis-seed-hex> https://ffm.core.test.networkStep 7: Verify
Check the explorer to confirm:
- Genesis account has 0 XE remaining
- Four multisig accounts exist with correct balances
- Each multisig account shows "multisig 2 of 3" badge
- Blocks propagated to all nodes (check frontiers)
# Quick verification
for api in ldn.core.test.network ffm.core.test.network nyc.core.test.network; do
echo "$api:"
curl -s "https://$api/frontiers" | python3 -c \
"import sys,json; d=json.load(sys.stdin); print(f' {len(d)} accounts')"
doneShould show 5 accounts on each node (1 genesis + 4 treasury wallets).
Token model summary
After setup, the testnet has:
Token
Supply
Source
XE
100,000,000 (fixed)
Genesis block, distributed to 4 multisig wallets
XUSD
Unlimited (faucet)
100 XUSD per claim, once per account per 24 hours
- XE cannot be claimed. New XE enters circulation only via lease settlement (provider emission).
- XUSD is the testnet faucet token. Any account can claim 100 XUSD per day via
xe fund. - Voting weight is based on XUSD balance, not XE.
Peer ID recovery
If peer IDs change (full data wipe including host.key), get new multiaddrs from logs:
for host in ldn.test.network ffm.test.network nyc.test.network; do
echo -n "$host: "
ssh root@$host "pm2 logs xe-node --lines 200 --nostream --no-color 2>/dev/null" \
| grep "Listening on: /ip4/" | grep -v "127.0.0.1\|172.17" | head -1 \
| grep -oP '/ip4/.+'
doneThen update PM2 configs (bootstrap) and systemd unit files (providers) with the new -dial addresses.