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

SubmitTransaction

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.

Overview

SubmitTransaction is the primary gRPC RPC for all dWallet operations. It accepts a UserSignedRequest and returns a TransactionResponse.

The request type is determined by the DWalletRequest enum variant inside the BCS-serialized payload. This means a single RPC endpoint handles DKG, signing, presigning, and other operations.

Service Definition

service DWalletService {
  rpc SubmitTransaction(UserSignedRequest) returns (TransactionResponse);
  rpc GetPresigns(GetPresignsRequest) returns (GetPresignsResponse);
  rpc GetPresignsForDWallet(GetPresignsForDWalletRequest) returns (GetPresignsResponse);
}

UserSignedRequest

All mutation requests are wrapped in UserSignedRequest:

message UserSignedRequest {
  bytes user_signature = 1;      // BCS-serialized UserSignature enum
  bytes signed_request_data = 2; // BCS-serialized SignedRequestData
}
FieldTypeDescription
user_signaturebytesBCS-serialized UserSignature enum (signature + public key + scheme)
signed_request_databytesBCS-serialized SignedRequestData (the signed payload)

The user_signature covers the signed_request_data bytes – validators independently verify the signature.

Authentication

The UserSignature enum is self-contained: it carries both the signature bytes and the public key bytes, with the variant determining the scheme:

#![allow(unused)]
fn main() {
pub enum UserSignature {
    Ed25519 {
        signature: Vec<u8>,   // 64 bytes
        public_key: Vec<u8>,  // 32 bytes
    },
    Secp256k1 {
        signature: Vec<u8>,   // 64 bytes
        public_key: Vec<u8>,  // 33 bytes (compressed)
    },
    Secp256r1 {
        signature: Vec<u8>,   // 64 bytes
        public_key: Vec<u8>,  // 33 bytes (compressed)
    },
}
}

Signed Payload

The SignedRequestData struct contains the operation to perform:

#![allow(unused)]
fn main() {
pub struct SignedRequestData {
    pub session_identifier_preimage: [u8; 32],
    pub epoch: u64,
    pub chain_id: ChainId,
    pub intended_chain_sender: Vec<u8>,
    pub request: DWalletRequest,
}
}
FieldDescription
session_identifier_preimageRandom 32 bytes (uniqueness nonce)
epochCurrent Ika epoch (prevents cross-epoch replay)
chain_idSolana or Sui
intended_chain_senderUser’s address on the target chain
requestThe DWalletRequest enum variant

TransactionResponse

message TransactionResponse {
  bytes response_data = 1; // BCS-serialized TransactionResponseData
}

Deserialize response_data into TransactionResponseData to get the result:

#![allow(unused)]
fn main() {
pub enum TransactionResponseData {
    Signature { signature: Vec<u8> },
    Attestation {
        attestation_data: Vec<u8>,
        network_signature: Vec<u8>,
        network_pubkey: Vec<u8>,
        epoch: u64,
    },
    Presign {
        presign_id: Vec<u8>,
        presign_data: Vec<u8>,
        epoch: u64,
    },
    Error { message: String },
}
}

Client Usage

#![allow(unused)]
fn main() {
use ika_grpc::d_wallet_service_client::DWalletServiceClient;
use ika_grpc::UserSignedRequest;

let mut client = DWalletServiceClient::connect(
    "https://pre-alpha-dev-1.ika.ika-network.net:443"
).await?;

let resp = client.submit_transaction(UserSignedRequest {
    user_signature: bcs::to_bytes(&user_sig)?,
    signed_request_data: bcs::to_bytes(&signed_data)?,
}).await?;

let tx_response = resp.into_inner();
let result: TransactionResponseData = bcs::from_bytes(&tx_response.response_data)?;
}

Query RPCs

GetPresigns

Get all global presigns for a user.

message GetPresignsRequest {
  bytes user_pubkey = 1;
}

GetPresignsForDWallet

Get all presigns for a specific dWallet.

message GetPresignsForDWalletRequest {
  bytes user_pubkey = 1;
  bytes dwallet_id = 2;
}

GetPresignsResponse

message GetPresignsResponse {
  repeated PresignInfo presigns = 1;
}

message PresignInfo {
  bytes presign_id = 1;
  bytes dwallet_id = 2;
  uint32 curve = 3;
  uint32 signature_scheme = 4;
  uint64 epoch = 5;
}