Skip to content

Commit

Permalink
Add PortableDid, use existing UniFFI interfaces (etro-js#275)
Browse files Browse the repository at this point in the history
  • Loading branch information
KendallWeihe authored Jul 31, 2024
1 parent 5a79dc7 commit 8350fc2
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 57 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
package web5.sdk.crypto.keys

import web5.sdk.crypto.signers.OuterSigner
import web5.sdk.crypto.signers.Signer
import web5.sdk.rust.SystemTarget
import web5.sdk.rust.InMemoryKeyManager as RustCoreInMemoryKeyManager
import web5.sdk.rust.KeyManager as RustCoreKeyManager

/**
* A class for managing cryptographic keys in-memory.
Expand Down Expand Up @@ -34,17 +32,7 @@ class InMemoryKeyManager : KeyManager {
* @return Signer The signer for the given public key.
*/
override fun getSigner(publicJwk: Jwk): Signer {
val innerSigner = this.rustCoreInMemoryKeyManager.getSigner(publicJwk)
return OuterSigner(innerSigner)
}

/**
* Returns the RustCoreKeyManager.
*
* @return RustCoreKeyManager The rust core key manager.
*/
override fun getRustCoreKeyManager(): RustCoreKeyManager {
return this.rustCoreInMemoryKeyManager.getAsKeyManager()
return this.rustCoreInMemoryKeyManager.getSigner(publicJwk)
}

/**
Expand Down
21 changes: 1 addition & 20 deletions bound/kt/src/main/kotlin/web5/sdk/crypto/keys/KeyManager.kt
Original file line number Diff line number Diff line change
@@ -1,25 +1,6 @@
package web5.sdk.crypto.keys

import web5.sdk.crypto.signers.Signer
import web5.sdk.rust.KeyManager as RustCoreKeyManager

/**
* An interface representing a key manager for cryptographic operations.
*/
interface KeyManager {
typealias KeyManager = RustCoreKeyManager

/**
* Returns the signer for the given public key.
*
* @param publicKey The public key represented as a Jwk.
* @return Signer The signer for the given public key.
*/
fun getSigner(publicJwk: Jwk): Signer

/**
* Returns the RustCoreKeyManager
*
* @return RustCoreKeyManager The rust core key manager
*/
fun getRustCoreKeyManager(): RustCoreKeyManager
}
21 changes: 1 addition & 20 deletions bound/kt/src/main/kotlin/web5/sdk/crypto/signers/Signer.kt
Original file line number Diff line number Diff line change
@@ -1,24 +1,5 @@
package web5.sdk.crypto.signers

import web5.sdk.rust.SystemTarget
import web5.sdk.rust.Signer as RustCoreSigner

interface Signer {
fun sign(payload: ByteArray): ByteArray
}

class OuterSigner: Signer {
init {
SystemTarget.set() // ensure the sys arch is set for first-time loading
}

private val rustCoreSigner: RustCoreSigner

constructor(rustCoreSigner: RustCoreSigner) {
this.rustCoreSigner = rustCoreSigner
}

override fun sign(payload: ByteArray): ByteArray {
return this.rustCoreSigner.sign(payload)
}
}
typealias Signer = RustCoreSigner
20 changes: 16 additions & 4 deletions bound/kt/src/main/kotlin/web5/sdk/dids/BearerDid.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package web5.sdk.dids

import web5.sdk.crypto.signers.Signer
import web5.sdk.crypto.keys.KeyManager
import web5.sdk.crypto.signers.OuterSigner
import web5.sdk.rust.SystemTarget

import web5.sdk.rust.BearerDid as RustCoreBearerDid
Expand Down Expand Up @@ -32,21 +31,34 @@ class BearerDid {
* @param keyManager The key manager to handle keys.
*/
constructor(uri: String, keyManager: KeyManager) {
this.rustCoreBearerDid = RustCoreBearerDid(uri, keyManager.getRustCoreKeyManager())
this.rustCoreBearerDid = RustCoreBearerDid(uri, keyManager)

this.did = this.rustCoreBearerDid.getData().did
this.document = this.rustCoreBearerDid.getData().document
this.keyManager = keyManager
}

/**
* Constructs a BearerDid instance from a PortableDid.
*
* @param portableDid The PortableDid.
*/
constructor(portableDid: PortableDid) {
this.rustCoreBearerDid = RustCoreBearerDid.fromPortableDid(portableDid.rustCorePortableDid)

val data = this.rustCoreBearerDid.getData()
this.did = data.did
this.document = data.document
this.keyManager = data.keyManager
}

/**
* Returns a signer for the DID.
*
* @return Signer The signer for the DID.
*/
fun getSigner(): Signer {
val keyId = this.document.verificationMethod.first().id
val innerSigner = this.rustCoreBearerDid.getSigner(keyId)
return OuterSigner(innerSigner)
return this.rustCoreBearerDid.getSigner(keyId)
}
}
30 changes: 30 additions & 0 deletions bound/kt/src/main/kotlin/web5/sdk/dids/PortableDid.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package web5.sdk.dids

import web5.sdk.crypto.keys.Jwk
import web5.sdk.rust.SystemTarget
import web5.sdk.rust.PortableDid as RustCorePortableDid

class PortableDid {
init {
SystemTarget.set() // ensure the sys arch is set for first-time loading
}

val didUri: String
val document: Document
val privateKeys: List<Jwk>

internal val rustCorePortableDid: RustCorePortableDid

/**
* Constructs a PortableDid from a JSON string.
*
* @param json The JSON string.
*/
constructor(json: String) {
this.rustCorePortableDid = RustCorePortableDid(json)

this.didUri = rustCorePortableDid.getData().didUri
this.document = rustCorePortableDid.getData().document
this.privateKeys = rustCorePortableDid.getData().privateJwks
}
}
29 changes: 29 additions & 0 deletions bound/kt/src/test/kotlin/web5/sdk/dids/PortableDidTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package web5.sdk.dids

import org.junit.jupiter.api.Test
import org.junit.jupiter.api.Assertions.assertDoesNotThrow
import org.junit.jupiter.api.Assertions.assertThrows
import org.junit.jupiter.api.Assertions.assertEquals
import web5.sdk.rust.RustCoreException

class PortableDidTest {
@Test
fun `can instantiate from json string`() {
val jsonString = """
{"uri":"did:web:tbd.website%3A9002:alice","document":{"id":"did:web:tbd.website%3A9002:alice","@context":["https://www.w3.org/ns/did/v1"],"verificationMethod":[{"id":"did:web:tbd.website%3A9002:alice#key-0","type":"JsonWebKey","controller":"did:web:tbd.website%3A9002:alice","publicKeyJwk":{"alg":"Ed25519","kty":"OKP","crv":"Ed25519","x":"NNoVSv_v34ombmylF572t9HYYDiJtMgfckRT1W0vW0g"}}]},"privateKeys":[{"alg":"Ed25519","kty":"OKP","crv":"Ed25519","d":"SwuWbL-Fm64OUFy6x3FBt3RiB79RcnZZrllGT24m4BA","x":"NNoVSv_v34ombmylF572t9HYYDiJtMgfckRT1W0vW0g"}]}
""".trimIndent()

assertDoesNotThrow {
val portableDid = PortableDid(jsonString)
assertEquals("did:web:tbd.website%3A9002:alice", portableDid.didUri)
}
}

@Test
fun `instantiation from json string throws with invalid json string`() {
val invalidJsonString = "something not valid"
assertThrows(RustCoreException::class.java) {
PortableDid(invalidJsonString)
}
}
}

0 comments on commit 8350fc2

Please sign in to comment.