Getting Started

Mainnet & Testnet

HyperDex ships both Stellar networks in a single build. A switcher in the navbar picks one at runtime — no separate deployment, no rebuild.

Maker onboarding is open in beta on testnet: Every onboarding step runs end to end against the deployed testnet contracts — application, API key, deploy_pool, inventory deposit and a live quoting session — so you can integrate the SDK and test a pricing engine on free Friendbot funds before committing real inventory. Backend: https://hyperdex-testnet.onrender.com. See Maker Registration to start.

How the switcher works

Both network configurations — contract addresses, RPC endpoint, Horizon endpoint, backend origin and explorer base — are compiled into the bundle. The one in effect is resolved at module load from localStorage["hyperdex.network"], falling back to the build-time default when a visitor has never chosen.

  • Click the Mainnet / Testnet pill next to Connect Wallet
  • Pick a network — the choice is stored and the page hard-reloads
  • Set your wallet to the matching network, then reconnect
Why a full reload: Contract addresses, the RPC URL and the backend origin are read at module scope across the app. Reloading is the only way to guarantee no component is left holding a half-swapped mix of two networks. The reload drops the wallet session, which is why the switcher asks for a second click first.

What differs per network

MainnetTestnet
PassphrasePublic Global Stellar Network ; September 2015Test SDF Network ; September 2015
Soroban RPChttps://mainnet.sorobanrpc.comhttps://soroban-testnet.stellar.org
Horizonhttps://horizon.stellar.orghttps://horizon-testnet.stellar.org
Backendhttps://hyperdex.onrender.comhttps://hyperdex-testnet.onrender.com
Explorerstellar.expert/explorer/publicstellar.expert/explorer/testnet
FundsReal — irreversibleTest funds — free from Friendbot

Backend routing

The backend is single-network per instance — it reads one STELLAR_NETWORK from its environment and derives the passphrase from it. Running both networks therefore means running two backend instances.

Because Next.js route handlers execute on the server, they cannot see the visitor's localStorage choice. Every browser call to an internal /api/* route is tagged with a header, and the handler maps it to the matching backend origin:

// browser
fetch('/api/maker-application', {
  headers: networkHeaders({ 'Content-Type': 'application/json' }),
  // -> x-hyperdex-network: testnet
});

// server route handler
const backendUrl = backendUrlFromRequest(req);
// -> NETWORKS['testnet'].backendUrl
Unknown header falls back: An absent or unrecognised x-hyperdex-network resolves to the default network rather than guessing — a stale client can never be routed somewhere arbitrary.

Wrong-network detection

After connecting, HyperDex compares the wallet's reported network passphrase with the selected network. On a mismatch a banner names the connected wallet and the network it should be on, and signing is blocked before the wallet is ever opened.

Wallets that do not expose a network (hardware devices, some bridges) return null and are allowed through — the check runs again at signing time. This matters: a signature produced against the wrong passphrase is rejected on-chain as txBadAuth, after the user has already approved it.

Environment variables

Each network has its own prefix. Un-suffixed legacy variables are kept as a fallback for whichever network NEXT_PUBLIC_STELLAR_NETWORK names, so an existing single-network deployment keeps working untouched.

# Network a first-time visitor sees
NEXT_PUBLIC_DEFAULT_NETWORK=mainnet

# Mainnet
NEXT_PUBLIC_MAINNET_STELLAR_RPC_URL=https://mainnet.sorobanrpc.com
NEXT_PUBLIC_MAINNET_HORIZON_URL=https://horizon.stellar.org
NEXT_PUBLIC_MAINNET_BACKEND_URL=https://hyperdex.onrender.com
NEXT_PUBLIC_MAINNET_POOL_REGISTRY_CONTRACT=...
NEXT_PUBLIC_MAINNET_QUOTE_VERIFIER_CONTRACT=...
NEXT_PUBLIC_MAINNET_MAKER_POOL_FACTORY_ADDRESS=...
NEXT_PUBLIC_MAINNET_FEE_DISTRIBUTOR_CONTRACT=...
NEXT_PUBLIC_MAINNET_USDC_CONTRACT=...
NEXT_PUBLIC_MAINNET_EURC_CONTRACT=...
NEXT_PUBLIC_MAINNET_ADMIN_ADDRESS=...

# Testnet — same keys, TESTNET_ prefix
NEXT_PUBLIC_TESTNET_STELLAR_RPC_URL=https://soroban-testnet.stellar.org
NEXT_PUBLIC_TESTNET_HORIZON_URL=https://horizon-testnet.stellar.org
NEXT_PUBLIC_TESTNET_BACKEND_URL=https://hyperdex-testnet.onrender.com
# ...same contract keys with TESTNET_
Do not refactor into a dynamic lookup: Next.js only inlines statically analysable process.env.NEXT_PUBLIC_X expressions. Every variable is spelled out literally in lib/networks.ts; a process.env[key] lookup resolves to undefined in the browser.

Getting testnet funds

Fund an account with XLM from Friendbot, then add trustlines and acquire Circle's testnet USDC/EURC. Note the two assets have different testnet issuers — USDC is issued by GBBD47IF… (centre.io) and EURC by GB3Q6QDZ… (circle.com).

# Fund a testnet account
curl "https://friendbot.stellar.org/?addr=<YOUR_G_ADDRESS>"

# Or via the CLI
stellar keys generate my-taker --network testnet --fund

Running the testnet stack locally

# 1. Backend pointed at testnet (backend/.env)
STELLAR_NETWORK=testnet
STELLAR_RPC_URL=https://soroban-testnet.stellar.org
HORIZON_URL=https://horizon-testnet.stellar.org
# ...testnet contract addresses

cd backend && npm run dev      # -> port 4000

# 2. Bootstrap a maker end-to-end (apply, approve, signer key, deploy pool)
bash scripts/bootstrap-testnet-maker.sh
# -> writes maker-sdk/.env with the API key, signer seed and pool address

# 3. Start the maker, then the frontend
cd maker-sdk && npm run dev
cd frontend  && npm run dev    # -> http://localhost:3000
Rebuildable from scratch: The bootstrap script is non-interactive and idempotent — if the pool already exists it reads it back from the factory and re-syncs the registry signer key, so the testnet environment can be torn down and rebuilt at any time.
HyperDex | Trade Without Limits