Skip to main content
Version: 1.1.2

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]/rn/api-ref/classes/BIP340).

import { StatefulEcdsa } from '@sodot/sodot-react-native-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 StatefulEcdsa(); // Note that a stateless Ecdsa class is also available with the same API as the Node and Web SDKs
const API_KEY = 'MY_API_KEY';
const keygenRoomUuid = await ecdsa.createRoom(N, API_KEY);
// All parties call initKeygen to get a keygenId
const keygenId = await ecdsa.initKeygen('myKeyName');
// All parties receive the keygenIds from all other parties
const keygenIds = [keygenId1, keygenId2];
// All parties join the keygen room
const publicKey = await ecdsa.keygen(keygenRoomUuid, N, T, 'myKeyName', keygenIds);

// 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 derivedPubkey = await ecdsa.derivePubkey('myKeyName', derivationPath);
API reference

Full details can be found here.

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

Signing

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

import { StatefulEcdsa, MessageHash } from '@sodot/sodot-react-native-sdk';

// To sign a message, create a signing room on the server side, using your API_KEY
const N = 3;
const T = 2;
const ecdsa = new StatefulEcdsa(); // Note that a stateless Ecdsa class is also available with the same API as the Node and Web SDKs
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 derivedPubkey = await ecdsa.derivePubkey('myKeyName', derivationPath);
// Hash the message
const messageHash = MessageHash.sha256('my message');
// 2 parties join the signing room
const signature = await ecdsa.sign(signingRoomUuid, 'myKeyName', messageHash, derivationPath);
// This signature can now be verified against derivedPubkey
API reference

Full details can be found here.

Behind the scenes this is the rough flow of communication that occurs, note that since only 2 signers are needed, Alice (chosen as a non-signer in this example) doesn't participate at all in the protocol:

Signature Verification

If necessary, the signature can be verified using extenal libraries.

import elliptic from 'elliptic';

// An EcdsaKeygenResult was previously generated using keygen
const keygenResult = await ecdsa.keygen(...);

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);

var EC = elliptic.ec;
var ec = new EC('secp256k1');
const uncompressed = pubkey.serializeUncompressed();
const signDer = Buffer.from(signature.der).toString('hex');
var key = ec.keyFromPublic(uncompressed, 'hex');
const isVerified = key.verify(messageHash.bytes, signDer);

Full library documentation can be found here.