Keygen
Generate a new MPC wallet. The app and the Duo Server run distributed key generation, and each ends up with its own keyshare. The resulting public key is the wallet address. No seed phrase is ever created.
Please refer to the Session creation section to learn how to create a new session.
Full example
- ECDSA
- EdDSA
- MLDSA
import { type EcdsaSession } from '@silencelaboratories/silent-shard-sdk/ecdsa';
export const keygen = async (session: EcdsaSession) => {
const keyshare = await session.keygen();
console.log('Created new keyshare with public key: ', keyshare.publicKeyHex);
};
import { type EddsaSession } from '@silencelaboratories/silent-shard-sdk/eddsa';
export const keygen = async (session: EddsaSession) => {
const keyshare = await session.keygen();
console.log('Created new keyshare with public key: ', keyshare.publicKeyHex);
};
import { MldsaLevels } from '@silencelaboratories/silent-shard-sdk';
import { type MldsaSession } from '@silencelaboratories/silent-shard-sdk/mldsa';
export const keygen = async (session: MldsaSession) => {
// ML-DSA security level (MlDsa44, MlDsa65, or MlDsa87)
const keyshare = await session.keygen(MldsaLevels.MlDsa44);
console.log('Created new keyshare with public key: ', keyshare.publicKeyHex);
};
- When
session.keygen()is called, the app and the server exchange messages to generate a new MPC wallet. - Two new "shares" are generated: one for the client and one for the server. Both shares together form the MPC wallet.
keyshareis of type Keyshare and represents the client's "share" of the MPC wallet.- The
keyshare.publicKeyHexproperty is the public key of the MPC wallet in hex format.
Please refer to the Session creation section to learn how to create a new session.
Full example
- ECDSA
- EdDSA
- Taproot
import 'package:silent_shard_sdk/silent_shard_sdk.dart' as sdk;
Future<sdk.DklsKeyshare> keygen(sdk.EcdsaSession session) async {
final sdk.DklsKeyshare keyshare = await session.keygen();
print('Keyshare created, public key: ${keyshare.publicKeyHex}');
return keyshare;
}
import 'package:silent_shard_sdk/silent_shard_sdk.dart' as sdk;
Future<sdk.SchnorrKeyshare> keygen(sdk.EddsaSession session) async {
final sdk.SchnorrKeyshare keyshare = await session.keygen();
print('Keyshare created, public key: ${keyshare.publicKeyHex}');
return keyshare;
}
import 'package:silent_shard_sdk/silent_shard_sdk.dart' as sdk;
Future<sdk.TaprootKeyshare> keygen(sdk.TaprootSession session) async {
final sdk.TaprootKeyshare keyshare = await session.keygen();
print('Keyshare created, public key: ${keyshare.publicKeyHex}');
return keyshare;
}
- When
session.keygen()is called, the app and the server exchange messages to generate a new MPC wallet. - Two new DklsKeyshare are generated: one for the client and one for the server. Both shares together form the MPC wallet.
- The
keyshare.publicKeyHexproperty is the public key of the MPC wallet in hex format.
This distributed key generation forms the basis for all subsequent MPC operations, providing a secure foundation for the wallet with enhanced privacy and security guarantees.
Step 1 : Create Session
- Create DuoSession if you haven't already.
Step 2 : Perform Keygen
- Call duoSession.keygen() which returns Result of Success with the newly generated
keyId(aString) or Failure with exception.
Example
// keygen runs distributed key generation and returns the new keyId.
// The keyshare itself is persisted to your StorageClient — keep the keyId to
// address it in later operations (sign, refresh, export, delete, …).
suspend fun performKeygen(duoSession: DuoSession): String {
return withContext(Dispatchers.IO) {
duoSession.keygen().getOrThrow()
}
}
- duoSession.keygen() performs message exchange between mobile and server to generate a new MPC wallet.
- Two new "shares" are generated: one for the client(on mobile) and one for the server(on server). Both shares together form the MPC wallet.
- Result of duoSession.keygen() could be a
Successwith thekeyId(String) that addresses the generated keyshare, orFailurewithException. The keyshare itself is persisted to your StorageClient — use thekeyIdfor later operations (sign, refresh, export, delete). - SilentShard.ECDSA.getKeysharePublicKey() or SilentShard.EdDSA.getKeysharePublicKey() could be used to get the compressed public key of the MPC wallet (read the keyshare bytes from your StorageClient by
keyIdfirst). Refer to SDK-Reference for additional Info and Utils.
This distributed key generation forms the basis for all subsequent MPC operations, providing a secure foundation for the wallet with enhanced privacy and security guarantees.
Step 1 : Create Session
- Create DuoSession if you haven't already.
Step 2 : Perform Keygen
- Call duoSession.keygen() which returns a
ResultofSuccesswith the generatedkeyId(aString) orFailurewith an error. The keyshare itself is persisted to your storage client, addressed by thiskeyId.
Example
// keygen returns the new keyId (a String). The keyshare is persisted to your
// StorageClient — keep the keyId to address it in later operations.
func performKeygen(duoSession: DuoSession) async -> String? {
let result: Result<String, any Error> = await duoSession.keygen()
// returns nil if the operation fails, or handle it however your flow needs
switch result {
case .success(let keyId):
// do something with the keyId
Swift.print(keyId)
return keyId
case .failure(let error):
// show the error to the user or abort the process
Swift.print(error)
return nil
}
}
- duoSession.keygen() performs message exchange between mobile and server to generate a new MPC wallet.
- Two new "shares" are generated: one for the client(on mobile) and one for the server(on server). Both shares together form the MPC wallet.
- Result of duoSession.keygen() could be a
Successwith akeyId(String) addressing the newly created keyshare in your storage client, orFailurewitherror - SilentShard.ECDSA.getKeysharePublicKey() or SilentShard.EdDSA.getKeysharePublicKey() could be used to get the compressed public key of the MPC wallet (read the keyshare bytes from your storage client by
keyIdfirst). Refer to SDK-Reference for additional Info and Utils.
Handling the operation
This is an MPC operation, so it takes a few seconds (the app and the Duo Server exchange several messages). Show a non-blocking loading state while it runs, confirm on success, and offer a retry on failure. When something goes wrong, the SDK surfaces the error for you to handle:
| Error | What it means | How to handle |
|---|---|---|
| Keyshares not in sync, run reconcile | A previous operation didn't finish cleanly (for example the app was force-closed mid-operation) | Run reconcile, then retry |
| Server error | The server ended the session unexpectedly | Show the error and offer a retry |
| Connection / transport error | The server was unreachable or the connection dropped | Show the error and offer a retry |
All of these operations are safe to retry from the start.