Create MPC Keys

Overview

For self-custody MPC hot 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 hot wallets, follow the steps in Set Up External-Signing Mode.

ECDSA or EdDSA

The elliptic curve of the asset determines how the keys are generated. 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