Testing against mainnet data
Mainnet Execution Simulation (MXS) allows you to test your Clarity smart contracts using actual data and state from the Stacks mainnet. This powerful feature helps ensure your contracts behave as expected in a live environment.
What you'll learn
What is Mainnet execution simulation?
Testing smart contracts in realistic conditions is essential. Simnet offers an isolated environment but lacks the live Stacks mainnet's complexity and history.
MXS fills this gap by enabling unit tests with the Clarinet JS SDK and Vitest to simulate the Stacks mainnet state at a specific block height. This allows you to:
- Validate contract logic with real data: Directly test mainnet contracts or data within your tests.
- (Re)simulate transactions: Analyze mainnet transactions' results, execution, or costs without deploying or using actual STX.
Enable MXS in your project
Add the following configuration to your Clarinet.toml
file:
[repl.remote_data]# Enable mainnet execution simulationenabled = true# Specify the Stacks block height to fork frominitial_height = 522000# API URL (optional, defaults to https://api.hiro.so)api_url = 'https://api.hiro.so'
Setting a specific initial_height
ensures consistent and reproducible test results.
Configure API access
While MXS works without an API key, you may encounter rate limits. Set up an API key for reliable access:
$export HIRO_API_KEY="<your-api-key>"
Write tests with mainnet data
Once MXS is enabled, your tests automatically operate against the mainnet state snapshot. Here's an example testing against the mainnet pox-4
contract:
import { describe, it, expect } from "vitest";import { Cl } from "@stacks/transactions";const accounts = simnet.getAccounts();const deployer = accounts.get("deployer")!;describe("pox-4 mainnet interaction", () => {it("reads current reward cycle from mainnet", () => {// Call the mainnet pox-4 contractconst call = simnet.callReadOnlyFn("SP000000000000000000002Q6VF78.pox-4", // Mainnet contract"current-pox-reward-cycle",[],deployer);// Assert the result (adjust based on your initial_height)expect(call.result).toBeUint(109);console.log("Current POX reward cycle:", Cl.prettyPrint(call.result));});});
The test uses simnet.callReadOnlyFn
just like in standard unit tests, but because MXS is enabled, it targets the actual pox-4
contract state at the specified block height.
Try it out
Run your test to see MXS in action:
$npm run test
Common issues
Issue | Solution |
---|---|
Rate limit errors | Set up HIRO_API_KEY environment variable |
Inconsistent results | Fix initial_height in configuration |
Function not found | Check the contract exists at your block height |
Next steps
Testing in the playground
Quickly experiment with MXS without setting up a project:
- 1Visit https://play.hiro.so/?remote_data=true
- 2Run mainnet contract calls:
$contract-call? 'SP000000000000000000002Q6VF78.pox-4 current-pox-reward-cycle
Advanced usage
- Test contract interactions with existing mainnet contracts
- Validate your contract logic against real-world data
- Simulate specific mainnet transactions for debugging
Current limitations
MXS does not support functions that query burn block or miner tenure information:
get-burn-block-info?
get-tenure-info?
Calls to these functions will result in runtime errors.