Key recovery
Recovery rebuilds a lost device-side keyshare from the two remaining cloud parties. No export blob is needed — the input is just the public key of the share to recover. This is unique to trio's 2-of-3 threshold: as long as any two of the three parties still hold their shares, the third party can be rebuilt.
For the SDK contract see Key Recovery (Kotlin) and Key Recovery (Swift).
How the example does it
- Android
- iOS / macOS
suspend fun recovery(publicKey: ByteArray, keyType: KeyType): KeyResult {
val keyshare = sessionFor(keyType).recovery(publicKey).getOrThrow()
val keyId = extractKeyId(keyType, keyshare)
val recoveredPublicKey = extractPublicKey(keyType, keyshare)
return KeyResult(keyId, recoveredPublicKey)
}
The UI entry point is RecoveryScreen.kt — the user selects the key type (ECDSA or EdDSA), pastes the hex-encoded public key, and taps "Recover Keyshare."
func recovery(publicKey: Data, keyType: KeyType) async throws -> KeygenResult {
let session = sessionForKeyType(keyType)
let keyshare = try await session.recovery(keysharePublicKey: publicKey).get()
let keyId = try await extractKeyId(keyType, keyshare: keyshare)
let recoveredPublicKey = try await extractPublicKeyFromKeyshare(keyType, keyshare: keyshare)
return KeygenResult(keyId: keyId, publicKey: recoveredPublicKey)
}
The UI entry point is RecoveryView.swift — accessible from both the Welcome screen (fresh install) and the Dashboard (existing wallets).
How recovery differs from import
| Import | Recovery | |
|---|---|---|
| Input | Encrypted export blob (from a previous export) | Public key of the lost share |
| Requires | The export file | Two cloud parties still holding their shares |
| Result | Fresh device share, same keyId/address | Same |
| Use case | Moving a wallet to a new device with a backup file | Rebuilding after losing the device with no backup |
Recovery is strictly more convenient (no file needed), but it only works in trio's 2-of-3 model — duo has no recovery because there's only one cloud party and one device party.