# Key Lifecycle

Once we have already generated our key shares, we can refresh and also export them.\
We show how to do this below.

## Key Refresh

Key Refresh (sometimes referred to as "Key Rotation") is a protocol that allows the devices to compute entirely **new** secret shares of the **same public key**.\
Refreshing the key material frequently is considered a best practice for enhanced security, as it adds an element of time to the security setting.\
Since even if one secret share was compromised, then after Key Refresh the compromised secret share will no longer be useful.
Below is an example of how to use Key Refresh:

<Tabs>
  <Tab title="ECDSA">
    ```kotlin
    import com.sodot.kotlin_sdk.Ecdsa
    import kotlinx.coroutines.runBlocking

    // Assume we have N parties with T threshold
    val N = 3
    val T = 2
    val API_KEY = "MY_API_KEY"
    val HOST_URL = "us1.sodot.dev" // Your Relay URL

    // A secret share was previously generated during keygen
    val secretShare = "previously_stored_secret_share"

    runBlocking {
        // Initialize the ECDSA scheme
        val ecdsa = Ecdsa(HOST_URL)

        // Your server creates a room for N parties
        val refreshRoomUuid = ecdsa.createRoom(N, API_KEY)
        
        // All parties now join the refresh room using their current secret share
        val (pubkey, refreshedSecretShare) = ecdsa.refresh(
            refreshRoomUuid,
            secretShare
        )
        
        // Note: The public key remains the same
        // Store refreshedSecretShare securely for future use
        // It can now be used for signing under the same threshold, as well as be refreshed again
    }
    ```
  </Tab>

  <Tab title="ED25519">
    ```kotlin
    import com.sodot.kotlin_sdk.Ed25519
    import kotlinx.coroutines.runBlocking

    // Assume we have N parties with T threshold
    val N = 3
    val T = 2
    val API_KEY = "MY_API_KEY"
    val HOST_URL = "us1.sodot.dev" // Your Relay URL

    // A secret share was previously generated during keygen
    val secretShare = "previously_stored_secret_share"

    runBlocking {
        // Initialize the Ed25519 scheme
        val ed25519 = Ed25519(HOST_URL)

        // Your server creates a room for N parties
        val refreshRoomUuid = ed25519.createRoom(N, API_KEY)
        
        // All parties now join the refresh room using their current secret share
        val (pubkey, refreshedSecretShare) = ed25519.refresh(
            refreshRoomUuid,
            secretShare
        )
        
        // Note: The public key remains the same
        // Store refreshedSecretShare securely for future use
        // It can now be used for signing under the same threshold, as well as be refreshed again
    }
    ```
  </Tab>

  <Tab title="SR25519">
    ```kotlin
    import com.sodot.kotlin_sdk.Sr25519
    import kotlinx.coroutines.runBlocking

    // Assume we have N parties with T threshold
    val N = 3
    val T = 2
    val API_KEY = "MY_API_KEY"
    val HOST_URL = "us1.sodot.dev" // Your Relay URL

    // A secret share was previously generated during keygen
    val secretShare = "previously_stored_secret_share"

    runBlocking {
        // Initialize the Sr25519 scheme
        val sr25519 = Sr25519(HOST_URL)

        // Your server creates a room for N parties
        val refreshRoomUuid = sr25519.createRoom(N, API_KEY)
        
        // All parties now join the refresh room using their current secret share
        val (pubkey, refreshedSecretShare) = sr25519.refresh(
            refreshRoomUuid,
            secretShare
        )
        
        // Note: The public key remains the same
        // Store refreshedSecretShare securely for future use
        // It can now be used for signing under the same threshold, as well as be refreshed again
    }
    ```
  </Tab>

  <Tab title="BIP340">
    ```kotlin
    import com.sodot.kotlin_sdk.BIP340
    import kotlinx.coroutines.runBlocking

    // Assume we have N parties with T threshold
    val N = 3
    val T = 2
    val API_KEY = "MY_API_KEY"
    val HOST_URL = "us1.sodot.dev" // Your Relay URL

    // A secret share was previously generated during keygen
    val secretShare = "previously_stored_secret_share"

    runBlocking {
        // Initialize the BIP340 scheme
        val bip340 = BIP340(HOST_URL)

        // Your server creates a room for N parties
        val refreshRoomUuid = bip340.createRoom(N, API_KEY)
        
        // All parties now join the refresh room using their current secret share
        val (pubkey, refreshedSecretShare) = bip340.refresh(
            refreshRoomUuid,
            secretShare
        )
        
        // Note: The public key remains the same
        // Store refreshedSecretShare securely for future use
        // It can now be used for signing under the same threshold, as well as be refreshed again
    }
    ```
  </Tab>

  <Tab title="EXPORTABLE ED25519">
    ```kotlin
    import com.sodot.kotlin_sdk.ExportableEd25519
    import kotlinx.coroutines.runBlocking

    // Assume we have N parties with T threshold
    val N = 3
    val T = 2
    val API_KEY = "MY_API_KEY"
    val HOST_URL = "us1.sodot.dev" // Your Relay URL

    // A secret share was previously generated during keygen
    val secretShare = "previously_stored_secret_share"

    runBlocking {
        // Initialize the ExportableEd25519 scheme
        val exportableEd25519 = ExportableEd25519(HOST_URL)
        
        // Your server creates a room for N parties
        val refreshRoomUuid = exportableEd25519.createRoom(N, API_KEY)
        
        // All parties now join the refresh room using their current secret share
        val (pubkey, refreshedSecretShare) = exportableEd25519.refresh(
            refreshRoomUuid,
            secretShare
        )
        
        // Note: The public key remains the same
        // Store refreshedSecretShare securely for future use
        // It can now be used for signing under the same threshold, as well as be refreshed again
    }
    ```
  </Tab>
