MPC signing flow

How to integrate MPC Bridge signing into your app

Your app builds transactions off-chain, then requests the MPC Bridge to sign them. The bridge returns a fully signed transaction ready for broadcast.

End-to-end flow

MPC Signing Flow
Your App                    MPC Bridge              Solana
   │                            │                      │
   │ 1. Build transaction       │                      │
   │    (instruction + accounts)│                      │
   │                            │                      │
   │ 2. Serialize message ──────▶                      │
   │    POST /v1/mpc/sign-solana-message               │
   │    { walletId, message }   │                      │
   │                            │                      │
   │ 3. Threshold signing       │                      │
   │    (key shares combine)    │                      │
   │                            │                      │
   │ ◀── 4. Signature returned  │                      │
   │                            │                      │
   │ 5. Attach signature ───────────────────────────▶  │
   │    sendRawTransaction()    │                      │
   │                            │                      │
   │ ◀──────────────────────── 6. Confirmation         │

Implementation example (TypeScript)

TypeScript
import { Connection, Transaction, PublicKey } from "@solana/web3.js";

const BRIDGE_URL = process.env.MPC_BRIDGE_URL;
const WALLET_ID = process.env.MPC_WALLET_ID;

async function signAndSend(transaction: Transaction, connection: Connection) {
  // 1. Serialize the transaction message
  const message = transaction.serializeMessage();

  // 2. Request signature from MPC Bridge
  const response = await fetch(`${BRIDGE_URL}/v1/mpc/sign-solana-message`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      walletId: WALLET_ID,
      message: Buffer.from(message).toString("base64"),
    }),
  });

  const { signature } = await response.json();

  // 3. Attach signature and broadcast
  transaction.addSignature(
    agentPubkey,
    Buffer.from(signature, "base64")
  );

  const txid = await connection.sendRawTransaction(
    transaction.serialize()
  );

  // 4. Confirm
  await connection.confirmTransaction(txid);
  return txid;
}

Implementation example (Python)

Python
import base64, requests
from solders.transaction import VersionedTransaction
from solana.rpc.api import Client

def sign_and_send(transaction, rpc_url, bridge_url, wallet_id):
    # 1. Serialize
    msg_bytes = bytes(transaction.message)

    # 2. Sign via MPC Bridge
    resp = requests.post(f"{bridge_url}/v1/mpc/sign-solana-message", json={
        "walletId": wallet_id,
        "message": base64.b64encode(msg_bytes).decode(),
    })
    signature = base64.b64decode(resp.json()["signature"])

    # 3. Attach signature and send
    signed_tx = VersionedTransaction(transaction.message, [signature])
    client = Client(rpc_url)
    result = client.send_transaction(signed_tx)
    return result.value

Error handling

ErrorCauseSolution
Bridge returns 401Invalid wallet IDVerify MPC_WALLET_ID matches the issued wallet
Bridge returns 503Bridge is down or overloadedRetry with exponential backoff; check /health endpoint
Transaction simulation failsInvalid instruction or insufficient fundsSimulate before signing; check account balances
Signature verification failedWrong signer or corrupted messageEnsure message bytes match exactly what was signed