Docs/Concepts

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!,
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. Umbra'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: ...,
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, Obscura's top-up flow funds your devnet agent's encrypted balance in ~30 seconds via UPI (the devnet stablecoin comes out of 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.