</Tabs>

## Key Reshare

Key Resharing is a protocol that allows changing the threshold parameters of the distributed key.
This can be useful when adding or removing participants, or when changing the threshold value.

There are two roles in the resharing process:

* **Remaining Parties**: Participants who already have a secret share
* **New Parties**: Participants who will receive a new secret share

<Tabs>
  <Tab title="ECDSA">
    ```kotlin
    import com.sodot.kotlin_sdk.Ecdsa
    import kotlinx.coroutines.runBlocking

    // Change from T=2 of N=3 to T'=3 of N'=5
    val oldThreshold = 2
    val newThreshold = 3
    val API_KEY = "MY_API_KEY"
    val HOST_URL = "us1.sodot.dev" // Your Relay URL

    runBlocking {
        // Initialize the ECDSA scheme
        val ecdsa = Ecdsa(HOST_URL)

        // Your server creates a room for the resharing
        val reshareRoomUuid = ecdsa.createRoom(5, API_KEY)
        
        // For remaining parties (those who already have a secret share):
        val keygenIds = arrayOf("keygenId1", "keygenId2", "keygenId3", "keygenId4", "keygenId5")
        val secretShare = "previously_stored_secret_share"
        
        val (remainingPartyPubkey, remainingPartySecretShare) = ecdsa.reshareRemainingParty(
            reshareRoomUuid,
            newThreshold,
            secretShare,
            keygenIds
        )
        
        // For new parties:
        val (keygenId, keygenPrivateKey) = ecdsa.initKeygen()
        
        val (newPartyPubkey, newPartySecretShare) = ecdsa.reshareNewParty(
            reshareRoomUuid,
            oldThreshold,
            newThreshold,
            keygenPrivateKey,
            keygenIds
        )
        
        // Both remaining and new parties should store their new secret shares
        // These can now be used with the new threshold parameters
    }
    ```
  </Tab>

  <Tab title="ED25519">
    ```kotlin
    import com.sodot.kotlin_sdk.Ed25519
    import kotlinx.coroutines.runBlocking

    // Change from T=2 of N=3 to T'=3 of N'=5
    val oldThreshold = 2
    val newThreshold = 3
    val API_KEY = "MY_API_KEY"
    val HOST_URL = "us1.sodot.dev" // Your Relay URL

    runBlocking {
        // Initialize the Ed25519 scheme
        val ed25519 = Ed25519(HOST_URL)

        // Your server creates a room for the resharing
        val reshareRoomUuid = ed25519.createRoom(5, API_KEY)
        
        // For remaining parties (those who already have a secret share):
        val keygenIds = arrayOf("keygenId1", "keygenId2", "keygenId3", "keygenId4", "keygenId5")
        val secretShare = "previously_stored_secret_share"
        
        val (remainingPartyPubkey, remainingPartySecretShare) = ed25519.reshareRemainingParty(
            reshareRoomUuid,
            newThreshold,
            secretShare,
            keygenIds
        )
        
        // For new parties:
        val (keygenId, keygenPrivateKey) = ed25519.initKeygen()
        
        val (newPartyPubkey, newPartySecretShare) = ed25519.reshareNewParty(
            reshareRoomUuid,
            oldThreshold,
            newThreshold,
            keygenPrivateKey,
            keygenIds
        )
        
        // Both remaining and new parties should store their new secret shares
        // These can now be used with the new threshold parameters
    }
    ```
  </Tab>

  <Tab title="SR25519">
    ```kotlin
    import com.sodot.kotlin_sdk.Sr25519
    import kotlinx.coroutines.runBlocking

    // Change from T=2 of N=3 to T'=3 of N'=5
    val oldThreshold = 2
    val newThreshold = 3
    val API_KEY = "MY_API_KEY"
    val HOST_URL = "us1.sodot.dev" // Your Relay URL

    runBlocking {
        // Initialize the Sr25519 scheme
        val sr25519 = Sr25519(HOST_URL)
        
        // Your server creates a room for the resharing
        val reshareRoomUuid = sr25519.createRoom(5, API_KEY)
        
        // For remaining parties (those who already have a secret share):
        val keygenIds = arrayOf("keygenId1", "keygenId2", "keygenId3", "keygenId4", "keygenId5")
        val secretShare = "previously_stored_secret_share"
        
        val (remainingPartyPubkey, remainingPartySecretShare) = sr25519.reshareRemainingParty(
            reshareRoomUuid,
            newThreshold,
            secretShare,
            keygenIds
        )
        
        // For new parties:
        val (keygenId, keygenPrivateKey) = sr25519.initKeygen()
        
        val (newPartyPubkey, newPartySecretShare) = sr25519.reshareNewParty(
            reshareRoomUuid,
            oldThreshold,
            newThreshold,
            keygenPrivateKey,
            keygenIds
        )
        
        // Both remaining and new parties should store their new secret shares
        // These can now be used with the new threshold parameters
    }
    ```
  </Tab>

  <Tab title="BIP340">
    ```kotlin
    import com.sodot.kotlin_sdk.BIP340
    import kotlinx.coroutines.runBlocking

    // Change from T=2 of N=3 to T'=3 of N'=5
    val oldThreshold = 2
    val newThreshold = 3
    val API_KEY = "MY_API_KEY"
    val HOST_URL = "us1.sodot.dev" // Your Relay URL

    runBlocking {
        // Initialize the BIP340 scheme
        val bip340 = BIP340(HOST_URL)

        // Your server creates a room for the resharing
        val reshareRoomUuid = bip340.createRoom(5, API_KEY)
        
        // For remaining parties (those who already have a secret share):
        val keygenIds = arrayOf("keygenId1", "keygenId2", "keygenId3", "keygenId4", "keygenId5")
        val secretShare = "previously_stored_secret_share"
        
        val (remainingPartyPubkey, remainingPartySecretShare) = bip340.reshareRemainingParty(
            reshareRoomUuid,
            newThreshold,
            secretShare,
            keygenIds
        )
        
        // For new parties:
        val (keygenId, keygenPrivateKey) = bip340.initKeygen()
        
        val (newPartyPubkey, newPartySecretShare) = bip340.reshareNewParty(
            reshareRoomUuid,
            oldThreshold,
            newThreshold,
            keygenPrivateKey,
            keygenIds
        )
        
        // Both remaining and new parties should store their new secret shares
        // These can now be used with the new threshold parameters
    }
    ```
  </Tab>

  <Tab title="EXPORTABLE ED25519">
    ```kotlin
    import com.sodot.kotlin_sdk.ExportableEd25519
    import kotlinx.coroutines.runBlocking

    // Change from T=2 of N=3 to T'=3 of N'=5
    val oldThreshold = 2
    val newThreshold = 3
    val API_KEY = "MY_API_KEY"
    val HOST_URL = "us1.sodot.dev" // Your Relay URL

    runBlocking {
        // Initialize the ExportableEd25519 scheme
        val exportableEd25519 = ExportableEd25519(HOST_URL)

        // Your server creates a room for the resharing
        val reshareRoomUuid = exportableEd25519.createRoom(5, API_KEY)
        
        // For remaining parties (those who already have a secret share):
        val keygenIds = arrayOf("keygenId1", "keygenId2", "keygenId3", "keygenId4", "keygenId5")
        val secretShare = "previously_stored_secret_share"
        
        val (remainingPartyPubkey, remainingPartySecretShare) = exportableEd25519.reshareRemainingParty(
            reshareRoomUuid,
            newThreshold,
            secretShare,
            keygenIds
        )
        
        // For new parties:
        val (keygenId, keygenPrivateKey) = exportableEd25519.initKeygen()
        
        val (newPartyPubkey, newPartySecretShare) = exportableEd25519.reshareNewParty(
            reshareRoomUuid,
            oldThreshold,
            newThreshold,
            keygenPrivateKey,
            keygenIds
        )
        
        // Both remaining and new parties should store their new secret shares
        // These can now be used with the new threshold parameters
    }
    ```
  </Tab>
