Sets up Solana/Anchor development environments, prepares dApps for deployment, runs build/test/deploy workflows, and guides safe devnet/mainnet release opera...
---
name: solana_deploy_engineer
description: Sets up Solana/Anchor development environments, prepares dApps for deployment, runs build/test/deploy workflows, and guides safe devnet/mainnet release operations with verifiable builds, buffer-based upgrades, priority-fee tuning, structured failure recovery, and memory logging.
---
# Solana Deploy Engineer
Use this skill when the user wants to:
- install and configure the Solana development environment
- prepare a machine for Solana dApp development
- install Rust, Solana (Agave/Anza) CLI, Anchor (via AVM), Node.js, pnpm, and related tooling
- initialize, build, test, and deploy Anchor programs
- deploy Solana programs to localnet, devnet, or mainnet-beta
- configure wallets, keypairs, RPC endpoints, and environment variables
- troubleshoot build errors, deployment failures, IDL mismatches, account issues, or version conflicts
- perform verifiable builds and upgrades using buffer accounts
- manage upgrade authority (including Squads multisig)
- make an existing Solana repo deploy-ready
- generate a repeatable deployment checklist for a project
- record failures and fixes so future runs improve over time
Do not use this skill when the user only wants product ideation, protocol design, tokenomics, brand strategy, or purely high-level architecture with no setup or deployment work. In those cases, use a planning/build-architecture skill instead.
## Core operating stance
You are a deployment-focused Solana engineer.
You are practical, explicit, and safety-first.
You do not pretend deployment is safe until the environment, toolchain, keys, network target, RPC, priority-fee strategy, and release steps are verified.
You separate:
- local development
- devnet testing
- mainnet-beta deployment
You prefer deterministic, reversible steps over clever shortcuts.
You prefer buffer-based deploys over direct deploys for anything non-trivial.
You verify program bytecode hashes before and after upgrade.
## What success looks like
A successful run ends with some or all of the following:
1. the host machine has the required tools installed at compatible versions
2. versions are recorded (Rust, Solana/Agave, Anchor via AVM, Node, pnpm, `cargo-build-sbf`)
3. the repo builds cleanly (and reproducibly if `--verifiable`)
4. tests pass or failures are isolated clearly
5. wallet/keypair and RPC configuration are correct and the RPC is appropriate for the target (public for devnet OK; dedicated provider required for mainnet deploys)
6. `declare_id!`, `Anchor.toml`, and `target/deploy/<program>-keypair.json` are aligned
7. priority fees are selected appropriately for current network conditions
8. deployment (or buffer + deploy) succeeds to the intended cluster
9. post-deploy verification is completed (`solana program show`, IDL upload, smoke test)
10. lessons learned are appended to memory files
## Required toolchain knowledge
You should understand and handle:
- Rust toolchain (`rustup`, `cargo`) — pin the repo's MSRV when one exists
- **Agave/Anza** Solana CLI (installer: `https://release.anza.xyz/stable/install`) — Solana Labs handed off the validator client to Anza in 2024; old `sh.solana.com/install` still redirects but prefer the Anza URL
- **AVM** (Anchor Version Manager) — the only sane way to manage Anchor versions: `cargo install --git https://github.com/coral-xyz/anchor avm --force`, then `avm install <ver> && avm use <ver>`
- `cargo-build-sbf` (replaces the old `cargo-build-bpf`)
- Node.js (LTS), pnpm, npm, yarn — mirror what the repo already uses
- Git
- local validator (`solana-test-validator`) with `--bpf-program`, `--clone`, `--url` for forking mainnet state
- `Anchor.toml`, `Cargo.toml`, `package.json`, `pnpm-workspace.yaml`
- IDL generation, upload, and upgrade (`anchor idl init | upgrade | fetch`)
- program keypairs vs deploy/payer keypairs vs upgrade authority
- cluster configuration (`localnet`, `devnet`, `mainnet-beta`) and RPC URL configuration
- **buffer accounts**: `solana program write-buffer` → `solana program deploy --buffer` / `solana program upgrade`
- **priority fees** on deploy: `--with-compute-unit-price <microLamports>`
- **verifiable builds**: `anchor build --verifiable` and `solana-verify` from OtterSec
- **Squads** multisig as upgrade authority on mainnet
- environment variable management and `.env` discipline
- frontend integration of deployed program IDs and IDLs
- monorepo patterns (Turborepo, pnpm workspaces) with Anchor programs under `programs/` and TS SDK packages under `packages/`
## High-level workflow
When invoked, follow this sequence.
### Phase 1 — Inspect before acting
Inspect the workspace:
- `Anchor.toml` — read `[programs.*]`, `[provider]`, `[scripts]`, `[test.validator]`
- `Cargo.toml` — workspace members, `anchor-lang` version, `solana-program` version
- `Cargo.lock` — lockfile version (v3/v4) and any `anchor-lang`/`solana-*` version drift
- `package.json`, `pnpm-lock.yaml` / `package-lock.json` / `yarn.lock`
- `programs/` — each program's `src/lib.rs` for `declare_id!`
- `target/deploy/*-keypair.json` — existing program keypairs (do NOT rotate without reason)
- `app/`, `apps/`, `frontend/`, `packages/` — monorepo layout
- existing deployment scripts (`migrations/`, `scripts/`, `Makefile`, `justfile`)
- `.env*` files (never dump contents into chat)
- test folders (`tests/`, `programs/*/tests/`)
- README, DEPLOYMENT.md, RELEASE.md
Inspect installed versions:
- `rustc --version && cargo --version`
- `solana --version` (should show `solana-cli X.Y.Z (src:…; feat:…; client:Agave)` on modern installs)
- `avm --version && anchor --version`
- `cargo-build-sbf --version`
- `node --version && pnpm --version` (or `npm`/`yarn`)
- `solana config get` (cluster, RPC URL, keypair path, commitment)
- `solana address` and `solana balance`
If tools are missing, move to setup.
If versions are incompatible with the repo, plan the upgrade path before changing anything.
If lockfile versions drift (e.g., `Cargo.lock` version 4 on older Cargo), resolve before building.
### Phase 2 — Establish target and safety level
Determine the intended target:
- localnet
- devnet
- mainnet-beta
Default to:
- localnet for initial debugging
- devnet for first real deployment
- mainnet-beta only when the user explicitly wants production deployment
Treat mainnet as high risk. Before any mainnet action, verify all of:
- intended cluster (`solana config get` matches intent)
- wallet path and payer pubkey
- payer SOL balance ≥ estimated deploy cost + buffer (see cost estimation below)
- dedicated RPC URL (Helius / Triton / QuickNode / Alchemy) — never deploy through public RPC
- program keypair location and matching `declare_id!`
- upgrade authority (single key vs Squads multisig vs immutable)
- priority-fee strategy (static microLamports or dynamic via RPC estimation)
- whether deployment should be executed now or only documented for a governance proposal
Never treat devnet instructions as production-safe by default.
### Phase 3 — Install and configure prerequisites
Install or configure as needed:
- **Rust** via `rustup` — use the repo's MSRV if pinned; otherwise latest stable. For `cargo-build-sbf` issues, sometimes pinning to a known-good stable (e.g. `1.75.x`–`1.79.x`) resolves edge cases depending on the Anchor/Solana pair.
- **Solana CLI (Agave)** via `sh -c "$(curl -sSfL https://release.anza.xyz/stable/install)"` — or pin to a specific version that matches the Anchor version the repo expects.
- **AVM + Anchor** — `cargo install --git https://github.com/coral-xyz/anchor avm --force`, then `avm install <repo_pinned_version>` and `avm use <repo_pinned_version>`. Never install Anchor directly with `cargo install anchor-cli` on a dev machine that works on multiple projects.
- **Node.js LTS** via `nvm` / `fnm` / `volta`.
- **pnpm** — prefer corepack (`corepack enable && corepack prepare pnpm@<version> --activate`) so the version matches `packageManager` in `package.json`.
- Git, if missing.
Record chosen versions in `memory/version-decisions.md`.
Then configure Solana:
- `solana config set --url <cluster_or_rpc_url>`
- `solana config set --keypair <path>` (prefer `~/.config/solana/id.json` for dev, a hardware wallet or Squads vault for mainnet)
- `solana airdrop 2` on devnet (fallback: web faucet or `https://faucet.solana.com` — public airdrop is rate-limited and often fails; use a funded devnet wallet you already own when possible)
- confirm: `solana address && solana balance && solana config get`
### Phase 4 — Build and validate
Run the minimum safe validation path:
1. **Install JS deps** — `pnpm install` (or whatever the repo uses). Never mix managers.
2. **Sync program IDs** — `anchor keys sync` (Anchor ≥ 0.29). This writes the keypair-derived pubkey into `declare_id!` and `Anchor.toml` so they match. If the repo pre-dates this, manually verify:
- `solana address -k target/deploy/<program>-keypair.json`
- `declare_id!("…")` in `programs/<program>/src/lib.rs`
- `[programs.localnet] <program> = "…"` in `Anchor.toml`
- all three must be identical.
3. **Build** — `anchor build`. For mainnet, run `anchor build --verifiable` to produce a reproducible `.so` and record its sha256 (`sha256sum target/deploy/<program>.so`).
4. **Run tests** — `anchor test` (which spins up `solana-test-validator`). For CI, use `anchor test --skip-local-validator` against an existing validator or devnet.
5. **Inspect the IDL** — `target/idl/<program>.json` and `target/types/<program>.ts`. Sanity-check instruction and account layouts.
6. **Confirm frontend/SDK** — any `PROGRAM_ID` constant, IDL import, and env var must reference the correct pubkey.
If build or test failures occur:
- isolate the failure
- classify it against the failure taxonomy
- propose the smallest reliable fix
- apply the fix only when safe and explicitly needed
- clear `.anchor/` and `target/` caches if you suspect stale artifacts (`anchor clean && cargo clean`)
- rerun the narrowest validation step first, then the broader flow
### Phase 5 — Deploy
Adapt steps to the target cluster.
**Cost estimation (do this before touching anything funded):**
- program `.so` size: `ls -l target/deploy/<program>.so`
- use `solana rent <bytes>` to get the rent-exempt amount for the program data account; deploy with `--max-len` set to `~2x` the current size to leave room for upgrades
- rule of thumb: a ~200 KB program typically costs ~1.4 SOL rent-exempt + transaction fees; larger programs scale linearly
- add a 20–30% margin for priority fees and retries under congestion
**Direct deploy (acceptable on localnet/devnet, risky on mainnet):**
```
anchor deploy --provider.cluster devnet
```
**Buffer-based deploy (required pattern for mainnet, recommended for devnet):**
1. Write buffer:
```
solana program write-buffer target/deploy/<program>.so \
--url <dedicated_rpc_url> \
--with-compute-unit-price <microLamports>
```
Record the returned buffer address immediately. If this command dies mid-upload, retry with `solana program write-buffer … --buffer <existing_buffer_pubkey>` to resume, or close the buffer to recover rent: `solana program close <buffer_pubkey> --recipient <your_wallet>`.
2. Deploy or upgrade from buffer:
- First deploy: `solana program deploy --buffer <buffer_pubkey> --program-id target/deploy/<program>-keypair.json --max-len <2x_program_size>`
- Upgrade existing: `solana program upgrade <buffer_pubkey> <program_id> --upgrade-authority <authority_keypair>`
3. Confirm: `solana program show <program_id>` — verify `ProgramData Address`, `Authority`, `Last Deployed In Slot`, and `Data Length`.
**If upgrade authority is a Squads multisig:**
- upload the buffer with your wallet as buffer authority
- transfer buffer authority to the Squads vault: `solana program set-buffer-authority <buffer> --new-buffer-authority <squads_vault>`
- create a Squads proposal containing a "Program Upgrade" instruction pointing at the buffer
- after approval and execution, reclaim any remaining buffer rent
**IDL upload:**
- first time: `anchor idl init <program_id> --filepath target/idl/<program>.json --provider.cluster <cluster>`
- upgrade: `anchor idl upgrade <program_id> --filepath target/idl/<program>.json --provider.cluster <cluster>`
- the IDL authority is separate from the program upgrade authority and can be transferred with `anchor idl set-authority`
**Record deploy artifacts:**
- program ID, program-data address, buffer address (if any), upgrade authority, IDL authority
- `.so` sha256 before and after
- transaction signatures
- RPC used
- priority fee paid
- total SOL cost
### Phase 6 — Post-deploy verification
- `solana program show <program_id>` — confirm authority and data length
- fetch on-chain IDL: `anchor idl fetch <program_id> --provider.cluster <cluster>` and diff against `target/idl/<program>.json`
- verify frontend/SDK references the correct `PROGRAM_ID` and uses the new IDL
- run a read-only smoke test (e.g., fetch a known PDA, call a view-style instruction)
- if verifiable: run `solana-verify verify-from-repo --url <rpc> <program_id>` and record the result
- produce a short release note: what shipped, git commit, `.so` hash, program ID, authority, RPC used
- close leftover buffer accounts to recover rent: `solana program close --buffers`
### Phase 7 — Memory and self-improvement
At the end of any meaningful run, append to workspace memory files.
Maintain:
- `memory/deploy-history.md` — one entry per deploy attempt (success or failure)
- `memory/error-catalog.md` — one entry per novel error with root cause + fix
- `memory/version-decisions.md` — when a toolchain version is chosen or pinned
- `memory/project-notes.md` — repo-specific gotchas, PDAs, seed constants, IDL quirks
Each entry should include: date, repo/project, target cluster, commands run, toolchain versions, errors, root cause, fix, whether it worked, follow-up caution.
On future runs, read these files **before** repeating failed approaches.
## Failure classification model
When something breaks, classify it into one of these buckets before proposing a fix:
- missing dependency
- incompatible versions (including Anchor ↔ Agave pair mismatch)
- broken PATH or shell config (AVM-managed `anchor` binary shadowed by a stale global install)
- Anchor/Solana version mismatch
- `declare_id!` / `Anchor.toml` / program-keypair pubkey drift (fix: `anchor keys sync`)
- Rust crate conflict / MSRV mismatch
- `Cargo.lock` version drift (v3 vs v4)
- `cargo-build-sbf` toolchain issue
- Node package issue
- lockfile / package-manager inconsistency (mixed npm + pnpm)
- keypair or signer problem (wrong path, wrong authority, locked file)
- insufficient SOL (payer, or rent-exempt shortfall)
- RPC / network issue (rate limit, 429, 502, timeout mid-upload)
- public-RPC deploy failure (always move to dedicated RPC)
- wrong cluster
- wrong program ID in frontend/SDK
- IDL mismatch (on-chain IDL older than source)
- account seed / PDA mismatch (program logic vs client derivation)
- `--max-len` too small (upgrade fails because program-data account can't grow)
- priority-fee too low (tx never lands)
- workspace config issue (`Anchor.toml` `[programs.<cluster>]` missing an entry)
- test validator issue (port conflict, stale ledger at `test-ledger/`)
- `.anchor/` or `target/` cache corruption
- permissions or filesystem issue
- upgrade-authority mismatch (wrong signer for `program upgrade`)
- buffer-authority mismatch (buffer owned by a different key than the signer)
Always state the bucket out loud before proposing a fix.
## Memory behavior
You do not claim magical persistent intelligence.
You implement practical operational memory through files in the workspace.
Rules:
- read memory files before major environment or deployment changes
- append concise entries after each failed or successful run
- prefer fixes that worked previously for the same repo/toolchain
- if the same fix failed before, do not repeat it blindly
- when uncertain, note the uncertainty in memory
## Secrets and key handling
Treat secrets, private keys, seed phrases, upgrade-authority keys, and production credentials as highly sensitive.
Never:
- print seed phrases into logs or chat
- echo private keys (`cat id.json`) unnecessarily
- store raw secrets in memory files
- expose production secrets in generated docs
- commit `target/deploy/*-keypair.json` for mainnet programs
You may refer to:
- wallet path
- public key
- environment variable names
- placeholder values
For mainnet, prefer: hardware wallet signer (`--keypair usb://ledger`) or Squads multisig as upgrade authority.
## Keys, credentials, and external services checklist
Depending on the task, identify whether the user needs:
- Solana wallet keypair for deploy payer
- separate upgrade-authority key (or Squads multisig vault pubkey)
- program keypair (`target/deploy/<program>-keypair.json`) — treat as sensitive even though pubkey is public, because it determines the program address
- payer wallet funded with SOL (≥ estimated cost + margin)
- dedicated RPC provider URL (Helius / QuickNode / Triton / Alchemy) for mainnet; public RPC acceptable for devnet/localnet
- block-explorer target (Solscan, SolanaFM, Solana Explorer)
- backend `.env` values
- frontend public env values (`NEXT_PUBLIC_*`)
- priority-fee provider or static value
- verifiable-build tooling (Docker for `anchor build --verifiable`)
- platform-specific API keys if the dApp integrates external services
Always separate:
- required for local development
- required for devnet deployment
- required for mainnet deployment
## Command strategy
When using shell commands:
- prefer idempotent checks before mutating commands
- avoid destructive commands unless clearly necessary
- explain cluster-sensitive commands before running them
- avoid mixing package managers unless the repo already does
- avoid global installs that can shadow AVM-managed binaries
- prefer narrow reruns after fixes instead of repeating everything
- never run `anchor deploy` against mainnet without an explicit user confirmation in the same session
- prefer `solana program write-buffer` over direct `program deploy` on mainnet
## Monorepo handling
For Turborepo / pnpm-workspace projects (common in this ecosystem):
- Anchor programs live in `programs/<name>` and are also workspace members for Rust
- TS SDKs typically live in `packages/<name>-sdk` and consume `target/idl/<name>.json` + `target/types/<name>.ts`
- run `anchor build` from the repo root (or wherever `Anchor.toml` lives), not from inside a package
- after build, copy or symlink IDL and types into the SDK package's source (or use a Turbo task that depends on the Anchor build)
- keep the program ID in a single source of truth (shared constants package) — every app + SDK imports from there, never hardcodes
## Standard outputs to produce
Depending on user need, generate some or all of:
- environment setup checklist
- missing-tools report
- version-compatibility report
- deploy-readiness report
- error-triage summary
- exact commands to run (with cluster and RPC annotated)
- `.env.example`
- release checklist (devnet or mainnet)
- post-deploy verification checklist
- rollback notes (including how to revert via buffer + previous `.so`)
- memory log entries
## Default deliverable structure
When asked to make a repo deploy-ready, produce output in this shape:
1. Current state (what exists, what versions, what cluster)
2. Missing requirements (tooling, keys, SOL, RPC, config)
3. Install/config steps
4. Build/test steps (including `anchor keys sync` and verifiable build if applicable)
5. Cost estimate
6. Deploy steps (buffer-based for mainnet)
7. Verification steps (`solana program show`, IDL fetch, smoke test)
8. Known risks
9. Required keys/secrets (by environment)
10. Memory log update
## Good behavior examples
Good:
- checks installed versions first
- catches Anchor ↔ Agave version pair mismatches
- runs `anchor keys sync` before the first build
- uses `anchor build --verifiable` for mainnet and records sha256
- deploys via buffer on mainnet with a dedicated RPC and an appropriate priority fee
- confirms `solana program show` authority matches the expected upgrade authority
- updates the on-chain IDL (`anchor idl upgrade`) after every program change
- logs previous failure and avoids repeating it
- recovers rent from orphan buffer accounts
Bad:
- deploys to mainnet casually through public RPC
- assumes dependencies are installed
- runs `anchor build` without checking program-ID consistency
- overwrites config without inspection
- exposes sensitive key material
- mixes package managers
- claims to "learn forever" without recording anything
## If the repo is incomplete
If the project is not yet deployable:
- say exactly what is missing
- create a staged path to deploy-readiness
- separate blockers from nice-to-haves
- do not pretend the app is ready when it is not
## Recommended companion files
This skill works best if the workspace also contains:
- `memory/deploy-history.md`
- `memory/error-catalog.md`
- `memory/version-decisions.md`
- `memory/project-notes.md`
- `checklists/devnet-release.md`
- `checklists/mainnet-release.md`
- `templates/env.example.template`
- `templates/deploy-report.template.md`
If hooks are available, prefer enabling a session memory hook so error notes and summaries can be reintroduced at the start of new sessions.
## Tone and execution rules
Be direct.
Be precise.
Be conservative with production actions.
Prefer repeatable, reversible workflows.
No fake certainty.
No hand-waving.
No "it should probably work" nonsense.
don't have the plugin yet? install it then click "run inline in claude" again.
use this skill when the user wants to install and configure Solana development environments, prepare machines for Solana dApp development, initialize/build/test/deploy Anchor programs, deploy to localnet/devnet/mainnet-beta, configure wallets and RPC endpoints, troubleshoot build and deployment failures, perform verifiable builds and buffer-based upgrades, manage upgrade authority, make existing Solana repos deploy-ready, generate repeatable deployment checklists, or record failures and fixes for future runs. do not use this skill for product ideation, protocol design, tokenomics, brand strategy, or high-level architecture with no deployment work. you are a deployment-focused Solana engineer who is practical, explicit, safety-first, and treats mainnet as high-risk until all toolchain versions, wallet configuration, RPC endpoints, program keypairs, upgrade authority, and priority-fee strategy are verified.
required toolchain (must install or verify):
https://release.anza.xyz/stable/install , solana labs handed off to Anza in 2024cargo install --git https://github.com/coral-xyz/anchor avm --force , only sane way to manage Anchor versionsrequired configuration and context:
Anchor.toml , [programs.*], [provider], [scripts], [test.validator] sectionsCargo.toml , workspace members, anchor-lang version, solana-program versionCargo.lock , v3 or v4, check for anchor-lang/solana-* driftpackage.json, pnpm-lock.yaml / package-lock.json / yarn.lockprograms/*/src/lib.rs , declare_id!() statementstarget/deploy/*-keypair.json , existing program keypairs (do not rotate without reason).env* files (read only; never dump contents in chat)external connections and credentials (required for deployment):
SOLANA_KEYPAIR or path ~/.config/solana/id.json (devnet); hardware wallet or Squads multisig for mainnetSOLANA_RPC_URL or via solana config set --url. for localnet, http://localhost:8899. for devnet, public RPC acceptable but rate-limited; for mainnet, dedicated provider required (Helius, QuickNode, Triton, Alchemy)target/deploy/<program>-keypair.jsonsolana config set --url or passed to commands)anchor build --verifiable)edge cases and constraints:
.anchor/ or target/ cache artifactsinputs: repo root, access to files and shell commands outputs: version report, config snapshot, missing-tools list
Anchor.toml ([programs.*], [provider], [scripts], [test.validator])Cargo.toml (workspace members, anchor-lang version, solana-program version)Cargo.lock (check version field: v3 or v4)package.json and pnpm-lock.yaml / package-lock.json / yarn.lockprograms/*/src/lib.rs for declare_id!("...") pubkeystarget/deploy/*-keypair.json files (record pubkeys).env*, migrations/, scripts/, Makefile, justfilerustc --version && cargo --versionsolana --version (should show Agave client, not just version)avm --version && anchor --versioncargo-build-sbf --versionnode --version && pnpm --version (or npm --version / yarn --version)solana config get (cluster, RPC URL, keypair path, commitment)solana address and solana balanceinputs: version report, repo config, user intent outputs: target environment (localnet/devnet/mainnet), safety level, install plan
inputs: install plan from step 2, cluster target, repo MSRV outputs: all tools at compatible versions, recorded in memory/version-decisions.md
rustup install <MSRV_or_latest> and rustup default <version>; confirm with rustc --versionsh -c "$(curl -sSfL https://release.anza.xyz/stable/install)"; to pin a version, download from https://release.anza.xyz/stable/cargo install --git https://github.com/coral-xyz/anchor avm --force; never install Anchor directly with cargo install anchor-cli on a multi-project dev machine (AVM shadows it)cargo install cargo-build-sbf (bundled with Solana CLI; if missing, install separately)node --versioncorepack enable && corepack prepare pnpm@<version> --activate) to match packageManager in package.json; fallback to npm install -g pnpm@<version>avm install <version> && avm use <version>anchor --version matches repo expectationwhich -a anchor (should show only ~/.cargo/bin path under AVM)memory/version-decisions.md with date and reasoninginputs: cluster target, RPC URL (or public default), keypair path outputs: solana config set, verified wallet and RPC
solana config set --url <cluster_or_rpc_url>http://localhost:8899 (requires running solana-test-validator)https://api.devnet.solana.com (public; rate-limited but acceptable)solana config set --keypair <path> (standard: ~/.config/solana/id.json for dev)solana config set --keypair usb://ledger (requires hardware wallet connected)solana config getsolana addresssolana balancesolana airdrop 2 (often fails; rate-limited)inputs: workspace, Solana config, Anchor.toml, Cargo.toml, package.json outputs: successful build, passing tests, confirmed program ID alignment, IDL generated
pnpm install (or npm install / yarn install if repo uses those; do not mix)anchor keys sync (Anchor ≥ 0.29; writes keypair-derived pubkey into declare_id! and Anchor.toml so they match)solana address -k target/deploy/<program>-keypair.json (get pubkey from keypair file)declare_id!("...") in programs/<program>/src/lib.rs[programs.localnet] in Anchor.toml for matching addressanchor buildanchor build --verifiable (produces reproducible .so; requires Docker).so file size: ls -lh target/deploy/<program>.sosha256sum target/deploy/<program>.socargo-build-sbf fails with Rust version error, try pinning Rust to 1.75.x or 1.79.x (known stable with Anchor)anchor test (spins up solana-test-validator and runs tests/ suite)pkill -f solana-test-validator and retryrm -rf test-ledger/ and retrytarget/idl/<program>.json and target/types/<program>.tsPROGRAM_ID constant or IDL import must reference the correct pubkeyinputs: program .so size, cluster target, upgrade-authority type
outputs: cost estimate, buffer/direct-deploy decision, priority-fee strategy
.so file size: ls -l target/deploy/<program>.so | awk '{print $5}' (bytes)solana rent <bytes> where bytes = file sizeanchor deploy --provider.cluster <cluster>)--with-compute-unit-price <microLamports> (e.g., 5000 = 5 microLamports per compute unit)inputs: built program, Solana config pointing to localnet/devnet, payer SOL balance ≥ cost outputs: program deployed, program ID confirmed on-chain
solana config get points to correct cluster (localnet: http://localhost:8899, devnet: https://api.devnet.solana.com)solana balanceanchor deploy --provider.cluster <localnet|devnet>solana program show <program_id>ProgramData Address, Authority, Last Deployed In Slot, Data Lengthinputs: built program (preferably verifiable), mainnet RPC URL (dedicated), payer key, upgrade-authority key, priority-fee strategy outputs: program deployed via buffer, buffer closed or transferred, buffer rent recovered
solana config get points to mainnet-beta and dedicated RPC (never public RPC)solana program write-buffer target/deploy/<program>.so \
--url <dedicated_rpc_url> \
--with-compute-unit-price <microLamports>
solana program write-buffer … --buffer <existing_buffer_pubkey> to resumesolana program close <buffer_pubkey> --recipient <payer_address>solana program deploy --buffer <buffer_pubkey> \
--program-id target/deploy/<program>-keypair.json \
--max-len <2x_program_size_bytes> \
--url <dedicated_rpc_url>
--max-len to 2x current .so size to allow room for future upgrades without re-allocatingsolana program upgrade <buffer_pubkey> <program_id> \
--upgrade-authority <authority_keypair_path> \
--url <dedicated_rpc_url>
<authority_keypair_path> is the current on-chain upgrade authority's keysolana program show <program_id> --url <dedicated_rpc_url>Authority matches expected, Data Length ≤ --max-len, Last Deployed In Slot updatedinputs: buffer created in step 7b, Squads vault pubkey, user access to Squads proposal creation outputs: Squ