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

CPI Framework

Pre-Alpha Disclaimer: This is a pre-alpha release for development and testing only. Signing uses a single mock signer, not real distributed MPC. All 11 protocol operations are implemented (DKG, Sign, Presign, FutureSign, ReEncryptShare, etc.) across all 4 curves and 7 signature schemes, but without real MPC 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.

DWalletContext

The CPI SDK is available for four Solana frameworks:

CrateFrameworkAccount type
ika-dwallet-pinocchioPinocchio&AccountView
ika-dwallet-nativesolana-program&AccountInfo<'info>
ika-dwallet-anchorAnchor v1AccountInfo<'info>
ika-dwallet-quasarQuasar&AccountView (via .to_account_view())

All four provide an identical DWalletContext with the same methods and wire format.

#![allow(unused)]
fn main() {
use ika_dwallet_pinocchio::DWalletContext; // or _anchor, _native, _quasar

let ctx = DWalletContext {
    dwallet_program: &dwallet_program_account,
    cpi_authority: &cpi_authority_account,
    caller_program: &my_program_account,
    cpi_authority_bump: bump,
};
}
FieldTypeDescription
dwallet_program&AccountViewThe dWallet program account
cpi_authority&AccountViewYour program’s CPI authority PDA
caller_program&AccountViewYour program’s account (must be executable)
cpi_authority_bumpu8Bump seed for the CPI authority PDA

CPI Authority PDA

Every program derives its CPI authority from a single seed:

#![allow(unused)]
fn main() {
pub const CPI_AUTHORITY_SEED: &[u8] = b"__ika_cpi_authority";

// Derivation:
let (cpi_authority, bump) = Address::find_program_address(
    &[CPI_AUTHORITY_SEED],
    &your_program_id,
);
}

The dWallet program verifies this derivation during CPI calls.

Available Methods

approve_message

Creates a MessageApproval PDA requesting a signature. The first account is the DWalletCoordinator PDA (used to read the current epoch).

#![allow(unused)]
fn main() {
ctx.approve_message(
    coordinator,        // readonly -- DWalletCoordinator PDA (for epoch)
    message_approval,   // writable, empty -- PDA to create
    dwallet,            // readonly -- the dWallet account
    payer,              // writable, signer -- rent payer
    system_program,     // readonly -- system program
    message_digest,     // [u8; 32] -- keccak256 hash of message
    message_metadata_digest, // [u8; 32] -- keccak256 hash of metadata (zero if none)
    user_pubkey,        // [u8; 32] -- user public key
    signature_scheme,   // u16 -- DWalletSignatureScheme value (0-6)
    bump,               // u8 -- MessageApproval PDA bump
)?;
}

CPI instruction data: [8, bump, message_digest(32), message_metadata_digest(32), user_pubkey(32), signature_scheme(2)] = 100 bytes.

CPI accounts:

#AccountWS
0coordinatornono
1message_approvalyesno
2dwalletnono
3caller_programnono
4cpi_authoritynoyes
5payeryesyes
6system_programnono

transfer_dwallet

Transfers dWallet authority to a new pubkey.

#![allow(unused)]
fn main() {
ctx.transfer_dwallet(
    dwallet,         // writable -- the dWallet account
    new_authority,   // [u8; 32] -- new authority pubkey
)?;
}

CPI instruction data: [24, new_authority(32)] = 33 bytes.

CPI accounts:

#AccountWS
0caller_programnono
1cpi_authoritynoyes
2dwalletyesno

transfer_future_sign

Transfers the completion authority of a PartialUserSignature.

#![allow(unused)]
fn main() {
ctx.transfer_future_sign(
    partial_user_sig,          // writable -- partial signature account
    new_completion_authority,  // [u8; 32] -- new authority pubkey
)?;
}

CPI instruction data: [42, new_completion_authority(32)] = 33 bytes.

CPI accounts:

#AccountWS
0partial_user_sigyesno
1caller_programnono
2cpi_authoritynoyes

Signing Mechanism

All CPI methods use invoke_signed with the CPI authority seeds:

#![allow(unused)]
fn main() {
let bump_byte = [self.cpi_authority_bump];
let signer_seeds: [Seed; 2] = [
    Seed::from(CPI_AUTHORITY_SEED),
    Seed::from(&bump_byte),
];
let signer = Signer::from(&signer_seeds);

invoke_signed(&instruction, &accounts, &[signer])
}

The dWallet program verifies:

  1. caller_program is executable
  2. cpi_authority matches PDA(["__ika_cpi_authority"], caller_program)
  3. dwallet.authority == cpi_authority (for approve_message and transfer_dwallet)

Instruction Discriminators

InstructionDiscriminator
approve_message8
transfer_ownership24
commit_network_dkg28
commit_network_key_reconfiguration30
commit_dwallet31
commit_future_sign33
commit_encrypted_user_secret_key_share34
commit_public_user_secret_key_share35
transfer_future_sign42
commit_signature43