Key Refresh
Rotate all three keyshares without changing the wallet address. After a refresh, the previous shares no longer match the new ones, so they are invalidated and can no longer be used for signing.
Please refer to the Session creation section to learn how to create a new session.
Using the session object and an existing keyshare, we can easily refresh it to generate a new keyshare.
Full example:
- ECDSA
- EdDSA
import { type EcdsaSession } from '@silencelaboratories/silent-shard-sdk/ecdsa';
export const refresh = async (session: EcdsaSession) => {
// Creating a new keyshare for demo purpose. In real application, you can use an existing keyshare.
const keyshare = await session.keygen();
console.log('Keyshare: ', keyshare.keyIdHex);
const refreshedKeyshare = await session.refresh(keyshare);
console.log('Refreshed keyshare: ', refreshedKeyshare.keyIdHex);
};
import { type EddsaSession } from '@silencelaboratories/silent-shard-sdk/eddsa';
export const refresh = async (session: EddsaSession) => {
// Creating a new keyshare for demo purpose. In real application, you can use an existing keyshare.
const keyshare = await session.keygen();
console.log('Keyshare: ', keyshare.keyIdHex);
const refreshedKeyshare = await session.refresh(keyshare);
console.log('Refreshed keyshare: ', refreshedKeyshare.keyIdHex);
};
- When
session.refresh(keyshare)is called, the app and the server exchange messages to "refresh" the MPC wallet. Refer to Key Refresh for more details. - This process enhances the long-term security of the MPC wallet by proactively updating the client's and server's secret shares.
- The wallet's public address or key remains unchanged during this process.
- The
refreshedKeyshareobject is of type Keyshare and represents the client's new share of the MPC wallet.
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<void> refresh(sdk.EcdsaSession session) async {
// Creating a new keyshare for demo purpose. In real application, you can use an existing keyshare.
final sdk.DklsKeyshare keyshare = await session.keygen();
print('Keyshare created, public key: ${keyshare.publicKeyHex}');
final sdk.DklsKeyshare refreshedKeyshare =
await session.refresh(keyId: keyshare.keyId);
print('Refreshed keyshare, public key: ${refreshedKeyshare.publicKeyHex}');
}
import 'package:silent_shard_sdk/silent_shard_sdk.dart' as sdk;
Future<void> refresh(sdk.EddsaSession session) async {
// Creating a new keyshare for demo purpose. In real application, you can use an existing keyshare.
final sdk.SchnorrKeyshare keyshare = await session.keygen();
print('Keyshare created, public key: ${keyshare.publicKeyHex}');
final sdk.SchnorrKeyshare refreshedKeyshare =
await session.refresh(keyId: await keyshare.keyId);
print('Refreshed keyshare, public key: ${refreshedKeyshare.publicKeyHex}');
}
import 'package:silent_shard_sdk/silent_shard_sdk.dart' as sdk;
Future<void> refresh(sdk.TaprootSession session) async {
// Creating a new keyshare for demo purpose. In real application, you can use an existing keyshare.
final sdk.TaprootKeyshare keyshare = await session.keygen();
print('Keyshare created, public key: ${keyshare.publicKeyHex}');
final sdk.TaprootKeyshare refreshedKeyshare =
await session.refresh(keyId: keyshare.keyId);
print('Refreshed keyshare, public key: ${refreshedKeyshare.publicKeyHex}');
}
- When
session.refresh(keyshare)is called, the app and the server exchange messages to "refresh" the MPC wallet. Refer to Key Refresh for more details. - This process enhances the long-term security of the MPC wallet by proactively updating the client's and server's secret shares.
- The wallet's public address or key remains unchanged during this process.
- The
refreshedKeyshareobject is of type DklsKeyshare and represents the client's new share of the MPC wallet.
Update the client's and server's secret shares without altering the wallet's public address or key.
Step 1 : Create Session
- Create TrioSession if you haven't already.
Step 2 : Perform Key-Refresh
- Call trioSession.refresh() which returns Result of Success with Refreshed-Keyshare
ByteArrayor Failure with exception.
Example
// refresh rotates the keyshares of the key addressed by keyId without changing
// its public key. The refreshed share is persisted to your StorageClient under
// the same keyId; the refreshed keyshare bytes are also returned.
suspend fun performKeyRefresh(keyId: String, trioSession: TrioSession): ByteArray {
return withContext(Dispatchers.IO) {
trioSession.refresh(
keyId = keyId
).getOrThrow()
}
}
keyIdidentifies the key to refresh; it is returned by keygen and stays the same after the refresh.- trioSession.refresh() performs message exchange between mobile and server to "refresh" the MPC wallet. Refer to Key Refresh for more details.
- Result of trioSession.refresh() could be a
SuccesswithByteArray(client's new share of the MPC wallet) orFailurewithException - This process enhances the long-term security of the MPC wallet by proactively updating the client's and server's secret shares.
- The wallet's public address or key remains unchanged during this process.
Update the client's and server's secret shares without altering the wallet's public address or key.
Step 1 : Create Session
- Create TrioSession if you haven't already.
Step 2 : Perform Key-Refresh
- Call trioSession.refresh() with the
keyIdwhich returnsResultofSuccesswith Refreshed-Keyshare bytes asDataorFailurewitherror.
Example
// refresh rotates the keyshares of the key addressed by keyId without changing
// its public key. The refreshed share is persisted under the same keyId.
func performKeyRefresh(keyId: String, trioSession: TrioSession) async -> Data? {
let result = await trioSession.refresh(keyId: keyId)
// returns nil if the operation fails, or handle it however your flow needs
switch result {
case .success(let keyshareBytes):
// do something with the refreshed keyshare bytes
Swift.print(keyshareBytes)
return keyshareBytes
case .failure(let error):
// show the error to the user or abort the process
Swift.print(error)
return nil
}
}
keyIdidentifies the client's key to refresh; the SDK loads the keyshare from your StorageClient using it.- trioSession.refresh() performs message exchange between mobile and server to "refresh" the MPC wallet. Refer to Key Refresh for more details.
- Result of trioSession.refresh() could be a
Successwith bytes asData(client's new share of the MPC wallet) orFailurewitherror - This process enhances the long-term security of the MPC wallet by proactively updating the client's and server's secret shares.
- The wallet's public address or key remains unchanged during this process.
A refresh rewrites all three shares, so an interrupted refresh could leave a party without a usable share. The reconcile protocol is the fallback that prevents this.