All versions / Web SDK v1.1

Getting Started

Generate a key and begin signing in under a minute.

Key Generation

First we must generate a public key and some key shares so that we can later sign messages.
You will need your API_KEY.

We show example code for a 2-of-3 threshold signing scenario.
(Note that Sodot MPC SDK allows any t-of-n threshold signing setting)

To generate a key we simply run:

Feature BIP-340 (for Bitcoin Taproot) is also supported. More details can be found here.

ECDSA Web:

import { Ecdsa } from '@sodot/sodot-web-sdk';

// Your server side creates a room for 3 parties using its API_KEY
// Creating a room uuid should always happen on the server side using your API_KEY, so that the API_KEY is never exposed to the client side
const N = 3;
const T = 2;
const ecdsa = new Ecdsa();
const API_KEY = 'MY_API_KEY';
const keygenRoomUuid = await ecdsa.createRoom(N, API_KEY);
// All parties call initKeygen to get an EcdsaInitKeygenResult, that contains a keygenId
const keygenInitResult = await ecdsa.initKeygen();
// All parties receive the keygenIds from all other parties
const keygenIds = [keygenId1, keygenId2];
// All parties join the keygen room
const keygenResult = await ecdsa.keygen(keygenRoomUuid, N, T, keygenInitResult, keygenIds);
// Discard the keygenInitResult object at this point
// Pick the derivation path of the public key you want to sign for
const derivationPath = new Uint32Array([44,60,0,0,0]);
// Get the public key for the derivation path
const pubkey = await ecdsa.derivePubkey(keygenResult, derivationPath);

API reference Full details can be found here.

Ed25519 Web:

import { Ed25519 } from '@sodot/sodot-web-sdk';

// Your server side creates a room for 3 parties using its API_KEY
// Creating a room uuid should always happen on the server side using your API_KEY, so that the API_KEY is never exposed to the client side
const N = 3;
const T = 2;
const ed25519 = new Ed25519();
const API_KEY = 'MY_API_KEY';
const keygenRoomUuid = await ed25519.createRoom(N, API_KEY);
// All parties call initKeygen to get an Ed25519InitKeygenResult, that contains a keygenId
const keygenInitResult = await ed25519.initKeygen();
// All parties receive the keygenIds from all other parties
const keygenIds = [keygenId1, keygenId2];
// All parties join the keygen room
const keygenResult = await ed25519.keygen(keygenRoomUuid, N, T, keygenInitResult, keygenIds);
// Discard the keygenInitResult object at this point
// Pick the derivation path of the public key you want to sign for
const derivationPath = new Uint32Array([44,60,0,0,0]);
// Get the public key for the derivation path
const pubkey = await ed25519.derivePubkey(keygenResult, derivationPath);

API reference Full details can be found here.

Behind the scenes this is the rough flow of communication that occurs:

sequenceDiagram
    actor Alice
    actor Bob
    actor Charlie
    participant App as App Server
    rect rgb(200,200,230,.3)
    Note left of Alice: Keygen Setup
    App->>Relay: Create room for 3 participants
    Relay->>App: room_id
    App->>Alice: room_id
    App->>Bob: room_id
    App->>Charlie: room_id
    par Alice handshakes w/ Bob
    Note over Alice,Bob: Propagated externally to the SDK 
    Alice-->>Bob: keygen_id
    Bob-->>Alice: keygen_id
    and Alice handshakes w/ Charlie
    Note over Alice,Charlie: Propagated externally to the SDK
    Alice-->>Charlie: keygen_id
    Charlie-->>Alice: keygen_id
    and Bob handshakes w/ Charlie
    Note over Bob,Charlie: Propagated externally to the SDK
    Bob-->>Charlie: keygen_id
    Charlie-->>Bob: keygen_id
    end
    Alice->>Relay: Connect to room_id
    Bob->>Relay: Connect to room_id
    Charlie->>Relay: Connect to room_id
    end
    rect rgb(200,230,200,.3)
    Note left of Alice: Key Generation
    Note over Alice,Charlie: Run Distributed Key Generation
    activate Alice
    activate Bob
    activate Charlie
    Alice->>Relay: Relayed Communication
    Relay->>Alice: 
    Bob->>Relay: 
    Relay->>Bob: 
    Charlie->>Relay: 
    Relay->>Charlie: 
    Note over Alice: Alice has a Key Share
    deactivate Alice
    Note over Bob: Bob has a Key Share
    deactivate Bob
    Note over Charlie: Charlie has a Key Share
    deactivate Charlie
    end

Signing

Now that we have key shares on all the devices/servers of the potential signers we can sign by running:

ECDSA Web:

import { Ecdsa, MessageHash } from '@sodot/sodot-web-sdk';

// To sign a message, create a signing room on the server side, using your API_KEY
const N = 3;
const T = 2;
// An EcdsaKeygenResult was previously generated using keygen
const keygenResult = await ecdsa.keygen(...);

const ecdsa = new Ecdsa();
const API_KEY = 'MY_API_KEY;
const signingRoomUuid = await ecdsa.createRoom(T, API_KEY);

// Pick the derivation path of the public key you want to sign for
const derivationPath = new Uint32Array([44,60,0,0,0]);
// Get the public key for the derivation path
const pubkey = await ecdsa.derivePubkey(keygenResult, derivationPath);

// Hash the message
const messageHash = MessageHash.sha256('my message');
// 2 parties join the signing room
const signature = await ecdsa.sign(signingRoomUuid, keygenResult, messageHash, derivationPath);
// signature can be verified against pubkey

API reference Full details can be found here.

Ed25519 Web:

import { Ed25519 } from '@sodot/sodot-web-sdk';

// To sign a message, create a signing room on the server side, using your API_KEY
const N = 3;
const T = 2;
// An Ed25519KeygenResult was previously generated using keygen
const keygenResult = await ed25519.keygen(...);

const ed25519 = new Ed25519();
const API_KEY = 'MY_API_KEY';
const signingRoomUuid = await ed25519.createRoom(T, API_KEY);

// Pick the derivation path of the public key you want to sign for
const derivationPath = new Uint32Array([44,60,0,0,0]);
// Get the public key for the derivation path
const pubkey = await ed25519.derivePubkey(keygenResult, derivationPath);
// The message as a hex string
const message = 'cafecafe';
// 2 parties join the signing room
const signature = await ed25519.sign(signingRoomUuid, keygenResult, message, derivationPath);

API reference Full details can be found here.