From 34bb77adcb03cf1f775b2a5aec8cfdadb814906d Mon Sep 17 00:00:00 2001 From: Henrique Nogara Date: Mon, 14 Mar 2022 09:45:48 -0300 Subject: [PATCH] Add `identity-iota-core`, `identity-account-storage` crates (#693) * split iota-identity - add iota-identity-core * fix tests, fix doc tests, fix imports in indentity-account * add default impl for coredoc, remove doc clone from resolver * fix wasm imports * move bee_message::message to iota_core * add set_previous_message_id and set_message_id for DiffMessage, move tangle ref back to identity-iota * split identity-account, add identity-account-core * move MessageId back to identity-iota * remove old error variants * remove nodejs bindings * fix tom fmt, tests * add default features false * change network import * Replace iota-client dependency with bee-message in identity-iota-core * Combine message and types modules into tangle * Remove unnecessary clone * Improve identity-iota-core errors * Fix Wasm compilation * Fix Wasm bindings * Remove dead code * Fix bee-message features * Remove dead code * Feature-gate stronghold * Make tokio optional in identity-account-storage Co-authored-by: Craig Bester --- Cargo.toml | 2 + bindings/wasm/docs/api-reference.md | 44 ++++++++++++++ bindings/wasm/src/chain/document_history.rs | 2 +- bindings/wasm/src/did/wasm_did.rs | 2 +- bindings/wasm/src/did/wasm_did_url.rs | 2 +- bindings/wasm/src/did/wasm_diff_message.rs | 13 ++-- bindings/wasm/src/did/wasm_document.rs | 24 +++++--- .../wasm/src/did/wasm_document_metadata.rs | 7 +-- .../wasm/src/did/wasm_resolved_document.rs | 10 +++- bindings/wasm/src/did/wasm_service.rs | 4 +- .../wasm/src/did/wasm_verification_method.rs | 4 +- bindings/wasm/src/error.rs | 10 +--- bindings/wasm/src/tangle/client.rs | 12 ++-- bindings/wasm/src/tangle/client_config.rs | 4 +- bindings/wasm/src/tangle/explorer.rs | 8 ++- bindings/wasm/src/tangle/network.rs | 2 +- bindings/wasm/src/tangle/resolver.rs | 4 +- bindings/wasm/tests/wasm.rs | 20 +++---- examples/Cargo.toml | 2 +- examples/account/config.rs | 4 +- examples/account/create_did.rs | 2 +- examples/account/lazy.rs | 2 +- examples/account/manipulate_did.rs | 2 +- examples/account/multiple_identities.rs | 2 +- examples/account/signing.rs | 2 +- examples/account/unchecked.rs | 2 +- examples/low-level-api/common.rs | 5 +- examples/low-level-api/diff_chain.rs | 4 +- examples/low-level-api/manipulate_did.rs | 4 +- examples/low-level-api/merkle_key.rs | 17 +++--- examples/low-level-api/private_tangle.rs | 2 +- examples/low-level-api/resolution.rs | 4 +- examples/low-level-api/resolve_history.rs | 8 +-- examples/low-level-api/revoke_vc.rs | 2 +- identity-account-storage/Cargo.toml | 56 +++++++++++++++++ .../src/crypto/mod.rs | 2 +- .../src/crypto/remote.rs | 4 +- identity-account-storage/src/error.rs | 60 +++++++++++++++++++ .../src/identity/chain_state.rs | 8 +-- .../src/identity/identity_state.rs | 12 ++-- identity-account-storage/src/identity/mod.rs | 8 +++ identity-account-storage/src/lib.rs | 28 +++++++++ .../src/storage/memstore.rs | 4 +- .../src/storage/mod.rs | 2 +- .../src/storage/stronghold.rs | 2 +- .../src/storage/traits.rs | 4 +- .../src/stronghold/context.rs | 0 .../src/stronghold/error.rs | 9 ++- .../src/stronghold/hint.rs | 0 .../src/stronghold/mod.rs | 2 +- .../src/stronghold/records.rs | 4 +- .../src/stronghold/snapshot.rs | 0 .../src/stronghold/status.rs | 0 .../src/stronghold/store.rs | 0 .../src/stronghold/tests.rs | 2 +- .../src/stronghold/vault.rs | 0 .../src/types/generation.rs | 5 +- .../src/types/key_location.rs | 4 +- identity-account-storage/src/types/mod.rs | 10 ++++ .../src/types/signature.rs | 2 +- .../src/utils/crypto.rs | 2 +- .../src/utils/fs.rs | 2 +- .../src/utils/mod.rs | 2 +- .../src/utils/shared.rs | 6 +- identity-account/Cargo.toml | 37 +++--------- identity-account/src/account/account.rs | 23 ++++--- identity-account/src/account/builder.rs | 17 +++--- identity-account/src/account/config.rs | 3 +- identity-account/src/error.rs | 36 ++--------- identity-account/src/identity/mod.rs | 4 -- identity-account/src/lib.rs | 12 ---- identity-account/src/tests/account.rs | 25 ++++---- identity-account/src/tests/updates.rs | 20 ++++--- identity-account/src/types/mod.rs | 6 -- identity-account/src/updates/error.rs | 5 +- identity-account/src/updates/update.rs | 27 +++++---- identity-iota-core/Cargo.toml | 31 ++++++++++ identity-iota-core/README.md | 1 + .../src/did/iota_did.rs | 4 +- .../src/did/macros.rs | 6 +- .../src/did/mod.rs | 2 +- .../src/did/segments.rs | 2 +- .../src/diff/diff_iota_did.rs | 0 .../src/diff/diff_iota_document.rs | 0 .../src/diff/diff_iota_document_metadata.rs | 9 ++- .../src/diff/diff_message.rs | 40 +++++-------- .../src/diff/mod.rs | 0 .../src/document/iota_document.rs | 27 +++++---- .../src/document/iota_document_metadata.rs | 7 +-- identity-iota-core/src/document/mod.rs | 11 ++++ identity-iota-core/src/error.rs | 29 +++++++++ identity-iota-core/src/lib.rs | 28 +++++++++ identity-iota-core/src/tangle/message_id.rs | 39 ++++++++++++ identity-iota-core/src/tangle/mod.rs | 12 ++++ .../src/tangle/network.rs | 0 identity-iota/Cargo.toml | 5 +- identity-iota/src/chain/diff_chain.rs | 31 +++++----- identity-iota/src/chain/document_chain.rs | 15 +++-- identity-iota/src/chain/document_history.rs | 12 ++-- identity-iota/src/chain/integration_chain.rs | 16 +++-- identity-iota/src/chain/milestone.rs | 4 +- .../src/credential/credential_validator.rs | 21 +++---- .../src/credential/presentation_validator.rs | 12 ++-- identity-iota/src/credential/test_utils.rs | 6 +- identity-iota/src/document/mod.rs | 7 --- .../src/document/resolved_iota_document.rs | 15 +++-- identity-iota/src/error.rs | 20 +------ identity-iota/src/lib.rs | 2 - identity-iota/src/resolver.rs | 10 +++- identity-iota/src/tangle/client.rs | 17 +++--- identity-iota/src/tangle/client_builder.rs | 6 +- identity-iota/src/tangle/explorer.rs | 13 ++-- .../src/tangle/message/compression_brotli.rs | 3 +- .../src/tangle/message/message_ext.rs | 45 +++----------- .../src/tangle/message/message_index.rs | 7 ++- identity-iota/src/tangle/message/mod.rs | 1 - identity-iota/src/tangle/mod.rs | 12 ---- identity-iota/src/tangle/publish.rs | 10 ++-- identity-iota/src/tangle/receipt.rs | 8 +-- identity-iota/src/tangle/resolver.rs | 6 +- identity-iota/src/tangle/traits.rs | 29 ++++++++- identity/Cargo.toml | 13 ++-- identity/benches/benchmark.rs | 4 +- identity/benches/diff_chain.rs | 8 +-- identity/src/lib.rs | 35 ++++++++--- 125 files changed, 805 insertions(+), 529 deletions(-) create mode 100644 identity-account-storage/Cargo.toml rename {identity-account => identity-account-storage}/src/crypto/mod.rs (67%) rename {identity-account => identity-account-storage}/src/crypto/remote.rs (97%) create mode 100644 identity-account-storage/src/error.rs rename {identity-account => identity-account-storage}/src/identity/chain_state.rs (92%) rename {identity-account => identity-account-storage}/src/identity/identity_state.rs (95%) create mode 100644 identity-account-storage/src/identity/mod.rs create mode 100644 identity-account-storage/src/lib.rs rename {identity-account => identity-account-storage}/src/storage/memstore.rs (98%) rename {identity-account => identity-account-storage}/src/storage/mod.rs (85%) rename {identity-account => identity-account-storage}/src/storage/stronghold.rs (99%) rename {identity-account => identity-account-storage}/src/storage/traits.rs (98%) rename {identity-account => identity-account-storage}/src/stronghold/context.rs (100%) rename {identity-account => identity-account-storage}/src/stronghold/error.rs (93%) rename {identity-account => identity-account-storage}/src/stronghold/hint.rs (100%) rename {identity-account => identity-account-storage}/src/stronghold/mod.rs (90%) rename {identity-account => identity-account-storage}/src/stronghold/records.rs (98%) rename {identity-account => identity-account-storage}/src/stronghold/snapshot.rs (100%) rename {identity-account => identity-account-storage}/src/stronghold/status.rs (100%) rename {identity-account => identity-account-storage}/src/stronghold/store.rs (100%) rename {identity-account => identity-account-storage}/src/stronghold/tests.rs (99%) rename {identity-account => identity-account-storage}/src/stronghold/vault.rs (100%) rename {identity-account => identity-account-storage}/src/types/generation.rs (95%) rename {identity-account => identity-account-storage}/src/types/key_location.rs (94%) create mode 100644 identity-account-storage/src/types/mod.rs rename {identity-account => identity-account-storage}/src/types/signature.rs (94%) rename {identity-account => identity-account-storage}/src/utils/crypto.rs (92%) rename {identity-account => identity-account-storage}/src/utils/fs.rs (88%) rename {identity-account => identity-account-storage}/src/utils/mod.rs (77%) rename {identity-account => identity-account-storage}/src/utils/shared.rs (90%) create mode 100644 identity-iota-core/Cargo.toml create mode 100644 identity-iota-core/README.md rename {identity-iota => identity-iota-core}/src/did/iota_did.rs (99%) rename {identity-iota => identity-iota-core}/src/did/macros.rs (89%) rename {identity-iota => identity-iota-core}/src/did/mod.rs (83%) rename {identity-iota => identity-iota-core}/src/did/segments.rs (97%) rename {identity-iota => identity-iota-core}/src/diff/diff_iota_did.rs (100%) rename {identity-iota => identity-iota-core}/src/diff/diff_iota_document.rs (100%) rename {identity-iota => identity-iota-core}/src/diff/diff_iota_document_metadata.rs (99%) rename {identity-iota => identity-iota-core}/src/diff/diff_message.rs (88%) rename {identity-iota => identity-iota-core}/src/diff/mod.rs (100%) rename {identity-iota => identity-iota-core}/src/document/iota_document.rs (98%) rename {identity-iota => identity-iota-core}/src/document/iota_document_metadata.rs (96%) create mode 100644 identity-iota-core/src/document/mod.rs create mode 100644 identity-iota-core/src/error.rs create mode 100644 identity-iota-core/src/lib.rs create mode 100644 identity-iota-core/src/tangle/message_id.rs create mode 100644 identity-iota-core/src/tangle/mod.rs rename {identity-iota => identity-iota-core}/src/tangle/network.rs (100%) diff --git a/Cargo.toml b/Cargo.toml index 54e3ace491..1564d0b248 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,11 +4,13 @@ members = [ "identity", "identity-comm", "identity-account", + "identity-account-storage", "identity-core", "identity-credential", "identity-did", "identity-diff", "identity-iota", + "identity-iota-core", "examples", ] diff --git a/bindings/wasm/docs/api-reference.md b/bindings/wasm/docs/api-reference.md index 43bc517b31..a21dcd47b4 100644 --- a/bindings/wasm/docs/api-reference.md +++ b/bindings/wasm/docs/api-reference.md @@ -285,6 +285,8 @@ Serializes a `Credential` object as a JSON object. ### credential.clone() ⇒ [Credential](#Credential) +Deep clones the object. + **Kind**: instance method of [Credential](#Credential) @@ -355,6 +357,8 @@ Serializes a `CredentialValidationOptions` as a JSON object. ### credentialValidationOptions.clone() ⇒ [CredentialValidationOptions](#CredentialValidationOptions) +Deep clones the object. + **Kind**: instance method of [CredentialValidationOptions](#CredentialValidationOptions) @@ -583,6 +587,8 @@ Serializes a `DID` as a JSON object. ### did.clone() ⇒ [DID](#DID) +Deep clones the object. + **Kind**: instance method of [DID](#DID) @@ -728,6 +734,8 @@ Serializes a `DIDUrl` as a JSON object. ### didUrl.clone() ⇒ [DIDUrl](#DIDUrl) +Deep clones the object. + **Kind**: instance method of [DIDUrl](#DIDUrl) @@ -892,6 +900,8 @@ Serializes a `DiffMessage` as a JSON object. ### diffMessage.clone() ⇒ [DiffMessage](#DiffMessage) +Deep clones the object. + **Kind**: instance method of [DiffMessage](#DiffMessage) @@ -1419,6 +1429,8 @@ Serializes a `Document` as a JSON object. ### document.clone() ⇒ [Document](#Document) +Deep clones the object. + **Kind**: instance method of [Document](#Document) @@ -1545,6 +1557,8 @@ Serializes `DocumentHistory` as a JSON object. ### documentHistory.clone() ⇒ [DocumentHistory](#DocumentHistory) +Deep clones the object. + **Kind**: instance method of [DocumentHistory](#DocumentHistory) @@ -1596,6 +1610,8 @@ Returns a reference to the `proof`. ### documentMetadata.clone() ⇒ [DocumentMetadata](#DocumentMetadata) +Deep clones the object. + **Kind**: instance method of [DocumentMetadata](#DocumentMetadata) @@ -1887,6 +1903,8 @@ Serializes a `KeyCollection` object as a JSON object. ### keyCollection.clone() ⇒ [KeyCollection](#KeyCollection) +Deep clones the object. + **Kind**: instance method of [KeyCollection](#KeyCollection) @@ -1953,6 +1971,8 @@ Serializes a `KeyPair` object as a JSON object. ### keyPair.clone() ⇒ [KeyPair](#KeyPair) +Deep clones the object. + **Kind**: instance method of [KeyPair](#KeyPair) @@ -2014,6 +2034,8 @@ Serializes a `MethodScope` object as a JSON object. ### methodScope.clone() ⇒ [MethodScope](#MethodScope) +Deep clones the object. + **Kind**: instance method of [MethodScope](#MethodScope) @@ -2075,6 +2097,8 @@ Serializes a `MethodType` object as a JSON object. ### methodType.clone() ⇒ [MethodType](#MethodType) +Deep clones the object. + **Kind**: instance method of [MethodType](#MethodType) @@ -2136,6 +2160,8 @@ Serializes a `Network` as a JSON object. ### network.clone() ⇒ [Network](#Network) +Deep clones the object. + **Kind**: instance method of [Network](#Network) @@ -2209,6 +2235,8 @@ Returns a copy of the credentials contained in the presentation. ### presentation.clone() ⇒ [Presentation](#Presentation) +Deep clones the object. + **Kind**: instance method of [Presentation](#Presentation) @@ -2258,6 +2286,8 @@ Serializes a `PresentationValidationOptions` as a JSON object. ### presentationValidationOptions.clone() ⇒ [PresentationValidationOptions](#PresentationValidationOptions) +Deep clones the object. + **Kind**: instance method of [PresentationValidationOptions](#PresentationValidationOptions) @@ -2384,6 +2414,8 @@ Serializes a `ProofPurpose` object as a JSON object. ### proofPurpose.clone() ⇒ [ProofPurpose](#ProofPurpose) +Deep clones the object. + **Kind**: instance method of [ProofPurpose](#ProofPurpose) @@ -2459,6 +2491,8 @@ Serializes a `Receipt` as a JSON object. ### receipt.clone() ⇒ [Receipt](#Receipt) +Deep clones the object. + **Kind**: instance method of [Receipt](#Receipt) @@ -2573,6 +2607,8 @@ Serializes a `Document` object as a JSON object. ### resolvedDocument.clone() ⇒ [ResolvedDocument](#ResolvedDocument) +Deep clones the object. + **Kind**: instance method of [ResolvedDocument](#ResolvedDocument) @@ -2852,6 +2888,8 @@ Serializes a `Service` object as a JSON object. ### service.clone() ⇒ [Service](#Service) +Deep clones the object. + **Kind**: instance method of [Service](#Service) @@ -2894,6 +2932,8 @@ Throws an error if any of the options are invalid. ### signatureOptions.clone() ⇒ [SignatureOptions](#SignatureOptions) +Deep clones the object. + **Kind**: instance method of [SignatureOptions](#SignatureOptions) @@ -3060,6 +3100,8 @@ Serializes a `VerificationMethod` object as a JSON object. ### verificationMethod.clone() ⇒ [VerificationMethod](#VerificationMethod) +Deep clones the object. + **Kind**: instance method of [VerificationMethod](#VerificationMethod) @@ -3124,6 +3166,8 @@ Serializes a `VerifierOptions` as a JSON object. ### verifierOptions.clone() ⇒ [VerifierOptions](#VerifierOptions) +Deep clones the object. + **Kind**: instance method of [VerifierOptions](#VerifierOptions) diff --git a/bindings/wasm/src/chain/document_history.rs b/bindings/wasm/src/chain/document_history.rs index 72673af492..3831b52bc6 100644 --- a/bindings/wasm/src/chain/document_history.rs +++ b/bindings/wasm/src/chain/document_history.rs @@ -2,9 +2,9 @@ // SPDX-License-Identifier: Apache-2.0 use identity::iota::ChainHistory; -use identity::iota::DiffMessage; use identity::iota::DocumentHistory; use identity::iota::ResolvedIotaDocument; +use identity::iota_core::DiffMessage; use wasm_bindgen::prelude::*; use wasm_bindgen::JsCast; diff --git a/bindings/wasm/src/did/wasm_did.rs b/bindings/wasm/src/did/wasm_did.rs index d1e899ef74..59d1a1e408 100644 --- a/bindings/wasm/src/did/wasm_did.rs +++ b/bindings/wasm/src/did/wasm_did.rs @@ -3,7 +3,7 @@ use identity::core::decode_b58; use identity::did::DID; -use identity::iota::IotaDID; +use identity::iota_core::IotaDID; use wasm_bindgen::prelude::*; use crate::crypto::WasmKeyPair; diff --git a/bindings/wasm/src/did/wasm_did_url.rs b/bindings/wasm/src/did/wasm_did_url.rs index e3eb910945..153aad7c09 100644 --- a/bindings/wasm/src/did/wasm_did_url.rs +++ b/bindings/wasm/src/did/wasm_did_url.rs @@ -1,7 +1,7 @@ // Copyright 2020-2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -use identity::iota::IotaDIDUrl; +use identity::iota_core::IotaDIDUrl; use wasm_bindgen::prelude::*; use crate::did::WasmDID; diff --git a/bindings/wasm/src/did/wasm_diff_message.rs b/bindings/wasm/src/did/wasm_diff_message.rs index a3693a9319..b7a94e646e 100644 --- a/bindings/wasm/src/did/wasm_diff_message.rs +++ b/bindings/wasm/src/did/wasm_diff_message.rs @@ -4,9 +4,8 @@ use std::str::FromStr; use identity::core::ToJson; -use identity::iota::DiffMessage; -use identity::iota::MessageId; -use identity::iota::TangleRef; +use identity::iota_core::DiffMessage; +use identity::iota_core::MessageId; use wasm_bindgen::prelude::*; use crate::did::WasmDID; @@ -51,7 +50,9 @@ impl WasmDiffMessage { /// Sets the message_id of the DID Document diff. #[wasm_bindgen(setter = messageId)] pub fn set_message_id(&mut self, message_id: &str) -> Result<()> { - let message_id: MessageId = MessageId::from_str(message_id).wasm_result()?; + let message_id: MessageId = MessageId::from_str(message_id) + .map_err(identity::iota_core::Error::InvalidMessage) + .wasm_result()?; self.0.set_message_id(message_id); Ok(()) } @@ -65,7 +66,9 @@ impl WasmDiffMessage { /// Sets the Tangle message id of the previous DID Document diff. #[wasm_bindgen(setter = previousMessageId)] pub fn set_previous_message_id(&mut self, message_id: &str) -> Result<()> { - let previous_message_id: MessageId = MessageId::from_str(message_id).wasm_result()?; + let previous_message_id: MessageId = MessageId::from_str(message_id) + .map_err(identity::iota_core::Error::InvalidMessage) + .wasm_result()?; self.0.set_previous_message_id(previous_message_id); Ok(()) } diff --git a/bindings/wasm/src/did/wasm_document.rs b/bindings/wasm/src/did/wasm_document.rs index 6432c53ac7..06c86760f8 100644 --- a/bindings/wasm/src/did/wasm_document.rs +++ b/bindings/wasm/src/did/wasm_document.rs @@ -17,12 +17,12 @@ use identity::crypto::PublicKey; use identity::crypto::SignatureOptions; use identity::did::verifiable::VerifiableProperties; use identity::did::MethodScope; -use identity::iota::Error; -use identity::iota::IotaDID; -use identity::iota::IotaDocument; -use identity::iota::IotaVerificationMethod; -use identity::iota::MessageId; -use identity::iota::NetworkName; +use identity::iota_core::Error; +use identity::iota_core::IotaDID; +use identity::iota_core::IotaDocument; +use identity::iota_core::IotaVerificationMethod; +use identity::iota_core::MessageId; +use identity::iota_core::NetworkName; use wasm_bindgen::prelude::*; use crate::common::WasmTimestamp; @@ -537,7 +537,9 @@ impl WasmDocument { .0 .diff( &other.0, - MessageId::from_str(message_id).wasm_result()?, + MessageId::from_str(message_id) + .map_err(identity::iota_core::Error::InvalidMessage) + .wasm_result()?, key.0.private(), &method_query, ) @@ -583,7 +585,9 @@ impl WasmDocument { /// This is the Base58-btc encoded SHA-256 digest of the hex-encoded message id. #[wasm_bindgen(js_name = diffIndex)] pub fn diff_index(message_id: &str) -> Result { - let message_id = MessageId::from_str(message_id).wasm_result()?; + let message_id = MessageId::from_str(message_id) + .map_err(identity::iota_core::Error::InvalidMessage) + .wasm_result()?; IotaDocument::diff_index(&message_id).wasm_result() } @@ -633,7 +637,9 @@ impl WasmDocument { /// Sets the previous integration chain message id. #[wasm_bindgen(setter = metadataPreviousMessageId)] pub fn set_metadata_previous_message_id(&mut self, value: &str) -> Result<()> { - let message_id: MessageId = MessageId::from_str(value).wasm_result()?; + let message_id: MessageId = MessageId::from_str(value) + .map_err(identity::iota_core::Error::InvalidMessage) + .wasm_result()?; self.0.metadata.previous_message_id = message_id; Ok(()) } diff --git a/bindings/wasm/src/did/wasm_document_metadata.rs b/bindings/wasm/src/did/wasm_document_metadata.rs index a62f99f4c0..587e6dc09b 100644 --- a/bindings/wasm/src/did/wasm_document_metadata.rs +++ b/bindings/wasm/src/did/wasm_document_metadata.rs @@ -1,11 +1,10 @@ -// Copyright 2020-2021 IOTA Stiftung +// Copyright 2020-2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -use identity::iota::IotaDocumentMetadata; - -use crate::common::WasmTimestamp; +use identity::iota_core::IotaDocumentMetadata; use wasm_bindgen::prelude::*; +use crate::common::WasmTimestamp; use crate::error::Result; use crate::error::WasmResult; diff --git a/bindings/wasm/src/did/wasm_resolved_document.rs b/bindings/wasm/src/did/wasm_resolved_document.rs index 58e9240622..2f1a6c6f0c 100644 --- a/bindings/wasm/src/did/wasm_resolved_document.rs +++ b/bindings/wasm/src/did/wasm_resolved_document.rs @@ -1,8 +1,8 @@ // Copyright 2020-2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -use identity::iota::MessageId; use identity::iota::ResolvedIotaDocument; +use identity::iota_core::MessageId; use std::str::FromStr; use crate::did::WasmDiffMessage; @@ -86,7 +86,9 @@ impl WasmResolvedDocument { /// Sets the diff chain message id. #[wasm_bindgen(setter = diffMessageId)] pub fn set_diff_message_id(&mut self, value: &str) -> Result<()> { - let message_id: MessageId = MessageId::from_str(value).wasm_result()?; + let message_id: MessageId = MessageId::from_str(value) + .map_err(identity::iota_core::Error::InvalidMessage) + .wasm_result()?; self.0.diff_message_id = message_id; Ok(()) } @@ -100,7 +102,9 @@ impl WasmResolvedDocument { /// Sets the integration chain message id. #[wasm_bindgen(setter = integrationMessageId)] pub fn set_integration_message_id(&mut self, value: &str) -> Result<()> { - let message_id: MessageId = MessageId::from_str(value).wasm_result()?; + let message_id: MessageId = MessageId::from_str(value) + .map_err(identity::iota_core::Error::InvalidMessage) + .wasm_result()?; self.0.integration_message_id = message_id; Ok(()) } diff --git a/bindings/wasm/src/did/wasm_service.rs b/bindings/wasm/src/did/wasm_service.rs index 2611b3127f..3f39366005 100644 --- a/bindings/wasm/src/did/wasm_service.rs +++ b/bindings/wasm/src/did/wasm_service.rs @@ -2,8 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 use identity::did::ServiceEndpoint; -use identity::iota::IotaDIDUrl; -use identity::iota::IotaService; +use identity::iota_core::IotaDIDUrl; +use identity::iota_core::IotaService; use wasm_bindgen::prelude::*; use wasm_bindgen::JsCast; diff --git a/bindings/wasm/src/did/wasm_verification_method.rs b/bindings/wasm/src/did/wasm_verification_method.rs index e5419e02a8..ebbb18ea9f 100644 --- a/bindings/wasm/src/did/wasm_verification_method.rs +++ b/bindings/wasm/src/did/wasm_verification_method.rs @@ -5,8 +5,8 @@ use identity::core::decode_b58; use identity::crypto::merkle_key::Blake2b256; use identity::crypto::merkle_key::Sha256; use identity::crypto::PublicKey; -use identity::iota::IotaDID; -use identity::iota::IotaVerificationMethod; +use identity::iota_core::IotaDID; +use identity::iota_core::IotaVerificationMethod; use wasm_bindgen::prelude::*; use crate::crypto::Digest; diff --git a/bindings/wasm/src/error.rs b/bindings/wasm/src/error.rs index 9c1697775c..b41c4edfec 100644 --- a/bindings/wasm/src/error.rs +++ b/bindings/wasm/src/error.rs @@ -91,6 +91,7 @@ impl_wasm_error_from!( identity::credential::Error, identity::did::Error, identity::did::DIDError, + identity::iota_core::Error, identity::iota::ValidationError ); @@ -171,15 +172,6 @@ impl From for WasmError<'_> { } } -impl From for WasmError<'_> { - fn from(error: identity::iota::BeeMessageError) -> Self { - Self { - name: Cow::Borrowed("bee_message::Error"), - message: Cow::Owned(error.to_string()), - } - } -} - impl From for WasmError<'_> { fn from(error: identity::iota::CompoundCredentialValidationError) -> Self { Self { diff --git a/bindings/wasm/src/tangle/client.rs b/bindings/wasm/src/tangle/client.rs index 91d51a60bc..4a84a01bfa 100644 --- a/bindings/wasm/src/tangle/client.rs +++ b/bindings/wasm/src/tangle/client.rs @@ -7,12 +7,12 @@ use std::rc::Rc; use futures::executor; use identity::iota::Client; use identity::iota::ClientBuilder; -use identity::iota::DiffMessage; -use identity::iota::IotaDID; -use identity::iota::IotaDocument; -use identity::iota::MessageId; use identity::iota::ResolvedIotaDocument; use identity::iota::TangleResolve; +use identity::iota_core::DiffMessage; +use identity::iota_core::IotaDID; +use identity::iota_core::IotaDocument; +use identity::iota_core::MessageId; use js_sys::Promise; use wasm_bindgen::prelude::*; use wasm_bindgen::JsCast; @@ -88,7 +88,9 @@ impl WasmClient { /// Publishes a `DiffMessage` to the Tangle. #[wasm_bindgen(js_name = publishDiff)] pub fn publish_diff(&self, message_id: &str, diff: &WasmDiffMessage) -> Result { - let message: MessageId = MessageId::from_str(message_id).wasm_result()?; + let message: MessageId = MessageId::from_str(message_id) + .map_err(identity::iota_core::Error::InvalidMessage) + .wasm_result()?; let diff: DiffMessage = diff.0.clone(); let client: Rc = self.client.clone(); diff --git a/bindings/wasm/src/tangle/client_config.rs b/bindings/wasm/src/tangle/client_config.rs index 030495732d..f7057f26d1 100644 --- a/bindings/wasm/src/tangle/client_config.rs +++ b/bindings/wasm/src/tangle/client_config.rs @@ -5,7 +5,7 @@ use std::time::Duration; use identity::iota::ClientBuilder; use identity::iota::DIDMessageEncoding; -use identity::iota::Network; +use identity::iota_core::Network; use wasm_bindgen::prelude::*; use crate::error::WasmResult; @@ -240,7 +240,7 @@ mod tests { use identity::core::Object; use identity::iota::ClientBuilder; use identity::iota::DIDMessageEncoding; - use identity::iota::Network; + use identity::iota_core::Network; use wasm_bindgen::JsCast; use wasm_bindgen::JsValue; use wasm_bindgen_test::*; diff --git a/bindings/wasm/src/tangle/explorer.rs b/bindings/wasm/src/tangle/explorer.rs index aaf58578e3..dd1588018f 100644 --- a/bindings/wasm/src/tangle/explorer.rs +++ b/bindings/wasm/src/tangle/explorer.rs @@ -4,8 +4,8 @@ use std::str::FromStr; use identity::iota::ExplorerUrl; -use identity::iota::IotaDID; -use identity::iota::MessageId; +use identity::iota_core::IotaDID; +use identity::iota_core::MessageId; use wasm_bindgen::prelude::*; use crate::did::UWasmDID; @@ -44,7 +44,9 @@ impl WasmExplorerUrl { /// E.g. https://explorer.iota.org/mainnet/message/{message_id} #[wasm_bindgen(js_name = messageUrl)] pub fn message_url(&self, message_id: &str) -> Result { - let message_id = MessageId::from_str(message_id).wasm_result()?; + let message_id = MessageId::from_str(message_id) + .map_err(identity::iota_core::Error::InvalidMessage) + .wasm_result()?; self.0.message_url(&message_id).map(|url| url.to_string()).wasm_result() } diff --git a/bindings/wasm/src/tangle/network.rs b/bindings/wasm/src/tangle/network.rs index 079eb8604a..79df7080e3 100644 --- a/bindings/wasm/src/tangle/network.rs +++ b/bindings/wasm/src/tangle/network.rs @@ -1,7 +1,7 @@ // Copyright 2020-2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -use identity::iota::Network; +use identity::iota_core::Network; use wasm_bindgen::prelude::*; use crate::error::Result; diff --git a/bindings/wasm/src/tangle/resolver.rs b/bindings/wasm/src/tangle/resolver.rs index 8e1e42b805..c56759b974 100644 --- a/bindings/wasm/src/tangle/resolver.rs +++ b/bindings/wasm/src/tangle/resolver.rs @@ -8,11 +8,11 @@ use futures::executor; use identity::core::Url; use identity::iota::Client; use identity::iota::ClientBuilder; -use identity::iota::IotaDID; -use identity::iota::NetworkName; use identity::iota::ResolvedIotaDocument; use identity::iota::Resolver; use identity::iota::ResolverBuilder; +use identity::iota_core::IotaDID; +use identity::iota_core::NetworkName; use js_sys::Promise; use wasm_bindgen::prelude::*; use wasm_bindgen::JsCast; diff --git a/bindings/wasm/tests/wasm.rs b/bindings/wasm/tests/wasm.rs index 478c97fa96..5571245b67 100644 --- a/bindings/wasm/tests/wasm.rs +++ b/bindings/wasm/tests/wasm.rs @@ -1,11 +1,14 @@ // Copyright 2020-2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 +use std::borrow::Cow; + use identity::core::FromJson; use identity::core::Object; use identity::core::Timestamp; use identity::core::ToJson; -use identity::iota::IotaDID; +use identity::iota_core::IotaDID; +use identity_wasm::common::WasmTimestamp; use identity_wasm::credential::WasmCredential; use identity_wasm::credential::WasmCredentialValidationOptions; use identity_wasm::credential::WasmCredentialValidator; @@ -13,25 +16,22 @@ use identity_wasm::credential::WasmFailFast; use identity_wasm::credential::WasmPresentation; use identity_wasm::credential::WasmPresentationValidationOptions; use identity_wasm::credential::WasmPresentationValidator; -use identity_wasm::crypto::WasmSignatureOptions; -use identity_wasm::did::WasmVerifierOptions; -use js_sys::Array; -use std::borrow::Cow; -use wasm_bindgen::prelude::*; -use wasm_bindgen::JsCast; -use wasm_bindgen_test::*; - -use identity_wasm::common::WasmTimestamp; use identity_wasm::crypto::Digest; use identity_wasm::crypto::KeyType; use identity_wasm::crypto::WasmKeyCollection; use identity_wasm::crypto::WasmKeyPair; +use identity_wasm::crypto::WasmSignatureOptions; use identity_wasm::did::WasmDID; use identity_wasm::did::WasmDIDUrl; use identity_wasm::did::WasmDocument; use identity_wasm::did::WasmMethodScope; use identity_wasm::did::WasmVerificationMethod; +use identity_wasm::did::WasmVerifierOptions; use identity_wasm::error::WasmError; +use js_sys::Array; +use wasm_bindgen::prelude::*; +use wasm_bindgen::JsCast; +use wasm_bindgen_test::*; #[wasm_bindgen_test] fn test_keypair() { diff --git a/examples/Cargo.toml b/examples/Cargo.toml index a1eab817d2..fb8ece9d80 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -8,7 +8,7 @@ publish = false identity = { path = "../identity", features = ["account"] } pretty_env_logger = { version = "0.4" } rand = { version = "0.8" } -tokio = { version = "1.10", features = ["full"] } +tokio = { version = "1.17.0", features = ["full"] } [[example]] name = "getting_started" diff --git a/examples/account/config.rs b/examples/account/config.rs index 25e69ebf93..8fe4217ff8 100644 --- a/examples/account/config.rs +++ b/examples/account/config.rs @@ -11,8 +11,8 @@ use identity::account::IdentitySetup; use identity::account::Result; use identity::iota::ClientBuilder; use identity::iota::ExplorerUrl; -use identity::iota::IotaDID; -use identity::iota::Network; +use identity::iota_core::IotaDID; +use identity::iota_core::Network; #[tokio::main] async fn main() -> Result<()> { diff --git a/examples/account/create_did.rs b/examples/account/create_did.rs index b12a10c711..b99fb6581a 100644 --- a/examples/account/create_did.rs +++ b/examples/account/create_did.rs @@ -10,7 +10,7 @@ use identity::account::AccountStorage; use identity::account::IdentitySetup; use identity::account::Result; use identity::iota::ExplorerUrl; -use identity::iota::IotaDID; +use identity::iota_core::IotaDID; #[tokio::main] async fn main() -> Result<()> { diff --git a/examples/account/lazy.rs b/examples/account/lazy.rs index e8c5664022..e2f6eb7584 100644 --- a/examples/account/lazy.rs +++ b/examples/account/lazy.rs @@ -10,7 +10,7 @@ use identity::account::IdentitySetup; use identity::account::Result; use identity::core::Url; use identity::iota::ExplorerUrl; -use identity::iota::IotaDID; +use identity::iota_core::IotaDID; #[tokio::main] async fn main() -> Result<()> { diff --git a/examples/account/manipulate_did.rs b/examples/account/manipulate_did.rs index 95ccdbe7b5..b9fe007e0e 100644 --- a/examples/account/manipulate_did.rs +++ b/examples/account/manipulate_did.rs @@ -12,7 +12,7 @@ use identity::account::Result; use identity::core::Url; use identity::did::MethodRelationship; use identity::iota::ExplorerUrl; -use identity::iota::IotaDID; +use identity::iota_core::IotaDID; #[tokio::main] async fn main() -> Result<()> { diff --git a/examples/account/multiple_identities.rs b/examples/account/multiple_identities.rs index 53909547b0..789aa1aaa6 100644 --- a/examples/account/multiple_identities.rs +++ b/examples/account/multiple_identities.rs @@ -11,7 +11,7 @@ use identity::account::AccountStorage; use identity::account::IdentitySetup; use identity::account::Result; use identity::iota::ExplorerUrl; -use identity::iota::IotaDID; +use identity::iota_core::IotaDID; #[tokio::main] async fn main() -> Result<()> { diff --git a/examples/account/signing.rs b/examples/account/signing.rs index 681734cb70..07f7977034 100644 --- a/examples/account/signing.rs +++ b/examples/account/signing.rs @@ -19,8 +19,8 @@ use identity::crypto::SignatureOptions; use identity::did::verifiable::VerifierOptions; use identity::did::DID; use identity::iota::ExplorerUrl; -use identity::iota::IotaDID; use identity::iota::ResolvedIotaDocument; +use identity::iota_core::IotaDID; #[tokio::main] async fn main() -> Result<()> { diff --git a/examples/account/unchecked.rs b/examples/account/unchecked.rs index e94484f581..42503e8585 100644 --- a/examples/account/unchecked.rs +++ b/examples/account/unchecked.rs @@ -11,7 +11,7 @@ use identity::account::IdentitySetup; use identity::account::Result; use identity::core::Timestamp; use identity::iota::ExplorerUrl; -use identity::iota::IotaDID; +use identity::iota_core::IotaDID; use identity::prelude::IotaDocument; #[tokio::main] diff --git a/examples/low-level-api/common.rs b/examples/low-level-api/common.rs index 7a70bd3d3c..0ae348d73f 100644 --- a/examples/low-level-api/common.rs +++ b/examples/low-level-api/common.rs @@ -8,17 +8,14 @@ use identity::core::json; use identity::core::FromJson; use identity::core::Timestamp; - use identity::core::Url; use identity::credential::Credential; use identity::credential::CredentialBuilder; use identity::credential::Subject; - use identity::did::MethodScope; use identity::did::DID; - -use identity::iota::IotaVerificationMethod; use identity::iota::Receipt; +use identity::iota_core::IotaVerificationMethod; use identity::prelude::*; /// Helper that takes two DID Documents (identities) for issuer and subject, and diff --git a/examples/low-level-api/diff_chain.rs b/examples/low-level-api/diff_chain.rs index d4eedd17a4..6786ccda11 100644 --- a/examples/low-level-api/diff_chain.rs +++ b/examples/low-level-api/diff_chain.rs @@ -12,10 +12,10 @@ use identity::core::Timestamp; use identity::core::ToJson; use identity::did::Service; use identity::did::DID; -use identity::iota::DiffMessage; use identity::iota::ExplorerUrl; -use identity::iota::IotaService; use identity::iota::Receipt; +use identity::iota_core::DiffMessage; +use identity::iota_core::IotaService; use identity::prelude::*; mod create_did; diff --git a/examples/low-level-api/manipulate_did.rs b/examples/low-level-api/manipulate_did.rs index af0d02ef1d..ce78667580 100644 --- a/examples/low-level-api/manipulate_did.rs +++ b/examples/low-level-api/manipulate_did.rs @@ -13,9 +13,9 @@ use identity::did::MethodScope; use identity::did::Service; use identity::did::DID; use identity::iota::ExplorerUrl; -use identity::iota::IotaService; -use identity::iota::IotaVerificationMethod; use identity::iota::Receipt; +use identity::iota_core::IotaService; +use identity::iota_core::IotaVerificationMethod; use identity::prelude::*; mod create_did; diff --git a/examples/low-level-api/merkle_key.rs b/examples/low-level-api/merkle_key.rs index 06c18426db..2266a6fec7 100644 --- a/examples/low-level-api/merkle_key.rs +++ b/examples/low-level-api/merkle_key.rs @@ -5,13 +5,6 @@ //! //! cargo run --example merkle_key -use identity::iota::CredentialValidationOptions; -use identity::iota::CredentialValidator; -use identity::iota::Resolver; - -use rand::rngs::OsRng; -use rand::Rng; - use identity::core::Timestamp; use identity::credential::Credential; use identity::crypto::merkle_key::Sha256; @@ -20,11 +13,15 @@ use identity::crypto::KeyCollection; use identity::crypto::PrivateKey; use identity::crypto::PublicKey; use identity::did::MethodScope; - -use identity::iota::IotaDID; -use identity::iota::IotaVerificationMethod; +use identity::iota::CredentialValidationOptions; +use identity::iota::CredentialValidator; use identity::iota::Receipt; +use identity::iota::Resolver; +use identity::iota_core::IotaDID; +use identity::iota_core::IotaVerificationMethod; use identity::prelude::*; +use rand::rngs::OsRng; +use rand::Rng; mod common; mod create_did; diff --git a/examples/low-level-api/private_tangle.rs b/examples/low-level-api/private_tangle.rs index bd50c80581..9175a3006e 100644 --- a/examples/low-level-api/private_tangle.rs +++ b/examples/low-level-api/private_tangle.rs @@ -12,8 +12,8 @@ use identity::iota::ClientBuilder; use identity::iota::DIDMessageEncoding; use identity::iota::ExplorerUrl; -use identity::iota::Network; use identity::iota::Receipt; +use identity::iota_core::Network; use identity::prelude::*; #[tokio::main] diff --git a/examples/low-level-api/resolution.rs b/examples/low-level-api/resolution.rs index 34966bd939..2743330d57 100644 --- a/examples/low-level-api/resolution.rs +++ b/examples/low-level-api/resolution.rs @@ -16,9 +16,9 @@ use identity::did::resolution::Resource; use identity::did::resolution::SecondaryResource; use identity::did::CoreDID; use identity::did::DID; -use identity::iota::IotaDID; -use identity::iota::IotaDIDUrl; use identity::iota::Receipt; +use identity::iota_core::IotaDID; +use identity::iota_core::IotaDIDUrl; use identity::prelude::*; mod create_did; diff --git a/examples/low-level-api/resolve_history.rs b/examples/low-level-api/resolve_history.rs index d88b1d2412..eddbe309d9 100644 --- a/examples/low-level-api/resolve_history.rs +++ b/examples/low-level-api/resolve_history.rs @@ -15,13 +15,13 @@ use identity::did::Service; use identity::did::DID; use identity::iota::ChainHistory; use identity::iota::Client; -use identity::iota::DiffMessage; use identity::iota::DocumentHistory; -use identity::iota::IotaDocument; -use identity::iota::IotaService; -use identity::iota::IotaVerificationMethod; use identity::iota::Receipt; use identity::iota::Result; +use identity::iota_core::DiffMessage; +use identity::iota_core::IotaDocument; +use identity::iota_core::IotaService; +use identity::iota_core::IotaVerificationMethod; mod create_did; diff --git a/examples/low-level-api/revoke_vc.rs b/examples/low-level-api/revoke_vc.rs index e54e55c818..6de991d8b2 100644 --- a/examples/low-level-api/revoke_vc.rs +++ b/examples/low-level-api/revoke_vc.rs @@ -21,11 +21,11 @@ use identity::did::DID; use identity::iota::CredentialValidationOptions; use identity::iota::CredentialValidator; use identity::iota::ExplorerUrl; -use identity::iota::IotaVerificationMethod; use identity::iota::Receipt; use identity::iota::Resolver; use identity::iota::Result; +use identity::iota_core::IotaVerificationMethod; use identity::prelude::*; mod common; diff --git a/identity-account-storage/Cargo.toml b/identity-account-storage/Cargo.toml new file mode 100644 index 0000000000..c1b65697e8 --- /dev/null +++ b/identity-account-storage/Cargo.toml @@ -0,0 +1,56 @@ +[package] +name = "identity-account-storage" +version = "0.5.0-dev.4" +authors = ["IOTA Stiftung"] +edition = "2021" +homepage = "https://www.iota.org" +keywords = ["iota", "tangle", "identity"] +license = "Apache-2.0" +readme = "../README.md" +repository = "https://github.com/iotaledger/identity.rs" +description = "Secure storage for Decentralized Identifiers and Verifiable Credentials." + +[dependencies] +actix = { version = "0.12.0", optional = true } +async-trait = { version = "0.1", default-features = false } +futures = { version = "0.3", optional = true } +hashbrown = { version = "0.11", features = ["serde"] } +identity-core = { version = "=0.5.0-dev.4", path = "../identity-core", default-features = false } +identity-did = { version = "=0.5.0-dev.4", path = "../identity-did", default-features = false } +identity-iota-core = { version = "=0.5.0-dev.4", path = "../identity-iota-core", default-features = false } +once_cell = { version = "1.7", default-features = false, features = ["std"] } +parking_lot = { version = "0.12" } +serde = { version = "1.0", default-features = false, features = ["alloc", "derive"] } +strum = { version = "0.24.0", default-features = false, features = ["std", "derive"] } +thiserror = { version = "1.0" } +tokio = { version = "1.17.0", default-features = false, features = ["sync"], optional = true } +zeroize = { version = "1.4" } + +[dependencies.iota-crypto] +version = "0.7" +features = ["blake2b", "ed25519", "hmac", "pbkdf", "sha", "slip10", "std"] + +[dependencies.iota_stronghold] +git = "https://github.com/iotaledger/stronghold.rs" +rev = "969df405661ba4977f2cf30e9909cef7e30cefa2" +optional = true + +[dependencies.stronghold_engine] +git = "https://github.com/iotaledger/stronghold.rs" +rev = "969df405661ba4977f2cf30e9909cef7e30cefa2" +optional = true + +[dev-dependencies] +rand = { version = "0.8" } +rusty-fork = { version = "0.3" } +tokio = { version = "1.17.0", default-features = false, features = ["macros", "rt", "rt-multi-thread", "sync"] } + +[features] +default = ["stronghold"] +stronghold = [ + "iota_stronghold", + "stronghold_engine", + "actix", + "tokio/rt-multi-thread", + "futures", +] diff --git a/identity-account/src/crypto/mod.rs b/identity-account-storage/src/crypto/mod.rs similarity index 67% rename from identity-account/src/crypto/mod.rs rename to identity-account-storage/src/crypto/mod.rs index 48e4e90f23..a08fb953c6 100644 --- a/identity-account/src/crypto/mod.rs +++ b/identity-account-storage/src/crypto/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2020-2021 IOTA Stiftung +// Copyright 2020-2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 mod remote; diff --git a/identity-account/src/crypto/remote.rs b/identity-account-storage/src/crypto/remote.rs similarity index 97% rename from identity-account/src/crypto/remote.rs rename to identity-account-storage/src/crypto/remote.rs index 1925996a68..63a9000f22 100644 --- a/identity-account/src/crypto/remote.rs +++ b/identity-account-storage/src/crypto/remote.rs @@ -1,4 +1,4 @@ -// Copyright 2020-2021 IOTA Stiftung +// Copyright 2020-2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 use core::marker::PhantomData; @@ -14,7 +14,7 @@ use identity_core::crypto::SignatureValue; use identity_core::error::Error; use identity_core::error::Result; use identity_core::utils::encode_b58; -use identity_iota::did::IotaDID; +use identity_iota_core::did::IotaDID; use crate::storage::Storage; use crate::types::KeyLocation; diff --git a/identity-account-storage/src/error.rs b/identity-account-storage/src/error.rs new file mode 100644 index 0000000000..dec31777bf --- /dev/null +++ b/identity-account-storage/src/error.rs @@ -0,0 +1,60 @@ +// Copyright 2020-2022 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +//! Errors that may occur when working with Identity Accounts. + +/// Alias for a `Result` with the error type [`Error`]. +pub type Result = ::core::result::Result; + +/// This type represents all possible errors that can occur in the library. +#[derive(Debug, thiserror::Error, strum::IntoStaticStr)] +pub enum Error { + /// Caused by errors from the [identity_core] crate. + #[error(transparent)] + CoreError(#[from] identity_core::Error), + /// Caused by errors from the [identity_did] crate. + #[error(transparent)] + DIDError(#[from] identity_did::Error), + /// Caused by attempting to perform an invalid IO operation. + #[error(transparent)] + IoError(#[from] std::io::Error), + /// Caused by errors from the [iota_stronghold] crate. + #[cfg(feature = "stronghold")] + #[error(transparent)] + StrongholdError(#[from] crate::stronghold::StrongholdError), + + /// Caused by attempting to increment a generation above the maximum value. + #[error("Generation overflow")] + GenerationOverflow, + /// Caused by attempting to decrement a generation below the minimum value. + #[error("Generation underflow")] + GenerationUnderflow, + /// Caused by providing bytes that cannot be used as a private key of the + /// [`KeyType`][identity_core::crypto::KeyType]. + #[error("Invalid Private Key: {0}")] + InvalidPrivateKey(String), + /// Caused by attempting to find a key in storage that does not exist. + #[error("key not found")] + KeyNotFound, + /// Caused by attempting to find an identity key vault that does not exist. + #[error("Key vault not found")] + KeyVaultNotFound, + /// Caused by attempting to read a poisoned shared resource. + #[error("Shared resource poisoned: read")] + SharedReadPoisoned, + /// Caused by attempting to write a poisoned shared resource. + #[error("Shared resource poisoned: write")] + SharedWritePoisoned, +} + +#[doc(hidden)] +pub trait PleaseDontMakeYourOwnResult { + #[allow(clippy::wrong_self_convention)] + fn to_result(self) -> Result; +} + +impl From for Error { + fn from(error: identity_did::did::DIDError) -> Self { + identity_did::Error::from(error).into() + } +} diff --git a/identity-account/src/identity/chain_state.rs b/identity-account-storage/src/identity/chain_state.rs similarity index 92% rename from identity-account/src/identity/chain_state.rs rename to identity-account-storage/src/identity/chain_state.rs index 30fd554f4b..20cd82c265 100644 --- a/identity-account/src/identity/chain_state.rs +++ b/identity-account-storage/src/identity/chain_state.rs @@ -1,11 +1,11 @@ -// Copyright 2020-2021 IOTA Stiftung +// Copyright 2020-2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 +use identity_iota_core::tangle::MessageId; +use identity_iota_core::tangle::MessageIdExt; +use serde::Deserialize; use serde::Serialize; -use identity_iota::tangle::MessageId; -use identity_iota::tangle::MessageIdExt; - /// Holds the last published message ids of the integration and diff chains. #[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] pub struct ChainState { diff --git a/identity-account/src/identity/identity_state.rs b/identity-account-storage/src/identity/identity_state.rs similarity index 95% rename from identity-account/src/identity/identity_state.rs rename to identity-account-storage/src/identity/identity_state.rs index e1d1fb2240..3fb308f207 100644 --- a/identity-account/src/identity/identity_state.rs +++ b/identity-account-storage/src/identity/identity_state.rs @@ -1,17 +1,17 @@ -// Copyright 2020-2021 IOTA Stiftung +// Copyright 2020-2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 use hashbrown::HashMap; -use serde::Serialize; - use identity_core::common::Fragment; use identity_core::crypto::SetSignature; use identity_core::crypto::SignatureOptions; use identity_did::did::DID; use identity_did::verification::MethodType; -use identity_iota::did::IotaDID; -use identity_iota::did::IotaDIDUrl; -use identity_iota::document::IotaDocument; +use identity_iota_core::did::IotaDID; +use identity_iota_core::did::IotaDIDUrl; +use identity_iota_core::document::IotaDocument; +use serde::Deserialize; +use serde::Serialize; use crate::crypto::RemoteEd25519; use crate::crypto::RemoteKey; diff --git a/identity-account-storage/src/identity/mod.rs b/identity-account-storage/src/identity/mod.rs new file mode 100644 index 0000000000..75aa222865 --- /dev/null +++ b/identity-account-storage/src/identity/mod.rs @@ -0,0 +1,8 @@ +// Copyright 2020-2022 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +mod chain_state; +mod identity_state; + +pub use self::chain_state::*; +pub use self::identity_state::*; diff --git a/identity-account-storage/src/lib.rs b/identity-account-storage/src/lib.rs new file mode 100644 index 0000000000..87575428c6 --- /dev/null +++ b/identity-account-storage/src/lib.rs @@ -0,0 +1,28 @@ +// Copyright 2020-2022 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +#![forbid(unsafe_code)] +#![allow(clippy::upper_case_acronyms)] +#![warn( + rust_2018_idioms, + unreachable_pub, + // missing_docs, + // rustdoc::missing_crate_level_docs, + rustdoc::broken_intra_doc_links, + rustdoc::private_intra_doc_links, + rustdoc::private_doc_tests, + clippy::missing_safety_doc, + // clippy::missing_errors_doc +)] + +pub mod crypto; +pub mod error; +pub mod identity; +pub mod storage; +#[cfg(feature = "stronghold")] +pub mod stronghold; +pub mod types; +pub mod utils; + +pub use self::error::Error; +pub use self::error::Result; diff --git a/identity-account/src/storage/memstore.rs b/identity-account-storage/src/storage/memstore.rs similarity index 98% rename from identity-account/src/storage/memstore.rs rename to identity-account-storage/src/storage/memstore.rs index 6e9b84568b..6cf346617a 100644 --- a/identity-account/src/storage/memstore.rs +++ b/identity-account-storage/src/storage/memstore.rs @@ -1,4 +1,4 @@ -// Copyright 2020-2021 IOTA Stiftung +// Copyright 2020-2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 use core::fmt::Debug; @@ -13,7 +13,7 @@ use identity_core::crypto::PrivateKey; use identity_core::crypto::PublicKey; use identity_core::crypto::Sign; use identity_did::verification::MethodType; -use identity_iota::did::IotaDID; +use identity_iota_core::did::IotaDID; use std::convert::TryFrom; use std::sync::RwLockReadGuard; use std::sync::RwLockWriteGuard; diff --git a/identity-account/src/storage/mod.rs b/identity-account-storage/src/storage/mod.rs similarity index 85% rename from identity-account/src/storage/mod.rs rename to identity-account-storage/src/storage/mod.rs index e8a12f17bc..ac2b990f8a 100644 --- a/identity-account/src/storage/mod.rs +++ b/identity-account-storage/src/storage/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2020-2021 IOTA Stiftung +// Copyright 2020-2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 mod memstore; diff --git a/identity-account/src/storage/stronghold.rs b/identity-account-storage/src/storage/stronghold.rs similarity index 99% rename from identity-account/src/storage/stronghold.rs rename to identity-account-storage/src/storage/stronghold.rs index 1d8f58e151..f62a5f47fc 100644 --- a/identity-account/src/storage/stronghold.rs +++ b/identity-account-storage/src/storage/stronghold.rs @@ -9,7 +9,7 @@ use identity_core::crypto::PrivateKey; use identity_core::crypto::PublicKey; use identity_did::did::DID; use identity_did::verification::MethodType; -use identity_iota::did::IotaDID; +use identity_iota_core::did::IotaDID; use iota_stronghold::procedures::Chain; use iota_stronghold::procedures::Ed25519Sign; use iota_stronghold::procedures::Slip10Derive; diff --git a/identity-account/src/storage/traits.rs b/identity-account-storage/src/storage/traits.rs similarity index 98% rename from identity-account/src/storage/traits.rs rename to identity-account-storage/src/storage/traits.rs index c547e0ef42..24993ef650 100644 --- a/identity-account/src/storage/traits.rs +++ b/identity-account-storage/src/storage/traits.rs @@ -1,10 +1,10 @@ -// Copyright 2020-2021 IOTA Stiftung +// Copyright 2020-2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 use core::fmt::Debug; use identity_core::crypto::PrivateKey; use identity_core::crypto::PublicKey; -use identity_iota::did::IotaDID; +use identity_iota_core::did::IotaDID; use crate::error::Result; use crate::identity::ChainState; diff --git a/identity-account/src/stronghold/context.rs b/identity-account-storage/src/stronghold/context.rs similarity index 100% rename from identity-account/src/stronghold/context.rs rename to identity-account-storage/src/stronghold/context.rs diff --git a/identity-account/src/stronghold/error.rs b/identity-account-storage/src/stronghold/error.rs similarity index 93% rename from identity-account/src/stronghold/error.rs rename to identity-account-storage/src/stronghold/error.rs index bd9b5df1c7..5042448e5e 100644 --- a/identity-account/src/stronghold/error.rs +++ b/identity-account-storage/src/stronghold/error.rs @@ -1,8 +1,6 @@ // Copyright 2020-2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -use iota_stronghold::procedures::ProcedureError; - pub type IotaStrongholdResult = Result; /// Caused by errors from the [`iota_stronghold`] crate. @@ -18,12 +16,13 @@ pub enum StrongholdError { StrongholdFatalEngineError(#[from] iota_stronghold::FatalEngineError), #[error(transparent)] StrongholdMailboxError(#[from] iota_stronghold::MailboxError), + /// Caused by receiving an unexpected return value from a Stronghold procedure. + #[error("Stronghold procedure returned unexpected type")] + StrongholdProcedureFailure(#[from] iota_stronghold::procedures::ProcedureError), /// Caused by attempting to perform an invalid IO operation. #[error(transparent)] IoError(#[from] std::io::Error), - /// Caused by receiving an unexpected return value from a Stronghold procedure. - #[error("Stronghold procedure returned unexpected type")] - StrongholdProcedureFailure(#[from] ProcedureError), + /// Caused by attempting to access a Stronghold snapshot without a password. #[error("Stronghold snapshot password not found")] StrongholdPasswordNotSet, diff --git a/identity-account/src/stronghold/hint.rs b/identity-account-storage/src/stronghold/hint.rs similarity index 100% rename from identity-account/src/stronghold/hint.rs rename to identity-account-storage/src/stronghold/hint.rs diff --git a/identity-account/src/stronghold/mod.rs b/identity-account-storage/src/stronghold/mod.rs similarity index 90% rename from identity-account/src/stronghold/mod.rs rename to identity-account-storage/src/stronghold/mod.rs index ff8ef78225..80c5594faf 100644 --- a/identity-account/src/stronghold/mod.rs +++ b/identity-account-storage/src/stronghold/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2020-2021 IOTA Stiftung +// Copyright 2020-2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 mod context; diff --git a/identity-account/src/stronghold/records.rs b/identity-account-storage/src/stronghold/records.rs similarity index 98% rename from identity-account/src/stronghold/records.rs rename to identity-account-storage/src/stronghold/records.rs index bd06db0cf8..6392d96f7d 100644 --- a/identity-account/src/stronghold/records.rs +++ b/identity-account-storage/src/stronghold/records.rs @@ -57,14 +57,14 @@ impl Records<'_> { } pub async fn all(&self) -> IotaStrongholdResult>>> { - Ok(self.index().await?.load_all(&self.store).await?) + self.index().await?.load_all(&self.store).await } pub async fn get(&self, record_id: &[u8]) -> IotaStrongholdResult>> { let record_tag: RecordTag = RecordIndex::tag(record_id); let location: Location = Locations::record(&record_tag); - Ok(self.store.get(location).await?) + self.store.get(location).await } pub async fn set(&self, record_id: &[u8], record: &[u8]) -> IotaStrongholdResult<()> { diff --git a/identity-account/src/stronghold/snapshot.rs b/identity-account-storage/src/stronghold/snapshot.rs similarity index 100% rename from identity-account/src/stronghold/snapshot.rs rename to identity-account-storage/src/stronghold/snapshot.rs diff --git a/identity-account/src/stronghold/status.rs b/identity-account-storage/src/stronghold/status.rs similarity index 100% rename from identity-account/src/stronghold/status.rs rename to identity-account-storage/src/stronghold/status.rs diff --git a/identity-account/src/stronghold/store.rs b/identity-account-storage/src/stronghold/store.rs similarity index 100% rename from identity-account/src/stronghold/store.rs rename to identity-account-storage/src/stronghold/store.rs diff --git a/identity-account/src/stronghold/tests.rs b/identity-account-storage/src/stronghold/tests.rs similarity index 99% rename from identity-account/src/stronghold/tests.rs rename to identity-account-storage/src/stronghold/tests.rs index 9ec8c8fb76..dae0cfa918 100644 --- a/identity-account/src/stronghold/tests.rs +++ b/identity-account-storage/src/stronghold/tests.rs @@ -1,4 +1,4 @@ -// Copyright 2020-2021 IOTA Stiftung +// Copyright 2020-2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 use core::iter; diff --git a/identity-account/src/stronghold/vault.rs b/identity-account-storage/src/stronghold/vault.rs similarity index 100% rename from identity-account/src/stronghold/vault.rs rename to identity-account-storage/src/stronghold/vault.rs diff --git a/identity-account/src/types/generation.rs b/identity-account-storage/src/types/generation.rs similarity index 95% rename from identity-account/src/types/generation.rs rename to identity-account-storage/src/types/generation.rs index c168cd4e7b..64c1f3e536 100644 --- a/identity-account/src/types/generation.rs +++ b/identity-account-storage/src/types/generation.rs @@ -1,10 +1,13 @@ -// Copyright 2020-2021 IOTA Stiftung +// Copyright 2020-2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 use core::fmt::Debug; use core::fmt::Display; use core::fmt::Formatter; +use serde::Deserialize; +use serde::Serialize; + use crate::error::Error; use crate::error::Result; diff --git a/identity-account/src/types/key_location.rs b/identity-account-storage/src/types/key_location.rs similarity index 94% rename from identity-account/src/types/key_location.rs rename to identity-account-storage/src/types/key_location.rs index c178d196d9..f7026552b5 100644 --- a/identity-account/src/types/key_location.rs +++ b/identity-account-storage/src/types/key_location.rs @@ -1,4 +1,4 @@ -// Copyright 2020-2021 IOTA Stiftung +// Copyright 2020-2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 use core::fmt::Debug; @@ -7,6 +7,8 @@ use core::fmt::Formatter; use core::fmt::Result; use identity_core::common::Fragment; use identity_did::verification::MethodType; +use serde::Deserialize; +use serde::Serialize; use crate::types::Generation; diff --git a/identity-account-storage/src/types/mod.rs b/identity-account-storage/src/types/mod.rs new file mode 100644 index 0000000000..b92049f574 --- /dev/null +++ b/identity-account-storage/src/types/mod.rs @@ -0,0 +1,10 @@ +// Copyright 2020-2022 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +mod generation; +mod key_location; +mod signature; + +pub use self::generation::*; +pub use self::key_location::*; +pub use self::signature::*; diff --git a/identity-account/src/types/signature.rs b/identity-account-storage/src/types/signature.rs similarity index 94% rename from identity-account/src/types/signature.rs rename to identity-account-storage/src/types/signature.rs index 962e4b8916..073e96805b 100644 --- a/identity-account/src/types/signature.rs +++ b/identity-account-storage/src/types/signature.rs @@ -1,4 +1,4 @@ -// Copyright 2020-2021 IOTA Stiftung +// Copyright 2020-2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 use identity_core::crypto::PublicKey; diff --git a/identity-account/src/utils/crypto.rs b/identity-account-storage/src/utils/crypto.rs similarity index 92% rename from identity-account/src/utils/crypto.rs rename to identity-account-storage/src/utils/crypto.rs index 778af84a35..8b758e2641 100644 --- a/identity-account/src/utils/crypto.rs +++ b/identity-account-storage/src/utils/crypto.rs @@ -1,4 +1,4 @@ -// Copyright 2020-2021 IOTA Stiftung +// Copyright 2020-2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 use crypto::keys::pbkdf::PBKDF2_HMAC_SHA512; diff --git a/identity-account/src/utils/fs.rs b/identity-account-storage/src/utils/fs.rs similarity index 88% rename from identity-account/src/utils/fs.rs rename to identity-account-storage/src/utils/fs.rs index 4940a72101..a2ec7974a8 100644 --- a/identity-account/src/utils/fs.rs +++ b/identity-account-storage/src/utils/fs.rs @@ -1,4 +1,4 @@ -// Copyright 2020-2021 IOTA Stiftung +// Copyright 2020-2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 use std::fs; diff --git a/identity-account/src/utils/mod.rs b/identity-account-storage/src/utils/mod.rs similarity index 77% rename from identity-account/src/utils/mod.rs rename to identity-account-storage/src/utils/mod.rs index 9adc775404..8904969bd4 100644 --- a/identity-account/src/utils/mod.rs +++ b/identity-account-storage/src/utils/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2020-2021 IOTA Stiftung +// Copyright 2020-2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 mod crypto; diff --git a/identity-account/src/utils/shared.rs b/identity-account-storage/src/utils/shared.rs similarity index 90% rename from identity-account/src/utils/shared.rs rename to identity-account-storage/src/utils/shared.rs index 86914a18e3..131e9414dc 100644 --- a/identity-account/src/utils/shared.rs +++ b/identity-account-storage/src/utils/shared.rs @@ -1,13 +1,15 @@ -// Copyright 2020-2021 IOTA Stiftung +// Copyright 2020-2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 use core::fmt::Debug; use core::fmt::Formatter; - use std::sync::RwLock; use std::sync::RwLockReadGuard; use std::sync::RwLockWriteGuard; +use serde::Deserialize; +use serde::Serialize; + use crate::error::Error; use crate::error::Result; diff --git a/identity-account/Cargo.toml b/identity-account/Cargo.toml index f5e6b9245c..23eca61d10 100644 --- a/identity-account/Cargo.toml +++ b/identity-account/Cargo.toml @@ -11,52 +11,31 @@ repository = "https://github.com/iotaledger/identity.rs" description = "Secure storage for Decentralized Identifiers and Verifiable Credentials." [dependencies] -actix = { version = "0.12.0", optional = true } -async-trait = { version = "0.1", default-features = false } -futures = { version = "0.3" } -hashbrown = { version = "0.11", features = ["serde"] } +identity-account-storage = { version = "=0.5.0-dev.4", path = "../identity-account-storage", default-features = false } identity-core = { version = "=0.5.0-dev.4", path = "../identity-core" } identity-credential = { version = "=0.5.0-dev.4", path = "../identity-credential" } identity-did = { version = "=0.5.0-dev.4", path = "../identity-did" } identity-iota = { version = "=0.5.0-dev.4", path = "../identity-iota", default-features = false } -itoa = { version = "0.4" } +identity-iota-core = { version = "=0.5.0-dev.4", path = "../identity-iota-core", default-features = false } log = { version = "0.4", default-features = false } -once_cell = { version = "1.7", default-features = false, features = ["std"] } -parking_lot = { version = "0.12" } paste = { version = "1.0" } serde = { version = "1.0", default-features = false, features = ["alloc", "derive"] } -slog = { version = "2.7" } -strum = { version = "0.21", features = ["derive"] } +strum = { version = "0.24.0", default-features = false, features = ["std", "derive"] } thiserror = { version = "1.0" } -tokio = { version = "1.5", features = ["sync"] } -zeroize = { version = "1.4" } +zeroize = { version = "1.4", optional = true } [dependencies.iota-crypto] version = "0.7" features = ["blake2b", "ed25519", "hmac", "pbkdf", "sha", "slip10", "std"] -[dependencies.iota_stronghold] -git = "https://github.com/iotaledger/stronghold.rs" -rev = "969df405661ba4977f2cf30e9909cef7e30cefa2" -optional = true - -[dependencies.stronghold_engine] -git = "https://github.com/iotaledger/stronghold.rs" -rev = "969df405661ba4977f2cf30e9909cef7e30cefa2" -optional = true - [dev-dependencies] +futures = { version = "0.3" } rand = { version = "0.8" } rusty-fork = { version = "0.3" } -tokio = { version = "1.5", features = ["macros", "rt", "rt-multi-thread", "sync"] } +tokio = { version = "1.17.0", default-features = false, features = ["macros", "rt", "rt-multi-thread", "sync"] } [features] +default = ["async", "stronghold"] mem-client = [] -stronghold = [ - "iota_stronghold", - "stronghold_engine", - "actix", - "tokio/rt-multi-thread", -] +stronghold = ["identity-account-storage/stronghold", "zeroize"] async = ["identity-iota/async"] -default = ["stronghold", "async"] diff --git a/identity-account/src/account/account.rs b/identity-account/src/account/account.rs index 6f72174ab6..a424367f95 100644 --- a/identity-account/src/account/account.rs +++ b/identity-account/src/account/account.rs @@ -5,29 +5,28 @@ use std::sync::atomic::AtomicUsize; use std::sync::atomic::Ordering; use std::sync::Arc; -use serde::Serialize; - +use identity_account_storage::identity::ChainState; +use identity_account_storage::identity::IdentityState; +use identity_account_storage::storage::Storage; +use identity_account_storage::types::KeyLocation; use identity_core::crypto::SetSignature; use identity_core::crypto::SignatureOptions; use identity_iota::chain::DocumentChain; -use identity_iota::did::IotaDID; -use identity_iota::diff::DiffMessage; -use identity_iota::document::IotaDocument; -use identity_iota::document::IotaVerificationMethod; use identity_iota::document::ResolvedIotaDocument; use identity_iota::tangle::Client; -use identity_iota::tangle::MessageId; -use identity_iota::tangle::MessageIdExt; use identity_iota::tangle::PublishType; +use identity_iota_core::did::IotaDID; +use identity_iota_core::diff::DiffMessage; +use identity_iota_core::document::IotaDocument; +use identity_iota_core::document::IotaVerificationMethod; +use identity_iota_core::tangle::MessageId; +use identity_iota_core::tangle::MessageIdExt; +use serde::Serialize; use crate::account::AccountBuilder; use crate::account::PublishOptions; -use crate::identity::ChainState; use crate::identity::IdentitySetup; -use crate::identity::IdentityState; use crate::identity::IdentityUpdater; -use crate::storage::Storage; -use crate::types::KeyLocation; use crate::updates::create_identity; use crate::updates::Update; use crate::Error; diff --git a/identity-account/src/account/builder.rs b/identity-account/src/account/builder.rs index ae8e8b05af..428c57f790 100644 --- a/identity-account/src/account/builder.rs +++ b/identity-account/src/account/builder.rs @@ -8,21 +8,20 @@ use std::sync::Arc; #[cfg(feature = "stronghold")] use zeroize::Zeroize; -use identity_iota::did::IotaDID; +use identity_account_storage::storage::MemStore; +use identity_account_storage::storage::Storage; +#[cfg(feature = "stronghold")] +use identity_account_storage::storage::Stronghold; use identity_iota::tangle::Client; use identity_iota::tangle::ClientBuilder; - -use crate::account::Account; -use crate::error::Result; -use crate::identity::IdentitySetup; -use crate::storage::MemStore; -use crate::storage::Storage; -#[cfg(feature = "stronghold")] -use crate::storage::Stronghold; +use identity_iota_core::did::IotaDID; use super::config::AccountConfig; use super::config::AccountSetup; use super::config::AutoSave; +use crate::account::Account; +use crate::error::Result; +use crate::identity::IdentitySetup; /// The storage adapter used by an [`Account`]. /// diff --git a/identity-account/src/account/config.rs b/identity-account/src/account/config.rs index 48ed6cd271..23653c2959 100644 --- a/identity-account/src/account/config.rs +++ b/identity-account/src/account/config.rs @@ -3,10 +3,9 @@ use std::sync::Arc; +use identity_account_storage::storage::Storage; use identity_iota::tangle::Client; -use crate::storage::Storage; - /// A wrapper that holds configuration for an [`Account`] instantiation. /// /// The setup implements `Clone` so multiple [`Account`]s can be created diff --git a/identity-account/src/error.rs b/identity-account/src/error.rs index 11438fb7e5..4291e7a078 100644 --- a/identity-account/src/error.rs +++ b/identity-account/src/error.rs @@ -3,9 +3,6 @@ //! Errors that may occur when working with Identity Accounts. -#[cfg(feature = "stronghold")] -use crate::stronghold::StrongholdError; - /// Alias for a `Result` with the error type [`Error`]. pub type Result = ::core::result::Result; @@ -24,43 +21,22 @@ pub enum Error { /// Caused by errors from the [identity_credential] crate. #[error(transparent)] CredentialError(#[from] identity_credential::Error), + /// Caused by errors from the [crypto] crate. + #[error(transparent)] + AccountCoreError(#[from] identity_account_storage::Error), /// Caused by errors from the [identity_iota] crate. #[error(transparent)] IotaError(#[from] identity_iota::Error), - /// Caused by attempting to perform an invalid IO operation. + /// Caused by errors from the [identity_iota_core] crate. #[error(transparent)] - IoError(#[from] std::io::Error), - #[cfg(feature = "stronghold")] - #[error(transparent)] - StrongholdError(#[from] StrongholdError), - /// Caused by attempting to read a poisoned shared resource. - #[error("Shared resource poisoned: read")] - SharedReadPoisoned, - /// Caused by attempting to write a poisoned shared resource. - #[error("Shared resource poisoned: write")] - SharedWritePoisoned, - /// Caused by attempting to increment a generation above the maximum value. - #[error("Generation overflow")] - GenerationOverflow, - /// Caused by attempting to decrement a generation below the minimum value. - #[error("Generation underflow")] - GenerationUnderflow, - /// Caused by attempting to find an identity key vault that does not exist. - #[error("Key vault not found")] - KeyVaultNotFound, - /// Caused by attempting to find a key in storage that does not exist. - #[error("key not found")] - KeyNotFound, + IotaCoreError(#[from] identity_iota_core::Error), + /// Caused by attempting to find an identity that does not exist. #[error("Identity not found")] IdentityNotFound, /// Caused by attempting to perform an upate in an invalid context. #[error("Update Error: {0}")] UpdateError(#[from] crate::updates::UpdateError), - /// Caused by providing bytes that cannot be used as a private key of the - /// [`KeyType`][identity_core::crypto::KeyType]. - #[error("Invalid Private Key: {0}")] - InvalidPrivateKey(String), #[error("method missing fragment")] MethodMissingFragment, } diff --git a/identity-account/src/identity/mod.rs b/identity-account/src/identity/mod.rs index 9d1f95d448..98d9678a63 100644 --- a/identity-account/src/identity/mod.rs +++ b/identity-account/src/identity/mod.rs @@ -1,12 +1,8 @@ // Copyright 2020-2021 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -mod chain_state; mod identity_setup; -mod identity_state; mod identity_updater; -pub use self::chain_state::*; pub use self::identity_setup::*; -pub use self::identity_state::*; pub use self::identity_updater::*; diff --git a/identity-account/src/lib.rs b/identity-account/src/lib.rs index d937a582b4..e70d9dc7cd 100644 --- a/identity-account/src/lib.rs +++ b/identity-account/src/lib.rs @@ -15,24 +15,12 @@ // clippy::missing_errors_doc )] -#[macro_use] -extern crate log; - -#[macro_use] -extern crate serde; - pub mod account; -pub mod crypto; pub mod error; pub mod identity; -pub mod storage; -#[cfg(feature = "stronghold")] -pub mod stronghold; #[cfg(test)] mod tests; pub mod types; pub mod updates; -pub mod utils; - pub use self::error::Error; pub use self::error::Result; diff --git a/identity-account/src/tests/account.rs b/identity-account/src/tests/account.rs index 5b3d1fc533..3e35075a3d 100644 --- a/identity-account/src/tests/account.rs +++ b/identity-account/src/tests/account.rs @@ -6,19 +6,22 @@ use std::sync::Arc; use futures::Future; +use identity_account_storage::identity::ChainState; +use identity_account_storage::identity::IdentityState; +use identity_account_storage::storage::MemStore; use identity_core::common::Timestamp; use identity_core::common::Url; use identity_core::crypto::SignatureOptions; use identity_did::utils::Queryable; use identity_did::verification::MethodScope; use identity_iota::chain::DocumentChain; -use identity_iota::diff::DiffMessage; -use identity_iota::document::IotaDocument; use identity_iota::tangle::Client; use identity_iota::tangle::ClientBuilder; -use identity_iota::tangle::MessageId; -use identity_iota::tangle::MessageIdExt; -use identity_iota::tangle::Network; +use identity_iota_core::diff::DiffMessage; +use identity_iota_core::document::IotaDocument; +use identity_iota_core::tangle::MessageId; +use identity_iota_core::tangle::MessageIdExt; +use identity_iota_core::tangle::Network; use crate::account::Account; use crate::account::AccountBuilder; @@ -27,10 +30,8 @@ use crate::account::AccountSetup; use crate::account::AccountStorage; use crate::account::AutoSave; use crate::account::PublishOptions; -use crate::identity::ChainState; use crate::identity::IdentitySetup; -use crate::identity::IdentityState; -use crate::storage::MemStore; + use crate::Error; use crate::Result; @@ -268,7 +269,9 @@ async fn test_account_publish_options_sign_with() -> Result<()> { .publish_with_options(PublishOptions::default().sign_with("non-existent-method")) .await .unwrap_err(), - Error::IotaError(identity_iota::Error::InvalidDoc(identity_did::Error::MethodNotFound)) + Error::IotaCoreError(identity_iota_core::Error::InvalidDoc( + identity_did::Error::MethodNotFound + )) )); assert!(matches!( @@ -276,7 +279,9 @@ async fn test_account_publish_options_sign_with() -> Result<()> { .publish_with_options(PublishOptions::default().sign_with(auth_method)) .await .unwrap_err(), - Error::IotaError(identity_iota::Error::InvalidDoc(identity_did::Error::MethodNotFound)) + Error::IotaCoreError(identity_iota_core::Error::InvalidDoc( + identity_did::Error::MethodNotFound + )) )); // TODO: Once implemented, add a merkle key collection method with capability invocation relationship and test for diff --git a/identity-account/src/tests/updates.rs b/identity-account/src/tests/updates.rs index 0805f2c567..e7184726a8 100644 --- a/identity-account/src/tests/updates.rs +++ b/identity-account/src/tests/updates.rs @@ -3,6 +3,10 @@ use std::sync::Arc; +use identity_account_storage::identity::IdentityState; +use identity_account_storage::storage::MemStore; +use identity_account_storage::types::Generation; +use identity_account_storage::types::KeyLocation; use identity_core::common::OneOrSet; use identity_core::common::OrderedSet; use identity_core::common::Timestamp; @@ -17,9 +21,9 @@ use identity_did::utils::Queryable; use identity_did::verification::MethodRelationship; use identity_did::verification::MethodScope; use identity_did::verification::MethodType; -use identity_iota::did::IotaDID; use identity_iota::tangle::ClientBuilder; -use identity_iota::tangle::Network; +use identity_iota_core::did::IotaDID; +use identity_iota_core::tangle::Network; use crate::account::Account; use crate::account::AccountConfig; @@ -27,10 +31,6 @@ use crate::account::AccountSetup; use crate::error::Error; use crate::error::Result; use crate::identity::IdentitySetup; -use crate::identity::IdentityState; -use crate::storage::MemStore; -use crate::types::Generation; -use crate::types::KeyLocation; use crate::types::MethodSecret; use crate::updates::Update; use crate::updates::UpdateError; @@ -414,7 +414,7 @@ async fn test_attach_method_relationship() -> Result<()> { assert!(matches!( err, - Error::IotaError(identity_iota::Error::InvalidDoc( + Error::IotaCoreError(identity_iota_core::Error::InvalidDoc( identity_did::Error::InvalidMethodEmbedded )) )); @@ -498,7 +498,7 @@ async fn test_detach_method_relationship() -> Result<()> { assert!(matches!( err, - Error::IotaError(identity_iota::Error::InvalidDoc( + Error::IotaCoreError(identity_iota_core::Error::InvalidDoc( identity_did::Error::InvalidMethodEmbedded )) )); @@ -629,7 +629,9 @@ async fn test_delete_method() -> Result<()> { assert!(matches!( output.unwrap_err(), - Error::IotaError(identity_iota::Error::InvalidDoc(identity_did::Error::MethodNotFound)) + Error::IotaCoreError(identity_iota_core::Error::InvalidDoc( + identity_did::Error::MethodNotFound + )) )); Ok(()) diff --git a/identity-account/src/types/mod.rs b/identity-account/src/types/mod.rs index 671684f807..26a8d38aad 100644 --- a/identity-account/src/types/mod.rs +++ b/identity-account/src/types/mod.rs @@ -1,12 +1,6 @@ // Copyright 2020-2021 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -mod generation; -mod key_location; mod method_secret; -mod signature; -pub use self::generation::*; -pub use self::key_location::*; pub use self::method_secret::*; -pub use self::signature::*; diff --git a/identity-account/src/updates/error.rs b/identity-account/src/updates/error.rs index e68b7c3dd4..7d49c32077 100644 --- a/identity-account/src/updates/error.rs +++ b/identity-account/src/updates/error.rs @@ -1,10 +1,9 @@ -// Copyright 2020-2021 IOTA Stiftung +// Copyright 2020-2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 +use identity_account_storage::types::KeyLocation; use identity_did::verification::MethodType; -use crate::types::KeyLocation; - /// Errors than may occur while processing an update in the [`Account`][crate::account::Account]. #[derive(Debug, thiserror::Error)] pub enum UpdateError { diff --git a/identity-account/src/updates/update.rs b/identity-account/src/updates/update.rs index eb6add28a0..1aa37f2cd2 100644 --- a/identity-account/src/updates/update.rs +++ b/identity-account/src/updates/update.rs @@ -2,7 +2,10 @@ // SPDX-License-Identifier: Apache-2.0 use crypto::signatures::ed25519; - +use identity_account_storage::identity::IdentityState; +use identity_account_storage::storage::Storage; +use identity_account_storage::types::Generation; +use identity_account_storage::types::KeyLocation; use identity_core::common::Fragment; use identity_core::common::Object; use identity_core::common::OneOrSet; @@ -21,20 +24,18 @@ use identity_did::verification::MethodRef; use identity_did::verification::MethodRelationship; use identity_did::verification::MethodScope; use identity_did::verification::MethodType; -use identity_iota::did::IotaDID; -use identity_iota::did::IotaDIDUrl; -use identity_iota::document::IotaDocument; -use identity_iota::document::IotaService; -use identity_iota::document::IotaVerificationMethod; -use identity_iota::tangle::NetworkName; +use identity_iota_core::did::IotaDID; +use identity_iota_core::did::IotaDIDUrl; +use identity_iota_core::document::IotaDocument; +use identity_iota_core::document::IotaService; +use identity_iota_core::document::IotaVerificationMethod; +use identity_iota_core::tangle::NetworkName; +use log::debug; +use log::trace; use crate::account::Account; use crate::error::Result; use crate::identity::IdentitySetup; -use crate::identity::IdentityState; -use crate::storage::Storage; -use crate::types::Generation; -use crate::types::KeyLocation; use crate::types::MethodSecret; use crate::updates::UpdateError; @@ -171,7 +172,7 @@ impl Update { let public: PublicKey = if let Some(method_private_key) = method_secret { insert_method_secret(storage, did, &location, type_, method_private_key).await } else { - storage.key_new(did, &location).await + storage.key_new(did, &location).await.map_err(Into::into) }?; let method: IotaVerificationMethod = @@ -316,7 +317,7 @@ async fn insert_method_secret( ) ); - store.key_insert(did, location, private_key).await + store.key_insert(did, location, private_key).await.map_err(Into::into) } MethodSecret::MerkleKeyCollection(_) => { ensure!( diff --git a/identity-iota-core/Cargo.toml b/identity-iota-core/Cargo.toml new file mode 100644 index 0000000000..6fb4c12afb --- /dev/null +++ b/identity-iota-core/Cargo.toml @@ -0,0 +1,31 @@ +[package] +name = "identity-iota-core" +version = "0.5.0-dev.4" +authors = ["IOTA Stiftung"] +edition = "2021" +homepage = "https://www.iota.org" +keywords = ["iota", "tangle", "identity"] +license = "Apache-2.0" +readme = "../README.md" +repository = "https://github.com/iotaledger/identity.rs" +description = "" + +[dependencies] +bee-message = { version = "0.1.6", default-features = false, features = ["serde"] } +identity-core = { version = "=0.5.0-dev.4", path = "../identity-core", default-features = false } +identity-did = { version = "=0.5.0-dev.4", path = "../identity-did", default-features = false } +lazy_static = { version = "1.4", default-features = false } +serde = { version = "1.0", default-features = false, features = ["std", "derive"] } +strum = { version = "0.24.0", default-features = false, features = ["std", "derive"] } +thiserror = { version = "1.0", default-features = false } + +[dependencies.iota-crypto] +version = "0.7" +default-features = false +features = ["blake2b"] + +[package.metadata.docs.rs] +# To build locally: +# RUSTDOCFLAGS="--cfg docsrs" cargo +nightly doc --all-features --no-deps --workspace --open +all-features = true +rustdoc-args = ["--cfg", "docsrs"] diff --git a/identity-iota-core/README.md b/identity-iota-core/README.md new file mode 100644 index 0000000000..39daac66db --- /dev/null +++ b/identity-iota-core/README.md @@ -0,0 +1 @@ +The IOTA Identity Library diff --git a/identity-iota/src/did/iota_did.rs b/identity-iota-core/src/did/iota_did.rs similarity index 99% rename from identity-iota/src/did/iota_did.rs rename to identity-iota-core/src/did/iota_did.rs index dd012e6f77..5857663a81 100644 --- a/identity-iota/src/did/iota_did.rs +++ b/identity-iota-core/src/did/iota_did.rs @@ -124,7 +124,9 @@ impl IotaDID { // We checked if `id_segments` was empty so this should not panic let mid: &str = segments.last().unwrap(); - let len: usize = decode_b58(mid)?.len(); + let len: usize = decode_b58(mid) + .map_err(|_| Error::InvalidDID(DIDError::InvalidMethodId))? + .len(); if len == BLAKE2B_256_LEN { Ok(()) diff --git a/identity-iota/src/did/macros.rs b/identity-iota-core/src/did/macros.rs similarity index 89% rename from identity-iota/src/did/macros.rs rename to identity-iota-core/src/did/macros.rs index 5f29481349..afb9decf56 100644 --- a/identity-iota/src/did/macros.rs +++ b/identity-iota-core/src/did/macros.rs @@ -1,4 +1,4 @@ -// Copyright 2020-2021 IOTA Stiftung +// Copyright 2020-2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 /// Creates a new IOTA DID from a `public` key and optional `network`. @@ -11,7 +11,7 @@ /// /// ``` /// # use identity_did::did::DID; -/// # use identity_iota::try_construct_did; +/// # use identity_iota_core::try_construct_did; /// # /// let did = try_construct_did!(b"public-key")?; /// assert_eq!(did.as_str(), "did:iota:2xQiiGHDq5gCi1H7utY1ni7cf65fTay3G11S4xKp1vkS"); @@ -21,7 +21,7 @@ /// did.as_str(), /// "did:iota:com:2xQiiGHDq5gCi1H7utY1ni7cf65fTay3G11S4xKp1vkS" /// ); -/// # Ok::<(), identity_iota::Error>(()) +/// # Ok::<(), identity_iota_core::Error>(()) /// ``` #[macro_export] macro_rules! try_construct_did { diff --git a/identity-iota/src/did/mod.rs b/identity-iota-core/src/did/mod.rs similarity index 83% rename from identity-iota/src/did/mod.rs rename to identity-iota-core/src/did/mod.rs index c206f49d4e..96c9658573 100644 --- a/identity-iota/src/did/mod.rs +++ b/identity-iota-core/src/did/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2020-2021 IOTA Stiftung +// Copyright 2020-2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 pub use self::iota_did::IotaDID; diff --git a/identity-iota/src/did/segments.rs b/identity-iota-core/src/did/segments.rs similarity index 97% rename from identity-iota/src/did/segments.rs rename to identity-iota-core/src/did/segments.rs index 83dab1b2cb..982ee3af6c 100644 --- a/identity-iota/src/did/segments.rs +++ b/identity-iota-core/src/did/segments.rs @@ -1,4 +1,4 @@ -// Copyright 2020-2021 IOTA Stiftung +// Copyright 2020-2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 use crate::did::IotaDID; diff --git a/identity-iota/src/diff/diff_iota_did.rs b/identity-iota-core/src/diff/diff_iota_did.rs similarity index 100% rename from identity-iota/src/diff/diff_iota_did.rs rename to identity-iota-core/src/diff/diff_iota_did.rs diff --git a/identity-iota/src/diff/diff_iota_document.rs b/identity-iota-core/src/diff/diff_iota_document.rs similarity index 100% rename from identity-iota/src/diff/diff_iota_document.rs rename to identity-iota-core/src/diff/diff_iota_document.rs diff --git a/identity-iota/src/diff/diff_iota_document_metadata.rs b/identity-iota-core/src/diff/diff_iota_document_metadata.rs similarity index 99% rename from identity-iota/src/diff/diff_iota_document_metadata.rs rename to identity-iota-core/src/diff/diff_iota_document_metadata.rs index 54abb5cc3b..111bf147fc 100644 --- a/identity-iota/src/diff/diff_iota_document_metadata.rs +++ b/identity-iota-core/src/diff/diff_iota_document_metadata.rs @@ -3,18 +3,17 @@ use std::str::FromStr; -use serde::Deserialize; -use serde::Serialize; - +use bee_message::MessageId; use identity_core::common::Object; use identity_core::common::Timestamp; use identity_core::diff::Diff; use identity_core::diff::DiffString; use identity_core::diff::Error; use identity_core::diff::Result; +use serde::Deserialize; +use serde::Serialize; use crate::document::IotaDocumentMetadata; -use crate::tangle::MessageId; /// NOTE: excludes the `proof` [`Signature`] from the diff to save space on the Tangle and because /// a merged signature will be invalid in general. @@ -152,7 +151,7 @@ impl Diff for IotaDocumentMetadata { #[cfg(test)] mod test { - use iota_client::bee_message::MESSAGE_ID_LENGTH; + use bee_message::MESSAGE_ID_LENGTH; use identity_core::common::Object; use identity_core::convert::FromJson; diff --git a/identity-iota/src/diff/diff_message.rs b/identity-iota-core/src/diff/diff_message.rs similarity index 88% rename from identity-iota/src/diff/diff_message.rs rename to identity-iota-core/src/diff/diff_message.rs index f4d1f0aec7..154cf072f2 100644 --- a/identity-iota/src/diff/diff_message.rs +++ b/identity-iota-core/src/diff/diff_message.rs @@ -19,7 +19,6 @@ use crate::document::IotaDocument; use crate::error::Result; use crate::tangle::MessageId; use crate::tangle::MessageIdExt; -use crate::tangle::TangleRef; /// Defines the difference between two DID [`Document`]s' JSON representations. #[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] @@ -29,7 +28,7 @@ pub struct DiffMessage { #[serde( rename = "previousMessageId", default = "MessageId::null", - skip_serializing_if = "MessageIdExt::is_null" + skip_serializing_if = "MessageId::is_null" )] pub(crate) previous_message_id: MessageId, #[serde(skip_serializing_if = "Option::is_none")] @@ -65,11 +64,26 @@ impl DiffMessage { &self.diff } + /// Returns the DID of associated DID Document. + pub fn message_id(&self) -> &MessageId { + &self.message_id + } + + /// Sets the DID of the associated DID Document. + pub fn set_message_id(&mut self, message_id: MessageId) { + self.message_id = message_id; + } + /// Returns the Tangle message id of the previous DID Document diff. pub fn previous_message_id(&self) -> &MessageId { &self.previous_message_id } + /// Sets the Tangle message id of the previous DID Document diff. + pub fn set_previous_message_id(&mut self, message_id: MessageId) { + self.previous_message_id = message_id; + } + /// Returns a reference to the DID Document proof. pub fn proof(&self) -> Option<&Signature> { self.proof.as_ref() @@ -83,28 +97,6 @@ impl DiffMessage { } } -impl TangleRef for DiffMessage { - fn did(&self) -> &IotaDID { - self.id() - } - - fn message_id(&self) -> &MessageId { - &self.message_id - } - - fn set_message_id(&mut self, message_id: MessageId) { - self.message_id = message_id; - } - - fn previous_message_id(&self) -> &MessageId { - &self.previous_message_id - } - - fn set_previous_message_id(&mut self, message_id: MessageId) { - self.previous_message_id = message_id; - } -} - impl TrySignature for DiffMessage { fn signature(&self) -> Option<&Signature> { self.proof.as_ref() diff --git a/identity-iota/src/diff/mod.rs b/identity-iota-core/src/diff/mod.rs similarity index 100% rename from identity-iota/src/diff/mod.rs rename to identity-iota-core/src/diff/mod.rs diff --git a/identity-iota/src/document/iota_document.rs b/identity-iota-core/src/document/iota_document.rs similarity index 98% rename from identity-iota/src/document/iota_document.rs rename to identity-iota-core/src/document/iota_document.rs index dd31d2a1ae..976e74946e 100644 --- a/identity-iota/src/document/iota_document.rs +++ b/identity-iota-core/src/document/iota_document.rs @@ -5,10 +5,6 @@ use core::fmt; use core::fmt::Debug; use core::fmt::Display; -use serde; -use serde::Deserialize; -use serde::Serialize; - use identity_core::common::Object; use identity_core::common::OneOrSet; use identity_core::common::OrderedSet; @@ -37,6 +33,9 @@ use identity_did::verification::MethodType; use identity_did::verification::MethodUriType; use identity_did::verification::TryMethod; use identity_did::verification::VerificationMethod; +use serde; +use serde::Deserialize; +use serde::Serialize; use crate::did::IotaDID; use crate::did::IotaDIDUrl; @@ -90,7 +89,7 @@ impl IotaDocument { /// /// ``` /// # use identity_core::crypto::KeyPair; - /// # use identity_iota::document::IotaDocument; + /// # use identity_iota_core::document::IotaDocument; /// # /// // Create a DID Document from a new Ed25519 keypair. /// let keypair = KeyPair::new_ed25519().unwrap(); @@ -115,8 +114,8 @@ impl IotaDocument { /// /// ``` /// # use identity_core::crypto::KeyPair; - /// # use identity_iota::document::IotaDocument; - /// # use identity_iota::tangle::Network; + /// # use identity_iota_core::document::IotaDocument; + /// # use identity_iota_core::tangle::Network; /// # /// // Create a new DID Document for the devnet from a new Ed25519 keypair. /// let keypair = KeyPair::new_ed25519().unwrap(); @@ -482,15 +481,19 @@ impl IotaDocument { pub fn verify_root_document(document: &IotaDocument) -> Result<()> { // The previous message id must be null. if !document.metadata.previous_message_id.is_null() { - return Err(Error::InvalidRootDocument); + return Err(Error::InvalidRootDocument("previousMessageId not null")); } // Validate the hash of the public key matches the DID tag. - let signature: &Signature = document.try_signature()?; + let signature: &Signature = document + .try_signature() + .map_err(|err| Error::InvalidRootDocument(err.into()))?; let method: &IotaVerificationMethod = document.try_resolve_method(signature)?; let public: PublicKey = method.key_data().try_decode()?.into(); if document.id().tag() != IotaDID::encode_key(public.as_ref()) { - return Err(Error::InvalidRootDocument); + return Err(Error::InvalidRootDocument( + "DID tag does not match any verification method", + )); } // Validate the document is correctly self-signed. @@ -591,7 +594,7 @@ impl IotaDocument { Ok(IotaDID::encode_key(message_id.encode_hex().as_bytes())) } - pub(crate) fn extract_signing_keys(&self) -> Vec> { + pub fn extract_signing_keys(&self) -> Vec> { self .core_document() .capability_invocation() @@ -660,7 +663,7 @@ impl AsRef for IotaDocument { mod tests { use std::str::FromStr; - use iota_client::bee_message::MESSAGE_ID_LENGTH; + use bee_message::MESSAGE_ID_LENGTH; use identity_core::common::Object; use identity_core::common::OneOrSet; diff --git a/identity-iota/src/document/iota_document_metadata.rs b/identity-iota-core/src/document/iota_document_metadata.rs similarity index 96% rename from identity-iota/src/document/iota_document_metadata.rs rename to identity-iota-core/src/document/iota_document_metadata.rs index 3a0d9a0816..94b5475f9b 100644 --- a/identity-iota/src/document/iota_document_metadata.rs +++ b/identity-iota-core/src/document/iota_document_metadata.rs @@ -6,13 +6,12 @@ use core::fmt::Display; use core::fmt::Formatter; use core::fmt::Result as FmtResult; -use serde::Deserialize; -use serde::Serialize; - use identity_core::common::Object; use identity_core::common::Timestamp; use identity_core::convert::FmtJson; use identity_core::crypto::Signature; +use serde::Deserialize; +use serde::Serialize; use crate::tangle::MessageId; use crate::tangle::MessageIdExt; @@ -25,7 +24,7 @@ pub struct IotaDocumentMetadata { #[serde( rename = "previousMessageId", default = "MessageId::null", - skip_serializing_if = "MessageIdExt::is_null" + skip_serializing_if = "MessageId::is_null" )] pub previous_message_id: MessageId, #[serde(skip_serializing_if = "Option::is_none")] diff --git a/identity-iota-core/src/document/mod.rs b/identity-iota-core/src/document/mod.rs new file mode 100644 index 0000000000..167e1dfa61 --- /dev/null +++ b/identity-iota-core/src/document/mod.rs @@ -0,0 +1,11 @@ +// Copyright 2020-2022 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +pub use self::iota_document::IotaCoreDocument; +pub use self::iota_document::IotaDocument; +pub use self::iota_document::IotaService; +pub use self::iota_document::IotaVerificationMethod; +pub use self::iota_document_metadata::IotaDocumentMetadata; + +mod iota_document; +mod iota_document_metadata; diff --git a/identity-iota-core/src/error.rs b/identity-iota-core/src/error.rs new file mode 100644 index 0000000000..79ded1089f --- /dev/null +++ b/identity-iota-core/src/error.rs @@ -0,0 +1,29 @@ +// Copyright 2020-2022 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +pub type Result = core::result::Result; + +#[derive(Debug, thiserror::Error, strum::IntoStaticStr)] +pub enum Error { + #[error("{0}")] + DiffError(#[from] identity_core::diff::Error), + #[error("{0}")] + InvalidDID(#[from] identity_did::did::DIDError), + #[error("{0}")] + InvalidDoc(#[from] identity_did::Error), + #[error("Invalid Message: {0}")] + InvalidMessage(#[from] bee_message::Error), + + #[error("signing failed: {0}")] + DocumentSignError(&'static str, #[source] Option), + #[error("Invalid Document - Missing Message Id")] + InvalidDocumentMessageId, + #[error("Invalid Document - Signing Verification Method Type Not Supported")] + InvalidDocumentSigningMethodType, + #[error("Invalid Network Name")] + InvalidNetworkName, + #[error("invalid root document: {0}")] + InvalidRootDocument(&'static str), + #[error("Missing Signing Key")] + MissingSigningKey, +} diff --git a/identity-iota-core/src/lib.rs b/identity-iota-core/src/lib.rs new file mode 100644 index 0000000000..a7b5cb97eb --- /dev/null +++ b/identity-iota-core/src/lib.rs @@ -0,0 +1,28 @@ +// Copyright 2020-2022 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +#![forbid(unsafe_code)] +#![cfg_attr(docsrs, feature(doc_cfg, extended_key_value_attributes))] +#![cfg_attr(docsrs, cfg_attr(docsrs, doc = include_str!("../README.md")))] +#![cfg_attr(not(docsrs), doc = "")] +#![allow(clippy::upper_case_acronyms)] +#![warn( + rust_2018_idioms, + unreachable_pub, + // missing_docs, + rustdoc::missing_crate_level_docs, + rustdoc::broken_intra_doc_links, + rustdoc::private_intra_doc_links, + rustdoc::private_doc_tests, + clippy::missing_safety_doc, + // clippy::missing_errors_doc, +)] + +pub use self::error::Error; +pub use self::error::Result; + +pub mod did; +pub mod diff; +pub mod document; +pub mod error; +pub mod tangle; diff --git a/identity-iota-core/src/tangle/message_id.rs b/identity-iota-core/src/tangle/message_id.rs new file mode 100644 index 0000000000..9cb24f58c2 --- /dev/null +++ b/identity-iota-core/src/tangle/message_id.rs @@ -0,0 +1,39 @@ +// Copyright 2020-2022 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +// Re-export types from bee-message to avoid adding it or iota-client as a dependency for +// downstream crates. +#[doc(inline)] +pub use bee_message::Message; +#[doc(inline)] +pub use bee_message::MessageId; + +use crate::Error; +use bee_message::MESSAGE_ID_LENGTH; + +use crate::error::Result; + +// TODO: Use MessageId when it has a const ctor +static NULL: &[u8; MESSAGE_ID_LENGTH] = &[0; MESSAGE_ID_LENGTH]; + +pub trait MessageIdExt: Sized { + fn is_null(&self) -> bool; + + fn encode_hex(&self) -> String; + + fn decode_hex(hex: &str) -> Result; +} + +impl MessageIdExt for MessageId { + fn is_null(&self) -> bool { + self.as_ref() == NULL + } + + fn encode_hex(&self) -> String { + self.to_string() + } + + fn decode_hex(hex: &str) -> Result { + hex.parse().map_err(Error::InvalidMessage) + } +} diff --git a/identity-iota-core/src/tangle/mod.rs b/identity-iota-core/src/tangle/mod.rs new file mode 100644 index 0000000000..ee31431993 --- /dev/null +++ b/identity-iota-core/src/tangle/mod.rs @@ -0,0 +1,12 @@ +// Copyright 2020-2022 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +pub use network::Network; +pub use network::NetworkName; + +mod message_id; +mod network; + +pub use message_id::Message; +pub use message_id::MessageId; +pub use message_id::MessageIdExt; diff --git a/identity-iota/src/tangle/network.rs b/identity-iota-core/src/tangle/network.rs similarity index 100% rename from identity-iota/src/tangle/network.rs rename to identity-iota-core/src/tangle/network.rs diff --git a/identity-iota/Cargo.toml b/identity-iota/Cargo.toml index 9c362aa5fc..2a501f7707 100644 --- a/identity-iota/Cargo.toml +++ b/identity-iota/Cargo.toml @@ -16,9 +16,10 @@ bee-rest-api = { version = "0.1.7", default-features = false } brotli = { version = "3.3", default-features = false, features = ["std"] } form_urlencoded = { version = "1.0" } futures = { version = "0.3" } -identity-core = { version = "=0.5.0-dev.4", path = "../identity-core" } +identity-core = { version = "=0.5.0-dev.4", path = "../identity-core", default-features = false } identity-credential = { version = "=0.5.0-dev.4", path = "../identity-credential" } identity-did = { version = "=0.5.0-dev.4", path = "../identity-did" } +identity-iota-core = { version = "=0.5.0-dev.4", path = "../identity-iota-core", default-features = false } itertools = { version = "0.10" } lazy_static = { version = "1.4", default-features = false } log = { version = "0.4", default-features = false } @@ -48,7 +49,7 @@ features = ["blake2b"] [dev-dependencies] proptest = { version = "1.0.0", default-features = false, features = ["std"] } -tokio = { version = "1.15", default-features = false, features = ["macros"] } +tokio = { version = "1.17.0", default-features = false, features = ["macros"] } [features] default = ["async"] diff --git a/identity-iota/src/chain/diff_chain.rs b/identity-iota/src/chain/diff_chain.rs index ad8007973f..2157dd24d3 100644 --- a/identity-iota/src/chain/diff_chain.rs +++ b/identity-iota/src/chain/diff_chain.rs @@ -5,24 +5,23 @@ use core::fmt::Display; use core::fmt::Formatter; use core::slice::Iter; +use identity_core::convert::FmtJson; +use identity_iota_core::did::IotaDID; +use identity_iota_core::diff::DiffMessage; +use identity_iota_core::tangle::Message; +use identity_iota_core::tangle::MessageId; +use identity_iota_core::tangle::MessageIdExt; use serde; use serde::Deserialize; use serde::Serialize; -use identity_core::convert::FmtJson; - use crate::chain::milestone::sort_by_milestone; use crate::chain::IntegrationChain; -use crate::did::IotaDID; -use crate::diff::DiffMessage; use crate::document::ResolvedIotaDocument; use crate::error::Error; use crate::error::Result; use crate::tangle::Client; -use crate::tangle::Message; use crate::tangle::MessageExt; -use crate::tangle::MessageId; -use crate::tangle::MessageIdExt; use crate::tangle::MessageIndex; use crate::tangle::PublishType; use crate::tangle::TangleRef; @@ -49,7 +48,7 @@ impl DiffChain { log::debug!("[Diff] Valid Messages = {}/{}", messages.len(), index.len()); - Ok(Self::try_from_index(integration_chain, index, client).await?) + Self::try_from_index(integration_chain, index, client).await } /// Constructs a new [`DiffChain`] for the given [`IntegrationChain`] from the given [`MessageIndex`]. @@ -183,7 +182,7 @@ impl DiffChain { document: &ResolvedIotaDocument, expected_prev_message_id: &MessageId, ) -> Result<()> { - if document.document.id() != &diff.id { + if document.document.id() != diff.id() { return Err(Error::ChainError { error: "invalid DID" }); } @@ -274,13 +273,13 @@ mod tests { use identity_core::json; use identity_did::did::DID; use identity_did::service::Service; + use identity_iota_core::diff::DiffMessage; + use identity_iota_core::document::IotaDocument; + use identity_iota_core::document::IotaService; + use identity_iota_core::tangle::MessageId; - use crate::diff::DiffMessage; - use crate::document::IotaDocument; - use crate::document::IotaService; use crate::document::ResolvedIotaDocument; use crate::tangle::ClientBuilder; - use crate::tangle::MessageId; use crate::tangle::MessageIndex; use crate::tangle::TangleRef; @@ -332,7 +331,7 @@ mod tests { let mut diff_delete: DiffMessage = updated1 .diff( &updated2, - diff_add.message_id, + *diff_add.message_id(), keypair.private(), updated1.default_signing_method().unwrap().id(), ) @@ -392,13 +391,13 @@ mod tests { })) .unwrap(); updated2 - .document + .core_document_mut() .service_mut() .replace(&service, service_updated.clone()); let mut diff_edit: DiffMessage = updated1 .diff( &updated2, - diff_add.message_id, + *diff_add.message_id(), keypair.private(), updated1.default_signing_method().unwrap().id(), ) diff --git a/identity-iota/src/chain/document_chain.rs b/identity-iota/src/chain/document_chain.rs index 9e493b6f22..38ac45f083 100644 --- a/identity-iota/src/chain/document_chain.rs +++ b/identity-iota/src/chain/document_chain.rs @@ -4,18 +4,17 @@ use core::fmt::Display; use core::fmt::Formatter; +use identity_core::convert::FmtJson; +use identity_iota_core::did::IotaDID; +use identity_iota_core::diff::DiffMessage; +use identity_iota_core::tangle::MessageId; use serde::Deserialize; use serde::Serialize; -use identity_core::convert::FmtJson; - use crate::chain::DiffChain; use crate::chain::IntegrationChain; -use crate::did::IotaDID; -use crate::diff::DiffMessage; use crate::document::ResolvedIotaDocument; use crate::error::Result; -use crate::tangle::MessageId; /// Holds an [`IntegrationChain`] and its corresponding [`DiffChain`] that can be used to resolve the /// latest version of a [`ResolvedIotaDocument`]. @@ -169,10 +168,10 @@ mod test { use identity_did::verification::MethodRelationship; use identity_did::verification::MethodScope; use identity_did::verification::MethodType; + use identity_iota_core::did::IotaDIDUrl; + use identity_iota_core::document::IotaDocument; + use identity_iota_core::document::IotaVerificationMethod; - use crate::did::IotaDIDUrl; - use crate::document::IotaDocument; - use crate::document::IotaVerificationMethod; use crate::tangle::TangleRef; use crate::Error; diff --git a/identity-iota/src/chain/document_history.rs b/identity-iota/src/chain/document_history.rs index 8e70a3638a..282573629f 100644 --- a/identity-iota/src/chain/document_history.rs +++ b/identity-iota/src/chain/document_history.rs @@ -1,24 +1,24 @@ -// Copyright 2020-2021 IOTA Stiftung +// Copyright 2020-2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 use std::collections::HashSet; use std::ops::Deref; +use identity_iota_core::did::IotaDID; +use identity_iota_core::diff::DiffMessage; +use identity_iota_core::document::IotaDocument; +use identity_iota_core::tangle::Message; +use identity_iota_core::tangle::MessageId; use serde; use serde::Deserialize; use serde::Serialize; use crate::chain::DiffChain; use crate::chain::IntegrationChain; -use crate::did::IotaDID; -use crate::diff::DiffMessage; -use crate::document::IotaDocument; use crate::document::ResolvedIotaDocument; use crate::error::Result; use crate::tangle::Client; -use crate::tangle::Message; use crate::tangle::MessageExt; -use crate::tangle::MessageId; use crate::tangle::MessageIndex; use crate::tangle::TangleRef; diff --git a/identity-iota/src/chain/integration_chain.rs b/identity-iota/src/chain/integration_chain.rs index d9ff324ad4..d0be119543 100644 --- a/identity-iota/src/chain/integration_chain.rs +++ b/identity-iota/src/chain/integration_chain.rs @@ -1,28 +1,26 @@ -// Copyright 2020-2021 IOTA Stiftung +// Copyright 2020-2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 use core::fmt::Display; use core::fmt::Formatter; - use core::mem; +use identity_core::convert::FmtJson; +use identity_iota_core::did::IotaDID; +use identity_iota_core::document::IotaDocument; +use identity_iota_core::tangle::Message; +use identity_iota_core::tangle::MessageId; +use identity_iota_core::tangle::MessageIdExt; use serde; use serde::Deserialize; use serde::Serialize; -use identity_core::convert::FmtJson; - use crate::chain::milestone::sort_by_milestone; -use crate::did::IotaDID; -use crate::document::IotaDocument; use crate::document::ResolvedIotaDocument; use crate::error::Error; use crate::error::Result; use crate::tangle::Client; -use crate::tangle::Message; use crate::tangle::MessageExt; -use crate::tangle::MessageId; -use crate::tangle::MessageIdExt; use crate::tangle::MessageIndex; use crate::tangle::TangleRef; diff --git a/identity-iota/src/chain/milestone.rs b/identity-iota/src/chain/milestone.rs index 8434e451c2..649d147488 100644 --- a/identity-iota/src/chain/milestone.rs +++ b/identity-iota/src/chain/milestone.rs @@ -67,8 +67,8 @@ fn sort_by_milestone_index(messages_milestones: Vec<(Option, #[cfg(test)] mod tests { - use crate::did::IotaDID; - use crate::tangle::MessageId; + use identity_iota_core::did::IotaDID; + use identity_iota_core::tangle::MessageId; use super::*; diff --git a/identity-iota/src/credential/credential_validator.rs b/identity-iota/src/credential/credential_validator.rs index 83333938cb..3d05ddc1d2 100644 --- a/identity-iota/src/credential/credential_validator.rs +++ b/identity-iota/src/credential/credential_validator.rs @@ -1,16 +1,13 @@ // Copyright 2020-2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -use crate::credential::errors::CompoundCredentialValidationError; -use crate::did::IotaDID; -use crate::document::IotaDocument; - -use crate::Result; use identity_core::common::OneOrMany; use identity_core::common::Timestamp; use identity_core::common::Url; use identity_credential::credential::Credential; use identity_did::verifiable::VerifierOptions; +use identity_iota_core::did::IotaDID; +use identity_iota_core::document::IotaDocument; use serde::Serialize; use super::errors::SignerContext; @@ -18,6 +15,8 @@ use super::errors::ValidationError; use super::CredentialValidationOptions; use super::FailFast; use super::SubjectHolderRelationship; +use crate::credential::errors::CompoundCredentialValidationError; +use crate::Result; /// A struct for validating [`Credential`]s. #[derive(Debug, Clone)] @@ -105,7 +104,7 @@ impl CredentialValidator { ) -> ValidationUnitResult { // try to extract the corresponding issuer from `trusted_issuers` let extracted_issuer_result: std::result::Result<&IotaDocument, ValidationError> = { - let issuer_did: Result = credential.issuer.url().as_str().parse(); + let issuer_did: Result = credential.issuer.url().as_str().parse().map_err(Into::into); match issuer_did { Ok(did) => { // if the issuer_did corresponds to one of the trusted issuers we use the corresponding DID Document to verify @@ -226,19 +225,17 @@ mod tests { use identity_core::common::Duration; use identity_core::common::Object; use identity_core::common::OneOrMany; - use identity_credential::credential::Subject; - use identity_did::did::DID; - use proptest::proptest; - use identity_core::common::Timestamp; - use identity_core::convert::FromJson; use identity_core::crypto::KeyPair; use identity_core::crypto::SignatureOptions; + use identity_credential::credential::Subject; + use identity_did::did::DID; + use identity_iota_core::document::IotaDocument; + use proptest::proptest; use crate::credential::test_utils; use crate::credential::CredentialValidationOptions; - use crate::document::IotaDocument; const LAST_RFC3339_COMPATIBLE_UNIX_TIMESTAMP: i64 = 253402300799; // 9999-12-31T23:59:59Z const FIRST_RFC3999_COMPATIBLE_UNIX_TIMESTAMP: i64 = -62167219200; // 0000-01-01T00:00:00Z diff --git a/identity-iota/src/credential/presentation_validator.rs b/identity-iota/src/credential/presentation_validator.rs index a6ebd8578a..8251d9093b 100644 --- a/identity-iota/src/credential/presentation_validator.rs +++ b/identity-iota/src/credential/presentation_validator.rs @@ -5,6 +5,8 @@ use std::collections::BTreeMap; use identity_credential::presentation::Presentation; use identity_did::verifiable::VerifierOptions; +use identity_iota_core::did::IotaDID; +use identity_iota_core::document::IotaDocument; use serde::Serialize; use super::errors::CompoundCredentialValidationError; @@ -14,8 +16,6 @@ use super::errors::ValidationError; use super::FailFast; use super::PresentationValidationOptions; use crate::credential::credential_validator::CredentialValidator; -use crate::did::IotaDID; -use crate::document::IotaDocument; /// A struct for validating [`Presentation`]s. #[derive(Debug, Clone)] @@ -223,18 +223,18 @@ impl PresentationValidator { #[cfg(test)] mod tests { - use crate::credential::test_utils; - use crate::credential::CredentialValidationOptions; - use crate::credential::SubjectHolderRelationship; - use crate::document::IotaDocument; use identity_core::common::Timestamp; use identity_core::common::Url; use identity_core::crypto::KeyPair; use identity_core::crypto::SignatureOptions; use identity_credential::credential::Credential; use identity_credential::presentation::PresentationBuilder; + use identity_iota_core::document::IotaDocument; use super::*; + use crate::credential::test_utils; + use crate::credential::CredentialValidationOptions; + use crate::credential::SubjectHolderRelationship; fn build_presentation(holder: &IotaDocument, credentials: Vec) -> Presentation { let mut builder = PresentationBuilder::default() diff --git a/identity-iota/src/credential/test_utils.rs b/identity-iota/src/credential/test_utils.rs index 8954ece5f6..469f57b50e 100644 --- a/identity-iota/src/credential/test_utils.rs +++ b/identity-iota/src/credential/test_utils.rs @@ -1,20 +1,18 @@ // Copyright 2020-2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -use crate::Result; use identity_core::common::Timestamp; use identity_core::common::Url; use identity_core::convert::FromJson; use identity_core::crypto::KeyPair; - use identity_core::json; use identity_credential::credential::Credential; use identity_credential::credential::CredentialBuilder; use identity_credential::credential::Subject; - use identity_did::did::DID; +use identity_iota_core::document::IotaDocument; -use crate::document::IotaDocument; +use crate::Result; pub(super) fn generate_document_with_keys() -> (IotaDocument, KeyPair) { let keypair: KeyPair = KeyPair::new_ed25519().unwrap(); diff --git a/identity-iota/src/document/mod.rs b/identity-iota/src/document/mod.rs index b3e33d5860..7673da7966 100644 --- a/identity-iota/src/document/mod.rs +++ b/identity-iota/src/document/mod.rs @@ -1,13 +1,6 @@ // Copyright 2020-2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -pub use self::iota_document::IotaCoreDocument; -pub use self::iota_document::IotaDocument; -pub use self::iota_document::IotaService; -pub use self::iota_document::IotaVerificationMethod; -pub use self::iota_document_metadata::IotaDocumentMetadata; pub use self::resolved_iota_document::ResolvedIotaDocument; -mod iota_document; -mod iota_document_metadata; mod resolved_iota_document; diff --git a/identity-iota/src/document/resolved_iota_document.rs b/identity-iota/src/document/resolved_iota_document.rs index 6026d97821..f23371fe16 100644 --- a/identity-iota/src/document/resolved_iota_document.rs +++ b/identity-iota/src/document/resolved_iota_document.rs @@ -6,17 +6,16 @@ use core::fmt::Display; use core::fmt::Formatter; use core::fmt::Result as FmtResult; +use identity_core::convert::FmtJson; +use identity_iota_core::did::IotaDID; +use identity_iota_core::diff::DiffMessage; +use identity_iota_core::document::IotaDocument; +use identity_iota_core::tangle::MessageId; +use identity_iota_core::tangle::MessageIdExt; use serde::Deserialize; use serde::Serialize; -use identity_core::convert::FmtJson; - -use crate::did::IotaDID; -use crate::diff::DiffMessage; -use crate::document::IotaDocument; use crate::error::Result; -use crate::tangle::MessageId; -use crate::tangle::MessageIdExt; use crate::tangle::TangleRef; /// An IOTA DID document resolved from the Tangle. Represents an integration chain message possibly @@ -58,7 +57,7 @@ impl ResolvedIotaDocument { /// Fails if the merge operation or signature verification on the diff fails. pub fn merge_diff_message(&mut self, diff_message: &DiffMessage) -> Result<()> { self.document.merge_diff(diff_message)?; - self.diff_message_id = diff_message.message_id; + self.diff_message_id = *diff_message.message_id(); Ok(()) } diff --git a/identity-iota/src/error.rs b/identity-iota/src/error.rs index b83d9a25e4..a393607ff9 100644 --- a/identity-iota/src/error.rs +++ b/identity-iota/src/error.rs @@ -8,8 +8,6 @@ pub enum Error { #[error("{0}")] CoreError(#[from] identity_core::Error), #[error("{0}")] - DiffError(#[from] identity_core::diff::Error), - #[error("{0}")] CredError(#[from] identity_credential::Error), #[error("{0}")] InvalidDID(#[from] identity_did::did::DIDError), @@ -17,27 +15,15 @@ pub enum Error { InvalidDoc(#[from] identity_did::Error), #[error("{0}")] ClientError(#[from] iota_client::error::Error), - #[error("Invalid Message: {0}")] - InvalidMessage(#[from] iota_client::bee_message::Error), + #[error("{0}")] + IotaCoreError(#[from] identity_iota_core::Error), #[error("{0}")] DIDNotFound(String), - #[error("Invalid Document - Missing Message Id")] - InvalidDocumentMessageId, - #[error("Invalid Document - Signing Verification Method Type Not Supported")] - InvalidDocumentSigningMethodType, - #[error("Invalid Root Document")] - InvalidRootDocument, - #[error("Invalid Network Name")] - InvalidNetworkName, - #[error("signing failed: {0}")] - DocumentSignError(&'static str, #[source] Option), #[error("{0}")] IncompatibleNetwork(String), #[error("Chain Error: {error}")] ChainError { error: &'static str }, - #[error("Missing Signing Key")] - MissingSigningKey, #[error("no client nodes provided for network")] NoClientNodesProvided, #[error("Invalid Explorer Url")] @@ -49,7 +35,7 @@ pub enum Error { /// Caused by a single concern credential or presentation validation method failing. #[error("A validation unit failed")] IsolatedValidationError(#[from] crate::credential::ValidationError), - /// Caused by one or more failures when validating a credential. + /// Caused by one or more failures when validating a credential. #[error("credential validation failed")] CredentialValidationError(#[from] crate::credential::CompoundCredentialValidationError), /// Caused by one or more failures when validating a presentation. diff --git a/identity-iota/src/lib.rs b/identity-iota/src/lib.rs index 85e1c00a92..e7655508a6 100644 --- a/identity-iota/src/lib.rs +++ b/identity-iota/src/lib.rs @@ -25,8 +25,6 @@ mod resolver; pub mod chain; pub mod credential; -pub mod did; -pub mod diff; pub mod document; pub mod error; pub mod tangle; diff --git a/identity-iota/src/resolver.rs b/identity-iota/src/resolver.rs index da302a1666..02197b555f 100644 --- a/identity-iota/src/resolver.rs +++ b/identity-iota/src/resolver.rs @@ -1,16 +1,18 @@ -// Copyright 2020-2021 IOTA Stiftung +// Copyright 2020-2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 use async_trait::async_trait; use identity_did::did::CoreDID; +use identity_did::document::CoreDocument; use identity_did::error::Error; use identity_did::error::Result; use identity_did::resolution::DocumentMetadata; use identity_did::resolution::InputMetadata; use identity_did::resolution::MetaDocument; use identity_did::resolution::ResolverMethod; +use identity_iota_core::did::IotaDID; +use identity_iota_core::document::IotaCoreDocument; -use crate::did::IotaDID; use crate::document::ResolvedIotaDocument; use crate::tangle::Client; use crate::tangle::TangleResolve; @@ -32,8 +34,10 @@ impl ResolverMethod for Client { metadata.created = Some(resolved.document.metadata.created); metadata.updated = Some(resolved.document.metadata.updated); + let core_document: CoreDocument = + IotaCoreDocument::from(resolved.document).map(CoreDID::from, |properties| properties); Ok(Some(MetaDocument { - data: resolved.document.document.map(CoreDID::from, |properties| properties), + data: core_document, meta: metadata, })) } diff --git a/identity-iota/src/tangle/client.rs b/identity-iota/src/tangle/client.rs index f5046dee1d..74eec64187 100644 --- a/identity-iota/src/tangle/client.rs +++ b/identity-iota/src/tangle/client.rs @@ -4,27 +4,26 @@ use bee_rest_api::types::dtos::LedgerInclusionStateDto; use futures::stream::FuturesUnordered; use futures::stream::TryStreamExt; +use identity_core::convert::ToJson; +use identity_iota_core::did::IotaDID; +use identity_iota_core::diff::DiffMessage; +use identity_iota_core::document::IotaDocument; +use identity_iota_core::tangle::Message; +use identity_iota_core::tangle::MessageId; +use identity_iota_core::tangle::Network; use iota_client::Client as IotaClient; use iota_client::Error as IotaClientError; -use identity_core::convert::ToJson; - use crate::chain::ChainHistory; use crate::chain::DiffChain; use crate::chain::DocumentChain; use crate::chain::DocumentHistory; use crate::chain::IntegrationChain; -use crate::did::IotaDID; -use crate::diff::DiffMessage; -use crate::document::IotaDocument; use crate::document::ResolvedIotaDocument; use crate::error::Error; use crate::error::Result; use crate::tangle::ClientBuilder; use crate::tangle::DIDMessageEncoding; -use crate::tangle::Message; -use crate::tangle::MessageId; -use crate::tangle::Network; use crate::tangle::Receipt; use crate::tangle::TangleRef; use crate::tangle::TangleResolve; @@ -222,7 +221,7 @@ impl Client { pub async fn resolve_diff_history(&self, document: &ResolvedIotaDocument) -> Result> { let diff_index: String = IotaDocument::diff_index(document.message_id())?; let diff_messages: Vec = self.read_messages(&diff_index).await?; - Ok(ChainHistory::try_from_raw_messages(document, &diff_messages, self).await?) + ChainHistory::try_from_raw_messages(document, &diff_messages, self).await } /// Fetch all [`Messages`][Message] from the given index on the IOTA Tangle. diff --git a/identity-iota/src/tangle/client_builder.rs b/identity-iota/src/tangle/client_builder.rs index 5c9b18cb41..e834bbec94 100644 --- a/identity-iota/src/tangle/client_builder.rs +++ b/identity-iota/src/tangle/client_builder.rs @@ -1,15 +1,15 @@ -// Copyright 2020-2021 IOTA Stiftung +// Copyright 2020-2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 use core::fmt::Debug; use core::fmt::Formatter; - use std::time::Duration; +use identity_iota_core::tangle::Network; + use crate::error::Result; use crate::tangle::Client; use crate::tangle::DIDMessageEncoding; -use crate::tangle::Network; const DEFAULT_LOCAL_POW: bool = false; diff --git a/identity-iota/src/tangle/explorer.rs b/identity-iota/src/tangle/explorer.rs index 9f6640b7e5..fd2c5c7f47 100644 --- a/identity-iota/src/tangle/explorer.rs +++ b/identity-iota/src/tangle/explorer.rs @@ -1,4 +1,4 @@ -// Copyright 2020-2021 IOTA Stiftung +// Copyright 2020-2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 use core::convert::TryFrom; @@ -6,16 +6,15 @@ use core::fmt::Display; use core::fmt::Formatter; use std::str::FromStr; +use identity_core::common::Url; +use identity_did::did::DID; +use identity_iota_core::tangle::MessageId; use serde; use serde::Deserialize; use serde::Serialize; -use identity_core::common::Url; -use identity_did::did::DID; - use crate::error::Error; use crate::error::Result; -use crate::tangle::MessageId; lazy_static::lazy_static! { static ref EXPLORER_MAIN: ExplorerUrl = @@ -30,7 +29,7 @@ lazy_static::lazy_static! { /// # Example /// /// ``` -/// # use identity_iota::did::IotaDID; +/// # use identity_iota_core::did::IotaDID; /// # use identity_iota::tangle::ExplorerUrl; /// let explorer = ExplorerUrl::mainnet(); /// let did = IotaDID::parse("did:iota:H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV")?; @@ -153,7 +152,7 @@ impl Display for ExplorerUrl { #[cfg(test)] mod tests { - use crate::did::IotaDID; + use identity_iota_core::did::IotaDID; use super::*; diff --git a/identity-iota/src/tangle/message/compression_brotli.rs b/identity-iota/src/tangle/message/compression_brotli.rs index 1704464fea..2cb8ddc06c 100644 --- a/identity-iota/src/tangle/message/compression_brotli.rs +++ b/identity-iota/src/tangle/message/compression_brotli.rs @@ -30,8 +30,7 @@ pub(crate) fn decompress_brotli + ?Sized>(input: &T) -> Result(message: &Message, did: &IotaDID) -> Option { let message_id: MessageId = message.id().0; let payload: Option<&Payload> = message.payload().as_ref(); @@ -106,28 +101,6 @@ fn add_flags_to_message( buffer } -pub trait MessageIdExt: Sized { - fn is_null(&self) -> bool; - - fn encode_hex(&self) -> String; - - fn decode_hex(hex: &str) -> Result; -} - -impl MessageIdExt for MessageId { - fn is_null(&self) -> bool { - self.as_ref() == NULL - } - - fn encode_hex(&self) -> String { - self.to_string() - } - - fn decode_hex(hex: &str) -> Result { - hex.parse().map_err(Into::into) - } -} - pub trait MessageExt { fn try_extract_document(&self, did: &IotaDID) -> Option; @@ -168,12 +141,12 @@ mod test { use identity_did::service::ServiceBuilder; use identity_did::service::ServiceEndpoint; use identity_did::verification::MethodScope; + use identity_iota_core::document::IotaDocument; + use identity_iota_core::document::IotaVerificationMethod; + use identity_iota_core::tangle::MessageId; - use crate::document::IotaDocument; - use crate::document::IotaVerificationMethod; use crate::document::ResolvedIotaDocument; use crate::tangle::message::message_encoding::DIDMessageEncoding; - use crate::tangle::MessageId; use super::*; diff --git a/identity-iota/src/tangle/message/message_index.rs b/identity-iota/src/tangle/message/message_index.rs index 51fb36a27c..a2159f6953 100644 --- a/identity-iota/src/tangle/message/message_index.rs +++ b/identity-iota/src/tangle/message/message_index.rs @@ -1,4 +1,4 @@ -// Copyright 2020-2021 IOTA Stiftung +// Copyright 2020-2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 use core::borrow::Borrow; @@ -8,7 +8,8 @@ use core::ops::Deref; use core::ops::DerefMut; use std::collections::HashMap; -use crate::tangle::MessageId; +use identity_iota_core::tangle::MessageId; + use crate::tangle::TangleRef; type __Index = HashMap>; @@ -114,7 +115,7 @@ where #[cfg(test)] mod tests { - use crate::did::IotaDID; + use identity_iota_core::did::IotaDID; use super::*; diff --git a/identity-iota/src/tangle/message/mod.rs b/identity-iota/src/tangle/message/mod.rs index 03d8ecd71f..b7ac52c486 100644 --- a/identity-iota/src/tangle/message/mod.rs +++ b/identity-iota/src/tangle/message/mod.rs @@ -4,7 +4,6 @@ pub use self::message_encoding::DIDMessageEncoding; pub(crate) use self::message_ext::pack_did_message; pub use self::message_ext::MessageExt; -pub use self::message_ext::MessageIdExt; pub use self::message_ext::TryFromMessage; pub use self::message_index::MessageIndex; pub use self::message_version::DIDMessageVersion; diff --git a/identity-iota/src/tangle/mod.rs b/identity-iota/src/tangle/mod.rs index 9080febb1b..3806d325f3 100644 --- a/identity-iota/src/tangle/mod.rs +++ b/identity-iota/src/tangle/mod.rs @@ -1,14 +1,6 @@ // Copyright 2020-2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -// Re-export bee_message::Error to use it directly in bindings -#[doc(inline)] -pub use iota_client::bee_message::Error as BeeMessageError; -#[doc(inline)] -pub use iota_client::bee_message::Message; -#[doc(inline)] -pub use iota_client::bee_message::MessageId; - pub use self::client::Client; pub use self::client_builder::ClientBuilder; pub use self::explorer::ExplorerUrl; @@ -16,11 +8,8 @@ pub(crate) use self::message::pack_did_message; pub use self::message::DIDMessageEncoding; pub use self::message::DIDMessageVersion; pub use self::message::MessageExt; -pub use self::message::MessageIdExt; pub use self::message::MessageIndex; pub use self::message::TryFromMessage; -pub use self::network::Network; -pub use self::network::NetworkName; pub use self::publish::PublishType; pub use self::receipt::Receipt; pub use self::resolver::Resolver; @@ -32,7 +21,6 @@ mod client; mod client_builder; mod explorer; mod message; -mod network; mod publish; mod receipt; mod resolver; diff --git a/identity-iota/src/tangle/publish.rs b/identity-iota/src/tangle/publish.rs index 1ef56f8bd3..cff00fc4a9 100644 --- a/identity-iota/src/tangle/publish.rs +++ b/identity-iota/src/tangle/publish.rs @@ -1,8 +1,8 @@ -// Copyright 2020-2021 IOTA Stiftung +// Copyright 2020-2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -use crate::document::IotaDocument; -use crate::document::IotaVerificationMethod; +use identity_iota_core::document::IotaDocument; +use identity_iota_core::document::IotaVerificationMethod; /// Determines whether an updated document needs to be published as an integration or diff message. #[derive(Clone, Copy, Debug)] @@ -35,14 +35,14 @@ impl PublishType { #[cfg(test)] mod test { - use crate::did::IotaDIDUrl; use identity_core::crypto::merkle_key::Sha256; use identity_core::crypto::KeyCollection; use identity_core::crypto::KeyPair; use identity_did::did::DID; use identity_did::verification::MethodScope; + use identity_iota_core::did::IotaDIDUrl; + use identity_iota_core::document::IotaVerificationMethod; - use crate::document::IotaVerificationMethod; use crate::Result; use super::*; diff --git a/identity-iota/src/tangle/receipt.rs b/identity-iota/src/tangle/receipt.rs index 1616a17b2f..288623f9a6 100644 --- a/identity-iota/src/tangle/receipt.rs +++ b/identity-iota/src/tangle/receipt.rs @@ -1,13 +1,13 @@ -// Copyright 2020-2021 IOTA Stiftung +// Copyright 2020-2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 use serde; use serde::Deserialize; use serde::Serialize; -use crate::tangle::Message; -use crate::tangle::MessageId; -use crate::tangle::Network; +use identity_iota_core::tangle::Message; +use identity_iota_core::tangle::MessageId; +use identity_iota_core::tangle::Network; #[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] pub struct Receipt { diff --git a/identity-iota/src/tangle/resolver.rs b/identity-iota/src/tangle/resolver.rs index e30b34d5de..b022e25499 100644 --- a/identity-iota/src/tangle/resolver.rs +++ b/identity-iota/src/tangle/resolver.rs @@ -8,6 +8,9 @@ use std::sync::Arc; use identity_core::common::Url; use identity_credential::credential::Credential; use identity_credential::presentation::Presentation; +use identity_iota_core::did::IotaDID; +use identity_iota_core::diff::DiffMessage; +use identity_iota_core::tangle::NetworkName; use serde::Serialize; use crate::chain::ChainHistory; @@ -15,14 +18,11 @@ use crate::chain::DocumentHistory; use crate::credential::FailFast; use crate::credential::PresentationValidationOptions; use crate::credential::PresentationValidator; -use crate::did::IotaDID; -use crate::diff::DiffMessage; use crate::document::ResolvedIotaDocument; use crate::error::Error; use crate::error::Result; use crate::tangle::Client; use crate::tangle::ClientBuilder; -use crate::tangle::NetworkName; use crate::tangle::TangleResolve; /// A `Resolver` supports resolving DID Documents across different Tangle networks using diff --git a/identity-iota/src/tangle/traits.rs b/identity-iota/src/tangle/traits.rs index 73169d431e..53b8a09c01 100644 --- a/identity-iota/src/tangle/traits.rs +++ b/identity-iota/src/tangle/traits.rs @@ -1,12 +1,13 @@ // Copyright 2020-2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -use crate::did::IotaDID; +use identity_iota_core::did::IotaDID; +use identity_iota_core::diff::DiffMessage; +use identity_iota_core::tangle::MessageId; + use crate::document::ResolvedIotaDocument; use crate::error::Result; -use crate::tangle::MessageId; - pub trait TangleRef { fn did(&self) -> &IotaDID; @@ -25,3 +26,25 @@ pub trait TangleResolve { /// Resolves a DID on the Tangle async fn resolve(&self, did: &IotaDID) -> Result; } + +impl TangleRef for DiffMessage { + fn did(&self) -> &IotaDID { + self.id() + } + + fn message_id(&self) -> &MessageId { + self.message_id() + } + + fn set_message_id(&mut self, message_id: MessageId) { + self.set_message_id(message_id); + } + + fn previous_message_id(&self) -> &MessageId { + self.previous_message_id() + } + + fn set_previous_message_id(&mut self, message_id: MessageId) { + self.set_previous_message_id(message_id); + } +} diff --git a/identity/Cargo.toml b/identity/Cargo.toml index aa8cb0f73e..82abd3d83d 100644 --- a/identity/Cargo.toml +++ b/identity/Cargo.toml @@ -12,16 +12,18 @@ repository = "https://github.com/iotaledger/identity.rs" description = "Tools for working with Self-sovereign Identity." [dependencies] -identity-account = { version = "=0.5.0-dev.4", path = "../identity-account", optional = true } +identity-account = { version = "=0.5.0-dev.4", path = "../identity-account", default-features = false, optional = true } +identity-account-storage = { version = "=0.5.0-dev.4", path = "../identity-account-storage", default-features = false, optional = true } identity-comm = { version = "=0.5.0-dev.4", path = "../identity-comm", optional = true } identity-core = { version = "=0.5.0-dev.4", path = "../identity-core", default-features = false } identity-credential = { version = "=0.5.0-dev.4", path = "../identity-credential" } identity-did = { version = "=0.5.0-dev.4", path = "../identity-did" } identity-iota = { version = "=0.5.0-dev.4", path = "../identity-iota", default-features = false } +identity-iota-core = { version = "=0.5.0-dev.4", path = "../identity-iota-core", default-features = false } [dev-dependencies] criterion = { version = "0.3" } -tokio = { version = "1.5", features = ["full"] } +tokio = { version = "1.17.0", features = ["full"] } [[bench]] name = "benchmark" @@ -30,11 +32,14 @@ harness = false [features] default = ["async"] -# Enables async runtime support (Tokio) +# Enables async runtime support (Tokio). async = ["identity-iota/async"] # Enables support for secure storage of DID Documents -account = ["identity-account"] +account = ["identity-account", "identity-account-storage"] + +# Enables support for stronghold storage. +stronghold = ["identity-account/stronghold", "identity-account-storage/stronghold"] # Enables support for DID Communication comm = ["identity-comm"] diff --git a/identity/benches/benchmark.rs b/identity/benches/benchmark.rs index ead89e9fb7..830b3e5095 100644 --- a/identity/benches/benchmark.rs +++ b/identity/benches/benchmark.rs @@ -9,8 +9,8 @@ use criterion::Criterion; use identity::crypto::KeyPair; use identity::iota::DocumentChain; use identity::iota::IntegrationChain; -use identity::iota::IotaDID; -use identity::iota::IotaDocument; +use identity::iota_core::IotaDID; +use identity::iota_core::IotaDocument; use self::diff_chain::setup_diff_chain_bench; use self::diff_chain::update_diff_chain; diff --git a/identity/benches/diff_chain.rs b/identity/benches/diff_chain.rs index ed452fb357..ace7be78dd 100644 --- a/identity/benches/diff_chain.rs +++ b/identity/benches/diff_chain.rs @@ -8,13 +8,13 @@ use identity::did::MethodData; use identity::did::MethodRef; use identity::did::MethodType; use identity::did::DID; -use identity::iota::DiffMessage; use identity::iota::DocumentChain; -use identity::iota::IotaDocument; -use identity::iota::MessageId; use identity::iota::TangleRef; +use identity::iota_core::DiffMessage; +use identity::iota_core::IotaDID; +use identity::iota_core::IotaDocument; +use identity::iota_core::MessageId; use identity_core::crypto::SignatureOptions; -use identity_iota::did::IotaDID; use identity_iota::document::ResolvedIotaDocument; pub fn setup_diff_chain_bench() -> (ResolvedIotaDocument, KeyPair) { diff --git a/identity/src/lib.rs b/identity/src/lib.rs index 99e94c6d69..4731b9df17 100644 --- a/identity/src/lib.rs +++ b/identity/src/lib.rs @@ -71,14 +71,22 @@ pub mod iota { pub use identity_iota::chain::*; pub use identity_iota::credential::*; - pub use identity_iota::did::*; - pub use identity_iota::diff::*; pub use identity_iota::document::*; pub use identity_iota::error::*; pub use identity_iota::tangle::*; +} + +pub mod iota_core { + //! IOTA Core Traits and Types definitions + + pub use identity_iota_core::did::*; + pub use identity_iota_core::diff::*; + pub use identity_iota_core::document::*; + pub use identity_iota_core::error::*; + pub use identity_iota_core::tangle::*; #[doc(inline)] - pub use identity_iota::try_construct_did; + pub use identity_iota_core::try_construct_did; } #[cfg(feature = "account")] @@ -87,14 +95,25 @@ pub mod account { //! Secure storage for Decentralized Identifiers pub use identity_account::account::*; - pub use identity_account::crypto::*; pub use identity_account::error::*; pub use identity_account::identity::*; - pub use identity_account::storage::*; - pub use identity_account::stronghold::*; pub use identity_account::types::*; pub use identity_account::updates::*; - pub use identity_account::utils::*; +} + +#[cfg(feature = "account")] +#[cfg_attr(docsrs, doc(cfg(feature = "account")))] +pub mod account_storage { + //! Storage Trait and Types definitions + + pub use identity_account_storage::crypto::*; + pub use identity_account_storage::error::*; + pub use identity_account_storage::identity::*; + pub use identity_account_storage::storage::*; + #[cfg(feature = "stronghold")] + pub use identity_account_storage::stronghold::*; + pub use identity_account_storage::types::*; + pub use identity_account_storage::utils::*; } #[cfg(feature = "comm")] @@ -113,7 +132,7 @@ pub mod prelude { //! Prelude of commonly used types pub use identity_core::crypto::KeyPair; - pub use identity_iota::document::IotaDocument; pub use identity_iota::tangle::Client; pub use identity_iota::Result; + pub use identity_iota_core::document::IotaDocument; }