MPCKitMPCKit

Authentication

API keys, the seed-driven identity model, and how the SDK persists what it must.

mpckit authentication has two layers. API keys authorize HTTP calls against a project's credit balance. Seed-driven identity binds a specific dWallet's user share. The SDK derives keys from a 32-byte seed you provide, and persists nothing for you.

API keys

Every HTTP call to api.mpckit.xyz carries the bearer token in the Authorization header.

GET /v1/health
Authorization: Bearer mpckit_test_4f1a8c93…

Tokens are issued in the dashboard, scoped to one project, and rotate on demand. They authorize what your project can do; they do not on their own authorize signing for any particular dWallet.

The SDK reads the key from MPCKitOptions.apiKey:

import { MPCKit } from "@mpckit/sdk";

const api = new MPCKit({
  baseUrl: "https://api.mpckit.xyz",
  apiKey: process.env.MPCKIT_API_KEY!,
  network: "testnet",
});

Server-side only

mpckit_test_ and mpckit_live_ keys belong on a server. Don't ship them to a browser. For browser/mobile signing, derive a per-user seed from a passkey PRF or similar and call the SDK directly from your backend.

Seed-driven identity

The SDK takes a 32-byte seed (Uint8Array) on every onboard and sign call. The seed is yours; you choose how to source it:

Prop

Type

The seed deterministically produces the encryption keys used by DKG and signing. Same seed + same dWallet = signing succeeds. Different seeds cannot sign the same dWallet.

What you actually need to persist

The seed is the only thing you must protect. Lose it and the dWallet is unrecoverable. Everything else is either on chain or derivable from the seed.

const result = await api.onboard({ seed, curve: Curve.SECP256K1 });

// the dWallet id (public, fine to store anywhere):
const dwalletId = result.dwallet.id;

What lives where

ValueWhere it livesRecoverable?
seedWherever you sourced it (passkey PRF, KMS…)No.
dwalletIdOn chain (Sui), mirrored in backendYes
EncryptedUserSecretKeyShare (encrypted)On chain (Sui)Yes
userSecretKeyShareHex (plaintext)Optional cache in your storageYes (rederive from seed + on-chain encrypted share)
userPublicOutputHexOptional cache; on chain tooYes

userSecretKeyShareHex is the warm-path input sign expects, but it's recoverable. UserShareEncryptionKeys.decryptUserShare (in upstream @ika.xyz/sdk) derives the class-groups decryption key from your seed, reads the on-chain encrypted share, and recovers the plaintext. So persist the share alongside the dWallet to keep sign fast; if you lose the cache, recover it from chain + seed.

If the cache leaks but the seed is safe, an attacker with the leaked share alone cannot sign — they also need a valid passkey assertion or project API key to reach the backend, and the network share is threshold-held by Ika validators. If the seed leaks, anyone with that seed plus a way to call sign can co-sign with the network. Treat the seed accordingly.

Token rotation

Rotate API keys from the dashboard or via the HTTP API. Plan for overlap when you rotate: deploy the new key, switch traffic to it, then revoke the old one when you're confident nothing still references it.

On this page