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

TypeScript Client

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.

The @ika.xyz/pre-alpha-solana-client package provides a TypeScript client for interacting with the dWallet program on Solana. Built on @solana/kit (web3.js v2).

Installation

bun add @ika.xyz/pre-alpha-solana-client @solana/kit

Or with npm:

npm install @ika.xyz/pre-alpha-solana-client @solana/kit

Quick Start

import {
  address,
  createSolanaRpc,
  createSolanaRpcSubscriptions,
  generateKeyPairSigner,
  pipe,
  createTransactionMessage,
  setTransactionMessageFeePayerSigner,
  setTransactionMessageLifetimeUsingBlockhash,
  appendTransactionMessageInstruction,
  signTransactionMessageWithSigners,
  sendAndConfirmTransactionFactory,
} from "@solana/kit";

const RPC_URL = "https://api.devnet.solana.com";
const WS_URL = "wss://api.devnet.solana.com";
const DWALLET_PROGRAM = address("TODO: program ID after deployment");

const rpc = createSolanaRpc(RPC_URL);
const rpcSubscriptions = createSolanaRpcSubscriptions(WS_URL);
const sendAndConfirm = sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions });

Building Transactions

Approve Message

Build an ApproveMessage instruction to authorize the Ika network to sign a message:

import { getAddressEncoder, getProgramDerivedAddress, getUtf8Encoder } from "@solana/kit";

const utf8 = getUtf8Encoder();
const addressEncoder = getAddressEncoder();

// Derive MessageApproval PDA
const [messageApprovalPda, messageApprovalBump] = await getProgramDerivedAddress({
  seeds: [
    utf8.encode("message_approval"),
    addressEncoder.encode(dwalletAddress),
    messageHash, // Uint8Array(32)
  ],
  programAddress: DWALLET_PROGRAM,
});

// Build instruction data: disc(1) + bump(1) + message_hash(32) + user_pubkey(32) + scheme(1) = 67
const data = new Uint8Array(67);
data[0] = 8; // IX_APPROVE_MESSAGE discriminator
data[1] = messageApprovalBump;
data.set(messageHash, 2);
data.set(userPubkey, 34);
data[66] = 0; // signature_scheme: 0=Ed25519

const approveMessageIx = {
  programAddress: DWALLET_PROGRAM,
  accounts: [
    { address: messageApprovalPda, role: AccountRole.WRITABLE },
    { address: dwalletAddress, role: AccountRole.READONLY },
    { address: authority, role: AccountRole.READONLY_SIGNER },
    { address: payer, role: AccountRole.WRITABLE_SIGNER },
    { address: SYSTEM_PROGRAM, role: AccountRole.READONLY },
  ],
  data,
};

Transfer dWallet Authority

const data = new Uint8Array(33);
data[0] = 24; // IX_TRANSFER_DWALLET discriminator
data.set(newAuthorityBytes, 1);

const transferIx = {
  programAddress: DWALLET_PROGRAM,
  accounts: [
    { address: currentAuthority, role: AccountRole.READONLY_SIGNER },
    { address: dwalletAddress, role: AccountRole.WRITABLE },
  ],
  data,
};

Send Transaction

const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();

const tx = pipe(
  createTransactionMessage({ version: 0 }),
  (msg) => setTransactionMessageFeePayerSigner(payer, msg),
  (msg) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, msg),
  (msg) => appendTransactionMessageInstruction(approveMessageIx, msg),
);

const signedTx = await signTransactionMessageWithSigners(tx);
await sendAndConfirm(signedTx, { commitment: "confirmed" });

Reading Accounts

Read dWallet

const account = await rpc.getAccountInfo(dwalletAddress, { encoding: "base64" }).send();
const data = Buffer.from(account.value.data[0], "base64");

// Field offsets (after 2-byte disc+version prefix):
const authority = data.subarray(2, 34);       // [u8; 32]
const curve = data[34];                        // u8
const state = data[35];                        // u8: 0=DKGInProgress, 1=Active, 2=Frozen
const publicKeyLen = data[36];                 // u8
const publicKey = data.subarray(37, 37 + publicKeyLen);

Read MessageApproval

const data = Buffer.from(account.value.data[0], "base64");

const dwallet = data.subarray(2, 34);
const messageHash = data.subarray(34, 66);
const approver = data.subarray(66, 98);
const status = data[139];                      // 0=Pending, 1=Signed
const signatureLen = data.readUInt16LE(140);
const signature = data.subarray(142, 142 + signatureLen);

gRPC Client

For submitting dWallet operations (DKG, Sign, Presign) via gRPC:

// The gRPC client uses BCS-serialized request/response types.
// See the gRPC API section for details on SubmitTransaction.

// Connect to the pre-alpha dWallet gRPC service
const GRPC_URL = "pre-alpha-dev-1.ika.ika-network.net:443";

// gRPC types are defined in proto/ika_dwallet.proto
// Use a gRPC client library (e.g., @grpc/grpc-js or connectrpc) to call:
//   DWalletService.SubmitTransaction(UserSignedRequest) -> TransactionResponse

Instruction Discriminators

DiscriminatorInstruction
8ApproveMessage
24TransferDWallet
31CommitDWallet
33CommitFutureSign
34CommitEncryptedUserSecretKeyShare
35CommitPublicUserSecretKeyShare
36CreateDeposit
37TopUp
38SettleGas
42TransferFutureSign
43CommitSignature
44RequestWithdraw
45Withdraw
46Initialize

PDA Seeds

AccountSeeds
DWalletCoordinator["dwallet_coordinator"]
DWallet["dwallet", curve_byte, public_key_bytes]
MessageApproval["message_approval", dwallet_pubkey, message_hash]
GasDeposit["gas_deposit", user_pubkey]
NetworkEncryptionKey["network_encryption_key", noa_public_key]
CPI Authority["__ika_cpi_authority"] (derived per calling program)

Framework Comparison

PinocchioNativeAnchorTypeScript
LanguageRust (no_std)Rust (std)Rust (std)TypeScript
RunsOn-chainOn-chainOn-chainOff-chain
Use caseProgram CPIProgram CPIProgram CPIClient transactions
Account typesAccountViewAccountInfoAccount/UncheckedAccountAddress + raw bytes
Best forMax performanceExisting codebasesRapid developmentdApps, scripts, bots