Concepts

/docs/concepts/networks

Devnet vs mainnet

Obscura supports two Solana networks:

  • solana-devnet — free test network. Default for new accounts. Funds are synthetic and worthless; good for end-to-end integration tests.
  • solana (mainnet-beta) — the real Solana network. Actual USDC, actual money.

The two networks are isolated — a devnet transaction never touches mainnet and vice versa. Wallets, ETAs, mints, and mixer trees are all network-scoped.

Default: devnet

Both SDKs default to solana-devnet. That's deliberate:

  • Mistakes are free during integration. An off-by-a-zero price in pay.charge() costs the merchant nothing.
  • Test agents and test merchants can be set up in seconds with zero-stakes keypairs.
  • The flow is identical to mainnet — same x402 handshake, same umbra-mixer-v1 envelope, same on-chain verification path. Moving to production is an env flag change.

Switching to mainnet

Agent side

Agents don't pick a network — they use whatever network their merchant serves. When you're ready for real money, hit a merchant configured for mainnet. The SDK handles everything else.

Merchant side

Flip the network config:

ts
const pay = obscura({
merchantEtaAddress: process.env.MERCHANT_ETA_ADDRESS!,
obscuraAttestationPublicKey: process.env.OBSCURA_ATTESTATION_PUBKEY!,
network: "solana",   // was "solana-devnet"
rpcUrl: process.env.HELIUS_RPC_URL,
});

The merchant SDK's mint default switches based on network:

  • solana-devnet4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU (devnet USDC, 6 decimals)
  • solanaEPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v (mainnet USDC, 6 decimals)

Devnet today runs on WSOL (9 decimals), not USDC. The mixer's devnet deployment doesn't yet include the devnet USDC mint, so the Obscura backend is configured to accept WSOL with decimals: 9. If you're running a merchant against the public Obscura devnet, override the SDK defaults to match:

ts
obscura({
merchantEtaAddress: ...,
obscuraAttestationPublicKey: ...,
network: "solana-devnet",
mint: "So11111111111111111111111111111111111111112",
decimals: 9,
})

Mainnet uses real USDC at 6 decimals — no override needed.

ETAs are network-isolated

Your merchantEtaAddress is derived deterministically from a server-held seed plus your merchant ID, so the same Solana pubkey is valid on both networks — but the encrypted balance behind that pubkey is a separate on-chain account per network. Don't mix them:

  • Your devnet ETA registration only accepts devnet incoming payments.
  • Your mainnet ETA needs a separate registration (handled at signup when a mainnet account is provisioned).

Obscura's merchant dashboard shows network-scoped balances and feeds, so you won't accidentally see devnet earnings appear next to mainnet ones.

Getting devnet funds

For agent-side testing, send devnet USDC (dUSDC) to your agent's deposit address — it's swept into the agent's encrypted balance within ~30 seconds (the devnet stablecoin comes from a faucet / an Obscura-operated treasury, not a real exchange).

For merchant-side testing, any devnet payment landing on your ETA counts. A single agent spend ($0.01) is enough to see the full flow end-to-end.

Mainnet readiness checklist

Before you flip the flag:

  1. [ ] Your dashboard balance is real. The merchant dashboard shows mainnet ETA balance — confirm it matches what you expect on Solscan.
  2. [ ] Your RPC is production-grade. The default public RPC is rate-limited; set HELIUS_RPC_URL (or any other paid provider) on the merchant SDK config.
  3. [ ] Your prices are right. One extra zero in amount costs 10× per call on mainnet. Use the dashboard's API catalog to cross-check the prices you've registered against your code.
  4. [ ] Your handler is idempotent. If a paid request hits your handler more than once for the same queueSignature (the merchant SDK rejects this within the replay window, but cross-process or post-window replays are possible), does your handler double-charge downstream systems?
  5. [ ] Your replay window is sized for your traffic. Default 5 minutes is fine for most workloads; raise via replayWindowMs if you have unusually slow client retry loops.

Once all five are checked, the flag flip is safe.