</Tabs>

## Key Export

In certain scenarios, you might need to export the full private key from the distributed key shares.
This should be used with caution as it negates some of the security benefits of MPC.

<Tabs>
  <Tab title="ECDSA">
    ```kotlin
    import com.sodot.kotlin_sdk.Ecdsa
    import kotlinx.coroutines.runBlocking

    val API_KEY = "MY_API_KEY"
    val HOST_URL = "us1.sodot.dev" // Your Relay URL
    val secretShare = "previously_stored_secret_share"

    runBlocking {
        // Initialize the ECDSA scheme
        val ecdsa = Ecdsa(HOST_URL)
        
        // First, get the export ID from the secret share
        val exportID = ecdsa.exportID(secretShare)
        
        // Create a room for the export process
        val exportRoomUuid = ecdsa.createRoom(2, API_KEY)
        
        // Export the full private key (requires threshold number of participants)
        val fullPrivateKey = ecdsa.exportFullPrivateKey(
            exportRoomUuid,
            secretShare,
            exportID
        )
        
        // Handle the full private key with extreme care
        // This key should be securely stored or used immediately and then discarded
    }

    // Alternatively, if you already have collected all secret shares offline:
    val secretShares = arrayOf("share1", "share2") // At least threshold number of shares
    val ecdsa = Ecdsa(HOST_URL)
    val offlinePrivateKey = ecdsa.offlineExportFullPrivateKey(secretShares)
    ```
  </Tab>

  <Tab title="ED25519">
    ```kotlin
    import com.sodot.kotlin_sdk.Ed25519
    import kotlinx.coroutines.runBlocking

    val API_KEY = "MY_API_KEY"
    val HOST_URL = "us1.sodot.dev" // Your Relay URL
    val secretShare = "previously_stored_secret_share"

    runBlocking {
        // Initialize the Ed25519 scheme
        val ed25519 = Ed25519(HOST_URL)
        
        // First, get the export ID from the secret share
        val exportID = ed25519.exportID(secretShare)
        
        // Create a room for the export process
        val exportRoomUuid = ed25519.createRoom(2, API_KEY)
        
        // Export the full private key (requires threshold number of participants)
        val fullPrivateKey = ed25519.exportFullPrivateKey(
            exportRoomUuid,
            secretShare,
            exportID
        )
        
        // Handle the full private key with extreme care
        // This key should be securely stored or used immediately and then discarded
    }

    // Alternatively, if you already have collected all secret shares offline:
    val secretShares = arrayOf("share1", "share2") // At least threshold number of shares
    val ed25519 = Ed25519(HOST_URL)
    val offlinePrivateKey = ed25519.offlineExportFullPrivateKey(secretShares)
    ```
  </Tab>

  <Tab title="SR25519">
    ```kotlin
    import com.sodot.kotlin_sdk.Sr25519
    import kotlinx.coroutines.runBlocking

    val API_KEY = "MY_API_KEY"
    val HOST_URL = "us1.sodot.dev" // Your Relay URL
    val secretShare = "previously_stored_secret_share"

    runBlocking {
        // Initialize the Sr25519 scheme
        val sr25519 = Sr25519(HOST_URL)
        
        // First, get the export ID from the secret share
        val exportID = sr25519.exportID(secretShare)
        
        // Create a room for the export process
        val exportRoomUuid = sr25519.createRoom(2, API_KEY)
        
        // Export the full private key (requires threshold number of participants)
        val fullPrivateKey = sr25519.exportFullPrivateKey(
            exportRoomUuid,
            secretShare,
            exportID
        )
        
        // Handle the full private key with extreme care
        // This key should be securely stored or used immediately and then discarded
    }

    // Alternatively, if you already have collected all secret shares offline:
    val secretShares = arrayOf("share1", "share2") // At least threshold number of shares
    val sr25519 = Sr25519(HOST_URL)
    val offlinePrivateKey = sr25519.offlineExportFullPrivateKey(secretShares)
    ```
  </Tab>

  <Tab title="BIP340">
    ```kotlin
    import com.sodot.kotlin_sdk.BIP340
    import kotlinx.coroutines.runBlocking

    val API_KEY = "MY_API_KEY"
    val HOST_URL = "us1.sodot.dev" // Your Relay URL
    val secretShare = "previously_stored_secret_share"

    runBlocking {
        // Initialize the BIP340 scheme
        val bip340 = BIP340(HOST_URL)
        
        // First, get the export ID from the secret share
        val exportID = bip340.exportID(secretShare)
        
        // Create a room for the export process
        val exportRoomUuid = bip340.createRoom(2, API_KEY)
        
        // Export the full private key (requires threshold number of participants)
        val fullPrivateKey = bip340.exportFullPrivateKey(
            exportRoomUuid,
            secretShare,
            exportID
        )
        
        // Handle the full private key with extreme care
        // This key should be securely stored or used immediately and then discarded
    }

    // Alternatively, if you already have collected all secret shares offline:
    val secretShares = arrayOf("share1", "share2") // At least threshold number of shares
    val bip340 = BIP340(HOST_URL)
    val offlinePrivateKey = bip340.offlineExportFullPrivateKey(secretShares)
    ```
  </Tab>

  <Tab title="EXPORTABLE ED25519">
    ```kotlin
    import com.sodot.kotlin_sdk.ExportableEd25519
    import kotlinx.coroutines.runBlocking

    val API_KEY = "MY_API_KEY"
    val HOST_URL = "us1.sodot.dev" // Your Relay URL
    val secretShare = "previously_stored_secret_share"

    runBlocking {
        // Initialize the ExportableEd25519 scheme
        val exportableEd25519 = ExportableEd25519(HOST_URL)
        
        // First, get the export ID from the secret share
        val exportID = exportableEd25519.exportID(secretShare)
        
        // Create a room for the export process
        val exportRoomUuid = exportableEd25519.createRoom(2, API_KEY)
        
        // Export the full private key (requires threshold number of participants)
        val fullPrivateKey = exportableEd25519.exportFullPrivateKey(
            exportRoomUuid,
            secretShare,
            exportID
        )
        
        // Handle the full private key with extreme care
        // This key should be securely stored or used immediately and then discarded
    }

    // Alternatively, if you already have collected all secret shares offline:
    val secretShares = arrayOf("share1", "share2") // At least threshold number of shares
    val exportableEd25519 = ExportableEd25519(HOST_URL)
    val offlinePrivateKey = exportableEd25519.offlineExportFullPrivateKey(secretShares)
    ```
  </Tab>
