# 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](/cryptography/signature-scheme#what-is-a-threshold-signature-scheme) setting)

To generate a key we simply run:

:::tip[Feature]
BIP-340 (for Bitcoin Taproot) is also supported. More details can be found [here](/rn/api-ref/classes/BIP340).
:::

<Tabs>
  <Tab title="ECDSA RN">
    ```typescript
    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);
    ```

    :::tip[API reference]
    Full details can be found [here](/rn/api-ref/classes/StatefulEcdsa).
    :::
  </Tab>

  <Tab title="Ed25519 RN">
    ```typescript
    import { StatefulEd25519 } 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 ed25519 = new StatefulEd25519(); // Note that a stateless Ed25519 class is also available with the same API as the Node and Web SDKs
    const API_KEY = 'MY_API_KEY';
    const keygenRoomUuid = await ed25519.createRoom(N, API_KEY);
    // All parties call initKeygen to get a keygenId
    const keygenId = await ed25519.initKeygen('myKeyName');
    // All parties receive the keygenIds from all other parties
    const keygenIds = [keygenId1, keygenId2];
    // All parties join the keygen room
    const publicKey = await ed25519.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 ed25519.derivePubkey('myKeyName', derivationPath);
    ```

    :::tip[API reference]
    Full details can be found [here](/rn/api-ref/classes/StatefulEd25519).
    :::
  </Tab>
</Tabs>

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

```mermaid
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:

<Tabs>
  <Tab title="ECDSA RN">
    ```typescript
    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
    ```

    :::tip[API reference]
    Full details can be found [here](/rn/api-ref/classes/StatefulEcdsa).
    :::
  </Tab>

  <Tab title="Ed25519 RN">
    ```typescript
    import { StatefulEd25519 } 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 ed25519 = new StatefulEd25519(); // Note that a stateless Ed25519 class is also available with the same API as the Node and Web SDKs
    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 derivedPubkey = await ed25519.derivePubkey('myKeyName', derivationPath);
    // The message as a hex string
    const message = 'cafecafe';
    // 2 parties join the signing room
    const signature = await ed25519.sign(signingRoomUuid, 'myKeyName', message, derivationPath);
    // This signature can now be verified against derivedPubkey
    ```

    :::tip[API reference]
    Full details can be found [here](/rn/api-ref/classes/StatefulEd25519).
    :::
  </Tab>
</Tabs>

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:

```mermaid
sequenceDiagram
    actor Alice
    actor Bob
    actor Charlie
    participant App as App Server
    rect rgb(200,200,230,.3)
    Note left of Alice: Room Setup
    App->>Relay: Create room for 2 participants
    Relay->>App: room_id
    App->>Bob: room_id
    App->>Charlie: room_id
    par Bob invites Charlie
    Note over Bob,Charlie: Propagated externally to the SDK 
    Bob-->>Charlie: msg, key_name
    Note over Charlie: Charlie decides whether they wish to sign msg
    end
    Bob->>Relay: Connect to room_id
    Charlie->>Relay: Connect to room_id
    end
    rect rgb(230,200,200,.3)
    Note left of Alice: Signing
    Note over Bob,Charlie: Run Signing
    activate Bob
    activate Charlie
    Bob->>Relay: Relayed Communication
    Relay->>Bob: 
    Charlie->>Relay: 
    Relay->>Charlie: 
    Note over Bob: Bob has a signature on msg
    deactivate Bob
    Note over Charlie: Charlie has a signature on msg
    deactivate Charlie
    end

```

## Signature Verification

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

<Tabs>
  <Tab title="ECDSA RN">
    ```typescript
    import { Ecdsa, MessageHash } from '@sodot/sodot-react-native-sdk';
    import elliptic from 'elliptic';

    const ecdsa = new Ecdsa();
    // An EcdsaKeygenResult (keygenResult) was previously generated using keygen
    // A signing room (signingRoomUuid) was previously created on the server side

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

    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.](https://www.npmjs.com/package/elliptic)
  </Tab>

  <Tab title="Ed25519 RN">
    ```typescript
    import { Ed25519 } from '@sodot/sodot-react-native-sdk';
    import * as ed from '@noble/ed25519';
    import { sha512 } from '@noble/hashes/sha512';
    ed.etc.sha512Sync = (...m) => sha512(ed.etc.concatBytes(...m));

    const ed25519 = new Ed25519();
    // An Ed25519KeygenResult (keygenResult) was previously generated using keygen
    // A signing room (signingRoomUuid) was previously created on the server side

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

    // validating the signature using the '@noble/ed25519' package
    const messageAsUint8Array = Uint8Array.from(Buffer.from(message, 'hex'));
    const isValid = await ed.verify(signature, messageAsUint8Array, pubkey);
    ```

    Full library documentation can be found [here.](https://www.npmjs.com/package/@noble/ed25519/v/1.7.1)
  </Tab>
</Tabs>
