The Last Mile: Taking a STON.fi Integration From Test Network to Real Users Getting a swap working in a test environment is the easy 80% of shipping a STON.fi integration. The remaining 20% —
The Last Mile: Taking a STON.fi Integration From Test Network to Real Users
Getting a swap working in a test environment is the easy 80% of shipping a STON.fi integration. The remaining 20% — the part that actually determines whether real users lose money to a preventable bug — is almost entirely about the gap between "works in sandbox" and "safe on mainnet." This piece walks through that gap concretely, with the specific patterns STON.fi's own documentation flags as production-critical.
🗨️ "The production-ready pattern is API-driven. Always let the STON.fi API dictate which router to use, and work against the mainnet endpoint. This keeps your integration compatible with future router upgrades and avoids hardcoding contract addresses." — STON.fi, SDK v2 Swap Documentation
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
🧳 Why "It Worked in Testing" Isn't the Bar

Test environments are deliberately forgiving in ways production isn't. Three gaps close the distance between the two:
- 🔲 Endpoints are genuinely separate, not a toggle. wss://omni-ws-sandbox.ston.fi and wss://omni-ws.ston.fi are different environments entirely — a misconfigured environment variable is the single most avoidable production incident.
- 🔳 Contract addresses differ, and mixing them is dangerous, not just broken. STON.fi's own DEX core repository lists distinct mainnet (EQB3ncy...) and testnet (EQBsGx9...) router addresses, and third-party integration docs explicitly warn against sending funds across that boundary in either direction.
- ▶️ Hardcoded values that "worked" in testing quietly rot in production. A fee constant or router address that was correct on day one silently becomes wrong the moment STON.fi ships a router upgrade — which is precisely the failure mode the API-driven pattern exists to prevent.
None of these are exotic mistakes. They're the ordinary, boring gaps that separate a demo from a system real money moves through.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
The Single Highest-Leverage Rule: Let the API Decide, Don't Decide for It
If this article had to compress into one sentence, it would be this one, because STON.fi's own documentation states it as explicitly as production advice ever gets stated.
🗨️ "STON.fi's REST API (api.ston.fi) only serves mainnet data, so every production swap should follow this flow: simulate the swap to obtain routing metadata, feed simulationResult.router directly into dexFactory() to build contracts dynamically." — STON.fi, SDK v2 Swap Documentation
The instinct after testing successfully is to lock in what worked — save the router address you tested against, hardcode it, ship it. That instinct is exactly backwards for this ecosystem. STON.fi's router can be upgraded, and an integration that hardcodes a specific router address instead of asking the API which one to use will break silently the next time that happens — not with an error message, but with a transaction that's quietly built against a router that's no longer the current one.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
🚧 The Shipping Checklist, One Gap at a Time
🔲 Confirm every environment variable before the first sandbox test, not the last. Both the WebSocket endpoint and the REST API base URL need to point at sandbox during testing and mainnet in production — a single missed variable in a deploy config is enough to send test transactions against real liquidity, or worse, production transactions against a test router.
🔳 Never hardcode a router or contract address, even one that's "definitely stable." Follow the documented pattern exactly: simulate first, then feed the simulation's own router object into dexFactory() to build contracts dynamically. This single pattern absorbs future router upgrades automatically, without a code change on your side.
▶️ Calculate fees dynamically, never as a hardcoded constant. STON.fi's own SDK constants for fees exist mainly as fallbacks — the documented best practice is calculating fees from current config parameters rather than relying on values that were correct when the code was written but aren't guaranteed to stay that way.
◀️ Prefer the SDK and TonConnect over manual BOC compilation, unless you have a genuinely specialized need. STON.fi's own API reference is explicit that custom BOC compilation should be reserved for advanced use cases — the SDK handles edge cases and receives official support that a hand-rolled transaction builder won't.
🔲 Test both refund paths and the documented exit codes before launch, not after a user reports a problem. This means deliberately exercising the failure modes covered in STON.fi's own error handling — a zero minAskAmount, insufficient gas producing exit code 37, and both the default and explicitly-set refundAddress behaviors — as part of the pre-launch test suite, not as reactive debugging once something has already gone wrong for a real user.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
🗝️ What Changes Once Real Referral Fees and Real Vaults Are Involved
If an integration routes through a referral program, there's a specific mechanic worth understanding before launch rather than after the first payout question comes in.
🗨️ "DEX v2 accumulates each swap's referral portion in a dedicated Vault contract (one per referrer × token pair). Fees can be configured in the 0.01%–1% range and must later be withdrawn by the referrer." — STON.fi, v2 Smart Contract Documentation
This means referral revenue doesn't arrive automatically in a wallet — it accrues in a per-referrer, per-pair Vault contract that requires an explicit withdrawal step. An integration's launch checklist should include verifying that this withdrawal flow actually works end to end in sandbox, not just that the referral fee is correctly attached to outgoing swap transactions. A referral fee that accrues correctly but can never actually be withdrawn is a production bug that looks like a success in every log line up until someone tries to claim it.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
📶 Comparing on the Dimensions That Actually Matter
💧 Hardcoded stability vs. adaptive stability. A hardcoded router address feels more stable during development because it never changes on you unexpectedly. In production, that's exactly backwards — the API-driven pattern is the version that actually stays stable as STON.fi's own infrastructure evolves underneath it.
🧭 Sandbox correctness vs. production correctness. Sandbox testing proves your logic is right for the inputs you thought to test. Production correctness additionally requires that your environment configuration, fee calculation, and referral withdrawal flow are all verified against real, current mainnet state — a genuinely broader bar.
⏱️ Reactive debugging vs. pre-launch failure testing. Discovering an exit-code handling gap from a confused user's support ticket costs far more — in trust and in engineering time — than deliberately triggering that same exit code in a sandbox test the week before launch.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
✅ What a Genuinely Production-Ready Integration Gets Right
- Every router and contract address comes from a live simulation, never a saved constant. This single pattern absorbs STON.fi's own infrastructure changes automatically.
- Environment separation is verified in CI, not assumed from a config file. Sandbox and mainnet endpoints get explicitly checked before any test suite runs, closing off the most common and most avoidable production incident.
- Referral and fee mechanics are tested end to end, including withdrawal. Fees accruing correctly is only half the mechanism — confirming they can actually be claimed is the other half most teams skip.
⚠️ What's Worth Understanding Correctly
- Sandbox and mainnet contract addresses are not interchangeable, and mixing them is an active risk, not just an error. Third-party integration guides explicitly warn against sending funds across that boundary in either direction.
- A router upgrade on STON.fi's side is not your integration's emergency if you followed the API-driven pattern. It only becomes one if a router address was hardcoded somewhere it shouldn't have been.
- Manual BOC compilation is a deliberate, advanced choice, not a shortcut. STON.fi's own documentation reserves it for specialized cases precisely because the SDK already handles the edge cases a hand-rolled path would need to reimplement.
🏁 Bottom Line
Shipping a STON.fi integration from sandbox to mainnet isn't about writing more code — it's about removing the specific hardcoded assumptions that work fine in a test environment and quietly fail in a production one: fixed router addresses instead of live simulation results, static fee constants instead of dynamic config reads, and untested refund or withdrawal paths that only get discovered once a real user is waiting on them. The gap between a working demo and a production-ready integration is almost entirely made of these small, documented, entirely avoidable decisions.
This article reflects independent research based on STON.fi's public developer documentation and open-source repositories as of mid-2026. Contract addresses, fee ranges, and recommended patterns evolve as the protocol ships updates — always verify current details directly on docs.ston.fi before shipping a production integration.