This guide covers everything needed to deploy, verify, upgrade, and monitor StellarRoute contracts on Stellar Testnet and Mainnet.
- Rust 1.75+ with
wasm32-unknown-unknowntarget - Soroban CLI (
cargo install --locked soroban-cli) jq(for JSON parsing in scripts)- A funded Stellar account (use Friendbot for testnet)
# Generate a new identity (stored in ~/.config/soroban/identity/)
soroban keys generate deployer --network testnet
# Fund on testnet via Friendbot
curl "https://friendbot.stellar.org/?addr=$(soroban keys address deployer)"- Store the deployer secret key as a GitHub repository secret:
SOROBAN_DEPLOYER_SECRET - Store the deployed contract ID as a repository variable:
SOROBAN_CONTRACT_ID - Set
DEPLOY_ENABLED=trueas a repository variable to enable the deploy workflow.
- NEVER commit private keys, seed phrases, or secret keys to the repository.
- NEVER share identity files across environments (testnet vs mainnet).
- Use separate deployer accounts for testnet and mainnet.
- Rotate keys if compromise is suspected.
- The
.gitignoreexcludes.soroban/,*.secret-key, andidentity.toml.
Use this checklist when rotating database, Redis, or Soroban RPC credentials:
- Add the new secret or credential alongside the old one in the target secret store.
- Update the runtime environment to point at the new value, keeping the old value available for rollback.
- Restart one service at a time and confirm
GET /healthandGET /health/depsremain healthy. - Remove the old credential only after the new one has been verified in production.
- Confirm no startup logs or health checks print secret material.
Recommended order: database first, Redis second, Soroban RPC last.
The unified liquidity path reads from normalized_liquidity, which combines SDEX offers and AMM reserves.
Migration sequence:
- Apply the new schema/migration that creates or updates
normalized_liquidityand the AMM reserve tables. - Backfill existing SDEX data before switching quote or routing reads.
- Verify quote responses and route selection on a staging environment.
- Flip the API/query path to the unified model.
Rollback sequence:
- Stop new writes into the unified path.
- Switch reads back to the previous SDEX-only query path.
- Preserve the backfill checkpoint tables so a later retry can resume safely.
- Keep the last known-good schema migration file and deployment artifact together.
# Clone and enter the repository
git clone https://github.com/StellarRoute/StellarRoute.git
cd StellarRoute
# Install Rust + WASM target
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
rustup target add wasm32-unknown-unknown
# Install Soroban CLI
cargo install --locked soroban-cli
# Generate and fund deployer identity
soroban keys generate deployer --network testnet
curl "https://friendbot.stellar.org/?addr=$(soroban keys address deployer)"./scripts/deploy.sh --network testnetThis will:
- Build contracts to WASM
- Optimize the WASM binary
- Deploy router + adapter contracts to testnet
- Initialize router with deployer as admin, 30 bps fee rate
- Save contract IDs to
config/deployment-testnet.json - Verify router deployment by calling
get_admin()
Environment and runtime options:
# optional defaults
export STELLAR_NETWORK=testnet
# simulate without writing on-chain transactions
./scripts/deploy.sh --dry-run
# use a non-default soroban identity name
./scripts/deploy.sh --network testnet --identity deployerEdit config/pools-testnet.json with real pool addresses, then:
./scripts/register-pools.sh --network testnet./scripts/verify.sh --network testnet./scripts/monitor.sh --network testnet- Bug fixes in contract logic
- New features (e.g., additional getter functions)
- Performance improvements
# Increment CONTRACT_VERSION in crates/contracts/src/router.rs
# Then run:
./scripts/upgrade.sh --network testnetThe upgrade script will:
- Capture pre-upgrade state (admin, fee rate, paused status, pool count, version)
- Build and optimize new WASM
- Compare bytecode hashes (skip if identical)
- Install new WASM on-chain
- Propose a timelocked router upgrade using
propose_upgrade - Redeploy adapter contract with the new WASM
- Verify all critical invariants are preserved
- Update the deployment artifact
./scripts/verify.sh --network testnet
./scripts/monitor.sh --network testnetSoroban does not support native rollback. Once a contract is upgraded:
- The old WASM code is replaced.
- Storage state is preserved (keys and values persist).
- To "rollback," you must deploy the previous WASM version as a new upgrade.
Recommendation: Always keep the last known-good WASM binary archived (the deploy workflow uploads it as a GitHub Actions artifact with 30-day retention).
If a contract upgrade changes the storage schema (e.g., new StorageKey variants):
- Additive changes (new keys): No migration needed. New keys will have default values (
unwrap_orpattern). - Renamed keys: Requires a migration function that reads old keys and writes new ones. This must be called once after upgrade.
- Removed keys: Old keys will remain in storage but become unused. They will naturally expire when their TTL runs out.
- Changed value types: Not supported without migration. Deploy a one-time migration entrypoint, call it, then upgrade again to remove the migration code.
Before deploying an upgrade to mainnet:
- All changes reviewed and merged to
main - Testnet deployment successful and verified
- Changelog written describing what changed and why
- Stakeholders notified (Discord, GitHub Discussions)
- Monitoring in place for post-upgrade health checks
- Previous WASM binary archived
- Deployment artifact backed up
- Trigger: GitHub Actions > "Deploy to Testnet" > Run workflow
- Supports dry-run mode (build + hash only, no deploy)
- Requires
SOROBAN_DEPLOYER_SECRETsecret andDEPLOY_ENABLED=truevariable
- Runs automatically at 03:00 UTC daily
- Rebuilds contracts from source and compares bytecode hash against deployed contract
- Requires
SOROBAN_CONTRACT_IDrepository variable - Fails the workflow if hashes mismatch
Restore the main CI gate in this order so regressions are easier to isolate:
- Re-enable formatting and lint checks first (
cargo fmt --check,cargo clippy -- -D warnings). - Re-enable unit tests next, starting with the crates touched most often.
- Re-enable contract verification last, keeping the nightly verification workflow as the safety net.
- Quarantine any flaky step in a separate workflow or scheduled job until it is stable.
- Require the restored baseline to stay green for a full review window before tightening merge policy again.
Merge gating policy:
- Main branch merges should require the restored baseline checks to pass.
- Contract verification can remain advisory until the restore sequence is complete.
- Flaky checks should be documented with owner and next review date.
Run ./scripts/deploy.sh --network testnet first. The deployment artifact is generated at deploy time.
cargo install --locked soroban-cli
# Ensure ~/.cargo/bin is in your PATHsoroban keys generate deployer --network testnet
# Or import an existing key:
echo "S..." | soroban keys add deployer --secret-key stdinFund the deployer account:
# Testnet
curl "https://friendbot.stellar.org/?addr=$(soroban keys address deployer)"
# Mainnet: transfer XLM from an exchange or wallet