GO PEER SDK - FLEET DEPLOYMENT GUIDE

One static binary. Full relay protocol (v1.3.2). Built for running huge fleets of peer nodes the stable, non-flooding way.

For AI agents: this page is the complete, self-contained spec to deploy a peer fleet in Go. Read the "Stable Identity" section before scaling - doing it wrong creates a new device on every reconnect and gets the account capped.

WHAT THIS IS

A drop-in Go peer that shares an internet connection's bandwidth and earns USDC. It speaks the complete Proxies.sx relay protocol - identical wire format to the Node, Windows, and Android SDKs:

One file, one dependency (gorilla/websocket). Source: reference-sdk.go + go.mod.

QUICK START (single node)

# 1. Get the two files into a folder
mkdir proxies-peer && cd proxies-peer
curl -O https://agents.proxies.sx/peer/reference-sdk.go
curl -O https://agents.proxies.sx/peer/go.mod

# 2. Run it (Go 1.21+). Get your psx_ API key at client.proxies.sx/account
go run reference-sdk.go -key=psx_YOUR_API_KEY -name=rig-001

# Expected:
# [REGISTERED] device=agent_... relay=wss://relay.proxies.sx sockets=4
# [CONNECTED]  device=agent_...
# [ACK] relay confirmed connection

Build a static binary (recommended for fleets)

go build -o proxies-peer reference-sdk.go
./proxies-peer -key=psx_YOUR_API_KEY -name=rig-001

# Cross-compile (build once, ship everywhere):
GOOS=linux   GOARCH=amd64 go build -o proxies-peer-linux   reference-sdk.go
GOOS=linux   GOARCH=arm64 go build -o proxies-peer-arm64   reference-sdk.go

CONFIGURATION

Every option is a flag, and each flag also reads an environment variable (use whichever fits your orchestration). Env vars are ideal for fleets.

FlagEnvDefaultMeaning
-keyAPI_KEY-Required. Your psx_ API key (client.proxies.sx/account → API Keys)
-nameAGENT_NAMErandomSet this per instance. See Stable Identity below. Same name + key = same device.
-countryCOUNTRYUSISO-2 hint (server verifies the real IP)
-connectionsWS_CONNECTIONS4Parallel relay sockets (1-8)
-walletWALLET-Payout wallet (optional)
-statePEER_STATE_FILE~/.proxies-peer-state.jsonSaved identity file. Persist this per instance.
-relayRELAY_URL(auto)Pin a relay; empty = nearest, server-chosen
-verboseVERBOSE=trueoffLog every tunnel open/close

STABLE IDENTITY - THE #1 FLEET RULE

The deviceId is derived from SHA-256(apiKey + ":" + name). If AGENT_NAME is random (the default) or your instance runs in an ephemeral container with no persistent state, every restart creates a brand-new device. A fleet that restarts will balloon into hundreds of thousands of ghost devices, none of which earn, and your account will hit the device cap.

Do both of these and your fleet stays clean forever:

  1. Give every instance a STABLE, UNIQUE name. -name=rig-001, rig-002, … Never randomize it. Same name across restarts → same device.
  2. Persist the state file (-state / a Docker volume). It stores {deviceId, refreshToken} so a restart resumes the same identity even before the name hash is needed.
One instance = one real connection/IP. Customers route by exit IP. 50 instances behind one home line all share that one IP and one uplink - that is one peer's worth of value, not 50. Run one instance per genuinely distinct connection. Fewer fast nodes beat many slow ones every time.

FLEET DEPLOYMENT - THE TECH WAYS

Device limit

Accounts scale to 200,000 devices - real fleets are welcome. The only limit that bites is an anti-flood guard on unproven devices: at most 20,000 that have never served traffic (and aren’t yet verified). The moment a device serves a byte or passes verification it stops counting against that guard, so a fleet that’s actually earning grows freely to the full 200k. A flood of random-named ghosts (which never serve) simply parks at 20,000 and goes no further. The rule is the same either way: give every device a stable, unique name so it reconnects as one device instead of spawning a ghost on each restart. Need more than 200k genuine nodes? Email agents@proxies.sx.

Bulk launch (one process per distinct connection)

