keygen
Generates a new distributed keyshare through two-party MPC.
Creates a new key where neither party knows the complete private key.
Important: Keygen internally performs reconciliation (the after-part) automatically, transitioning the keyshare from "staged" to "current/active" state. However, if the reconciliation step fails due to network interruption or crash, you can retry it manually using reconcileKeyshare without redoing the entire expensive MPC operation.
When to use standalone reconciliation: Only needed if keygen completes but the after-part fails. The keyshare will be in "staged" state and you can complete it later.
Example: Normal Successful Flow (No Manual Reconciliation Needed)
// Keygen automatically reconciles internally - keyshare is ready to use
val keyshare = session.keygen().getOrThrow()
// Get key ID
val keyId = SilentShard.ECDSA.getKeyshareKeyId(keyshare)
.getOrThrow()
.toHexString()
// Derive address and start using immediately
val publicKey = SilentShard.ECDSA.getKeysharePublicKey(keyshare).getOrThrow()
val address = deriveAddressFromPublicKey(publicKey)
// Store and use
secureStorage.save("keyshare_$keyId", keyshare)
println("Wallet created with address: $address")Content copied to clipboard
Example: Recovery Scenario (Manual Reconciliation Needed)
// Keygen completes successfully (internally reconciled)
val keyshare = session.keygen().getOrThrow()
// Normal flow - keyshare is ready to use
val publicKey = SilentShard.ECDSA.getKeysharePublicKey(keyshare).getOrThrow()
// If app crashes before completion, on restart:
// Check storage for any staged keyshares
suspend fun checkForIncompleteOperations(
storageClient: StorageClient<ReconcileStoreDao>
) {
// User provides keyId of their last operation
val keyId = getLastAttemptedKeyId() // from your app state
val dao = storageClient.read(keyId)
if (dao?.stagedKeyshare != null && dao.currentKeyshare == null) {
// Found incomplete reconciliation - retry
println("Retrying reconciliation for $keyId...")
val reconciledKeyshare = session.reconcileKeyshare(keyId).getOrThrow()
println("Reconciliation complete!")
}
}Content copied to clipboard
Example: HD Wallet with Multiple Accounts
// Generate master keyshare (internally reconciled)
val keyshare = session.keygen().getOrThrow()
// Derive multiple accounts using different paths
val accounts = (0..4).map { index ->
val childKey = SilentShard.ECDSA.deriveChildPublicKey(
keyshare = keyshare,
derivationPath = "m/44'/X'/0'/0/$index" // X = your coin type
).getOrThrow()
Account(
index = index,
address = deriveAddressFromPublicKey(childKey),
path = "m/44'/X'/0'/0/$index"
)
}
accounts.forEach { println("Account ${it.index}: ${it.address}") }Content copied to clipboard