Skip to content

Commit

Permalink
Add did web impl in web5-rs (etro-js#273)
Browse files Browse the repository at this point in the history
  • Loading branch information
nitro-neal authored Jul 31, 2024
1 parent 3a95df4 commit 5a79dc7
Show file tree
Hide file tree
Showing 13 changed files with 177 additions and 9 deletions.
10 changes: 10 additions & 0 deletions bindings/web5_uniffi/libtargets/build_all.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/bash

for dir in */; do
echo "Entering directory: $dir"
(cd "$dir" && ./build)
echo "Finished building in $dir"
echo "------------------------"
done

echo "All builds completed"
2 changes: 2 additions & 0 deletions bindings/web5_uniffi/src/web5.udl
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,8 @@ dictionary DidWebData {
};

interface DidWeb {
[Name=from_public_jwk, Throws=RustCoreError]
constructor([ByRef] string domain, JwkData public_jwk);
[Async, Name=from_uri, Throws=RustCoreError]
constructor([ByRef] string uri);
DidWebData get_data();
Expand Down
6 changes: 6 additions & 0 deletions bindings/web5_uniffi_wrapper/src/dids/methods/did_web.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::{dids::resolution::resolution_result::ResolutionResult, errors::Result};
use std::sync::Arc;
use web5::crypto::jwk::Jwk;
use web5::dids::methods::did_web::DidWeb as InnerDidWeb;

pub struct DidWeb(pub InnerDidWeb);
Expand All @@ -10,6 +11,11 @@ pub async fn did_web_resolve(uri: &str) -> Result<Arc<ResolutionResult>> {
}

impl DidWeb {
pub fn from_public_jwk(domain: &str, public_key: Jwk) -> Result<Self> {
let did_web = InnerDidWeb::new(domain, public_key)?;
Ok(Self(did_web))
}

pub async fn from_uri(uri: &str) -> Result<Self> {
let did_web = InnerDidWeb::from_uri(uri).await?;
Ok(Self(did_web))
Expand Down
14 changes: 8 additions & 6 deletions bound/kt/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,6 @@
<artifactId>jna</artifactId>
<version>5.12.0</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.10.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlinx</groupId>
<artifactId>kotlinx-coroutines-core</artifactId>
Expand All @@ -56,6 +50,14 @@
<artifactId>jackson-module-kotlin</artifactId>
<version>2.17.0</version>
</dependency>

<!-- Test Dependencies -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.10.2</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down
71 changes: 71 additions & 0 deletions bound/kt/src/main/kotlin/web5/sdk/dids/methods/web/DidWeb.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package web5.sdk.dids.methods.web

import kotlinx.coroutines.runBlocking
import web5.sdk.crypto.keys.Jwk
import web5.sdk.dids.Did
import web5.sdk.dids.Document
import web5.sdk.dids.ResolutionResult
import web5.sdk.rust.SystemTarget

import web5.sdk.rust.didWebResolve as rustCoreDidWebResolve
import web5.sdk.rust.DidWeb as RustCoreDidWeb

/**
* A class representing a DID (Decentralized Identifier) using the Web method.
*
* @property did The DID associated with this instance.
* @property document The DID document associated with this instance.
*/
class DidWeb {
init {
SystemTarget.set() // ensure the sys arch is set for first-time loading
}

val did: Did
val document: Document

/**
* Constructs a DidWeb instance using a DID URI.
*
* @param uri The DID URI.
*/
constructor(uri: String) {
val rustCoreDidWeb = runBlocking {
RustCoreDidWeb.fromUri(uri)
}

this.did = rustCoreDidWeb.getData().did
this.document = rustCoreDidWeb.getData().document
}

/**
* Constructs a DidWeb instance using a domain and public key jwk
*
* @param domain The DID domain name.
*/
constructor(domain: String, publicKey: Jwk) {
val rustCoreDidWeb = runBlocking {
RustCoreDidWeb.fromPublicJwk(domain, publicKey);
}

this.did = rustCoreDidWeb.getData().did
this.document = rustCoreDidWeb.getData().document
}

companion object {
/**
* Resolves a DID URI to a DidResolutionResult.
*
* @param uri The DID URI to resolve.
* @return DidResolutionResult The result of the DID resolution.
*/
@JvmStatic
fun resolve(uri: String): ResolutionResult {
val rustCoreResolutionObject =
runBlocking {
rustCoreDidWebResolve(uri).getData()
}
return rustCoreResolutionObject
}
}
}
20 changes: 20 additions & 0 deletions bound/kt/src/main/kotlin/web5/sdk/rust/UniFFI.kt
Original file line number Diff line number Diff line change
Expand Up @@ -881,6 +881,8 @@ internal open class UniffiVTableCallbackInterfaceVerifier(








Expand Down Expand Up @@ -954,6 +956,8 @@ internal interface UniffiLib : Library {
): Pointer
fun uniffi_web5_uniffi_fn_free_didweb(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus,
): Unit
fun uniffi_web5_uniffi_fn_constructor_didweb_from_public_jwk(`domain`: RustBuffer.ByValue,`publicJwk`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus,
): Pointer
fun uniffi_web5_uniffi_fn_constructor_didweb_from_uri(`uri`: RustBuffer.ByValue,
): Long
fun uniffi_web5_uniffi_fn_method_didweb_get_data(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus,
Expand Down Expand Up @@ -1254,6 +1258,8 @@ internal interface UniffiLib : Library {
): Short
fun uniffi_web5_uniffi_checksum_constructor_didjwk_from_uri(
): Short
fun uniffi_web5_uniffi_checksum_constructor_didweb_from_public_jwk(
): Short
fun uniffi_web5_uniffi_checksum_constructor_didweb_from_uri(
): Short
fun uniffi_web5_uniffi_checksum_constructor_document_new(
Expand Down Expand Up @@ -1401,6 +1407,9 @@ private fun uniffiCheckApiChecksums(lib: UniffiLib) {
if (lib.uniffi_web5_uniffi_checksum_constructor_didjwk_from_uri() != 10422.toShort()) {
throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
}
if (lib.uniffi_web5_uniffi_checksum_constructor_didweb_from_public_jwk() != 58059.toShort()) {
throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
}
if (lib.uniffi_web5_uniffi_checksum_constructor_didweb_from_uri() != 44078.toShort()) {
throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
}
Expand Down Expand Up @@ -2950,6 +2959,17 @@ open class DidWeb: Disposable, AutoCloseable, DidWebInterface {

companion object {

@Throws(RustCoreException::class) fun `fromPublicJwk`(`domain`: kotlin.String, `publicJwk`: JwkData): DidWeb {
return FfiConverterTypeDidWeb.lift(
uniffiRustCallWithError(RustCoreException) { _status ->
UniffiLib.INSTANCE.uniffi_web5_uniffi_fn_constructor_didweb_from_public_jwk(
FfiConverterString.lower(`domain`),FfiConverterTypeJwkData.lower(`publicJwk`),_status)
}
)
}



@Throws(RustCoreException::class)
@Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE")
suspend fun `fromUri`(`uri`: kotlin.String) : DidWeb {
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ class DidJwkTests {

val didJwk = DidJwk(jwk)

println(didJwk.document.id)

val rustCoreDidJwk = RustCoreDidJwk.fromPublicJwk(jwk);
assertEquals(rustCoreDidJwk.getData().did.uri, didJwk.did.uri)
assertEquals(rustCoreDidJwk.getData().document.id, didJwk.document.id)
Expand Down
49 changes: 49 additions & 0 deletions bound/kt/src/test/kotlin/web5/sdk/dids/methods/web/DidWebTests.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package web5.sdk.dids.methods.web

import org.junit.jupiter.api.Assertions.*
import org.junit.jupiter.api.Test
import web5.sdk.rust.ed25519GeneratorGenerate

class DidWebTests {

@Test
fun `can create did web`() {
val domain = "example.com"
val jwk = ed25519GeneratorGenerate();

val didWeb = DidWeb(domain, jwk)
assertEquals(didWeb.did.uri, "did:web:example.com")
assertEquals(didWeb.document.verificationMethod.get(0).publicKeyJwk, jwk)
}

@Test
fun `can resolve did web uri`() {
// Works if you host a local did web document You must host this json at http://localhost:1234/.well-known/did.json
// val didDocumentJson = """
// {
// "id":"did:web.tbd.website",
// "@context":[
// "https://www.w3.org/ns/did/v1"
// ],
// "verificationMethod":[
// {
// "id":"did:web:www.tbd.website#key-0",
// "type":"JsonWebKey",
// "controller":"did:web:www.tbd.website",
// "publicKeyJwk":{
// "alg":"Ed25519",
// "kty":"OKP",
// "crv":"Ed25519",
// "x":"gNFtgCZhOYv00p48FHQYt4edkoBPOyw0oGAB20LrT0c"
// }
// }
// ]
// }
// """.trimIndent()
//
// val didUri = "did:web:localhost%3A1234"
// val resolvedDid = DidWeb.resolve(didUri)
//
// assertEquals(resolvedDid.document!!.id, "did:web:www.tbd.website")
}
}
12 changes: 11 additions & 1 deletion crates/web5/src/dids/resolution/resolution_result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ mod tests {
}

#[test]
fn can_resolve_did_web() {
fn can_resolve_invalid_did_web() {
let did_uri = "did:web:tbd.website";
let resolution_result = ResolutionResult::new(did_uri);

Expand All @@ -67,6 +67,16 @@ mod tests {
);
}

// This works if you host a did web document json at http://localhost:1234/.well-known/did.json
// #[test]
// fn can_resolve_valid_did_web() {
// let did_uri = "did:web:localhost%3A1234";
// let resolution_result = ResolutionResult::new(did_uri);
//
// assert_eq!(None, resolution_result.resolution_metadata.error);
// assert_eq!(resolution_result.document.unwrap().id, "did:web:tbd.website");
// }

#[test]
fn can_resolve_did_dht() {
let did_uri = "did:dht:swit41ctrddy1s38c5j46yfgbxmwo1emau71zo5hn1tws1g63hiy";
Expand Down

0 comments on commit 5a79dc7

Please sign in to comment.