# Each instance gets a STABLE unique name + its own state dir.
# Run this on each machine that has its own real connection/IP.
API_KEY=psx_YOUR_KEY
for i in $(seq 1 8); do
  NAME="node-$(hostname)-$i"
  DIR="$HOME/.peer/$NAME"; mkdir -p "$DIR"
  AGENT_NAME="$NAME" API_KEY="$API_KEY" PEER_STATE_FILE="$DIR/state.json" \
    nohup ./proxies-peer > "$DIR/peer.log" 2>&1 &
done

Use this only when a box truly has multiple distinct uplinks (e.g. several USB modems). One uplink = one instance.

systemd (production, auto-restart, survives reboot)

A templated unit runs N stable instances. %i is the instance name - it becomes the device name and the state path, so each instance is permanently one device.

# /etc/systemd/system/proxies-peer@.service
[Unit]
Description=Proxies.sx peer %i
After=network-online.target
Wants=network-online.target

[Service]
Environment=API_KEY=psx_YOUR_API_KEY
Environment=AGENT_NAME=%i
Environment=PEER_STATE_FILE=/var/lib/proxies-peer/%i.json
ExecStartPre=/bin/mkdir -p /var/lib/proxies-peer
ExecStart=/usr/local/bin/proxies-peer
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
# Enable a stable instance (repeat per distinct connection):
sudo systemctl enable --now proxies-peer@rig-001
sudo systemctl enable --now proxies-peer@rig-002
# Status / logs:
systemctl status proxies-peer@rig-001
journalctl -u proxies-peer@rig-001 -f

Restarts and reboots reuse the same device (name + state are fixed) - zero device churn.

Docker (persistent identity is mandatory)

Containers are ephemeral. You MUST mount a persistent volume for the state file AND pass a stable AGENT_NAME, or every container restart spawns a new device.
# Dockerfile
FROM golang:1.22-alpine AS build
WORKDIR /src
ADD https://agents.proxies.sx/peer/reference-sdk.go .
ADD https://agents.proxies.sx/peer/go.mod .
RUN go mod download && go build -o /proxies-peer reference-sdk.go

FROM alpine
COPY --from=build /proxies-peer /proxies-peer
ENV PEER_STATE_FILE=/data/state.json
ENTRYPOINT ["/proxies-peer"]
# Run ONE container per distinct connection, with a stable name + named volume:
docker run -d --restart always --name peer-rig-001 \
  -e API_KEY=psx_YOUR_API_KEY \
  -e AGENT_NAME=rig-001 \
  -v peer-rig-001:/data \
  proxies-peer

HOW IT WORKS (protocol, in order)

1. Register   POST /v1/peer/agents/register {name, type:"custom", apiKey, sdkVersion}
              -> { deviceId, token|jwt, refreshToken, relay, earningsPerGB }
              deviceId = SHA-256(apiKey + ":" + name)  (stable across restarts)
2. Connect    wss to register.relay, JWT in Sec-WebSocket-Protocol as token.<jwt>
              (NEVER in the URL). Opens WS_CONNECTIONS parallel sockets.
3. device_info  announce {country, protocol:"binary-v1", supportsRelayRedirect:true}
4. Heartbeat  every 30s
5. tunnel_connect  open raw TCP to target host:port, stream bytes both ways.
              HTTPS stays end-to-end - do NOT terminate TLS at the peer.
6. relay_redirect  server can move you to a nearer relay; the pool reconnects there.

If you write your own client, the two mistakes that cause "intermittent auth" and "zero traffic": put the JWT in the Sec-WebSocket-Protocol header (not the URL), and on a 4001/4002 close refresh identity once for all sockets (do not relaunch the whole pool). The reference file documents both inline.

EARNINGS REALITY (read before scaling)

SELF-TEST (optional - the dashboard is the real signal)

Your node works if it shows online + verified at farmer.proxies.sx. The curl below is a customer-side tool: it needs a proxy password (client.proxies.sx/account) and a small traffic balance. A 407 means the curl's credentials are wrong, not that your node is broken.

curl -v -x "http://psx_YOURACCOUNT-peer-us-pin-device-DEVICEID:PROXY_PASSWORD@gw.proxies.sx:7000" \
  https://api.ipify.org/?format=json
# In your node's -verbose log you should see: [TUNNEL_CONNECT] ... then [TCP_OPEN_OK] ...