Appearance
Quickstart
Build, test, and deploy a Starframe program on Zink in under ten minutes. Zink runs an unmodified SVM, so a Starframe program is just a standard Solana program pointed at a Zink RPC endpoint.
Upstream-compatible
The Zink-specific part is the RPC URL and deployment target. Build and test locally with the normal Solana toolchain, then deploy the compiled .so to Zink.
Prerequisites
| Tool | Version | Install |
|---|---|---|
| Rust | 1.84.1+ | rustup.rs |
| Solana CLI | cluster-compatible | sh -c "$(curl -sSfL https://release.anza.xyz/stable/install)" |
| Starframe CLI | latest | cargo install star_frame_cli |
| Zink RPC access | testnet or operator-provided | See Clusters & Environments |
Verify the tools:
bash
rustc --version
solana --version
cargo build-sbf --version
sf --helpIf you need the newest Starframe CLI from source:
bash
cargo install --git https://github.com/staratlasmeta/star_frame star_frame_cli --lockedStep 1 — Scaffold a project
bash
sf new my_program
cd my_programThe scaffold creates a small counter program:
text
my_program/
├── .cargo/config.toml # sets SBF_OUT_DIR = "target/deploy"
├── Cargo.toml # Starframe, Borsh, bytemuck, and test deps
├── README.md
├── src/
│ ├── lib.rs # program declaration and instruction set
│ ├── states.rs # counter account, seeds, validation
│ ├── instructions/
│ │ ├── initialize.rs
│ │ └── increment.rs
│ └── tests/
│ └── counter.rs # Mollusk-based test and IDL generator
└── target/deploy/
└── my_program-keypair.json # generated program keypairThe generated keypair public key is written into the program declaration, so the program ID is deterministic from the first build.
Step 2 — Inspect the program surface
Open src/lib.rs. The scaffold uses a StarFrameProgram declaration plus an InstructionSet enum instead of a hand-written entrypoint:
rust
use instructions::*;
use star_frame::prelude::*;
mod instructions;
pub mod states;
#[cfg(test)]
mod tests;
#[derive(StarFrameProgram)]
#[program(
instruction_set = MyProgramInstructionSet,
id = "<GENERATED_PROGRAM_ID>"
)]
pub struct MyProgramProgram;
#[derive(InstructionSet)]
pub enum MyProgramInstructionSet {
Initialize(InitializeCounter),
Increment(Increment),
}The account state and PDA seeds live in src/states.rs, and each instruction gets its own account set and handler under src/instructions/.
Step 3 — Build
Run a normal Rust build first, then compile the on-chain sBPF artifact:
bash
cargo build
cargo build-sbfThe deployable binary lands at:
text
target/deploy/my_program.soConfirm the program ID from the generated keypair:
bash
solana-keygen pubkey target/deploy/my_program-keypair.jsonThat pubkey should match the id = "..." value in src/lib.rs.
Step 4 — Test locally
Run fast native tests:
bash
cargo testThen build the sBPF artifact and run the scaffolded Mollusk test against it:
bash
cargo build-sbf
cargo test-sbfThe scaffolded test uses Mollusk to call the generated Starframe client helpers, initialize the counter PDA, increment it, and assert the serialized account state. It skips the program-binary check when target/deploy/<program>.so is missing, so cargo build-sbf && cargo test-sbf is the CLI-advertised loop that validates the compiled artifact. If your installed Solana toolchain does not expose cargo test-sbf, rerun cargo test after cargo build-sbf; the test also reads SBF_OUT_DIR and target/deploy directly.
Generate a Codama-compatible IDL when you need client bindings:
bash
cargo test --features idl -- generate_idlThe generated IDL is written under target/idl/.
Step 5 — Deploy to Zink Testnet
Point the Solana CLI at the published Zink Testnet endpoint and confirm the deployer wallet is funded:
bash
solana config set --url https://testnet-rpc.z.ink
solana balanceZink-specific
https://testnet-rpc.z.ink is the currently published public Zink Testnet endpoint. If you need funds for that cluster, use the operator or environment-specific funding workflow you were given rather than assuming a public faucet.
Deploy the compiled program with the generated program keypair:
bash
solana program deploy \
target/deploy/my_program.so \
--program-id target/deploy/my_program-keypair.jsonVerify the deployment:
bash
PROGRAM_ID=$(solana-keygen pubkey target/deploy/my_program-keypair.json)
solana program show "$PROGRAM_ID" --url https://testnet-rpc.z.inkStep 6 — Iterate
A tight local loop looks like this:
bash
cargo test
cargo build-sbf
cargo test-sbfThe first cargo test keeps the native loop fast. The SBF test step runs after the deployable binary exists, so the scaffolded Mollusk test can load target/deploy/<program>.so and validate the compiled artifact before you redeploy.
Before redeploying to Zink, rerun the full test suite, check account layout compatibility, and regenerate the IDL if the instruction or account surface changed.
Next steps
- Local Setup — install the full toolchain
- Starframe — framework concepts and examples
- Testing & Localnet — local validator and test strategies
- Deployment — deploy, upgrade, and verify programs on Zink