Testnet Runbook
Reproduce the full Writz flow from a clean checkout. This is the operational companion to Quick Start. Quick Start gets the test suites green; this runbook gets the protocol running against Soroban testnet and Bitcoin Signet.What this covers, and what it cannot
The flow splits into two halves with very different reproducibility:
Be aware of what the scripted half does not prove:
e2e_zkflow.js builds a
fabricated Bitcoin transaction (RAW_TX_HEX = '010000000000000000') and a
synthetic single-transaction block header. The bitcoin-spv contract genuinely
verifies that header chain and Merkle inclusion, but no real Bitcoin
transaction, and therefore no real deposit, is involved. It also passes an empty
enc_note, so the sealed recovery-note round trip (#18) is untested there.
Treat the scripted run as proof that the Soroban and ZK layers work.
The Bitcoin custody path needs the manual walkthrough at the end.
1. Prerequisites
Versions below are the ones CI pins; anything older is untested.circom 2.x is a Rust binary. Do not npm install -g circom — that
installs the legacy 1.x package, which cannot compile pragma circom 2.0.0:
snarkjs needs no global install — it is a dependency of circuits/.
2. Build the artifacts a clean checkout lacks
Four directories the scripts depend on are gitignored, so a fresh clone does not have them:3. Trusted setup — read before running setup_dev.sh
circuits/scripts/setup_dev.sh generates the proving keys. It seeds its
entropy with $(date):
- The setup is not reproducible. Running it produces a different proving/verification key pair every time.
- It overwrites the committed
keys/*_vkey.json. Your working tree will show those four files as modified. Do not commit them unless you also intend to push the new keys on-chain.
zk-verifier (CDV45GLX…) holds the verification keys from the
original setup, whose .zkey files are not in git. So:
-
To test against the shared testnet contracts: you need the original
.zkeyfiles. Ask a maintainer — regenerating will not reproduce them. -
To work fully from a clean checkout: regenerate the setup, deploy your own
zk-verifier, push your keys to it, and point the flow at it:
InvalidZkProof — that is a key mismatch, not a bug in your proof.
4. Run the scripted ZK flow
Get a funded testnet account:stellar.expert link per transaction.
Overridable via environment:
Last verified run
2026-07-30, instanceCBM5OUBYBICB3QB4T5PAGYUWWLZOIVWQCUHKV3HCSNZGB72GYM5Q5ID4,
six transactions, whole run about a minute:
contracts/deployments/testnet.md.
If your run diverges from these steps, § 7 lists the failures we hit getting here.
5. Testnet assumptions
The scripted flow is not a faithful mainnet rehearsal. What differs:6. The Bitcoin half (manual)
This part cannot be scripted — it needs Signet coins and two browser wallets. You need: Xverse on Signet with ≥ 0.0001 sBTC (from a Signet faucet), and Freighter on Stellar testnet, funded via Friendbot.-
Start the relayer, or point at the hosted one:
Hosted alternative:
https://writz-relayer-production.up.railway.app. -
Start the frontend:
- In the browser: connect Xverse + Freighter, derive the deposit P2WSH address, send sBTC to it, and wait for confirmations. Budget ~10 minutes per Signet confirmation — this is the slow step, and the reason the demo script pre-stages deposits.
-
Click Deposit. The relayer assembles the SPV bundle,
bitcoin-spvverifies inclusion on-chain, and the browser generates the deposit proof locally. - Borrow, then repay in full. On full repayment the protocol co-signs the release PSBT; countersign in Xverse and broadcast. BTC returns to your wallet.
7. Troubleshooting
Errors seen while validating this runbook, and what they actually mean:Next: Contribution Guide → · Contract Reference →