MPCKitMPCKit

Low-level onboarding

Drive DKG step by step from your own crypto pipeline.

The four-step onboarding flow is exposed directly so you can drive it from your own crypto pipeline (FFI to the upstream ika crypto crate, hardware-backed signers, alternative WASM bindings, etc.).

api.register_encryption_key(/* args */).await?;
api.onboard_zero_trust(/* args */).await?;
// poll get_dwallet until status == AwaitingUserShare
api.accept_user_share(/* args */).await?;

Stages

Register the encryption key

api.register_encryption_key(RegisterEncryptionKeyArgs {
    curve: Curve::Secp256k1,
    encryption_key_bytes: /* class-groups public component */,
    proof_bytes: /* possession proof */,
}).await?;

Returns the backend record id you'll pass into onboard_zero_trust.

Submit the DKG

let onboard = api.onboard_zero_trust(OnboardZeroTrustArgs {
    encryption_key_id: ek.id,
    dkg_message_bytes: /* user-side DKG message */,
}).await?;

The backend submits the on-chain DKG. The dWallet starts in Submitting and transitions to AwaitingUserShare.

Poll for the awaiting state

loop {
    let d = api.get_dwallet(&onboard.dwallet.id).await?;
    if matches!(d.dwallet.status, DWalletStatus::AwaitingUserShare) { break; }
    if matches!(d.dwallet.status, DWalletStatus::Failed) { /* bail */ }
    tokio::time::sleep(std::time::Duration::from_millis(500)).await;
}

Accept the user share

api.accept_user_share(AcceptUserShareArgs {
    dwallet_id: onboard.dwallet.id.clone(),
    user_public_output_signature: /* sign(user_public_output, seed-derived sk) */,
}).await?;

The dWallet transitions to Active. From here it's signable.

Argument shapes

The exact *Args structs depend on the upstream crypto crate's output shapes. They're documented in the rustdoc shipped with the crate. The high-level crypto-feature client wraps all four steps when the crypto feature is on.

On this page