Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Create the Program

Pre-Alpha Disclaimer: This is an early pre-alpha release for exploring the SDK and starting development only. There is no real MPC signing — all signatures are generated by a single mock signer, not a distributed network. Do not submit any real transactions for signing or rely on any security guarantees. The dWallet keys, trust model, and signing protocol are not final; do not rely on any key material until mainnet. All interfaces, APIs, and data formats are subject to change without notice. The Solana program and all on-chain data will be wiped periodically and everything will be deleted when we transition to Ika Alpha 1. This software is provided “as is” without warranty of any kind; use is entirely at your own risk and dWallet Labs assumes no liability for any damages arising from its use.

Cargo.toml

[package]
name = "ika-example-voting"
version = "0.1.0"
edition = "2024"

[dependencies]
ika-dwallet-pinocchio = { git = "https://github.com/dwallet-labs/ika-pre-alpha" }
pinocchio = "0.10"
pinocchio-system = "0.5"

[dev-dependencies]
mollusk-svm = "0.2"
solana-account = "2"
solana-instruction = "2"
solana-pubkey = "2"

[lib]
crate-type = ["cdylib", "lib"]

Key crates:

  • ika-dwallet-pinocchioDWalletContext CPI wrapper and CPI_AUTHORITY_SEED
  • pinocchio – zero-copy Solana program framework
  • pinocchio-systemCreateAccount CPI helper

lib.rs Skeleton

#![allow(unused)]
#![no_std]
fn main() {
extern crate alloc;

use pinocchio::{
    cpi::Signer,
    entrypoint,
    error::ProgramError,
    AccountView, Address, ProgramResult,
};
use pinocchio_system::instructions::CreateAccount;
use ika_dwallet_pinocchio::DWalletContext;

entrypoint!(process_instruction);
pinocchio::nostd_panic_handler!();

pub const ID: Address = Address::new_from_array([5u8; 32]);
}

Account Discriminators

#![allow(unused)]
fn main() {
const PROPOSAL_DISCRIMINATOR: u8 = 1;
const VOTE_RECORD_DISCRIMINATOR: u8 = 2;

const STATUS_OPEN: u8 = 0;
const STATUS_APPROVED: u8 = 1;
}

Proposal Account Layout

The Proposal PDA stores the dWallet reference, message hash, vote counts, and quorum:

Proposal PDA (seeds: ["proposal", proposal_id]):
  195 bytes total (2-byte header + 193 bytes data)
OffsetFieldSizeDescription
0discriminator11
1version11
2proposal_id32Unique proposal identifier
34dwallet32dWallet account pubkey
66message_hash32Hash of the message to sign
98user_pubkey32User public key for signing
130signature_scheme1Ed25519(0), Secp256k1(1), Secp256r1(2)
131creator32Proposal creator pubkey
163yes_votes4Yes vote count (LE u32)
167no_votes4No vote count (LE u32)
171quorum4Required yes votes (LE u32)
175status1Open(0) or Approved(1)
176msg_approval_bump1MessageApproval PDA bump
177bump1Proposal PDA bump
178_reserved16Reserved for future use

VoteRecord Account Layout

The VoteRecord PDA prevents double voting. Its existence proves the voter has already voted.

VoteRecord PDA (seeds: ["vote", proposal_id, voter]):
  69 bytes total (2-byte header + 67 bytes data)
OffsetFieldSizeDescription
0discriminator12
1version11
2voter32Voter pubkey
34proposal_id32Associated proposal
66vote1Yes(1) or No(0)
67bump1VoteRecord PDA bump

Instruction Dispatch

#![allow(unused)]
fn main() {
pub fn process_instruction(
    program_id: &Address,
    accounts: &[AccountView],
    data: &[u8],
) -> ProgramResult {
    let (discriminator, rest) = data
        .split_first()
        .ok_or(ProgramError::InvalidInstructionData)?;

    match *discriminator {
        0 => create_proposal(program_id, accounts, rest),
        1 => cast_vote(program_id, accounts, rest),
        _ => Err(ProgramError::InvalidInstructionData),
    }
}
}

Rent Calculation

The dWallet program uses a simple rent formula:

#![allow(unused)]
fn main() {
fn minimum_balance(data_len: usize) -> u64 {
    (data_len as u64 + 128) * 6960
}
}

Next Step

With the program skeleton in place, the next chapter implements the create_proposal instruction and the message approval flow.