Skip to content

Commit

Permalink
Polish identity_iota_core (#1203)
Browse files Browse the repository at this point in the history
* Remove unused error variants

* Link to shimmer spec

* Polish document signatures and docs

* Rename `tag` to `tag_str`

* Update Wasm bindings compatibly

* Add lints and add docs
  • Loading branch information
PhilippGackstatter authored Jul 17, 2023
1 parent 0fac0bb commit 5eabeff
Show file tree
Hide file tree
Showing 19 changed files with 194 additions and 100 deletions.
4 changes: 2 additions & 2 deletions bindings/wasm/lib/iota_identity_client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,10 +149,10 @@ export class IotaIdentityClient implements IIotaIdentityClient {
*/
async deleteDidOutput(secretManager: SecretManager, address: AddressTypes, did: IotaDID) {
const networkHrp = await this.getNetworkHrp();
if (networkHrp !== did.networkStr()) {
if (networkHrp !== did.network()) {
throw new Error(
"deleteDidOutput: DID network mismatch, client expected `" + networkHrp + "`, DID network is `"
+ did.networkStr() + "`",
+ did.network() + "`",
);
}

Expand Down
6 changes: 3 additions & 3 deletions bindings/wasm/src/iota/iota_did.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,15 +80,15 @@ impl WasmIotaDID {
// ===========================================================================

/// Returns the Tangle network name of the `IotaDID`.
#[wasm_bindgen(js_name = networkStr)]
pub fn network_str(&self) -> String {
#[wasm_bindgen]
pub fn network(&self) -> String {
self.0.network_str().to_owned()
}

/// Returns a copy of the unique tag of the `IotaDID`.
#[wasm_bindgen]
pub fn tag(&self) -> String {
self.0.tag().to_owned()
self.0.tag_str().to_owned()
}

#[wasm_bindgen(js_name = toCoreDid)]
Expand Down
4 changes: 2 additions & 2 deletions bindings/wasm/src/iota/iota_document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -548,10 +548,10 @@ impl WasmIotaDocument {
let value: Option<serde_json::Value> = value.into_serde().wasm_result()?;
match value {
Some(value) => {
self.0.blocking_write().metadata.properties.insert(key, value);
self.0.blocking_write().metadata.properties_mut().insert(key, value);
}
None => {
self.0.blocking_write().metadata.properties.remove(&key);
self.0.blocking_write().metadata.properties_mut().remove(&key);
}
}
Ok(())
Expand Down
2 changes: 1 addition & 1 deletion bindings/wasm/src/iota/iota_document_metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ impl WasmIotaDocumentMetadata {
/// Returns a copy of the custom metadata properties.
#[wasm_bindgen]
pub fn properties(&self) -> Result<MapStringAny> {
MapStringAny::try_from(&self.0.properties)
MapStringAny::try_from(self.0.properties())
}
}

Expand Down
6 changes: 3 additions & 3 deletions bindings/wasm/tests/iota.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ describe("IotaDID", function() {
assert.deepStrictEqual(did.toString(), "did:" + IotaDID.METHOD + ":" + networkName + ":" + aliasIdHex);
assert.deepStrictEqual(did.tag(), aliasIdHex);
assert.deepStrictEqual(did.method(), IotaDID.METHOD);
assert.deepStrictEqual(did.networkStr(), networkName);
assert.deepStrictEqual(did.network(), networkName);
assert.deepStrictEqual(did.authority(), IotaDID.METHOD + ":" + networkName + ":" + aliasIdHex);
assert.deepStrictEqual(did.methodId(), networkName + ":" + aliasIdHex);
assert.deepStrictEqual(did.scheme(), "did");
Expand All @@ -55,7 +55,7 @@ describe("IotaDID", function() {
assert.deepStrictEqual(did.toString(), "did:" + IotaDID.METHOD + ":" + networkName + ":" + aliasIdHex);
assert.deepStrictEqual(did.tag(), aliasIdHex);
assert.deepStrictEqual(did.method(), IotaDID.METHOD);
assert.deepStrictEqual(did.networkStr(), networkName);
assert.deepStrictEqual(did.network(), networkName);
assert.deepStrictEqual(did.authority(), IotaDID.METHOD + ":" + networkName + ":" + aliasIdHex);
assert.deepStrictEqual(did.methodId(), networkName + ":" + aliasIdHex);
assert.deepStrictEqual(did.scheme(), "did");
Expand All @@ -68,7 +68,7 @@ describe("IotaDID", function() {
assert.deepStrictEqual(did.toString(), "did:" + IotaDID.METHOD + ":" + networkName + ":" + expectedTag);
assert.deepStrictEqual(did.tag(), expectedTag);
assert.deepStrictEqual(did.method(), IotaDID.METHOD);
assert.deepStrictEqual(did.networkStr(), networkName);
assert.deepStrictEqual(did.network(), networkName);
assert.deepStrictEqual(did.authority(), IotaDID.METHOD + ":" + networkName + ":" + expectedTag);
assert.deepStrictEqual(did.methodId(), networkName + ":" + expectedTag);
assert.deepStrictEqual(did.scheme(), "did");
Expand Down
74 changes: 41 additions & 33 deletions identity_document/src/document/core_document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -437,14 +437,14 @@ impl CoreDocument {
Ok(())
}

/// Removes and returns the [`VerificationMethod`] from the document.
/// Removes and returns the [`VerificationMethod`] identified by `did_url` from the document.
///
/// # Note
///
/// All _references to the method_ found in the document will be removed.
/// This includes cases where the reference is to a method contained in another DID document.
pub fn remove_method(&mut self, did: &DIDUrl) -> Option<VerificationMethod> {
self.remove_method_and_scope(did).map(|(method, _scope)| method)
pub fn remove_method(&mut self, did_url: &DIDUrl) -> Option<VerificationMethod> {
self.remove_method_and_scope(did_url).map(|(method, _scope)| method)
}

/// Removes and returns the [`VerificationMethod`] from the document. The [`MethodScope`] under which the method was
Expand All @@ -454,33 +454,33 @@ impl CoreDocument {
///
/// All _references to the method_ found in the document will be removed.
/// This includes cases where the reference is to a method contained in another DID document.
pub fn remove_method_and_scope(&mut self, did: &DIDUrl) -> Option<(VerificationMethod, MethodScope)> {
pub fn remove_method_and_scope(&mut self, did_url: &DIDUrl) -> Option<(VerificationMethod, MethodScope)> {
for (method_ref, scope) in [
self.data.authentication.remove(did).map(|method_ref| {
self.data.authentication.remove(did_url).map(|method_ref| {
(
method_ref,
MethodScope::VerificationRelationship(MethodRelationship::Authentication),
)
}),
self.data.assertion_method.remove(did).map(|method_ref| {
self.data.assertion_method.remove(did_url).map(|method_ref| {
(
method_ref,
MethodScope::VerificationRelationship(MethodRelationship::AssertionMethod),
)
}),
self.data.key_agreement.remove(did).map(|method_ref| {
self.data.key_agreement.remove(did_url).map(|method_ref| {
(
method_ref,
MethodScope::VerificationRelationship(MethodRelationship::KeyAgreement),
)
}),
self.data.capability_delegation.remove(did).map(|method_ref| {
self.data.capability_delegation.remove(did_url).map(|method_ref| {
(
method_ref,
MethodScope::VerificationRelationship(MethodRelationship::CapabilityDelegation),
)
}),
self.data.capability_invocation.remove(did).map(|method_ref| {
self.data.capability_invocation.remove(did_url).map(|method_ref| {
(
method_ref,
MethodScope::VerificationRelationship(MethodRelationship::CapabilityInvocation),
Expand All @@ -500,7 +500,7 @@ impl CoreDocument {
self
.data
.verification_method
.remove(did)
.remove(did_url)
.map(|method| (method, MethodScope::VerificationMethod))
}

Expand All @@ -526,6 +526,7 @@ impl CoreDocument {
pub fn remove_service(&mut self, id: &DIDUrl) -> Option<Service> {
self.data.service.remove(id)
}

/// Attaches the relationship to the method resolved by `method_query`.
///
/// # Errors
Expand Down Expand Up @@ -565,6 +566,7 @@ impl CoreDocument {
}

/// Detaches the relationship from the method resolved by `method_query`.
/// Returns `true` if the relationship was found and removed, `false` otherwise.
///
/// # Errors
///
Expand Down Expand Up @@ -680,10 +682,14 @@ impl CoreDocument {
}

/// Returns the first [`VerificationMethod`] with an `id` property matching the
/// provided `query` and the verification relationship specified by `scope` if present.
/// provided `method_query` and the verification relationship specified by `scope` if present.
// NOTE: This method demonstrates unexpected behaviour in the edge cases where the document contains methods
// whose ids are of the form <did different from this document's>#<fragment>.
pub fn resolve_method<'query, 'me, Q>(&'me self, query: Q, scope: Option<MethodScope>) -> Option<&VerificationMethod>
pub fn resolve_method<'query, 'me, Q>(
&'me self,
method_query: Q,
scope: Option<MethodScope>,
) -> Option<&VerificationMethod>
where
Q: Into<DIDUrlQuery<'query>>,
{
Expand All @@ -692,38 +698,40 @@ impl CoreDocument {
let resolve_ref_helper = |method_ref: &'me MethodRef| self.resolve_method_ref(method_ref);

match scope {
MethodScope::VerificationMethod => self.data.verification_method.query(query.into()),
MethodScope::VerificationMethod => self.data.verification_method.query(method_query.into()),
MethodScope::VerificationRelationship(MethodRelationship::Authentication) => self
.data
.authentication
.query(query.into())
.query(method_query.into())
.and_then(resolve_ref_helper),
MethodScope::VerificationRelationship(MethodRelationship::AssertionMethod) => self
.data
.assertion_method
.query(query.into())
.query(method_query.into())
.and_then(resolve_ref_helper),
MethodScope::VerificationRelationship(MethodRelationship::KeyAgreement) => self
.data
.key_agreement
.query(method_query.into())
.and_then(resolve_ref_helper),
MethodScope::VerificationRelationship(MethodRelationship::KeyAgreement) => {
self.data.key_agreement.query(query.into()).and_then(resolve_ref_helper)
}
MethodScope::VerificationRelationship(MethodRelationship::CapabilityDelegation) => self
.data
.capability_delegation
.query(query.into())
.query(method_query.into())
.and_then(resolve_ref_helper),
MethodScope::VerificationRelationship(MethodRelationship::CapabilityInvocation) => self
.data
.capability_invocation
.query(query.into())
.query(method_query.into())
.and_then(resolve_ref_helper),
}
}
None => self.resolve_method_inner(query.into()),
None => self.resolve_method_inner(method_query.into()),
}
}

/// Returns a mutable reference to the first [`VerificationMethod`] with an `id` property
/// matching the provided `query`.
/// matching the provided `method_query`.
///
/// # Warning
///
Expand All @@ -732,43 +740,43 @@ impl CoreDocument {
// whose ids are of the form <did different from this document's>#<fragment>.
pub fn resolve_method_mut<'query, 'me, Q>(
&'me mut self,
query: Q,
method_query: Q,
scope: Option<MethodScope>,
) -> Option<&'me mut VerificationMethod>
where
Q: Into<DIDUrlQuery<'query>>,
{
match scope {
Some(scope) => match scope {
MethodScope::VerificationMethod => self.data.verification_method.query_mut(query.into()),
MethodScope::VerificationMethod => self.data.verification_method.query_mut(method_query.into()),
MethodScope::VerificationRelationship(MethodRelationship::Authentication) => {
method_ref_mut_helper!(self, authentication, query)
method_ref_mut_helper!(self, authentication, method_query)
}
MethodScope::VerificationRelationship(MethodRelationship::AssertionMethod) => {
method_ref_mut_helper!(self, assertion_method, query)
method_ref_mut_helper!(self, assertion_method, method_query)
}
MethodScope::VerificationRelationship(MethodRelationship::KeyAgreement) => {
method_ref_mut_helper!(self, key_agreement, query)
method_ref_mut_helper!(self, key_agreement, method_query)
}
MethodScope::VerificationRelationship(MethodRelationship::CapabilityDelegation) => {
method_ref_mut_helper!(self, capability_delegation, query)
method_ref_mut_helper!(self, capability_delegation, method_query)
}
MethodScope::VerificationRelationship(MethodRelationship::CapabilityInvocation) => {
method_ref_mut_helper!(self, capability_invocation, query)
method_ref_mut_helper!(self, capability_invocation, method_query)
}
},
None => self.resolve_method_mut_inner(query.into()),
None => self.resolve_method_mut_inner(method_query.into()),
}
}

/// Returns the first [`Service`] with an `id` property matching the provided `query`, if present.
/// Returns the first [`Service`] with an `id` property matching the provided `service_query`, if present.
// NOTE: This method demonstrates unexpected behaviour in the edge cases where the document contains
// services whose ids are of the form <did different from this document's>#<fragment>.
pub fn resolve_service<'query, 'me, Q>(&'me self, query: Q) -> Option<&Service>
pub fn resolve_service<'query, 'me, Q>(&'me self, service_query: Q) -> Option<&Service>
where
Q: Into<DIDUrlQuery<'query>>,
{
self.service().query(query.into())
self.service().query(service_query.into())
}

#[doc(hidden)]
Expand Down
2 changes: 1 addition & 1 deletion identity_iota_core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ description = "An IOTA Ledger integration for the IOTA DID Method."

[dependencies]
async-trait = { version = "0.1.56", default-features = false, optional = true }
futures = { version = "0.3" }
futures = { version = "0.3", default-features = false }
identity_core = { version = "=0.7.0-alpha.6", path = "../identity_core", default-features = false }
identity_credential = { version = "=0.7.0-alpha.6", path = "../identity_credential", default-features = false, features = ["validator"] }
identity_did = { version = "=0.7.0-alpha.6", path = "../identity_did", default-features = false }
Expand Down
2 changes: 1 addition & 1 deletion identity_iota_core/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
IOTA Identity
===

This crate provides the core data structures for the [IOTA DID Method Specification](https://wiki.iota.org/identity.rs/specs/did/iota_did_method_spec). It provides interfaces for publishing and resolving DID Documents to and from the Tangle according to the IOTA DID Method Specification.
This crate provides the core data structures for the [IOTA DID Method Specification](https://wiki.iota.org/shimmer/identity.rs/specs/did/iota_did_method_spec). It provides interfaces for publishing and resolving DID Documents to and from the Tangle according to the IOTA DID Method Specification.
5 changes: 2 additions & 3 deletions identity_iota_core/src/client/identity_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ pub trait IotaIdentityClient {
///
/// This trait is not intended to be implemented directly, a blanket implementation is
/// provided for [`IotaIdentityClient`] implementers.

#[cfg_attr(feature = "send-sync-client-ext", async_trait::async_trait)]
#[cfg_attr(not(feature = "send-sync-client-ext"), async_trait::async_trait(?Send))]
pub trait IotaIdentityClientExt: IotaIdentityClient {
Expand All @@ -46,7 +45,7 @@ pub trait IotaIdentityClientExt: IotaIdentityClient {
/// `rent_structure`, which will be fetched from the node if not provided.
/// The returned Alias Output can be further customised before publication, if desired.
///
/// NOTE: this does *not* publish the Alias Output.
/// NOTE: This does *not* publish the Alias Output.
///
/// # Errors
///
Expand Down Expand Up @@ -83,7 +82,7 @@ pub trait IotaIdentityClientExt: IotaIdentityClient {
/// The storage deposit on the output is left unchanged. If the size of the document increased,
/// the amount should be increased manually.
///
/// NOTE: this does *not* publish the updated Alias Output.
/// NOTE: This does *not* publish the updated Alias Output.
///
/// # Errors
///
Expand Down
2 changes: 0 additions & 2 deletions identity_iota_core/src/client/iota_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,6 @@ pub trait IotaClientExt: IotaIdentityClient {
async fn delete_did_output(&self, secret_manager: &SecretManager, address: Address, did: &IotaDID) -> Result<()>;
}

/// An extension trait for [`Client`] that provides helper functions for publication
/// and deletion of DID documents in Alias Outputs.
#[cfg_attr(feature = "send-sync-client-ext", async_trait::async_trait)]
#[cfg_attr(not(feature = "send-sync-client-ext"), async_trait::async_trait(?Send))]
impl IotaClientExt for Client {
Expand Down
Loading

0 comments on commit 5eabeff

Please sign in to comment.