Skip to content

Commit

Permalink
Add PortableDid from_json_string() and to_json_string() (#296)
Browse files Browse the repository at this point in the history
  • Loading branch information
KendallWeihe authored Aug 20, 2024
1 parent 8c0bf68 commit 5400f95
Show file tree
Hide file tree
Showing 9 changed files with 104 additions and 61 deletions.
4 changes: 3 additions & 1 deletion bindings/web5_uniffi/src/web5.udl
Original file line number Diff line number Diff line change
Expand Up @@ -208,9 +208,11 @@ dictionary PortableDidData {
};

interface PortableDid {
[Throws=Web5Error]
[Name=from_json_string, Throws=Web5Error]
constructor([ByRef] string json);
PortableDidData get_data();
[Throws=Web5Error]
string to_json_string();
};

dictionary BearerDidData {
Expand Down
15 changes: 11 additions & 4 deletions bindings/web5_uniffi_wrapper/src/dids/portable_did.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
use web5::dids::portable_did::PortableDid as InnerPortableDid;

use crate::errors::Result;
use web5::{
dids::portable_did::PortableDid as InnerPortableDid,
json::{FromJson, ToJson},
};

pub struct PortableDid(pub InnerPortableDid);

impl PortableDid {
pub fn new(json: &str) -> Result<Self> {
let inner_portable_did = InnerPortableDid::new(json)?;
pub fn from_json_string(json: &str) -> Result<Self> {
let inner_portable_did = InnerPortableDid::from_json_string(json)?;
Ok(Self(inner_portable_did))
}

pub fn get_data(&self) -> InnerPortableDid {
self.0.clone()
}

pub fn to_json_string(&self) -> Result<String> {
let json_string = self.0.to_json_string()?;
Ok(json_string)
}
}
7 changes: 0 additions & 7 deletions bindings/web5_uniffi_wrapper/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ use web5::crypto::dsa::DsaError;
use web5::crypto::key_managers::KeyManagerError;
use web5::dids::bearer_did::BearerDidError;
use web5::dids::methods::MethodError;
use web5::dids::portable_did::PortableDidError;
use web5::errors::Web5Error as InnerWeb5Error;

#[derive(Debug, Error)]
Expand Down Expand Up @@ -90,12 +89,6 @@ impl From<DsaError> for Web5Error {
}
}

impl From<PortableDidError> for Web5Error {
fn from(error: PortableDidError) -> Self {
Web5Error::new(error)
}
}

impl From<MethodError> for Web5Error {
fn from(error: MethodError) -> Self {
Web5Error::new(error)
Expand Down
33 changes: 22 additions & 11 deletions bound/kt/src/main/kotlin/web5/sdk/dids/PortableDid.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,34 @@ package web5.sdk.dids
import web5.sdk.crypto.keys.Jwk
import web5.sdk.rust.PortableDid as RustCorePortableDid

class PortableDid {
val didUri: String
val document: Document
val privateKeys: List<Jwk>

class PortableDid private constructor(
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)
companion object {
fun fromJsonString(json: String): PortableDid {
val rustCorePortableDid = RustCorePortableDid.fromJsonString(json)
val data = rustCorePortableDid.getData()
return PortableDid(
data.didUri,
data.document,
data.privateJwks.map { Jwk.fromRustCoreJwkData(it) },
rustCorePortableDid
)
}
}

this.didUri = rustCorePortableDid.getData().didUri
this.document = rustCorePortableDid.getData().document
this.privateKeys = rustCorePortableDid.getData().privateJwks.map {Jwk.fromRustCoreJwkData(it) }
/**
* Serializes a PortableDid to a JSON string.
*/
fun toJsonString(): String {
return rustCorePortableDid.toJsonString()
}
}
51 changes: 40 additions & 11 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 @@ -1018,10 +1020,12 @@ internal interface UniffiLib : Library {
): Pointer
fun uniffi_web5_uniffi_fn_free_portabledid(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus,
): Unit
fun uniffi_web5_uniffi_fn_constructor_portabledid_new(`json`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus,
fun uniffi_web5_uniffi_fn_constructor_portabledid_from_json_string(`json`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus,
): Pointer
fun uniffi_web5_uniffi_fn_method_portabledid_get_data(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus,
): RustBuffer.ByValue
fun uniffi_web5_uniffi_fn_method_portabledid_to_json_string(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus,
): RustBuffer.ByValue
fun uniffi_web5_uniffi_fn_clone_presentationdefinition(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus,
): Pointer
fun uniffi_web5_uniffi_fn_free_presentationdefinition(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus,
Expand Down Expand Up @@ -1228,6 +1232,8 @@ internal interface UniffiLib : Library {
): Short
fun uniffi_web5_uniffi_checksum_method_portabledid_get_data(
): Short
fun uniffi_web5_uniffi_checksum_method_portabledid_to_json_string(
): Short
fun uniffi_web5_uniffi_checksum_method_presentationdefinition_get_json_serialized_presentation_definition(
): Short
fun uniffi_web5_uniffi_checksum_method_presentationdefinition_select_credentials(
Expand Down Expand Up @@ -1268,7 +1274,7 @@ internal interface UniffiLib : Library {
): Short
fun uniffi_web5_uniffi_checksum_constructor_jwk_new(
): Short
fun uniffi_web5_uniffi_checksum_constructor_portabledid_new(
fun uniffi_web5_uniffi_checksum_constructor_portabledid_from_json_string(
): Short
fun uniffi_web5_uniffi_checksum_constructor_presentationdefinition_new(
): Short
Expand Down Expand Up @@ -1359,6 +1365,9 @@ private fun uniffiCheckApiChecksums(lib: UniffiLib) {
if (lib.uniffi_web5_uniffi_checksum_method_portabledid_get_data() != 27045.toShort()) {
throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
}
if (lib.uniffi_web5_uniffi_checksum_method_portabledid_to_json_string() != 53673.toShort()) {
throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
}
if (lib.uniffi_web5_uniffi_checksum_method_presentationdefinition_get_json_serialized_presentation_definition() != 52261.toShort()) {
throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
}
Expand Down Expand Up @@ -1419,7 +1428,7 @@ private fun uniffiCheckApiChecksums(lib: UniffiLib) {
if (lib.uniffi_web5_uniffi_checksum_constructor_jwk_new() != 59888.toShort()) {
throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
}
if (lib.uniffi_web5_uniffi_checksum_constructor_portabledid_new() != 37852.toShort()) {
if (lib.uniffi_web5_uniffi_checksum_constructor_portabledid_from_json_string() != 64165.toShort()) {
throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
}
if (lib.uniffi_web5_uniffi_checksum_constructor_presentationdefinition_new() != 13282.toShort()) {
Expand Down Expand Up @@ -4649,6 +4658,8 @@ public interface PortableDidInterface {

fun `getData`(): PortableDidData

fun `toJsonString`(): kotlin.String

companion object
}

Expand All @@ -4669,13 +4680,6 @@ open class PortableDid: Disposable, AutoCloseable, PortableDidInterface {
this.pointer = null
this.cleanable = UniffiLib.CLEANER.register(this, UniffiCleanAction(pointer))
}
constructor(`json`: kotlin.String) :
this(
uniffiRustCallWithError(Web5Exception) { _status ->
UniffiLib.INSTANCE.uniffi_web5_uniffi_fn_constructor_portabledid_new(
FfiConverterString.lower(`json`),_status)
}
)

protected val pointer: Pointer?
protected val cleanable: UniffiCleaner.Cleanable
Expand Down Expand Up @@ -4753,10 +4757,35 @@ open class PortableDid: Disposable, AutoCloseable, PortableDidInterface {



@Throws(Web5Exception::class)override fun `toJsonString`(): kotlin.String {
return FfiConverterString.lift(
callWithPointer {
uniffiRustCallWithError(Web5Exception) { _status ->
UniffiLib.INSTANCE.uniffi_web5_uniffi_fn_method_portabledid_to_json_string(
it, _status)
}
}
)
}





companion object {

@Throws(Web5Exception::class) fun `fromJsonString`(`json`: kotlin.String): PortableDid {
return FfiConverterTypePortableDid.lift(
uniffiRustCallWithError(Web5Exception) { _status ->
UniffiLib.INSTANCE.uniffi_web5_uniffi_fn_constructor_portabledid_from_json_string(
FfiConverterString.lower(`json`),_status)
}
)
}

companion object


}

}

Expand Down
17 changes: 15 additions & 2 deletions bound/kt/src/test/kotlin/web5/sdk/dids/PortableDidTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class PortableDidTest {
""".trimIndent()

assertDoesNotThrow {
val portableDid = PortableDid(jsonString)
val portableDid = PortableDid.fromJsonString(jsonString)
assertEquals("did:web:tbd.website%3A9002:alice", portableDid.didUri)
}
}
Expand All @@ -23,7 +23,20 @@ class PortableDidTest {
fun `instantiation from json string throws with invalid json string`() {
val invalidJsonString = "something not valid"
assertThrows(Web5Exception::class.java) {
PortableDid(invalidJsonString)
PortableDid.fromJsonString(invalidJsonString)
}
}

@Test
fun `can serialize to a 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.fromJsonString(jsonString)
val serializedJsonString = portableDid.toJsonString()
assertEquals(jsonString, serializedJsonString)
}
}
}
28 changes: 6 additions & 22 deletions crates/web5/src/dids/portable_did.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use super::data_model::document::Document;
use crate::crypto::jwk::Jwk;
use crate::{
crypto::jwk::Jwk,
json::{FromJson, ToJson},
};
use serde::{Deserialize, Serialize};
use serde_json::Error as SerdeJsonError;

#[derive(Serialize, Deserialize, Clone)]
pub struct PortableDid {
Expand All @@ -12,23 +14,5 @@ pub struct PortableDid {
pub private_jwks: Vec<Jwk>,
}

#[derive(thiserror::Error, Debug)]
pub enum PortableDidError {
#[error("serde json error {0}")]
SerdeJsonError(String),
}

impl From<SerdeJsonError> for PortableDidError {
fn from(err: SerdeJsonError) -> Self {
PortableDidError::SerdeJsonError(err.to_string())
}
}

type Result<T> = std::result::Result<T, PortableDidError>;

impl PortableDid {
pub fn new(json: &str) -> Result<Self> {
let portable_did = serde_json::from_str::<Self>(json)?;
Ok(portable_did)
}
}
impl FromJson for PortableDid {}
impl ToJson for PortableDid {}
6 changes: 4 additions & 2 deletions crates/web5_cli/src/vcs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use web5::{
CredentialSubject, Issuer, VerifiableCredential, VerifiableCredentialCreateOptions,
},
dids::{bearer_did::BearerDid, portable_did::PortableDid},
json::ToJson,
json::{FromJson, ToJson},
};

#[derive(Subcommand, Debug)]
Expand Down Expand Up @@ -44,7 +44,9 @@ impl Commands {
no_indent,
json_escape,
} => {
let portable_did = portable_did.as_ref().map(|p| PortableDid::new(p).unwrap());
let portable_did = portable_did
.as_ref()
.map(|p| PortableDid::from_json_string(p).unwrap());
let issuer = Issuer::String(match issuer {
Some(i) => i.to_string(),
None => match &portable_did {
Expand Down
4 changes: 3 additions & 1 deletion docs/API_DESIGN.md
Original file line number Diff line number Diff line change
Expand Up @@ -695,7 +695,9 @@ CLASS PortableDid
DATA MEMBER uri: string
DATA MEMBER private_jwks: []Jwk
DATA MEMBER document: Document
CONSTRUCTOR(json: string)
CONSTRUCTOR from_json_string(json: string)
METHOD to_json_string(): string
```

### Example: Create a [`PortableDid`](#portabledid) via the `web5` CLI
Expand Down

0 comments on commit 5400f95

Please sign in to comment.