Skip to main content

Sign

Signing produces a threshold signature over a message hash using the device's keyshare and the server's keyshare. The full private key is never reconstructed — each party contributes its share to the MPC protocol and the resulting signature is valid on-chain.

For the SDK contract see Sign (Kotlin) and Sign (Swift).

How the example does it

vault/.../session/VaultSessionManager.kt
suspend fun sign(keyId: String, message: ByteArray, derivationPath: String): ByteArray {
val dao = readDao(keyId)
val keyshare = dao.currentKeyshare
?: throw Exception("No active keyshare found for keyId: $keyId")

val signature = sessionFor(dao.keyType)
.signature(keyshare = keyshare, message = message.toHex(), derivationPath = derivationPath)
.getOrThrow()

return signature
}

The example loads the keyshare from encrypted storage via readDao(keyId) / loadRecord(keyId:), which returns the storage client's VaultReconcileStoreDao / VaultReconcileRecord wrapper. The keyType on that wrapper is how the example knows which session (ECDSA or EdDSA) to dispatch to.

The message parameter is the transaction hash (hex-encoded). The derivationPath is "m" in this example (the root BIP-32 path). For child key derivation see BIP-32.

Send tokensTransaction submitted