Skip to main content

Quick Start

info

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.

MPC Communication between Duo Server and Mobile App

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

info

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:

Terminal
dart pub token add https://dart-pkg.silencelaboratories.com
Enter secret token: <silence-dart-token>

Dependency Installation

  • Add silent_shard_sdk from the https://dart-pkg.silencelaboratories.com registry. In terminal from root of the flutter project, run
Terminal
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

main.dart
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

curl -fsSL https://get.docker.com | sh

Install OpenSSL

# Ubuntu/Debian
sudo apt-get update && sudo apt-get install openssl

Login to Docker

  • Login to docker using Personal Access Token(PAT) and your username.
Guide to generate GitHub Personal Access Token
  1. Go to GitHub Personal Access Tokens
  2. Click on "Generate new token", we are using the classic token for this guide.
  3. Enter a name for the token
  4. Select the "read::packages Download packages from GitHub Package Registry" scope.
  5. Generate the token.
info

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

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

shell
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.