Quick Start

Build the xe CLI, run a node, create a wallet, and lease a VM

Build the xe binary, run a node, create a wallet, and lease a VM.

Building from source

Prerequisites

  • Go 1.25 or later (the module declares go 1.25.0)
  • Git

Clone and build

git clone https://github.com/xeprotocol/core.git
cd core
go build -o xe ./cmd/xe/

To embed a version string (reported by xe version and GET /node):

go build -ldflags "-X main.version=$(git rev-parse --short HEAD)" -o xe ./cmd/xe/

Running a node

./xe node

Starts a node daemon with default settings: libp2p on port 9000, HTTP API on port 8080, data in ./data. The node runs until SIGINT/SIGTERM.

Connecting to a network

./xe node -dial /ip4/45.77.226.208/tcp/9000/p2p/12D3KooW...

Multiple bootstrap peers can be comma-separated. The multiaddr above is a public testnet bootstrap node; there is no mainnet to join yet.

Exposing the API

./xe node -api-bind 0.0.0.0 -cors-origin "https://explorer.example.com"

See xe CLI Reference for all flags.

Using the CLI

The xe binary is both the node daemon and the client tool. Client commands work against any node's API:

# Use a remote node (no local node needed)
export XE_NODE=https://ldn.core.test.network

[!WARNING] Testnet only The walkthrough below targets the public testnet. https://ldn.core.test.network is the CLI's built-in default for XE_NODE, and the faucet step is a testnet affordance with no mainnet equivalent.

Create a wallet

xe wallet create
# Wallet created!
#   Address: 7df14bbd...891e85aa
#   File:    ~/.xe/wallet.seed

Fund the wallet

Leases are paid in XUSD. On testnet you ask the faucet service for a grant:

xe faucet
# Requested testnet XUSD for 7df14bbd...891e85aa
#   Tx: 3f0c8b12...

xe faucet POSTs your wallet address to the faucet service at XE_FAUCET (default https://faucet.test.network). The service holds the network's authorized minter wallet (sys.minter), mints XUSD, and sends it to your address. There is no permissionless self-mint: minting is authorization-gated in the ledger.

[!WARNING] The faucet service is not deployed yet faucet.test.network does not currently resolve, so xe faucet fails before it reaches any service. Deployment is tracked in xeprotocol/faucet#4. Until that lands there is no self-service way to fund a testnet wallet, and the steps below cannot be completed end to end.

Receive the funds

A send credits nothing until the recipient receives it — the funds sit as pending on your account until you publish a receive block. Nothing auto-receives on your behalf:

xe receive
# Receiving 1 pending send(s)...
#   Received 100 XUSD from 849382f7...2e2f4d64
xe wallet balance
# Address: 7df14bbd...891e85aa
#   XUSD: 100

Check providers

xe providers
# [1] 42346388...dd015557
#     Total: 4 vCPU, 8192 MB, 50 GB
#     Free:  4 vCPU, 8192 MB, 50 GB
#     XUSD:  100 | Leases: 0 active, 0 total

Lease a VM

xe lease --vcpus 1 --memory 1024 --duration 300
# Lease: 1 vCPU, 1024 MB, 1 GB, 300s (mult=1000)
# Cost: 0.031 XUSD, Stake: 0.0062 XUSD
#
# Provider: 42346388...dd015557
# Lease submitted: ab9ada6f...
# Waiting for acceptance...
# Lease accepted!
#
#   xe vm ab9ada6f...
#   xe ssh ab9ada6f...

--memory is in MB and --disk in GB; both default to 1024 and 1 if omitted, alongside --vcpus 1 and --duration 300 (seconds). Cost is derived from the resource rates and the provider's price multiplier, and duration is billed per started hour — a 300-second lease is charged as one hour. See Cost Model.

SSH into the VM

xe ssh ab9ada6f...
# root@lima-xe-ab9ada6f:~#

The SSH connection goes through the network's SSH gateway with end-to-end encryption — your SSH client negotiates directly with the VM's sshd. The gateway is taken from XE_SSH_HOST / XE_SSH_PORT, which default to the testnet gateway ldn.test.network:2222.

Full demo

From nothing to a root shell on a decentralised VM:

xe wallet create
xe faucet          # testnet only — service not deployed yet (faucet#4)
xe receive         # pending sends do not credit until received
xe lease --duration 300
xe ssh <hash>

Docker deployment

FROM golang:1.25-alpine AS build
ARG VERSION=dev
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -ldflags "-X main.version=${VERSION}" -o /xe ./cmd/xe/

FROM alpine:3.20
COPY --from=build /xe /usr/local/bin/xe
EXPOSE 8080 9000
ENTRYPOINT ["xe", "node"]
docker build -t xe .
docker run -p 8080:8080 -p 9000:9000 -v xe-data:/data \
  xe -data /data -api-bind 0.0.0.0 \
  -dial /ip4/45.77.226.208/tcp/9000/p2p/12D3KooW...

See also