keyRefresh

abstract suspend fun keyRefresh(keyshare: ByteArray): Result<ByteArray>

Refreshes an existing keyshare without changing its public key.

Proactive security measure to protect against potential key leakage. Recommended every 30-90 days. Public key and addresses remain unchanged.

Important: KeyRefresh internally performs reconciliation automatically. Manual reconciliation with reconcileKeyshare is only needed in case of failure (e.g., crash or network interruption).

Example: MPC Keyshare Refresh and Recovery

suspend fun refreshKeyshareIfNeeded(
session: DuoSession,
storage: StorageClient<ReconcileStoreDao>,
keyId: String
) {
val dao = storage.read(keyId)
val currentKeyshare = dao?.currentKeyshare

// MPC: Only refresh if currentKeyshare exists and is old enough
if (currentKeyshare != null && isKeyshareOld(keyId)) {
println("Refreshing MPC keyshare for $keyId...")
val refreshedKeyshare = session.keyRefresh(currentKeyshare).getOrThrow()
// Use refreshedKeyshare immediately
println("Refreshed keyshare for $keyId")
}

// MPC: In case of failure, check for staged keyshare and retry reconciliation
if (dao?.stagedKeyshare != null && dao.currentKeyshare == null) {
println("Recovery: Retrying reconciliation for $keyId...")
val reconciledKeyshare = session.reconcileKeyshare(keyId).getOrThrow()
println("Reconciliation complete for $keyId")
}
}

Return

Result containing refreshed keyshare with same public key

Parameters

keyshare

The current keyshare to refresh

See also

only for retry in case of failure