Programs → Solana devnet
anchor build produces signal_markets/target/idl/signal_markets.json. Note the deployed program id and set it as PROGRAM_ID for the keeper.
Deploy mock_validator as well (see its README) and point TXLINE_PROGRAM_ID at it.
The program accepts exactly two validator addresses for resolve_market: the real TxLINE txoracle (6pW64gN1…) and mock_validator (FPnwSSp2…). Which one is used depends on two keeper settings that must agree — see selecting a path.
To settle through the real validator:
- Set
MOCK_VALIDATOR=falseon the keeper, so it fetches a real proof instead of a stub. - Point
TXLINE_PROGRAM_IDat thetxoracleaddress — this is already the devnet default, so leaving it blank also works. - Raise the resolve transaction’s compute budget — verification costs ~234k CU.
TXLINE_PROGRAM_ID explicitly to the mock_validator address and leave MOCK_VALIDATOR=true. Leaving TXLINE_PROGRAM_ID blank here would send a stub proof to the real validator, which rejects it.
Frontend → Vercel
Point a Vercel project at the repository. The rootvercel.json already sets the build:
- Build command:
cd frontend-react && npm install && npm run build - Output directory:
frontend-react/dist
VITE_* environment variables in the Vercel project settings: RPC URL, USDC mint, Privy app id, fund endpoint, and fee recipient. These are client-side and non-secret. Vite bakes them in at build time, so redeploy after changing one.
Keeper → always-on host
A persistent Node process. Deploy it somewhere that keeps a process running.signal_markets.idl.json, so it runs without the signal_markets/ workspace beside it — IDL_PATH defaults to ./signal_markets.idl.json.
Environment
Set these on the host, starting fromkeeper/.env.example:
For two-sided markets to pay out, the keeper must be running and funded: SOL for transaction fees, plus USDC if
BOOTSTRAP_LIQUIDITY_USDC > 0, which it spends seeding empty pools.
Container hosts
Ready-made artifacts live inkeeper/: Dockerfile, .dockerignore, .railwayignore, and fly.toml.
- Railway
- Fly.io
Create a new service with root directory
keeper/, set the environment variables, and deploy. Running railway up from keeper/ also works.RPC rate limits. If the RPC endpoint returns 429s, the keeper’s crash guards absorb them and let its retry timers resume the work rather than restarting. A restart would replay the full startup burst — market scan, board seed, bootstrap deposits, resolve and claim — against the same throttled endpoint, which earns the next 429. Use a dedicated RPC endpoint for anything beyond light testing.
Secrets
- The keeper’s signing key is set only through the host’s secret manager. Never commit it, and never bake it into an image.
- Never commit
.env— only.env.example, with placeholders — or any Solana keypair (*id.json,.fee-wallet.json,.treasury.json)..gitignorecovers these. - Never commit an RPC URL containing an API key. Config defaults in the repository are public endpoints only; supply your own key through environment variables on the host.
- The frontend holds no secrets — only public RPC URLs, program ids, and mints.
