Initializes the console error panic hook for better error messages
+
@@ -397,6 +405,9 @@ Deserializes an instance from a JSON object.
## CoreDocument
A method-agnostic DID Document.
+Note: All methods that involve reading from this class may potentially raise an error
+if the object is being concurrently modified.
+
**Kind**: global class
* [CoreDocument](#CoreDocument)
@@ -437,7 +448,7 @@ A method-agnostic DID Document.
* [.generateMethod(storage, keyType, alg, fragment, scope)](#CoreDocument+generateMethod) ⇒ Promise.<string>
* [.purgeMethod(storage, id)](#CoreDocument+purgeMethod) ⇒ Promise.<void>
* [.createJws(storage, fragment, payload, options)](#CoreDocument+createJws) ⇒ [Promise.<Jws>](#Jws)
- * [.createCredentialJwt(storage, fragment, credential, options)](#CoreDocument+createCredentialJwt) ⇒ [Promise.<Jwt>](#Jwt)
+ * [.createCredentialJwt(storage, fragment, credential, options, custom_claims)](#CoreDocument+createCredentialJwt) ⇒ [Promise.<Jwt>](#Jwt)
* [.createPresentationJwt(storage, fragment, presentation, signature_options, presentation_options)](#CoreDocument+createPresentationJwt) ⇒ [Promise.<Jwt>](#Jwt)
* _static_
* [.fromJSON(json)](#CoreDocument.fromJSON) ⇒ [CoreDocument](#CoreDocument)
@@ -709,7 +720,8 @@ verifying EdDSA signatures.
Regardless of which options are passed the following conditions must be met in order for a verification attempt to
take place.
- The JWS must be encoded according to the JWS compact serialization.
-- The `kid` value in the protected header must be an identifier of a verification method in this DID document.
+- The `kid` value in the protected header must be an identifier of a verification method in this DID document,
+or set explicitly in the `options`.
**Kind**: instance method of [CoreDocument](#CoreDocument)
@@ -717,7 +729,7 @@ take place.
| --- | --- |
| jws | [Jws](#Jws) |
| options | [JwsVerificationOptions](#JwsVerificationOptions) |
-| signatureVerifier | IJwsVerifier \| undefined |
+| signatureVerifier | IJwsVerifier |
| detachedPayload | string \| undefined |
@@ -827,12 +839,15 @@ See [RFC7515 section 3.1](https://www.rfc-editor.org/rfc/rfc7515#section-3.1).
-### coreDocument.createCredentialJwt(storage, fragment, credential, options) ⇒ [Promise.<Jwt>](#Jwt)
+### coreDocument.createCredentialJwt(storage, fragment, credential, options, custom_claims) ⇒ [Promise.<Jwt>](#Jwt)
Produces a JWT where the payload is produced from the given `credential`
-in accordance with [VC-JWT version 1.1](https://w3c.github.io/vc-jwt/#version-1.1).
+in accordance with [VC Data Model v1.1](https://www.w3.org/TR/vc-data-model/#json-web-token).
+
+Unless the `kid` is explicitly set in the options, the `kid` in the protected header is the `id`
+of the method identified by `fragment` and the JWS signature will be produced by the corresponding
+private key backed by the `storage` in accordance with the passed `options`.
-The `kid` in the protected header is the `id` of the method identified by `fragment` and the JWS signature will be
-produced by the corresponding private key backed by the `storage` in accordance with the passed `options`.
+The `custom_claims` can be used to set additional claims on the resulting JWT.
**Kind**: instance method of [CoreDocument](#CoreDocument)
@@ -842,15 +857,17 @@ produced by the corresponding private key backed by the `storage` in accordance
| fragment | string |
| credential | [Credential](#Credential) |
| options | [JwsSignatureOptions](#JwsSignatureOptions) |
+| custom_claims | Record.<string, any> \| undefined |
### coreDocument.createPresentationJwt(storage, fragment, presentation, signature_options, presentation_options) ⇒ [Promise.<Jwt>](#Jwt)
Produces a JWT where the payload is produced from the given presentation.
-in accordance with [VC-JWT version 1.1](https://w3c.github.io/vc-jwt/#version-1.1).
+in accordance with [VC Data Model v1.1](https://www.w3.org/TR/vc-data-model/#json-web-token).
-The `kid` in the protected header is the `id` of the method identified by `fragment` and the JWS signature will be
-produced by the corresponding private key backed by the `storage` in accordance with the passed `options`.
+Unless the `kid` is explicitly set in the options, the `kid` in the protected header is the `id`
+of the method identified by `fragment` and the JWS signature will be produced by the corresponding
+private key backed by the `storage` in accordance with the passed `options`.
**Kind**: instance method of [CoreDocument](#CoreDocument)
@@ -1274,6 +1291,7 @@ It does not imply anything about a potentially present proof property on the cre
* [DecodedJwtCredential](#DecodedJwtCredential)
* [.credential()](#DecodedJwtCredential+credential) ⇒ [Credential](#Credential)
* [.protectedHeader()](#DecodedJwtCredential+protectedHeader) ⇒ [JwsHeader](#JwsHeader)
+ * [.customClaims()](#DecodedJwtCredential+customClaims) ⇒ Record.<string, any> \| undefined
* [.intoCredential()](#DecodedJwtCredential+intoCredential) ⇒ [Credential](#Credential)
@@ -1287,6 +1305,12 @@ Returns a copy of the credential parsed to the [Verifiable Credentials Data mode
### decodedJwtCredential.protectedHeader() ⇒ [JwsHeader](#JwsHeader)
Returns a copy of the protected header parsed from the decoded JWS.
+**Kind**: instance method of [DecodedJwtCredential](#DecodedJwtCredential)
+
+
+### decodedJwtCredential.customClaims() ⇒ Record.<string, any> \| undefined
+The custom claims parsed from the JWT.
+
**Kind**: instance method of [DecodedJwtCredential](#DecodedJwtCredential)
@@ -1315,6 +1339,7 @@ It does not imply anything about a potentially present proof property on the pre
* [.expirationDate()](#DecodedJwtPresentation+expirationDate) ⇒ [Timestamp](#Timestamp) \| undefined
* [.issuanceDate()](#DecodedJwtPresentation+issuanceDate) ⇒ [Timestamp](#Timestamp) \| undefined
* [.audience()](#DecodedJwtPresentation+audience) ⇒ string \| undefined
+ * [.customClaims()](#DecodedJwtPresentation+customClaims) ⇒ Record.<string, any> \| undefined
@@ -1352,6 +1377,12 @@ The issuance date parsed from the JWT claims.
### decodedJwtPresentation.audience() ⇒ string \| undefined
The `aud` property parsed from JWT claims.
+**Kind**: instance method of [DecodedJwtPresentation](#DecodedJwtPresentation)
+
+
+### decodedJwtPresentation.customClaims() ⇒ Record.<string, any> \| undefined
+The custom claims parsed from the JWT.
+
**Kind**: instance method of [DecodedJwtPresentation](#DecodedJwtPresentation)
@@ -1510,6 +1541,46 @@ Deserializes an instance from a JSON object.
| --- | --- |
| json | any |
+
+
+## EdDSAJwsVerifier
+An implementor of `IJwsVerifier` that can handle the
+`EdDSA` algorithm.
+
+**Kind**: global class
+
+* [EdDSAJwsVerifier](#EdDSAJwsVerifier)
+ * [new EdDSAJwsVerifier()](#new_EdDSAJwsVerifier_new)
+ * [.verify(alg, signingInput, decodedSignature, publicKey)](#EdDSAJwsVerifier+verify)
+
+
+
+### new EdDSAJwsVerifier()
+Constructs an EdDSAJwsVerifier.
+
+
+
+### edDSAJwsVerifier.verify(alg, signingInput, decodedSignature, publicKey)
+Verify a JWS signature secured with the `EdDSA` algorithm.
+Only the `Ed25519` curve is supported for now.
+
+This function is useful when one is building an `IJwsVerifier` that extends the default provided by
+the IOTA Identity Framework.
+
+# Warning
+
+This function does not check whether `alg = EdDSA` in the protected header. Callers are expected to assert this
+prior to calling the function.
+
+**Kind**: instance method of [EdDSAJwsVerifier](#EdDSAJwsVerifier)
+
+| Param | Type |
+| --- | --- |
+| alg | JwsAlgorithm |
+| signingInput | Uint8Array |
+| decodedSignature | Uint8Array |
+| publicKey | [Jwk](#Jwk) |
+
## IotaDID
@@ -1724,6 +1795,11 @@ Deserializes an instance from a JSON object.
## IotaDocument
+A DID Document adhering to the IOTA DID method specification.
+
+Note: All methods that involve reading from this class may potentially raise an error
+if the object is being concurrently modified.
+
**Kind**: global class
* [IotaDocument](#IotaDocument)
@@ -1768,7 +1844,7 @@ Deserializes an instance from a JSON object.
* [.generateMethod(storage, keyType, alg, fragment, scope)](#IotaDocument+generateMethod) ⇒ Promise.<string>
* [.purgeMethod(storage, id)](#IotaDocument+purgeMethod) ⇒ Promise.<void>
* [.createJwt(storage, fragment, payload, options)](#IotaDocument+createJwt) ⇒ [Promise.<Jws>](#Jws)
- * [.createCredentialJwt(storage, fragment, credential, options)](#IotaDocument+createCredentialJwt) ⇒ [Promise.<Jwt>](#Jwt)
+ * [.createCredentialJwt(storage, fragment, credential, options, custom_claims)](#IotaDocument+createCredentialJwt) ⇒ [Promise.<Jwt>](#Jwt)
* [.createPresentationJwt(storage, fragment, presentation, signature_options, presentation_options)](#IotaDocument+createPresentationJwt) ⇒ [Promise.<Jwt>](#Jwt)
* _static_
* [.newWithId(id)](#IotaDocument.newWithId) ⇒ [IotaDocument](#IotaDocument)
@@ -1982,7 +2058,7 @@ take place.
| --- | --- |
| jws | [Jws](#Jws) |
| options | [JwsVerificationOptions](#JwsVerificationOptions) |
-| signatureVerifier | IJwsVerifier \| undefined |
+| signatureVerifier | IJwsVerifier |
| detachedPayload | string \| undefined |
@@ -2201,12 +2277,15 @@ See [RFC7515 section 3.1](https://www.rfc-editor.org/rfc/rfc7515#section-3.1).
-### iotaDocument.createCredentialJwt(storage, fragment, credential, options) ⇒ [Promise.<Jwt>](#Jwt)
+### iotaDocument.createCredentialJwt(storage, fragment, credential, options, custom_claims) ⇒ [Promise.<Jwt>](#Jwt)
Produces a JWS where the payload is produced from the given `credential`
-in accordance with [VC-JWT version 1.1](https://w3c.github.io/vc-jwt/#version-1.1).
+in accordance with [VC Data Model v1.1](https://www.w3.org/TR/vc-data-model/#json-web-token).
+
+Unless the `kid` is explicitly set in the options, the `kid` in the protected header is the `id`
+of the method identified by `fragment` and the JWS signature will be produced by the corresponding
+private key backed by the `storage` in accordance with the passed `options`.
-The `kid` in the protected header is the `id` of the method identified by `fragment` and the JWS signature will be
-produced by the corresponding private key backed by the `storage` in accordance with the passed `options`.
+The `custom_claims` can be used to set additional claims on the resulting JWT.
**Kind**: instance method of [IotaDocument](#IotaDocument)
@@ -2216,15 +2295,17 @@ produced by the corresponding private key backed by the `storage` in accordance
| fragment | string |
| credential | [Credential](#Credential) |
| options | [JwsSignatureOptions](#JwsSignatureOptions) |
+| custom_claims | Record.<string, any> \| undefined |
### iotaDocument.createPresentationJwt(storage, fragment, presentation, signature_options, presentation_options) ⇒ [Promise.<Jwt>](#Jwt)
Produces a JWT where the payload is produced from the given presentation.
-in accordance with [VC-JWT version 1.1](https://w3c.github.io/vc-jwt/#version-1.1).
+in accordance with [VC Data Model v1.1](https://www.w3.org/TR/vc-data-model/#json-web-token).
-The `kid` in the protected header is the `id` of the method identified by `fragment` and the JWS signature will be
-produced by the corresponding private key backed by the `storage` in accordance with the passed `options`.
+Unless the `kid` is explicitly set in the options, the `kid` in the protected header is the `id`
+of the method identified by `fragment` and the JWS signature will be produced by the corresponding
+private key backed by the `storage` in accordance with the passed `options`.
**Kind**: instance method of [IotaDocument](#IotaDocument)
@@ -2725,6 +2806,7 @@ Returns a clone of the JWS string.
* [.setAlg(value)](#JwsHeader+setAlg)
* [.b64()](#JwsHeader+b64) ⇒ boolean \| undefined
* [.setB64(value)](#JwsHeader+setB64)
+ * [.custom()](#JwsHeader+custom) ⇒ Record.<string, any> \| undefined
* [.has(claim)](#JwsHeader+has) ⇒ boolean
* [.isDisjoint(other)](#JwsHeader+isDisjoint) ⇒ boolean
* [.jku()](#JwsHeader+jku) ⇒ string \| undefined
@@ -2795,6 +2877,12 @@ Sets a value for the base64url-encode payload claim (b64).
| --- | --- |
| value | boolean |
+
+
+### jwsHeader.custom() ⇒ Record.<string, any> \| undefined
+Additional header parameters.
+
+**Kind**: instance method of [JwsHeader](#JwsHeader)
### jwsHeader.has(claim) ⇒ boolean
@@ -3058,7 +3146,9 @@ Deserializes an instance from a JSON object.
* [.setCty(value)](#JwsSignatureOptions+setCty)
* [.serUrl(value)](#JwsSignatureOptions+serUrl)
* [.setNonce(value)](#JwsSignatureOptions+setNonce)
+ * [.setKid(value)](#JwsSignatureOptions+setKid)
* [.setDetachedPayload(value)](#JwsSignatureOptions+setDetachedPayload)
+ * [.setCustomHeaderParameters(value)](#JwsSignatureOptions+setCustomHeaderParameters)
* [.toJSON()](#JwsSignatureOptions+toJSON) ⇒ any
* [.clone()](#JwsSignatureOptions+clone) ⇒ [JwsSignatureOptions](#JwsSignatureOptions)
* _static_
@@ -3138,6 +3228,17 @@ Replace the value of the `nonce` field.
| --- | --- |
| value | string |
+
+
+### jwsSignatureOptions.setKid(value)
+Replace the value of the `kid` field.
+
+**Kind**: instance method of [JwsSignatureOptions](#JwsSignatureOptions)
+
+| Param | Type |
+| --- | --- |
+| value | string |
+
### jwsSignatureOptions.setDetachedPayload(value)
@@ -3149,6 +3250,17 @@ Replace the value of the `detached_payload` field.
| --- | --- |
| value | boolean |
+
+
+### jwsSignatureOptions.setCustomHeaderParameters(value)
+Add additional header parameters.
+
+**Kind**: instance method of [JwsSignatureOptions](#JwsSignatureOptions)
+
+| Param | Type |
+| --- | --- |
+| value | Record.<string, any> |
+
### jwsSignatureOptions.toJSON() ⇒ any
@@ -3181,7 +3293,8 @@ Deserializes an instance from a JSON object.
* [new JwsVerificationOptions(options)](#new_JwsVerificationOptions_new)
* _instance_
* [.setNonce(value)](#JwsVerificationOptions+setNonce)
- * [.setScope(value)](#JwsVerificationOptions+setScope)
+ * [.setMethodScope(value)](#JwsVerificationOptions+setMethodScope)
+ * [.setMethodId(value)](#JwsVerificationOptions+setMethodId)
* [.toJSON()](#JwsVerificationOptions+toJSON) ⇒ any
* [.clone()](#JwsVerificationOptions+clone) ⇒ [JwsVerificationOptions](#JwsVerificationOptions)
* _static_
@@ -3208,9 +3321,9 @@ Set the expected value for the `nonce` parameter of the protected header.
| --- | --- |
| value | string |
-
+
-### jwsVerificationOptions.setScope(value)
+### jwsVerificationOptions.setMethodScope(value)
Set the scope of the verification methods that may be used to verify the given JWS.
**Kind**: instance method of [JwsVerificationOptions](#JwsVerificationOptions)
@@ -3219,6 +3332,17 @@ Set the scope of the verification methods that may be used to verify the given J
| --- | --- |
| value | [MethodScope](#MethodScope) |
+
+
+### jwsVerificationOptions.setMethodId(value)
+Set the DID URl of the method, whose JWK should be used to verify the JWS.
+
+**Kind**: instance method of [JwsVerificationOptions](#JwsVerificationOptions)
+
+| Param | Type |
+| --- | --- |
+| value | [DIDUrl](#DIDUrl) |
+
### jwsVerificationOptions.toJSON() ⇒ any
@@ -3373,7 +3497,7 @@ algorithm will be used.
| Param | Type |
| --- | --- |
-| signatureVerifier | IJwsVerifier \| undefined |
+| signatureVerifier | IJwsVerifier |
@@ -3545,7 +3669,7 @@ algorithm will be used.
| Param | Type |
| --- | --- |
-| signatureVerifier | IJwsVerifier \| undefined |
+| signatureVerifier | IJwsVerifier |
@@ -3712,7 +3836,7 @@ algorithm will be used.
| Param | Type |
| --- | --- |
-| signatureVerifier | IJwsVerifier \| undefined |
+| signatureVerifier | IJwsVerifier |
@@ -4619,6 +4743,7 @@ Obtain the wrapped `JwkStorage`.
**Kind**: global class
* [Timestamp](#Timestamp)
+ * [new Timestamp()](#new_Timestamp_new)
* _instance_
* [.toRFC3339()](#Timestamp+toRFC3339) ⇒ string
* [.checkedAdd(duration)](#Timestamp+checkedAdd) ⇒ [Timestamp](#Timestamp) \| undefined
@@ -4629,6 +4754,11 @@ Obtain the wrapped `JwkStorage`.
* [.nowUTC()](#Timestamp.nowUTC) ⇒ [Timestamp](#Timestamp)
* [.fromJSON(json)](#Timestamp.fromJSON) ⇒ [Timestamp](#Timestamp)
+
+
+### new Timestamp()
+Creates a new [Timestamp](#Timestamp) with the current date and time.
+
### timestamp.toRFC3339() ⇒ string
@@ -4911,14 +5041,6 @@ Deserializes an instance from a JSON object.
| --- | --- |
| json | any |
-
-
-## StateMetadataEncoding
-**Kind**: global variable
-
-
-## MethodRelationship
-**Kind**: global variable
## StatusCheck
@@ -4995,12 +5117,14 @@ Return all errors that occur during validation.
Return after the first error occurs.
**Kind**: global variable
-
+
-## start()
-Initializes the console error panic hook for better error messages
+## StateMetadataEncoding
+**Kind**: global variable
+
-**Kind**: global function
+## MethodRelationship
+**Kind**: global variable
## encodeB64(data) ⇒ string
@@ -5023,16 +5147,16 @@ Decode the given url-safe base64-encoded slice into its raw bytes.
| --- | --- |
| data | Uint8Array |
-
+
-## verifyEdDSA(alg, signingInput, decodedSignature, publicKey)
-Verify a JWS signature secured with the `JwsAlgorithm::EdDSA` algorithm.
-Only the `EdCurve::Ed25519` variant is supported for now.
+## verifyEd25519(alg, signingInput, decodedSignature, publicKey)
+Verify a JWS signature secured with the `EdDSA` algorithm and curve `Ed25519`.
-This function is useful when one is building an `IJwsVerifier` that extends the default provided by
-the IOTA Identity Framework.
+This function is useful when one is composing a `IJwsVerifier` that delegates
+`EdDSA` verification with curve `Ed25519` to this function.
# Warning
+
This function does not check whether `alg = EdDSA` in the protected header. Callers are expected to assert this
prior to calling the function.
@@ -5045,3 +5169,9 @@ prior to calling the function.
| decodedSignature | Uint8Array |
| publicKey | [Jwk](#Jwk) |
+
+
+## start()
+Initializes the console error panic hook for better error messages
+
+**Kind**: global function
diff --git a/bindings/wasm/src/common/imported_document_lock.rs b/bindings/wasm/src/common/imported_document_lock.rs
index 5590424067..4852ab216e 100644
--- a/bindings/wasm/src/common/imported_document_lock.rs
+++ b/bindings/wasm/src/common/imported_document_lock.rs
@@ -11,6 +11,7 @@ use crate::did::ArrayIToCoreDocument;
use crate::did::CoreDocumentLock;
use crate::did::IToCoreDocument;
use crate::did::WasmCoreDocument;
+use crate::error::Result;
use crate::iota::IotaDocumentLock;
use crate::iota::WasmIotaDocument;
@@ -27,13 +28,13 @@ pub(crate) enum ImportedDocumentLock {
impl ImportedDocumentLock {
/// Obtain a read guard which implements `AsRef`.
- pub(crate) fn blocking_read(&self) -> ImportedDocumentReadGuard<'_> {
+ pub(crate) fn try_read(&self) -> Result> {
match self {
- Self::Iota(lock) => ImportedDocumentReadGuard(tokio::sync::RwLockReadGuard::map(
- lock.blocking_read(),
+ Self::Iota(lock) => Ok(ImportedDocumentReadGuard(tokio::sync::RwLockReadGuard::map(
+ lock.try_read()?,
IotaDocument::core_document,
- )),
- Self::Core(lock) => ImportedDocumentReadGuard(lock.blocking_read()),
+ ))),
+ Self::Core(lock) => Ok(ImportedDocumentReadGuard(lock.try_read()?)),
}
}
/// Must only be called on values implementing `IToCoreDocument`.
diff --git a/bindings/wasm/src/credential/domain_linkage_validator.rs b/bindings/wasm/src/credential/domain_linkage_validator.rs
index 4dc8840b4b..a38639d853 100644
--- a/bindings/wasm/src/credential/domain_linkage_validator.rs
+++ b/bindings/wasm/src/credential/domain_linkage_validator.rs
@@ -60,7 +60,7 @@ impl WasmJwtDomainLinkageValidator {
) -> Result<()> {
let domain = Url::parse(domain).wasm_result()?;
let doc = ImportedDocumentLock::from(issuer);
- let doc_guard = doc.blocking_read();
+ let doc_guard = doc.try_read()?;
self
.validator
.validate_linkage(&doc_guard, &configuration.0, &domain, &options.0)
@@ -81,7 +81,7 @@ impl WasmJwtDomainLinkageValidator {
) -> Result<()> {
let domain = Url::parse(domain).wasm_result()?;
let doc = ImportedDocumentLock::from(issuer);
- let doc_guard = doc.blocking_read();
+ let doc_guard = doc.try_read()?;
self
.validator
.validate_credential(&doc_guard, &credentialJwt.0, &domain, &options.0)
diff --git a/bindings/wasm/src/credential/jwt_credential_validation/jwt_credential_validator.rs b/bindings/wasm/src/credential/jwt_credential_validation/jwt_credential_validator.rs
index cf1a48254b..74682d3e0d 100644
--- a/bindings/wasm/src/credential/jwt_credential_validation/jwt_credential_validator.rs
+++ b/bindings/wasm/src/credential/jwt_credential_validation/jwt_credential_validator.rs
@@ -78,7 +78,7 @@ impl WasmJwtCredentialValidator {
fail_fast: WasmFailFast,
) -> Result {
let issuer_lock = ImportedDocumentLock::from(issuer);
- let issuer_guard = issuer_lock.blocking_read();
+ let issuer_guard = issuer_lock.try_read()?;
self
.0
@@ -112,8 +112,12 @@ impl WasmJwtCredentialValidator {
options: &WasmJwsVerificationOptions,
) -> Result {
let issuer_locks: Vec = trustedIssuers.into();
- let trusted_issuers: Vec> =
- issuer_locks.iter().map(ImportedDocumentLock::blocking_read).collect();
+ let trusted_issuers: Vec> = issuer_locks
+ .iter()
+ .map(ImportedDocumentLock::try_read)
+ .collect::>>>(
+ )?;
+
self
.0
.verify_signature(&credential.0, &trusted_issuers, &options.0)
@@ -157,8 +161,11 @@ impl WasmJwtCredentialValidator {
statusCheck: WasmStatusCheck,
) -> Result<()> {
let issuer_locks: Vec = trustedIssuers.into();
- let trusted_issuers: Vec> =
- issuer_locks.iter().map(ImportedDocumentLock::blocking_read).collect();
+ let trusted_issuers: Vec> = issuer_locks
+ .iter()
+ .map(ImportedDocumentLock::try_read)
+ .collect::>>>(
+ )?;
let status_check: StatusCheck = statusCheck.into();
JwtCredentialValidatorUtils::check_status(&credential.0, &trusted_issuers, status_check).wasm_result()
}
diff --git a/bindings/wasm/src/credential/jwt_presentation_validation/jwt_presentation_validator.rs b/bindings/wasm/src/credential/jwt_presentation_validation/jwt_presentation_validator.rs
index a502c20075..40a44f916b 100644
--- a/bindings/wasm/src/credential/jwt_presentation_validation/jwt_presentation_validator.rs
+++ b/bindings/wasm/src/credential/jwt_presentation_validation/jwt_presentation_validator.rs
@@ -65,7 +65,7 @@ impl WasmJwtPresentationValidator {
validation_options: &WasmJwtPresentationValidationOptions,
) -> Result {
let holder_lock = ImportedDocumentLock::from(holder);
- let holder_guard = holder_lock.blocking_read();
+ let holder_guard = holder_lock.try_read()?;
self
.0
diff --git a/bindings/wasm/src/did/wasm_core_document.rs b/bindings/wasm/src/did/wasm_core_document.rs
index bd349b7723..0bae16c048 100644
--- a/bindings/wasm/src/did/wasm_core_document.rs
+++ b/bindings/wasm/src/did/wasm_core_document.rs
@@ -72,12 +72,12 @@ impl CoreDocumentLock {
Self(tokio::sync::RwLock::new(input))
}
- pub(crate) fn blocking_read(&self) -> tokio::sync::RwLockReadGuard<'_, CoreDocument> {
- self.0.blocking_read()
+ pub(crate) fn try_read(&self) -> Result> {
+ self.0.try_read().wasm_result()
}
- pub(crate) fn blocking_write(&self) -> tokio::sync::RwLockWriteGuard<'_, CoreDocument> {
- self.0.blocking_write()
+ pub(crate) fn try_write(&self) -> Result> {
+ self.0.try_write().wasm_result()
}
pub(crate) async fn read(&self) -> tokio::sync::RwLockReadGuard<'_, CoreDocument> {
@@ -90,6 +90,9 @@ impl CoreDocumentLock {
}
/// A method-agnostic DID Document.
+///
+/// Note: All methods that involve reading from this class may potentially raise an error
+/// if the object is being concurrently modified.
#[wasm_bindgen(js_name = CoreDocument, inspectable)]
pub struct WasmCoreDocument(pub(crate) Rc);
@@ -104,8 +107,8 @@ impl WasmCoreDocument {
/// Returns a copy of the DID Document `id`.
#[wasm_bindgen]
- pub fn id(&self) -> WasmCoreDID {
- WasmCoreDID::from(self.0.blocking_read().id().clone())
+ pub fn id(&self) -> Result {
+ Ok(WasmCoreDID::from(self.0.try_read()?.id().clone()))
}
/// Sets the DID of the document.
@@ -116,14 +119,15 @@ impl WasmCoreDocument {
/// `resolve_method`, `resolve_service` and the related
/// [DID URL dereferencing](https://w3c-ccg.github.io/did-resolution/#dereferencing) algorithm.
#[wasm_bindgen(js_name = setId)]
- pub fn set_id(&mut self, id: &WasmCoreDID) {
- *self.0.blocking_write().id_mut_unchecked() = id.0.clone();
+ pub fn set_id(&mut self, id: &WasmCoreDID) -> Result<()> {
+ *self.0.try_write()?.id_mut_unchecked() = id.0.clone();
+ Ok(())
}
/// Returns a copy of the document controllers.
#[wasm_bindgen]
- pub fn controller(&self) -> ArrayCoreDID {
- match self.0.blocking_read().controller() {
+ pub fn controller(&self) -> Result {
+ let controller = match self.0.try_read()?.controller() {
Some(controllers) => controllers
.iter()
.cloned()
@@ -132,7 +136,8 @@ impl WasmCoreDocument {
.collect::()
.unchecked_into::(),
None => js_sys::Array::new().unchecked_into::(),
- }
+ };
+ Ok(controller)
}
/// Sets the controllers of the DID Document.
@@ -151,22 +156,24 @@ impl WasmCoreDocument {
} else {
None
};
- *self.0.blocking_write().controller_mut() = controller_set;
+ *self.0.try_write()?.controller_mut() = controller_set;
Ok(())
}
/// Returns a copy of the document's `alsoKnownAs` set.
#[wasm_bindgen(js_name = alsoKnownAs)]
- pub fn also_known_as(&self) -> ArrayString {
- self
- .0
- .blocking_read()
- .also_known_as()
- .iter()
- .map(|url| url.to_string())
- .map(JsValue::from)
- .collect::()
- .unchecked_into::()
+ pub fn also_known_as(&self) -> Result {
+ Ok(
+ self
+ .0
+ .try_read()?
+ .also_known_as()
+ .iter()
+ .map(|url| url.to_string())
+ .map(JsValue::from)
+ .collect::()
+ .unchecked_into::(),
+ )
}
/// Sets the `alsoKnownAs` property in the DID document.
@@ -179,114 +186,126 @@ impl WasmCoreDocument {
urls_set.append(Url::parse(url).wasm_result()?);
}
}
- *self.0.blocking_write().also_known_as_mut() = urls_set;
+ *self.0.try_write()?.also_known_as_mut() = urls_set;
Ok(())
}
/// Returns a copy of the document's `verificationMethod` set.
#[wasm_bindgen(js_name = verificationMethod)]
- pub fn verification_method(&self) -> ArrayVerificationMethod {
- self
- .0
- .blocking_read()
- .verification_method()
- .iter()
- .cloned()
- .map(WasmVerificationMethod::from)
- .map(JsValue::from)
- .collect::()
- .unchecked_into::()
+ pub fn verification_method(&self) -> Result {
+ Ok(
+ self
+ .0
+ .try_read()?
+ .verification_method()
+ .iter()
+ .cloned()
+ .map(WasmVerificationMethod::from)
+ .map(JsValue::from)
+ .collect::()
+ .unchecked_into::(),
+ )
}
/// Returns a copy of the document's `authentication` set.
#[wasm_bindgen]
- pub fn authentication(&self) -> ArrayCoreMethodRef {
- self
- .0
- .blocking_read()
- .authentication()
- .iter()
- .cloned()
- .map(|method_ref| match method_ref {
- MethodRef::Embed(verification_method) => JsValue::from(WasmVerificationMethod(verification_method)),
- MethodRef::Refer(did_url) => JsValue::from(WasmDIDUrl(did_url)),
- })
- .collect::()
- .unchecked_into::()
+ pub fn authentication(&self) -> Result {
+ Ok(
+ self
+ .0
+ .try_read()?
+ .authentication()
+ .iter()
+ .cloned()
+ .map(|method_ref| match method_ref {
+ MethodRef::Embed(verification_method) => JsValue::from(WasmVerificationMethod(verification_method)),
+ MethodRef::Refer(did_url) => JsValue::from(WasmDIDUrl(did_url)),
+ })
+ .collect::()
+ .unchecked_into::(),
+ )
}
/// Returns a copy of the document's `assertionMethod` set.
#[wasm_bindgen(js_name = assertionMethod)]
- pub fn assertion_method(&self) -> ArrayCoreMethodRef {
- self
- .0
- .blocking_read()
- .assertion_method()
- .iter()
- .cloned()
- .map(|method_ref| match method_ref {
- MethodRef::Embed(verification_method) => JsValue::from(WasmVerificationMethod(verification_method)),
- MethodRef::Refer(did_url) => JsValue::from(WasmDIDUrl(did_url)),
- })
- .collect::()
- .unchecked_into::()
+ pub fn assertion_method(&self) -> Result {
+ Ok(
+ self
+ .0
+ .try_read()?
+ .assertion_method()
+ .iter()
+ .cloned()
+ .map(|method_ref| match method_ref {
+ MethodRef::Embed(verification_method) => JsValue::from(WasmVerificationMethod(verification_method)),
+ MethodRef::Refer(did_url) => JsValue::from(WasmDIDUrl(did_url)),
+ })
+ .collect::()
+ .unchecked_into::(),
+ )
}
/// Returns a copy of the document's `keyAgreement` set.
#[wasm_bindgen(js_name = keyAgreement)]
- pub fn key_agreement(&self) -> ArrayCoreMethodRef {
- self
- .0
- .blocking_read()
- .key_agreement()
- .iter()
- .cloned()
- .map(|method_ref| match method_ref {
- MethodRef::Embed(verification_method) => JsValue::from(WasmVerificationMethod(verification_method)),
- MethodRef::Refer(did_url) => JsValue::from(WasmDIDUrl(did_url)),
- })
- .collect::()
- .unchecked_into::()
+ pub fn key_agreement(&self) -> Result {
+ Ok(
+ self
+ .0
+ .try_read()?
+ .key_agreement()
+ .iter()
+ .cloned()
+ .map(|method_ref| match method_ref {
+ MethodRef::Embed(verification_method) => JsValue::from(WasmVerificationMethod(verification_method)),
+ MethodRef::Refer(did_url) => JsValue::from(WasmDIDUrl(did_url)),
+ })
+ .collect::()
+ .unchecked_into::(),
+ )
}
/// Returns a copy of the document's `capabilityDelegation` set.
#[wasm_bindgen(js_name = capabilityDelegation)]
- pub fn capability_delegation(&self) -> ArrayCoreMethodRef {
- self
- .0
- .blocking_read()
- .capability_delegation()
- .iter()
- .cloned()
- .map(|method_ref| match method_ref {
- MethodRef::Embed(verification_method) => JsValue::from(WasmVerificationMethod(verification_method)),
- MethodRef::Refer(did_url) => JsValue::from(WasmDIDUrl(did_url)),
- })
- .collect::()
- .unchecked_into::()
+ pub fn capability_delegation(&self) -> Result {
+ Ok(
+ self
+ .0
+ .try_read()?
+ .capability_delegation()
+ .iter()
+ .cloned()
+ .map(|method_ref| match method_ref {
+ MethodRef::Embed(verification_method) => JsValue::from(WasmVerificationMethod(verification_method)),
+ MethodRef::Refer(did_url) => JsValue::from(WasmDIDUrl(did_url)),
+ })
+ .collect::()
+ .unchecked_into::(),
+ )
}
/// Returns a copy of the document's `capabilityInvocation` set.
#[wasm_bindgen(js_name = capabilityInvocation)]
- pub fn capability_invocation(&self) -> ArrayCoreMethodRef {
- self
- .0
- .blocking_read()
- .capability_invocation()
- .iter()
- .cloned()
- .map(|method_ref| match method_ref {
- MethodRef::Embed(verification_method) => JsValue::from(WasmVerificationMethod(verification_method)),
- MethodRef::Refer(did_url) => JsValue::from(WasmDIDUrl(did_url)),
- })
- .collect::()
- .unchecked_into::()
+ pub fn capability_invocation(&self) -> Result {
+ Ok(
+ self
+ .0
+ .try_read()?
+ .capability_invocation()
+ .iter()
+ .cloned()
+ .map(|method_ref| match method_ref {
+ MethodRef::Embed(verification_method) => JsValue::from(WasmVerificationMethod(verification_method)),
+ MethodRef::Refer(did_url) => JsValue::from(WasmDIDUrl(did_url)),
+ })
+ .collect::()
+ .unchecked_into::(),
+ )
}
/// Returns a copy of the custom DID Document properties.
#[wasm_bindgen]
pub fn properties(&self) -> Result {
- MapStringAny::try_from(self.0.blocking_read().properties())
+ MapStringAny::try_from(self.0.try_read()?.properties())
}
/// Sets a custom property in the DID Document.
@@ -300,10 +319,10 @@ impl WasmCoreDocument {
let value: Option = value.into_serde().wasm_result()?;
match value {
Some(value) => {
- self.0.blocking_write().properties_mut_unchecked().insert(key, value);
+ self.0.try_write()?.properties_mut_unchecked().insert(key, value);
}
None => {
- self.0.blocking_write().properties_mut_unchecked().remove(&key);
+ self.0.try_write()?.properties_mut_unchecked().remove(&key);
}
}
Ok(())
@@ -315,17 +334,19 @@ impl WasmCoreDocument {
/// Returns a set of all {@link Service} in the document.
#[wasm_bindgen]
- pub fn service(&self) -> ArrayService {
- self
- .0
- .blocking_read()
- .service()
- .iter()
- .cloned()
- .map(WasmService)
- .map(JsValue::from)
- .collect::()
- .unchecked_into::()
+ pub fn service(&self) -> Result {
+ Ok(
+ self
+ .0
+ .try_read()?
+ .service()
+ .iter()
+ .cloned()
+ .map(WasmService)
+ .map(JsValue::from)
+ .collect::()
+ .unchecked_into::(),
+ )
}
/// Add a new {@link Service} to the document.
@@ -333,7 +354,7 @@ impl WasmCoreDocument {
/// Errors if there already exists a service or verification method with the same id.
#[wasm_bindgen(js_name = insertService)]
pub fn insert_service(&mut self, service: &WasmService) -> Result<()> {
- self.0.blocking_write().insert_service(service.0.clone()).wasm_result()
+ self.0.try_write()?.insert_service(service.0.clone()).wasm_result()
}
/// Remove a {@link Service} identified by the given {@link DIDUrl} from the document.
@@ -341,25 +362,23 @@ impl WasmCoreDocument {
/// Returns `true` if the service was removed.
#[wasm_bindgen(js_name = removeService)]
#[allow(non_snake_case)]
- pub fn remove_service(&mut self, didUrl: &WasmDIDUrl) -> Option {
- self
- .0
- .blocking_write()
- .remove_service(&didUrl.0.clone())
- .map(Into::into)
+ pub fn remove_service(&mut self, didUrl: &WasmDIDUrl) -> Result