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 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.

DWalletContext

The ika-dwallet-pinocchio crate provides DWalletContext for calling dWallet instructions via CPI from Pinocchio programs.

#![allow(unused)]
fn main() {
use ika_dwallet_pinocchio::DWalletContext;

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.

#![allow(unused)]
fn main() {
ctx.approve_message(
    message_approval,   // writable, empty -- PDA to create
    dwallet,            // readonly -- the dWallet account
    payer,              // writable, signer -- rent payer
    system_program,     // readonly -- system program
    message_hash,       // [u8; 32] -- hash of message to sign
    user_pubkey,        // [u8; 32] -- user public key
    signature_scheme,   // u8 -- Ed25519(0), Secp256k1(1), Secp256r1(2)
    bump,               // u8 -- MessageApproval PDA bump
)?;
}

CPI instruction data: [8, bump, message_hash(32), user_pubkey(32), signature_scheme] = 67 bytes.

CPI accounts:

#AccountWS
0message_approvalyesno
1dwalletnono
2caller_programnono
3cpi_authoritynoyes
4payeryesyes
5system_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
transfer_future_sign42