Quick Start
If you don't have have access to the docker image or don't have NPM token, please contact us at info@silencelaboratories.com.
Here is how you can setup the Mobile SDK and perform MPC operations in less than a minute.
You will create a working MPC two-party setup, where the first party, a React Native mobile application interacts with Duo Server as a second party. We are providing a demo server endpoint for your convenience.
Prerequisites
For quick testing, the demo server is already deployed at demo-server.silencelaboratories.com. We are using this server for the quickstart guide.
The Cloud Verifying Key for the demo server is 01829099948d222f9731323900bc42bd3cc6f4e692f920705a9959b3e52378f188.
The Cloud Node Endpoint for the demo server is demo-server.silencelaboratories.com.
Setup the Mobile SDK (React Native)
Create a new React Native project
npx create-expo-app@latest SilentMPC --template blank-typescript
Configure Your Package Manager
Configure your package manager with a private token provided by us to access the private registry.
- yarn v2
- yarn v1 / npm
- Create a
.yarnrc.ymlfile in the root of your project and add the following line:
npmScopes:
"silencelaboratories":
npmAlwaysAuth: true
npmRegistryServer: "https://registry.npmjs.org"
npmAuthToken: ${NPM_TOKEN}
- Create a
.npmrcfile in the root of your project and add the following line:
//registry.npmjs.org/:_authToken=${NPM_TOKEN}
- Add the npm token as an environment variable, e.g., in a terminal session run:
export NPM_TOKEN=your-npm-token
Install the packages
Now you can install the Silent Shard SDK packages.
- npm
- yarn
npm install @silencelaboratories/silent-shard-sdk @silencelaboratories/dkls-sdk @silencelaboratories/schnorr-sdk
yarn add @silencelaboratories/silent-shard-sdk @silencelaboratories/dkls-sdk @silencelaboratories/schnorr-sdk
Project setup
Run the following command to generate the native code for your project:
npx expo prebuild
Session Creation
The Session object is the main entry point to interact with the Silent Shard SDK. It manages the lifecycle of the MPC operations.
import {
CloudWebSocketClient,
createEcdsaDuoSession,
} from "@silencelaboratories/silent-shard-sdk";
// Create a session
const cloudClient = new CloudWebSocketClient(
"demo-server.silencelaboratories.com",
true // Use true for secure connection, otherwise use false for local server
);
const session = await createEcdsaDuoSession({
cloudVerifyingKey: "01829099948d222f9731323900bc42bd3cc6f4e692f920705a9959b3e52378f188",
client: cloudClient,
});
Run the MPC operations
After creating the session, you can perform MPC operations.
Key Generation
Generate MPC keyshares and return the client keyshare with keygen method.
const clientKeyshare = await session.keygen();
console.log("Client Public Key:", clientKeyshare.publicKeyHex);
Signature Generation
Sign a message using the sign method.
const signature = await session.sign({
keyshare: clientKeyshare,
// Keccak256 Hash("Trusted Third Parties are Security Holes")
messageHash:
"53c48e76b32d4fb862249a81f0fc95da2d3b16bf53771cc03fd512ef5d4e6ed9",
derivationPath: "m",
});
console.log("Generated signature: ", signature);
Complete Code Example
Add the following code to your App.tsx.
import * as React from 'react';
import { CloudWebSocketClient, createEcdsaDuoSession } from '@silencelaboratories/silent-shard-sdk';
export default function App() {
React.useEffect(() => {
// We will MPC functions here
const mpcTest = async () => {
// Create a session
const cloudClient = new CloudWebSocketClient(
"demo-server.silencelaboratories.com",
true // Use true for secure connection, otherwise use false for local server
);
const session = await createEcdsaDuoSession({
cloudVerifyingKey: '01829099948d222f9731323900bc42bd3cc6f4e692f920705a9959b3e52378f188',
client: cloudClient,
});
// Key generation
const clientKeyshare = await session.keygen();
// Get public key of newly generated wallet
console.log('Client Public Key:', clientKeyshare.publicKeyHex);
// Signature generation
const signature = await session.sign({
keyshare: clientKeyshare,
// Keccak256 Hash("Trusted Third Parties are Security Holes")
messageHash: '53c48e76b32d4fb862249a81f0fc95da2d3b16bf53771cc03fd512ef5d4e6ed9',
derivationPath: 'm',
});
console.log('Generated signature: ', signature);
};
mpcTest();
}, []);
return null;
}
Run your application!
Run your application in a classic way.
Expo Go support is coming soon too!
- npm
- yarn
npm run android
or
npm run ios
yarn android
or
yarn ios
Once the application is running, check your console log to see the key generation and signing process updates in real-time.
Happy signing!
Optional: Run your own Duo Server
Install Docker
- Linux
- macOS
- Windows
curl -fsSL https://get.docker.com | sh
Download and install Docker Desktop from the official website.
Alternatively, you can install using Homebrew:
brew install --cask docker
Download and install Docker Desktop from the official website.
Make sure to enable WSL 2 backend during installation for better performance.
Install OpenSSL
- Linux
- macOS
- Windows
# Ubuntu/Debian
sudo apt-get update && sudo apt-get install openssl
OpenSSL is usually pre-installed on macOS. To install or update using Homebrew:
brew install openssl
Download and install from the official OpenSSL website.
Alternatively, you can install using Chocolatey:
choco install openssl
Or using Windows Package Manager:
winget install OpenSSL.OpenSSL
Generate GitHub Personal Access Token
Get a Personal Access Token from GitHub if you don't have one.
Guide to generate GitHub Personal Access Token
- Go to GitHub Personal Access Tokens
- Click on "Generate new token", we are using the classic token for this guide.
- Enter a name for the token
- Select the "read::packages Download packages from GitHub Package Registry" scope.
- Generate the token.
Login to Docker Registry
Login to docker using Personal Access Token and your GitHub username.
echo <PAT> | docker login ghcr.io -u <username> --password-stdin
Start the Server
For local setup, let's use this example docker-compose.yml
services:
duo-server:
image: ghcr.io/silence-laboratories/dkls23-rs/duo-server:v4
command: /usr/local/bin/sigpair-node
environment:
RUST_LOG: info
LISTEN: 0.0.0.0:8080
DEV_MASTER_SIGN_KEY: /run/secrets/duo-signing-master-key
FILE_STORAGE_URL: file:///data/
ports:
- 8080:8080
volumes:
- duo-server-data:/data
secrets:
- duo-signing-master-key
volumes:
duo-server-data:
secrets:
duo-signing-master-key:
file: ${MESSAGE_SIGNING_KEY:-./party_0_sk}
The docker compose file is configured to use the party_0_sk file in the root of the project. party_0_sk is the random bytes used as seed to create the server private key.
Create the party_0_sk file with random bytes in the root of the project.
openssl rand 32 > party_0_sk
Now let's start the server by running
docker compose up
If everything was setup correctly, the server should be running with these logs
Attaching to duo-server-1
duo-server-1 | WARN: The dotenv file is not set
duo-server-1 | 2025-09-16T09:59:09.200234Z INFO sigpair_node: Creating SimpleStorage
duo-server-1 | 2025-09-16T09:59:09.201975Z INFO sigpair_node: Party VK <YOUR_CLOUD_VERIFYING_KEY_HEX_STRING>
duo-server-1 | 2025-09-16T09:59:09.202413Z INFO sigpair_node: listening on 0.0.0.0:8080
Great! The server is now setup to perform MPC actions with our mobile.
In logs you will notice a hex string of length 66 (33 bytes). This is the YOUR_CLOUD_VERIFYING_KEY_HEX_STRING which will be used by server to verify the requests from other party (In this case, our mobile app).
The YOUR_CLOUD_NODE_ENDPOINT is the endpoint of the server. In this case, it is 0.0.0.0:8080 for ios and 10.0.2.2:8080 for android. Also you can use the IP address of your machine if you are running the server on your machine.
Second argument of the CloudWebSocketClient constructor is a boolean indicates if the connection is WSS or WS. Use true for secure connection, otherwise use false for local server.