</Tabs>

## Key Import

You can also import an existing private key into the MPC system to create distributed shares.
This is useful for migrating existing keys to the MPC framework.

<Tabs>
  <Tab title="ECDSA">
    ```kotlin
    import com.sodot.kotlin_sdk.Ecdsa
    import kotlinx.coroutines.runBlocking

    val threshold = 2
    val API_KEY = "MY_API_KEY"
    val HOST_URL = "us1.sodot.dev" // Your Relay URL
    val privateKey = byteArrayOf(/* your private key bytes */) // The private key to import

    runBlocking {
        // Initialize the ECDSA scheme
        val ecdsa = Ecdsa(HOST_URL)

        // Create a room for the import process
        val importRoomUuid = ecdsa.createRoom(3, API_KEY)
        
        // All parties initialize key generation
        val (keygenId, keygenPrivateKey) = ecdsa.initKeygen()
        
        // All parties exchange their keygenIds
        val keygenIds = arrayOf("keygenId1", "keygenId2", "keygenId3")
        
        // For the party importing the key (the importer):
        val (importerPubkey, importerSecretShare) = ecdsa.importPrivateKeyImporter(
            importRoomUuid,
            threshold,
            privateKey,
            keygenPrivateKey,
            keygenIds,
            null // chaincode: optionally provide a 32-byte BIP-32 chaincode
        )
        
        // For all other parties (the recipients):
        val (recipientPubkey, recipientSecretShare) = ecdsa.importPrivateKeyRecipient(
            importRoomUuid,
            threshold,
            keygenPrivateKey,
            keygenIds
        )
        
        // All parties now have a secret share of the imported key
        // Store the secret share for future use
    }
    ```
  </Tab>

  <Tab title="ED25519">
    ```kotlin
    import com.sodot.kotlin_sdk.Ed25519
    import kotlinx.coroutines.runBlocking

    val threshold = 2
    val API_KEY = "MY_API_KEY"
    val HOST_URL = "us1.sodot.dev" // Your Relay URL
    val privateKey = byteArrayOf(/* your private key bytes */) // The private key to import
    val isPrivateKeyRaw = false // Set to true if the key is in raw format

    runBlocking {
        // Initialize the Ed25519 scheme
        val ed25519 = Ed25519(HOST_URL)

        // Create a room for the import process
        val importRoomUuid = ed25519.createRoom(3, API_KEY)
        
        // All parties initialize key generation
        val (keygenId, keygenPrivateKey) = ed25519.initKeygen()
        
        // All parties exchange their keygenIds
        val keygenIds = arrayOf("keygenId1", "keygenId2", "keygenId3")
        
        // For the party importing the key (the importer):
        val (importerPubkey, importerSecretShare) = ed25519.importPrivateKeyImporter(
            importRoomUuid,
            threshold,
            privateKey,
            keygenPrivateKey,
            keygenIds,
            isPrivateKeyRaw
        )
        
        // For all other parties (the recipients):
        val (recipientPubkey, recipientSecretShare) = ed25519.importPrivateKeyRecipient(
            importRoomUuid,
            threshold,
            keygenPrivateKey,
            keygenIds
        )
        
        // All parties now have a secret share of the imported key
        // Store the secret share for future use
    }
    ```
  </Tab>

  <Tab title="SR25519">
    ```kotlin
    import com.sodot.kotlin_sdk.Sr25519
    import kotlinx.coroutines.runBlocking

    val threshold = 2
    val API_KEY = "MY_API_KEY"
    val HOST_URL = "us1.sodot.dev" // Your Relay URL
    val privateKey = byteArrayOf(/* your private key bytes */) // The private key to import
    val isPrivateKeyRaw = false // Set to true if the key is in raw format

    runBlocking {
        // Initialize the Sr25519 scheme
        val sr25519 = Sr25519(HOST_URL)

        // Create a room for the import process
        val importRoomUuid = sr25519.createRoom(3, API_KEY)
        
        // All parties initialize key generation
        val (keygenId, keygenPrivateKey) = sr25519.initKeygen()
        
        // All parties exchange their keygenIds
        val keygenIds = arrayOf("keygenId1", "keygenId2", "keygenId3")
        
        // For the party importing the key (the importer):
        val (importerPubkey, importerSecretShare) = sr25519.importPrivateKeyImporter(
            importRoomUuid,
            threshold,
            privateKey,
            keygenPrivateKey,
            keygenIds,
            isPrivateKeyRaw
        )
        
        // For all other parties (the recipients):
        val (recipientPubkey, recipientSecretShare) = sr25519.importPrivateKeyRecipient(
            importRoomUuid,
            threshold,
            keygenPrivateKey,
            keygenIds
        )
        
        // All parties now have a secret share of the imported key
        // Store the secret share for future use
    }
    ```
  </Tab>

  <Tab title="BIP340">
    ```kotlin
    import com.sodot.kotlin_sdk.BIP340
    import kotlinx.coroutines.runBlocking

    val threshold = 2
    val API_KEY = "MY_API_KEY"
    val HOST_URL = "us1.sodot.dev" // Your Relay URL
    val privateKey = byteArrayOf(/* your private key bytes */) // The private key to import

    runBlocking {
        // Initialize the BIP340 scheme
        val bip340 = BIP340(HOST_URL)

        // Create a room for the import process
        val importRoomUuid = bip340.createRoom(3, API_KEY)
        
        // All parties initialize key generation
        val (keygenId, keygenPrivateKey) = bip340.initKeygen()
        
        // All parties exchange their keygenIds
        val keygenIds = arrayOf("keygenId1", "keygenId2", "keygenId3")
        
        // For the party importing the key (the importer):
        val (importerPubkey, importerSecretShare) = bip340.importPrivateKeyImporter(
            importRoomUuid,
            threshold,
            privateKey,
            keygenPrivateKey,
            keygenIds,
            null // chaincode: optionally provide a 32-byte BIP-32 chaincode
        )
        
        // For all other parties (the recipients):
        val (recipientPubkey, recipientSecretShare) = bip340.importPrivateKeyRecipient(
            importRoomUuid,
            threshold,
            keygenPrivateKey,
            keygenIds
        )
        
        // All parties now have a secret share of the imported key
        // Store the secret share for future use
    }
    ```
  </Tab>

  <Tab title="EXPORTABLE ED25519">
    ```kotlin
    import com.sodot.kotlin_sdk.ExportableEd25519
    import kotlinx.coroutines.runBlocking

    val threshold = 2
    val API_KEY = "MY_API_KEY"
    val HOST_URL = "us1.sodot.dev" // Your Relay URL
    val privateKey = byteArrayOf(/* your private key bytes */) // The private key to import

    runBlocking {
        // Initialize the ExportableEd25519 scheme
        val exportableEd25519 = ExportableEd25519(HOST_URL)

        // Create a room for the import process
        val importRoomUuid = exportableEd25519.createRoom(3, API_KEY)
        
        // All parties initialize key generation
        val (keygenId, keygenPrivateKey) = exportableEd25519.initKeygen()
        
        // All parties exchange their keygenIds
        val keygenIds = arrayOf("keygenId1", "keygenId2", "keygenId3")
        
        // For the party importing the key (the importer):
        val (importerPubkey, importerSecretShare) = exportableEd25519.importPrivateKeyImporter(
            importRoomUuid,
            threshold,
            privateKey,
            keygenPrivateKey,
            keygenIds
        )
        
        // For all other parties (the recipients):
        val (recipientPubkey, recipientSecretShare) = exportableEd25519.importPrivateKeyRecipient(
            importRoomUuid,
            threshold,
            keygenPrivateKey,
            keygenIds
        )
        
        // All parties now have a secret share of the imported key
        // Store the secret share for future use
    }
    ```
  </Tab>
</Tabs>
