Pilots run a checklist before every takeoff. Surgeons run one before every incision. Not because they forgot how to fly or operate — because the cost of skipping a single step under pressure is too high to trust to memory. Shipping a Solana program to mainnet-beta belongs in that same category: irreversible actions, real value on the line, and a dozen small things that each seem obvious right up until the moment you forget one.
I spent the last several days building every piece of a real launch — promoting a program from devnet to mainnet-beta, taking deliberate control of its upgrade authority, publishing an IDL and generating a typed client, wiring a React frontend through the Wallet Standard, and teaching that frontend to fail politely instead of loudly. All of that knowledge is fresh in my head right now, which is exactly the problem: in three weeks, when I'm about to ship the next program, it won't be. "I'll remember" is not a launch strategy.
So here's the checklist, written in the order the steps actually happen, with the gotchas I personally hit called out along the way.
Phase 1: Pre-flight, on devnet
These are the steps that catch problems while they're still cheap to fix.
- [ ] Every test passes against your final program build. Not an earlier build, not "close enough" — the exact bytecode you're about to ship.
- [ ] Run the program end-to-end on devnet exactly as it will run on mainnet. If there's a step you're planning to skip "just this once" on the real deploy, do it on devnet first and see what breaks.
- [ ] Produce a verifiable build with
anchor build --verifiable. This is what lets anyone later match the bytecode sitting on-chain back to your actual source code. Skip it and your program is just a trusted black box forever. - [ ] Confirm your deploy wallet holds enough SOL to cover the rent-exempt minimum for the program account plus fees. You can preview the rent number with
solana rent $(wc -c < target/deploy/vault.so)before you commit to anything.
The gotcha: once you have a verifiable build, do not overwrite it with a plain anchor build or cargo build-sbf afterward. Either of those can produce a different hash and quietly break verification later, and you won't find out until someone tries to verify it.
Phase 2: The deploy itself
This is the irreversible phase, so this is where the checklist earns its keep.
- [ ] Switch your CLI to mainnet-beta and confirm it with
solana config getbefore running anything else. A stray command pointed at the wrong cluster is the easiest mistake to make and one of the more annoying to notice. - [ ] Deploy through a dedicated RPC endpoint, not the public one. A deploy is dozens of write transactions in a row, and the free public RPC is rate-limited enough that writes can expire before they land.
- [ ] Attach a priority fee if the network is busy. A priority fee is a small extra payment per unit of compute that nudges the current block leader to include your transaction ahead of others competing for the same block. Add one with
--with-compute-unit-price, and route through your endpoint with--use-rpc. - [ ] Know the recovery path before you need it. A deploy is not atomic. If it's interrupted, you can be left with a buffer account holding your SOL.
solana program show --bufferslists anything stranded, and you can resume into it or close it to recover the rent rather than starting over and leaking SOL on every failed attempt. The official deployment docs walk through this recovery flow — read it once before you deploy, it's cheaper than reading it for the first time mid-failure.
Phase 3: Authority and verification, right after deploy
- [ ] Confirm the program is live and inspect it with
solana program show <PROGRAM_ID>to read back its upgrade authority and confirm it's what you intended. - [ ] Decide, deliberately, who holds upgrade authority. Whoever signed the deploy holds it by default, and that's a lot of quiet power to leave unexamined. The real options are: a single keypair you control, a Squads multisig where upgrades require multiple approvals, or
--finalto make the program permanently immutable. Each is legitimate; write down which one you chose and why, because "I meant to move it later" is how authority ends up parked on a laptop indefinitely. - [ ] Publish your IDL so the program's interface travels with the program itself, retrievable by anyone with just the program ID.
- [ ] Regenerate your typed client from the published IDL.
The gotcha: skipping the IDL publish step will cause build verification to fail later, even if the deploy itself was perfectly fine.
Phase 4: Frontend and going live
- [ ] Point your React frontend at the mainnet program ID.
- [ ] Confirm the Wallet Standard connection surfaces real wallets against mainnet, not a leftover devnet configuration. A mismatch between where your app reads and where your wallet is set is the single most common reason a balance shows up as zero.
- [ ] Re-confirm every failure mode you classified — rejected approval, insufficient funds, expired blockhash — still produces a calm, legible message now that the stakes are real and not devnet-free.
- [ ] Announce the launch.
- [ ] Write down where users should report problems, before they need to find you.
Prove it
Before publishing this checklist anywhere, I ran the one command that confirms the single most important fact in the whole thing — that the program is live and its upgrade authority is exactly what I claim it is:
solana program show <YOUR_PROGRAM_ID> --url mainnet-beta
Enter fullscreen mode Exit fullscreen mode
That output is the receipt. If you're writing your own version of this checklist, paste yours in too.
The thing that surprised me most
Going in, I expected the deploy command itself to be the scary part. It wasn't. The deploy is just anchor build and a command you've run a dozen times on devnet, aimed somewhere more permanent. What actually required care was everything sitting around the deploy — confirming the cluster before touching anything irreversible, treating upgrade authority as a decision instead of a default, and remembering that a stalled deploy isn't a failure to restart from scratch but SOL sitting in a buffer waiting to be recovered. None of that is complicated. All of it is exactly the kind of thing that's obvious in the moment and gone from memory three weeks later, which is the whole reason this checklist exists.
The best engineering teams don't treat launches as feats of memory or heroics — they treat them as procedures. A multisig on the upgrade authority, a verifiable build, a confirmed cluster before an irreversible command: none of that is paranoia. It's the small discipline that lets a team ship to production calmly and repeatedly, instead of white-knuckling it every time. This is my version of that discipline, written down so I don't have to relearn it, and so the next person walking this path for the first time has something more useful than the reference docs: a checklist written by someone who still remembers exactly what was confusing.
0 Comments
Log in to join the conversation.No comments yet. Be the first to share your thoughts.