Overview

For self-custody MPC wallets, you can create a key share by exchanging a public share and an encrypted-private share of a key between all parties (user, backup, and BitGo). Unlike multisignature wallets, the backup can't be managed by a key recovery service (KRS) - you must manage it yourself. For example:

  • User exchanges shares with the backup and BitGo.
  • Backup exchanges shares with the user and BitGo.
  • BitGo exchanges shares with the user and backup.

Key-share creation completes once each party exchanges its shares with a different party member and each member verifies they can derive the same common key.

Note

If you want to store your own keys for your self-custody wallets, follow the steps in Set Up External-Signing Mode.

ECDSA or EdDSA

Cookbooks

Need just the steps? Expand a cookbook below to get started:

Create MPC Keys (ECDSA)Open Cookbook Create MPC Keys (EdDSA)Open Cookbook

The elliptic curve of the asset determines which algorithm BitGo uses to generate the keys. Select the elliptic curve for the asset you want to create keys for:

Prerequisites

Get Started

Create Keys

import * as dotenv from "dotenv";
dotenv.config();
import { EnvironmentName } from "bitgo";
import { BitGoAPI } from "@bitgo/sdk-api";
import { Hteth } from "@bitgo/sdk-coin-eth";

const config = {
  USERNAME: process.env.USERNAME as string,
  PASSWORD: process.env.PASSWORD as string,
  ENV: process.env.ENV as EnvironmentName,
  OTP: process.env.OTP as string,
  ENTERPRISE_ID: process.env.ENTERPRISE_ID as string,
};

const bitgo = new BitGoAPI({ env: config.ENV });
bitgo.register("hteth", Hteth.createInstance);
const coin = bitgo.coin("hteth");

async function auth() {
  await bitgo.authenticate({
    username: config.USERNAME,
    password: config.PASSWORD,
    otp: config.OTP,
  });
}

async function main() {
  await auth();
  const keychains = await coin.keychains().createMpc({
    multisigType: "tss",
    passphrase: config.PASSWORD,
    enterprise: config.ENTERPRISE_ID,
  });
  console.log(keychains);
  /**
   * Note: the userKeychain and backupKeychain fields have a very large encryptedPrv
   * Note: the reducedEncryptedPrv field is the same as what exists on KeyCards generated in the web UI
   * Or if the result of this is passed into the @bitgo/key-card package
   */
}

main().catch((err) => console.error(err));

Step Result

Note

This is critical key information. Save it in a secure place. This is the only time you're given the full encryptedPrv that you use to decrypt the user key.

{
    "userKeychain": {
        "id": "6674a960bb9d6a5d41228bfcf8d15724",
        "source": "user",
        "type": "tss",
        "commonKeychain": "032ba30f224e85a300fdc94eb28b37c83d0435e706389db33e0b977ad15b94edbc63b15dee6045330287bc9ccd33522a6e50c90a5f7e845e6dbc6299556e3619c6",
        "encryptedPrv": "string",
        "reducedEncryptedPrv": "string"
    },
    "backupKeychain": {
        "id": "6674a96064bda5f82a6f95efc7ad656e",
        "source": "backup",
        "type": "tss",
        "commonKeychain": "032ba30f224e85a300fdc94eb28b37c83d0435e706389db33e0b977ad15b94edbc63b15dee6045330287bc9ccd33522a6e50c90a5f7e845e6dbc6299556e3619c6",
        "encryptedPrv": "string",
        "reducedEncryptedPrv": "string"
    },
    "bitgoKeychain": {
        "id": "6674a95f38be1dec30ce8f2ae40489c4",
        "source": "bitgo",
        "type": "tss",
        "commonKeychain": "032ba30f224e85a300fdc94eb28b37c83d0435e706389db33e0b977ad15b94edbc63b15dee6045330287bc9ccd33522a6e50c90a5f7e845e6dbc6299556e3619c6",
        "isBitGo": true
    }
}

Next

Use the id for each key when you Create Wallets.

See Also