Quick Start
If you don't have have access to the docker image or don't have <silence-dart-token> for registry dart-pkg.silencelaboratories.com, 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 Flutter 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 (Flutter)
Create a new Flutter project
flutter create silent_mpc
Configure your dart pub client
-
Obtain a Pub token from Silence Laboratories team.
-
Add token to dart pub client using the command:
dart pub token add https://dart-pkg.silencelaboratories.com
Enter secret token: <silence-dart-token>
Dependency Installation
- Add
silent_shard_sdkfrom thehttps://dart-pkg.silencelaboratories.comregistry. In terminal from root of the flutter project, run
dart pub add 'silent_shard_sdk:{"version":"1.0.0", "hosted":"https://dart-pkg.silencelaboratories.com"}'
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 'package:silent_shard_sdk/silent_shard_sdk.dart' as sdk;
final cloudClient = sdk.CloudClient(
baseUri: "demo-server.silencelaboratories.com",
isSecure: true,
);
final sessionConfig = sdk.SessionConfig(
cloudClient: cloudClient,
cloudVerifyingKeyHex: "829099948d222f9731323900bc42bd3cc6f4e692f920705a9959b3e52378f188",
storageClient: sdk.SimpleStorageClient(),
);
final session = sdk.EcdsaSession(sessionConfig);
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.
final keyshare = await session.keygen();
print('Client Public Key: ${await keyshare.publicKeyHex}');
Signature Generation
Sign a message using the sign method.
final signature = await session.sign(
keyId: keyshare.keyId,
// Keccak256 Hash("Trusted Third Parties are Security Holes")
messageHash: "53c48e76b32d4fb862249a81f0fc95da2d3b16bf53771cc03fd512ef5d4e6ed9",
derivationPath: 'm',
);
print('Generated signature: $signature');
Complete Code Example
import 'package:flutter/material.dart';
import 'package:silent_shard_sdk/silent_shard_sdk.dart' as sdk;
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
Future<void> _testMpcOperations() async {
final cloudClient = sdk.CloudClient(baseUri: 'demo-server.silencelaboratories.com', isSecure: true);
final session = await sdk.createDuoEcdsaSession(
cloudClient: cloudClient,
cloudVerifyingKeyHex: '01829099948d222f9731323900bc42bd3cc6f4e692f920705a9959b3e52378f188',
storageClient: sdk.SimpleStorageClient(),
);
final keyshare = await session.keygen();
print('Client Public Key: ${keyshare.publicKeyHex}');
final signature = await session.sign(
keyId: keyshare.keyId,
// Keccak256 Hash("Trusted Third Parties are Security Holes")
messageHash: "53c48e76b32d4fb862249a81f0fc95da2d3b16bf53771cc03fd512ef5d4e6ed9",
derivationPath: 'm',
);
print('Generated signature: $signature');
}
// This widget is the root of your application.
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Silent MPC Demo')),
body: Center(
child: ElevatedButton(
onPressed: () async {
await _testMpcOperations();
},
child: Text('Test MPC operations'),
),
),
),
);
}
}
Once the app launches, check your console log to see the key generation and signing process updates in real-time.
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
Login to Docker
- Login to docker using Personal Access Token(PAT) and your username.
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.
Learn more about GitHub Personal Access Tokens here.
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.