Session creation
High level flow of the SDK
- Set up the WebSocket client to connect and communicate with the cloud node.
- Optional: set up a storage provider for keyshare persistence and sync. The SDK provides a default store; see Custom Storage Client to plug in your own.
- Optional: create a message signer to authenticate messages between the mobile app and the cloud node. See Message Signer.
- Start a new MPC session.
- Perform MPC actions.
The example uses the minimal setup. A custom storage provider and message signer are optional; the SDK falls back to sensible defaults, and the linked guides show how to plug in your own.
Create a new React Native project
Skip this section if you already have a React Native project.
npx @react-native-community/cli@latest init SilentMPC
After the project is created, install @silencelaboratories/silent-shard-sdk using the instructions from the Installation Guide
Start a new session
- ECDSA
- EdDSA
import { CloudWebSocketClient } from '@silencelaboratories/silent-shard-sdk';
import { createEcdsaTrioSession } from '@silencelaboratories/silent-shard-sdk/ecdsa';
const CLOUD_NODE_URI = 'localhost:8080';
const cloudVerifyingKey = 'SERVER_PUBLIC_KEY_HEX';
const cloudClient = new CloudWebSocketClient(CLOUD_NODE_URI, false);
export const initSession = async () => {
const session = await createEcdsaTrioSession({
client: cloudClient,
cloudVerifyingKey: cloudVerifyingKey,
});
console.log('Session created successfully');
return session;
};
import { CloudWebSocketClient } from '@silencelaboratories/silent-shard-sdk';
import { createEddsaTrioSession } from '@silencelaboratories/silent-shard-sdk/eddsa';
const CLOUD_NODE_URI = 'localhost:8080';
const cloudVerifyingKey = 'SERVER_PUBLIC_KEY_HEX';
const cloudClient = new CloudWebSocketClient(CLOUD_NODE_URI, false);
export const initSession = async () => {
const session = await createEddsaTrioSession({
client: cloudClient,
cloudVerifyingKey: cloudVerifyingKey,
});
console.log('Session created successfully');
return session;
};
-
CloudWebSocketClient: is a class that handles the WebSocket communication with the cloud node.
-
IStorageProvider: is a class manager for storing and retrieving MPC keyshares through a standardized interface.
-
MessageSigner: is a class that handles the signing of messages for secure communication between mobile and cloud node.
-
EcdsaSession: is the class that facilitates all actions for ECDSA wallets.
-
SessionConfig: is a configuration object that contains the necessary information for the session.
-
CLOUD_NODE_URIis the URI of the cloud node. -
cloudVerifyingKeyis the Hex encoded cloud verifying key (Ed25519 public key).- This public key is used to verify the server's signature on each message
- See example here
The session is now ready to run MPC operations such as keygen and sign.
High level flow of the SDK
- Set up the WebSocket client to connect and communicate with the cloud node.
- Optional: set up a storage provider for keyshare persistence and sync. The SDK provides a default store; see Custom Storage Client to plug in your own.
- Optional: create a message signer to authenticate messages between the mobile app and the cloud node. See Message Signer.
- Start a new MPC session.
- Perform MPC actions.
The example uses the minimal setup. A custom storage provider and message signer are optional; the SDK falls back to sensible defaults, and the linked guides show how to plug in your own.
Start a new session
- ECDSA
- EdDSA
- Taproot
import 'dart:io';
import 'package:silent_shard_sdk/silent_shard_sdk.dart' as sdk;
Future<sdk.EcdsaSession> setup(
[String cloudVerifyingKeyHex = 'SERVER_PUBLIC_KEY_HEX']) async {
/// The port number is the port number of the cloud node.
const port = 8080;
/// The nodeUri is the URI of the cloud node. It is the IP address of the cloud node.
/// Localhost url used for Android and iOS is shown below.
/// 10.0.2.2 is the IP address of the Android emulator.
/// 0.0.0.0 is the IP address of the iOS simulator.
final nodeUri = Platform.isAndroid ? '10.0.2.2:$port' : '0.0.0.0:$port';
final cloudClient = sdk.CloudClient(
baseUri: nodeUri,
isSecure: false,
);
final session = sdk.createTrioEcdsaSession(
cloudClient: cloudClient,
cloudVerifyingKeyHex: cloudVerifyingKeyHex,
storageClient: sdk.SimpleStorageClient(),);
return session;
}
import 'dart:io';
import 'package:silent_shard_sdk/silent_shard_sdk.dart' as sdk;
Future<sdk.EddsaSession> setup(
[String cloudVerifyingKeyHex = 'SERVER_PUBLIC_KEY_HEX']) async {
/// The port number is the port number of the cloud node.
const port = 8080;
/// The nodeUri is the URI of the cloud node. It is the IP address of the cloud node.
/// Localhost url used for Android and iOS is shown below.
/// 10.0.2.2 is the IP address of the Android emulator.
/// 0.0.0.0 is the IP address of the iOS simulator.
final nodeUri = Platform.isAndroid ? '10.0.2.2:$port' : '0.0.0.0:$port';
final cloudClient = sdk.CloudClient(
baseUri: nodeUri,
isSecure: false,
);
final session = await sdk.createTrioEddsaSession(
cloudClient: cloudClient,
cloudVerifyingKeyHex: cloudVerifyingKeyHex,
storageClient: sdk.SimpleStorageClient(),
);
return session;
}
import 'dart:io';
import 'package:silent_shard_sdk/silent_shard_sdk.dart' as sdk;
Future<sdk.TaprootSession> setup([String cloudVerifyingKeyHex = 'SERVER_PUBLIC_KEY_HEX']) async {
/// The port number is the port number of the cloud node.
const port = 8080;
/// The nodeUri is the URI of the cloud node. It is the IP address of the cloud node.
/// Localhost url used for Android and iOS is shown below.
/// 10.0.2.2 is the IP address of the Android emulator.
/// 0.0.0.0 is the IP address of the iOS simulator.
final nodeUri = Platform.isAndroid ? '10.0.2.2:$port' : '0.0.0.0:$port';
final cloudClient = sdk.CloudClient(
baseUri: nodeUri,
isSecure: false,
);
final session = await sdk.createTrioTaprootSession(
cloudClient: cloudClient,
cloudVerifyingKeyHex: cloudVerifyingKeyHex,
storageClient: sdk.SimpleStorageClient(),
);
return session;
}
-
Initialize an ECDSA session with the EcdsaSession class.
-
CloudClient: is a class that handles the WebSocket communication with the cloud node.
-
EcdsaSession is the class that facilitates all actions for ECDSA wallets.
-
CLOUD_NODE_URIis the URI of the cloud node. -
cloudVerifyingKeyis the Hex encoded cloud verifying key (Ed25519 public key).- This public key is used to verify the server's signature on each message
-
protocolis the protocol to use for the session.Protocol.triois the used for Trio.
The session is now ready to run MPC operations such as keygen and sign.
High level flow of TrioSession
- Configure/Implement transport layer NetworkClient
- Configure/Implement storage layer StorageClient
- Configure/Implement MessageSigner
- Create TrioSession
- Perform MPC actions
TrioSession is the main object which will be used to perform all of the MPC operations supported. To create TrioSession please follow the steps below.
Step 1 : Add library to your Project
-
Create new android studio project if you haven't.
-
Add SilentShard-Trio SDK using the instructions from the Installation Guide
Step 2 : Create new session
- We can Create TrioSession by calling SilentShard.ECDSA.trioInitiator() or SilentShard.EdDSA.trioInitiator() (whichever applies) by providing the following parameters
- Provide websocket client by using any of the below options :
- Providing WebsocketConfig object to let SDK use default WebsocketClient i.e. TrioNetworkClient.
- Providing custom NetworkClient overriding(extending) TrioNetworkClient to override existing connect, read or write, etc. methods to add your own logic/configuration or additional process.
- Provide cloud/server public key.
- Provide storage client. (You need to implement the interface StorageClient).
- Provide Message Signer (You need to implement the interface MessageSigner).
Example
- ECDSA
- EdDSA
import com.silencelaboratories.silentshard.network.websocket.WebsocketConfig
import com.silencelaboratories.silentshard.storage.KeyType
import com.silencelaboratories.silentshard.storage.StorageClient
import com.silencelaboratories.silentshard.storage.StorageDao
import com.silencelaboratories.silentshard.storage.silentshard.ReconcileStoreDao
import com.silencelaboratories.silentshard.trio.SilentShard
import com.silencelaboratories.silentshard.trio.TrioSession
import com.silencelaboratories.silentshard.utils.MessageSigner
object Constants {
// Replace with your own
const val CLOUD_NODE_URI = "trio-server.demo.silencelaboratories.com"
// Replace with your own
const val PORT = 443
}
// Other party verifying-key/public-key. Replace with your own Verifying Key.
val cloudPublicKey = "9c4c79e942bbc3ff1d6ace7256404d701498056978cc4638c35832acdf821b1e"
// Create websocketConfig to let SilentShard use the default WebsocketClient.
val websocketConfig = WebsocketConfig(url = Constants.CLOUD_NODE_URI, port = Constants.PORT, isSecure = true)
// Create a storageClient to persist keyshares. The SDK owns keyshare storage and
// addresses every share by its keyId — your code never holds raw keyshare bytes.
val storageClient = object : StorageClient {
// The algorithm family this client stores keyshares for. Provide a separate
// client (with a matching keyType) per algorithm if you run more than one.
override val keyType = KeyType.ECDSA
/**
* An in-memory database. In the real world this should be a SQL-based DB,
* secure storage, or custom hardware — it is up to the implementing app.
*/
private val entries = mutableMapOf<String, ReconcileStoreDao>()
override suspend fun write(dao: StorageDao) {
require(dao is ReconcileStoreDao) { "Expected ReconcileStoreDao" }
// Persist the whole snapshot, including any null fields.
entries[dao.keyId] = dao
}
override suspend fun read(key: String): StorageDao? = entries[key]
}
// Create a messageSigner backed by your secure key storage (TEE / Keystore).
val messageSigner = object : MessageSigner {
override val verifyingKey: ByteArray
get() = TODO("Public key of secure key (Secure Environment - TEE)")
override val keyType: MessageSigner.KeyType
get() = TODO("Type of secure key (Secure Environment - TEE)")
override suspend fun sign(data: ByteArray): ByteArray {
TODO("Sign data using secure key (Secure Environment - TEE) and return the signature")
}
}
// For quick-start you can use the test message signer. Do not use it in production.
val testMessageSigner = SilentShard.ECDSA.TestMessageSigner
// Create a TrioSession for the ECDSA algorithm
val trioSession: TrioSession = SilentShard.ECDSA.trioInitiator(
// pass your messageSigner instance in production; do not use testMessageSigner
testMessageSigner, cloudPublicKey, websocketConfig, storageClient
)
// Or create a TrioSession with your own network client by extending TrioNetworkClient:
// val trioSession: TrioSession = SilentShard.ECDSA.trioInitiator(
// testMessageSigner, cloudPublicKey, CustomTrioNetworkClient(), storageClient
// )
import com.silencelaboratories.silentshard.network.websocket.WebsocketConfig
import com.silencelaboratories.silentshard.storage.KeyType
import com.silencelaboratories.silentshard.storage.StorageClient
import com.silencelaboratories.silentshard.storage.StorageDao
import com.silencelaboratories.silentshard.storage.silentshard.ReconcileStoreDao
import com.silencelaboratories.silentshard.trio.SilentShard
import com.silencelaboratories.silentshard.trio.TrioSession
import com.silencelaboratories.silentshard.utils.MessageSigner
object Constants {
// Replace with your own
const val CLOUD_NODE_URI = "trio-server.demo.silencelaboratories.com"
// Replace with your own
const val PORT = 443
}
// Other party verifying-key/public-key. Replace with your own Verifying Key.
val cloudPublicKey = "9c4c79e942bbc3ff1d6ace7256404d701498056978cc4638c35832acdf821b1e"
// Create websocketConfig to let SilentShard use the default WebsocketClient.
val websocketConfig = WebsocketConfig(url = Constants.CLOUD_NODE_URI, port = Constants.PORT, isSecure = true)
// Create a storageClient to persist keyshares. The SDK owns keyshare storage and
// addresses every share by its keyId — your code never holds raw keyshare bytes.
val storageClient = object : StorageClient {
// The algorithm family this client stores keyshares for. Provide a separate
// client (with a matching keyType) per algorithm if you run more than one.
override val keyType = KeyType.EdDSA
/**
* An in-memory database. In the real world this should be a SQL-based DB,
* secure storage, or custom hardware — it is up to the implementing app.
*/
private val entries = mutableMapOf<String, ReconcileStoreDao>()
override suspend fun write(dao: StorageDao) {
require(dao is ReconcileStoreDao) { "Expected ReconcileStoreDao" }
// Persist the whole snapshot, including any null fields.
entries[dao.keyId] = dao
}
override suspend fun read(key: String): StorageDao? = entries[key]
}
// Create a messageSigner backed by your secure key storage (TEE / Keystore).
val messageSigner = object : MessageSigner {
override val verifyingKey: ByteArray
get() = TODO("Public key of secure key (Secure Environment - TEE)")
override val keyType: MessageSigner.KeyType
get() = TODO("Type of secure key (Secure Environment - TEE)")
override suspend fun sign(data: ByteArray): ByteArray {
TODO("Sign data using secure key (Secure Environment - TEE) and return the signature")
}
}
// For quick-start you can use the test message signer. Do not use it in production.
val testMessageSigner = SilentShard.EdDSA.TestMessageSigner
// Create a TrioSession for the EdDSA algorithm
val trioSession: TrioSession = SilentShard.EdDSA.trioInitiator(
// pass your messageSigner instance in production; do not use testMessageSigner
testMessageSigner, cloudPublicKey, websocketConfig, storageClient
)
// Or create a TrioSession with your own network client by extending TrioNetworkClient:
// val trioSession: TrioSession = SilentShard.EdDSA.trioInitiator(
// testMessageSigner, cloudPublicKey, CustomTrioNetworkClient(), storageClient
// )
CLOUD_NODE_URIis the URI of the cloud node.cloudPublicKeyis the cloud verifying key (Ed25519 public key).- This public key is used to verify the server's signature on each message
- See example here
- SilentShard Provides API for creating MPC TrioSession (Three-Party) using ECDSA algorithm.
- ECDSA Provides factory methods for creating MPC session using ECDSA algorithm.
- TrioSession Represents a three-party computation session that lets you perform MPC operations using SilentShard protocol.
The session is now ready to run MPC operations such as keygen and sign.
High level flow of TrioSession
- Configure/Implement transport layer TrioNetworkClient
- Configure/Implement storage layer StorageClient
- Configure/Implement MessageSigner
- Create TrioSession
- Perform MPC actions
TrioSession is the main object which will be used to perform all of the MPC operations supported. To create TrioSession please follow the steps below.
Step 1 : Add library to your Project
-
Create new xcode project if you haven't.
-
Add SilentShard-Trio SDK using the instructions from the Installation Guide
Step 2 : Create new session
- Import module - trio
- We can Create TrioSession by calling SilentShard.ECDSA.trioInitiator() or SilentShard.EdDSA.trioInitiator() (whichever applies) by providing the following parameters
- Provide websocket client by using any of the below options :
- Providing WebsocketConfig object to let SDK use default WebsocketClient i.e. TrioNetworkClient.
- Providing custom TrioNetworkClient overriding(extending) TrioNetworkClient to override existing connect, read or write, etc. methods to add your own logic/configuration or additional process.
- Provide cloud/server public key.
- Provide storage client. (You need to implement the protocol StorageClient).
- Provide message signer. (You need to implement the protocol MessageSigner).
Example
- ECDSA
- EdDSA
import SwiftUI
import trio
struct ContentView: View {
var body: some View {
VStack {
// The demo server, over TLS.
let CLOUD_NODE_URI = "trio-server.demo.silencelaboratories.com"
// Other party verifying-key/public-key. Replace with your own Verifying Key.
let cloudVerifyingKey = "9c4c79e942bbc3ff1d6ace7256404d701498056978cc4638c35832acdf821b1e"
// Create websocketConfig to let SilentShard use the default WebsocketClient.
let websocketConfig = WebsocketConfig(url: CLOUD_NODE_URI, port: 443, isSecure: true)
// Create a storageClient to persist keyshares. The SDK owns keyshare
// storage and addresses every share by its keyId.
let storageClient = CustomStorageClient()
// Create a messageSigner to authenticate protocol messages. For quick-start
// we use the test signer; do not use TestECDSAMessageSigner in production.
// Provide your own MessageSigner backed by the Secure Enclave instead:
// let messageSigner = CustomMessageSigner()
// Create a TrioSession
let trioSession = SilentShard.ECDSA.trioInitiator(
// Do not use TestECDSAMessageSigner in production
messageSigner: TestECDSAMessageSigner(),
cloudVerifyingKey: cloudVerifyingKey,
websocketConfig: websocketConfig,
storageClient: storageClient
)
// or using a custom network client
// let trioSession = SilentShard.ECDSA.trioInitiator(
// messageSigner: TestECDSAMessageSigner(),
// cloudVerifyingKey: cloudVerifyingKey,
// networkClient: CustomNetworkClient(),
// storageClient: storageClient
// )
}
.padding()
}
}
#Preview {
ContentView()
}
import SwiftUI
import trio
struct ContentView: View {
var body: some View {
VStack {
// The demo server, over TLS.
let CLOUD_NODE_URI = "trio-server.demo.silencelaboratories.com"
// Other party verifying-key/public-key. Replace with your own Verifying Key.
let cloudVerifyingKey = "9c4c79e942bbc3ff1d6ace7256404d701498056978cc4638c35832acdf821b1e"
// Create websocketConfig to let SilentShard use the default WebsocketClient.
let websocketConfig = WebsocketConfig(url: CLOUD_NODE_URI, port: 443, isSecure: true)
// Create a storageClient to persist keyshares. The SDK owns keyshare
// storage and addresses every share by its keyId.
let storageClient = CustomStorageClient()
// Create a messageSigner to authenticate protocol messages. For quick-start
// we use the test signer; do not use TestEdDSAMessageSigner in production.
// Provide your own MessageSigner backed by the Secure Enclave instead:
// let messageSigner = CustomMessageSigner()
// Create a TrioSession
let trioSession = SilentShard.EdDSA.trioInitiator(
// Do not use TestEdDSAMessageSigner in production
messageSigner: TestEdDSAMessageSigner(),
cloudVerifyingKey: cloudVerifyingKey,
websocketConfig: websocketConfig,
storageClient: storageClient
)
// or using a custom network client
// let trioSession = SilentShard.EdDSA.trioInitiator(
// messageSigner: TestEdDSAMessageSigner(),
// cloudVerifyingKey: cloudVerifyingKey,
// networkClient: CustomNetworkClient(),
// storageClient: storageClient
// )
}
.padding()
}
}
#Preview {
ContentView()
}
CLOUD_NODE_URIis the URI of the cloud node.cloudPublicKeyis the cloud verifying key (Ed25519 public key).- This public key is used to verify the server's signature on each message
- See example here
- SilentShard Provides API for creating MPC TrioSession (Three-Party) using ECDSA algorithm.
- ECDSA Provides factory methods for creating MPC session using ECDSA algorithm.
- TrioSession Represents a three-party computation session that lets you perform MPC operations using SilentShard protocol.
The session is now ready to run MPC operations such as keygen and sign.