Complete Zig implementation of the Solana SDK, enabling Solana blockchain development in Zig.
This project provides a comprehensive, type-safe Zig SDK that mirrors the Rust solana-sdk crate, allowing developers to build Solana programs and clients using Zig's modern, memory-safe language.
- Complete Solana SDK Implementation - Full feature parity with Rust
solana-sdk - Native SBF Support - solana-zig compiles directly to Solana BPF target
- Type-Safe API - Zero-cost abstractions matching Rust SDK
- Two-Layer Architecture - Shared SDK types + Program SDK with syscalls
| Feature | Status |
|---|---|
| SPL Token (Original) | ✅ Complete (v2.0.0) |
| Associated Token Account | ✅ Complete (v2.0.0) |
| Token-2022 Extensions | ⏳ Planned (v2.1.0) |
See docs/TOKEN_PROGRAMS.md for details.
┌─────────────┐ ┌─────────────┐
│ Zig Code │───────────────────>│ Solana eBPF │
│ │ solana-zig │ (.so) │
└─────────────┘ └─────────────┘
solana-program-sdk-zig/
├── sdk/ # Shared SDK (no syscalls)
│ └── src/
│ ├── public_key.zig # PublicKey type (pure SHA256 PDA)
│ ├── hash.zig # Hash type
│ ├── signature.zig # Signature type
│ ├── keypair.zig # Keypair type
│ ├── instruction.zig # Instruction types (no CPI)
│ ├── bincode.zig # Bincode serialization
│ ├── borsh.zig # Borsh serialization
│ └── ...
├── src/ # Program SDK (with syscalls)
│ ├── public_key.zig # Re-exports SDK + syscall PDA
│ ├── instruction.zig # Re-exports SDK + CPI
│ ├── account.zig # Account types
│ ├── syscalls.zig # Solana syscalls
│ ├── entrypoint.zig # Program entrypoint
│ ├── log.zig # Logging
│ └── ...
├── anchor/ # Anchor framework subpackage
│ └── src/
│ └── root.zig
├── program-test/ # Integration tests
└── build.zig
The Anchor-like framework is now a dedicated subpackage under anchor/.
const anchor = @import("sol_anchor_zig");
const sol = anchor.sdk;IDL + Zig client codegen:
const idl_json = try anchor.generateIdlJson(allocator, MyProgram, .{});
const client_src = try anchor.generateZigClient(allocator, MyProgram, .{});IDL output (build step):
./solana-zig/zig build idl \
-Didl-program=anchor/src/idl_example.zig \
-Didl-output-dir=idlidl-program must export pub const Program. By default, the IDL file name is derived from the program metadata name (or the program type name) and written under idl/. Use -Didl-output to override the full path.
Comptime derives:
const Accounts = anchor.Accounts(struct {
authority: anchor.Signer,
counter: anchor.Account(CounterData, .{
.discriminator = anchor.accountDiscriminator("Counter"),
.attrs = &.{
anchor.attr.seeds(&.{ anchor.seed("counter"), anchor.seedAccount("authority") }),
anchor.attr.bump(),
anchor.attr.constraint("authority.key() == counter.authority"),
},
}),
});
const AccountsSugar = anchor.Accounts(struct {
authority: anchor.Signer,
counter: anchor.Account(CounterData, .{
.discriminator = anchor.accountDiscriminator("Counter"),
.attrs = anchor.attr.account(.{
.seeds = &.{ anchor.seed("counter"), anchor.seedAccount("authority") },
.seeds_program = anchor.seedAccount("authority"),
.bump_field = "bump",
.constraint = "authority.key() == counter.authority",
}),
}),
});
const AccountsTyped = anchor.Accounts(struct {
authority: anchor.Signer,
counter: anchor.Account(CounterData, .{
.discriminator = anchor.accountDiscriminator("Counter"),
.attrs = anchor.attr.account(.{
.mut = true,
.signer = true,
.seeds = &.{ anchor.seed("counter"), anchor.seedAccount("authority") },
.bump_field = "bump",
.owner_expr = "authority.key()",
.space_expr = "8 + INIT_SPACE",
.constraint = "authority.key() == counter.authority",
}),
}),
});
const CounterTyped = anchor.Account(CounterData, .{
.discriminator = anchor.accountDiscriminator("Counter"),
.bump_field = anchor.dataField(CounterData, .bump),
.seeds = &.{
anchor.seed("counter"),
anchor.seedDataField(CounterData, .authority),
},
});
const FieldAccounts = anchor.AccountsWith(struct {
authority: anchor.Signer,
counter: CounterTyped,
}, .{
.counter = anchor.attr.account(.{
.mut = true,
.signer = true,
}),
});
const FieldAccountsDerive = anchor.AccountsDerive(struct {
authority: anchor.Signer,
counter: CounterTyped,
pub const attrs = .{
.counter = anchor.attr.account(.{
.mut = true,
.signer = true,
}),
};
});
const TokenAccounts = anchor.Accounts(struct {
payer: anchor.SignerMut,
authority: anchor.Signer,
mint: *const anchor.sdk.account.Account.Info,
});
const TokenAccountWrapped = anchor.AccountField(CounterTyped, &.{
anchor.attr.initIfNeeded(),
anchor.attr.payer(anchor.accountField(TokenAccounts, .payer)),
anchor.attr.tokenMint(anchor.accountField(TokenAccounts, .mint)),
anchor.attr.tokenAuthority(anchor.accountField(TokenAccounts, .authority)),
anchor.attr.associatedTokenMint(anchor.accountField(TokenAccounts, .mint)),
anchor.attr.associatedTokenAuthority(anchor.accountField(TokenAccounts, .authority)),
});
const CounterEvent = anchor.Event(struct {
amount: anchor.eventField(u64, .{ .index = true }),
owner: sol.PublicKey,
});Build/tests for anchor:
cd anchor
../solana-zig/zig build test --summary all./install-solana-zig.sh
# Or set custom version
SOLANA_ZIG_VERSION=v1.52.0 ./install-solana-zig.shsolana-zig is a modified Zig compiler with native Solana SBF target support. It compiles directly to .so files without external linkers.
# Solana CLI
sh -c "$(curl -sSfL https://release.anza.xyz/stable/install)"// src/main.zig
const sdk = @import("solana_program_sdk");
fn processInstruction(
program_id: *sdk.PublicKey,
accounts: []sdk.Account,
data: []const u8,
) sdk.ProgramResult {
sdk.log.sol_log("Hello from Zig!");
return .ok;
}
comptime {
sdk.entrypoint.define(processInstruction);
}# Build for Solana
./solana-zig/zig build -Dtarget=sbf-solanaconst sdk = @import("solana_sdk");
pub fn main() !void {
const pubkey = try sdk.PublicKey.fromBase58("11111111111111111111111111111112");
const keypair = sdk.Keypair.generate();
std.debug.print("Public key: {s}\n", .{pubkey.toBase58()});
}# Test Program SDK
./solana-zig/zig build test --summary all
# Integration tests
./program-test/test.shShared SDK types now live in the external repo DaviRain-Su/solana-sdk-zig; run its tests there if needed.
See docs/TESTING.md for the full test matrix.
For off-chain BN254 elliptic curve operations:
git submodule update --init vendor/mcl
./solana-zig/zig build test -Dwith-mclMCL is optional. On-chain programs use Solana's native syscalls (sol_alt_bn128_*).
Build for Solana SBF and deploy with Solana CLI. See docs/DEPLOYMENT.md for step-by-step workflows.
./solana-zig/zig build -Dtarget=sbf-solanaSee ROADMAP.md for current implementation status.
MIT