From ee173687d7b83e1db819d3c6fa212044a8d8d196 Mon Sep 17 00:00:00 2001 From: blu3beri Date: Tue, 3 Jan 2023 14:51:08 +0100 Subject: [PATCH 001/117] Integrated txn_signature into indy-vdr Signed-off-by: blu3beri --- libindy_vdr/src/utils/mod.rs | 3 +- libindy_vdr/src/utils/txn_signature.rs | 177 +++++++++++++++++++++++++ 2 files changed, 179 insertions(+), 1 deletion(-) create mode 100644 libindy_vdr/src/utils/txn_signature.rs diff --git a/libindy_vdr/src/utils/mod.rs b/libindy_vdr/src/utils/mod.rs index cbd1c9cf..f4e0b7d0 100644 --- a/libindy_vdr/src/utils/mod.rs +++ b/libindy_vdr/src/utils/mod.rs @@ -1,6 +1,8 @@ #[macro_use] mod macros; +pub mod txn_signature; + // re-exports pub use indy_utils::{qualifiable, ConversionError, Qualifiable, Validatable, ValidationError}; @@ -9,4 +11,3 @@ pub(crate) use indy_utils::base64; pub use indy_utils::did; pub(crate) use indy_utils::hash; pub use indy_utils::keys; -pub(crate) use indy_utils::txn_signature; diff --git a/libindy_vdr/src/utils/txn_signature.rs b/libindy_vdr/src/utils/txn_signature.rs new file mode 100644 index 00000000..6f3efbd0 --- /dev/null +++ b/libindy_vdr/src/utils/txn_signature.rs @@ -0,0 +1,177 @@ +use serde_json::Value as SJsonValue; + +use super::{ValidationError,hash::SHA256}; + +const ATTRIB: &str = "100"; +const GET_ATTR: &str = "104"; + +/// Generate the normalized form of a ledger transaction request for signing +pub fn serialize_signature(v: &SJsonValue) -> Result { + let _type = v["operation"]["type"].clone(); + _serialize_signature(v, true, _type.as_str()) +} + +fn _serialize_signature( + v: &SJsonValue, + is_top_level: bool, + _type: Option<&str>, +) -> Result { + match v { + SJsonValue::Bool(value) => Ok(if *value { + "True".to_string() + } else { + "False".to_string() + }), + SJsonValue::Number(value) => Ok(value.to_string()), + SJsonValue::String(value) => Ok(value.to_string()), + SJsonValue::Array(array) => array + .into_iter() + .map(|element| _serialize_signature(element, false, _type)) + .collect::, ValidationError>>() + .map(|res| res.join(",")), + SJsonValue::Object(map) => { + let mut result = "".to_string(); + let mut in_middle = false; + for key in map.keys() { + // Skip signature field at top level as in python code + if is_top_level && (key == "signature" || key == "fees" || key == "signatures") { + continue; + } + + if in_middle { + result += "|"; + } + + let mut value = map[key].clone(); + if (_type == Some(ATTRIB) || _type == Some(GET_ATTR)) + && (key == "raw" || key == "hash" || key == "enc") + { + // do it only for attribute related request + let hash = SHA256::digest( + &value + .as_str() + .ok_or_else(|| invalid!("Cannot update hash context"))? + .as_bytes(), + ); + value = SJsonValue::String(hex::encode(hash)); + } + result = result + key + ":" + &_serialize_signature(&value, false, _type)?; + in_middle = true; + } + Ok(result) + } + _ => Ok("".to_string()), + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn signature_serialize_works() { + let data = r#"{ + "name": "John Doe", + "age": 43, + "operation": { + "dest": 54 + }, + "phones": [ + "1234567", + "2345678", + {"rust": 5, "age": 1}, + 3 + ] + }"#; + let msg: SJsonValue = serde_json::from_str(data).unwrap(); + + let result = "age:43|name:John Doe|operation:dest:54|phones:1234567,2345678,age:1|rust:5,3"; + + assert_eq!(serialize_signature(&msg).unwrap(), result) + } + + #[test] + fn signature_serialize_works_for_skipped_fields() { + let data = r#"{ + "name": "John Doe", + "age": 43, + "operation": { + "type": "100", + "hash": "cool hash", + "dest": 54 + }, + "fees": "fees1", + "signature": "sign1", + "signatures": "sign-m", + "phones": [ + "1234567", + "2345678", + {"rust": 5, "age": 1}, + 3 + ] + }"#; + let msg: SJsonValue = serde_json::from_str(data).unwrap(); + + let result = "age:43|name:John Doe|operation:dest:54|hash:46aa0c92129b33ee72ee1478d2ae62fa6e756869dedc6c858af3214a6fcf1904|type:100|phones:1234567,2345678,age:1|rust:5,3"; + + assert_eq!(serialize_signature(&msg).unwrap(), result) + } + + #[test] + fn signature_serialize_works_with_raw_hash_for_attrib_related_type() { + let data = r#"{ + "name": "John Doe", + "age": 43, + "operation": { + "type": "100", + "hash": "cool hash", + "dest": 54, + "raw": "string for hash" + }, + "phones": [ + "1234567", + "2345678", + {"rust": 5, "age": 1}, + 3 + ] + }"#; + let msg: SJsonValue = serde_json::from_str(data).unwrap(); + + let result = "age:43|name:John Doe|operation:dest:54|hash:46aa0c92129b33ee72ee1478d2ae62fa6e756869dedc6c858af3214a6fcf1904|raw:1dcd0759ce38f57049344a6b3c5fc18144fca1724713090c2ceeffa788c02711|type:100|phones:1234567,2345678,age:1|rust:5,3"; + + assert_eq!(serialize_signature(&msg).unwrap(), result) + } + + #[test] + fn signature_serialize_works_with_raw_hash_for_not_attrib_related_type() { + let data = r#"{ + "name": "John Doe", + "age": 43, + "operation": { + "type": "101", + "hash": "cool hash", + "dest": 54, + "raw": "string for hash" + }, + "phones": [ + "1234567", + "2345678", + {"rust": 5, "age": 1}, + 3 + ] + }"#; + let msg: SJsonValue = serde_json::from_str(data).unwrap(); + + let result = "age:43|name:John Doe|operation:dest:54|hash:cool hash|raw:string for hash|type:101|phones:1234567,2345678,age:1|rust:5,3"; + + assert_eq!(serialize_signature(&msg).unwrap(), result) + } + + #[test] + fn signature_serialize_works_with_null() { + let data = r#"{"signature": null}"#; + let msg: serde_json::Value = serde_json::from_str(data).unwrap(); + let serialized = serialize_signature(&msg).unwrap(); + assert_eq!(serialized, ""); + } +} From c6f160871bdd48834e0e66aece852b2626d62ace Mon Sep 17 00:00:00 2001 From: blu3beri Date: Tue, 3 Jan 2023 14:56:06 +0100 Subject: [PATCH 002/117] Added base64 and base58 inside the package Signed-off-by: blu3beri --- libindy_vdr/Cargo.toml | 2 ++ libindy_vdr/src/utils/base58.rs | 13 +++++++++++++ libindy_vdr/src/utils/base64.rs | 18 ++++++++++++++++++ libindy_vdr/src/utils/mod.rs | 5 ++--- 4 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 libindy_vdr/src/utils/base58.rs create mode 100644 libindy_vdr/src/utils/base64.rs diff --git a/libindy_vdr/Cargo.toml b/libindy_vdr/Cargo.toml index dd99cbbe..1d93ff9a 100644 --- a/libindy_vdr/Cargo.toml +++ b/libindy_vdr/Cargo.toml @@ -24,6 +24,8 @@ rich_schema = ["indy-data-types/rich_schema"] default = ["ffi", "log", "zmq_vendored"] [dependencies] +base64_rs = { package = "base64", version = "0.13" } +bs58 = "0.4" env_logger = { version = "0.9", optional = true } etcommon-rlp = "0.2.4" ffi-support = { version = "0.4", optional = true } diff --git a/libindy_vdr/src/utils/base58.rs b/libindy_vdr/src/utils/base58.rs new file mode 100644 index 00000000..743b55a1 --- /dev/null +++ b/libindy_vdr/src/utils/base58.rs @@ -0,0 +1,13 @@ +use bs58; + +use super::ConversionError; + +pub fn decode>(val: T) -> Result, ConversionError> { + Ok(bs58::decode(val) + .into_vec() + .map_err(|err| ("Error decoding base58 data", err))?) +} + +pub fn encode>(val: T) -> String { + bs58::encode(val).into_string() +} diff --git a/libindy_vdr/src/utils/base64.rs b/libindy_vdr/src/utils/base64.rs new file mode 100644 index 00000000..f5012d37 --- /dev/null +++ b/libindy_vdr/src/utils/base64.rs @@ -0,0 +1,18 @@ +use base64_rs as base64; + +pub use base64::encode; + +use super::ConversionError; + +pub fn decode>(val: T) -> Result, ConversionError> { + Ok(base64::decode(val).map_err(|err| ("Error decoding base64 data", err))?) +} + +pub fn decode_urlsafe>(val: T) -> Result, ConversionError> { + Ok(base64::decode_config(val, base64::URL_SAFE) + .map_err(|err| ("Error decoding base64-URL data", err))?) +} + +pub fn encode_urlsafe>(val: T) -> String { + base64::encode_config(val, base64::URL_SAFE) +} diff --git a/libindy_vdr/src/utils/mod.rs b/libindy_vdr/src/utils/mod.rs index f4e0b7d0..da2adbfe 100644 --- a/libindy_vdr/src/utils/mod.rs +++ b/libindy_vdr/src/utils/mod.rs @@ -2,12 +2,11 @@ mod macros; pub mod txn_signature; +pub mod base64; +pub mod base58; // re-exports pub use indy_utils::{qualifiable, ConversionError, Qualifiable, Validatable, ValidationError}; - -pub(crate) use indy_utils::base58; -pub(crate) use indy_utils::base64; pub use indy_utils::did; pub(crate) use indy_utils::hash; pub use indy_utils::keys; From 7e98584008f20d57a151e4da7d3bd7ac9b0afc9a Mon Sep 17 00:00:00 2001 From: blu3beri Date: Wed, 4 Jan 2023 14:52:52 +0100 Subject: [PATCH 003/117] Removed features from indy-utils Work funded by the Government of Ontario. Signed-off-by: blu3beri --- libindy_vdr/Cargo.toml | 2 +- libindy_vdr/src/utils/mod.rs | 6 +++--- libindy_vdr/src/utils/txn_signature.rs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libindy_vdr/Cargo.toml b/libindy_vdr/Cargo.toml index 1d93ff9a..04b4df35 100644 --- a/libindy_vdr/Cargo.toml +++ b/libindy_vdr/Cargo.toml @@ -35,7 +35,7 @@ futures-util = "0.3" hex = "0.4" hex-literal = "0.3.4" indy-data-types = "0.5" -indy-utils = { version = "0.5", default-features = false, features = ["base64", "ed25519", "hash", "txn_signature"] } +indy-utils = { version = "0.5", default-features = false, features = [ "ed25519", "hash" ] } once_cell = "1.5" log = { version = "0.4", optional = true } pin-utils = "0.1" diff --git a/libindy_vdr/src/utils/mod.rs b/libindy_vdr/src/utils/mod.rs index da2adbfe..d5f9bb44 100644 --- a/libindy_vdr/src/utils/mod.rs +++ b/libindy_vdr/src/utils/mod.rs @@ -1,12 +1,12 @@ #[macro_use] mod macros; -pub mod txn_signature; -pub mod base64; pub mod base58; +pub mod base64; +pub mod txn_signature; // re-exports -pub use indy_utils::{qualifiable, ConversionError, Qualifiable, Validatable, ValidationError}; pub use indy_utils::did; pub(crate) use indy_utils::hash; pub use indy_utils::keys; +pub use indy_utils::{qualifiable, ConversionError, Qualifiable, Validatable, ValidationError}; diff --git a/libindy_vdr/src/utils/txn_signature.rs b/libindy_vdr/src/utils/txn_signature.rs index 6f3efbd0..690df2a5 100644 --- a/libindy_vdr/src/utils/txn_signature.rs +++ b/libindy_vdr/src/utils/txn_signature.rs @@ -1,6 +1,6 @@ use serde_json::Value as SJsonValue; -use super::{ValidationError,hash::SHA256}; +use super::{hash::SHA256, ValidationError}; const ATTRIB: &str = "100"; const GET_ATTR: &str = "104"; From fab0535832d87f8194cf49acc897ac6b004c38c4 Mon Sep 17 00:00:00 2001 From: Miroslav Kovar Date: Wed, 10 May 2023 11:23:05 +0200 Subject: [PATCH 004/117] Proxy client Signed-off-by: Miroslav Kovar --- Cargo.toml | 1 + indy-vdr-proxy-client/Cargo.toml | 12 +++ indy-vdr-proxy-client/src/error.rs | 56 ++++++++++++ indy-vdr-proxy-client/src/lib.rs | 136 +++++++++++++++++++++++++++++ 4 files changed, 205 insertions(+) create mode 100644 indy-vdr-proxy-client/Cargo.toml create mode 100644 indy-vdr-proxy-client/src/error.rs create mode 100644 indy-vdr-proxy-client/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index e3bc9415..b8d4c2f3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,7 @@ resolver = "2" members = [ "libindy_vdr", "indy-vdr-proxy", + "indy-vdr-proxy-client", ] [profile.release] diff --git a/indy-vdr-proxy-client/Cargo.toml b/indy-vdr-proxy-client/Cargo.toml new file mode 100644 index 00000000..7244abb5 --- /dev/null +++ b/indy-vdr-proxy-client/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "indy-vdr-proxy-client" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +reqwest = { version = "0.11.17", default-features = false, features = ["json"] } +indy-vdr = { file = "../libindy_vdr" } +serde_json = "1.0.96" +url = "2.3.1" diff --git a/indy-vdr-proxy-client/src/error.rs b/indy-vdr-proxy-client/src/error.rs new file mode 100644 index 00000000..da521e8e --- /dev/null +++ b/indy-vdr-proxy-client/src/error.rs @@ -0,0 +1,56 @@ +use std::error::Error; +use std::fmt; + +pub enum VdrProxyClientError { + HttpClientError(reqwest::Error), + ParseError(url::ParseError), + NonSuccessStatusCode(u16, String), +} + +impl fmt::Display for VdrProxyClientError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + VdrProxyClientError::HttpClientError(err) => write!(f, "HTTP request failed: {}", err), + VdrProxyClientError::ParseError(err) => write!(f, "URL parsing failed: {}", err), + VdrProxyClientError::NonSuccessStatusCode(_, msg) => { + write!(f, "Non-success status code: {}", msg) + } + } + } +} + +impl fmt::Debug for VdrProxyClientError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + VdrProxyClientError::HttpClientError(err) => { + write!(f, "HTTP request failed: {:?}", err) + } + VdrProxyClientError::ParseError(err) => write!(f, "URL parsing failed: {:?}", err), + VdrProxyClientError::NonSuccessStatusCode(code, body) => { + write!(f, "Non-success status code: {} {}", code, body) + } + } + } +} + +impl Error for VdrProxyClientError { + fn source(&self) -> Option<&(dyn Error + 'static)> { + match self { + VdrProxyClientError::HttpClientError(err) => Some(err), + VdrProxyClientError::ParseError(err) => Some(err), + VdrProxyClientError::NonSuccessStatusCode(_, _) => None, + } + } +} + +impl From for VdrProxyClientError { + fn from(err: reqwest::Error) -> VdrProxyClientError { + VdrProxyClientError::HttpClientError(err) + } +} + +impl From for VdrProxyClientError { + fn from(err: url::ParseError) -> VdrProxyClientError { + VdrProxyClientError::ParseError(err) + } +} diff --git a/indy-vdr-proxy-client/src/lib.rs b/indy-vdr-proxy-client/src/lib.rs new file mode 100644 index 00000000..5fc3129f --- /dev/null +++ b/indy-vdr-proxy-client/src/lib.rs @@ -0,0 +1,136 @@ +pub mod error; + +use error::VdrProxyClientError; +use reqwest::{Client, Response, Url}; + +pub use indy_vdr::ledger::RequestBuilder; +pub use indy_vdr::pool::PreparedRequest; + +pub struct VdrProxyClient { + client: Client, + url: Url, +} + +async fn map_resp(response: Response) -> Result { + let status = response.status(); + if !status.is_success() { + let text = response.text().await.unwrap_or_default(); + return Err(VdrProxyClientError::NonSuccessStatusCode( + status.as_u16(), + text, + )); + } + response + .text() + .await + .map_err(VdrProxyClientError::HttpClientError) +} + +impl VdrProxyClient { + pub fn new(url: &str) -> Result { + let url = Url::parse(url)?; + let client = Client::new(); + Ok(VdrProxyClient { client, url }) + } + + async fn get_request(&self, url: Url) -> Result { + let response = self.client.get(url).send().await?; + map_resp(response).await + } + + async fn post_request( + &self, + url: Url, + request: PreparedRequest, + ) -> Result { + let response = self + .client + .post(url) + .json(&request.req_json) + .send() + .await + .map_err(VdrProxyClientError::HttpClientError)?; + map_resp(response).await + } + + pub async fn post(&self, request: PreparedRequest) -> Result { + let url = self.url.join("submit")?; + self.post_request(url, request).await + } + + pub async fn get_nym(&self, did: &str) -> Result { + let url = self.url.join(&format!("nym/{}", did))?; + self.get_request(url).await + } + + pub async fn get_attrib(&self, did: &str, attrib: &str) -> Result { + let url = self.url.join(&format!("attrib/{}/{}", did, attrib))?; + self.get_request(url).await + } + + pub async fn get_schema(&self, schema_id: &str) -> Result { + let url = self.url.join(&format!("schema/{}", schema_id))?; + self.get_request(url).await + } + + pub async fn get_cred_def(&self, cred_def_id: &str) -> Result { + let url = self.url.join(&format!("cred_def/{}", cred_def_id))?; + self.get_request(url).await + } + + pub async fn get_rev_reg(&self, rev_reg_def_id: &str) -> Result { + let url = self.url.join(&format!("rev_reg/{}", rev_reg_def_id))?; + self.get_request(url).await + } + + pub async fn get_rev_reg_def( + &self, + rev_reg_def_id: &str, + ) -> Result { + let url = self.url.join(&format!("rev_reg_def/{}", rev_reg_def_id))?; + self.get_request(url).await + } + + pub async fn get_rev_reg_delta( + &self, + rev_reg_def_id: &str, + ) -> Result { + let url = self + .url + .join(&format!("rev_reg_delta/{}", rev_reg_def_id))?; + self.get_request(url).await + } + + pub async fn get_txn_author_agreement(&self) -> Result { + let url = self.url.join("taa")?; + self.get_request(url).await + } + + pub async fn get_genesis_txs(&self) -> Result { + let url = self.url.join("genesis")?; + self.get_request(url).await + } + + pub async fn get_acceptance_methods_list(&self) -> Result { + let url = self.url.join("aml")?; + self.get_request(url).await + } + + pub async fn get_auth_rules(&self) -> Result { + let url = self.url.join("auth")?; + self.get_request(url).await + } + + pub async fn get_proxy_status(&self) -> Result { + self.get_request(self.url.clone()).await + } + + pub async fn get_ledger_txn( + &self, + subledger: &str, + seq_no: u64, + ) -> Result { + let url = self.url.join(&format!("txn/{}/{}", subledger, seq_no))?; + self.get_request(url).await + } +} From c2d585c1050dc1b49fd9d954882e862a930bdaa0 Mon Sep 17 00:00:00 2001 From: blu3beri Date: Mon, 22 May 2023 13:59:56 +0200 Subject: [PATCH 005/117] chore: remove old nodejs wrapper Signed-off-by: blu3beri --- wrappers/nodejs/.eslintrc.js | 19 --- wrappers/nodejs/.gitignore | 13 -- wrappers/nodejs/.prettierrc.js | 7 - wrappers/nodejs/README.md | 11 -- wrappers/nodejs/demo/demo.js | 69 -------- wrappers/nodejs/demo/logger.js | 22 --- wrappers/nodejs/package.json | 74 --------- wrappers/nodejs/src/api/common.ts | 14 -- wrappers/nodejs/src/api/ffi-tools.ts | 44 ----- wrappers/nodejs/src/api/indy-vdr-pool.ts | 124 -------------- wrappers/nodejs/src/api/indy-vdr-utils.ts | 18 -- .../ledger-requests/ledger-request-custom.ts | 22 --- .../ledger-requests/ledger-request-get-nym.ts | 24 --- .../ledger-request-get-schema.ts | 21 --- .../ledger-requests/ledger-request-get-txn.ts | 21 --- .../ledger-request-get-validator-info.ts | 20 --- .../api/ledger-requests/ledger-request-nym.ts | 40 ----- .../src/api/ledger-requests/ledger-request.ts | 32 ---- wrappers/nodejs/src/errors.ts | 23 --- wrappers/nodejs/src/index.ts | 7 - wrappers/nodejs/src/rustlib.ts | 98 ----------- wrappers/nodejs/src/tools.ts | 34 ---- wrappers/nodejs/src/utils/error-message.ts | 12 -- wrappers/nodejs/src/utils/ffi-helpers.ts | 50 ------ .../src/utils/memory-management-helpers.ts | 34 ---- wrappers/nodejs/src/vdr.ts | 39 ----- wrappers/nodejs/test/common/init.ts | 28 ---- wrappers/nodejs/test/integration/main.spec.ts | 155 ------------------ .../nodejs/test/module-resolver-helper.ts | 4 - wrappers/nodejs/test/tsconfig.json | 19 --- wrappers/nodejs/test/tslint.json | 9 - wrappers/nodejs/test/unit/ffi-tools.spec.ts | 61 ------- .../nodejs/test/unit/indy-vdr-pool.spec.ts | 63 ------- .../nodejs/test/unit/indy-vdr-utils.spec.ts | 19 --- .../ledger-request-custom.spec.ts | 51 ------ .../ledger-request-get-txn.spec.ts | 39 ----- wrappers/nodejs/tsconfig.json | 20 --- 37 files changed, 1360 deletions(-) delete mode 100644 wrappers/nodejs/.eslintrc.js delete mode 100644 wrappers/nodejs/.gitignore delete mode 100644 wrappers/nodejs/.prettierrc.js delete mode 100644 wrappers/nodejs/README.md delete mode 100644 wrappers/nodejs/demo/demo.js delete mode 100644 wrappers/nodejs/demo/logger.js delete mode 100644 wrappers/nodejs/package.json delete mode 100644 wrappers/nodejs/src/api/common.ts delete mode 100644 wrappers/nodejs/src/api/ffi-tools.ts delete mode 100644 wrappers/nodejs/src/api/indy-vdr-pool.ts delete mode 100644 wrappers/nodejs/src/api/indy-vdr-utils.ts delete mode 100644 wrappers/nodejs/src/api/ledger-requests/ledger-request-custom.ts delete mode 100644 wrappers/nodejs/src/api/ledger-requests/ledger-request-get-nym.ts delete mode 100644 wrappers/nodejs/src/api/ledger-requests/ledger-request-get-schema.ts delete mode 100644 wrappers/nodejs/src/api/ledger-requests/ledger-request-get-txn.ts delete mode 100644 wrappers/nodejs/src/api/ledger-requests/ledger-request-get-validator-info.ts delete mode 100644 wrappers/nodejs/src/api/ledger-requests/ledger-request-nym.ts delete mode 100644 wrappers/nodejs/src/api/ledger-requests/ledger-request.ts delete mode 100644 wrappers/nodejs/src/errors.ts delete mode 100644 wrappers/nodejs/src/index.ts delete mode 100644 wrappers/nodejs/src/rustlib.ts delete mode 100644 wrappers/nodejs/src/tools.ts delete mode 100644 wrappers/nodejs/src/utils/error-message.ts delete mode 100644 wrappers/nodejs/src/utils/ffi-helpers.ts delete mode 100644 wrappers/nodejs/src/utils/memory-management-helpers.ts delete mode 100644 wrappers/nodejs/src/vdr.ts delete mode 100644 wrappers/nodejs/test/common/init.ts delete mode 100644 wrappers/nodejs/test/integration/main.spec.ts delete mode 100644 wrappers/nodejs/test/module-resolver-helper.ts delete mode 100644 wrappers/nodejs/test/tsconfig.json delete mode 100644 wrappers/nodejs/test/tslint.json delete mode 100644 wrappers/nodejs/test/unit/ffi-tools.spec.ts delete mode 100644 wrappers/nodejs/test/unit/indy-vdr-pool.spec.ts delete mode 100644 wrappers/nodejs/test/unit/indy-vdr-utils.spec.ts delete mode 100644 wrappers/nodejs/test/unit/ledger-requests/ledger-request-custom.spec.ts delete mode 100644 wrappers/nodejs/test/unit/ledger-requests/ledger-request-get-txn.spec.ts delete mode 100644 wrappers/nodejs/tsconfig.json diff --git a/wrappers/nodejs/.eslintrc.js b/wrappers/nodejs/.eslintrc.js deleted file mode 100644 index b264fc06..00000000 --- a/wrappers/nodejs/.eslintrc.js +++ /dev/null @@ -1,19 +0,0 @@ -module.exports = { - parser: '@typescript-eslint/parser', // Specifies the ESLint parser - parserOptions: { - ecmaVersion: 2020, // Allows for the parsing of modern ECMAScript features - sourceType: 'module', // Allows for the use of imports - ecmaFeatures: { - jsx: true, // Allows for the parsing of JSX - }, - }, - extends: [ - 'plugin:@typescript-eslint/recommended', // Uses the recommended rules from the @typescript-eslint/eslint-plugin - 'prettier/@typescript-eslint', // Uses eslint-config-prettier to disable ESLint rules from @typescript-eslint/eslint-plugin that would conflict with prettier - 'plugin:prettier/recommended', // Enables eslint-plugin-prettier and eslint-config-prettier. This will display prettier errors as ESLint errors. Make sure this is always the last configuration in the extends array. - ], - rules: { - // Place to specify ESLint rules. Can be used to overwrite rules specified from the extended configs - // e.g. "@typescript-eslint/explicit-function-return-type": "off", - }, -}; diff --git a/wrappers/nodejs/.gitignore b/wrappers/nodejs/.gitignore deleted file mode 100644 index 43cbdcd7..00000000 --- a/wrappers/nodejs/.gitignore +++ /dev/null @@ -1,13 +0,0 @@ -# this is the libindy header files needed for the build, must be published to npm -dist/ -node_modules/ -build/ -build-pre-gyp/ -Release/ -prebuilds/ -.idea/ -npm-debug.log -package-lock.json -yarn.lock -**/*.genesis.txn -test/integration/dev.spec.ts diff --git a/wrappers/nodejs/.prettierrc.js b/wrappers/nodejs/.prettierrc.js deleted file mode 100644 index 2c66e64e..00000000 --- a/wrappers/nodejs/.prettierrc.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - semi: true, - trailingComma: "all", - singleQuote: true, - printWidth: 120, - tabWidth: 4 -}; diff --git a/wrappers/nodejs/README.md b/wrappers/nodejs/README.md deleted file mode 100644 index 16c1b72e..00000000 --- a/wrappers/nodejs/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# Indy VDR Nodejs Wrapper -- To run demo, follow these steps: -1. Install dependencies `npm install` -2. Compile wrapper `npm run compile` -3. Run demo `npm run demo` - -- To enable library logs, specify `RUST_LOG` environment variable with desired logging level, for example: -```shell script -RUST_LOG=trace npm run demo -``` - diff --git a/wrappers/nodejs/demo/demo.js b/wrappers/nodejs/demo/demo.js deleted file mode 100644 index d8a52e1f..00000000 --- a/wrappers/nodejs/demo/demo.js +++ /dev/null @@ -1,69 +0,0 @@ -// eslint-disable-next-line @typescript-eslint/no-var-requires -const { IndyVdrPool, LedgerRequestCustom, LedgerRequestGetTxn } = require('../dist'); -// eslint-disable-next-line @typescript-eslint/no-var-requires -const { initVdr, indyVdrVersion, indyVdrSetDefaultLogger, indyVdrSetConfig } = require('../dist/api/indy-vdr-utils'); -// eslint-disable-next-line @typescript-eslint/no-var-requires -const axios = require('axios'); -// eslint-disable-next-line @typescript-eslint/no-var-requires -const fs = require('fs'); -// eslint-disable-next-line @typescript-eslint/no-var-requires -const logger = require('./logger')('demo'); - -async function donwloadGenesis() { - const genesisFileUrl = - 'https://raw.githubusercontent.com/sovrin-foundation/sovrin/master/sovrin/pool_transactions_builder_genesis'; - const targetFilePath = `${__dirname}/sov_buildernet.genesis.txn`; - const { data } = await axios.get(genesisFileUrl); - fs.writeFileSync(targetFilePath, data); - return targetFilePath; -} - -async function run() { - const initSuccess = initVdr(); - logger.info(`Init success = ${initSuccess}`); - - indyVdrSetDefaultLogger(); - - const vdrVersion = indyVdrVersion(); - logger.info(`vdrVersion = ${vdrVersion}`); - - const poolConfig = { - protocol_version: 'Node1_4', - freshness_threshold: 300, - ack_timeout: 20, - reply_timeout: 60, - conn_request_limit: 5, - conn_active_timeout: 5, - request_read_nodes: 2, - }; - indyVdrSetConfig(JSON.stringify(poolConfig)); - logger.info(`updated vdr configuration`); - - const genesisPath = await donwloadGenesis(); - const createPoolParams = JSON.stringify({ - transactions_path: genesisPath, - }); - const pool = IndyVdrPool.create('SovrinBuildernet', createPoolParams); - logger.info(`Created Pool ${pool.getName()} using params ${pool.getParams()}`); - - const testRequestData = { - operation: { data: 1, ledgerId: 1, type: '3' }, - protocolVersion: 2, - reqId: 123, - identifier: 'LibindyDid111111111111', - }; - { - const req = LedgerRequestCustom.create(JSON.stringify(testRequestData)); - logger.debug(`Created custom request: ${req.getRequestBody()}`); - const res = await pool.submitRequest(req); - logger.info(`Ledger response: ${JSON.stringify(JSON.parse(res), null, 2)}`); - } - { - const req = LedgerRequestGetTxn.create(1, 1, 'LibindyDid111111111111'); - logger.debug(`Created get-txn request: ${req.getRequestBody()}`); - const res = await pool.submitRequest(req); - logger.info(`Ledger response: ${JSON.stringify(JSON.parse(res), null, 2)}`); - } -} - -run(); diff --git a/wrappers/nodejs/demo/logger.js b/wrappers/nodejs/demo/logger.js deleted file mode 100644 index 3b1a3de7..00000000 --- a/wrappers/nodejs/demo/logger.js +++ /dev/null @@ -1,22 +0,0 @@ -const { createLogger, format, transports } = require('winston') -const { label } = format - -const prettyFormatter = format.combine( - format.printf( - info => `${info.label} [${info.level}]: ${info.message}` - ) -) - -module.exports = loggerLabel => { - return createLogger({ - level: 'debug', - format: format.combine( - label({ label: loggerLabel }), - format.colorize({ all: true }), - prettyFormatter - ), - transports: [ - new transports.Console() - ] - }) -} diff --git a/wrappers/nodejs/package.json b/wrappers/nodejs/package.json deleted file mode 100644 index 24075554..00000000 --- a/wrappers/nodejs/package.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "homepage": "https://github.com/hyperledger/indy-vdr", - "name": "@hyperledger/indy-vdr", - "version": "0.0.1", - "description": "Node wrapper for Indy VDR", - "main": "dist/src/index.js", - "license": "Apache-2.0", - "typings": "dist/index.d.ts", - "directories": { - "test": "test", - "build": "dist", - "lib": "src" - }, - "contributors": [ - { - "name": "Hyperledger Indy Contributors", - "email": "indy@lists.hyperledger.org" - } - ], - "repository": { - "url": "git+https://github.com/hyperledger/indy-vdr.git", - "type": "git" - }, - "dependencies": { - "@types/app-module-path": "^2.2.0", - "@types/ffi-napi": "^2.4.3", - "@types/node": "^8.0.47", - "@types/ref-napi": "^1.4.1", - "@types/ref-struct-di": "^1.1.0", - "@types/weak-napi": "2.0.0", - "eslint": "^7.3.0", - "ffi-napi": "^3.0.1", - "fs-extra": "^4.0.2", - "lodash": "^4.17.11", - "ref-napi": "^3.0.1", - "ref-struct-di": "^1.1.0", - "weak-napi": "^2.0.2" - }, - "devDependencies": { - "@types/chai": "^4.1.4", - "@types/lodash": "^4.14.109", - "@types/mocha": "^5.2.3", - "@typescript-eslint/eslint-plugin": "^3.3.0", - "@typescript-eslint/parser": "^3.3.0", - "app-module-path": "^2.2.0", - "axios": "^0.21.1", - "body-parser": "^1.19.0", - "canonical-json": "0.0.4", - "chai": "^4.1.2", - "eslint-config-prettier": "^6.11.0", - "eslint-plugin-prettier": "^3.1.4", - "mocha": "^7.2.0", - "prettier": "^2.0.5", - "ts-node": "^6.1.2", - "typedoc": "^0.15.4", - "typescript": "^3.2.4", - "winston": "^3.2.1" - }, - "scripts": { - "demo": "node demo/demo.js", - "compile": "./node_modules/.bin/tsc -p ./tsconfig.json", - "clean": "rm -rf dist node_modules", - "lint": "eslint 'src/**/*.{js,ts,tsx}' --quiet --fix", - "test": "npm run test:unit; npm run test:integration;", - "test:unit": "npm run test:ffi-tools; npm run test:vdr-request:custom; npm run test:vdr-request:get-txn; npm run test:vdr-pool;", - "test:integration": "TS_NODE_PROJECT=./test/tsconfig.json NODE_ENV=test RUST_BACKTRACE=full mocha --timeout 10000 --expose-gc --exit --recursive --use_strict --require ts-node/register ./test/integration/main.spec.ts", - "test:integration:dev": "TS_NODE_PROJECT=./test/tsconfig.json NODE_ENV=test RUST_BACKTRACE=full mocha --timeout 10000 --expose-gc --exit --recursive --use_strict --require ts-node/register ./test/integration/dev.spec.ts", - "test:ffi-tools": "TS_NODE_PROJECT=./test/tsconfig.json NODE_ENV=test RUST_BACKTRACE=full mocha --timeout 10000 --expose-gc --exit --recursive --use_strict --require ts-node/register ./test/unit/ffi-tools.spec.ts", - "test:vdr-pool": "TS_NODE_PROJECT=./test/tsconfig.json NODE_ENV=test RUST_BACKTRACE=full mocha --timeout 10000 --expose-gc --exit --recursive --use_strict --require ts-node/register ./test/unit/indy-vdr-pool.spec.ts", - "test:vdr-request": "TS_NODE_PROJECT=./test/tsconfig.json NODE_ENV=test RUST_BACKTRACE=full mocha --timeout 10000 --expose-gc --exit --recursive --use_strict --require ts-node/register ./test/unit/ledger-requests/*.spec.ts", - "test:vdr-request:custom": "TS_NODE_PROJECT=./test/tsconfig.json NODE_ENV=test RUST_BACKTRACE=full mocha --timeout 10000 --expose-gc --exit --recursive --use_strict --require ts-node/register ./test/unit/ledger-requests/ledger-request-custom.spec.ts", - "test:vdr-request:get-txn": "TS_NODE_PROJECT=./test/tsconfig.json NODE_ENV=test RUST_BACKTRACE=full mocha --timeout 10000 --expose-gc --exit --recursive --use_strict --require ts-node/register ./test/unit/ledger-requests/ledger-request-get-txn.spec.ts" - } -} diff --git a/wrappers/nodejs/src/api/common.ts b/wrappers/nodejs/src/api/common.ts deleted file mode 100644 index 556dde06..00000000 --- a/wrappers/nodejs/src/api/common.ts +++ /dev/null @@ -1,14 +0,0 @@ -export enum VDRCode { - SUCCESS = 0, - CONFIG = 1, - CONNECTION = 2, - FILESYSTEM = 3, - INPUT = 4, - RESOURCE = 5, - UNAVAILABLE = 6, - UNEXPECTED = 7, - INCOMPATIBLE = 8, - POOL_NO_CONSENSUS = 30, - POOL_REQUEST_FAILED = 31, - POOL_TIMEOUT = 32, -} diff --git a/wrappers/nodejs/src/api/ffi-tools.ts b/wrappers/nodejs/src/api/ffi-tools.ts deleted file mode 100644 index 1b76254b..00000000 --- a/wrappers/nodejs/src/api/ffi-tools.ts +++ /dev/null @@ -1,44 +0,0 @@ -import * as ref from 'ref-napi'; -import { readUInt64LE } from 'ref-napi'; - -/** - * Converts buffer handle to numeric representation - */ -export function handleBufferToNumber(handle: Buffer): number { - return handle.readIntLE(0, 6); -} - -/* - * Handle can have at most 48bits / 6 bytes - because: - * All numbers in Javascript are 64-bit floating point numbers, which is sufficient to represent any 48-bit integer. - * Source: https://stackoverflow.com/questions/2575523/48-bit-bitwise-operations-in-javascript - */ -export function allocateHandleBuffer(): Buffer { - return Buffer.alloc(6); -} - -/** - * Converts numeric handle to buffer which can be passed down to FFI layers - */ -export function handleNumberToBuffer(handle: number): Buffer { - const buffer = allocateHandleBuffer(); - - buffer.writeUIntLE(handle, 0, 6); - return buffer; -} - -/** - * Returns address of Buffer - */ -export function getAddressOfBuffer(data: Buffer) { - return Number(ref.address(data)).toString(16); -} - -/** - * Reads content of buffer, interprets is as little endian representation of memory address, returns it as string - */ -export function bufferTo64BitAddressString(address: Buffer) { - const address64bit = readUInt64LE(address); - const asString = BigInt(address64bit).toString(16); // if value > Number.MAX_SAFE_INTEGER, readUInt64LE returns the value as string - return `0x${asString}`; -} diff --git a/wrappers/nodejs/src/api/indy-vdr-pool.ts b/wrappers/nodejs/src/api/indy-vdr-pool.ts deleted file mode 100644 index fc8f62ef..00000000 --- a/wrappers/nodejs/src/api/indy-vdr-pool.ts +++ /dev/null @@ -1,124 +0,0 @@ -import { rustAPI } from '../rustlib'; -import { VDRInternalError } from '../errors'; -import { allocateHandleBuffer, handleBufferToNumber } from './ffi-tools'; -import { createFFICallbackPromise } from '../utils/ffi-helpers'; -import { Callback } from 'ffi-napi'; -import * as ref from 'ref-napi'; -import { LedgerRequest } from './ledger-requests/ledger-request'; - -/** - * @class Class representing a Indy Pool - */ -export class IndyVdrPool { - protected _handle: Buffer; - protected _params: string; - protected _name: string; - - constructor(name: string, params: string) { - this._handle = allocateHandleBuffer(); - this._params = params; - this._name = name; - } - - public static create(name: string, params: string): IndyVdrPool { - try { - const pool = new IndyVdrPool(name, params); - rustAPI().indy_vdr_pool_create(params, pool._handle); - return pool; - } catch (err) { - throw new VDRInternalError(err); - } - } - - public close() { - try { - const rc = rustAPI().indy_vdr_pool_close(this.getHandle()); - if (rc) { - throw Error(`Failed to close pool!`); - } - } catch (err) { - throw new VDRInternalError(err); - } - } - - public getHandle(): number { - return handleBufferToNumber(this._handle); - } - - public getName(): string { - return this._name; - } - - public getParams(): string { - return this._params; - } - - public async submitRequest(request: LedgerRequest): Promise { - try { - return await createFFICallbackPromise( - (resolve, reject, cb) => { - const rc = rustAPI().indy_vdr_pool_submit_request(this.getHandle(), request.getHandle(), cb, 5); - if (rc) { - reject(rc); - } - }, - (resolve, reject) => - Callback('void', ['uint32', 'uint32', 'pointer'], (id: number, err: number, response: Buffer) => { - if (err) { - reject(err); - return; - } - resolve(ref.readCString(response, 0)); - }), - ); - } catch (err) { - throw new VDRInternalError(err); - } - } - - public async getStatus(): Promise { - try { - return await createFFICallbackPromise( - (resolve, reject, cb) => { - const rc = rustAPI().indy_vdr_pool_get_status(this.getHandle(), cb, 5); - if (rc) { - reject(rc); - } - }, - (resolve, reject) => - Callback('void', ['uint32', 'uint32', 'pointer'], (id: number, err: number, response: Buffer) => { - if (err) { - reject(err); - return; - } - resolve(ref.readCString(response, 0)); - }), - ); - } catch (err) { - throw new VDRInternalError(err); - } - } - - public async getPoolTransactions(): Promise { - try { - return await createFFICallbackPromise( - (resolve, reject, cb) => { - const rc = rustAPI().indy_vdr_pool_get_transactions(this.getHandle(), cb, 5); - if (rc) { - reject(rc); - } - }, - (resolve, reject) => - Callback('void', ['uint32', 'uint32', 'pointer'], (id: number, err: number, response: Buffer) => { - if (err) { - reject(err); - return; - } - resolve(ref.readCString(response, 0)); - }), - ); - } catch (err) { - throw new VDRInternalError(err); - } - } -} diff --git a/wrappers/nodejs/src/api/indy-vdr-utils.ts b/wrappers/nodejs/src/api/indy-vdr-utils.ts deleted file mode 100644 index 58b2acc2..00000000 --- a/wrappers/nodejs/src/api/indy-vdr-utils.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { initRustAPI, rustAPI } from '../rustlib'; - -export function initVdr(vdrPath?: string): boolean { - initRustAPI(vdrPath); - return true; -} - -export function indyVdrVersion(): string { - return rustAPI().indy_vdr_version(); -} - -export function indyVdrSetConfig(config: string): number { - return rustAPI().indy_vdr_set_config(config); -} - -export function indyVdrSetDefaultLogger(): number { - return rustAPI().indy_vdr_set_default_logger(); -} diff --git a/wrappers/nodejs/src/api/ledger-requests/ledger-request-custom.ts b/wrappers/nodejs/src/api/ledger-requests/ledger-request-custom.ts deleted file mode 100644 index 1a442cac..00000000 --- a/wrappers/nodejs/src/api/ledger-requests/ledger-request-custom.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { rustAPI } from '../../rustlib'; -import { VDRInternalError } from '../../errors'; -import { LedgerRequest } from './ledger-request'; - -export class LedgerRequestCustom extends LedgerRequest { - protected _params: string; - - constructor(params: string) { - super(); - this._params = params; - } - - public static create(params: string): LedgerRequestCustom { - try { - const request = new LedgerRequestCustom(params); - rustAPI().indy_vdr_build_custom_request(params, request._handle); - return request; - } catch (err) { - throw new VDRInternalError(err); - } - } -} diff --git a/wrappers/nodejs/src/api/ledger-requests/ledger-request-get-nym.ts b/wrappers/nodejs/src/api/ledger-requests/ledger-request-get-nym.ts deleted file mode 100644 index 626d043f..00000000 --- a/wrappers/nodejs/src/api/ledger-requests/ledger-request-get-nym.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { rustAPI } from '../../rustlib'; -import { VDRInternalError } from '../../errors'; -import { LedgerRequest } from './ledger-request'; -import { allocCString, NULL } from 'ref-napi'; - -/** - * Builds GET_NYM transaction. - */ -export class LedgerRequestGetNym extends LedgerRequest { - constructor() { - super(); - } - - public static create(dest: string, submitterDid?: string): LedgerRequestGetNym { - try { - const request = new LedgerRequestGetNym(); - const submitterDidFfi = submitterDid ? allocCString(submitterDid) : NULL; - rustAPI().indy_vdr_build_get_nym_request(submitterDidFfi, allocCString(dest), request._handle); - return request; - } catch (err) { - throw new VDRInternalError(err); - } - } -} diff --git a/wrappers/nodejs/src/api/ledger-requests/ledger-request-get-schema.ts b/wrappers/nodejs/src/api/ledger-requests/ledger-request-get-schema.ts deleted file mode 100644 index 203b520c..00000000 --- a/wrappers/nodejs/src/api/ledger-requests/ledger-request-get-schema.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { rustAPI } from '../../rustlib'; -import { VDRInternalError } from '../../errors'; -import { LedgerRequest } from './ledger-request'; -import { allocCString, NULL } from 'ref-napi'; - -export class LedgerRequestGetSchema extends LedgerRequest { - constructor() { - super(); - } - - public static create(schemaId: string, submitterDid?: string): LedgerRequestGetSchema { - try { - const request = new LedgerRequestGetSchema(); - const submitterDidFfi = submitterDid ? allocCString(submitterDid) : NULL; - rustAPI().indy_vdr_build_get_schema_request(submitterDidFfi, allocCString(schemaId), request._handle); - return request; - } catch (err) { - throw new VDRInternalError(err); - } - } -} diff --git a/wrappers/nodejs/src/api/ledger-requests/ledger-request-get-txn.ts b/wrappers/nodejs/src/api/ledger-requests/ledger-request-get-txn.ts deleted file mode 100644 index 7a8abd5c..00000000 --- a/wrappers/nodejs/src/api/ledger-requests/ledger-request-get-txn.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { rustAPI } from '../../rustlib'; -import { VDRInternalError } from '../../errors'; -import { LedgerRequest } from './ledger-request'; -import { allocCString, NULL } from 'ref-napi'; - -export class LedgerRequestGetTxn extends LedgerRequest { - constructor() { - super(); - } - - public static create(ledgerType: number, seqNo: number, submitterDid?: string): LedgerRequestGetTxn { - try { - const request = new LedgerRequestGetTxn(); - const submitterDidFfi = submitterDid ? allocCString(submitterDid) : NULL; - rustAPI().indy_vdr_build_get_txn_request(submitterDidFfi, ledgerType, seqNo, request._handle); - return request; - } catch (err) { - throw new VDRInternalError(err); - } - } -} diff --git a/wrappers/nodejs/src/api/ledger-requests/ledger-request-get-validator-info.ts b/wrappers/nodejs/src/api/ledger-requests/ledger-request-get-validator-info.ts deleted file mode 100644 index 38199c9e..00000000 --- a/wrappers/nodejs/src/api/ledger-requests/ledger-request-get-validator-info.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { rustAPI } from '../../rustlib'; -import { VDRInternalError } from '../../errors'; -import { LedgerRequest } from './ledger-request'; -import { allocCString } from 'ref-napi'; - -export class LedgerRequestGetValidatorInfo extends LedgerRequest { - constructor() { - super(); - } - - public static create(submitterDid: string): LedgerRequestGetValidatorInfo { - try { - const request = new LedgerRequestGetValidatorInfo(); - rustAPI().indy_vdr_build_get_validator_info_request(allocCString(submitterDid), request._handle); - return request; - } catch (err) { - throw new VDRInternalError(err); - } - } -} diff --git a/wrappers/nodejs/src/api/ledger-requests/ledger-request-nym.ts b/wrappers/nodejs/src/api/ledger-requests/ledger-request-nym.ts deleted file mode 100644 index a8972758..00000000 --- a/wrappers/nodejs/src/api/ledger-requests/ledger-request-nym.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { rustAPI } from '../../rustlib'; -import { VDRInternalError } from '../../errors'; -import { LedgerRequest } from './ledger-request'; -import { allocCString, NULL } from 'ref-napi'; - -/** - * Builds NYM transaction. In order to submit this successfully, you'll have to attach signature using - * indy_vdr_request_set_signature or indy_vdr_request_add_multi_signature - */ -export class LedgerRequestNym extends LedgerRequest { - constructor() { - super(); - } - - public static create( - submitterDid: string, - dest: string, - verkey?: string, - alias?: string, - role?: string, - ): LedgerRequestNym { - try { - const request = new LedgerRequestNym(); - const verkeyFfi = verkey ? allocCString(verkey) : NULL; - const aliasFfi = alias ? allocCString(alias) : NULL; - const roleFfi = role ? allocCString(role) : NULL; - rustAPI().indy_vdr_build_nym_request( - allocCString(submitterDid), - allocCString(dest), - verkeyFfi, - aliasFfi, - roleFfi, - request._handle, - ); - return request; - } catch (err) { - throw new VDRInternalError(err); - } - } -} diff --git a/wrappers/nodejs/src/api/ledger-requests/ledger-request.ts b/wrappers/nodejs/src/api/ledger-requests/ledger-request.ts deleted file mode 100644 index 2aacc714..00000000 --- a/wrappers/nodejs/src/api/ledger-requests/ledger-request.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { rustAPI } from '../../rustlib'; -import { VDRInternalError } from '../../errors'; -import { allocateHandleBuffer, handleBufferToNumber } from '../ffi-tools'; -import * as ref from 'ref-napi'; - -export class LedgerRequest { - protected _handle: Buffer; - - constructor() { - this._handle = allocateHandleBuffer(); - } - - public getHandle(): number { - return handleBufferToNumber(this._handle); - } - - public getRequestBody(): string { - try { - const body_ptr = Buffer.alloc(8); - // indy_vdr_request_get_body requires pointer to memory where it can store pointer to the string - // it wants to return, essentially pointer to pointer - rustAPI().indy_vdr_request_get_body(this.getHandle(), ref.address(body_ptr)); - // now in body_ptr is store address where the CString begins, we create pointer (buffer) - const pointer = ref.readPointer(body_ptr, 0, 0); - // and read the CString starting from that location, until we NULL is encountered. - return ref.readCString(pointer, 0); - // TODO: question is now - will GC take care of this? Or do I have to call "indy_vdr_string_free" function? - } catch (err) { - throw new VDRInternalError(err); - } - } -} diff --git a/wrappers/nodejs/src/errors.ts b/wrappers/nodejs/src/errors.ts deleted file mode 100644 index dc77b099..00000000 --- a/wrappers/nodejs/src/errors.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { errorMessage } from './utils/error-message'; - -export class VDRInternalError extends Error { - public readonly vdrCode: number; - public readonly inheritedStackTraces: any[] = []; - - constructor(code: number | Error) { - super(errorMessage(code)); - if (code instanceof Error) { - if (code.stack) { - this.inheritedStackTraces.push(code.stack); - } - if (code instanceof VDRInternalError) { - this.vdrCode = code.vdrCode; - this.inheritedStackTraces.unshift(...code.inheritedStackTraces); - return this; - } - this.vdrCode = 1234; - return this; - } - this.vdrCode = code; - } -} diff --git a/wrappers/nodejs/src/index.ts b/wrappers/nodejs/src/index.ts deleted file mode 100644 index cd3258ff..00000000 --- a/wrappers/nodejs/src/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -export * from './api/indy-vdr-pool'; -export * from './api/indy-vdr-utils'; -export * from './api/ledger-requests/ledger-request-custom'; -export * from './api/ledger-requests/ledger-request-get-txn'; -export * from './vdr'; -export * from './rustlib'; -export * from './errors'; diff --git a/wrappers/nodejs/src/rustlib.ts b/wrappers/nodejs/src/rustlib.ts deleted file mode 100644 index 03f22059..00000000 --- a/wrappers/nodejs/src/rustlib.ts +++ /dev/null @@ -1,98 +0,0 @@ -import * as ref from 'ref-napi'; -// import * as StructType from 'ref-struct-di'; - -import { VDRRuntime } from './vdr'; - -interface IUintTypes { - [key: string]: string; -} -const UINTS_TYPES: IUintTypes = { x86: 'uint32', x64: 'uint64' }; -const ARCHITECTURE: string = process.env.INDY_VDR_FFI_ARCHITECTURE || 'x64'; -const FFI_USIZE: string = UINTS_TYPES[ARCHITECTURE]; - -// FFI Type Strings -export const FFI_CALLBACK_ID = 'int'; -export const FFI_ERROR_CODE = 'int'; -export const FFI_BOOL = 'bool'; -export const FFI_HANDLE = 'uint32'; -export const FFI_REQUEST_HANDLE = 'uint32'; -export const FFI_UNSIGNED_INT = 'uint32'; -export const FFI_UNSIGNED_LONG = 'uint64'; -export const FFI_UNSIGNED_INT_PTR = FFI_USIZE; -export const FFI_STRING = 'string'; -export const FFI_CONFIG_PATH = FFI_STRING; -export const FFI_STRING_DATA = 'string'; -export const FFI_SOURCE_ID = 'string'; -export const FFI_VOID = ref.types.void; -export const FFI_USIZE_PTR = ref.refType(FFI_HANDLE); -export const FFI_CALLBACK_PTR = 'pointer'; - -// Rust Lib Native Types -export type rust_string = string; -export type rust_err_code = number; -export type rust_command_handle = number; -export type rust_object_handle = number; -export type rust_pool_handle = rust_object_handle; - -export interface IFFIEntryPoint { - indy_vdr_version: () => rust_string; - indy_vdr_set_config: (config: rust_string) => rust_err_code; - indy_vdr_set_default_logger: () => rust_err_code; - // requests - indy_vdr_build_custom_request: (requestJson: string, requestHandle: Buffer) => rust_err_code; - indy_vdr_build_get_schema_request: (submitterDid: Buffer, schemaId: Buffer, requestHandle: Buffer) => rust_err_code; - indy_vdr_build_get_txn_request: ( - submitterDid: Buffer, - ledgerType: number, - seqNo: number, - requestHandle: Buffer, - ) => rust_err_code; - indy_vdr_build_nym_request: ( - submitterDid: Buffer, - dest: Buffer, - verkey: Buffer, - alias: Buffer, - role: Buffer, - requestHandle: Buffer, - ) => rust_err_code; - indy_vdr_build_get_nym_request: (submitterDid: Buffer, dest: Buffer, requestHandle: Buffer) => rust_err_code; - indy_vdr_build_get_validator_info_request: (submitterDid: Buffer, requestHandle: Buffer) => rust_err_code; - indy_vdr_request_get_body: (requestHandle: number, bodyReturnPtr: number) => rust_err_code; - // pool - indy_vdr_pool_create: (params: rust_string, pool_handle: Buffer) => rust_err_code; - indy_vdr_pool_close: (poolHandle: number) => rust_err_code; - indy_vdr_pool_submit_request: (poolHandle: number, requestHandle: number, cb: any, cbId: number) => rust_err_code; - indy_vdr_pool_get_status: (poolHandle: number, cb: any, cbId: number) => rust_err_code; - indy_vdr_pool_get_transactions: (poolHandle: number, cb: any, cbId: number) => rust_err_code; -} - -/** - * @class Class containing indyVDR FFI API functions - */ -export const FFIConfiguration: { [Key in keyof IFFIEntryPoint]: any } = { - // first element is method return type, second element is list of method argument types - indy_vdr_version: [FFI_STRING, []], - indy_vdr_set_config: [FFI_ERROR_CODE, [FFI_STRING_DATA]], - indy_vdr_set_default_logger: [FFI_ERROR_CODE, []], - // requests - indy_vdr_build_custom_request: [FFI_ERROR_CODE, [FFI_STRING_DATA, FFI_USIZE_PTR]], - indy_vdr_build_get_txn_request: [FFI_ERROR_CODE, [FFI_USIZE_PTR, FFI_USIZE, FFI_USIZE, FFI_USIZE_PTR]], - indy_vdr_build_nym_request: [ - FFI_ERROR_CODE, - [FFI_USIZE_PTR, FFI_USIZE_PTR, FFI_USIZE_PTR, FFI_USIZE_PTR, FFI_USIZE_PTR, FFI_USIZE_PTR], - ], - indy_vdr_build_get_schema_request: [FFI_ERROR_CODE, [FFI_USIZE_PTR, FFI_USIZE_PTR, FFI_USIZE_PTR]], - indy_vdr_build_get_nym_request: [FFI_ERROR_CODE, [FFI_USIZE_PTR, FFI_USIZE_PTR, FFI_USIZE_PTR]], - indy_vdr_build_get_validator_info_request: [FFI_ERROR_CODE, [FFI_USIZE_PTR, FFI_USIZE_PTR]], - indy_vdr_request_get_body: [FFI_ERROR_CODE, [FFI_USIZE, FFI_USIZE]], - // pool - indy_vdr_pool_create: [FFI_ERROR_CODE, [FFI_STRING_DATA, FFI_USIZE_PTR]], - indy_vdr_pool_close: [FFI_ERROR_CODE, [FFI_USIZE]], - indy_vdr_pool_submit_request: [FFI_ERROR_CODE, [FFI_USIZE, FFI_USIZE, FFI_CALLBACK_PTR, FFI_USIZE]], - indy_vdr_pool_get_status: [FFI_ERROR_CODE, [FFI_USIZE, FFI_CALLBACK_PTR, FFI_USIZE]], - indy_vdr_pool_get_transactions: [FFI_ERROR_CODE, [FFI_USIZE, FFI_CALLBACK_PTR, FFI_USIZE]], -}; - -let _rustAPI: IFFIEntryPoint; -export const initRustAPI = (path?: string) => (_rustAPI = new VDRRuntime({ basepath: path }).ffi); -export const rustAPI = () => _rustAPI; diff --git a/wrappers/nodejs/src/tools.ts b/wrappers/nodejs/src/tools.ts deleted file mode 100644 index 5a95488b..00000000 --- a/wrappers/nodejs/src/tools.ts +++ /dev/null @@ -1,34 +0,0 @@ -import axios from 'axios'; -import * as fs from 'fs'; -import { URL } from 'url'; - -export enum IndyNetwork { - SOVRIN_BUILDER_NET, - SOVRIN_STAGING_NET, - SOVRIN_MAIN_NET, -} - -export function getNetworkGenesisFileUrl(network: IndyNetwork): URL { - switch (network) { - case IndyNetwork.SOVRIN_BUILDER_NET: - return new URL( - 'https://raw.githubusercontent.com/sovrin-foundation/sovrin/master/sovrin/pool_transactions_builder_genesis', - ); - case IndyNetwork.SOVRIN_STAGING_NET: - return new URL( - 'https://raw.githubusercontent.com/sovrin-foundation/sovrin/master/sovrin/pool_transactions_sandbox_genesis', - ); - case IndyNetwork.SOVRIN_MAIN_NET: - return new URL( - 'https://raw.githubusercontent.com/sovrin-foundation/sovrin/master/sovrin/pool_transactions_live_genesis', - ); - default: - throw Error(`Unknown network ${network}`); - } -} - -export async function downloadGenesisFile(genesisFileUrl: URL, targetFilePath: string): Promise { - const { data } = await axios.get(genesisFileUrl.toString()); - fs.writeFileSync(targetFilePath, data); - return targetFilePath; -} diff --git a/wrappers/nodejs/src/utils/error-message.ts b/wrappers/nodejs/src/utils/error-message.ts deleted file mode 100644 index 5e60e456..00000000 --- a/wrappers/nodejs/src/utils/error-message.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { VDRInternalError } from '../errors'; - -export const errorMessage = (errorCode: number | Error): string => { - if (errorCode instanceof VDRInternalError) { - return errorCode.message; - } - if (errorCode instanceof Error) { - const message = 'VDR node error 1'; - return `${message}: ${errorCode.message}`; - } - return 'VDR node error 2'; -}; diff --git a/wrappers/nodejs/src/utils/ffi-helpers.ts b/wrappers/nodejs/src/utils/ffi-helpers.ts deleted file mode 100644 index 0f476f55..00000000 --- a/wrappers/nodejs/src/utils/ffi-helpers.ts +++ /dev/null @@ -1,50 +0,0 @@ -const maxTimeout = 2147483647; - -export type ICbRef = Buffer; - -// Lib function which accepts a callback and rejects with a return code if needed -export type ICreateFFICallbackPromiseFn = ( - resolve: (value?: T) => void, - reject: (reason?: any) => void, - cbRef: ICbRef, -) => void; - -// eslint-disable-next-line prettier/prettier -export type ICreateFFICallbackPromiseCb = ( - resolve: (value?: T) => void, - reject: (reason?: any) => void -) => ICbRef; - - -/** - * Creates promise which wraps two functions "fn" and "cb". The "fn" is supposed to be responsible - * for initiating calls into FFI. The "cb" is returns C function pointer to function which is capable - * of handling result of the FFI call. Based on the result, it either resolves or rejects the wrapping JS promise. - * The "fn" is also provided pointer to callback "cb" promise, which is typically provided into FFI - once the work - * below FFI layer is done, it would call "cb". - * - * @param fn - function responsible for making FFI call. It needs to assure the FFI underlying code will call "cb" - * with the result, once the work is done. - * - * @param cb - function returning C function pointer responsible for handling result of the FFI call - */ -export const createFFICallbackPromise = (fn: ICreateFFICallbackPromiseFn, cb: ICreateFFICallbackPromiseCb) => { - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - let cbRef = null; - // TODO: Research why registering a callback doesn't keep parent thread alive https://github.com/node-ffi/node-ffi - const processKeepAliveTimer = setTimeout(() => undefined, maxTimeout); - - // Creates promise wrapping "fn" and "cb" functions, both of which can resolve or reject the promise. - return new Promise((resolve, reject) => fn(resolve, reject, (cbRef = cb(resolve, reject)))) - .then((res) => { - cbRef = null; - clearTimeout(processKeepAliveTimer); - return res; - }) - .catch((err) => { - cbRef = null; - clearTimeout(processKeepAliveTimer); - throw err; - }); -}; diff --git a/wrappers/nodejs/src/utils/memory-management-helpers.ts b/wrappers/nodejs/src/utils/memory-management-helpers.ts deleted file mode 100644 index 447386a6..00000000 --- a/wrappers/nodejs/src/utils/memory-management-helpers.ts +++ /dev/null @@ -1,34 +0,0 @@ -import * as weak from 'weak-napi'; - -export abstract class GCWatcher { - protected abstract _releaseFn: any; - // LibVCX handles invalid handles - private _handleRef!: number; - - public async release(): Promise { - // we will not throw an error if released is called - // on an invalid/already released handle - this._releaseFn(this._handleRef); - } - - // Can not use setter because of https://github.com/Microsoft/TypeScript/issues/2521 - protected _setHandle(handle: number): void { - this._handleRef = handle; - this._clearOnExit(); - } - - // _clearOnExit creates a callback that will release the Rust Object - // when the node Connection object is Garbage collected - protected _clearOnExit() { - const weakRef = weak(this); - const release = this._releaseFn; - const handle = this._handleRef; - weak.addCallback(weakRef, () => { - release(handle); - }); - } - - get handle() { - return this._handleRef; - } -} diff --git a/wrappers/nodejs/src/vdr.ts b/wrappers/nodejs/src/vdr.ts deleted file mode 100644 index 9cd41fa2..00000000 --- a/wrappers/nodejs/src/vdr.ts +++ /dev/null @@ -1,39 +0,0 @@ -import * as ffi from 'ffi-napi'; -import * as os from 'os'; - -import { FFIConfiguration, IFFIEntryPoint } from './rustlib'; - -export interface IVDRRuntimeConfig { - basepath?: string; -} - -const extension: Dictionary = { darwin: '.dylib', linux: '.so', win32: '.dll' }; -const libPath: Dictionary = { darwin: '/usr/local/lib/', linux: '/usr/lib/', win32: 'c:\\windows\\system32\\' }; - -interface Dictionary { - [Key: string]: string; -} - -/** - * @class Class which encapsulates IndyVDR FFI initialization - */ -export class VDRRuntime { - public readonly ffi: IFFIEntryPoint; - private _config: IVDRRuntimeConfig; - - constructor(config: IVDRRuntimeConfig = {}) { - this._config = config; - // initialize FFI - const libraryPath = this._initializeBasepath(); - this.ffi = ffi.Library(libraryPath, FFIConfiguration); - } - - private _initializeBasepath = (): string => { - const platform = os.platform(); - const postfix = extension[platform.toLowerCase()] || extension.linux; - const libDir = libPath[platform.toLowerCase()] || libPath.linux; - const library = `libindy_vdr${postfix}`; - const customPath = process.env.LIB_INDY_VDR_PATH ? process.env.LIB_INDY_VDR_PATH + library : undefined; - return customPath || this._config.basepath || `${libDir}${library}`; - }; -} diff --git a/wrappers/nodejs/test/common/init.ts b/wrappers/nodejs/test/common/init.ts deleted file mode 100644 index 3d03b227..00000000 --- a/wrappers/nodejs/test/common/init.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { indyVdrSetDefaultLogger, initVdr } from 'src'; -import { assert } from 'chai'; -import { downloadGenesisFile, getNetworkGenesisFileUrl, IndyNetwork } from '../../src/tools'; -import * as fs from 'fs'; - -export interface NetworkInfo { - network: IndyNetwork; - genesisFilePath: string; -} - -export async function initVdrTest(): Promise { - const initSuccess = initVdr(); - assert.isTrue(initSuccess); - indyVdrSetDefaultLogger(); - - const selectedNetwork: string = process.env.INDY_NETWORK || 'SOVRIN_BUILDER_NET'; - const network = IndyNetwork[selectedNetwork as keyof typeof IndyNetwork]; - const genesisUrl = getNetworkGenesisFileUrl(network); - const genesisFilePath = `${__dirname}/${selectedNetwork}.genesis.txn`; - console.log(`genesisPath=${genesisFilePath}`); - if (!fs.existsSync(genesisFilePath)) { - await downloadGenesisFile(genesisUrl, genesisFilePath); - } - return { - genesisFilePath, - network, - }; -} diff --git a/wrappers/nodejs/test/integration/main.spec.ts b/wrappers/nodejs/test/integration/main.spec.ts deleted file mode 100644 index 7c1e7400..00000000 --- a/wrappers/nodejs/test/integration/main.spec.ts +++ /dev/null @@ -1,155 +0,0 @@ -import '../module-resolver-helper'; - -import { assert } from 'chai'; -import { IndyVdrPool, LedgerRequestCustom, LedgerRequestGetTxn } from 'src'; -import { initVdrTest, NetworkInfo } from '../common/init'; -import { LedgerRequestNym } from '../../src/api/ledger-requests/ledger-request-nym'; -import { LedgerRequestGetValidatorInfo } from '../../src/api/ledger-requests/ledger-request-get-validator-info'; -import { IndyNetwork } from '../../src/tools'; -import { LedgerRequestGetNym } from '../../src/api/ledger-requests/ledger-request-get-nym'; -import {LedgerRequestGetSchema} from "../../src/api/ledger-requests/ledger-request-get-schema"; - -describe('Integration suite', () => { - let network: NetworkInfo; - - before(async () => { - network = await initVdrTest(); - }); - - it('should fetch transaction using custom transaction', async () => { - const testRequestData = JSON.stringify({ - operation: { data: 1, ledgerId: 1, type: '3' }, - protocolVersion: 2, - reqId: 1234, - identifier: 'LibindyDid111111111111', - }); - - const request: LedgerRequestCustom = LedgerRequestCustom.create(testRequestData); - const createPoolParams = JSON.stringify({ transactions_path: network.genesisFilePath }); - - const pool: IndyVdrPool = IndyVdrPool.create(network.network.toString(), createPoolParams); - const response = await pool.submitRequest(request); - assert.isString(response); - const responseObj = JSON.parse(response); - assert.equal(responseObj.op, 'REPLY'); - assert.equal(responseObj.result.seqNo, 1); - assert.isObject(responseObj.result.data); - // pool.close(); - }); - - it('should fetch transaction using get-txn', async () => { - const request: LedgerRequestGetTxn = LedgerRequestGetTxn.create(1, 1); - const createPoolParams = JSON.stringify({ transactions_path: network.genesisFilePath }); - - const pool: IndyVdrPool = IndyVdrPool.create(network.network.toString(), createPoolParams); - const response = await pool.submitRequest(request); - assert.isString(response); - const responseObj = JSON.parse(response); - assert.equal(responseObj.op, 'REPLY'); - assert.equal(responseObj.result.seqNo, 1); - assert.isObject(responseObj.result.data); - // pool.close(); - }); - - // todo: to test this, we'd need to sign the request and attach it using indy_vdr_request_set_signature - it.skip('should fetch transaction using nym', async () => { - const request: LedgerRequestGetTxn = LedgerRequestNym.create( - 'LibindyDid111111111111', - 'FbjuFFq6jLsSMdgN9ifErE', - ); - const createPoolParams = JSON.stringify({ transactions_path: network.genesisFilePath }); - - const pool: IndyVdrPool = IndyVdrPool.create(network.network.toString(), createPoolParams); - const response = await pool.submitRequest(request); - assert.isString(response); - console.log(JSON.stringify(JSON.parse(response), null, 2)); - // pool.close(); - }); - - // todo: to test this, we'd need to sign the request and attach it using indy_vdr_request_set_signature - it.skip('should get validator info', async () => { - const request: LedgerRequestGetValidatorInfo = LedgerRequestGetValidatorInfo.create('FbjuFFq6jLsSMdgN9ifErE'); - const createPoolParams = JSON.stringify({ transactions_path: network.genesisFilePath }); - - const pool: IndyVdrPool = IndyVdrPool.create(network.network.toString(), createPoolParams); - const response = await pool.submitRequest(request); - assert.isString(response); - console.log(JSON.stringify(JSON.parse(response), null, 2)); - }); - - function getExistingDidForNetwork(network: IndyNetwork): string { - if (network === IndyNetwork.SOVRIN_MAIN_NET) { - return '4nbERyUuQuEGDxmBZqisda'; - } else if (network === IndyNetwork.SOVRIN_STAGING_NET) { - return 'VCAi7DaxdTAJAv2uQpuA8B'; - } else if (network === IndyNetwork.SOVRIN_BUILDER_NET) { - return 'V5qJo72nMeF7x3ci8Zv2WP'; - } - throw Error(`Unknown network`); - } - - it('should get nym', async () => { - const queryDid = getExistingDidForNetwork(network.network); - const request: LedgerRequestGetNym = LedgerRequestGetNym.create(queryDid); - const createPoolParams = JSON.stringify({ transactions_path: network.genesisFilePath }); - - const pool: IndyVdrPool = IndyVdrPool.create(network.network.toString(), createPoolParams); - const response = await pool.submitRequest(request); - const responseObj = JSON.parse(response); - assert.equal(responseObj.op, 'REPLY'); - assert.isNumber(responseObj.result.seqNo); - assert.isString(responseObj.result.data); - }); - - function getSchemaIdForNetwork(network: IndyNetwork): string { - if (network === IndyNetwork.SOVRIN_MAIN_NET) { - return '4xE68b6S5VRFrKMMG1U95M:2:Practicing Certificate:1.0.0'; - } else if (network === IndyNetwork.SOVRIN_STAGING_NET) { - return 'ALyqhiVkmT2zDLdNvBNZzm:2:SchemaExampleSAP:1.1'; - } else if (network === IndyNetwork.SOVRIN_BUILDER_NET) { - return 'FbjuFFq6jLsSMdgN9ifErE:2:Specialitate Medic:1.0'; - } - throw Error(`Unknown network`); - } - - it('should get schema', async () => { - const querySchemaId = getSchemaIdForNetwork(network.network); - const request: LedgerRequestGetSchema = LedgerRequestGetSchema.create(querySchemaId); - const createPoolParams = JSON.stringify({ transactions_path: network.genesisFilePath }); - - const pool: IndyVdrPool = IndyVdrPool.create(network.network.toString(), createPoolParams); - const response = await pool.submitRequest(request); - const responseObj = JSON.parse(response); - assert.equal(responseObj.op, 'REPLY'); - assert.isNumber(responseObj.result.seqNo); - assert.isObject(responseObj.result.state_proof); - assert.isArray(responseObj.result.data.attr_names); - }); - - it('should get pool status', async () => { - const createPoolParams = JSON.stringify({ transactions_path: network.genesisFilePath }); - const pool: IndyVdrPool = IndyVdrPool.create(network.network.toString(), createPoolParams); - const response = await pool.getStatus(); - assert.isString(response); - const responseObj = JSON.parse(response); - assert.isString(responseObj.mt_root); - assert.isNumber(responseObj.mt_size); - assert.isArray(responseObj.nodes); - // pool.close(); // TODO: looks like VDR bug, blocks for long time and fails to close the pool - }); - - it('should close pool', async () => { - const createPoolParams = JSON.stringify({ transactions_path: network.genesisFilePath }); - const pool: IndyVdrPool = IndyVdrPool.create(network.network.toString(), createPoolParams); - pool.close(); - let thrown = false; - try { - await pool.getStatus(); - } catch (err) { - thrown = true; - assert.equal(err.message, 'VDR node error 2'); - assert.equal(err.vdrCode, 4); // todo: looks like VDR bug, should be 2 - } - assert.isTrue(thrown); - }); -}); diff --git a/wrappers/nodejs/test/module-resolver-helper.ts b/wrappers/nodejs/test/module-resolver-helper.ts deleted file mode 100644 index f01ebdfe..00000000 --- a/wrappers/nodejs/test/module-resolver-helper.ts +++ /dev/null @@ -1,4 +0,0 @@ -import * as path from 'path'; -import * as appModulePath from 'app-module-path'; -appModulePath.addPath(path.resolve(__dirname, '../')); -appModulePath.addPath(__dirname); diff --git a/wrappers/nodejs/test/tsconfig.json b/wrappers/nodejs/test/tsconfig.json deleted file mode 100644 index 0ff7faaa..00000000 --- a/wrappers/nodejs/test/tsconfig.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "extends": "../tsconfig.json", - "compilerOptions": { - "baseUrl": "./", - "paths": { - "*": [ - "./*", - "*" - ], - "src": ["../src"] - }, - "lib": [ - "esnext.bigint" - ] - }, - "include": [ - "./**/*" - ] -} diff --git a/wrappers/nodejs/test/tslint.json b/wrappers/nodejs/test/tslint.json deleted file mode 100644 index cd0c757c..00000000 --- a/wrappers/nodejs/test/tslint.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "defaultSeverity": "error", - "extends": [ - "../tslint.json" - ], - "rules": { - "no-console": false - } -} \ No newline at end of file diff --git a/wrappers/nodejs/test/unit/ffi-tools.spec.ts b/wrappers/nodejs/test/unit/ffi-tools.spec.ts deleted file mode 100644 index c19eb61b..00000000 --- a/wrappers/nodejs/test/unit/ffi-tools.spec.ts +++ /dev/null @@ -1,61 +0,0 @@ -import '../module-resolver-helper'; -import { bufferTo64BitAddressString, handleBufferToNumber, handleNumberToBuffer } from '../../src/api/ffi-tools'; -import { assert } from 'chai'; - -describe('Common tools suite', () => { - describe('buffer conversions', () => { - it('should convert buffer to number', async () => { - { - const data1 = [0x01, 0x00, 0x00, 0x00, 0x00, 0x00]; - const buf1 = Buffer.from(data1); - const num1 = handleBufferToNumber(buf1); - assert.equal(num1, 1); - } - { - const data2 = [0x00, 0x01, 0x00, 0x00, 0x00, 0x00]; - const buf2 = Buffer.from(data2); - const num2 = handleBufferToNumber(buf2); - assert.equal(num2, 256); - } - { - const data1 = [0xff, 0xff, 0xff, 0xff, 0xff, 0x0f]; - const buf1 = Buffer.from(data1); - const num1 = handleBufferToNumber(buf1); - assert.equal(num1, 17592186044415); - } - { - const data1 = [0xff, 0xff, 0xff, 0xff, 0xff, 0xff]; - const buf1 = Buffer.from(data1); - const num1 = handleBufferToNumber(buf1); - assert.equal(num1, -1); - } - }); - - it('should convert number to buffer', async () => { - const buf1 = handleNumberToBuffer(0); - assert.equal(buf1.length, 6); - assert.equal(buf1[0], 0); - assert.equal(buf1[1], 0); - assert.equal(buf1[2], 0); - assert.equal(buf1[3], 0); - assert.equal(buf1[4], 0); - assert.equal(buf1[5], 0); - - const buf2 = handleNumberToBuffer(256); - assert.equal(buf2.length, 6); - assert.equal(buf2[0], 0); - assert.equal(buf2[1], 1); - assert.equal(buf2[2], 0); - assert.equal(buf2[3], 0); - assert.equal(buf2[4], 0); - assert.equal(buf2[5], 0); - }); - - it('should read buffer as little endian', async () => { - const address = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]; - const aaddresInBuffer = Buffer.from(address); - const hexAddressString = bufferTo64BitAddressString(aaddresInBuffer); - assert.equal(hexAddressString, '0x807060504030201'); - }); - }); -}); diff --git a/wrappers/nodejs/test/unit/indy-vdr-pool.spec.ts b/wrappers/nodejs/test/unit/indy-vdr-pool.spec.ts deleted file mode 100644 index dcfebef4..00000000 --- a/wrappers/nodejs/test/unit/indy-vdr-pool.spec.ts +++ /dev/null @@ -1,63 +0,0 @@ -import '../module-resolver-helper'; - -import { assert } from 'chai'; -import { IndyVdrPool } from 'src'; -import { initVdrTest, NetworkInfo } from '../common/init'; - -describe('Pool suite', () => { - let genesisPath: NetworkInfo; - - before(async () => { - genesisPath = await initVdrTest(); - }); - - describe('create:', () => { - it('many pool instances with unique handles', async () => { - const createPoolParams = JSON.stringify({ transactions_path: genesisPath.genesisFilePath }); - const poolHandles = []; - for (let i = 1; i < 20; i++) { - const pool: IndyVdrPool = IndyVdrPool.create('pool_foo', createPoolParams); - const poolHandle: number = pool.getHandle(); - assert.equal(poolHandle, i); - poolHandles.push(poolHandle); - } - }); - - it('success', async () => { - const createPoolParams = JSON.stringify({ transactions_path: genesisPath.genesisFilePath }); - - const pool: IndyVdrPool = IndyVdrPool.create('pool_foo', createPoolParams); - const poolHandle: number = pool.getHandle(); - assert.isNumber(poolHandle); - assert.equal(pool.getName(), 'pool_foo'); - assert.equal(pool.getParams(), createPoolParams); - - const pool2: IndyVdrPool = IndyVdrPool.create('pool_bar', createPoolParams); - const poolHandle2: number = pool2.getHandle(); - assert.isNumber(poolHandle2); - assert.equal(pool2.getName(), 'pool_bar'); - assert.equal(pool2.getParams(), createPoolParams); - - assert.notEqual(poolHandle, poolHandle2); - }); - - it('should get pool transactions', async () => { - const createPoolParams = JSON.stringify({ transactions_path: genesisPath.genesisFilePath }); - const pool: IndyVdrPool = IndyVdrPool.create('foo', createPoolParams); - const response = await pool.getPoolTransactions(); - const lines = response.split('\n'); - for (let i = 0; i < lines.length; i++) { - const poolTx = JSON.parse(lines[i]); - assert.isObject(poolTx.txn); - assert.isObject(poolTx.txnMetadata); - assert.isString(poolTx.ver); - } - }); - - // Todo: I suppose rust should check the path is valid and throw error if not - // it('bad path', async () => { - // const createPoolParams = JSON.stringify({ transactions_path: '/tmp/foo/bar/42' }); - // const pool: IndyVdrPool = IndyVdrPool.create(createPoolParams); - // }); - }); -}); diff --git a/wrappers/nodejs/test/unit/indy-vdr-utils.spec.ts b/wrappers/nodejs/test/unit/indy-vdr-utils.spec.ts deleted file mode 100644 index a510a142..00000000 --- a/wrappers/nodejs/test/unit/indy-vdr-utils.spec.ts +++ /dev/null @@ -1,19 +0,0 @@ -import '../module-resolver-helper'; - -import { assert } from 'chai'; -import { indyVdrSetDefaultLogger, indyVdrVersion, initVdr } from 'src'; - -describe('Pool:', () => { - before(() => { - const initSuccess = initVdr(); - assert.isTrue(initSuccess); - indyVdrSetDefaultLogger(); - }); - - describe('version', () => { - it('should be version 0.2.1', async () => { - const vdrVersion = indyVdrVersion(); - assert.equal(vdrVersion, '0.2.1'); - }); - }); -}); diff --git a/wrappers/nodejs/test/unit/ledger-requests/ledger-request-custom.spec.ts b/wrappers/nodejs/test/unit/ledger-requests/ledger-request-custom.spec.ts deleted file mode 100644 index 3d083ebc..00000000 --- a/wrappers/nodejs/test/unit/ledger-requests/ledger-request-custom.spec.ts +++ /dev/null @@ -1,51 +0,0 @@ -import '../../module-resolver-helper'; - -import { assert } from 'chai'; -import { LedgerRequestCustom, indyVdrSetDefaultLogger, initVdr } from 'src'; - -describe('Pool suite', () => { - before(async () => { - const initSuccess = initVdr(); - assert.isTrue(initSuccess); - indyVdrSetDefaultLogger(); - }); - - const testRequestData = JSON.stringify({ - operation: { data: 1, ledgerId: 1, type: '3' }, - protocolVersion: 2, - reqId: 123, - identifier: 'LibindyDid111111111111', - }); - - describe('create:', () => { - it('should create single request instance', async () => { - const request: LedgerRequestCustom = LedgerRequestCustom.create(testRequestData); - const handle: number = request.getHandle(); - assert.isNumber(handle); - }); - - it('request handles should be increment pre each new request created', async () => { - const handles = []; - for (let i = 1; i < 19; i++) { - const request: LedgerRequestCustom = LedgerRequestCustom.create(testRequestData); - const handle: number = request.getHandle(); - if (handles.length > 0) { - assert.equal(handle, handles[handles.length - 1] + 1); - } - handles.push(handle); - } - }); - - it('should get request body', async () => { - const request: LedgerRequestCustom = LedgerRequestCustom.create(testRequestData); - const body = request.getRequestBody(); - assert.deepEqual(JSON.parse(body), JSON.parse(testRequestData)); - }); - - // Todo: I suppose rust should check the path is valid and throw error if not - // it('bad path', async () => { - // const createPoolParams = JSON.stringify({ transactions_path: '/tmp/foo/bar/42' }); - // const pool: IndyVdrPool = IndyVdrPool.create(createPoolParams); - // }); - }); -}); diff --git a/wrappers/nodejs/test/unit/ledger-requests/ledger-request-get-txn.spec.ts b/wrappers/nodejs/test/unit/ledger-requests/ledger-request-get-txn.spec.ts deleted file mode 100644 index 10527d3b..00000000 --- a/wrappers/nodejs/test/unit/ledger-requests/ledger-request-get-txn.spec.ts +++ /dev/null @@ -1,39 +0,0 @@ -import '../../module-resolver-helper'; - -import { assert } from 'chai'; -import { LedgerRequestGetTxn, indyVdrSetDefaultLogger, initVdr } from 'src'; - -describe('Pool suite', () => { - before(async () => { - const initSuccess = initVdr(); - assert.isTrue(initSuccess); - indyVdrSetDefaultLogger(); - }); - - describe('create:', () => { - it.skip('should create single request instance', async () => { - const request: LedgerRequestGetTxn = LedgerRequestGetTxn.create(0, 1, '5eDbxuffvuopHgAAAAAAAA'); - const handle: number = request.getHandle(); - assert.isNumber(handle); - }); - - it('should get request body', async () => { - const request: LedgerRequestGetTxn = LedgerRequestGetTxn.create(0, 1, '5eDbxuffvuopHgAAAAAAAA'); - const body = request.getRequestBody(); - const bodyParsed = JSON.parse(body); - assert.equal(bodyParsed.identifier, '5eDbxuffvuopHgAAAAAAAA'); - assert.equal(bodyParsed.operation.data, 1); - assert.equal(bodyParsed.operation.ledgerId, 0); - assert.equal(bodyParsed.operation.type, '3'); - assert.isNumber(bodyParsed.protocolVersion); - assert.isNumber(bodyParsed.reqId); - }); - - // todo: enable this use case - // it('should be possible to not specify submitter did', async () => { - // const request: LedgerRequestGetTxn = LedgerRequestGetTxn.create(0, 1); - // const body = request.getRequestBody(); - // assert.isString(body); - // }); - }); -}); diff --git a/wrappers/nodejs/tsconfig.json b/wrappers/nodejs/tsconfig.json deleted file mode 100644 index bdfac65e..00000000 --- a/wrappers/nodejs/tsconfig.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "compilerOptions": { - "target": "es2016", - "module": "commonjs", - "sourceMap": true, - "outDir": "./dist", - "declaration": true, - "baseUrl": "./", - "strict": true, - "strictFunctionTypes": false, - "noUnusedLocals": true, - "preserveConstEnums": true, - "lib": [ - "esnext.bigint" - ] - }, - "include": [ - "./src/**/*", "test/suite3/logging.2.test.ts", "test/suite3/logging.1.test.ts" - ] -} From 8730c1ee568d815e6f914e5759232a9335939b04 Mon Sep 17 00:00:00 2001 From: Berend Sliedrecht <61358536+blu3beri@users.noreply.github.com> Date: Thu, 25 May 2023 15:11:07 +0200 Subject: [PATCH 006/117] feat: react native 0.71.x and Expo support (#186) Signed-off-by: blu3beri --- .github/workflows/build.yml | 20 +- build-xcframework.sh | 23 +- .../android/CMakeLists.txt | 196 ++++++++++++++---- .../android/build.gradle | 177 ++++++++++------ .../src/{library => }/NativeBindings.ts | 2 +- .../src/ReactNativeIndyVdr.ts | 114 +++++----- .../indy-vdr-react-native/src/index.ts | 18 +- .../src/library/index.ts | 2 - .../src/library/register.ts | 11 - .../src/{utils => }/serialize.ts | 0 .../src/utils/handleError.ts | 12 -- .../indy-vdr-react-native/src/utils/index.ts | 2 - 12 files changed, 357 insertions(+), 220 deletions(-) rename wrappers/javascript/indy-vdr-react-native/src/{library => }/NativeBindings.ts (99%) delete mode 100644 wrappers/javascript/indy-vdr-react-native/src/library/index.ts delete mode 100644 wrappers/javascript/indy-vdr-react-native/src/library/register.ts rename wrappers/javascript/indy-vdr-react-native/src/{utils => }/serialize.ts (100%) delete mode 100644 wrappers/javascript/indy-vdr-react-native/src/utils/handleError.ts delete mode 100644 wrappers/javascript/indy-vdr-react-native/src/utils/index.ts diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e9e4c96a..a83d6a03 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,7 +1,7 @@ name: "Indy-VDR" env: - RUST_VERSION: "1.63.0" + RUST_VERSION: "1.65.0" CROSS_VERSION: "0.2.4" on: @@ -283,16 +283,14 @@ jobs: - name: Install Rust toolchain uses: dtolnay/rust-toolchain@master with: - # First version with support for cdylib: https://github.com/rust-lang/rust/pull/100636 - toolchain: "1.65.0" + toolchain: ${{ env.RUST_VERSION }} targets: ${{ matrix.target }} - # Not useful unless the toolchain version matches the default - # - name: Cache cargo resources - # uses: Swatinem/rust-cache@v2 - # with: - # shared-key: deps - # save-if: false + - name: Cache cargo resources + uses: Swatinem/rust-cache@v2 + with: + shared-key: deps + save-if: false - name: Build run: | @@ -302,7 +300,7 @@ jobs: uses: actions/upload-artifact@v3 with: name: library-${{ matrix.target}} - path: target/${{ matrix.target }}/release/libindy_vdr.dylib + path: target/${{ matrix.target }}/release/libindy_vdr.a create-ios-xcframework: name: Create iOS xcframework @@ -313,7 +311,7 @@ jobs: - name: Checkout uses: actions/checkout@v3 - - name: Fetch dynamic libraries + - name: Fetch static libraries uses: actions/download-artifact@v3 - run: > diff --git a/build-xcframework.sh b/build-xcframework.sh index 9e74753b..8e74abec 100755 --- a/build-xcframework.sh +++ b/build-xcframework.sh @@ -3,22 +3,25 @@ set -eo pipefail # Check if lipo and xcodebuild exist -if [ -z `command -v lipo` ] || [ -z `command -v xcodebuild` ] +if [ -z `command -v lipo` ] || [ -z `command -v xcodebuild` ] || [ -z `command -v sed` ] + then - echo "!!! lipo or xcodebuild could not be found !!!" + echo "!!! lipo, xcodebuild or sed could not be found !!!" help fi NAME="indy_vdr" +BUNDLE_NAME="indy-vdr" VERSION=$(cargo generate-lockfile && cargo pkgid indy-vdr | sed -e "s/^.*[#@]//") echo $VERSION -BUNDLE_IDENTIFIER="org.hyperledger.$NAME" -LIBRARY_NAME="lib$NAME.dylib" +BUNDLE_IDENTIFIER="org.hyperledger.$BUNDLE_NAME" +LIBRARY_NAME="lib$NAME.a" XC_FRAMEWORK_NAME="$NAME.xcframework" FRAMEWORK_LIBRARY_NAME=$NAME FRAMEWORK_NAME="$FRAMEWORK_LIBRARY_NAME.framework" HEADER_NAME="lib$NAME.h" OUT_PATH="out" +MIN_IOS_VERSION="12.0" # Setting some default paths AARCH64_APPLE_IOS_PATH="./target/aarch64-apple-ios/release" @@ -33,9 +36,9 @@ Help() { echo " - xcodebuild" echo "To build an xcframework with underlying Frameworks" echo "the following can be passed in as positional arguments" - echo " 1. Path to the aarch64-apple-ios directory where the $LIBRARY is stored" - echo " 2. Path to the aarch64-apple-ios-sim directory where the $LIBRARY is stored" - echo " 3. Path to the x86_64-apple-ios directory where the $LIBRARY is stored" + echo " 1. Path to the aarch64-apple-ios directory where the $LIBRARY_NAME is stored" + echo " 2. Path to the aarch64-apple-ios-sim directory where the $LIBRARY_NAME is stored" + echo " 3. Path to the x86_64-apple-ios directory where the $LIBRARY_NAME is stored" echo " 4. Path to the header file, excluding the header" echo "Make sure to add the 'release' section of the path for a" echo "release build." @@ -156,6 +159,8 @@ cat <> Info.plist $VERSION NSPrincipalClass + MinimumOSVersion + $MIN_IOS_VERSION EOT @@ -179,8 +184,4 @@ xcodebuild -create-xcframework \ echo "cleaning up..." rm -rf $FRAMEWORK_NAME real sim -echo "Fixing the identifiers of the dylib..." -install_name_tool -id @rpath/$NAME.framework/$FRAMEWORK_LIBRARY_NAME $XC_FRAMEWORK_NAME/ios-arm64/$FRAMEWORK_NAME/$FRAMEWORK_LIBRARY_NAME -install_name_tool -id @rpath/$NAME.framework/$FRAMEWORK_LIBRARY_NAME $XC_FRAMEWORK_NAME/ios-arm64_x86_64-simulator/$FRAMEWORK_NAME/$FRAMEWORK_LIBRARY_NAME - echo "Framework written to $OUT_PATH/$XC_FRAMEWORK_NAME" diff --git a/wrappers/javascript/indy-vdr-react-native/android/CMakeLists.txt b/wrappers/javascript/indy-vdr-react-native/android/CMakeLists.txt index 604a32fd..91bc5376 100644 --- a/wrappers/javascript/indy-vdr-react-native/android/CMakeLists.txt +++ b/wrappers/javascript/indy-vdr-react-native/android/CMakeLists.txt @@ -1,26 +1,37 @@ -cmake_minimum_required(VERSION 3.9.0) project(indyvdrreactnative) +cmake_minimum_required(VERSION 3.4.1) set (PACKAGE_NAME "indyvdrreactnative") set (LIB_NAME "indyvdr") +file (GLOB LIBINDY_VDR_DIR "${CMAKE_SOURCE_DIR}/../native/mobile/android/${ANDROID_ABI}") + +set(CMAKE_VERBOSE_MAKEFILE ON) +set(CMAKE_CXX_STANDARD 14) + +if(${REACT_NATIVE_VERSION} GREATER_EQUAL 71) + include("${NODE_MODULES_DIR}/react-native/ReactAndroid/cmake-utils/folly-flags.cmake") + add_compile_options(${folly_FLAGS}) +else() + set (CMAKE_CXX_FLAGS "-DFOLLY_NO_CONFIG=1 -DFOLLY_HAVE_CLOCK_GETTIME=1 -DFOLLY_HAVE_MEMRCHR=1 -DFOLLY_USE_LIBCPP=1 -DFOLLY_MOBILE=1 -DON_ANDROID -DONANDROID -DFOR_HERMES=${FOR_HERMES}") +endif() + set (BUILD_DIR ${CMAKE_SOURCE_DIR}/build) +if(${REACT_NATIVE_VERSION} GREATER_EQUAL 71) + find_package(fbjni REQUIRED CONFIG) + find_package(ReactAndroid REQUIRED CONFIG) +else() + set (RN_SO_DIR ${NODE_MODULES_DIR}/react-native/ReactAndroid/src/main/jni/first-party/react/jni) +endif() -file (GLOB LIBFBJNI_INCLUDE_DIR "${BUILD_DIR}/fbjni-*-headers.jar/") -file (GLOB LIBRN_DIR "${BUILD_DIR}/react-native-0*/jni/${ANDROID_ABI}") -file (GLOB LIBVDR_DIR "${CMAKE_SOURCE_DIR}/../native/mobile/android/${ANDROID_ABI}") +if(${REACT_NATIVE_VERSION} LESS 66) + set (INCLUDE_JSI_CPP "${NODE_MODULES_DIR}/react-native/ReactCommon/jsi/jsi/jsi.cpp") + set (INCLUDE_JSIDYNAMIC_CPP "${NODE_MODULES_DIR}/react-native/ReactCommon/jsi/jsi/JSIDynamic.cpp") +endif() include_directories( ../cpp ../cpp/include - "${LIBVDR_DIR}" - "${LIBFBJNI_INCLUDE_DIR}" - "${NODE_MODULES_DIR}/react-native/React" - "${NODE_MODULES_DIR}/react-native/React/Base" - "${NODE_MODULES_DIR}/react-native/ReactCommon" - "${NODE_MODULES_DIR}/react-native/ReactCommon/jsi" - "${NODE_MODULES_DIR}/react-native/ReactCommon/callinvoker" - "${NODE_MODULES_DIR}/react-native/ReactAndroid/src/main/jni" - "${NODE_MODULES_DIR}/react-native/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni" + "${LIBINDY_VDR_DIR}" ) add_library( @@ -32,56 +43,157 @@ add_library( ../cpp/indyVdr.cpp ) -set_target_properties( - ${PACKAGE_NAME} - PROPERTIES - CXX_STANDARD 17 - CXX_EXTENSION OFF - POSITION_INDEPENDENT_CODE ON -) +if(${REACT_NATIVE_VERSION} GREATER_EQUAL 71) + target_include_directories( + ${PACKAGE_NAME} + PRIVATE + "${NODE_MODULES_DIR}/react-native/ReactAndroid/src/main/jni/react/turbomodule" + "${NODE_MODULES_DIR}/react-native/ReactCommon" + "${NODE_MODULES_DIR}/react-native/ReactCommon/callinvoker" + "${NODE_MODULES_DIR}/react-native/ReactCommon/jsi" + "${NODE_MODULES_DIR}/react-native/ReactCommon/react/renderer/graphics/platform/cxx" + "${NODE_MODULES_DIR}/react-native/ReactCommon/runtimeexecutor" + "${NODE_MODULES_DIR}/react-native/ReactCommon/yoga" + ) +else() + file (GLOB LIBFBJNI_INCLUDE_DIR "${BUILD_DIR}/fbjni-*-headers.jar/") + target_include_directories( + ${PACKAGE_NAME} + PRIVATE + "${LIBFBJNI_INCLUDE_DIR}" + "${NODE_MODULES_DIR}/react-native/React" + "${NODE_MODULES_DIR}/react-native/React/Base" + "${NODE_MODULES_DIR}/react-native/ReactAndroid/src/main/jni" + "${NODE_MODULES_DIR}/react-native/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni" + "${NODE_MODULES_DIR}/react-native/ReactCommon" + "${NODE_MODULES_DIR}/react-native/ReactCommon/callinvoker" + "${NODE_MODULES_DIR}/react-native/ReactCommon/jsi" + "${NODE_MODULES_DIR}/hermes-engine/android/include/" + ${INCLUDE_JSI_CPP} # only on older RN versions + ${INCLUDE_JSIDYNAMIC_CPP} # only on older RN versions + ) +endif() +file (GLOB LIBRN_DIR "${BUILD_DIR}/react-native-0*/jni/${ANDROID_ABI}") -find_library( - LOG_LIB - log -) +if(${FOR_HERMES}) + string(APPEND CMAKE_CXX_FLAGS " -DFOR_HERMES=1") -find_library( - FBJNI_LIB - fbjni - PATHS ${LIBRN_DIR} - NO_CMAKE_FIND_ROOT_PATH -) + if(${REACT_NATIVE_VERSION} GREATER_EQUAL 71) + find_package(hermes-engine REQUIRED CONFIG) + elseif(${REACT_NATIVE_VERSION} GREATER_EQUAL 69) + # Bundled Hermes from module `com.facebook.react:hermes-engine` or project `:ReactAndroid:hermes-engine` + target_include_directories( + ${PACKAGE_NAME} + PRIVATE + "${JS_RUNTIME_DIR}/API" + "${JS_RUNTIME_DIR}/public" + ) + else() + # From `hermes-engine` npm package + target_include_directories( + ${PACKAGE_NAME} + PRIVATE + "${JS_RUNTIME_DIR}/android/include" + ) + endif() + + if(${REACT_NATIVE_VERSION} GREATER_EQUAL 71) + target_link_libraries( + ${PACKAGE_NAME} + "hermes-engine::libhermes" + ) + else() + target_link_libraries( + ${PACKAGE_NAME} + "${BUILD_DIR}/third-party-ndk/hermes/jni/${ANDROID_ABI}/libhermes.so" + ) + endif() +else() + file (GLOB LIBJSC_DIR "${BUILD_DIR}/android-jsc*.aar/jni/${ANDROID_ABI}") + + if(${REACT_NATIVE_VERSION} GREATER_EQUAL 71) + set(JS_ENGINE_LIB ReactAndroid::jscexecutor) + else() + # Use JSC + find_library( + JS_ENGINE_LIB + jscexecutor + PATHS ${LIBRN_DIR} + NO_CMAKE_FIND_ROOT_PATH + ) + endif() + target_link_libraries( + ${PACKAGE_NAME} + ${JS_ENGINE_LIB} + ) +endif() + +if(${REACT_NATIVE_VERSION} LESS 71) + find_library( + FBJNI_LIB + fbjni + PATHS ${LIBRN_DIR} + NO_CMAKE_FIND_ROOT_PATH + ) +endif() + +if(${REACT_NATIVE_VERSION} LESS 71) + find_library( + REACT_NATIVE_JNI_LIB + reactnativejni + PATHS ${LIBRN_DIR} + NO_CMAKE_FIND_ROOT_PATH + ) +endif() + +if(${REACT_NATIVE_VERSION} GREATER_EQUAL 71) + target_link_libraries( + ${PACKAGE_NAME} + ReactAndroid::jsi + ReactAndroid::reactnativejni + fbjni::fbjni + ) +elseif(${REACT_NATIVE_VERSION} LESS 66) + # JSI lib didn't exist on RN 0.65 and before. Simply omit it. + set (JSI_LIB "") +else() + # RN 0.66 distributes libjsi.so, can be used instead of compiling jsi.cpp manually. + find_library( + JSI_LIB + jsi + PATHS ${LIBRN_DIR} + NO_CMAKE_FIND_ROOT_PATH + ) +endif() find_library( - REACT_NATIVE_JNI_LIB - reactnativejni - PATHS ${LIBRN_DIR} + REANIMATED_LIB + reanimated + PATHS ${LIBREANIMATED_DIR} NO_CMAKE_FIND_ROOT_PATH ) find_library( - JSI_LIB - jsi - PATHS ${LIBRN_DIR} - NO_CMAKE_FIND_ROOT_PATH + LOG_LIB + log ) find_library( - VDR_LIB + INDY_VDR_LIB indy_vdr - paths ${LIBVDR_DIR} + paths ${LIBINDY_VDR_DIR} NO_CMAKE_FIND_ROOT_PATH ) -if (NOT VDR_LIB) - message(FATAL_ERROR "Could not find VDR_LIB at: ${LIBVDR_DIR}") +if (NOT INDY_VDR_LIB) + message(FATAL_ERROR "Could not find INDY_VDR_LIB at: ${LIBINDY_VDR_DIR}") endif() target_link_libraries( ${PACKAGE_NAME} - ${VDR_LIB} + ${INDY_VDR_LIB} ${LOG_LIB} ${JSI_LIB} ${REACT_NATIVE_JNI_LIB} diff --git a/wrappers/javascript/indy-vdr-react-native/android/build.gradle b/wrappers/javascript/indy-vdr-react-native/android/build.gradle index 66c1e97a..e4c8cbf4 100644 --- a/wrappers/javascript/indy-vdr-react-native/android/build.gradle +++ b/wrappers/javascript/indy-vdr-react-native/android/build.gradle @@ -1,8 +1,14 @@ import org.apache.tools.ant.filters.ReplaceTokens import java.nio.file.Paths +apply plugin: 'com.android.library' +apply plugin: 'de.undercouch.download' + buildscript { repositories { + maven { + url "https://plugins.gradle.org/m2/" + } google() jcenter() mavenCentral() @@ -14,63 +20,101 @@ buildscript { } } -apply plugin: 'com.android.library' -apply plugin: 'de.undercouch.download' - -def getExtOrDefault(name) { - return rootProject.ext.get(name) -} - -def getExtOrIntegerDefault(name) { - return rootProject.ext.get(name) -} - -static def findNodeModules(baseDir, isHermesEnabled) { +static def findNodeModules(baseDir) { def basePath = baseDir.toPath().normalize() while (basePath) { def nodeModulesPath = Paths.get(basePath.toString(), "node_modules") def reactNativePath = Paths.get(nodeModulesPath.toString(), "react-native") - def jscAndroidPath = Paths.get(nodeModulesPath.toString(), "jsc-android/dist/org/webkit/android-jsc") if (nodeModulesPath.toFile().exists() && reactNativePath.toFile().exists()) { - if(isHermesEnabled || (!isHermesEnabled && jscAndroidPath.toFile().exists())) return nodeModulesPath.toString() } basePath = basePath.getParent() } - throw new GradleException("aries askar: Failed to find node_modules path!") + throw new GradleException("indy-vdr: Failed to find node_modules/ path!") } -def isHermesEnabled = "False" +static def findNodeModulePath(baseDir, packageName) { + def basePath = baseDir.toPath().normalize() + while (basePath) { + def candidatePath = Paths.get(basePath.toString(), "node_modules", packageName) + if (candidatePath.toFile().exists()) { + return candidatePath.toString() + } + basePath = basePath.getParent() + } + return null +} + +def isNewArchitectureEnabled() { + return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true" +} + +def nodeModules = findNodeModules(projectDir) + +def reactNative = new File("$nodeModules/react-native") +def CMAKE_NODE_MODULES_DIR = project.getProjectDir().getParentFile().getParent() +def reactProperties = new Properties() +file("$nodeModules/react-native/ReactAndroid/gradle.properties").withInputStream { reactProperties.load(it) } +def REACT_NATIVE_FULL_VERSION = reactProperties.getProperty("VERSION_NAME") +def REACT_NATIVE_VERSION = reactProperties.getProperty("VERSION_NAME").split("\\.")[1].toInteger() + +def FOR_HERMES = System.getenv("FOR_HERMES") == "True" rootProject.getSubprojects().forEach({project -> if (project.plugins.hasPlugin("com.android.application")) { - isHermesEnabled = project.ext.react.enableHermes + FOR_HERMES = REACT_NATIVE_VERSION >= 71 && project.hermesEnabled || project.ext.react.enableHermes } }) -def nodeModules = findNodeModules(projectDir, isHermesEnabled); -def reactNative = new File("$nodeModules/react-native") +def jsRuntimeDir = { + if (FOR_HERMES) { + if (REACT_NATIVE_VERSION >= 69) { + return Paths.get(CMAKE_NODE_MODULES_DIR, "react-native", "sdks", "hermes") + } else { + return Paths.get(CMAKE_NODE_MODULES_DIR, "hermes-engine") + } + } else { + return Paths.get(CMAKE_NODE_MODULES_DIR, "react-native", "ReactCommon", "jsi") + } +}.call() -def reactProperties = new Properties() -file("$nodeModules/react-native/ReactAndroid/gradle.properties").withInputStream { reactProperties.load(it) } -def REACT_NATIVE_VERSION = reactProperties.getProperty("VERSION_NAME").split("\\.")[1].toInteger() +def getExt(name) { + return rootProject.ext.get(name) +} + +def resolveBuildType() { + def buildType = "debug" + tasks.all({ task -> + if (task.name == "buildCMakeRelease") { + buildType = "release" + } + }) + return buildType +} android { - - compileSdkVersion getExtOrIntegerDefault('compileSdkVersion') - buildToolsVersion getExtOrDefault('buildToolsVersion') + compileSdkVersion getExt('compileSdkVersion') + buildToolsVersion getExt('buildToolsVersion') + ndkVersion getExt('ndkVersion') + + if (REACT_NATIVE_VERSION >= 71) { + buildFeatures { + prefab true + } + } defaultConfig { minSdkVersion 21 - targetSdkVersion getExtOrIntegerDefault('targetSdkVersion') - versionCode 1 - versionName "1.0" + targetSdkVersion getExt('targetSdkVersion') externalNativeBuild { cmake { - cppFlags "-O2", "-fexceptions", "-frtti", "-std=c++1y", "-DONANDROID" + cppFlags "-fexceptions", "-frtti", "-std=c++1y", "-DONANDROID" abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a' - arguments '-DANDROID_STL=c++_shared', - "-DNODE_MODULES_DIR=${nodeModules}" + arguments "-DANDROID_STL=c++_shared", + "-DREACT_NATIVE_VERSION=${REACT_NATIVE_VERSION}", + "-DNODE_MODULES_DIR=${nodeModules}", + "-DFOR_HERMES=${FOR_HERMES}", + "-DJS_RUNTIME_DIR=${jsRuntimeDir}" } } @@ -83,7 +127,13 @@ android { } packagingOptions { - excludes = ["**/libc++_shared.so", "**/libfbjni.so", "**/libjsi.so", "**/libreactnativejni.so", "**/libjscexecutor.so", "**/libhermes.so"] + excludes = ["**/libc++_shared.so", + "**/libfbjni.so", + "**/libjsi.so", + "**/libreactnativejni.so", + "**/libjscexecutor.so", + "**/libhermes.so" + ] } buildTypes { @@ -91,9 +141,11 @@ android { minifyEnabled false } } + lintOptions { disable 'GradleCompatible' } + compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 @@ -122,7 +174,10 @@ repositories { if (rootProject.ext.has('reactNativeAndroidRoot')) { defaultDir = rootProject.ext.get('reactNativeAndroidRoot') } else { - defaultDir = file("$nodeModules/react-native/android") + defaultDir = new File( + projectDir, + '/../../../node_modules/react-native/android' + ) } if (defaultDir.exists()) { @@ -180,42 +235,30 @@ repositories { dependencies { - // noinspection GradleDynamicVersion - api 'com.facebook.react:react-native:+' - //noinspection GradleDynamicVersion - extractHeaders("com.facebook.fbjni:fbjni:+:headers") - //noinspection GradleDynamicVersion - extractJNI("com.facebook.fbjni:fbjni:+") - - def buildType = "debug" - tasks.all({ task -> - if (task.name == "buildCMakeRelease") { - buildType = "release" + if (REACT_NATIVE_VERSION >= 71) { + implementation "com.facebook.react:react-android:" + implementation "com.facebook.react:hermes-android:" + } else { + implementation 'com.facebook.react:react-native:' + REACT_NATIVE_FULL_VERSION + } + + if (REACT_NATIVE_VERSION < 71) { + //noinspection GradleDynamicVersion + extractHeaders("com.facebook.fbjni:fbjni:+:headers") + //noinspection GradleDynamicVersion + extractJNI("com.facebook.fbjni:fbjni:+") + + def rnAarMatcher = "**/react-native/**/*${resolveBuildType()}.aar" + if (REACT_NATIVE_VERSION < 69) { + rnAarMatcher = "**/**/*.aar" } - }) - def rnAarMatcher = "**/react-native/**/*${buildType}.aar" - if (REACT_NATIVE_VERSION < 69) { - rnAarMatcher = "**/react-native/**/*.aar" - } - def rnAAR = fileTree("$reactNative/android").matching({ it.include rnAarMatcher }).singleFile - if(!isHermesEnabled) { + def rnAAR = fileTree("$reactNative/android").matching({ it.include rnAarMatcher }).singleFile def jscAAR = fileTree("${nodeModules}/jsc-android/dist/org/webkit/android-jsc").matching({ it.include "**/**/*.aar" }).singleFile - extractJNI(files(jscAAR)) - } - - extractJNI(files(rnAAR)) -} - -def downloadsDir = new File("$buildDir/downloads") - -task createNativeDepsDirectories { - doLast { - downloadsDir.mkdirs() + extractJNI(files(rnAAR, jscAAR)) } } - task extractAARHeaders { doLast { configurations.extractHeaders.files.each { @@ -229,8 +272,6 @@ task extractAARHeaders { } } -extractAARHeaders.mustRunAfter createNativeDepsDirectories - task extractJNIFiles { doLast { configurations.extractJNI.files.each { @@ -249,7 +290,9 @@ extractJNIFiles.mustRunAfter extractAARHeaders tasks.whenTaskAdded { task -> if (!task.name.contains('Clean') && (task.name.contains('externalNative') || task.name.contains('CMake'))) { - task.dependsOn(extractAARHeaders) - task.dependsOn(extractJNIFiles) + if (REACT_NATIVE_VERSION < 71) { + task.dependsOn(extractAARHeaders) + task.dependsOn(extractJNIFiles) + } } } diff --git a/wrappers/javascript/indy-vdr-react-native/src/library/NativeBindings.ts b/wrappers/javascript/indy-vdr-react-native/src/NativeBindings.ts similarity index 99% rename from wrappers/javascript/indy-vdr-react-native/src/library/NativeBindings.ts rename to wrappers/javascript/indy-vdr-react-native/src/NativeBindings.ts index 518d2576..e7b05923 100644 --- a/wrappers/javascript/indy-vdr-react-native/src/library/NativeBindings.ts +++ b/wrappers/javascript/indy-vdr-react-native/src/NativeBindings.ts @@ -1,4 +1,4 @@ -import type { Callback, CallbackWithResponse, ReturnObject } from '../utils' +import type { Callback, CallbackWithResponse, ReturnObject } from './serialize' export type PoolHandle = number export type RequestHandle = number diff --git a/wrappers/javascript/indy-vdr-react-native/src/ReactNativeIndyVdr.ts b/wrappers/javascript/indy-vdr-react-native/src/ReactNativeIndyVdr.ts index 307f3824..a3a88c67 100644 --- a/wrappers/javascript/indy-vdr-react-native/src/ReactNativeIndyVdr.ts +++ b/wrappers/javascript/indy-vdr-react-native/src/ReactNativeIndyVdr.ts @@ -1,4 +1,5 @@ -import type { Callback, CallbackWithResponse } from './utils' +import type { NativeBindings } from './NativeBindings' +import type { Callback, CallbackWithResponse, ReturnObject } from './serialize' import type { AcceptanceMechanismsRequestOptions, AttribRequestOptions, @@ -40,10 +41,23 @@ import type { import { handleInvalidNullResponse, IndyVdrError } from '@hyperledger/indy-vdr-shared' -import { indyVdrReactNative } from './library' -import { handleError, serializeArguments } from './utils' +import { serializeArguments } from './serialize' export class ReactNativeIndyVdr implements IndyVdr { + private indyVdr: NativeBindings + + public constructor(bindings: NativeBindings) { + this.indyVdr = bindings + } + + private handleError({ errorCode, value }: ReturnObject): T { + if (errorCode !== 0) { + throw new IndyVdrError(JSON.parse(this.getCurrentError()) as IndyVdrErrorObject) + } + + return value as T + } + private promisify = (method: (cb: Callback) => void): Promise => { return new Promise((resolve, reject) => { const _cb: Callback = ({ errorCode }) => { @@ -80,89 +94,87 @@ export class ReactNativeIndyVdr implements IndyVdr { } public getCurrentError(): string { - return indyVdrReactNative.getCurrentError({}) + return this.indyVdr.getCurrentError({}) } public version(): string { - return indyVdrReactNative.version({}) + return this.indyVdr.version({}) } public setConfig(options: { config: Record }): void { const serializedOptions = serializeArguments(options) - indyVdrReactNative.setConfig(serializedOptions) + this.indyVdr.setConfig(serializedOptions) } public setDefaultLogger(): void { - handleError(indyVdrReactNative.setDefaultLogger({})) + this.handleError(this.indyVdr.setDefaultLogger({})) } public setProtocolVersion(options: { version: number }): void { const serializedOptions = serializeArguments(options) - handleError(indyVdrReactNative.setProtocolVersion(serializedOptions)) + this.handleError(this.indyVdr.setProtocolVersion(serializedOptions)) } public setSocksProxy(options: { socksProxy: string }): void { const serializedOptions = serializeArguments(options) - handleError(indyVdrReactNative.setSocksProxy(serializedOptions)) + this.handleError(this.indyVdr.setSocksProxy(serializedOptions)) } public buildAcceptanceMechanismsRequest(options: AcceptanceMechanismsRequestOptions): number { const serializedOptions = serializeArguments(options) - return handleInvalidNullResponse( - handleError(indyVdrReactNative.buildAcceptanceMechanismsRequest(serializedOptions)) - ) + return handleInvalidNullResponse(this.handleError(this.indyVdr.buildAcceptanceMechanismsRequest(serializedOptions))) } public buildGetAcceptanceMechanismsRequest(options: GetAcceptanceMechanismsRequestOptions): number { const serializedOptions = serializeArguments(options) return handleInvalidNullResponse( - handleError(indyVdrReactNative.buildGetAcceptanceMechanismsRequest(serializedOptions)) + this.handleError(this.indyVdr.buildGetAcceptanceMechanismsRequest(serializedOptions)) ) } public buildAttribRequest(options: AttribRequestOptions): number { const serializedOptions = serializeArguments(options) - return handleInvalidNullResponse(handleError(indyVdrReactNative.buildAttribRequest(serializedOptions))) + return handleInvalidNullResponse(this.handleError(this.indyVdr.buildAttribRequest(serializedOptions))) } public buildGetAttribRequest(options: GetAttribRequestOptions): number { const serializedOptions = serializeArguments(options) - return handleInvalidNullResponse(handleError(indyVdrReactNative.buildGetAttribRequest(serializedOptions))) + return handleInvalidNullResponse(this.handleError(this.indyVdr.buildGetAttribRequest(serializedOptions))) } public buildCredDefRequest(options: CredentialDefinitionRequestOptions): number { const serializedOptions = serializeArguments(options) - return handleInvalidNullResponse(handleError(indyVdrReactNative.buildCredDefRequest(serializedOptions))) + return handleInvalidNullResponse(this.handleError(this.indyVdr.buildCredDefRequest(serializedOptions))) } public buildGetCredDefRequest(options: GetCredentialDefinitionRequestOptions): number { const serializedOptions = serializeArguments(options) - return handleInvalidNullResponse(handleError(indyVdrReactNative.buildGetCredDefRequest(serializedOptions))) + return handleInvalidNullResponse(this.handleError(this.indyVdr.buildGetCredDefRequest(serializedOptions))) } public buildGetRevocRegDefRequest(options: GetRevocationRegistryDefinitionRequestOptions): number { const serializedOptions = serializeArguments(options) - return handleInvalidNullResponse(handleError(indyVdrReactNative.buildGetRevocRegDefRequest(serializedOptions))) + return handleInvalidNullResponse(this.handleError(this.indyVdr.buildGetRevocRegDefRequest(serializedOptions))) } public buildGetRevocRegRequest(options: GetRevocationRegistryRequestOptions): number { const serializedOptions = serializeArguments(options) - return handleInvalidNullResponse(handleError(indyVdrReactNative.buildGetRevocRegRequest(serializedOptions))) + return handleInvalidNullResponse(this.handleError(this.indyVdr.buildGetRevocRegRequest(serializedOptions))) } public buildGetRevocRegDeltaRequest(options: GetRevocationRegistryDeltaRequestOptions): number { const serializedOptions = serializeArguments(options) - return handleInvalidNullResponse(handleError(indyVdrReactNative.buildGetRevocRegDeltaRequest(serializedOptions))) + return handleInvalidNullResponse(this.handleError(this.indyVdr.buildGetRevocRegDeltaRequest(serializedOptions))) } public buildRevocRegDefRequest(options: RevocationRegistryDefinitionRequestOptions): number { const serializedOptions = serializeArguments(options) - return handleInvalidNullResponse(handleError(indyVdrReactNative.buildRevocRegDefRequest(serializedOptions))) + return handleInvalidNullResponse(this.handleError(this.indyVdr.buildRevocRegDefRequest(serializedOptions))) } public buildCustomRequest(options: CustomRequestOptions): number { const serializedOptions = serializeArguments(options) - return handleInvalidNullResponse(handleError(indyVdrReactNative.buildCustomRequest(serializedOptions))) + return handleInvalidNullResponse(this.handleError(this.indyVdr.buildCustomRequest(serializedOptions))) } public buildDisableAllTxnAuthorAgreementsRequest( @@ -170,73 +182,71 @@ export class ReactNativeIndyVdr implements IndyVdr { ): number { const serializedOptions = serializeArguments(options) return handleInvalidNullResponse( - handleError(indyVdrReactNative.buildDisableAllTxnAuthorAgreementsRequest(serializedOptions)) + this.handleError(this.indyVdr.buildDisableAllTxnAuthorAgreementsRequest(serializedOptions)) ) } public buildGetNymRequest(options: GetNymRequestOptions): number { const serializedOptions = serializeArguments(options) - return handleInvalidNullResponse(handleError(indyVdrReactNative.buildGetNymRequest(serializedOptions))) + return handleInvalidNullResponse(this.handleError(this.indyVdr.buildGetNymRequest(serializedOptions))) } public buildGetSchemaRequest(options: GetSchemaRequestOptions): number { const serializedOptions = serializeArguments(options) - return handleInvalidNullResponse(handleError(indyVdrReactNative.buildGetSchemaRequest(serializedOptions))) + return handleInvalidNullResponse(this.handleError(this.indyVdr.buildGetSchemaRequest(serializedOptions))) } public buildGetTxnAuthorAgreementRequest(options: GetTransactionAuthorAgreementRequestOptions): number { const serializedOptions = serializeArguments(options) return handleInvalidNullResponse( - handleError(indyVdrReactNative.buildGetTxnAuthorAgreementRequest(serializedOptions)) + this.handleError(this.indyVdr.buildGetTxnAuthorAgreementRequest(serializedOptions)) ) } public buildGetTxnRequest(options: GetTransactionRequestOptions): number { const serializedOptions = serializeArguments(options) - return handleInvalidNullResponse(handleError(indyVdrReactNative.buildGetTxnRequest(serializedOptions))) + return handleInvalidNullResponse(this.handleError(this.indyVdr.buildGetTxnRequest(serializedOptions))) } public buildGetValidatorInfoRequest(options: GetValidatorInfoActionOptions): number { const serializedOptions = serializeArguments(options) - return handleInvalidNullResponse(handleError(indyVdrReactNative.buildGetValidatorInfoRequest(serializedOptions))) + return handleInvalidNullResponse(this.handleError(this.indyVdr.buildGetValidatorInfoRequest(serializedOptions))) } public buildNymRequest(options: NymRequestOptions): number { const serializedOptions = serializeArguments(options) - return handleInvalidNullResponse(handleError(indyVdrReactNative.buildNymRequest(serializedOptions))) + return handleInvalidNullResponse(this.handleError(this.indyVdr.buildNymRequest(serializedOptions))) } public buildRevocRegEntryRequest(options: RevocationRegistryEntryRequestOptions): number { const serializedOptions = serializeArguments(options) - return handleInvalidNullResponse(handleError(indyVdrReactNative.buildRevocRegEntryRequest(serializedOptions))) + return handleInvalidNullResponse(this.handleError(this.indyVdr.buildRevocRegEntryRequest(serializedOptions))) } public buildSchemaRequest(options: SchemaRequestOptions): number { const serializedOptions = serializeArguments(options) - return handleInvalidNullResponse(handleError(indyVdrReactNative.buildSchemaRequest(serializedOptions))) + return handleInvalidNullResponse(this.handleError(this.indyVdr.buildSchemaRequest(serializedOptions))) } public buildTxnAuthorAgreementRequest(options: TransactionAuthorAgreementRequestOptions): number { const serializedOptions = serializeArguments(options) - return handleInvalidNullResponse(handleError(indyVdrReactNative.buildTxnAuthorAgreementRequest(serializedOptions))) + return handleInvalidNullResponse(this.handleError(this.indyVdr.buildTxnAuthorAgreementRequest(serializedOptions))) } public poolCreate(options: PoolCreateOptions): number { const serializedOptions = serializeArguments(options) - return handleInvalidNullResponse(handleError(indyVdrReactNative.poolCreate(serializedOptions))) + return handleInvalidNullResponse(this.handleError(this.indyVdr.poolCreate(serializedOptions))) } public async poolRefresh(options: { poolHandle: PoolHandle }): Promise { const { poolHandle } = serializeArguments(options) - return this.promisify((cb) => handleError(indyVdrReactNative.poolRefresh({ cb, poolHandle }))) + return this.promisify((cb) => this.handleError(this.indyVdr.poolRefresh({ cb, poolHandle }))) } public async poolGetStatus(options: { poolHandle: PoolHandle }): Promise { const { poolHandle } = serializeArguments(options) const result = handleInvalidNullResponse( - await this.promisifyWithResponse((cb) => - handleError(indyVdrReactNative.poolGetStatus({ cb, poolHandle })) - ) + await this.promisifyWithResponse((cb) => this.handleError(this.indyVdr.poolGetStatus({ cb, poolHandle }))) ) return JSON.parse(result) as PoolStatus @@ -245,7 +255,7 @@ export class ReactNativeIndyVdr implements IndyVdr { public async poolGetTransactions(options: { poolHandle: PoolHandle }): Promise { const { poolHandle } = serializeArguments(options) const result = handleInvalidNullResponse( - await this.promisifyWithResponse((cb) => indyVdrReactNative.poolGetTransactions({ cb, poolHandle }), true) + await this.promisifyWithResponse((cb) => this.indyVdr.poolGetTransactions({ cb, poolHandle }), true) ) return JSON.parse(result) as Transactions @@ -254,7 +264,7 @@ export class ReactNativeIndyVdr implements IndyVdr { public async poolGetVerifiers(options: { poolHandle: PoolHandle }): Promise { const { poolHandle } = serializeArguments(options) const result = handleInvalidNullResponse( - await this.promisifyWithResponse((cb) => indyVdrReactNative.poolGetVerifiers({ cb, poolHandle })) + await this.promisifyWithResponse((cb) => this.indyVdr.poolGetVerifiers({ cb, poolHandle })) ) return JSON.parse(result) as Verifiers @@ -265,9 +275,7 @@ export class ReactNativeIndyVdr implements IndyVdr { ): Promise { const serializedOptions = serializeArguments(options) const result = handleInvalidNullResponse( - await this.promisifyWithResponse((cb) => - indyVdrReactNative.poolSubmitAction({ cb, ...serializedOptions }) - ) + await this.promisifyWithResponse((cb) => this.indyVdr.poolSubmitAction({ cb, ...serializedOptions })) ) return JSON.parse(result) as T @@ -278,9 +286,7 @@ export class ReactNativeIndyVdr implements IndyVdr { ): Promise { const serializedOptions = serializeArguments(options) const result = handleInvalidNullResponse( - await this.promisifyWithResponse((cb) => - indyVdrReactNative.poolSubmitRequest({ cb, ...serializedOptions }) - ) + await this.promisifyWithResponse((cb) => this.indyVdr.poolSubmitRequest({ cb, ...serializedOptions })) ) return JSON.parse(result) as T @@ -288,50 +294,50 @@ export class ReactNativeIndyVdr implements IndyVdr { public poolClose(options: { poolHandle: number }): void { const serializedOptions = serializeArguments(options) - indyVdrReactNative.poolClose(serializedOptions) + this.indyVdr.poolClose(serializedOptions) } public prepareTxnAuthorAgreementAcceptance(options: PrepareTxnAuthorAgreementAcceptanceOptions): string { const serializedOptions = serializeArguments(options) return handleInvalidNullResponse( - handleError(indyVdrReactNative.prepareTxnAuthorAgreementAcceptance(serializedOptions)) + this.handleError(this.indyVdr.prepareTxnAuthorAgreementAcceptance(serializedOptions)) ) } public requestFree(options: { requestHandle: number }): void { const serializedOptions = serializeArguments(options) - indyVdrReactNative.requestFree(serializedOptions) + this.indyVdr.requestFree(serializedOptions) } public requestGetBody(options: { requestHandle: number }): string { const serializedOptions = serializeArguments(options) - return handleError(indyVdrReactNative.requestGetBody(serializedOptions)) + return this.handleError(this.indyVdr.requestGetBody(serializedOptions)) } public requestGetSignatureInput(options: { requestHandle: number }): string { const serializedOptions = serializeArguments(options) - return handleInvalidNullResponse(handleError(indyVdrReactNative.requestGetSignatureInput(serializedOptions))) + return handleInvalidNullResponse(this.handleError(this.indyVdr.requestGetSignatureInput(serializedOptions))) } public requestSetEndorser(options: RequestSetEndorserOptions & { requestHandle: RequestHandle }): void { const serializedOptions = serializeArguments(options) - indyVdrReactNative.requestSetEndorser(serializedOptions) + this.indyVdr.requestSetEndorser(serializedOptions) } public requestSetMultiSignature(options: RequestSetMultiSignatureOptions & { requestHandle: RequestHandle }): void { const serializedOptions = serializeArguments(options) - indyVdrReactNative.requestSetMultiSignature(serializedOptions) + this.indyVdr.requestSetMultiSignature(serializedOptions) } public requestSetSignature(options: RequestSetSignatureOptions & { requestHandle: RequestHandle }): void { const serializedOptions = serializeArguments(options) - indyVdrReactNative.requestSetSignature(serializedOptions) + this.indyVdr.requestSetSignature(serializedOptions) } public requestSetTxnAuthorAgreementAcceptance( options: RequestSetTxnAuthorAgreementAcceptanceOptions & { requestHandle: RequestHandle } ): void { const serializedOptions = serializeArguments(options) - indyVdrReactNative.requestSetTxnAuthorAgreementAcceptance(serializedOptions) + this.indyVdr.requestSetTxnAuthorAgreementAcceptance(serializedOptions) } } diff --git a/wrappers/javascript/indy-vdr-react-native/src/index.ts b/wrappers/javascript/indy-vdr-react-native/src/index.ts index b002a1e6..3861cd7a 100644 --- a/wrappers/javascript/indy-vdr-react-native/src/index.ts +++ b/wrappers/javascript/indy-vdr-react-native/src/index.ts @@ -1,17 +1,21 @@ +import type { NativeBindings } from './NativeBindings' + import { registerIndyVdr } from '@hyperledger/indy-vdr-shared' import { NativeModules } from 'react-native' import { ReactNativeIndyVdr } from './ReactNativeIndyVdr' -type Module = { - install: () => boolean -} +export * from '@hyperledger/indy-vdr-shared' -const module = NativeModules.IndyVdr as Module +const module = NativeModules.IndyVdr as { install: () => boolean } if (!module.install()) throw Error('Unable to install the turboModule: indyVdr') -export * from '@hyperledger/indy-vdr-shared' +// This can already check whether `_indy_vdr` exists on global +// eslint-disable-next-line @typescript-eslint/no-use-before-define +if (!_indy_vdr) { + throw Error('_indy_vdr has not been exposed on global. Something went wrong while installing the turboModule') +} -export const indyVdrReactNative = new ReactNativeIndyVdr() +declare let _indy_vdr: NativeBindings -registerIndyVdr({ vdr: indyVdrReactNative }) +registerIndyVdr({ vdr: new ReactNativeIndyVdr(_indy_vdr) }) diff --git a/wrappers/javascript/indy-vdr-react-native/src/library/index.ts b/wrappers/javascript/indy-vdr-react-native/src/library/index.ts deleted file mode 100644 index 6a406992..00000000 --- a/wrappers/javascript/indy-vdr-react-native/src/library/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './NativeBindings' -export * from './register' diff --git a/wrappers/javascript/indy-vdr-react-native/src/library/register.ts b/wrappers/javascript/indy-vdr-react-native/src/library/register.ts deleted file mode 100644 index 23be96a9..00000000 --- a/wrappers/javascript/indy-vdr-react-native/src/library/register.ts +++ /dev/null @@ -1,11 +0,0 @@ -import type { NativeBindings } from './NativeBindings' - -// This can already check whether `_indy_vdr` exists on global -// eslint-disable-next-line @typescript-eslint/no-use-before-define -if (!_indy_vdr) { - throw Error('_indy_vdr has not been exposed on global. Something went wrong while installing the turboModule') -} - -declare let _indy_vdr: NativeBindings - -export const indyVdrReactNative = _indy_vdr diff --git a/wrappers/javascript/indy-vdr-react-native/src/utils/serialize.ts b/wrappers/javascript/indy-vdr-react-native/src/serialize.ts similarity index 100% rename from wrappers/javascript/indy-vdr-react-native/src/utils/serialize.ts rename to wrappers/javascript/indy-vdr-react-native/src/serialize.ts diff --git a/wrappers/javascript/indy-vdr-react-native/src/utils/handleError.ts b/wrappers/javascript/indy-vdr-react-native/src/utils/handleError.ts deleted file mode 100644 index a2525908..00000000 --- a/wrappers/javascript/indy-vdr-react-native/src/utils/handleError.ts +++ /dev/null @@ -1,12 +0,0 @@ -import type { ReturnObject } from './serialize' -import type { IndyVdrErrorObject } from '@hyperledger/indy-vdr-shared' - -import { indyVdr, IndyVdrError } from '@hyperledger/indy-vdr-shared' - -export const handleError = ({ errorCode, value }: ReturnObject): T => { - if (errorCode !== 0) { - throw new IndyVdrError(JSON.parse(indyVdr.getCurrentError()) as IndyVdrErrorObject) - } - - return value as T -} diff --git a/wrappers/javascript/indy-vdr-react-native/src/utils/index.ts b/wrappers/javascript/indy-vdr-react-native/src/utils/index.ts deleted file mode 100644 index c146126c..00000000 --- a/wrappers/javascript/indy-vdr-react-native/src/utils/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './handleError' -export * from './serialize' From 8a670cb678186ce7b08fa67a2f5d2a3e78dbcd3d Mon Sep 17 00:00:00 2001 From: blu3beri Date: Thu, 25 May 2023 13:30:18 +0200 Subject: [PATCH 007/117] build(android): use custom cross images Signed-off-by: blu3beri --- .github/workflows/build.yml | 3 +++ Cross.toml | 8 ++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e9e4c96a..85216ce3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -337,6 +337,9 @@ jobs: build-android: name: Build library (Android) needs: [checks] + env: + RUST_VERSION: "1.64.0" # Overriding the rust version here for lower NDK support + runs-on: ubuntu-latest strategy: matrix: diff --git a/Cross.toml b/Cross.toml index 0d7223a1..356642de 100644 --- a/Cross.toml +++ b/Cross.toml @@ -5,13 +5,13 @@ image = "ghcr.io/rust-cross/manylinux2014-cross:aarch64" image = "ghcr.io/rust-cross/manylinux2014-cross:x86_64" [target.x86_64-linux-android] -image = "ghcr.io/cross-rs/x86_64-linux-android:main" +image = "ghcr.io/hyperledger/aries-builder-images/cross/x86_64-linux-android:main" [target.i686-linux-android] -image = "ghcr.io/cross-rs/i686-linux-android:main" +image = "ghcr.io/hyperledger/aries-builder-images/cross/i686-linux-android:main" [target.aarch64-linux-android] -image = "ghcr.io/cross-rs/aarch64-linux-android:main" +image = "ghcr.io/hyperledger/aries-builder-images/cross/aarch64-linux-android:main" [target.armv7-linux-androideabi] -image = "ghcr.io/cross-rs/armv7-linux-androideabi:main" +image = "ghcr.io/hyperledger/aries-builder-images/cross/armv7-linux-androideabi:main" From 8a74d01da63190eb825f9c143166caec67e969cb Mon Sep 17 00:00:00 2001 From: blu3beri Date: Thu, 25 May 2023 13:30:18 +0200 Subject: [PATCH 008/117] build(android): use custom cross images Signed-off-by: blu3beri --- .github/workflows/build.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 27aac877..9c7878a0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -353,6 +353,11 @@ jobs: - name: Checkout uses: actions/checkout@v3 + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ env.RUST_VERSION }} + - name: Build run: | cargo install --bins --git https://github.com/rust-embedded/cross --tag v${{ env.CROSS_VERSION }} cross From 7d02c4cc954624aabc7fdd91ec22cc0ef902e2be Mon Sep 17 00:00:00 2001 From: blu3beri Date: Thu, 25 May 2023 19:07:08 +0200 Subject: [PATCH 009/117] chore: update version Signed-off-by: blu3beri --- libindy_vdr/Cargo.toml | 2 +- wrappers/javascript/indy-vdr-nodejs/package.json | 6 +++--- wrappers/javascript/indy-vdr-react-native/package.json | 6 +++--- wrappers/javascript/indy-vdr-shared/package.json | 2 +- wrappers/javascript/lerna.json | 2 +- wrappers/python/indy_vdr/version.py | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/libindy_vdr/Cargo.toml b/libindy_vdr/Cargo.toml index 7a4e601d..3c533a46 100644 --- a/libindy_vdr/Cargo.toml +++ b/libindy_vdr/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "indy-vdr" -version = "0.4.0-dev.14" +version = "0.4.0-dev.15" authors = ["Hyperledger Indy Contributors "] description = "A library for interacting with Hyperledger Indy Node, a distributed ledger for self-sovereign identity (https://www.hyperledger.org/use/hyperledger-indy)." edition = "2021" diff --git a/wrappers/javascript/indy-vdr-nodejs/package.json b/wrappers/javascript/indy-vdr-nodejs/package.json index 4fd61e54..85e6f244 100644 --- a/wrappers/javascript/indy-vdr-nodejs/package.json +++ b/wrappers/javascript/indy-vdr-nodejs/package.json @@ -1,6 +1,6 @@ { "name": "@hyperledger/indy-vdr-nodejs", - "version": "0.1.0-dev.14", + "version": "0.1.0-dev.15", "license": "Apache-2.0", "description": "Nodejs wrapper for Indy Vdr", "source": "src/index", @@ -41,7 +41,7 @@ "typescript": "~4.9.4" }, "dependencies": { - "@hyperledger/indy-vdr-shared": "0.1.0-dev.14", + "@hyperledger/indy-vdr-shared": "0.1.0-dev.15", "@mapbox/node-pre-gyp": "^1.0.10", "@types/ref-array-di": "^1.2.5", "ffi-napi": "^4.0.3", @@ -52,7 +52,7 @@ "binary": { "module_name": "indy_vdr", "module_path": "native", - "remote_path": "v0.4.0-dev.14", + "remote_path": "v0.4.0-dev.15", "host": "https://github.com/hyperledger/indy-vdr/releases/download/", "package_name": "library-{platform}-{arch}.tar.gz" } diff --git a/wrappers/javascript/indy-vdr-react-native/package.json b/wrappers/javascript/indy-vdr-react-native/package.json index 69bcdfd6..d32f7d84 100644 --- a/wrappers/javascript/indy-vdr-react-native/package.json +++ b/wrappers/javascript/indy-vdr-react-native/package.json @@ -1,6 +1,6 @@ { "name": "@hyperledger/indy-vdr-react-native", - "version": "0.1.0-dev.14", + "version": "0.1.0-dev.15", "license": "Apache-2.0", "description": "React Native wrapper for Indy Vdr", "source": "src/index", @@ -40,7 +40,7 @@ "install": "node-pre-gyp install" }, "dependencies": { - "@hyperledger/indy-vdr-shared": "0.1.0-dev.14", + "@hyperledger/indy-vdr-shared": "0.1.0-dev.15", "@mapbox/node-pre-gyp": "^1.0.10" }, "devDependencies": { @@ -58,7 +58,7 @@ "binary": { "module_name": "indy_vdr", "module_path": "native", - "remote_path": "v0.4.0-dev.14", + "remote_path": "v0.4.0-dev.15", "host": "https://github.com/hyperledger/indy-vdr/releases/download/", "package_name": "library-ios-android.tar.gz" } diff --git a/wrappers/javascript/indy-vdr-shared/package.json b/wrappers/javascript/indy-vdr-shared/package.json index fbbdcf6d..8c7168e1 100644 --- a/wrappers/javascript/indy-vdr-shared/package.json +++ b/wrappers/javascript/indy-vdr-shared/package.json @@ -1,6 +1,6 @@ { "name": "@hyperledger/indy-vdr-shared", - "version": "0.1.0-dev.14", + "version": "0.1.0-dev.15", "license": "Apache-2.0", "description": "Shared library for using Indy VDR with NodeJS and React Native", "main": "build/index", diff --git a/wrappers/javascript/lerna.json b/wrappers/javascript/lerna.json index ca41cfe1..de6d71fd 100644 --- a/wrappers/javascript/lerna.json +++ b/wrappers/javascript/lerna.json @@ -1,6 +1,6 @@ { "packages": ["packages/*"], - "version": "0.1.0-dev.14", + "version": "0.1.0-dev.15", "useWorkspaces": true, "npmClient": "yarn", "command": { diff --git a/wrappers/python/indy_vdr/version.py b/wrappers/python/indy_vdr/version.py index 5b52bbb7..29c1089f 100644 --- a/wrappers/python/indy_vdr/version.py +++ b/wrappers/python/indy_vdr/version.py @@ -1,3 +1,3 @@ """indy_vdr library wrapper version.""" -__version__ = "0.4.0.dev14" +__version__ = "0.4.0.dev15" From 86395e3c0e30876f161dc336fcccdafb201c78d1 Mon Sep 17 00:00:00 2001 From: Berend Sliedrecht <61358536+blu3beri@users.noreply.github.com> Date: Sat, 27 May 2023 22:42:51 +0200 Subject: [PATCH 010/117] build(js): use local network (#192) Signed-off-by: blu3beri --- .github/workflows/build.yml | 9 +++++++++ wrappers/javascript/.eslintrc.js | 15 +++++++++++++-- wrappers/javascript/indy-vdr-nodejs/README.md | 18 ++++++++++++++++++ .../indy-vdr-nodejs/scripts/platform.js | 4 ---- .../indy-vdr-nodejs/tests/IndyVdrPool.test.ts | 7 ++----- .../tests/IndyVdrRequest.test.ts | 2 -- .../indy-vdr-nodejs/tests/utils/fixtures.ts | 11 ++--------- .../indy-vdr-nodejs/tests/utils/initialize.ts | 4 ++-- 8 files changed, 46 insertions(+), 24 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9c7878a0..cdfd3daf 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -243,6 +243,15 @@ jobs: - name: Check types run: yarn check-types + - name: Run local node pool + run: | + cd ../../ + docker build -f ci/indy-pool.dockerfile -t test_pool --build-arg pool_ip=10.0.0.2 ci + docker network create --subnet=10.0.0.0/8 indy-sdk-network + docker run -d --name indy_pool -p 9701-9708:9701-9708 --net=indy-sdk-network test_pool + cd wrappers/javascript + docker exec $(docker ps -aqf "ancestor=test_pool") cat /var/lib/indy/sandbox/pool_transactions_genesis >> genesis.txn + - name: Run tests env: # binary is downloaded to root of repository diff --git a/wrappers/javascript/.eslintrc.js b/wrappers/javascript/.eslintrc.js index 051c7aff..cede0fd0 100644 --- a/wrappers/javascript/.eslintrc.js +++ b/wrappers/javascript/.eslintrc.js @@ -71,8 +71,10 @@ module.exports = { }, overrides: [ { - files: ['arch.js'], - env: { node: true }, + files: ['arch.js', 'platform.js'], + env: { + node: true, + }, rules: { '@typescript-eslint/no-unsafe-assignment': 'off', 'no-console': 'off', @@ -91,5 +93,14 @@ module.exports = { '@typescript-eslint/no-unsafe-call': 'off', }, }, + { + files: ['**.test.**'], + env: { + node: true, + }, + rules: { + '@typescript-eslint/no-unsafe-assignment': 'off', + }, + }, ], } diff --git a/wrappers/javascript/indy-vdr-nodejs/README.md b/wrappers/javascript/indy-vdr-nodejs/README.md index 3004b48b..73cf2c71 100644 --- a/wrappers/javascript/indy-vdr-nodejs/README.md +++ b/wrappers/javascript/indy-vdr-nodejs/README.md @@ -33,4 +33,22 @@ const getSchemaRequest = new GetSchemaRequest({ const schemaResponse = await pool.submitRequest(getSchemaRequest) ``` +## Testing + +In order to test this library, you need a local indy network running. This can be done with the following commands (from the root of the repository): + +```sh +docker build -f ci/indy-pool.dockerfile -t test_pool --build-arg pool_ip=10.0.0.2 ci +docker network create --subnet=10.0.0.0/8 indy-sdk-network +docker run -d --name indy_pool -p 9701-9708:9701-9708 --net=indy-sdk-network test_pool + +# Network is now running + +cd wrappers/javascript + +docker exec $(docker ps -aqf "ancestor=test_pool") cat /var/lib/indy/sandbox/pool_transactions_genesis >> genesis.txn + +yarn test:local-build +``` + > **Note**: If you want to use this library in a cross-platform environment you need to import methods from the `@hyperledger/indy-vdr-shared` package instead. This is a platform independent package that allows to register the native bindings. The `@hyperledger/indy-vdr-nodejs` package uses this package under the hood. See the [Indy VDR Shared README](https://github.com/hyperledger/indy-vdr/tree/main/wrappers/javascript/indy-vdr-shared/README.md) for documentation on how to use this package. diff --git a/wrappers/javascript/indy-vdr-nodejs/scripts/platform.js b/wrappers/javascript/indy-vdr-nodejs/scripts/platform.js index feea7aa9..e521f2e0 100644 --- a/wrappers/javascript/indy-vdr-nodejs/scripts/platform.js +++ b/wrappers/javascript/indy-vdr-nodejs/scripts/platform.js @@ -1,7 +1,3 @@ -/* eslint-disable @typescript-eslint/no-var-requires */ -/* eslint-disable no-console */ -/* eslint-disable @typescript-eslint/no-unsafe-assignment */ -/* eslint-disable no-undef */ const os = require('os') // Find appropriate target architecture for retrieving the anoncreds library diff --git a/wrappers/javascript/indy-vdr-nodejs/tests/IndyVdrPool.test.ts b/wrappers/javascript/indy-vdr-nodejs/tests/IndyVdrPool.test.ts index ac8127c9..b7002d4a 100644 --- a/wrappers/javascript/indy-vdr-nodejs/tests/IndyVdrPool.test.ts +++ b/wrappers/javascript/indy-vdr-nodejs/tests/IndyVdrPool.test.ts @@ -1,9 +1,6 @@ -// TODO: this should be turned off at a eslint config level for tests -/* eslint-disable @typescript-eslint/no-unsafe-assignment */ - import type { IndyVdrPool } from '@hyperledger/indy-vdr-nodejs' -import { SOVRIN_GENESIS_TRANSACTION_BUILDER_NET } from './utils' +import { genesisTxnPath } from './utils' import { PoolCreate } from '@hyperledger/indy-vdr-nodejs' @@ -11,7 +8,7 @@ describe('IndyVdrPool', () => { let pool: IndyVdrPool beforeAll(() => { - pool = new PoolCreate({ parameters: { transactions: SOVRIN_GENESIS_TRANSACTION_BUILDER_NET } }) + pool = new PoolCreate({ parameters: { transactions_path: genesisTxnPath } }) }) test('Get pool handle', () => { diff --git a/wrappers/javascript/indy-vdr-nodejs/tests/IndyVdrRequest.test.ts b/wrappers/javascript/indy-vdr-nodejs/tests/IndyVdrRequest.test.ts index 80fa3346..4bfe9055 100644 --- a/wrappers/javascript/indy-vdr-nodejs/tests/IndyVdrRequest.test.ts +++ b/wrappers/javascript/indy-vdr-nodejs/tests/IndyVdrRequest.test.ts @@ -1,5 +1,3 @@ -/* eslint-disable @typescript-eslint/no-unsafe-assignment */ - import type { IndyVdrRequest } from '@hyperledger/indy-vdr-nodejs' import { DID, SCHEMA_ID } from './utils' diff --git a/wrappers/javascript/indy-vdr-nodejs/tests/utils/fixtures.ts b/wrappers/javascript/indy-vdr-nodejs/tests/utils/fixtures.ts index cc20a604..ef837c71 100644 --- a/wrappers/javascript/indy-vdr-nodejs/tests/utils/fixtures.ts +++ b/wrappers/javascript/indy-vdr-nodejs/tests/utils/fixtures.ts @@ -1,15 +1,8 @@ -export const SOVRIN_GENESIS_TRANSACTION_BUILDER_NET = ` -{"reqSignature":{},"txn":{"data":{"data":{"alias":"FoundationBuilder","blskey":"3gmhmqpPLqznZF3g3niodaHjbpsB6TEeE9SpgXgBnZJLmXgeRzJqTLajVwbhxrkomJFTFU4ohDC4ZRXKbUPCQywJuPAQnst8XBtCFredMECn4Z3goi1mNt5QVRdU8Ue2xMSkdLpsQMjCsNwYUsBguwXYUQnDXQXnHqRkK9qrivucQ5Z","blskey_pop":"RHWacPhUNc9JWsGNdmWYHrAvvhsow399x3ttNKKLDpz9GkxxnTKxtiZqarkx4uP5ByTwF4kM8nZddFKWuzoKizVLttALQ2Sc2BNJfRzzUZMNeQSnESkKZ7U5vE2NhUDff6pjANczrrDAXd12AjSG61QADWdg8CVciZFYtEGmKepwzP","client_ip":"35.161.146.16","client_port":"9702","node_ip":"50.112.53.5","node_port":"9701","services":["VALIDATOR"]},"dest":"GVvdyd7Y6hsBEy5yDDHjqkXgH8zW34K74RsxUiUCZDCE"},"metadata":{"from":"V5qJo72nMeF7x3ci8Zv2WP"},"type":"0"},"txnMetadata":{"seqNo":1,"txnId":"fe991cd590fff10f596bb6fe2362229de47d49dd50748e38b96f368152be29c7"},"ver":"1"} -{"reqSignature":{},"txn":{"data":{"data":{"alias":"vnode1","blskey":"t5jtREu8au2dwFwtH6QWopmTGxu6qmJ3iSnk321yLgeu7mHQRXf2ZCBuez8KCAQvFZGqqAoy2FcYvDGCqQxRCz9qXKgiBtykzxjDjYu87JECwwddnktz5UabPfZmfu6EoDn4rFxvd4myPu2hksb5Z9GT6UeoEYi7Ub3yLFQ3xxaQXc","blskey_pop":"QuHB7tiuFBPQ6zPkwHfMtjzWqXJBLACtfggm7zCRHHgdva18VN4tNg7LUU2FfKGQSLZz1M7oRxhhgJkZLL19aGvaHB2MPtnBWK9Hr8LMiwi95UjX3TVXJri4EvPjQ6UUvHrjZGUFvKQphPyVTMZBJwfkpGAGhpbTQuQpEH7f56m1X5","client_ip":"206.189.143.34","client_port":"9796","node_ip":"206.189.143.34","node_port":"9797","services":["VALIDATOR"]},"dest":"9Aj2LjQ2fwszJRSdZqg53q5e6ayScmtpeZyPGgKDswT8"},"metadata":{"from":"FzAaV9Waa1DccDa72qwg13"},"type":"0"},"txnMetadata":{"seqNo":2,"txnId":"5afc282bf9a7a5e3674c09ee48e54d73d129aa86aa226691b042e56ff9eaf59b"},"ver":"1"} -{"reqSignature":{},"txn":{"data":{"data":{"alias":"xsvalidatorec2irl","blskey":"4ge1yEvjdcV6sDSqbevqPRWq72SgkZqLqfavBXC4LxnYh4QHFpHkrwzMNjpVefvhn1cgejHayXTfTE2Fhpu1grZreUajV36T6sT4BiewAisdEw59mjMxkp9teYDYLQqwPUFPgaGKDbFCUBEaNdAP4E8Q4UFiF13Qo5842pAY13mKC23","blskey_pop":"R5PoEfWvni5BKvy7EbUbwFMQrsgcuzuU1ksxfvySH6FC5jpmisvcHMdVNik6LMvAeSdt6K4sTLrqnaaQCf5aCHkeTcQRgDVR7oFYgyZCkF953m4kSwUM9QHzqWZP89C6GkBx6VPuL1RgPahuBHDJHHiK73xLaEJzzFZtZZxwoWYABH","client_ip":"52.50.114.133","client_port":"9702","node_ip":"52.209.6.196","node_port":"9701","services":["VALIDATOR"]},"dest":"DXn8PUYKZZkq8gC7CZ2PqwECzUs2bpxYiA5TWgoYARa7"},"metadata":{"from":"QuCBjYx4CbGCiMcoqQg1y"},"type":"0"},"txnMetadata":{"seqNo":3,"txnId":"1972fce7af84b7f63b7f0c00495a84425cce3b0c552008576e7996524cca04cb"},"ver":"1"} -{"reqSignature":{},"txn":{"data":{"data":{"alias":"danube","blskey":"3Vt8fxn7xg8n8pR872cvGWNuR7STFzFSPMftX96zF6871wYVTR27aspxGSeEtx9wj8g4D3GdCxHJbQ4FsxQz6TATQswiiZfxAVNjLLUci8WSH4t1GPx9CvGXB2uzDfVnnJyhhnASxJEbvykLUBBFG3fW4tMQixujpowUADz5jHm427u","blskey_pop":"RJpXXLkjRRv9Lk8tJz8LTkhhC7RWjHQcB9CG8J8U8fXT6arTDMYc62zXtToBAmGkGu8Udsmo3Hh7mv4KB9JAf8ufGY9WsnppCVwar7zEXyBfLpCnDhvVcBAzkhRpHmqHygN24DeBu9aH6tw4uXxVJvRRGSbPtxjWa379BmfQWzXHCb","client_ip":"207.180.207.73","client_port":"9702","node_ip":"173.249.14.196","node_port":"9701","services":["VALIDATOR"]},"dest":"52muwfE7EjTGDKxiQCYWr58D8BcrgyKVjhHgRQdaLiMw"},"metadata":{"from":"VbPQNHsvoLZdaNU7fTBeFx"},"type":"0"},"txnMetadata":{"seqNo":4,"txnId":"ebf340b317c044d970fcd0ca018d8903726fa70c8d8854752cd65e29d443686c"},"ver":"1"} -` +import path from 'path' +export const genesisTxnPath = path.join(__dirname, '../../../genesis.txn') export const DID = 'PqdUtwWhuX4GWRa58WSdvn' - export const SCHEMA_ID = 'J6nTnUo3YLayzc2GUUctb1:2:MyName:1.0' - export const CRED_DEF_ID = 'GeUpJLNXHEgTBJEy4nSjnd:3:CL:47756:default' - export const REVOC_REG_DEF_ID = 'EsUFXEDp9uqPL3tMNXhUst:4:EsUFXEDp9uqPL3tMNXhUst:3:CL:63132:Oliu.id:CL_ACCUM:6074b559-164e-458a-8532-2057d5b26946' diff --git a/wrappers/javascript/indy-vdr-nodejs/tests/utils/initialize.ts b/wrappers/javascript/indy-vdr-nodejs/tests/utils/initialize.ts index ca17a0ea..83dec783 100644 --- a/wrappers/javascript/indy-vdr-nodejs/tests/utils/initialize.ts +++ b/wrappers/javascript/indy-vdr-nodejs/tests/utils/initialize.ts @@ -1,7 +1,7 @@ import { PoolCreate } from '@hyperledger/indy-vdr-shared' -import { SOVRIN_GENESIS_TRANSACTION_BUILDER_NET } from './fixtures' +import { genesisTxnPath } from './fixtures' export const setupPool = () => { - return new PoolCreate({ parameters: { transactions: SOVRIN_GENESIS_TRANSACTION_BUILDER_NET } }) + return new PoolCreate({ parameters: { transactions_path: genesisTxnPath } }) } From 47719c2692b4d7a61ce8731008d78268c41e55be Mon Sep 17 00:00:00 2001 From: Berend Sliedrecht <61358536+blu3beri@users.noreply.github.com> Date: Thu, 1 Jun 2023 08:30:32 +0200 Subject: [PATCH 011/117] fix(rn): android works with JSC and Hermes (#194) --- .../android/CMakeLists.txt | 61 ------------------- .../android/build.gradle | 52 ++++++---------- 2 files changed, 18 insertions(+), 95 deletions(-) diff --git a/wrappers/javascript/indy-vdr-react-native/android/CMakeLists.txt b/wrappers/javascript/indy-vdr-react-native/android/CMakeLists.txt index 91bc5376..c84556e9 100644 --- a/wrappers/javascript/indy-vdr-react-native/android/CMakeLists.txt +++ b/wrappers/javascript/indy-vdr-react-native/android/CMakeLists.txt @@ -8,13 +8,6 @@ file (GLOB LIBINDY_VDR_DIR "${CMAKE_SOURCE_DIR}/../native/mobile/android/${ANDRO set(CMAKE_VERBOSE_MAKEFILE ON) set(CMAKE_CXX_STANDARD 14) -if(${REACT_NATIVE_VERSION} GREATER_EQUAL 71) - include("${NODE_MODULES_DIR}/react-native/ReactAndroid/cmake-utils/folly-flags.cmake") - add_compile_options(${folly_FLAGS}) -else() - set (CMAKE_CXX_FLAGS "-DFOLLY_NO_CONFIG=1 -DFOLLY_HAVE_CLOCK_GETTIME=1 -DFOLLY_HAVE_MEMRCHR=1 -DFOLLY_USE_LIBCPP=1 -DFOLLY_MOBILE=1 -DON_ANDROID -DONANDROID -DFOR_HERMES=${FOR_HERMES}") -endif() - set (BUILD_DIR ${CMAKE_SOURCE_DIR}/build) if(${REACT_NATIVE_VERSION} GREATER_EQUAL 71) find_package(fbjni REQUIRED CONFIG) @@ -69,7 +62,6 @@ else() "${NODE_MODULES_DIR}/react-native/ReactCommon" "${NODE_MODULES_DIR}/react-native/ReactCommon/callinvoker" "${NODE_MODULES_DIR}/react-native/ReactCommon/jsi" - "${NODE_MODULES_DIR}/hermes-engine/android/include/" ${INCLUDE_JSI_CPP} # only on older RN versions ${INCLUDE_JSIDYNAMIC_CPP} # only on older RN versions ) @@ -77,59 +69,6 @@ endif() file (GLOB LIBRN_DIR "${BUILD_DIR}/react-native-0*/jni/${ANDROID_ABI}") -if(${FOR_HERMES}) - string(APPEND CMAKE_CXX_FLAGS " -DFOR_HERMES=1") - - if(${REACT_NATIVE_VERSION} GREATER_EQUAL 71) - find_package(hermes-engine REQUIRED CONFIG) - elseif(${REACT_NATIVE_VERSION} GREATER_EQUAL 69) - # Bundled Hermes from module `com.facebook.react:hermes-engine` or project `:ReactAndroid:hermes-engine` - target_include_directories( - ${PACKAGE_NAME} - PRIVATE - "${JS_RUNTIME_DIR}/API" - "${JS_RUNTIME_DIR}/public" - ) - else() - # From `hermes-engine` npm package - target_include_directories( - ${PACKAGE_NAME} - PRIVATE - "${JS_RUNTIME_DIR}/android/include" - ) - endif() - - if(${REACT_NATIVE_VERSION} GREATER_EQUAL 71) - target_link_libraries( - ${PACKAGE_NAME} - "hermes-engine::libhermes" - ) - else() - target_link_libraries( - ${PACKAGE_NAME} - "${BUILD_DIR}/third-party-ndk/hermes/jni/${ANDROID_ABI}/libhermes.so" - ) - endif() -else() - file (GLOB LIBJSC_DIR "${BUILD_DIR}/android-jsc*.aar/jni/${ANDROID_ABI}") - - if(${REACT_NATIVE_VERSION} GREATER_EQUAL 71) - set(JS_ENGINE_LIB ReactAndroid::jscexecutor) - else() - # Use JSC - find_library( - JS_ENGINE_LIB - jscexecutor - PATHS ${LIBRN_DIR} - NO_CMAKE_FIND_ROOT_PATH - ) - endif() - target_link_libraries( - ${PACKAGE_NAME} - ${JS_ENGINE_LIB} - ) -endif() - if(${REACT_NATIVE_VERSION} LESS 71) find_library( FBJNI_LIB diff --git a/wrappers/javascript/indy-vdr-react-native/android/build.gradle b/wrappers/javascript/indy-vdr-react-native/android/build.gradle index e4c8cbf4..9017d77e 100644 --- a/wrappers/javascript/indy-vdr-react-native/android/build.gradle +++ b/wrappers/javascript/indy-vdr-react-native/android/build.gradle @@ -1,14 +1,8 @@ import org.apache.tools.ant.filters.ReplaceTokens import java.nio.file.Paths -apply plugin: 'com.android.library' -apply plugin: 'de.undercouch.download' - buildscript { repositories { - maven { - url "https://plugins.gradle.org/m2/" - } google() jcenter() mavenCentral() @@ -58,24 +52,8 @@ file("$nodeModules/react-native/ReactAndroid/gradle.properties").withInputStream def REACT_NATIVE_FULL_VERSION = reactProperties.getProperty("VERSION_NAME") def REACT_NATIVE_VERSION = reactProperties.getProperty("VERSION_NAME").split("\\.")[1].toInteger() -def FOR_HERMES = System.getenv("FOR_HERMES") == "True" -rootProject.getSubprojects().forEach({project -> - if (project.plugins.hasPlugin("com.android.application")) { - FOR_HERMES = REACT_NATIVE_VERSION >= 71 && project.hermesEnabled || project.ext.react.enableHermes - } -}) - -def jsRuntimeDir = { - if (FOR_HERMES) { - if (REACT_NATIVE_VERSION >= 69) { - return Paths.get(CMAKE_NODE_MODULES_DIR, "react-native", "sdks", "hermes") - } else { - return Paths.get(CMAKE_NODE_MODULES_DIR, "hermes-engine") - } - } else { - return Paths.get(CMAKE_NODE_MODULES_DIR, "react-native", "ReactCommon", "jsi") - } -}.call() +apply plugin: 'com.android.library' +apply plugin: 'de.undercouch.download' def getExt(name) { return rootProject.ext.get(name) @@ -112,9 +90,7 @@ android { abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a' arguments "-DANDROID_STL=c++_shared", "-DREACT_NATIVE_VERSION=${REACT_NATIVE_VERSION}", - "-DNODE_MODULES_DIR=${nodeModules}", - "-DFOR_HERMES=${FOR_HERMES}", - "-DJS_RUNTIME_DIR=${jsRuntimeDir}" + "-DNODE_MODULES_DIR=${nodeModules}" } } @@ -132,7 +108,6 @@ android { "**/libjsi.so", "**/libreactnativejni.so", "**/libjscexecutor.so", - "**/libhermes.so" ] } @@ -237,10 +212,10 @@ repositories { dependencies { if (REACT_NATIVE_VERSION >= 71) { implementation "com.facebook.react:react-android:" - implementation "com.facebook.react:hermes-android:" } else { + // noinspection GradleDynamicVersion implementation 'com.facebook.react:react-native:' + REACT_NATIVE_FULL_VERSION - } + } if (REACT_NATIVE_VERSION < 71) { //noinspection GradleDynamicVersion @@ -259,6 +234,15 @@ dependencies { } } +def downloadsDir = new File("$buildDir/downloads") + +task createNativeDepsDirectories { + doLast { + downloadsDir.mkdirs() + } +} + + task extractAARHeaders { doLast { configurations.extractHeaders.files.each { @@ -272,6 +256,8 @@ task extractAARHeaders { } } +extractAARHeaders.mustRunAfter createNativeDepsDirectories + task extractJNIFiles { doLast { configurations.extractJNI.files.each { @@ -290,9 +276,7 @@ extractJNIFiles.mustRunAfter extractAARHeaders tasks.whenTaskAdded { task -> if (!task.name.contains('Clean') && (task.name.contains('externalNative') || task.name.contains('CMake'))) { - if (REACT_NATIVE_VERSION < 71) { - task.dependsOn(extractAARHeaders) - task.dependsOn(extractJNIFiles) - } + task.dependsOn(extractAARHeaders) + task.dependsOn(extractJNIFiles) } } From 724b570614a8c0c8e2bbfcef84b9d7960e6893af Mon Sep 17 00:00:00 2001 From: Berend Sliedrecht Date: Thu, 1 Jun 2023 09:13:57 +0200 Subject: [PATCH 012/117] chore: update version Signed-off-by: Berend Sliedrecht --- libindy_vdr/Cargo.toml | 2 +- wrappers/javascript/indy-vdr-nodejs/package.json | 6 +++--- wrappers/javascript/indy-vdr-react-native/package.json | 6 +++--- wrappers/javascript/indy-vdr-shared/package.json | 2 +- wrappers/python/indy_vdr/version.py | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/libindy_vdr/Cargo.toml b/libindy_vdr/Cargo.toml index 3c533a46..4b24a168 100644 --- a/libindy_vdr/Cargo.toml +++ b/libindy_vdr/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "indy-vdr" -version = "0.4.0-dev.15" +version = "0.4.0-dev.16" authors = ["Hyperledger Indy Contributors "] description = "A library for interacting with Hyperledger Indy Node, a distributed ledger for self-sovereign identity (https://www.hyperledger.org/use/hyperledger-indy)." edition = "2021" diff --git a/wrappers/javascript/indy-vdr-nodejs/package.json b/wrappers/javascript/indy-vdr-nodejs/package.json index 85e6f244..2550a4d8 100644 --- a/wrappers/javascript/indy-vdr-nodejs/package.json +++ b/wrappers/javascript/indy-vdr-nodejs/package.json @@ -1,6 +1,6 @@ { "name": "@hyperledger/indy-vdr-nodejs", - "version": "0.1.0-dev.15", + "version": "0.1.0-dev.16", "license": "Apache-2.0", "description": "Nodejs wrapper for Indy Vdr", "source": "src/index", @@ -41,7 +41,7 @@ "typescript": "~4.9.4" }, "dependencies": { - "@hyperledger/indy-vdr-shared": "0.1.0-dev.15", + "@hyperledger/indy-vdr-shared": "0.1.0-dev.16", "@mapbox/node-pre-gyp": "^1.0.10", "@types/ref-array-di": "^1.2.5", "ffi-napi": "^4.0.3", @@ -52,7 +52,7 @@ "binary": { "module_name": "indy_vdr", "module_path": "native", - "remote_path": "v0.4.0-dev.15", + "remote_path": "v0.4.0-dev.16", "host": "https://github.com/hyperledger/indy-vdr/releases/download/", "package_name": "library-{platform}-{arch}.tar.gz" } diff --git a/wrappers/javascript/indy-vdr-react-native/package.json b/wrappers/javascript/indy-vdr-react-native/package.json index d32f7d84..a116c79c 100644 --- a/wrappers/javascript/indy-vdr-react-native/package.json +++ b/wrappers/javascript/indy-vdr-react-native/package.json @@ -1,6 +1,6 @@ { "name": "@hyperledger/indy-vdr-react-native", - "version": "0.1.0-dev.15", + "version": "0.1.0-dev.16", "license": "Apache-2.0", "description": "React Native wrapper for Indy Vdr", "source": "src/index", @@ -40,7 +40,7 @@ "install": "node-pre-gyp install" }, "dependencies": { - "@hyperledger/indy-vdr-shared": "0.1.0-dev.15", + "@hyperledger/indy-vdr-shared": "0.1.0-dev.16", "@mapbox/node-pre-gyp": "^1.0.10" }, "devDependencies": { @@ -58,7 +58,7 @@ "binary": { "module_name": "indy_vdr", "module_path": "native", - "remote_path": "v0.4.0-dev.15", + "remote_path": "v0.4.0-dev.16", "host": "https://github.com/hyperledger/indy-vdr/releases/download/", "package_name": "library-ios-android.tar.gz" } diff --git a/wrappers/javascript/indy-vdr-shared/package.json b/wrappers/javascript/indy-vdr-shared/package.json index 8c7168e1..f470ed50 100644 --- a/wrappers/javascript/indy-vdr-shared/package.json +++ b/wrappers/javascript/indy-vdr-shared/package.json @@ -1,6 +1,6 @@ { "name": "@hyperledger/indy-vdr-shared", - "version": "0.1.0-dev.15", + "version": "0.1.0-dev.16", "license": "Apache-2.0", "description": "Shared library for using Indy VDR with NodeJS and React Native", "main": "build/index", diff --git a/wrappers/python/indy_vdr/version.py b/wrappers/python/indy_vdr/version.py index 29c1089f..0a61ca82 100644 --- a/wrappers/python/indy_vdr/version.py +++ b/wrappers/python/indy_vdr/version.py @@ -1,3 +1,3 @@ """indy_vdr library wrapper version.""" -__version__ = "0.4.0.dev15" +__version__ = "0.4.0.dev16" From 43aa575b6dab8e2f8a20af489dfc1bfccd7a832c Mon Sep 17 00:00:00 2001 From: Berend Sliedrecht <61358536+blu3beri@users.noreply.github.com> Date: Fri, 2 Jun 2023 19:10:47 +0200 Subject: [PATCH 013/117] chore(js): update to stable version (#196) Signed-off-by: Berend Sliedrecht --- wrappers/javascript/indy-vdr-nodejs/package.json | 4 ++-- wrappers/javascript/indy-vdr-react-native/package.json | 4 ++-- wrappers/javascript/indy-vdr-shared/package.json | 2 +- wrappers/javascript/lerna.json | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/wrappers/javascript/indy-vdr-nodejs/package.json b/wrappers/javascript/indy-vdr-nodejs/package.json index 2550a4d8..895516b5 100644 --- a/wrappers/javascript/indy-vdr-nodejs/package.json +++ b/wrappers/javascript/indy-vdr-nodejs/package.json @@ -1,6 +1,6 @@ { "name": "@hyperledger/indy-vdr-nodejs", - "version": "0.1.0-dev.16", + "version": "0.1.0", "license": "Apache-2.0", "description": "Nodejs wrapper for Indy Vdr", "source": "src/index", @@ -41,7 +41,7 @@ "typescript": "~4.9.4" }, "dependencies": { - "@hyperledger/indy-vdr-shared": "0.1.0-dev.16", + "@hyperledger/indy-vdr-shared": "0.1.0", "@mapbox/node-pre-gyp": "^1.0.10", "@types/ref-array-di": "^1.2.5", "ffi-napi": "^4.0.3", diff --git a/wrappers/javascript/indy-vdr-react-native/package.json b/wrappers/javascript/indy-vdr-react-native/package.json index a116c79c..4ffdedaf 100644 --- a/wrappers/javascript/indy-vdr-react-native/package.json +++ b/wrappers/javascript/indy-vdr-react-native/package.json @@ -1,6 +1,6 @@ { "name": "@hyperledger/indy-vdr-react-native", - "version": "0.1.0-dev.16", + "version": "0.1.0", "license": "Apache-2.0", "description": "React Native wrapper for Indy Vdr", "source": "src/index", @@ -40,7 +40,7 @@ "install": "node-pre-gyp install" }, "dependencies": { - "@hyperledger/indy-vdr-shared": "0.1.0-dev.16", + "@hyperledger/indy-vdr-shared": "0.1.0", "@mapbox/node-pre-gyp": "^1.0.10" }, "devDependencies": { diff --git a/wrappers/javascript/indy-vdr-shared/package.json b/wrappers/javascript/indy-vdr-shared/package.json index f470ed50..f9ac6e01 100644 --- a/wrappers/javascript/indy-vdr-shared/package.json +++ b/wrappers/javascript/indy-vdr-shared/package.json @@ -1,6 +1,6 @@ { "name": "@hyperledger/indy-vdr-shared", - "version": "0.1.0-dev.16", + "version": "0.1.0", "license": "Apache-2.0", "description": "Shared library for using Indy VDR with NodeJS and React Native", "main": "build/index", diff --git a/wrappers/javascript/lerna.json b/wrappers/javascript/lerna.json index de6d71fd..22c0c4f3 100644 --- a/wrappers/javascript/lerna.json +++ b/wrappers/javascript/lerna.json @@ -1,6 +1,6 @@ { "packages": ["packages/*"], - "version": "0.1.0-dev.15", + "version": "0.1.0", "useWorkspaces": true, "npmClient": "yarn", "command": { From e211fd3c14de2e13973b71cd97fdf90c946112c2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 11 Jul 2023 09:18:01 +0000 Subject: [PATCH 014/117] build(deps): bump semver from 5.7.1 to 5.7.2 in /wrappers/javascript Bumps [semver](https://github.com/npm/node-semver) from 5.7.1 to 5.7.2. - [Release notes](https://github.com/npm/node-semver/releases) - [Changelog](https://github.com/npm/node-semver/blob/v5.7.2/CHANGELOG.md) - [Commits](https://github.com/npm/node-semver/compare/v5.7.1...v5.7.2) --- updated-dependencies: - dependency-name: semver dependency-type: indirect ... Signed-off-by: dependabot[bot] --- wrappers/javascript/yarn.lock | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/wrappers/javascript/yarn.lock b/wrappers/javascript/yarn.lock index 199e40d8..4af0963e 100644 --- a/wrappers/javascript/yarn.lock +++ b/wrappers/javascript/yarn.lock @@ -5988,19 +5988,19 @@ semver@7.0.0: integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== semver@^5.5.0, semver@^5.6.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + version "5.7.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" + integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" - integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + version "6.3.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== semver@^7.3.5: - version "7.3.7" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" - integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== dependencies: lru-cache "^6.0.0" From 76c5d7d24852a08c1d7d6400530aae238f87c209 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20W=C3=B6rner?= Date: Mon, 21 Feb 2022 10:48:57 +0100 Subject: [PATCH 015/117] did:indy resolver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- libindy_vdr/Cargo.toml | 1 + libindy_vdr/src/common/error.rs | 2 + libindy_vdr/src/ffi/error.rs | 2 + libindy_vdr/src/ledger/mod.rs | 3 + libindy_vdr/src/ledger/responses.rs | 59 +++ libindy_vdr/src/lib.rs | 3 + libindy_vdr/src/resolver/did.rs | 587 +++++++++++++++++++++++ libindy_vdr/src/resolver/did_document.rs | 542 +++++++++++++++++++++ libindy_vdr/src/resolver/mod.rs | 4 + libindy_vdr/src/resolver/resolver.rs | 336 +++++++++++++ 10 files changed, 1539 insertions(+) create mode 100644 libindy_vdr/src/ledger/responses.rs create mode 100644 libindy_vdr/src/resolver/did.rs create mode 100644 libindy_vdr/src/resolver/did_document.rs create mode 100644 libindy_vdr/src/resolver/mod.rs create mode 100644 libindy_vdr/src/resolver/resolver.rs diff --git a/libindy_vdr/Cargo.toml b/libindy_vdr/Cargo.toml index 4b24a168..4eec64d1 100644 --- a/libindy_vdr/Cargo.toml +++ b/libindy_vdr/Cargo.toml @@ -48,6 +48,7 @@ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" sha3 = "0.10" thiserror = "1.0" +url = "2.2.2" zmq = "0.9" [dependencies.ursa] diff --git a/libindy_vdr/src/common/error.rs b/libindy_vdr/src/common/error.rs index abd68993..632cd1ce 100644 --- a/libindy_vdr/src/common/error.rs +++ b/libindy_vdr/src/common/error.rs @@ -46,6 +46,8 @@ pub enum VdrErrorKind { PoolRequestFailed(String), #[error("Pool timeout")] PoolTimeout, + #[error("Resolver error ")] + Resolver, } impl VdrError { diff --git a/libindy_vdr/src/ffi/error.rs b/libindy_vdr/src/ffi/error.rs index bbaf19b4..16f561b3 100644 --- a/libindy_vdr/src/ffi/error.rs +++ b/libindy_vdr/src/ffi/error.rs @@ -23,6 +23,7 @@ pub enum ErrorCode { PoolNoConsensus = 30, PoolRequestFailed = 31, PoolTimeout = 32, + Resolver = 9, } impl From<&VdrErrorKind> for ErrorCode { @@ -39,6 +40,7 @@ impl From<&VdrErrorKind> for ErrorCode { VdrErrorKind::PoolNoConsensus => ErrorCode::PoolNoConsensus, VdrErrorKind::PoolRequestFailed(_) => ErrorCode::PoolRequestFailed, VdrErrorKind::PoolTimeout => ErrorCode::PoolTimeout, + VdrErrorKind::Resolver => ErrorCode::Resolver, } } } diff --git a/libindy_vdr/src/ledger/mod.rs b/libindy_vdr/src/ledger/mod.rs index 91a8b33e..1d45be8c 100644 --- a/libindy_vdr/src/ledger/mod.rs +++ b/libindy_vdr/src/ledger/mod.rs @@ -19,6 +19,9 @@ pub mod identifiers { #[macro_use] pub mod requests; +/// Types for data of ledger responses +pub mod responses; + /// Helpers for constructing ledger requests mod request_builder; diff --git a/libindy_vdr/src/ledger/responses.rs b/libindy_vdr/src/ledger/responses.rs new file mode 100644 index 00000000..4c5c3e57 --- /dev/null +++ b/libindy_vdr/src/ledger/responses.rs @@ -0,0 +1,59 @@ +use crate::utils::did::DidValue; +use serde::Deserialize; +use serde_json::value::Value; +use std::collections::HashMap; + +pub enum ResponseTypes { + GetNymResult(GetNymResult), + GetSchemaResult(GetSchemaResult), + GetClaimDefResult(GetClaimDefResult), +} + +#[derive(Deserialize, Debug)] +#[serde(untagged)] +pub enum GetNymResult { + GetNymResultV0(GetNymResultV0), + GetNymResultV1(GetNymResultV1), +} + +#[derive(Deserialize, Eq, PartialEq, Debug)] +pub struct GetNymResultV0 { + pub identifier: Option, + pub dest: DidValue, + pub role: Option, + pub verkey: String, +} + +#[derive(Deserialize, Eq, PartialEq, Debug)] +#[serde(rename_all = "camelCase")] +pub struct GetNymResultV1 { + pub identifier: Option, + pub dest: DidValue, + pub role: Option, + pub verkey: String, + pub diddoc_content: Option, +} + +#[derive(Deserialize, Eq, PartialEq, Debug)] +pub struct GetSchemaResult { + pub attr_names: Vec, + pub name: String, + pub version: String, +} + +#[derive(Deserialize, Eq, PartialEq, Debug)] +#[serde(rename_all = "camelCase")] +pub struct GetClaimDefResult { + pub ref_schema_attributes: Vec, + pub ref_schema_from: String, + pub ref_schema_id: String, + pub ref_schema_name: String, + pub ref_schema_txn_seq_no: u32, + pub ref_schema_txn_time: String, + pub ref_schema_version: String, +} + +#[derive(Clone, Deserialize, Eq, PartialEq, Debug)] +pub struct Endpoint { + pub endpoint: HashMap, +} diff --git a/libindy_vdr/src/lib.rs b/libindy_vdr/src/lib.rs index fdd15d4c..1bf2a2cd 100644 --- a/libindy_vdr/src/lib.rs +++ b/libindy_vdr/src/lib.rs @@ -66,6 +66,9 @@ mod ffi; pub mod ledger; /// Handling of verifier pool instances and communication pub mod pool; + +/// did:indy DID URL resolver +pub mod resolver; /// State proof verification for ledger read transactions pub mod state_proof; diff --git a/libindy_vdr/src/resolver/did.rs b/libindy_vdr/src/resolver/did.rs new file mode 100644 index 00000000..b6301a2e --- /dev/null +++ b/libindy_vdr/src/resolver/did.rs @@ -0,0 +1,587 @@ +use crate::common::error::prelude::*; +use crate::utils::did::DidValue; +use regex::Regex; +use url::Url; + +use std::collections::HashMap; + +// Patterns to build regular expressions for ledger objects +static DID_INDY_PREFIX: &str = "did:indy"; +static NAMESPACE_PATTERN: &str = "((?:[a-z0-9_-]+:?){1,2})"; +// uses base58 alphabet +static INDY_UNQUALIFIED_DID_PATTERN: &str = + "([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22})"; +static OBJECT_FAMILY_PATTERN: &str = "([a-z]*)"; +static OBJECT_FAMILY_VERSION_PATTERN: &str = "([a-zA-Z0-9]*)"; + +static ANONCREDSV0_OBJECTS_PATTERN: &str = + "(SCHEMA|CLAIM_DEF|REV_REG_DEF|REV_REG_ENTRY|REV_REG_DELTA)"; + +static CLIENT_DEFINED_NAME_PATTERN: &str = "([\\w-]*)"; +static SEQ_NO_PATTERN: &str = "(\\d*)"; +static VERSION_PATTERN: &str = "((\\d*\\.){1,2}\\d*)"; + +#[derive(Debug, PartialEq, Eq, Hash)] +pub enum QueryParameter { + VersionId, + VersionTime, + From, + To, +} + +impl QueryParameter { + pub fn from_str(input: &str) -> VdrResult { + match input { + "versionId" => Ok(QueryParameter::VersionId), + "versionTime" => Ok(QueryParameter::VersionTime), + "from" => Ok(QueryParameter::From), + "to" => Ok(QueryParameter::To), + _ => Err(err_msg( + VdrErrorKind::Resolver, + format!("Query parameter {} not supported", input), + )), + } + } +} + +#[derive(Debug, PartialEq)] +pub enum ObjectFamily { + Anoncreds, +} + +impl ObjectFamily { + fn from_str(input: &str) -> VdrResult { + match input { + "anoncreds" => Ok(ObjectFamily::Anoncreds), + _ => Err(err_msg( + VdrErrorKind::Resolver, + format!("Object family {} not supported", input), + )), + } + } +} + +#[derive(Debug, PartialEq)] +pub enum Anoncreds { + AnoncredsV0, +} + +impl Anoncreds { + fn from_str(input: &str) -> VdrResult { + match input { + "v0" => Ok(Anoncreds::AnoncredsV0), + _ => Err(err_msg( + VdrErrorKind::Resolver, + format!("Anoncreds version {} not supported", input), + )), + } + } +} + +#[derive(Debug, PartialEq)] +pub struct Schema { + pub name: String, + pub version: String, +} + +impl Schema { + fn new(name: String, version: String) -> Self { + Self { name, version } + } + + fn from_str(input: &str) -> VdrResult { + let re = + Regex::new(format!(r"^{}/{}", CLIENT_DEFINED_NAME_PATTERN, VERSION_PATTERN).as_str()) + .unwrap(); + + let captures = re.captures(input); + + match captures { + Some(cap) => Ok(Schema::new( + cap.get(1) + .ok_or(err_msg( + VdrErrorKind::Resolver, + format!("Invalid DID URL path for schema {}", input), + ))? + .as_str() + .to_string(), + cap.get(2) + .ok_or(err_msg( + VdrErrorKind::Resolver, + format!("Invalid DID URL path for schema {}", input), + ))? + .as_str() + .to_string(), + )), + _ => Err(err_msg( + VdrErrorKind::Resolver, + format!("Invalid DID URL path for schema {}", input), + )), + } + } +} + +#[derive(Debug, PartialEq)] +pub struct ClaimDef { + pub schema_seq_no: u32, + pub name: String, +} + +impl ClaimDef { + fn new(schema_seq_no: u32, name: String) -> Self { + Self { + schema_seq_no, + name, + } + } + + fn from_str(input: &str) -> VdrResult { + let re = + Regex::new(format!(r"^{}/{}", SEQ_NO_PATTERN, CLIENT_DEFINED_NAME_PATTERN).as_str()) + .unwrap(); + + let captures = re.captures(input); + + match captures { + Some(cap) => Ok(ClaimDef::new( + cap.get(1) + .ok_or(err_msg( + VdrErrorKind::Resolver, + format!("Invalid DID URL path for claim def {}", input), + ))? + .as_str() + .to_string() + .parse::() + .unwrap(), + cap.get(2) + .ok_or(err_msg( + VdrErrorKind::Resolver, + format!("Invalid DID URL path for claim def {}", input), + ))? + .as_str() + .to_string(), + )), + _ => Err(err_msg( + VdrErrorKind::Resolver, + format!("Invalid DID URL path for claim def {}", input), + )), + } + } +} + +#[derive(Debug, PartialEq)] +pub struct RevReg { + pub schema_seq_no: u32, + pub claim_def_name: String, + pub tag: String, +} + +impl RevReg { + fn new(schema_seq_no: u32, claim_def_name: String, tag: String) -> Self { + Self { + schema_seq_no, + claim_def_name, + tag, + } + } + + fn from_str(input: &str) -> VdrResult { + let re = Regex::new( + format!(r"^{}/{}/{1}", SEQ_NO_PATTERN, CLIENT_DEFINED_NAME_PATTERN).as_str(), + ) + .unwrap(); + + let captures = re.captures(input); + + match captures { + Some(cap) => Ok(RevReg::new( + cap.get(1) + .ok_or(err_msg( + VdrErrorKind::Resolver, + format!("Invalid DID URL path for revocation registry {}", input), + ))? + .as_str() + .to_string() + .parse::() + .unwrap(), + cap.get(2) + .ok_or(err_msg( + VdrErrorKind::Resolver, + format!("Invalid DID URL path for revocation registry {}", input), + ))? + .as_str() + .to_string(), + cap.get(3) + .ok_or(err_msg( + VdrErrorKind::Resolver, + format!("Invalid DID URL path for revocation registry {}", input), + ))? + .as_str() + .to_string(), + )), + _ => Err(err_msg( + VdrErrorKind::Resolver, + format!("Invalid DID URL path for revocation registry {}", input), + )), + } + } +} + +#[derive(Debug, PartialEq)] +pub enum LedgerObject { + Schema(Schema), + ClaimDef(ClaimDef), + RevRegDef(RevReg), + RevRegEntry(RevReg), + RevRegDelta(RevReg), +} + +impl LedgerObject { + pub fn from_str(input: &str) -> VdrResult { + let re = Regex::new( + format!( + r"{}/{}/{}/(.+)?", + OBJECT_FAMILY_PATTERN, OBJECT_FAMILY_VERSION_PATTERN, ANONCREDSV0_OBJECTS_PATTERN + ) + .as_str(), + ) + .unwrap(); + + let captures = re.captures(input); + + if let Some(cap) = captures { + let object_family_str = cap + .get(1) + .ok_or(err_msg( + VdrErrorKind::Resolver, + format!("Invalid DID URL path"), + ))? + .as_str(); + let version = cap + .get(2) + .ok_or(err_msg( + VdrErrorKind::Resolver, + format!("Invalid DID URL path"), + ))? + .as_str(); + + let object_family = ObjectFamily::from_str(object_family_str)?; + + match object_family { + ObjectFamily::Anoncreds => { + let object_family_versioned = Anoncreds::from_str(version)?; + match object_family_versioned { + Anoncreds::AnoncredsV0 => { + let ledger_object_type_str = cap + .get(3) + .ok_or(err_msg( + VdrErrorKind::Resolver, + format!("Invalid DID URL path"), + ))? + .as_str(); + let ledger_object_type_specific_str = cap + .get(4) + .ok_or(err_msg( + VdrErrorKind::Resolver, + format!("Invalid DID URL path"), + ))? + .as_str(); + match ledger_object_type_str { + "SCHEMA" => Ok(LedgerObject::Schema(Schema::from_str( + ledger_object_type_specific_str, + )?)), + "CLAIM_DEF" => Ok(LedgerObject::ClaimDef(ClaimDef::from_str( + ledger_object_type_specific_str, + )?)), + "REV_REG_DEF" => Ok(LedgerObject::RevRegDef(RevReg::from_str( + ledger_object_type_specific_str, + )?)), + "REV_REG_ENTRY" => Ok(LedgerObject::RevRegEntry(RevReg::from_str( + ledger_object_type_specific_str, + )?)), + "REV_REG_DELTA" => Ok(LedgerObject::RevRegDelta(RevReg::from_str( + ledger_object_type_specific_str, + )?)), + + _ => Err(err_msg( + VdrErrorKind::Resolver, + format!( + "Unknown ledger object type {}", + ledger_object_type_str + ), + )), + } + } + } + } + } + } else { + Err(err_msg( + VdrErrorKind::Resolver, + format!("Invalid DID URL path for ledger object {}", input), + )) + } + } +} + +#[derive(Debug, PartialEq)] +pub struct DidUrl { + pub namespace: String, + pub id: DidValue, + pub path: Option, + pub query: HashMap, + pub url: String, +} + +impl DidUrl { + pub fn from_str(input: &str) -> VdrResult { + let did_regex = Regex::new( + format!( + r"{}:{}:{}(.+)?$", + DID_INDY_PREFIX, NAMESPACE_PATTERN, INDY_UNQUALIFIED_DID_PATTERN + ) + .as_str(), + ) + .unwrap(); + + let input_without_query = match input.split_once("?") { + Some(s) => s.0, + None => input, + }; + + let url = Url::parse(input) + .map_err(|_| err_msg(VdrErrorKind::Resolver, format!("Could not parse as URL")))?; + let mut query_pairs: HashMap = HashMap::new(); + let _query_pairs: HashMap<_, _> = url.query_pairs().into_owned().collect(); + + for (k, v) in _query_pairs.iter() { + let qp = QueryParameter::from_str(k)?; + + query_pairs.insert(qp, v.to_string()); + } + + let captures = did_regex.captures(input_without_query.trim()); + match captures { + Some(cap) => { + let did = DidUrl { + namespace: cap.get(1).unwrap().as_str().to_string(), + id: DidValue::new(cap.get(2).unwrap().as_str(), Option::None), + path: cap.get(3).and_then(|p| Some(p.as_str().to_string())), + query: query_pairs, + url: input.to_string(), + }; + Ok(did) + } + None => Err(err_msg( + VdrErrorKind::Resolver, + format!("Invalid DID URL {}", input), + )), + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn parse_unknown_ledger_object_fails() { + let _err = LedgerObject::from_str("/anoncreds/v0/PANTS/npdb/4.3.4").unwrap_err(); + } + + #[test] + fn parse_unknown_object_family_fails() { + let _err = LedgerObject::from_str("/othercreds/v0/SCHEMA/npdb/4.3.4").unwrap_err(); + } + + #[test] + fn parse_unknown_anoncreds_version_fails() { + let _err = LedgerObject::from_str("/anoncreds/v5/SCHEMA/npdb/4.3.4").unwrap_err(); + } + + #[test] + fn parse_to_schema() { + assert_eq!( + LedgerObject::from_str("/anoncreds/v0/SCHEMA/npdb/4.3.4").unwrap(), + LedgerObject::Schema(Schema::new(String::from("npdb"), String::from("4.3.4"))) + ) + } + + #[test] + fn parse_to_schema_two_point_seperated_version() { + assert_eq!( + LedgerObject::from_str("/anoncreds/v0/SCHEMA/npdb/4.3").unwrap(), + LedgerObject::Schema(Schema::new(String::from("npdb"), String::from("4.3"))) + ) + } + + #[test] + fn parse_to_schema_two_digit_version() { + assert_eq!( + LedgerObject::from_str("/anoncreds/v0/SCHEMA/npdb/11.3").unwrap(), + LedgerObject::Schema(Schema::new(String::from("npdb"), String::from("11.3"))) + ) + } + + #[test] + fn parse_to_schema_without_version_fails() { + let _err = LedgerObject::from_str("/anoncreds/v0/SCHEMA/npdb").unwrap_err(); + } + + #[test] + fn parse_to_schema_with_one_digit_version_fails() { + let _err = LedgerObject::from_str("/anoncreds/v0/SCHEMA/npdb/4").unwrap_err(); + } + + #[test] + fn parse_to_claim_def() { + assert_eq!( + LedgerObject::from_str("/anoncreds/v0/CLAIM_DEF/23452/npdb").unwrap(), + LedgerObject::ClaimDef(ClaimDef::new(23452, String::from("npdb"))) + ) + } + + #[test] + fn parse_to_claim_def_without_seq_no_fails() { + let _err = LedgerObject::from_str("/anoncreds/v0/CLAIM_DEF/npdb").unwrap_err(); + } + + #[test] + fn parse_to_claim_def_with_seq_no_as_string_fails() { + let _err = LedgerObject::from_str("/anoncreds/v0/CLAIM_DEF/myseqno/npdb").unwrap_err(); + } + + #[test] + fn parse_to_rev_reg_entry() { + assert_eq!( + LedgerObject::from_str("/anoncreds/v0/REV_REG_ENTRY/104/revocable/a4e25e54").unwrap(), + LedgerObject::RevRegEntry(RevReg::new( + 104, + String::from("revocable"), + String::from("a4e25e54") + )) + ) + } + + #[test] + fn parse_to_rev_reg_def() { + assert_eq!( + LedgerObject::from_str( + "/anoncreds/v0/REV_REG_DEF/104/revocable/a4e25e54-e028-462b-a4d6-b1d1712d51a1" + ) + .unwrap(), + LedgerObject::RevRegDef(RevReg::new( + 104, + String::from("revocable"), + String::from("a4e25e54-e028-462b-a4d6-b1d1712d51a1") + )) + ) + } + + mod did_syntax_tests { + + use super::*; + + #[test] + fn did_syntax_tests() { + let _err = DidUrl::from_str("did:indy:onlynamespace").unwrap_err(); + + assert_eq!( + DidUrl::from_str("did:indy:idunion:BDrEcHc8Tb4Lb2VyQZWEDE").unwrap(), + DidUrl { + namespace: String::from("idunion"), + id: DidValue::new("BDrEcHc8Tb4Lb2VyQZWEDE", None), + path: None, + query: HashMap::new(), + url: String::from("did:indy:idunion:BDrEcHc8Tb4Lb2VyQZWEDE"), + } + ); + + assert_eq!( + DidUrl::from_str("did:indy:sovrin:staging:6cgbu8ZPoWTnR5Rv5JcSMB").unwrap(), + DidUrl { + namespace: String::from("sovrin:staging"), + id: DidValue::new("6cgbu8ZPoWTnR5Rv5JcSMB", None), + path: None, + query: HashMap::new(), + url: String::from("did:indy:sovrin:staging:6cgbu8ZPoWTnR5Rv5JcSMB"), + } + ); + + let _err = DidUrl::from_str("did:indy:illegal:third:namespace:1111111111111111111111") + .unwrap_err(); + + let _err = DidUrl::from_str("did:indy:test:12345678901234567890").unwrap_err(); + let _err = DidUrl::from_str("did:indy:test:12345678901234567890123").unwrap_err(); + + // fails because contains characters not in base58 + // 0 + let _err = DidUrl::from_str("did:indy:test:0cgbu8ZPoWTnR5Rv5JcSMB").unwrap_err(); + // O + let _err = DidUrl::from_str("did:indy:test:Ocgbu8ZPoWTnR5Rv5JcSMB").unwrap_err(); + // I + let _err = DidUrl::from_str("did:indy:test:Icgbu8ZPoWTnR5Rv5JcSMB").unwrap_err(); + // l + let _err = DidUrl::from_str("did:indy:test:lcgbu8ZPoWTnR5Rv5JcSMB").unwrap_err(); + } + + #[test] + fn parse_did_url_with_query_parameter() { + let mut q = HashMap::new(); + q.insert(QueryParameter::VersionId, String::from("1")); + + assert_eq!( + DidUrl::from_str("did:indy:idunion:BDrEcHc8Tb4Lb2VyQZWEDE?versionId=1").unwrap(), + DidUrl { + namespace: String::from("idunion"), + id: DidValue::new("BDrEcHc8Tb4Lb2VyQZWEDE", None), + path: None, + query: q, + url: String::from("did:indy:idunion:BDrEcHc8Tb4Lb2VyQZWEDE?versionId=1"), + } + ); + } + + #[test] + fn parse_did_url_fails_with_arbitrary_query_parameter() { + let _err = DidUrl::from_str("did:indy:idunion:BDrEcHc8Tb4Lb2VyQZWEDE?hello=world").unwrap_err(); + } + + #[test] + fn parse_did_url_with_path() { + assert_eq!( + DidUrl::from_str("did:indy:idunion:Dk1fRRTtNazyMuK2cr64wp/anoncreds/v0/REV_REG_DEF/104/revocable/a4e25e54-e028-462b-a4d6-b1d1712d51a1") + .unwrap(), + DidUrl { + namespace: String::from("idunion"), + id: DidValue::new("Dk1fRRTtNazyMuK2cr64wp", None), + path: Some(String::from("/anoncreds/v0/REV_REG_DEF/104/revocable/a4e25e54-e028-462b-a4d6-b1d1712d51a1")), + query: HashMap::new(), + url: String::from( + "did:indy:idunion:Dk1fRRTtNazyMuK2cr64wp/anoncreds/v0/REV_REG_DEF/104/revocable/a4e25e54-e028-462b-a4d6-b1d1712d51a1" + ), + } + ); + } + + #[test] + fn parse_did_url_with_path_and_query() { + let mut q = HashMap::new(); + q.insert(QueryParameter::VersionTime, String::from("someXmlDateTime")); + + assert_eq!( + DidUrl::from_str("did:indy:idunion:Dk1fRRTtNazyMuK2cr64wp/anoncreds/v0/REV_REG_DEF/104/revocable/a4e25e54-e028-462b-a4d6-b1d1712d51a1?versionTime=someXmlDateTime") + .unwrap(), + DidUrl { + namespace: String::from("idunion"), + id: DidValue::new("Dk1fRRTtNazyMuK2cr64wp", None), + path: Some(String::from("/anoncreds/v0/REV_REG_DEF/104/revocable/a4e25e54-e028-462b-a4d6-b1d1712d51a1")), + query: q, + url: String::from( + "did:indy:idunion:Dk1fRRTtNazyMuK2cr64wp/anoncreds/v0/REV_REG_DEF/104/revocable/a4e25e54-e028-462b-a4d6-b1d1712d51a1?versionTime=someXmlDateTime" + ), + } + ); + } + } +} diff --git a/libindy_vdr/src/resolver/did_document.rs b/libindy_vdr/src/resolver/did_document.rs new file mode 100644 index 00000000..27c18f0f --- /dev/null +++ b/libindy_vdr/src/resolver/did_document.rs @@ -0,0 +1,542 @@ +use crate::common::error::prelude::*; +use crate::ledger::responses::Endpoint; +use serde::{Deserialize, Serialize}; +use serde_json::{json, Value}; + +pub const LEGACY_INDY_SERVICE: &str = "endpoint"; +pub const DID_CORE_CONTEXT: &str = "https://www.w3.org/ns/did/v1"; + +#[derive(Serialize, PartialEq, Debug)] +#[serde(rename_all = "camelCase")] +pub struct Ed25519VerificationKey2018 { + pub id: String, + pub type_: String, + pub controller: String, + pub public_key_base58: String, +} + +#[derive(Serialize, Deserialize, PartialEq, Debug)] +#[serde(rename_all = "camelCase")] +pub struct DidCommService { + pub id: String, + pub type_: String, + pub recipient_keys: Vec, + pub routing_keys: Vec, + pub priority: u8, +} + +impl DidCommService { + pub fn new(id: String, recipient_keys: Vec, routing_keys: Vec) -> Self { + Self { + id, + type_: "did-communication".to_string(), + recipient_keys, + routing_keys, + priority: 0, + } + } +} + +#[derive(Serialize, Deserialize, PartialEq, Debug)] +#[serde(rename_all = "camelCase")] +pub struct GenericService { + pub id: String, + pub type_: String, + pub service_endpoint: String, +} + +#[derive(Serialize, PartialEq, Debug)] +pub enum Service { + GenericService(GenericService), + DidCommService(DidCommService), +} + +pub struct DidDocument { + namespace: String, + id: String, + verkey: String, + endpoint: Option, + diddoc_content: Option, +} + +impl DidDocument { + pub fn new( + namespace: &str, + id: &str, + verkey: &str, + endpoint: Option, + diddoc_content: Option, + ) -> Self { + DidDocument { + namespace: namespace.to_string(), + id: id.to_string(), + verkey: expand_verkey(id, verkey), + endpoint, + diddoc_content, + } + } + + pub fn to_string(&self) -> VdrResult { + let mut doc = json!({ + "id": format!("did:indy:{}:{}", self.namespace, self.id), + "verificationMethod": [Ed25519VerificationKey2018 { + id: format!("did:indy:{}:{}#verkey", self.namespace, self.id), + type_: format!("Ed25519VerificationKey2018"), + controller: format!("did:indy:{}:{}", self.namespace, self.id), + public_key_base58: format!("{}", self.verkey), + }], + "authentication": [format!("did:indy:{}:{}#verkey", self.namespace, self.id)], + }); + + if self.diddoc_content.is_some() { + let is_valid = validate_diddoc_content(&(self.diddoc_content.as_ref().unwrap())); + + if is_valid { + merge_diddoc(&mut doc, self.diddoc_content.as_ref().unwrap()); + } else { + return Err(err_msg(VdrErrorKind::Resolver, "Invalid DIDdoc Content")); + } + + // Handling of legacy services + } else if self.endpoint.is_some() { + let mut services = Vec::new(); + let endpoints = self.endpoint.clone(); + for (service, service_endpoint) in endpoints.unwrap().endpoint.into_iter() { + let s = match service.as_str() { + LEGACY_INDY_SERVICE => json!(DidCommService::new( + format!("did:indy:{}:{}#did-communication", self.namespace, self.id), + vec![format!("did:indy:{}:{}#verkey", self.namespace, self.id)], + vec![], + )), + type_ => json!(GenericService { + id: format!("did:indy:{}:{}#{}", self.namespace, self.id, type_), + type_: type_.to_string(), + service_endpoint, + }), + }; + services.push(s); + } + + if let Value::Object(ref mut map) = doc { + map.insert("service".to_string(), serde_json::Value::Array(services)); + } + } + + Ok(serde_json::to_string_pretty(&doc).unwrap()) + } +} + +fn validate_context(context: &str) -> bool { + context == DID_CORE_CONTEXT +} + +fn validate_diddoc_content(diddoc_content: &Value) -> bool { + if diddoc_content.get("id").is_some() { + false + } else if diddoc_content.get("@context").is_some() { + let context = diddoc_content.get("@context").unwrap(); + + if context.is_string() { + validate_context(context.as_str().unwrap()) + } else if context.is_array() { + let mut buf = false; + for c in context.as_array().unwrap() { + if buf { + return buf; + } + buf = validate_context(c.as_str().unwrap()); + } + buf + } else { + false + } + } else { + true + } +} + +fn merge_diddoc(base: &mut Value, content: &Value) { + match (base, content) { + (Value::Object(base), Value::Object(content)) => { + for (k, v) in content { + if k == "authentication" || k == "verificationMethod" { + let mut _tmp = base[k].as_array().unwrap().to_owned(); + _tmp.append(&mut v.as_array().unwrap_or(&vec![v.to_owned()]).to_owned()); + base[k] = Value::from(_tmp); + } else { + merge_diddoc(base.entry(k).or_insert(Value::Null), v); + } + } + } + (a, b) => *a = b.clone(), + } +} + +fn expand_verkey(id: &str, verkey: &str) -> String { + if verkey.starts_with('~') { + format!("{}{}", id, &verkey[1..]) + } else { + verkey.to_string() + } +} + +#[cfg(test)] +mod tests { + use std::collections::HashMap; + + use super::*; + + #[test] + fn serialze_diddoc_without_diddoc_content() { + let doc = DidDocument::new( + "idunion", + "QowxFtwciWceMFr7WbwnM", + "67yDXtw6MK2D7V2kFSL7uMH6qTtrEbNtkdiTkbk9YJBk", + None, + None, + ); + + let serialized = json!({ + "id": "did:indy:idunion:QowxFtwciWceMFr7WbwnM", + "verificationMethod": [{ + "id": "did:indy:idunion:QowxFtwciWceMFr7WbwnM#verkey", + "type": "Ed25519VerificationKey2018", + "controller": "did:indy:idunion:QowxFtwciWceMFr7WbwnM", + "publicKeyBase58": "67yDXtw6MK2D7V2kFSL7uMH6qTtrEbNtkdiTkbk9YJBk", + }], + "authentication": ["did:indy:idunion:QowxFtwciWceMFr7WbwnM#verkey"], + }); + + // Need to compare serde value instead of string, since elements might be in + // different order. + + let v_from_doc: Value = serde_json::from_str(doc.to_string().unwrap().as_str()).unwrap(); + let v_from_serialized: Value = + serde_json::from_str(serde_json::to_string(&serialized).unwrap().as_str()).unwrap(); + + assert_eq!(v_from_doc, v_from_serialized) + } + + #[test] + fn serialze_diddoc_with_diddoc_content() { + let diddoc_content = json!({ + "@context" : [ + "https://www.w3.org/ns/did/v1", + "https://identity.foundation/didcomm-messaging/service-endpoint/v1" + ], + "service": [ + { + "id": "did:indy:idunion:QowxFtwciWceMFr7WbwnM#did-communication", + "type": "did-communication", + "serviceEndpoint": "https://example.com", + "recipientKeys": [ "#verkey" ], + "routingKeys": [ ], + "priority": 0 + } + ] + }); + + let doc = DidDocument::new( + "idunion", + "QowxFtwciWceMFr7WbwnM", + "67yDXtw6MK2D7V2kFSL7uMH6qTtrEbNtkdiTkbk9YJBk", + None, + Some(diddoc_content), + ); + + let serialized = json!({ + "@context": [ + "https://www.w3.org/ns/did/v1", + "https://identity.foundation/didcomm-messaging/service-endpoint/v1" + ], + "id": "did:indy:idunion:QowxFtwciWceMFr7WbwnM", + "verificationMethod": [{ + "id": "did:indy:idunion:QowxFtwciWceMFr7WbwnM#verkey", + "type": "Ed25519VerificationKey2018", + "controller": "did:indy:idunion:QowxFtwciWceMFr7WbwnM", + "publicKeyBase58": "67yDXtw6MK2D7V2kFSL7uMH6qTtrEbNtkdiTkbk9YJBk", + }], + "authentication": ["did:indy:idunion:QowxFtwciWceMFr7WbwnM#verkey"], + "service": [{ + "id": "did:indy:idunion:QowxFtwciWceMFr7WbwnM#did-communication", + "type": "did-communication", + "serviceEndpoint": "https://example.com", + "recipientKeys": [ "#verkey" ], + "routingKeys": [], + "priority": 0 + }] + + }); + + let v_from_doc: Value = serde_json::from_str(doc.to_string().unwrap().as_str()).unwrap(); + let v_from_serialized: Value = + serde_json::from_str(serde_json::to_string(&serialized).unwrap().as_str()).unwrap(); + + assert_eq!(v_from_doc, v_from_serialized) + } + + #[test] + fn serialze_diddoc_with_diddoc_content_with_additional_auth() { + let diddoc_content = json!({ + "@context" : [ + "https://www.w3.org/ns/did/v1", + "https://identity.foundation/didcomm-messaging/service-endpoint/v1" + ], + "verificationMethod": [{ + "id": "did:indy:idunion:QowxFtwciWceMFr7WbwnM#keys-2", + "type": "Ed25519VerificationKey2018", + "controller": "did:indy:idunion:QowxFtwciWceMFr7WbwnM", + "publicKeyBase58": "67yDXtw6MK2D7V2kFSL7uMH6qTtrEbNtkdiTkbk9YJBc", + }], + "authentication": ["did:indy:idunion:QowxFtwciWceMFr7WbwnM#keys-2"], + "service": [{ + "id": "did:indy:idunion:QowxFtwciWceMFr7WbwnM#did-communication", + "type": "did-communication", + "serviceEndpoint": "https://example.com", + "recipientKeys": [ "#verkey" ], + "routingKeys": [], + "priority": 0 + }] + }); + + let doc = DidDocument::new( + "idunion", + "QowxFtwciWceMFr7WbwnM", + "67yDXtw6MK2D7V2kFSL7uMH6qTtrEbNtkdiTkbk9YJBk", + None, + Some(diddoc_content), + ); + + let serialized = json!({ + "@context": [ + "https://www.w3.org/ns/did/v1", + "https://identity.foundation/didcomm-messaging/service-endpoint/v1" + ], + "id": "did:indy:idunion:QowxFtwciWceMFr7WbwnM", + "verificationMethod": [{ + "id": "did:indy:idunion:QowxFtwciWceMFr7WbwnM#verkey", + "type": "Ed25519VerificationKey2018", + "controller": "did:indy:idunion:QowxFtwciWceMFr7WbwnM", + "publicKeyBase58": "67yDXtw6MK2D7V2kFSL7uMH6qTtrEbNtkdiTkbk9YJBk", + },{ + "id": "did:indy:idunion:QowxFtwciWceMFr7WbwnM#keys-2", + "type": "Ed25519VerificationKey2018", + "controller": "did:indy:idunion:QowxFtwciWceMFr7WbwnM", + "publicKeyBase58": "67yDXtw6MK2D7V2kFSL7uMH6qTtrEbNtkdiTkbk9YJBc", + }], + "authentication": [ + "did:indy:idunion:QowxFtwciWceMFr7WbwnM#verkey", + "did:indy:idunion:QowxFtwciWceMFr7WbwnM#keys-2"], + "service": [{ + "id": "did:indy:idunion:QowxFtwciWceMFr7WbwnM#did-communication", + "type": "did-communication", + "serviceEndpoint": "https://example.com", + "recipientKeys": [ "#verkey" ], + "routingKeys": [], + "priority": 0 + }] + + }); + + let v_from_doc: Value = serde_json::from_str(doc.to_string().unwrap().as_str()).unwrap(); + let v_from_serialized: Value = + serde_json::from_str(serde_json::to_string(&serialized).unwrap().as_str()).unwrap(); + + assert_eq!(v_from_doc, v_from_serialized) + } + + #[test] + fn serialze_diddoc_with_diddoc_content_with_additional_auth_as_string() { + let diddoc_content = json!({ + "@context" : [ + "https://www.w3.org/ns/did/v1", + "https://identity.foundation/didcomm-messaging/service-endpoint/v1" + ], + "verificationMethod": [{ + "id": "did:indy:idunion:QowxFtwciWceMFr7WbwnM#keys-2", + "type": "Ed25519VerificationKey2018", + "controller": "did:indy:idunion:QowxFtwciWceMFr7WbwnM", + "publicKeyBase58": "67yDXtw6MK2D7V2kFSL7uMH6qTtrEbNtkdiTkbk9YJBc", + }], + "authentication": "did:indy:idunion:QowxFtwciWceMFr7WbwnM#keys-2", + "service": [{ + "id": "did:indy:idunion:QowxFtwciWceMFr7WbwnM#did-communication", + "type": "did-communication", + "serviceEndpoint": "https://example.com", + "recipientKeys": [ "#verkey" ], + "routingKeys": [], + "priority": 0 + }] + }); + + let doc = DidDocument::new( + "idunion", + "QowxFtwciWceMFr7WbwnM", + "67yDXtw6MK2D7V2kFSL7uMH6qTtrEbNtkdiTkbk9YJBk", + None, + Some(diddoc_content), + ); + + let serialized = json!({ + "@context": [ + "https://www.w3.org/ns/did/v1", + "https://identity.foundation/didcomm-messaging/service-endpoint/v1" + ], + "id": "did:indy:idunion:QowxFtwciWceMFr7WbwnM", + "verificationMethod": [{ + "id": "did:indy:idunion:QowxFtwciWceMFr7WbwnM#verkey", + "type": "Ed25519VerificationKey2018", + "controller": "did:indy:idunion:QowxFtwciWceMFr7WbwnM", + "publicKeyBase58": "67yDXtw6MK2D7V2kFSL7uMH6qTtrEbNtkdiTkbk9YJBk", + },{ + "id": "did:indy:idunion:QowxFtwciWceMFr7WbwnM#keys-2", + "type": "Ed25519VerificationKey2018", + "controller": "did:indy:idunion:QowxFtwciWceMFr7WbwnM", + "publicKeyBase58": "67yDXtw6MK2D7V2kFSL7uMH6qTtrEbNtkdiTkbk9YJBc", + }], + "authentication": [ + "did:indy:idunion:QowxFtwciWceMFr7WbwnM#verkey", + "did:indy:idunion:QowxFtwciWceMFr7WbwnM#keys-2" + ], + "service": [{ + "id": "did:indy:idunion:QowxFtwciWceMFr7WbwnM#did-communication", + "type": "did-communication", + "serviceEndpoint": "https://example.com", + "recipientKeys": [ "#verkey" ], + "routingKeys": [], + "priority": 0 + }] + + }); + + let v_from_doc: Value = serde_json::from_str(doc.to_string().unwrap().as_str()).unwrap(); + let v_from_serialized: Value = + serde_json::from_str(serde_json::to_string(&serialized).unwrap().as_str()).unwrap(); + + assert_eq!(v_from_doc, v_from_serialized) + } + + #[test] + fn serialze_diddoc_with_legacy_did_comm_endpoint() { + let mut endpoint_map: HashMap = HashMap::new(); + endpoint_map.insert(String::from("endpoint"), String::from("https://agent.com")); + + let doc = DidDocument::new( + "idunion", + "QowxFtwciWceMFr7WbwnM", + "67yDXtw6MK2D7V2kFSL7uMH6qTtrEbNtkdiTkbk9YJBk", + Some(Endpoint { + endpoint: endpoint_map, + }), + None, + ); + + let serialized = json!({ + "id": "did:indy:idunion:QowxFtwciWceMFr7WbwnM", + "verificationMethod": [{ + "id": "did:indy:idunion:QowxFtwciWceMFr7WbwnM#verkey", + "type": "Ed25519VerificationKey2018", + "controller": "did:indy:idunion:QowxFtwciWceMFr7WbwnM", + "publicKeyBase58": "67yDXtw6MK2D7V2kFSL7uMH6qTtrEbNtkdiTkbk9YJBk", + }], + "authentication": ["did:indy:idunion:QowxFtwciWceMFr7WbwnM#verkey"], + "service": [{ + "id": "did:indy:idunion:QowxFtwciWceMFr7WbwnM#did-communication", + "type": "did-communication", + "recipientKeys": ["did:indy:idunion:QowxFtwciWceMFr7WbwnM#verkey"], + "routingKeys": [], + "priority": 0 + }] + + }); + + let v_from_doc: Value = serde_json::from_str(doc.to_string().unwrap().as_str()).unwrap(); + let v_from_serialized: Value = + serde_json::from_str(serde_json::to_string(&serialized).unwrap().as_str()).unwrap(); + + assert_eq!(v_from_doc, v_from_serialized) + } + + #[test] + fn serialze_diddoc_with_multiple_legacy_endpoints() { + let mut endpoint_map: HashMap = HashMap::new(); + endpoint_map.insert(String::from("endpoint"), String::from("https://agent.com")); + endpoint_map.insert( + String::from("profile"), + String::from("https://agent.com/profile"), + ); + + let doc = DidDocument::new( + "idunion", + "QowxFtwciWceMFr7WbwnM", + "67yDXtw6MK2D7V2kFSL7uMH6qTtrEbNtkdiTkbk9YJBk", + Some(Endpoint { + endpoint: endpoint_map, + }), + None, + ); + + let v_from_doc: Value = serde_json::from_str(doc.to_string().unwrap().as_str()).unwrap(); + + assert_eq!(2, v_from_doc["service"].as_array().unwrap().len()) + } + + #[test] + fn validate_diddoc_with_context_as_string() { + let diddoc_content = json!({ + "@context" : "https://www.w3.org/ns/did/v1" + }); + assert!(validate_diddoc_content(&diddoc_content)) + } + + #[test] + fn validate_diddoc_without_context() { + let diddoc_content = json!({ + "service": [ + { + "id": "did:indy:sovrin:123456#did-communication", + "type": "did-communication", + "serviceEndpoint": "https://example.com", + "recipientKeys": [ "#verkey" ], + "routingKeys": [ ] + } + ] + }); + assert!(validate_diddoc_content(&diddoc_content)) + } + + #[test] + fn validate_diddoc_with_context_as_array() { + let diddoc_content = json!({ + "@context" : [ + "https://www.w3.org/ns/did/v1", + "https://identity.foundation/didcomm-messaging/service-endpoint/v1" + ], + }); + assert!(validate_diddoc_content(&diddoc_content)) + } + + #[test] + fn validate_diddoc_with_empty_context_as_array() { + let diddoc_content = json!({ + "@context" : [], + }); + assert!(!validate_diddoc_content(&diddoc_content)) + } + + #[test] + fn validate_diddoc_with_empty_context_as_string() { + let diddoc_content = json!({ + "@context" : "", + }); + assert!(!validate_diddoc_content(&diddoc_content)) + } + + #[test] + fn validate_diddoc_with_id() { + let diddoc_content = json!({ + "id" : "sg3535sd", + }); + assert!(!validate_diddoc_content(&diddoc_content)) + } +} diff --git a/libindy_vdr/src/resolver/mod.rs b/libindy_vdr/src/resolver/mod.rs new file mode 100644 index 00000000..1fa5684a --- /dev/null +++ b/libindy_vdr/src/resolver/mod.rs @@ -0,0 +1,4 @@ +pub mod resolver; + +pub mod did; +pub mod did_document; \ No newline at end of file diff --git a/libindy_vdr/src/resolver/resolver.rs b/libindy_vdr/src/resolver/resolver.rs new file mode 100644 index 00000000..c8256b60 --- /dev/null +++ b/libindy_vdr/src/resolver/resolver.rs @@ -0,0 +1,336 @@ +use chrono::{DateTime, Utc}; + +use crate::utils::Qualifiable; +use futures_executor::block_on; +use serde_json::Value; + +use super::did::{DidUrl, LedgerObject, QueryParameter}; +use super::did_document::{DidDocument, LEGACY_INDY_SERVICE}; +use crate::common::error::prelude::*; +use crate::ledger::responses::{Endpoint, GetNymResultV1}; + +use crate::ledger::constants; +use crate::ledger::identifiers::{CredentialDefinitionId, RevocationRegistryId, SchemaId}; +use crate::ledger::RequestBuilder; +use crate::pool::helpers::perform_ledger_request; +use crate::pool::{Pool, PreparedRequest, RequestResult, TimingResult}; +use crate::utils::did::DidValue; + +// DID (URL) Resolver for did:indy method +pub struct Resolver { + pool: T, +} + +impl Resolver { + pub fn new(pool: T) -> Resolver { + Resolver { pool } + } + + pub fn resolve(&self, did: &str) -> VdrResult { + let did_url = DidUrl::from_str(did)?; + + let builder = self.pool.get_request_builder(); + let request = build_request(&did_url, &builder)?; + + let ledger_data = handle_request(&self.pool, &request)?; + let data = parse_ledger_data(&ledger_data)?; + + let result = match request.txn_type.as_str() { + constants::GET_NYM => { + let get_nym_result: GetNymResultV1 = + serde_json::from_str(data.as_str().unwrap()) + .map_err(|_| err_msg(VdrErrorKind::Resolver, "Could not parse NYM data"))?; + + let endpoint: Option = if get_nym_result.diddoc_content.is_none() { + // Legacy: Try to find an attached ATTRIBUTE transacation with raw endpoint + self.fetch_legacy_endpoint(&did_url.id).ok() + } else { + None + }; + + let did_document = DidDocument::new( + &did_url.namespace, + &get_nym_result.dest, + &get_nym_result.verkey, + endpoint, + None, + ); + did_document.to_string()? + } + // other ledger objects + _ => data.to_string(), + }; + + Ok(result) + } + + fn fetch_legacy_endpoint(&self, did: &DidValue) -> VdrResult { + let builder = self.pool.get_request_builder(); + let request = builder.build_get_attrib_request( + None, + did, + Some(String::from(LEGACY_INDY_SERVICE)), + None, + None, + )?; + let ledger_data = handle_request(&self.pool, &request)?; + let endpoint_data = parse_ledger_data(&ledger_data)?; + let endpoint_data: Endpoint = serde_json::from_str(endpoint_data.as_str().unwrap()) + .map_err(|_| err_msg(VdrErrorKind::Resolver, "Could not parse endpoint data"))?; + Ok(endpoint_data) + } +} + +fn build_request(did: &DidUrl, builder: &RequestBuilder) -> VdrResult { + let request = if did.path.is_some() { + match LedgerObject::from_str(did.path.as_ref().unwrap().as_str())? { + LedgerObject::Schema(schema) => builder.build_get_schema_request( + None, + &SchemaId::new(&did.id, &schema.name, &schema.version), + ), + LedgerObject::ClaimDef(claim_def) => builder.build_get_cred_def_request( + None, + &CredentialDefinitionId::from_str( + format!( + "{}:3:CL:{}:{}", + &did.id, claim_def.schema_seq_no, claim_def.name + ) + .as_str(), + ) + .unwrap(), + ), + LedgerObject::RevRegDef(rev_reg_def) => builder.build_get_revoc_reg_def_request( + None, + &RevocationRegistryId::from_str( + format!( + "{}:4:{}:3:CL:{}:{}:CL_ACCUM:{}", + &did.id, + &did.id, + rev_reg_def.schema_seq_no, + rev_reg_def.claim_def_name, + rev_reg_def.tag + ) + .as_str(), + ) + .unwrap(), + ), + LedgerObject::RevRegEntry(rev_reg_entry) => { + let timestamp = parse_or_now(did.query.get(&QueryParameter::VersionTime))?; + + builder.build_get_revoc_reg_request( + None, + &RevocationRegistryId::from_str( + format!( + "{}:4:{}:3:CL:{}:{}:CL_ACCUM:{}", + &did.id, + &did.id, + rev_reg_entry.schema_seq_no, + rev_reg_entry.claim_def_name, + rev_reg_entry.tag + ) + .as_str(), + ) + .unwrap(), + timestamp, + ) + } + LedgerObject::RevRegDelta(rev_reg_delta) => { + let mut from: Option = None; + if did.query.contains_key(&QueryParameter::From) { + from = did + .query + .get(&QueryParameter::From) + .and_then(|d| DateTime::parse_from_rfc3339(d).ok()) + .and_then(|d| Some(d.timestamp())); + } + + let to = parse_or_now(did.query.get(&QueryParameter::To))?; + + builder.build_get_revoc_reg_delta_request( + None, + &RevocationRegistryId::from_str( + format!( + "{}:4:{}:3:CL:{}:{}:CL_ACCUM:{}", + &did.id, + &did.id, + rev_reg_delta.schema_seq_no, + rev_reg_delta.claim_def_name, + rev_reg_delta.tag + ) + .as_str(), + ) + .unwrap(), + from, + to, + ) + } + } + } else { + // TODO: Use with new get nym request + + let _seq_no: Option = did + .query + .get(&QueryParameter::VersionId) + .and_then(|v| v.parse().ok()); + let _timestamp: Option = did + .query + .get(&QueryParameter::VersionTime) + .and_then(|d| DateTime::parse_from_rfc3339(d).ok()) + .and_then(|d| Some(d.timestamp())); + + builder.build_get_nym_request(Option::None, &did.id) + }; + request +} + +fn handle_request(pool: &T, request: &PreparedRequest) -> VdrResult { + let (result, _timing) = block_on(request_transaction(pool, &request))?; + match result { + RequestResult::Reply(data) => Ok(data), + RequestResult::Failed(error) => Err(error), + } +} + +async fn request_transaction( + pool: &T, + request: &PreparedRequest, +) -> VdrResult<(RequestResult, Option)> { + perform_ledger_request(pool, &request).await +} + +fn parse_ledger_data(ledger_data: &str) -> VdrResult { + let v: Value = serde_json::from_str(&ledger_data) + .map_err(|_| err_msg(VdrErrorKind::Resolver, "Could not parse ledger response"))?; + let data: &Value = &v["result"]["data"]; + if *data == Value::Null { + Err(err_msg( + VdrErrorKind::Resolver, + format!("Empty data in ledger response"), + )) + } else { + Ok(data.to_owned()) + } +} + +fn parse_or_now(datetime: Option<&String>) -> VdrResult { + match datetime { + Some(datetime) => { + let dt = DateTime::parse_from_rfc3339(datetime).map_err(|_| { + err_msg( + VdrErrorKind::Resolver, + format!("Could not parse datetime {}", datetime), + ) + })?; + Ok(dt.timestamp()) + } + None => Ok(Utc::now().timestamp()), + } +} + +#[cfg(test)] +mod tests { + + use super::*; + use rstest::*; + + use crate::pool::ProtocolVersion; + + #[fixture] + fn request_builder() -> RequestBuilder { + RequestBuilder::new(ProtocolVersion::Node1_4) + } + + #[rstest] + fn build_get_revoc_reg_request_from_version_time(request_builder: RequestBuilder) { + let datetime_as_str = "2020-12-20T19:17:47Z"; + let did_url_as_str = format!("did:indy:idunion:Dk1fRRTtNazyMuK2cr64wp/anoncreds/v0/REV_REG_ENTRY/104/revocable/a4e25e54?versionTime={}",datetime_as_str); + let did_url = DidUrl::from_str(&did_url_as_str).unwrap(); + let request = build_request(&did_url, &request_builder).unwrap(); + let timestamp = (*(request.req_json).get("operation").unwrap()) + .get("timestamp") + .unwrap() + .as_u64() + .unwrap() as i64; + assert_eq!(constants::GET_REVOC_REG, request.txn_type); + + assert_eq!( + DateTime::parse_from_rfc3339(datetime_as_str) + .unwrap() + .timestamp(), + timestamp + ); + } + + #[rstest] + fn build_get_revoc_reg_without_version_time(request_builder: RequestBuilder) { + let now = chrono::Utc::now().timestamp(); + + let did_url_as_str = "did:indy:idunion:Dk1fRRTtNazyMuK2cr64wp/anoncreds/v0/REV_REG_ENTRY/104/revocable/a4e25e54"; + let did_url = DidUrl::from_str(did_url_as_str).unwrap(); + let request = build_request(&did_url, &request_builder).unwrap(); + let timestamp = (*(request.req_json).get("operation").unwrap()) + .get("timestamp") + .unwrap() + .as_u64() + .unwrap() as i64; + + assert_eq!(constants::GET_REVOC_REG, request.txn_type); + assert!(timestamp >= now); + } + + #[rstest] + fn build_get_revoc_reg_request_fails_with_unparsable_version_time( + request_builder: RequestBuilder, + ) { + let datetime_as_str = "20201220T19:17:47Z"; + let did_url_as_str = format!("did:indy:idunion:Dk1fRRTtNazyMuK2cr64wp/anoncreds/v0/REV_REG_ENTRY/104/revocable/a4e25e54?versionTime={}",datetime_as_str); + let did_url = DidUrl::from_str(&did_url_as_str).unwrap(); + let _err = build_request(&did_url, &request_builder).unwrap_err(); + } + + #[rstest] + fn build_get_revoc_reg_delta_request_with_from_to(request_builder: RequestBuilder) { + let from_as_str = "2019-12-20T19:17:47Z"; + let to_as_str = "2020-12-20T19:17:47Z"; + let did_url_as_str = format!("did:indy:idunion:Dk1fRRTtNazyMuK2cr64wp/anoncreds/v0/REV_REG_DELTA/104/revocable/a4e25e54?from={}&to={}",from_as_str, to_as_str); + let did_url = DidUrl::from_str(&did_url_as_str).unwrap(); + let request = build_request(&did_url, &request_builder).unwrap(); + assert_eq!(request.txn_type, constants::GET_REVOC_REG_DELTA); + } + + #[rstest] + fn build_get_revoc_reg_delta_request_with_from_only(request_builder: RequestBuilder) { + let now = chrono::Utc::now().timestamp(); + let from_as_str = "2019-12-20T19:17:47Z"; + let did_url_as_str = format!("did:indy:idunion:Dk1fRRTtNazyMuK2cr64wp/anoncreds/v0/REV_REG_DELTA/104/revocable/a4e25e54?from={}",from_as_str); + let did_url = DidUrl::from_str(&did_url_as_str).unwrap(); + let request = build_request(&did_url, &request_builder).unwrap(); + + let to = (*(request.req_json).get("operation").unwrap()) + .get("to") + .unwrap() + .as_u64() + .unwrap() as i64; + assert_eq!(request.txn_type, constants::GET_REVOC_REG_DELTA); + assert!(to >= now) + } + + #[rstest] + fn build_get_revoc_reg_delta_request_without_parameter(request_builder: RequestBuilder) { + let now = chrono::Utc::now().timestamp(); + let did_url_as_str = "did:indy:idunion:Dk1fRRTtNazyMuK2cr64wp/anoncreds/v0/REV_REG_DELTA/104/revocable/a4e25e54"; + let did_url = DidUrl::from_str(did_url_as_str).unwrap(); + let request = build_request(&did_url, &request_builder).unwrap(); + + let to = (*(request.req_json).get("operation").unwrap()) + .get("to") + .unwrap() + .as_u64() + .unwrap() as i64; + + let from = (*(request.req_json).get("operation").unwrap()).get("from"); + assert_eq!(request.txn_type, constants::GET_REVOC_REG_DELTA); + assert!(from.is_none()); + assert!(to >= now); + } +} From a9a14d792763051725a666aee95394731733fc77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20W=C3=B6rner?= Date: Mon, 21 Feb 2022 15:09:29 +0100 Subject: [PATCH 016/117] new nym request MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- libindy_vdr/Cargo.toml | 1 + libindy_vdr/src/ffi/ledger.rs | 31 +++++++++++++++ libindy_vdr/src/ledger/request_builder.rs | 48 +++++++++++++++++++++-- libindy_vdr/src/ledger/requests/nym.rs | 5 +++ libindy_vdr/tests/nym.rs | 33 +++++++++++++++- libindy_vdr/tests/utils/fixtures.rs | 15 +++++++ libindy_vdr/tests/utils/helpers.rs | 3 +- 7 files changed, 129 insertions(+), 7 deletions(-) diff --git a/libindy_vdr/Cargo.toml b/libindy_vdr/Cargo.toml index 4eec64d1..dc9deac4 100644 --- a/libindy_vdr/Cargo.toml +++ b/libindy_vdr/Cargo.toml @@ -18,6 +18,7 @@ crate-type = ["staticlib", "rlib", "cdylib"] [features] ffi = ["ffi-support", "logger"] +legacy = [] logger = ["env_logger", "log"] zmq_vendored = ["zmq/vendored"] local_nodes_pool = [] diff --git a/libindy_vdr/src/ffi/ledger.rs b/libindy_vdr/src/ffi/ledger.rs index 84a050ee..c1978d86 100644 --- a/libindy_vdr/src/ffi/ledger.rs +++ b/libindy_vdr/src/ffi/ledger.rs @@ -392,6 +392,7 @@ pub extern "C" fn indy_vdr_build_get_validator_info_request( } } +#[cfg(feature = "legacy")] #[no_mangle] pub extern "C" fn indy_vdr_build_nym_request( submitter_did: FfiStr, @@ -419,6 +420,36 @@ pub extern "C" fn indy_vdr_build_nym_request( } } +#[cfg(not(feature = "legacy"))] +#[no_mangle] +pub extern "C" fn indy_vdr_build_nym_request( + submitter_did: FfiStr, + dest: FfiStr, + verkey: FfiStr, // optional + alias: FfiStr, // optional + role: FfiStr, // optional + diddoc_content: FfiStr, // optional + handle_p: *mut usize, +) -> ErrorCode { + catch_err! { + trace!("Build NYM request"); + check_useful_c_ptr!(handle_p); + let builder = get_request_builder()?; + let identifier = DidValue::from_str(submitter_did.as_str())?; + let dest = DidValue::from_str(dest.as_str())?; + let verkey = verkey.into_opt_string(); + let alias = alias.into_opt_string(); + let role = role.into_opt_string(); + let diddoc_content = serde_json::from_str(diddoc_content.as_str()).with_input_err("Error deserializing diddoc_content as JSON")?; + let req = builder.build_nym_request(&identifier, &dest, verkey, alias, role, diddoc_content)?; + let handle = add_request(req)?; + unsafe { + *handle_p = *handle; + } + Ok(ErrorCode::Success) + } +} + #[no_mangle] pub extern "C" fn indy_vdr_build_revoc_reg_def_request( submitter_did: FfiStr, diff --git a/libindy_vdr/src/ledger/request_builder.rs b/libindy_vdr/src/ledger/request_builder.rs index a4b229a6..a8e44343 100644 --- a/libindy_vdr/src/ledger/request_builder.rs +++ b/libindy_vdr/src/ledger/request_builder.rs @@ -122,8 +122,23 @@ impl RequestBuilder { )) } - /// Build a `NYM` transaction request - pub fn build_nym_request( + /// Build a new did:indy `NYM` transaction request + pub fn build_nym_request_did_indy( + &self, + identifier: &DidValue, + dest: &DidValue, + verkey: Option, + alias: Option, + role: Option, + diddoc_content: Option<::serde_json::Value>, + ) -> VdrResult { + let role = role_to_code(role)?; + let operation = NymOperation::new(dest.to_short(), verkey, alias, role, diddoc_content); + self.build(operation, Some(identifier)) + } + + /// Build a legacy `NYM` transaction request + pub fn build_nym_request_legacy( &self, identifier: &DidValue, dest: &DidValue, @@ -132,10 +147,35 @@ impl RequestBuilder { role: Option, ) -> VdrResult { let role = role_to_code(role)?; - let operation = NymOperation::new(dest.to_short(), verkey, alias, role); + let operation = NymOperation::new(dest.to_short(), verkey, alias, role, None); self.build(operation, Some(identifier)) } + #[cfg(feature = "legacy")] + pub fn build_nym_request( + &self, + identifier: &DidValue, + dest: &DidValue, + verkey: Option, + alias: Option, + role: Option, + ) -> VdrResult { + self.build_nym_request_legacy(identifier, dest, verkey, alias, role) + } + + #[cfg(not(feature = "legacy"))] + pub fn build_nym_request( + &self, + identifier: &DidValue, + dest: &DidValue, + verkey: Option, + alias: Option, + role: Option, + diddoc_content: Option, + ) -> VdrResult { + self.build_nym_request_did_indy(identifier, dest, verkey, alias, role, diddoc_content) + } + /// Build a `GET_NYM` transaction request pub fn build_get_nym_request( &self, @@ -713,7 +753,7 @@ mod tests { request_builder: RequestBuilder, ) { let request = request_builder - .build_nym_request(&_identifier(), &_dest(), None, None, None) + .build_nym_request_did_indy(&_identifier(), &_dest(), None, None, None, None) .unwrap(); assert_eq!(request.txn_type, constants::NYM); diff --git a/libindy_vdr/src/ledger/requests/nym.rs b/libindy_vdr/src/ledger/requests/nym.rs index b7704319..faf60764 100644 --- a/libindy_vdr/src/ledger/requests/nym.rs +++ b/libindy_vdr/src/ledger/requests/nym.rs @@ -6,6 +6,7 @@ use super::did::ShortDidValue; use super::{ProtocolVersion, RequestType}; use crate::ledger::constants::{ENDORSER, NETWORK_MONITOR, ROLES, ROLE_REMOVE, STEWARD, TRUSTEE}; + #[derive(Serialize, PartialEq, Debug)] pub struct NymOperation { #[serde(rename = "type")] @@ -17,6 +18,8 @@ pub struct NymOperation { pub alias: Option, #[serde(skip_serializing_if = "Option::is_none")] pub role: Option<::serde_json::Value>, + #[serde(skip_serializing_if = "Option::is_none")] + pub diddoc_content: Option<::serde_json::Value>, } impl NymOperation { @@ -25,6 +28,7 @@ impl NymOperation { verkey: Option, alias: Option, role: Option<::serde_json::Value>, + diddoc_content: Option<::serde_json::Value>, ) -> NymOperation { NymOperation { _type: Self::get_txn_type().to_string(), @@ -32,6 +36,7 @@ impl NymOperation { verkey, alias, role, + diddoc_content, } } } diff --git a/libindy_vdr/tests/nym.rs b/libindy_vdr/tests/nym.rs index 964e67b9..4a212e19 100644 --- a/libindy_vdr/tests/nym.rs +++ b/libindy_vdr/tests/nym.rs @@ -27,11 +27,31 @@ mod builder { mod nym { use super::*; + #[cfg(not(feature = "legacy"))] #[rstest] fn test_build_nym_request( request_builder: RequestBuilder, trustee_did: DidValue, my_did: DidValue, + ) { + let nym_request = request_builder + .build_nym_request(&trustee_did, &my_did, None, None, None, None) + .unwrap(); + + let expected_result = json!({ + "type": constants::NYM, + "dest": my_did, + }); + + helpers::check_request_operation(&nym_request, expected_result); + } + + #[cfg(feature = "legacy")] + #[rstest] + fn test_build_nym_request_legacy( + request_builder: RequestBuilder, + trustee_did: DidValue, + my_did: DidValue, ) { let nym_request = request_builder .build_nym_request(&trustee_did, &my_did, None, None, None) @@ -45,12 +65,15 @@ mod builder { helpers::check_request_operation(&nym_request, expected_result); } + #[cfg(not(feature = "legacy"))] #[rstest] fn test_build_nym_request_for_optional_fields( request_builder: RequestBuilder, trustee_did: DidValue, identity: Identity, + diddoc_content: serde_json::Value, ) { + let copy = diddoc_content.clone(); let nym_request = request_builder .build_nym_request( &trustee_did, @@ -58,6 +81,7 @@ mod builder { Some(identity.verkey.clone()), Some(ALIAS.to_string()), Some(ROLE.to_string()), + Some(diddoc_content) ) .unwrap(); @@ -67,11 +91,13 @@ mod builder { "verkey": identity.verkey, "alias": ALIAS, "role": role_to_code(Some(String::from(ROLE))).unwrap(), + "diddoc_content": copy, }); helpers::check_request_operation(&nym_request, expected_result); } + #[cfg(not(feature = "legacy"))] #[rstest] fn test_pool_build_nym_request_for_empty_role( request_builder: RequestBuilder, @@ -79,7 +105,7 @@ mod builder { my_did: DidValue, ) { let nym_request = request_builder - .build_nym_request(&trustee_did, &my_did, None, None, Some(String::from(""))) + .build_nym_request(&trustee_did, &my_did, None, None, Some(String::from("")), None) .unwrap(); let expected_result = json!({ @@ -91,6 +117,7 @@ mod builder { helpers::check_request_operation(&nym_request, expected_result); } + #[cfg(not(feature = "legacy"))] #[rstest] fn test_pool_build_nym_request_for_fully_qualified_dids( request_builder: RequestBuilder, @@ -99,7 +126,7 @@ mod builder { my_did: DidValue, ) { let nym_request = request_builder - .build_nym_request(&fq_trustee_did, &fq_my_did, None, None, None) + .build_nym_request(&fq_trustee_did, &fq_my_did, None, None, None, None) .unwrap(); let expected_result = json!({ @@ -110,6 +137,7 @@ mod builder { helpers::check_request_operation(&nym_request, expected_result); } + #[cfg(not(feature = "legacy"))] #[rstest] fn test_build_nym_request_works_for_invalid_role( request_builder: RequestBuilder, @@ -125,6 +153,7 @@ mod builder { Some(identity.verkey), None, Some(role.to_string()), + None ) .unwrap_err(); } diff --git a/libindy_vdr/tests/utils/fixtures.rs b/libindy_vdr/tests/utils/fixtures.rs index 0e41da1f..b4bd72b9 100644 --- a/libindy_vdr/tests/utils/fixtures.rs +++ b/libindy_vdr/tests/utils/fixtures.rs @@ -46,6 +46,21 @@ pub fn identity() -> Identity { Identity::new(None) } +#[fixture] +pub fn diddoc_content() -> serde_json::Value { + serde_json::json!({ + "service": [ + { + "id": "did:indy:sovrin:123456#did-communication", + "type": "did-communication", + "serviceEndpoint": "https://example.com", + "recipientKeys": [ "#verkey" ], + "routingKeys": [ ] + } + ] + }) +} + #[fixture] pub fn pool() -> TestPool { TestPool::new() diff --git a/libindy_vdr/tests/utils/helpers.rs b/libindy_vdr/tests/utils/helpers.rs index b01f94ea..6ac301f2 100644 --- a/libindy_vdr/tests/utils/helpers.rs +++ b/libindy_vdr/tests/utils/helpers.rs @@ -38,12 +38,13 @@ pub fn new_ledger_identity(pool: &TestPool, role: Option) -> Identity { // Send NYM let mut nym_request = pool .request_builder() - .build_nym_request( + .build_nym_request_did_indy( &trustee.did, &new_identity.did, Some(new_identity.verkey.to_string()), None, role, + None, ) .unwrap(); From 72dd9842fcf45510ccbd3905facb73159edef918 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20W=C3=B6rner?= Date: Mon, 21 Feb 2022 15:16:49 +0100 Subject: [PATCH 017/117] do not add resolver in legacy mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- libindy_vdr/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/libindy_vdr/src/lib.rs b/libindy_vdr/src/lib.rs index 1bf2a2cd..43fdc94c 100644 --- a/libindy_vdr/src/lib.rs +++ b/libindy_vdr/src/lib.rs @@ -68,6 +68,7 @@ pub mod ledger; pub mod pool; /// did:indy DID URL resolver +#[cfg(not(feature = "legacy"))] pub mod resolver; /// State proof verification for ledger read transactions pub mod state_proof; From d03fc82f26193aeff9059a84a78c9cd0c2474756 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20W=C3=B6rner?= Date: Tue, 8 Mar 2022 10:23:26 +0100 Subject: [PATCH 018/117] sync with IDunion/indy-did-resolver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- libindy_vdr/Cargo.toml | 1 + libindy_vdr/src/ledger/responses.rs | 2 +- libindy_vdr/src/resolver/did.rs | 20 +-- libindy_vdr/src/resolver/did_document.rs | 10 +- libindy_vdr/src/resolver/resolver.rs | 178 ++++++++++++++++++++--- 5 files changed, 174 insertions(+), 37 deletions(-) diff --git a/libindy_vdr/Cargo.toml b/libindy_vdr/Cargo.toml index dc9deac4..972302ba 100644 --- a/libindy_vdr/Cargo.toml +++ b/libindy_vdr/Cargo.toml @@ -50,6 +50,7 @@ serde_json = "1.0" sha3 = "0.10" thiserror = "1.0" url = "2.2.2" +urlencoding = "2.1.0" zmq = "0.9" [dependencies.ursa] diff --git a/libindy_vdr/src/ledger/responses.rs b/libindy_vdr/src/ledger/responses.rs index 4c5c3e57..5a90e7fb 100644 --- a/libindy_vdr/src/ledger/responses.rs +++ b/libindy_vdr/src/ledger/responses.rs @@ -53,7 +53,7 @@ pub struct GetClaimDefResult { pub ref_schema_version: String, } -#[derive(Clone, Deserialize, Eq, PartialEq, Debug)] +#[derive(Clone, Serialize, Deserialize, Eq, PartialEq, Debug)] pub struct Endpoint { pub endpoint: HashMap, } diff --git a/libindy_vdr/src/resolver/did.rs b/libindy_vdr/src/resolver/did.rs index b6301a2e..571942c2 100644 --- a/libindy_vdr/src/resolver/did.rs +++ b/libindy_vdr/src/resolver/did.rs @@ -2,6 +2,7 @@ use crate::common::error::prelude::*; use crate::utils::did::DidValue; use regex::Regex; use url::Url; +use urlencoding::decode; use std::collections::HashMap; @@ -17,7 +18,7 @@ static OBJECT_FAMILY_VERSION_PATTERN: &str = "([a-zA-Z0-9]*)"; static ANONCREDSV0_OBJECTS_PATTERN: &str = "(SCHEMA|CLAIM_DEF|REV_REG_DEF|REV_REG_ENTRY|REV_REG_DELTA)"; -static CLIENT_DEFINED_NAME_PATTERN: &str = "([\\w-]*)"; +static CLIENT_DEFINED_NAME_PATTERN: &str = "([\\w -]*)"; static SEQ_NO_PATTERN: &str = "(\\d*)"; static VERSION_PATTERN: &str = "((\\d*\\.){1,2}\\d*)"; @@ -337,20 +338,14 @@ impl DidUrl { pub fn from_str(input: &str) -> VdrResult { let did_regex = Regex::new( format!( - r"{}:{}:{}(.+)?$", + r"{}:{}:{}([^\?]+)?(?:\?(.+))?$", DID_INDY_PREFIX, NAMESPACE_PATTERN, INDY_UNQUALIFIED_DID_PATTERN ) .as_str(), ) .unwrap(); - let input_without_query = match input.split_once("?") { - Some(s) => s.0, - None => input, - }; - - let url = Url::parse(input) - .map_err(|_| err_msg(VdrErrorKind::Resolver, format!("Could not parse as URL")))?; + let url = Url::parse(input).map_err(|_| err_msg(VdrErrorKind::Resolver, "Could not parse DID Url"))?; let mut query_pairs: HashMap = HashMap::new(); let _query_pairs: HashMap<_, _> = url.query_pairs().into_owned().collect(); @@ -360,13 +355,13 @@ impl DidUrl { query_pairs.insert(qp, v.to_string()); } - let captures = did_regex.captures(input_without_query.trim()); + let captures = did_regex.captures(input.trim()); match captures { Some(cap) => { let did = DidUrl { namespace: cap.get(1).unwrap().as_str().to_string(), id: DidValue::new(cap.get(2).unwrap().as_str(), Option::None), - path: cap.get(3).and_then(|p| Some(p.as_str().to_string())), + path: cap.get(3).and_then(|p| Some(decode(p.as_str()).unwrap().to_string())), query: query_pairs, url: input.to_string(), }; @@ -544,7 +539,8 @@ mod tests { #[test] fn parse_did_url_fails_with_arbitrary_query_parameter() { - let _err = DidUrl::from_str("did:indy:idunion:BDrEcHc8Tb4Lb2VyQZWEDE?hello=world").unwrap_err(); + let _err = DidUrl::from_str("did:indy:idunion:BDrEcHc8Tb4Lb2VyQZWEDE?hello=world") + .unwrap_err(); } #[test] diff --git a/libindy_vdr/src/resolver/did_document.rs b/libindy_vdr/src/resolver/did_document.rs index 27c18f0f..4af3f1a3 100644 --- a/libindy_vdr/src/resolver/did_document.rs +++ b/libindy_vdr/src/resolver/did_document.rs @@ -51,6 +51,9 @@ pub enum Service { DidCommService(DidCommService), } + +#[derive(Serialize, Deserialize, PartialEq, Debug)] +#[serde(rename_all = "camelCase")] pub struct DidDocument { namespace: String, id: String, @@ -76,7 +79,7 @@ impl DidDocument { } } - pub fn to_string(&self) -> VdrResult { + pub fn to_value(&self) -> VdrResult { let mut doc = json!({ "id": format!("did:indy:{}:{}", self.namespace, self.id), "verificationMethod": [Ed25519VerificationKey2018 { @@ -122,6 +125,11 @@ impl DidDocument { } } + Ok(doc) + } + + pub fn to_string(&self) -> VdrResult { + let doc = self.to_value()?; Ok(serde_json::to_string_pretty(&doc).unwrap()) } } diff --git a/libindy_vdr/src/resolver/resolver.rs b/libindy_vdr/src/resolver/resolver.rs index c8256b60..51cf4cf3 100644 --- a/libindy_vdr/src/resolver/resolver.rs +++ b/libindy_vdr/src/resolver/resolver.rs @@ -16,6 +16,36 @@ use crate::pool::helpers::perform_ledger_request; use crate::pool::{Pool, PreparedRequest, RequestResult, TimingResult}; use crate::utils::did::DidValue; +#[derive(Serialize, Deserialize, PartialEq, Debug)] +#[serde(rename_all = "camelCase")] +pub enum Result { + DidDocument(DidDocument), + Content(Value), +} + +#[derive(Serialize, Deserialize, PartialEq, Debug)] +#[serde(rename_all = "camelCase")] +pub struct ContentMetadata { + node_response: Value, + object_type: String, +} + +#[derive(Serialize, Deserialize, PartialEq, Debug)] +#[serde(rename_all = "camelCase")] +pub struct ResolutionResult { + did_resolution_metadata: Option, + did_document: Option, + did_document_metadata: Option, +} + +#[derive(Serialize, Deserialize, PartialEq, Debug)] +#[serde(rename_all = "camelCase")] +pub struct DereferencingResult { + dereferencing_metadata: Option, + content_stream: Option, + content_metadata: Option, +} + // DID (URL) Resolver for did:indy method pub struct Resolver { pool: T, @@ -26,7 +56,40 @@ impl Resolver { Resolver { pool } } + pub fn dereference(&self, did_url: &str) -> VdrResult { + let (data, metadata) = self._resolve(did_url)?; + + let content = match data { + Result::Content(c) => Some(c), + _ => None, + }; + + let result = DereferencingResult { + dereferencing_metadata: None, + content_stream: content, + content_metadata: Some(metadata), + }; + + Ok(serde_json::to_string_pretty(&result).unwrap()) + } + pub fn resolve(&self, did: &str) -> VdrResult { + let (data, metadata) = self._resolve(did)?; + + let diddoc = match data { + Result::DidDocument(doc) => Some(doc.to_value()?), + _ => None, + }; + let result = ResolutionResult { + did_resolution_metadata: None, + did_document: diddoc, + did_document_metadata: Some(metadata), + }; + + Ok(serde_json::to_string_pretty(&result).unwrap()) + } + + pub fn _resolve(&self, did: &str) -> VdrResult<(Result, ContentMetadata)> { let did_url = DidUrl::from_str(did)?; let builder = self.pool.get_request_builder(); @@ -35,7 +98,7 @@ impl Resolver { let ledger_data = handle_request(&self.pool, &request)?; let data = parse_ledger_data(&ledger_data)?; - let result = match request.txn_type.as_str() { + let (result, object_type) = match request.txn_type.as_str() { constants::GET_NYM => { let get_nym_result: GetNymResultV1 = serde_json::from_str(data.as_str().unwrap()) @@ -55,13 +118,25 @@ impl Resolver { endpoint, None, ); - did_document.to_string()? + (Result::DidDocument(did_document), String::from("NYM")) } - // other ledger objects - _ => data.to_string(), + constants::GET_CRED_DEF => (Result::Content(data), String::from("CRED_DEF")), + constants::GET_SCHEMA => (Result::Content(data), String::from("SCHEMA")), + constants::GET_REVOC_REG_DEF => (Result::Content(data), String::from("REVOC_REG_DEF")), + constants::GET_REVOC_REG_DELTA => { + (Result::Content(data), String::from("REVOC_REG_DELTA")) + } + _ => (Result::Content(data), String::from("UNKOWN")), + }; + + let metadata = ContentMetadata { + node_response: serde_json::from_str(&ledger_data).unwrap(), + object_type, }; - Ok(result) + let result_with_metadata = (result, metadata); + + Ok(result_with_metadata) } fn fetch_legacy_endpoint(&self, did: &DidValue) -> VdrResult { @@ -115,25 +190,61 @@ fn build_request(did: &DidUrl, builder: &RequestBuilder) -> VdrResult { - let timestamp = parse_or_now(did.query.get(&QueryParameter::VersionTime))?; - - builder.build_get_revoc_reg_request( - None, - &RevocationRegistryId::from_str( - format!( - "{}:4:{}:3:CL:{}:{}:CL_ACCUM:{}", - &did.id, - &did.id, - rev_reg_entry.schema_seq_no, - rev_reg_entry.claim_def_name, - rev_reg_entry.tag + // If From or To parameters, return RevRegDelta request + if did.query.contains_key(&QueryParameter::From) + || did.query.contains_key(&QueryParameter::To) + { + let mut from: Option = None; + if did.query.contains_key(&QueryParameter::From) { + from = did + .query + .get(&QueryParameter::From) + .and_then(|d| DateTime::parse_from_rfc3339(d).ok()) + .and_then(|d| Some(d.timestamp())); + } + + let to = parse_or_now(did.query.get(&QueryParameter::To))?; + + builder.build_get_revoc_reg_delta_request( + None, + &RevocationRegistryId::from_str( + format!( + "{}:4:{}:3:CL:{}:{}:CL_ACCUM:{}", + &did.id, + &did.id, + rev_reg_entry.schema_seq_no, + rev_reg_entry.claim_def_name, + rev_reg_entry.tag + ) + .as_str(), ) - .as_str(), + .unwrap(), + from, + to, ) - .unwrap(), - timestamp, - ) + // Else return RevRegEntry request + } else { + let timestamp = parse_or_now(did.query.get(&QueryParameter::VersionTime))?; + + builder.build_get_revoc_reg_request( + None, + &RevocationRegistryId::from_str( + format!( + "{}:4:{}:3:CL:{}:{}:CL_ACCUM:{}", + &did.id, + &did.id, + rev_reg_entry.schema_seq_no, + rev_reg_entry.claim_def_name, + rev_reg_entry.tag + ) + .as_str(), + ) + .unwrap(), + timestamp, + ) + } } + // This path is deprecated. Deltas can be retrieved through RevRegEntry LedgerObject::RevRegDelta(rev_reg_delta) => { let mut from: Option = None; if did.query.contains_key(&QueryParameter::From) { @@ -230,6 +341,8 @@ fn parse_or_now(datetime: Option<&String>) -> VdrResult { #[cfg(test)] mod tests { + use urlencoding::encode; + use super::*; use rstest::*; @@ -292,7 +405,7 @@ mod tests { fn build_get_revoc_reg_delta_request_with_from_to(request_builder: RequestBuilder) { let from_as_str = "2019-12-20T19:17:47Z"; let to_as_str = "2020-12-20T19:17:47Z"; - let did_url_as_str = format!("did:indy:idunion:Dk1fRRTtNazyMuK2cr64wp/anoncreds/v0/REV_REG_DELTA/104/revocable/a4e25e54?from={}&to={}",from_as_str, to_as_str); + let did_url_as_str = format!("did:indy:idunion:Dk1fRRTtNazyMuK2cr64wp/anoncreds/v0/REV_REG_ENTRY/104/revocable/a4e25e54?from={}&to={}",from_as_str, to_as_str); let did_url = DidUrl::from_str(&did_url_as_str).unwrap(); let request = build_request(&did_url, &request_builder).unwrap(); assert_eq!(request.txn_type, constants::GET_REVOC_REG_DELTA); @@ -302,7 +415,7 @@ mod tests { fn build_get_revoc_reg_delta_request_with_from_only(request_builder: RequestBuilder) { let now = chrono::Utc::now().timestamp(); let from_as_str = "2019-12-20T19:17:47Z"; - let did_url_as_str = format!("did:indy:idunion:Dk1fRRTtNazyMuK2cr64wp/anoncreds/v0/REV_REG_DELTA/104/revocable/a4e25e54?from={}",from_as_str); + let did_url_as_str = format!("did:indy:idunion:Dk1fRRTtNazyMuK2cr64wp/anoncreds/v0/REV_REG_ENTRY/104/revocable/a4e25e54?from={}",from_as_str); let did_url = DidUrl::from_str(&did_url_as_str).unwrap(); let request = build_request(&did_url, &request_builder).unwrap(); @@ -333,4 +446,23 @@ mod tests { assert!(from.is_none()); assert!(to >= now); } + + #[rstest] + fn build_get_schema_request_with_whitespace(request_builder: RequestBuilder) { + let name = "My Schema"; + let encoded_schema_name = encode(name).to_string(); + let did_url_string = format!( + "did:indy:idunion:Dk1fRRTtNazyMuK2cr64wp/anoncreds/v0/SCHEMA/{}/1.0", + encoded_schema_name + ); + + let did_url = DidUrl::from_str(did_url_string.as_str()).unwrap(); + let request = build_request(&did_url, &request_builder).unwrap(); + let schema_name = (*(request.req_json).get("operation").unwrap()) + .get("data") + .and_then(|v| v.get("name")) + .and_then(|v| v.as_str()) + .unwrap(); + assert_eq!(schema_name, name); + } } From 2695ed8a92a24401556f9ef16983968cfacf5d96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20W=C3=B6rner?= Date: Tue, 8 Mar 2022 10:29:14 +0100 Subject: [PATCH 019/117] renaming Value to SJsonValue MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- libindy_vdr/src/ledger/responses.rs | 4 +-- libindy_vdr/src/resolver/did_document.rs | 44 ++++++++++++------------ libindy_vdr/src/resolver/resolver.rs | 18 +++++----- 3 files changed, 33 insertions(+), 33 deletions(-) diff --git a/libindy_vdr/src/ledger/responses.rs b/libindy_vdr/src/ledger/responses.rs index 5a90e7fb..6d60a15a 100644 --- a/libindy_vdr/src/ledger/responses.rs +++ b/libindy_vdr/src/ledger/responses.rs @@ -1,6 +1,6 @@ use crate::utils::did::DidValue; use serde::Deserialize; -use serde_json::value::Value; +use serde_json::{Value as SJsonValue}; use std::collections::HashMap; pub enum ResponseTypes { @@ -31,7 +31,7 @@ pub struct GetNymResultV1 { pub dest: DidValue, pub role: Option, pub verkey: String, - pub diddoc_content: Option, + pub diddoc_content: Option, } #[derive(Deserialize, Eq, PartialEq, Debug)] diff --git a/libindy_vdr/src/resolver/did_document.rs b/libindy_vdr/src/resolver/did_document.rs index 4af3f1a3..03b56b28 100644 --- a/libindy_vdr/src/resolver/did_document.rs +++ b/libindy_vdr/src/resolver/did_document.rs @@ -1,7 +1,7 @@ use crate::common::error::prelude::*; use crate::ledger::responses::Endpoint; use serde::{Deserialize, Serialize}; -use serde_json::{json, Value}; +use serde_json::{self, Value as SJsonValue}; pub const LEGACY_INDY_SERVICE: &str = "endpoint"; pub const DID_CORE_CONTEXT: &str = "https://www.w3.org/ns/did/v1"; @@ -59,7 +59,7 @@ pub struct DidDocument { id: String, verkey: String, endpoint: Option, - diddoc_content: Option, + diddoc_content: Option, } impl DidDocument { @@ -68,7 +68,7 @@ impl DidDocument { id: &str, verkey: &str, endpoint: Option, - diddoc_content: Option, + diddoc_content: Option, ) -> Self { DidDocument { namespace: namespace.to_string(), @@ -79,7 +79,7 @@ impl DidDocument { } } - pub fn to_value(&self) -> VdrResult { + pub fn to_value(&self) -> VdrResult { let mut doc = json!({ "id": format!("did:indy:{}:{}", self.namespace, self.id), "verificationMethod": [Ed25519VerificationKey2018 { @@ -120,8 +120,8 @@ impl DidDocument { services.push(s); } - if let Value::Object(ref mut map) = doc { - map.insert("service".to_string(), serde_json::Value::Array(services)); + if let SJsonValue::Object(ref mut map) = doc { + map.insert("service".to_string(), SJsonValue::Array(services)); } } @@ -138,7 +138,7 @@ fn validate_context(context: &str) -> bool { context == DID_CORE_CONTEXT } -fn validate_diddoc_content(diddoc_content: &Value) -> bool { +fn validate_diddoc_content(diddoc_content: &SJsonValue) -> bool { if diddoc_content.get("id").is_some() { false } else if diddoc_content.get("@context").is_some() { @@ -163,16 +163,16 @@ fn validate_diddoc_content(diddoc_content: &Value) -> bool { } } -fn merge_diddoc(base: &mut Value, content: &Value) { +fn merge_diddoc(base: &mut SJsonValue, content: &SJsonValue) { match (base, content) { - (Value::Object(base), Value::Object(content)) => { + (SJsonValue::Object(base), SJsonValue::Object(content)) => { for (k, v) in content { if k == "authentication" || k == "verificationMethod" { let mut _tmp = base[k].as_array().unwrap().to_owned(); _tmp.append(&mut v.as_array().unwrap_or(&vec![v.to_owned()]).to_owned()); - base[k] = Value::from(_tmp); + base[k] = SJsonValue::from(_tmp); } else { - merge_diddoc(base.entry(k).or_insert(Value::Null), v); + merge_diddoc(base.entry(k).or_insert(SJsonValue::Null), v); } } } @@ -218,8 +218,8 @@ mod tests { // Need to compare serde value instead of string, since elements might be in // different order. - let v_from_doc: Value = serde_json::from_str(doc.to_string().unwrap().as_str()).unwrap(); - let v_from_serialized: Value = + let v_from_doc: SJsonValue = serde_json::from_str(doc.to_string().unwrap().as_str()).unwrap(); + let v_from_serialized: SJsonValue = serde_json::from_str(serde_json::to_string(&serialized).unwrap().as_str()).unwrap(); assert_eq!(v_from_doc, v_from_serialized) @@ -276,8 +276,8 @@ mod tests { }); - let v_from_doc: Value = serde_json::from_str(doc.to_string().unwrap().as_str()).unwrap(); - let v_from_serialized: Value = + let v_from_doc: SJsonValue = serde_json::from_str(doc.to_string().unwrap().as_str()).unwrap(); + let v_from_serialized: SJsonValue = serde_json::from_str(serde_json::to_string(&serialized).unwrap().as_str()).unwrap(); assert_eq!(v_from_doc, v_from_serialized) @@ -346,8 +346,8 @@ mod tests { }); - let v_from_doc: Value = serde_json::from_str(doc.to_string().unwrap().as_str()).unwrap(); - let v_from_serialized: Value = + let v_from_doc: SJsonValue = serde_json::from_str(doc.to_string().unwrap().as_str()).unwrap(); + let v_from_serialized: SJsonValue = serde_json::from_str(serde_json::to_string(&serialized).unwrap().as_str()).unwrap(); assert_eq!(v_from_doc, v_from_serialized) @@ -417,8 +417,8 @@ mod tests { }); - let v_from_doc: Value = serde_json::from_str(doc.to_string().unwrap().as_str()).unwrap(); - let v_from_serialized: Value = + let v_from_doc: SJsonValue = serde_json::from_str(doc.to_string().unwrap().as_str()).unwrap(); + let v_from_serialized: SJsonValue = serde_json::from_str(serde_json::to_string(&serialized).unwrap().as_str()).unwrap(); assert_eq!(v_from_doc, v_from_serialized) @@ -458,8 +458,8 @@ mod tests { }); - let v_from_doc: Value = serde_json::from_str(doc.to_string().unwrap().as_str()).unwrap(); - let v_from_serialized: Value = + let v_from_doc: SJsonValue = serde_json::from_str(doc.to_string().unwrap().as_str()).unwrap(); + let v_from_serialized: SJsonValue = serde_json::from_str(serde_json::to_string(&serialized).unwrap().as_str()).unwrap(); assert_eq!(v_from_doc, v_from_serialized) @@ -484,7 +484,7 @@ mod tests { None, ); - let v_from_doc: Value = serde_json::from_str(doc.to_string().unwrap().as_str()).unwrap(); + let v_from_doc: SJsonValue = serde_json::from_str(doc.to_string().unwrap().as_str()).unwrap(); assert_eq!(2, v_from_doc["service"].as_array().unwrap().len()) } diff --git a/libindy_vdr/src/resolver/resolver.rs b/libindy_vdr/src/resolver/resolver.rs index 51cf4cf3..6d75422e 100644 --- a/libindy_vdr/src/resolver/resolver.rs +++ b/libindy_vdr/src/resolver/resolver.rs @@ -2,7 +2,7 @@ use chrono::{DateTime, Utc}; use crate::utils::Qualifiable; use futures_executor::block_on; -use serde_json::Value; +use serde_json::{Value as SJsonValue}; use super::did::{DidUrl, LedgerObject, QueryParameter}; use super::did_document::{DidDocument, LEGACY_INDY_SERVICE}; @@ -20,13 +20,13 @@ use crate::utils::did::DidValue; #[serde(rename_all = "camelCase")] pub enum Result { DidDocument(DidDocument), - Content(Value), + Content(SJsonValue), } #[derive(Serialize, Deserialize, PartialEq, Debug)] #[serde(rename_all = "camelCase")] pub struct ContentMetadata { - node_response: Value, + node_response: SJsonValue, object_type: String, } @@ -34,7 +34,7 @@ pub struct ContentMetadata { #[serde(rename_all = "camelCase")] pub struct ResolutionResult { did_resolution_metadata: Option, - did_document: Option, + did_document: Option, did_document_metadata: Option, } @@ -42,7 +42,7 @@ pub struct ResolutionResult { #[serde(rename_all = "camelCase")] pub struct DereferencingResult { dereferencing_metadata: Option, - content_stream: Option, + content_stream: Option, content_metadata: Option, } @@ -309,11 +309,11 @@ async fn request_transaction( perform_ledger_request(pool, &request).await } -fn parse_ledger_data(ledger_data: &str) -> VdrResult { - let v: Value = serde_json::from_str(&ledger_data) +fn parse_ledger_data(ledger_data: &str) -> VdrResult { + let v: SJsonValue = serde_json::from_str(&ledger_data) .map_err(|_| err_msg(VdrErrorKind::Resolver, "Could not parse ledger response"))?; - let data: &Value = &v["result"]["data"]; - if *data == Value::Null { + let data: &SJsonValue = &v["result"]["data"]; + if *data == SJsonValue::Null { Err(err_msg( VdrErrorKind::Resolver, format!("Empty data in ledger response"), From e9de63cd829fe9dddcc6057cf35281906ead7c1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20W=C3=B6rner?= Date: Tue, 8 Mar 2022 10:37:20 +0100 Subject: [PATCH 020/117] invert feature flag logic: legacy -> did_indy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- libindy_vdr/Cargo.toml | 2 +- libindy_vdr/src/ffi/ledger.rs | 4 ++-- libindy_vdr/src/ledger/request_builder.rs | 4 ++-- libindy_vdr/src/lib.rs | 1 - libindy_vdr/tests/nym.rs | 13 +++++++------ 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/libindy_vdr/Cargo.toml b/libindy_vdr/Cargo.toml index 972302ba..46450bac 100644 --- a/libindy_vdr/Cargo.toml +++ b/libindy_vdr/Cargo.toml @@ -18,7 +18,7 @@ crate-type = ["staticlib", "rlib", "cdylib"] [features] ffi = ["ffi-support", "logger"] -legacy = [] +did_indy = [] logger = ["env_logger", "log"] zmq_vendored = ["zmq/vendored"] local_nodes_pool = [] diff --git a/libindy_vdr/src/ffi/ledger.rs b/libindy_vdr/src/ffi/ledger.rs index c1978d86..6ca0671f 100644 --- a/libindy_vdr/src/ffi/ledger.rs +++ b/libindy_vdr/src/ffi/ledger.rs @@ -392,7 +392,7 @@ pub extern "C" fn indy_vdr_build_get_validator_info_request( } } -#[cfg(feature = "legacy")] +#[cfg(not(feature = "did_indy"))] #[no_mangle] pub extern "C" fn indy_vdr_build_nym_request( submitter_did: FfiStr, @@ -420,7 +420,7 @@ pub extern "C" fn indy_vdr_build_nym_request( } } -#[cfg(not(feature = "legacy"))] +#[cfg(feature = "did_indy")] #[no_mangle] pub extern "C" fn indy_vdr_build_nym_request( submitter_did: FfiStr, diff --git a/libindy_vdr/src/ledger/request_builder.rs b/libindy_vdr/src/ledger/request_builder.rs index a8e44343..f2f3ac12 100644 --- a/libindy_vdr/src/ledger/request_builder.rs +++ b/libindy_vdr/src/ledger/request_builder.rs @@ -151,7 +151,7 @@ impl RequestBuilder { self.build(operation, Some(identifier)) } - #[cfg(feature = "legacy")] + #[cfg(not(feature = "did_indy"))] pub fn build_nym_request( &self, identifier: &DidValue, @@ -163,7 +163,7 @@ impl RequestBuilder { self.build_nym_request_legacy(identifier, dest, verkey, alias, role) } - #[cfg(not(feature = "legacy"))] + #[cfg(feature = "did_indy")] pub fn build_nym_request( &self, identifier: &DidValue, diff --git a/libindy_vdr/src/lib.rs b/libindy_vdr/src/lib.rs index 43fdc94c..1bf2a2cd 100644 --- a/libindy_vdr/src/lib.rs +++ b/libindy_vdr/src/lib.rs @@ -68,7 +68,6 @@ pub mod ledger; pub mod pool; /// did:indy DID URL resolver -#[cfg(not(feature = "legacy"))] pub mod resolver; /// State proof verification for ledger read transactions pub mod state_proof; diff --git a/libindy_vdr/tests/nym.rs b/libindy_vdr/tests/nym.rs index 4a212e19..b4bb6a31 100644 --- a/libindy_vdr/tests/nym.rs +++ b/libindy_vdr/tests/nym.rs @@ -4,6 +4,7 @@ mod utils; inject_dependencies!(); use indy_vdr::ledger::constants; +#[cfg(feature = "did_indy")] use indy_vdr::ledger::requests::nym::role_to_code; use indy_vdr::utils::did::DidValue; @@ -27,7 +28,7 @@ mod builder { mod nym { use super::*; - #[cfg(not(feature = "legacy"))] + #[cfg(feature = "did_indy")] #[rstest] fn test_build_nym_request( request_builder: RequestBuilder, @@ -46,7 +47,7 @@ mod builder { helpers::check_request_operation(&nym_request, expected_result); } - #[cfg(feature = "legacy")] + #[cfg(not(feature = "did_indy"))] #[rstest] fn test_build_nym_request_legacy( request_builder: RequestBuilder, @@ -65,7 +66,7 @@ mod builder { helpers::check_request_operation(&nym_request, expected_result); } - #[cfg(not(feature = "legacy"))] + #[cfg(feature = "did_indy")] #[rstest] fn test_build_nym_request_for_optional_fields( request_builder: RequestBuilder, @@ -97,7 +98,7 @@ mod builder { helpers::check_request_operation(&nym_request, expected_result); } - #[cfg(not(feature = "legacy"))] + #[cfg(feature = "did_indy")] #[rstest] fn test_pool_build_nym_request_for_empty_role( request_builder: RequestBuilder, @@ -117,7 +118,7 @@ mod builder { helpers::check_request_operation(&nym_request, expected_result); } - #[cfg(not(feature = "legacy"))] + #[cfg(feature = "did_indy")] #[rstest] fn test_pool_build_nym_request_for_fully_qualified_dids( request_builder: RequestBuilder, @@ -137,7 +138,7 @@ mod builder { helpers::check_request_operation(&nym_request, expected_result); } - #[cfg(not(feature = "legacy"))] + #[cfg(feature = "did_indy")] #[rstest] fn test_build_nym_request_works_for_invalid_role( request_builder: RequestBuilder, From 08494bbcd40f91c189f575a2c0e9645df924eed6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20W=C3=B6rner?= Date: Tue, 8 Mar 2022 10:50:24 +0100 Subject: [PATCH 021/117] format MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- libindy_vdr/src/ffi/ledger.rs | 6 +++--- libindy_vdr/src/ledger/requests/nym.rs | 1 - libindy_vdr/src/ledger/responses.rs | 2 +- libindy_vdr/src/resolver/did.rs | 7 +++++-- libindy_vdr/src/resolver/did_document.rs | 19 ++++++++++++------- libindy_vdr/src/resolver/mod.rs | 2 +- libindy_vdr/src/resolver/resolver.rs | 2 +- libindy_vdr/tests/nym.rs | 15 +++++++++++---- 8 files changed, 34 insertions(+), 20 deletions(-) diff --git a/libindy_vdr/src/ffi/ledger.rs b/libindy_vdr/src/ffi/ledger.rs index 6ca0671f..dfa232ef 100644 --- a/libindy_vdr/src/ffi/ledger.rs +++ b/libindy_vdr/src/ffi/ledger.rs @@ -425,9 +425,9 @@ pub extern "C" fn indy_vdr_build_nym_request( pub extern "C" fn indy_vdr_build_nym_request( submitter_did: FfiStr, dest: FfiStr, - verkey: FfiStr, // optional - alias: FfiStr, // optional - role: FfiStr, // optional + verkey: FfiStr, // optional + alias: FfiStr, // optional + role: FfiStr, // optional diddoc_content: FfiStr, // optional handle_p: *mut usize, ) -> ErrorCode { diff --git a/libindy_vdr/src/ledger/requests/nym.rs b/libindy_vdr/src/ledger/requests/nym.rs index faf60764..0baa64fa 100644 --- a/libindy_vdr/src/ledger/requests/nym.rs +++ b/libindy_vdr/src/ledger/requests/nym.rs @@ -6,7 +6,6 @@ use super::did::ShortDidValue; use super::{ProtocolVersion, RequestType}; use crate::ledger::constants::{ENDORSER, NETWORK_MONITOR, ROLES, ROLE_REMOVE, STEWARD, TRUSTEE}; - #[derive(Serialize, PartialEq, Debug)] pub struct NymOperation { #[serde(rename = "type")] diff --git a/libindy_vdr/src/ledger/responses.rs b/libindy_vdr/src/ledger/responses.rs index 6d60a15a..3066787c 100644 --- a/libindy_vdr/src/ledger/responses.rs +++ b/libindy_vdr/src/ledger/responses.rs @@ -1,6 +1,6 @@ use crate::utils::did::DidValue; use serde::Deserialize; -use serde_json::{Value as SJsonValue}; +use serde_json::Value as SJsonValue; use std::collections::HashMap; pub enum ResponseTypes { diff --git a/libindy_vdr/src/resolver/did.rs b/libindy_vdr/src/resolver/did.rs index 571942c2..85c62c44 100644 --- a/libindy_vdr/src/resolver/did.rs +++ b/libindy_vdr/src/resolver/did.rs @@ -345,7 +345,8 @@ impl DidUrl { ) .unwrap(); - let url = Url::parse(input).map_err(|_| err_msg(VdrErrorKind::Resolver, "Could not parse DID Url"))?; + let url = Url::parse(input) + .map_err(|_| err_msg(VdrErrorKind::Resolver, "Could not parse DID Url"))?; let mut query_pairs: HashMap = HashMap::new(); let _query_pairs: HashMap<_, _> = url.query_pairs().into_owned().collect(); @@ -361,7 +362,9 @@ impl DidUrl { let did = DidUrl { namespace: cap.get(1).unwrap().as_str().to_string(), id: DidValue::new(cap.get(2).unwrap().as_str(), Option::None), - path: cap.get(3).and_then(|p| Some(decode(p.as_str()).unwrap().to_string())), + path: cap + .get(3) + .and_then(|p| Some(decode(p.as_str()).unwrap().to_string())), query: query_pairs, url: input.to_string(), }; diff --git a/libindy_vdr/src/resolver/did_document.rs b/libindy_vdr/src/resolver/did_document.rs index 03b56b28..a84fe82a 100644 --- a/libindy_vdr/src/resolver/did_document.rs +++ b/libindy_vdr/src/resolver/did_document.rs @@ -51,7 +51,6 @@ pub enum Service { DidCommService(DidCommService), } - #[derive(Serialize, Deserialize, PartialEq, Debug)] #[serde(rename_all = "camelCase")] pub struct DidDocument { @@ -218,7 +217,8 @@ mod tests { // Need to compare serde value instead of string, since elements might be in // different order. - let v_from_doc: SJsonValue = serde_json::from_str(doc.to_string().unwrap().as_str()).unwrap(); + let v_from_doc: SJsonValue = + serde_json::from_str(doc.to_string().unwrap().as_str()).unwrap(); let v_from_serialized: SJsonValue = serde_json::from_str(serde_json::to_string(&serialized).unwrap().as_str()).unwrap(); @@ -276,7 +276,8 @@ mod tests { }); - let v_from_doc: SJsonValue = serde_json::from_str(doc.to_string().unwrap().as_str()).unwrap(); + let v_from_doc: SJsonValue = + serde_json::from_str(doc.to_string().unwrap().as_str()).unwrap(); let v_from_serialized: SJsonValue = serde_json::from_str(serde_json::to_string(&serialized).unwrap().as_str()).unwrap(); @@ -346,7 +347,8 @@ mod tests { }); - let v_from_doc: SJsonValue = serde_json::from_str(doc.to_string().unwrap().as_str()).unwrap(); + let v_from_doc: SJsonValue = + serde_json::from_str(doc.to_string().unwrap().as_str()).unwrap(); let v_from_serialized: SJsonValue = serde_json::from_str(serde_json::to_string(&serialized).unwrap().as_str()).unwrap(); @@ -417,7 +419,8 @@ mod tests { }); - let v_from_doc: SJsonValue = serde_json::from_str(doc.to_string().unwrap().as_str()).unwrap(); + let v_from_doc: SJsonValue = + serde_json::from_str(doc.to_string().unwrap().as_str()).unwrap(); let v_from_serialized: SJsonValue = serde_json::from_str(serde_json::to_string(&serialized).unwrap().as_str()).unwrap(); @@ -458,7 +461,8 @@ mod tests { }); - let v_from_doc: SJsonValue = serde_json::from_str(doc.to_string().unwrap().as_str()).unwrap(); + let v_from_doc: SJsonValue = + serde_json::from_str(doc.to_string().unwrap().as_str()).unwrap(); let v_from_serialized: SJsonValue = serde_json::from_str(serde_json::to_string(&serialized).unwrap().as_str()).unwrap(); @@ -484,7 +488,8 @@ mod tests { None, ); - let v_from_doc: SJsonValue = serde_json::from_str(doc.to_string().unwrap().as_str()).unwrap(); + let v_from_doc: SJsonValue = + serde_json::from_str(doc.to_string().unwrap().as_str()).unwrap(); assert_eq!(2, v_from_doc["service"].as_array().unwrap().len()) } diff --git a/libindy_vdr/src/resolver/mod.rs b/libindy_vdr/src/resolver/mod.rs index 1fa5684a..55aca841 100644 --- a/libindy_vdr/src/resolver/mod.rs +++ b/libindy_vdr/src/resolver/mod.rs @@ -1,4 +1,4 @@ pub mod resolver; pub mod did; -pub mod did_document; \ No newline at end of file +pub mod did_document; diff --git a/libindy_vdr/src/resolver/resolver.rs b/libindy_vdr/src/resolver/resolver.rs index 6d75422e..3663ab71 100644 --- a/libindy_vdr/src/resolver/resolver.rs +++ b/libindy_vdr/src/resolver/resolver.rs @@ -2,7 +2,7 @@ use chrono::{DateTime, Utc}; use crate::utils::Qualifiable; use futures_executor::block_on; -use serde_json::{Value as SJsonValue}; +use serde_json::Value as SJsonValue; use super::did::{DidUrl, LedgerObject, QueryParameter}; use super::did_document::{DidDocument, LEGACY_INDY_SERVICE}; diff --git a/libindy_vdr/tests/nym.rs b/libindy_vdr/tests/nym.rs index b4bb6a31..c4176dde 100644 --- a/libindy_vdr/tests/nym.rs +++ b/libindy_vdr/tests/nym.rs @@ -72,7 +72,7 @@ mod builder { request_builder: RequestBuilder, trustee_did: DidValue, identity: Identity, - diddoc_content: serde_json::Value, + diddoc_content: serde_json::Value, ) { let copy = diddoc_content.clone(); let nym_request = request_builder @@ -82,7 +82,7 @@ mod builder { Some(identity.verkey.clone()), Some(ALIAS.to_string()), Some(ROLE.to_string()), - Some(diddoc_content) + Some(diddoc_content), ) .unwrap(); @@ -106,7 +106,14 @@ mod builder { my_did: DidValue, ) { let nym_request = request_builder - .build_nym_request(&trustee_did, &my_did, None, None, Some(String::from("")), None) + .build_nym_request( + &trustee_did, + &my_did, + None, + None, + Some(String::from("")), + None, + ) .unwrap(); let expected_result = json!({ @@ -154,7 +161,7 @@ mod builder { Some(identity.verkey), None, Some(role.to_string()), - None + None, ) .unwrap_err(); } From 6482b9999678352bbe47f6921587cbe274d9b64a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20W=C3=B6rner?= Date: Tue, 8 Mar 2022 11:08:27 +0100 Subject: [PATCH 022/117] small fix in test dependencies MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- libindy_vdr/tests/nym.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/libindy_vdr/tests/nym.rs b/libindy_vdr/tests/nym.rs index c4176dde..ee5c28b1 100644 --- a/libindy_vdr/tests/nym.rs +++ b/libindy_vdr/tests/nym.rs @@ -4,7 +4,6 @@ mod utils; inject_dependencies!(); use indy_vdr::ledger::constants; -#[cfg(feature = "did_indy")] use indy_vdr::ledger::requests::nym::role_to_code; use indy_vdr::utils::did::DidValue; From 40815b5da579f731839246f26dcc6036ec29ac20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20W=C3=B6rner?= Date: Tue, 8 Mar 2022 15:18:13 +0100 Subject: [PATCH 023/117] nym and get_nym + proxy. No wrappers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- indy-vdr-proxy/src/handlers.rs | 3 +- libindy_vdr/Cargo.toml | 1 + libindy_vdr/src/ffi/ledger.rs | 7 ++- libindy_vdr/src/ledger/request_builder.rs | 53 ++++------------------- libindy_vdr/src/ledger/requests/nym.rs | 16 +++++-- libindy_vdr/src/resolver/resolver.rs | 14 +++--- libindy_vdr/tests/nym.rs | 52 ++++++++-------------- libindy_vdr/tests/utils/helpers.rs | 2 +- 8 files changed, 54 insertions(+), 94 deletions(-) diff --git a/indy-vdr-proxy/src/handlers.rs b/indy-vdr-proxy/src/handlers.rs index 25601956..1f3856e2 100644 --- a/indy-vdr-proxy/src/handlers.rs +++ b/indy-vdr-proxy/src/handlers.rs @@ -271,11 +271,12 @@ async fn get_attrib(pool: &T, dest: &str, raw: &str) -> VdrResult(pool: &T, nym: &str) -> VdrResult { let nym = DidValue::from_str(nym)?; let request = pool .get_request_builder() - .build_get_nym_request(None, &nym)?; + .build_get_nym_request(None, &nym, None, None)?; let result = perform_ledger_request(pool, &request).await?; Ok(result.into()) } diff --git a/libindy_vdr/Cargo.toml b/libindy_vdr/Cargo.toml index 46450bac..596f9ba3 100644 --- a/libindy_vdr/Cargo.toml +++ b/libindy_vdr/Cargo.toml @@ -26,6 +26,7 @@ rich_schema = ["indy-data-types/rich_schema"] default = ["ffi", "log", "zmq_vendored"] [dependencies] +chrono = "0.4" # This is added so we can lock the version that zmq uses # 0.1.49 is broken for ios targets cmake = { version = "=0.1.48", optional = true } diff --git a/libindy_vdr/src/ffi/ledger.rs b/libindy_vdr/src/ffi/ledger.rs index dfa232ef..59ef8dcb 100644 --- a/libindy_vdr/src/ffi/ledger.rs +++ b/libindy_vdr/src/ffi/ledger.rs @@ -219,6 +219,8 @@ pub extern "C" fn indy_vdr_build_get_cred_def_request( pub extern "C" fn indy_vdr_build_get_nym_request( submitter_did: FfiStr, // optional dest: FfiStr, + seq_no: i32, // optional + timestamp: i64, // optional handle_p: *mut RequestHandle, ) -> ErrorCode { catch_err! { @@ -227,7 +229,8 @@ pub extern "C" fn indy_vdr_build_get_nym_request( let builder = get_request_builder()?; let identifier = submitter_did.as_opt_str().map(DidValue::from_str).transpose()?; let dest = DidValue::from_str(dest.as_str())?; - let req = builder.build_get_nym_request(identifier.as_ref(), &dest)?; + let timestamp = if timestamp == -1 { None } else { Some(timestamp as u64) }; + let req = builder.build_get_nym_request(identifier.as_ref(), &dest, Some(seq_no), timestamp)?; let handle = add_request(req)?; unsafe { *handle_p = handle; @@ -411,7 +414,7 @@ pub extern "C" fn indy_vdr_build_nym_request( let verkey = verkey.into_opt_string(); let alias = alias.into_opt_string(); let role = role.into_opt_string(); - let req = builder.build_nym_request(&identifier, &dest, verkey, alias, role)?; + let req = builder.build_nym_request(&identifier, &dest, verkey, alias, role, None)?; let handle = add_request(req)?; unsafe { *handle_p = handle; diff --git a/libindy_vdr/src/ledger/request_builder.rs b/libindy_vdr/src/ledger/request_builder.rs index f2f3ac12..04058af2 100644 --- a/libindy_vdr/src/ledger/request_builder.rs +++ b/libindy_vdr/src/ledger/request_builder.rs @@ -123,7 +123,7 @@ impl RequestBuilder { } /// Build a new did:indy `NYM` transaction request - pub fn build_nym_request_did_indy( + pub fn build_nym_request( &self, identifier: &DidValue, dest: &DidValue, @@ -137,53 +137,16 @@ impl RequestBuilder { self.build(operation, Some(identifier)) } - /// Build a legacy `NYM` transaction request - pub fn build_nym_request_legacy( - &self, - identifier: &DidValue, - dest: &DidValue, - verkey: Option, - alias: Option, - role: Option, - ) -> VdrResult { - let role = role_to_code(role)?; - let operation = NymOperation::new(dest.to_short(), verkey, alias, role, None); - self.build(operation, Some(identifier)) - } - - #[cfg(not(feature = "did_indy"))] - pub fn build_nym_request( - &self, - identifier: &DidValue, - dest: &DidValue, - verkey: Option, - alias: Option, - role: Option, - ) -> VdrResult { - self.build_nym_request_legacy(identifier, dest, verkey, alias, role) - } - - #[cfg(feature = "did_indy")] - pub fn build_nym_request( - &self, - identifier: &DidValue, - dest: &DidValue, - verkey: Option, - alias: Option, - role: Option, - diddoc_content: Option, - ) -> VdrResult { - self.build_nym_request_did_indy(identifier, dest, verkey, alias, role, diddoc_content) - } - - /// Build a `GET_NYM` transaction request + /// Build a new did:indy `GET_NYM` transaction request pub fn build_get_nym_request( &self, identifier: Option<&DidValue>, dest: &DidValue, + seq_no: Option, + timestamp: Option, ) -> VdrResult { let dest = dest.to_short(); - let operation = GetNymOperation::new(dest); + let operation = GetNymOperation::new(dest, seq_no, timestamp); self.build(operation, identifier) } @@ -753,7 +716,7 @@ mod tests { request_builder: RequestBuilder, ) { let request = request_builder - .build_nym_request_did_indy(&_identifier(), &_dest(), None, None, None, None) + .build_nym_request(&_identifier(), &_dest(), None, None, None, None) .unwrap(); assert_eq!(request.txn_type, constants::NYM); @@ -765,7 +728,7 @@ mod tests { request_builder: RequestBuilder, ) { let request = request_builder - .build_get_nym_request(None, &_dest()) + .build_get_nym_request(None, &_dest(), None, None) .unwrap(); assert_eq!(request.txn_type, constants::GET_NYM); @@ -975,7 +938,7 @@ mod tests { )] fn test_prepare_request_for_different_protocol_versions(protocol_version: ProtocolVersion) { let request = RequestBuilder::new(protocol_version) - .build_get_nym_request(None, &_dest()) + .build_get_nym_request(None, &_dest(), None, None) .unwrap(); assert_eq!(request.protocol_version, protocol_version); diff --git a/libindy_vdr/src/ledger/requests/nym.rs b/libindy_vdr/src/ledger/requests/nym.rs index 0baa64fa..89a50004 100644 --- a/libindy_vdr/src/ledger/requests/nym.rs +++ b/libindy_vdr/src/ledger/requests/nym.rs @@ -7,8 +7,8 @@ use super::{ProtocolVersion, RequestType}; use crate::ledger::constants::{ENDORSER, NETWORK_MONITOR, ROLES, ROLE_REMOVE, STEWARD, TRUSTEE}; #[derive(Serialize, PartialEq, Debug)] +#[serde(rename_all = "camelCase")] pub struct NymOperation { - #[serde(rename = "type")] pub _type: String, pub dest: ShortDidValue, #[serde(skip_serializing_if = "Option::is_none")] @@ -47,17 +47,27 @@ impl RequestType for NymOperation { } #[derive(Serialize, PartialEq, Debug)] +#[serde(rename_all = "camelCase")] pub struct GetNymOperation { - #[serde(rename = "type")] pub _type: String, pub dest: ShortDidValue, + #[serde(skip_serializing_if = "Option::is_none")] + pub seq_no: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub timestamp: Option, } impl GetNymOperation { - pub fn new(dest: ShortDidValue) -> GetNymOperation { + pub fn new( + dest: ShortDidValue, + seq_no: Option, + timestamp: Option, + ) -> GetNymOperation { GetNymOperation { _type: Self::get_txn_type().to_string(), dest, + seq_no, + timestamp, } } } diff --git a/libindy_vdr/src/resolver/resolver.rs b/libindy_vdr/src/resolver/resolver.rs index 3663ab71..a406c3bd 100644 --- a/libindy_vdr/src/resolver/resolver.rs +++ b/libindy_vdr/src/resolver/resolver.rs @@ -1,6 +1,5 @@ -use chrono::{DateTime, Utc}; - use crate::utils::Qualifiable; +use chrono::{DateTime, Utc}; use futures_executor::block_on; use serde_json::Value as SJsonValue; @@ -277,19 +276,18 @@ fn build_request(did: &DidUrl, builder: &RequestBuilder) -> VdrResult = did + let seq_no: Option = did .query .get(&QueryParameter::VersionId) .and_then(|v| v.parse().ok()); - let _timestamp: Option = did + let timestamp: Option = did .query .get(&QueryParameter::VersionTime) .and_then(|d| DateTime::parse_from_rfc3339(d).ok()) - .and_then(|d| Some(d.timestamp())); + .and_then(|d| Some(d.timestamp())) + .and_then(|d| Some(d as u64)); - builder.build_get_nym_request(Option::None, &did.id) + builder.build_get_nym_request(Option::None, &did.id, seq_no, timestamp) }; request } diff --git a/libindy_vdr/tests/nym.rs b/libindy_vdr/tests/nym.rs index ee5c28b1..16b3a747 100644 --- a/libindy_vdr/tests/nym.rs +++ b/libindy_vdr/tests/nym.rs @@ -27,7 +27,7 @@ mod builder { mod nym { use super::*; - #[cfg(feature = "did_indy")] + #[rstest] fn test_build_nym_request( request_builder: RequestBuilder, @@ -46,26 +46,6 @@ mod builder { helpers::check_request_operation(&nym_request, expected_result); } - #[cfg(not(feature = "did_indy"))] - #[rstest] - fn test_build_nym_request_legacy( - request_builder: RequestBuilder, - trustee_did: DidValue, - my_did: DidValue, - ) { - let nym_request = request_builder - .build_nym_request(&trustee_did, &my_did, None, None, None) - .unwrap(); - - let expected_result = json!({ - "type": constants::NYM, - "dest": my_did, - }); - - helpers::check_request_operation(&nym_request, expected_result); - } - - #[cfg(feature = "did_indy")] #[rstest] fn test_build_nym_request_for_optional_fields( request_builder: RequestBuilder, @@ -91,13 +71,12 @@ mod builder { "verkey": identity.verkey, "alias": ALIAS, "role": role_to_code(Some(String::from(ROLE))).unwrap(), - "diddoc_content": copy, + "diddocContent": copy, }); helpers::check_request_operation(&nym_request, expected_result); } - #[cfg(feature = "did_indy")] #[rstest] fn test_pool_build_nym_request_for_empty_role( request_builder: RequestBuilder, @@ -124,7 +103,6 @@ mod builder { helpers::check_request_operation(&nym_request, expected_result); } - #[cfg(feature = "did_indy")] #[rstest] fn test_pool_build_nym_request_for_fully_qualified_dids( request_builder: RequestBuilder, @@ -144,7 +122,6 @@ mod builder { helpers::check_request_operation(&nym_request, expected_result); } - #[cfg(feature = "did_indy")] #[rstest] fn test_build_nym_request_works_for_invalid_role( request_builder: RequestBuilder, @@ -176,7 +153,7 @@ mod builder { my_did: DidValue, ) { let nym_request = request_builder - .build_get_nym_request(Some(&trustee_did), &my_did) + .build_get_nym_request(Some(&trustee_did), &my_did, None, None) .unwrap(); let expected_result = json!({ @@ -195,7 +172,7 @@ mod builder { my_did: DidValue, ) { let nym_request = request_builder - .build_get_nym_request(Some(&fq_trustee_did), &fq_my_did) + .build_get_nym_request(Some(&fq_trustee_did), &fq_my_did, None, None) .unwrap(); let expected_result = json!({ @@ -226,6 +203,7 @@ mod send { Some(identity.verkey.to_string()), None, None, + None, ) .unwrap(); @@ -235,7 +213,7 @@ mod send { // Get NYM let get_nym_request = pool .request_builder() - .build_get_nym_request(None, &identity.did) + .build_get_nym_request(None, &identity.did, None, None) .unwrap(); let response = pool @@ -265,6 +243,7 @@ mod send { Some(identity.verkey.to_string()), Some(ALIAS.to_string()), Some(ROLE.to_string()), + None, ) .unwrap(); @@ -274,7 +253,7 @@ mod send { // Get NYM let get_nym_request = pool .request_builder() - .build_get_nym_request(None, &identity.did) + .build_get_nym_request(None, &identity.did, None, None) .unwrap(); let response = pool @@ -313,6 +292,7 @@ mod send { Some(new_identity.verkey.to_string()), None, Some(role.to_string()), + None, ) .unwrap(); @@ -322,7 +302,7 @@ mod send { // Get NYM let get_nym_request = pool .request_builder() - .build_get_nym_request(None, &new_identity.did) + .build_get_nym_request(None, &new_identity.did, None, None) .unwrap(); let response = pool @@ -352,6 +332,7 @@ mod send { Some(identity.verkey.to_string()), None, Some(ROLE.to_string()), + None, ) .unwrap(); @@ -361,7 +342,7 @@ mod send { // Get NYM to ensure role is TRUSTEE let get_nym_request = pool .request_builder() - .build_get_nym_request(None, &identity.did) + .build_get_nym_request(None, &identity.did, None, None) .unwrap(); let response = pool @@ -384,6 +365,7 @@ mod send { None, None, Some(ROLE_REMOVE.to_string()), + None, ) .unwrap(); @@ -393,7 +375,7 @@ mod send { // Get NYM to ensure role was reset let get_nym_request = pool .request_builder() - .build_get_nym_request(None, &identity.did) + .build_get_nym_request(None, &identity.did, None, None) .unwrap(); let response = pool @@ -423,6 +405,7 @@ mod send { Some(identity.verkey.to_string()), None, None, + None, ) .unwrap(); @@ -435,7 +418,7 @@ mod send { // Send NYM let mut nym_request = pool .request_builder() - .build_nym_request(&identity.did, &identity.did, None, None, None) + .build_nym_request(&identity.did, &identity.did, None, None, None, None) .unwrap(); identity.sign_request(&mut nym_request); @@ -458,6 +441,7 @@ mod send { Some(new_identity.verkey), None, None, + None, ) .unwrap(); @@ -470,7 +454,7 @@ mod send { // Get NYM let get_nym_request = pool .request_builder() - .build_get_nym_request(None, &identity.did) + .build_get_nym_request(None, &identity.did, None, None) .unwrap(); let response = pool.send_request(&get_nym_request).unwrap(); diff --git a/libindy_vdr/tests/utils/helpers.rs b/libindy_vdr/tests/utils/helpers.rs index 6ac301f2..5fda455e 100644 --- a/libindy_vdr/tests/utils/helpers.rs +++ b/libindy_vdr/tests/utils/helpers.rs @@ -38,7 +38,7 @@ pub fn new_ledger_identity(pool: &TestPool, role: Option) -> Identity { // Send NYM let mut nym_request = pool .request_builder() - .build_nym_request_did_indy( + .build_nym_request( &trustee.did, &new_identity.did, Some(new_identity.verkey.to_string()), From 57e8aba04e32be6e6c541c28743b93e348881129 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20W=C3=B6rner?= Date: Tue, 8 Mar 2022 15:32:41 +0100 Subject: [PATCH 024/117] adapt python wrapper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- wrappers/python/indy_vdr/ledger.py | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/wrappers/python/indy_vdr/ledger.py b/wrappers/python/indy_vdr/ledger.py index 7891f8c0..b559d434 100644 --- a/wrappers/python/indy_vdr/ledger.py +++ b/wrappers/python/indy_vdr/ledger.py @@ -268,7 +268,12 @@ def build_get_cred_def_request( return Request(handle) -def build_get_nym_request(submitter_did: Optional[str], dest: str) -> Request: +def build_get_nym_request( + submitter_did: Optional[str], + dest: str, + seq_no: Optional[int], + timestamp: Optional[int], +) -> Request: """ Builds a GET_NYM request to get information about a DID (NYM). @@ -276,11 +281,22 @@ def build_get_nym_request(submitter_did: Optional[str], dest: str) -> Request: submitter_did: (Optional) DID of the read request sender. If not provided then the default Libindy DID will be use) target_did: Target DID as base58-encoded string for 16 or 32 bit DID value + seq_no: (Optional) Version of NYM as sepecified by txn sequence number + timestamp: (Optional) Version of NYM as sepecified by timestamp """ handle = RequestHandle() did_p = encode_str(submitter_did) dest_p = encode_str(dest) - do_call("indy_vdr_build_get_nym_request", did_p, dest_p, byref(handle)) + seq_no_c = (c_int32(seq_no),) + timestamp_c = (c_int64(timestamp),) + do_call( + "indy_vdr_build_get_nym_request", + did_p, + dest_p, + seq_no_c, + timestamp_c, + byref(handle), + ) return Request(handle) @@ -471,6 +487,7 @@ def build_nym_request( verkey: str = None, alias: str = None, role: str = None, + diddoc_content: str = None, ) -> Request: """ Builds a NYM request to create new DID on the ledger. @@ -489,6 +506,7 @@ def build_nym_request( ENDORSER - equal to TRUST_ANCHOR that will be removed soon NETWORK_MONITOR empty string to reset role + diddoc_content: (Optional) The DIDDoc content """ handle = RequestHandle() did_p = encode_str(submitter_did) @@ -496,6 +514,7 @@ def build_nym_request( verkey_p = encode_str(verkey) alias_p = encode_str(alias) role_p = encode_str(role) + diddoc_content_p = encode_str(diddoc_content) do_call( "indy_vdr_build_nym_request", did_p, @@ -503,6 +522,7 @@ def build_nym_request( verkey_p, alias_p, role_p, + diddoc_content_p, byref(handle), ) return Request(handle) @@ -962,7 +982,7 @@ def build_pool_upgrade_request( justification: Optional[str], reinstall: bool, force: bool, - package: Optional[str] + package: Optional[str], ) -> str: """ Builds an POOL_UPGRADE request. From 0e7dd063bf309d1ae4a8dc9c9388d76e037a318b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20W=C3=B6rner?= Date: Tue, 8 Mar 2022 15:35:09 +0100 Subject: [PATCH 025/117] remove feature MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- libindy_vdr/Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/libindy_vdr/Cargo.toml b/libindy_vdr/Cargo.toml index 596f9ba3..01347f5b 100644 --- a/libindy_vdr/Cargo.toml +++ b/libindy_vdr/Cargo.toml @@ -18,7 +18,6 @@ crate-type = ["staticlib", "rlib", "cdylib"] [features] ffi = ["ffi-support", "logger"] -did_indy = [] logger = ["env_logger", "log"] zmq_vendored = ["zmq/vendored"] local_nodes_pool = [] From 470ab1a2d9d59c973386cf55185fbbb3fd9b1a6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20W=C3=B6rner?= Date: Tue, 8 Mar 2022 16:03:49 +0100 Subject: [PATCH 026/117] minimal changes to go wrapper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- wrappers/golang/vdr/indy_vdr.go | 2 +- wrappers/golang/vdr/libindy_vdr.h | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/wrappers/golang/vdr/indy_vdr.go b/wrappers/golang/vdr/indy_vdr.go index 3402edda..de453313 100644 --- a/wrappers/golang/vdr/indy_vdr.go +++ b/wrappers/golang/vdr/indy_vdr.go @@ -131,7 +131,7 @@ func (r *Client) GetNym(did string) (*ReadReply, error) { var nymreq C.int64_t var none *C.char cdid := C.CString(did) - result := C.indy_vdr_build_get_nym_request(none, cdid, &nymreq) + result := C.indy_vdr_build_get_nym_request(none, cdid, none, none, &nymreq) C.free(unsafe.Pointer(cdid)) if result != 0 { return nil, fmt.Errorf("invalid get nym request: (Indy error code: [%v])", result) diff --git a/wrappers/golang/vdr/libindy_vdr.h b/wrappers/golang/vdr/libindy_vdr.h index 25661c1d..7397e013 100644 --- a/wrappers/golang/vdr/libindy_vdr.h +++ b/wrappers/golang/vdr/libindy_vdr.h @@ -220,9 +220,7 @@ ErrorCode indy_vdr_build_get_cred_def_request(FfiStr submitter_did, FfiStr cred_def_id, RequestHandle *handle_p); -ErrorCode indy_vdr_build_get_nym_request(FfiStr submitter_did, - FfiStr dest, - RequestHandle *handle_p); +ErrorCode indy_vdr_build_get_nym_request(FfiStr submitter_did, FfiStr dest, int32_t seq_no, int64_t timestamp, RequestHandle *handle_p); ErrorCode indy_vdr_build_get_revoc_reg_def_request(FfiStr submitter_did, FfiStr revoc_reg_id, @@ -273,6 +271,7 @@ ErrorCode indy_vdr_build_nym_request(FfiStr submitter_did, FfiStr verkey, FfiStr alias, FfiStr role, + FfiStr diddoc_content, RequestHandle *handle_p); ErrorCode indy_vdr_build_revoc_reg_def_request(FfiStr submitter_did, From 5dc2ff84a6e73dfc8e30e9e4dfec6b3c4d7791a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20W=C3=B6rner?= Date: Tue, 8 Mar 2022 16:05:58 +0100 Subject: [PATCH 027/117] test build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cdfd3daf..e3d530d3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -6,7 +6,7 @@ env: on: push: - branches: [main] + branches: [main, did-indy-only] pull_request: branches: [main] release: From 89642d1cb62dd6eb6c0921291c7954436221e4b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20W=C3=B6rner?= Date: Tue, 8 Mar 2022 16:18:06 +0100 Subject: [PATCH 028/117] format MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- libindy_vdr/tests/nym.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/libindy_vdr/tests/nym.rs b/libindy_vdr/tests/nym.rs index 16b3a747..b3d577af 100644 --- a/libindy_vdr/tests/nym.rs +++ b/libindy_vdr/tests/nym.rs @@ -27,7 +27,6 @@ mod builder { mod nym { use super::*; - #[rstest] fn test_build_nym_request( request_builder: RequestBuilder, From f134fc868eb5763cca5b70a2f6ca5574cb78e80d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20W=C3=B6rner?= Date: Tue, 8 Mar 2022 16:54:37 +0100 Subject: [PATCH 029/117] fix nym builder in tests and try to fix go wrapper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- libindy_vdr/tests/author_agreement.rs | 3 ++- libindy_vdr/tests/get_txn.rs | 1 + wrappers/golang/vdr/indy_vdr.go | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/libindy_vdr/tests/author_agreement.rs b/libindy_vdr/tests/author_agreement.rs index 2a5a641c..f8d901bc 100644 --- a/libindy_vdr/tests/author_agreement.rs +++ b/libindy_vdr/tests/author_agreement.rs @@ -323,6 +323,7 @@ mod author_agreement { Some(new_identity.verkey.to_string()), None, None, + None, ) .unwrap() } @@ -377,7 +378,7 @@ mod author_agreement { // Ensure NYM is written let get_nym_request = pool .request_builder() - .build_get_nym_request(None, &new_identity.did) + .build_get_nym_request(None, &new_identity.did, None, None) .unwrap(); let _response = pool diff --git a/libindy_vdr/tests/get_txn.rs b/libindy_vdr/tests/get_txn.rs index cb889821..bd76a5c2 100644 --- a/libindy_vdr/tests/get_txn.rs +++ b/libindy_vdr/tests/get_txn.rs @@ -60,6 +60,7 @@ mod get_txn { Some(identity.verkey.to_string()), None, None, + None, ) .unwrap(); diff --git a/wrappers/golang/vdr/indy_vdr.go b/wrappers/golang/vdr/indy_vdr.go index de453313..08d09552 100644 --- a/wrappers/golang/vdr/indy_vdr.go +++ b/wrappers/golang/vdr/indy_vdr.go @@ -131,7 +131,7 @@ func (r *Client) GetNym(did string) (*ReadReply, error) { var nymreq C.int64_t var none *C.char cdid := C.CString(did) - result := C.indy_vdr_build_get_nym_request(none, cdid, none, none, &nymreq) + result := C.indy_vdr_build_get_nym_request(none, cdid, NULL, NULL, &nymreq) C.free(unsafe.Pointer(cdid)) if result != 0 { return nil, fmt.Errorf("invalid get nym request: (Indy error code: [%v])", result) From 2a5ff3dcef557156ba3789f797e4953596eee666 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20W=C3=B6rner?= Date: Tue, 8 Mar 2022 21:03:29 +0100 Subject: [PATCH 030/117] another attempt to fix go wrapper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- wrappers/golang/vdr/indy_vdr.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/wrappers/golang/vdr/indy_vdr.go b/wrappers/golang/vdr/indy_vdr.go index 08d09552..fe636e56 100644 --- a/wrappers/golang/vdr/indy_vdr.go +++ b/wrappers/golang/vdr/indy_vdr.go @@ -130,8 +130,10 @@ func (r *Client) Submit(request []byte) (*ReadReply, error) { func (r *Client) GetNym(did string) (*ReadReply, error) { var nymreq C.int64_t var none *C.char + var zero32 C.int32_t + var zero64 C.int64_t cdid := C.CString(did) - result := C.indy_vdr_build_get_nym_request(none, cdid, NULL, NULL, &nymreq) + result := C.indy_vdr_build_get_nym_request(none, cdid, zero32, zero64, &nymreq) C.free(unsafe.Pointer(cdid)) if result != 0 { return nil, fmt.Errorf("invalid get nym request: (Indy error code: [%v])", result) From cb0c404ab11ebc8792305e3089e263457aa3b24d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20W=C3=B6rner?= Date: Fri, 11 Mar 2022 11:05:10 +0100 Subject: [PATCH 031/117] not working due to lifetimes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- libindy_vdr/src/ffi/resolver.rs | 86 +++++++++++++++++ libindy_vdr/src/resolver/resolver.rs | 139 +++++++++++++++++++++++++-- wrappers/python/indy_vdr/bindings.py | 29 +++++- wrappers/python/indy_vdr/resolver.py | 19 ++++ 4 files changed, 264 insertions(+), 9 deletions(-) create mode 100644 libindy_vdr/src/ffi/resolver.rs create mode 100644 wrappers/python/indy_vdr/resolver.py diff --git a/libindy_vdr/src/ffi/resolver.rs b/libindy_vdr/src/ffi/resolver.rs new file mode 100644 index 00000000..6ebf2726 --- /dev/null +++ b/libindy_vdr/src/ffi/resolver.rs @@ -0,0 +1,86 @@ +use crate::common::error::prelude::*; +use crate::resolver::resolver::PoolRunnerResolver as Resolver; +use std::sync::RwLock; + +use std::collections::BTreeMap; + +use super::error::{set_last_error, ErrorCode}; +use super::pool::{PoolHandle, POOLS}; +use crate::ffi::c_char; +use ffi_support::{rust_string_to_c, FfiStr}; +use once_cell::sync::Lazy; + +new_handle_type!(ResolverHandle, FFI_PH_COUNTER); + +static RESOLVERS: Lazy>> = + Lazy::new(|| RwLock::new(BTreeMap::new())); + +#[no_mangle] +pub extern "C" fn indy_vdr_resolver_create(pool_handle: usize, handle_p: *mut usize) -> ErrorCode { + catch_err! { + trace!("Create resolver"); + let pools = read_lock!(POOLS)?; + let pool = pools.get(&PoolHandle(pool_handle)) + .ok_or_else(|| input_err("Unknown pool handle"))?; + let resolver = Resolver::new(pool); + let handle = ResolverHandle::next(); + let mut resolvers = write_lock!(RESOLVERS)?; + resolvers.insert(handle, resolver); + unsafe { + *handle_p = *handle; + } + + Ok(ErrorCode::Success) + } +} + +#[no_mangle] +pub extern "C" fn indy_vdr_resolve( + resolver_handle: usize, + did: FfiStr, + cb: Option, + cb_id: i64, +) -> ErrorCode { + catch_err! { + trace!("Resolve DID: {:#?}", did); + let cb = cb.ok_or_else(|| input_err("No callback provided")).unwrap(); + + let resolvers = read_lock!(RESOLVERS)?; + let resolver = resolvers.get(&ResolverHandle(resolver_handle)) + .ok_or_else(|| input_err("Unknown resolver handle"))?; + + resolver + .resolve( + did.as_str(), + Box::new(move |result| { + let (errcode, reply) = match result { + Ok(status) => (ErrorCode::Success, status), + Err(err) => { + let code = ErrorCode::from(err.kind()); + set_last_error(Some(err)); + (code, String::new()) + } + }; + cb(cb_id, errcode, rust_string_to_c(reply)) + }), + ) + .unwrap(); + + + Ok(ErrorCode::Success) + } +} + +// #[no_mangle] +// pub extern "C" fn indy_vdr_dereference( +// resolver_handle: i64, +// did_url: FfiStr, +// cb: Option, +// cb_id: i64, +// ) -> ErrorCode { +// catch_err! { +// trace!("Dereference DID Url: {:#?}", did_url); +// let cb = cb.ok_or_else(|| input_err("No callback provided"))?; +// Ok(ErrorCode::Success) +// } +// } diff --git a/libindy_vdr/src/resolver/resolver.rs b/libindy_vdr/src/resolver/resolver.rs index a406c3bd..7846ad77 100644 --- a/libindy_vdr/src/resolver/resolver.rs +++ b/libindy_vdr/src/resolver/resolver.rs @@ -8,11 +8,10 @@ use super::did_document::{DidDocument, LEGACY_INDY_SERVICE}; use crate::common::error::prelude::*; use crate::ledger::responses::{Endpoint, GetNymResultV1}; -use crate::ledger::constants; use crate::ledger::identifiers::{CredentialDefinitionId, RevocationRegistryId, SchemaId}; -use crate::ledger::RequestBuilder; +use crate::ledger::{constants, RequestBuilder}; use crate::pool::helpers::perform_ledger_request; -use crate::pool::{Pool, PreparedRequest, RequestResult, TimingResult}; +use crate::pool::{Pool, PoolRunner, PreparedRequest, RequestResult, TimingResult}; use crate::utils::did::DidValue; #[derive(Serialize, Deserialize, PartialEq, Debug)] @@ -46,13 +45,13 @@ pub struct DereferencingResult { } // DID (URL) Resolver for did:indy method -pub struct Resolver { +pub struct PoolResolver { pool: T, } -impl Resolver { - pub fn new(pool: T) -> Resolver { - Resolver { pool } +impl PoolResolver { + pub fn new(pool: T) -> PoolResolver { + PoolResolver { pool } } pub fn dereference(&self, did_url: &str) -> VdrResult { @@ -307,6 +306,132 @@ async fn request_transaction( perform_ledger_request(pool, &request).await } +pub struct PoolRunnerResolver<'a> { + runner: &'a PoolRunner, +} + +impl<'a> PoolRunnerResolver<'a> { + pub fn new(runner: &'a PoolRunner) -> PoolRunnerResolver { + PoolRunnerResolver { runner } + } + + // pub fn dereference(&self, did_url: &str, callback: Callback) -> VdrResult { + // let (data, metadata) = self._resolve(did_url)?; + + // let content = match data { + // Result::Content(c) => Some(c), + // _ => None, + // }; + + // let result = DereferencingResult { + // dereferencing_metadata: None, + // content_stream: content, + // content_metadata: Some(metadata), + // }; + + // Ok(serde_json::to_string_pretty(&result).unwrap()) + // } + + pub fn resolve(&self, did: &str, callback: Callback>) -> VdrResult<()> { + self._resolve( + did, + Box::new(|result| { + let (data, metadata) = result.unwrap(); + let diddoc = match data { + Result::DidDocument(doc) => Some(doc.to_value().unwrap()), + _ => None, + }; + let result = ResolutionResult { + did_resolution_metadata: None, + did_document: diddoc, + did_document_metadata: Some(metadata), + }; + + callback(Ok(serde_json::to_string_pretty(&result).unwrap())) + }), + ) + } + + fn _resolve( + &self, + did: &str, + callback: Callback>, + ) -> VdrResult<()> { + let did_url = DidUrl::from_str(did)?; + + let builder = RequestBuilder::default(); + let request = build_request(&did_url, &builder)?; + let txn_type = request.txn_type.clone(); + self.runner.send_request( + request, + Box::new( + move |result: VdrResult<(RequestResult, Option)>| { + match result { + Ok((res, _)) => { + match res { + RequestResult::Reply(reply_data) => { + let data = parse_ledger_data(&reply_data).unwrap(); + let (result, object_type) = match txn_type.as_str() { + constants::GET_NYM => { + let get_nym_result: GetNymResultV1 = + serde_json::from_str(data.as_str().unwrap()) + .unwrap(); + + let endpoint: Option = + if get_nym_result.diddoc_content.is_none() { + // Legacy: Try to find an attached ATTRIBUTE transacation with raw endpoint + // self.fetch_legacy_endpoint(&did_url.id).ok() + None + } else { + None + }; + + let did_document = DidDocument::new( + &did_url.namespace, + &get_nym_result.dest, + &get_nym_result.verkey, + endpoint, + None, + ); + (Result::DidDocument(did_document), String::from("NYM")) + } + constants::GET_CRED_DEF => { + (Result::Content(data), String::from("CRED_DEF")) + } + constants::GET_SCHEMA => { + (Result::Content(data), String::from("SCHEMA")) + } + constants::GET_REVOC_REG_DEF => { + (Result::Content(data), String::from("REVOC_REG_DEF")) + } + constants::GET_REVOC_REG_DELTA => { + (Result::Content(data), String::from("REVOC_REG_DELTA")) + } + _ => (Result::Content(data), String::from("UNKOWN")), + }; + + let metadata = ContentMetadata { + node_response: serde_json::from_str(&reply_data).unwrap(), + object_type, + }; + + let result_with_metadata = (result, metadata); + callback(Ok(result_with_metadata)); + } + RequestResult::Failed(err) => callback(Err(err)), + } + } + Err(err) => callback(Err(err)), + } + }, + ), + ) + } +} + +type Callback = Box ()) + Send>; +type SendReqResponse = VdrResult<(RequestResult, Option)>; + fn parse_ledger_data(ledger_data: &str) -> VdrResult { let v: SJsonValue = serde_json::from_str(&ledger_data) .map_err(|_| err_msg(VdrErrorKind::Resolver, "Could not parse ledger response"))?; diff --git a/wrappers/python/indy_vdr/bindings.py b/wrappers/python/indy_vdr/bindings.py index 162b3d50..56daf2c5 100644 --- a/wrappers/python/indy_vdr/bindings.py +++ b/wrappers/python/indy_vdr/bindings.py @@ -44,8 +44,16 @@ def __repr__(self) -> str: return f"{self.__class__.__name__}({self.value})" +class ResolverHandle(c_int64): + """Index of an active Resolver instance.""" + + def __repr__(self) -> str: + """Format resolver handle as a string.""" + return f"{self.__class__.__name__}({self.value})" + + class FfiByteBuffer(Structure): - """A byte buffer allocated by python.""" + """A byte buffer allocated by Python.""" _fields_ = [ ("len", c_int64), @@ -249,6 +257,24 @@ def pool_create(params: Union[str, bytes, dict]) -> PoolHandle: return handle +def resolver_create(pool_handle: PoolHandle) -> ResolverHandle: + """Create a new resolver instance.""" + handle = ResolverHandle() + do_call("indy_vdr_resolver_create", pool_handle, byref(handle)) + return handle + + +def resolve(resolver_handle: ResolverHandle, did_url: str) -> asyncio.Future: + """Resovle a DID to retrieve a DID Doc.""" + return do_call_async( + "indy_vdr_resolve", + resolver_handle, + did_url, + return_type=lib_string, + post_process=str, + ) + + def pool_get_status(pool_handle: PoolHandle) -> asyncio.Future: """Get the status of an opened pool instance.""" return do_call_async( @@ -352,7 +378,6 @@ def request_set_multi_signature( ): """Add a multi-signature entry to a prepared request.""" identifier = encode_str(identifier) - sig_len = len(signature) do_call( "indy_vdr_request_set_multi_signature", handle, diff --git a/wrappers/python/indy_vdr/resolver.py b/wrappers/python/indy_vdr/resolver.py new file mode 100644 index 00000000..20475c0a --- /dev/null +++ b/wrappers/python/indy_vdr/resolver.py @@ -0,0 +1,19 @@ +from . import bindings + + +class Resolver: + """did:indy compliant resolver interface for a specific network.""" + + def __init__(self, handle: bindings.ResolverHandle): + """Initialize the pool instance.""" + self.handle = handle + + async def resolve(self, did: str) -> dict: + """Resolve a DID to retrieve a DID Doc.""" + result = await bindings.resolve(self.handle, did) + return result + + async def dereference(self, did_url: str) -> dict: + """Dereference a DID Url to retrieve a ledger object.""" + result = await bindings.dereference(self.handle, did_url) + return result From 55d819ce9b4de4caccd83c90c2ebbe90dde61477 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20W=C3=B6rner?= Date: Fri, 11 Mar 2022 11:52:32 +0100 Subject: [PATCH 032/117] run tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- .github/workflows/build.yml | 2 +- libindy_vdr/src/resolver/resolver.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e3d530d3..1522ad29 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -6,7 +6,7 @@ env: on: push: - branches: [main, did-indy-only] + branches: [main, did-indy-only, ffi-resolver] pull_request: branches: [main] release: diff --git a/libindy_vdr/src/resolver/resolver.rs b/libindy_vdr/src/resolver/resolver.rs index 7846ad77..2e67ca31 100644 --- a/libindy_vdr/src/resolver/resolver.rs +++ b/libindy_vdr/src/resolver/resolver.rs @@ -430,7 +430,7 @@ impl<'a> PoolRunnerResolver<'a> { } type Callback = Box ()) + Send>; -type SendReqResponse = VdrResult<(RequestResult, Option)>; +// type SendReqResponse = VdrResult<(RequestResult, Option)>; fn parse_ledger_data(ledger_data: &str) -> VdrResult { let v: SJsonValue = serde_json::from_str(&ledger_data) From 266df852f53c16790db2246b8eab133ebe6bda66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20W=C3=B6rner?= Date: Mon, 14 Mar 2022 14:53:42 +0100 Subject: [PATCH 033/117] ffi resolver working for single request MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- libindy_vdr/src/ffi/mod.rs | 1 + libindy_vdr/src/ffi/pool.rs | 2 +- libindy_vdr/src/ffi/resolver.rs | 85 +++++------ libindy_vdr/src/resolver/resolver.rs | 204 +++++++++++++++++++-------- wrappers/python/demo/test.py | 10 +- wrappers/python/indy_vdr/bindings.py | 17 ++- wrappers/python/indy_vdr/error.py | 2 + wrappers/python/indy_vdr/resolver.py | 4 +- 8 files changed, 211 insertions(+), 114 deletions(-) diff --git a/libindy_vdr/src/ffi/mod.rs b/libindy_vdr/src/ffi/mod.rs index bf563716..7b91fe3e 100644 --- a/libindy_vdr/src/ffi/mod.rs +++ b/libindy_vdr/src/ffi/mod.rs @@ -17,6 +17,7 @@ mod error; mod ledger; mod pool; mod requests; +mod resolver; use self::error::{set_last_error, ErrorCode}; diff --git a/libindy_vdr/src/ffi/pool.rs b/libindy_vdr/src/ffi/pool.rs index 6654f3a9..58b0da14 100644 --- a/libindy_vdr/src/ffi/pool.rs +++ b/libindy_vdr/src/ffi/pool.rs @@ -22,7 +22,7 @@ pub struct PoolHandle(pub i64); impl_sequence_handle!(PoolHandle, FFI_PH_COUNTER); -static POOLS: Lazy>> = +pub static POOLS: Lazy>> = Lazy::new(|| RwLock::new(BTreeMap::new())); #[derive(Serialize, Deserialize, Debug, Clone)] diff --git a/libindy_vdr/src/ffi/resolver.rs b/libindy_vdr/src/ffi/resolver.rs index 6ebf2726..3dcf4e33 100644 --- a/libindy_vdr/src/ffi/resolver.rs +++ b/libindy_vdr/src/ffi/resolver.rs @@ -1,57 +1,63 @@ use crate::common::error::prelude::*; use crate::resolver::resolver::PoolRunnerResolver as Resolver; -use std::sync::RwLock; - -use std::collections::BTreeMap; use super::error::{set_last_error, ErrorCode}; use super::pool::{PoolHandle, POOLS}; use crate::ffi::c_char; use ffi_support::{rust_string_to_c, FfiStr}; -use once_cell::sync::Lazy; - -new_handle_type!(ResolverHandle, FFI_PH_COUNTER); -static RESOLVERS: Lazy>> = - Lazy::new(|| RwLock::new(BTreeMap::new())); #[no_mangle] -pub extern "C" fn indy_vdr_resolver_create(pool_handle: usize, handle_p: *mut usize) -> ErrorCode { +pub extern "C" fn indy_vdr_resolve( + pool_handle: usize, + did: FfiStr, + cb: Option, + cb_id: i64, +) -> ErrorCode { catch_err! { - trace!("Create resolver"); - let pools = read_lock!(POOLS)?; - let pool = pools.get(&PoolHandle(pool_handle)) - .ok_or_else(|| input_err("Unknown pool handle"))?; - let resolver = Resolver::new(pool); - let handle = ResolverHandle::next(); - let mut resolvers = write_lock!(RESOLVERS)?; - resolvers.insert(handle, resolver); - unsafe { - *handle_p = *handle; - } + trace!("Resolve DID: {:#?}", did); + let cb = cb.ok_or_else(|| input_err("No callback provided")).unwrap(); + let pools = read_lock!(POOLS)?; + let pool = pools.get(&PoolHandle(pool_handle)).ok_or_else(|| input_err("Unknown pool handle"))?; + let resolver = Resolver::new(pool); + resolver + .resolve( + did.as_str(), + Box::new(move |result| { + let (errcode, reply) = match result { + Ok(status) => (ErrorCode::Success, status), + Err(err) => { + let code = ErrorCode::from(err.kind()); + set_last_error(Some(err)); + (code, String::new()) + } + }; + cb(cb_id, errcode, rust_string_to_c(reply)) + }), + )?; + Ok(ErrorCode::Success) } } + #[no_mangle] -pub extern "C" fn indy_vdr_resolve( - resolver_handle: usize, - did: FfiStr, +pub extern "C" fn indy_vdr_dereference( + pool_handle: usize, + did_url: FfiStr, cb: Option, cb_id: i64, ) -> ErrorCode { catch_err! { - trace!("Resolve DID: {:#?}", did); + trace!("Dereference DID Url: {:#?}", did_url); let cb = cb.ok_or_else(|| input_err("No callback provided")).unwrap(); - - let resolvers = read_lock!(RESOLVERS)?; - let resolver = resolvers.get(&ResolverHandle(resolver_handle)) - .ok_or_else(|| input_err("Unknown resolver handle"))?; - + let pools = read_lock!(POOLS)?; + let pool = pools.get(&PoolHandle(pool_handle)).ok_or_else(|| input_err("Unknown pool handle"))?; + let resolver = Resolver::new(pool); resolver - .resolve( - did.as_str(), + .dereference( + did_url.as_str(), Box::new(move |result| { let (errcode, reply) = match result { Ok(status) => (ErrorCode::Success, status), @@ -63,24 +69,9 @@ pub extern "C" fn indy_vdr_resolve( }; cb(cb_id, errcode, rust_string_to_c(reply)) }), - ) - .unwrap(); + )?; Ok(ErrorCode::Success) } } - -// #[no_mangle] -// pub extern "C" fn indy_vdr_dereference( -// resolver_handle: i64, -// did_url: FfiStr, -// cb: Option, -// cb_id: i64, -// ) -> ErrorCode { -// catch_err! { -// trace!("Dereference DID Url: {:#?}", did_url); -// let cb = cb.ok_or_else(|| input_err("No callback provided"))?; -// Ok(ErrorCode::Success) -// } -// } diff --git a/libindy_vdr/src/resolver/resolver.rs b/libindy_vdr/src/resolver/resolver.rs index 2e67ca31..bab7cc69 100644 --- a/libindy_vdr/src/resolver/resolver.rs +++ b/libindy_vdr/src/resolver/resolver.rs @@ -87,7 +87,7 @@ impl PoolResolver { Ok(serde_json::to_string_pretty(&result).unwrap()) } - pub fn _resolve(&self, did: &str) -> VdrResult<(Result, ContentMetadata)> { + fn _resolve(&self, did: &str) -> VdrResult<(Result, ContentMetadata)> { let did_url = DidUrl::from_str(did)?; let builder = self.pool.get_request_builder(); @@ -311,31 +311,43 @@ pub struct PoolRunnerResolver<'a> { } impl<'a> PoolRunnerResolver<'a> { - pub fn new(runner: &'a PoolRunner) -> PoolRunnerResolver { + pub fn new(runner: &'a PoolRunner) -> PoolRunnerResolver<'a> { PoolRunnerResolver { runner } } - // pub fn dereference(&self, did_url: &str, callback: Callback) -> VdrResult { - // let (data, metadata) = self._resolve(did_url)?; - - // let content = match data { - // Result::Content(c) => Some(c), - // _ => None, - // }; + pub fn dereference( + &'a self, + did_url: &str, + callback: Callback>, + ) -> VdrResult<()> { + self._resolve( + did_url, + Box::new(move |result| { + let (data, metadata) = result.unwrap(); + let content = match data { + Result::Content(c) => Some(c), + _ => None, + }; - // let result = DereferencingResult { - // dereferencing_metadata: None, - // content_stream: content, - // content_metadata: Some(metadata), - // }; + let result = DereferencingResult { + dereferencing_metadata: None, + content_stream: content, + content_metadata: Some(metadata), + }; - // Ok(serde_json::to_string_pretty(&result).unwrap()) - // } + callback(Ok(serde_json::to_string_pretty(&result).unwrap())) + }), + ) + } - pub fn resolve(&self, did: &str, callback: Callback>) -> VdrResult<()> { + pub fn resolve( + &'a self, + did: &str, + callback: Callback>, + ) -> VdrResult<()> { self._resolve( did, - Box::new(|result| { + Box::new(move |result| { let (data, metadata) = result.unwrap(); let diddoc = match data { Result::DidDocument(doc) => Some(doc.to_value().unwrap()), @@ -353,7 +365,7 @@ impl<'a> PoolRunnerResolver<'a> { } fn _resolve( - &self, + &'a self, did: &str, callback: Callback>, ) -> VdrResult<()> { @@ -367,56 +379,99 @@ impl<'a> PoolRunnerResolver<'a> { Box::new( move |result: VdrResult<(RequestResult, Option)>| { match result { - Ok((res, _)) => { - match res { + Ok((reply, _)) => { + match reply { RequestResult::Reply(reply_data) => { let data = parse_ledger_data(&reply_data).unwrap(); - let (result, object_type) = match txn_type.as_str() { - constants::GET_NYM => { - let get_nym_result: GetNymResultV1 = - serde_json::from_str(data.as_str().unwrap()) - .unwrap(); - - let endpoint: Option = - if get_nym_result.diddoc_content.is_none() { - // Legacy: Try to find an attached ATTRIBUTE transacation with raw endpoint - // self.fetch_legacy_endpoint(&did_url.id).ok() - None - } else { - None - }; - + if txn_type.as_str() == constants::GET_NYM { + let get_nym_result: GetNymResultV1 = + serde_json::from_str(data.as_str().unwrap()).unwrap(); + + // let did = did_url.id.clone(); + if get_nym_result.diddoc_content.is_none() { + // Legacy: Try to find an attached ATTRIBUTE transacation with raw endpoint + // self.fetch_legacy_endpoint( + // &did, + // Box::new(move |result| { + // let did_document = DidDocument::new( + // &did_url.namespace, + // &get_nym_result.dest, + // &get_nym_result.verkey, + // result.ok(), + // None, + // ); + + // let metadata = ContentMetadata { + // node_response: serde_json::from_str( + // &reply_data, + // ) + // .unwrap(), + // object_type: String::from("NYM"), + // }; + + // let result = + // Some(Result::DidDocument(did_document)); + + // let result_with_metadata = + // (result.unwrap(), metadata); + // callback(Ok(result_with_metadata)); + // }), + // ); + } else { let did_document = DidDocument::new( &did_url.namespace, &get_nym_result.dest, &get_nym_result.verkey, - endpoint, + None, None, ); - (Result::DidDocument(did_document), String::from("NYM")) - } - constants::GET_CRED_DEF => { - (Result::Content(data), String::from("CRED_DEF")) - } - constants::GET_SCHEMA => { - (Result::Content(data), String::from("SCHEMA")) - } - constants::GET_REVOC_REG_DEF => { - (Result::Content(data), String::from("REVOC_REG_DEF")) - } - constants::GET_REVOC_REG_DELTA => { - (Result::Content(data), String::from("REVOC_REG_DELTA")) - } - _ => (Result::Content(data), String::from("UNKOWN")), - }; - let metadata = ContentMetadata { - node_response: serde_json::from_str(&reply_data).unwrap(), - object_type, - }; + let metadata = ContentMetadata { + node_response: serde_json::from_str(&reply_data) + .unwrap(), + object_type: String::from("NYM"), + }; - let result_with_metadata = (result, metadata); - callback(Ok(result_with_metadata)); + let result = Some(Result::DidDocument(did_document)); + + let result_with_metadata = (result.unwrap(), metadata); + callback(Ok(result_with_metadata)); + } + } else { + let (result, object_type) = match txn_type.as_str() { + constants::GET_CRED_DEF => ( + Some(Result::Content(data)), + String::from("CRED_DEF"), + ), + constants::GET_SCHEMA => ( + Some(Result::Content(data)), + String::from("SCHEMA"), + ), + constants::GET_REVOC_REG_DEF => ( + Some(Result::Content(data)), + String::from("REVOC_REG_DEF"), + ), + constants::GET_REVOC_REG_DELTA => ( + Some(Result::Content(data)), + String::from("REVOC_REG_DELTA"), + ), + _ => ( + Some(Result::Content(data)), + String::from("UNKOWN"), + ), + }; + + let metadata = ContentMetadata { + node_response: serde_json::from_str(&reply_data) + .unwrap(), + object_type, + }; + + if result.is_some() { + let result_with_metadata = (result.unwrap(), metadata); + callback(Ok(result_with_metadata)); + } + } } RequestResult::Failed(err) => callback(Err(err)), } @@ -427,10 +482,39 @@ impl<'a> PoolRunnerResolver<'a> { ), ) } + + fn fetch_legacy_endpoint( + &'a self, + did: &DidValue, + cb: Callback> + ) -> VdrResult<()> { + let builder = RequestBuilder::default(); + let request = builder.build_get_attrib_request( + None, + did, + Some(String::from(LEGACY_INDY_SERVICE)), + None, + None, + )?; + self.runner.send_request( + request, + Box::new(move |result| match result { + Ok((res, _)) => match res { + RequestResult::Reply(reply_data) => { + let endpoint_data = parse_ledger_data(&reply_data).unwrap(); + let endpoint_data: Endpoint = + serde_json::from_str(endpoint_data.as_str().unwrap()).unwrap(); + cb(Ok(endpoint_data)); + } + RequestResult::Failed(err) => cb(Err(err)), + }, + Err(err) => cb(Err(err)), + }), + ) + } } type Callback = Box ()) + Send>; -// type SendReqResponse = VdrResult<(RequestResult, Option)>; fn parse_ledger_data(ledger_data: &str) -> VdrResult { let v: SJsonValue = serde_json::from_str(&ledger_data) diff --git a/wrappers/python/demo/test.py b/wrappers/python/demo/test.py index 71294704..28023171 100644 --- a/wrappers/python/demo/test.py +++ b/wrappers/python/demo/test.py @@ -33,6 +33,7 @@ LedgerType, ) from indy_vdr.pool import Pool, open_pool +from indy_vdr.resolver import Resolver def log(*args): @@ -187,9 +188,16 @@ async def basic_test(transactions_path): req = build_get_frozen_ledgers_request(identifier) log("Get Frozen Ledgers request:", req.body) - req = build_pool_upgrade_request(identifier, 'up', '2.0.0', 'start', 'abc', None, {}, None, False, False, None) + req = build_pool_upgrade_request( + identifier, "up", "2.0.0", "start", "abc", None, {}, None, False, False, None + ) log("Pool Upgrade request:", req.body) + resolver = Resolver(pool.handle) + doc = await resolver.resolve("did:indy:sovrin:XvSeT51zDWVTXatLWPknWb") + + log(json.dumps(doc, indent=2)) + # req = build_rich_schema_request( # None, "did:sov:some_hash", '{"some": 1}', "test", "version", "sch", "1.0.0" # ) diff --git a/wrappers/python/indy_vdr/bindings.py b/wrappers/python/indy_vdr/bindings.py index 56daf2c5..f74e20a0 100644 --- a/wrappers/python/indy_vdr/bindings.py +++ b/wrappers/python/indy_vdr/bindings.py @@ -264,12 +264,23 @@ def resolver_create(pool_handle: PoolHandle) -> ResolverHandle: return handle -def resolve(resolver_handle: ResolverHandle, did_url: str) -> asyncio.Future: - """Resovle a DID to retrieve a DID Doc.""" +def resolve(resolver_handle: ResolverHandle, did: str) -> asyncio.Future: + """Resolve a DID to retrieve a DID Doc.""" return do_call_async( "indy_vdr_resolve", resolver_handle, - did_url, + encode_str(did), + return_type=lib_string, + post_process=str, + ) + + +def dereference(pool_handle: PoolHandle, did_url: str) -> asyncio.Future: + """Dereference a DID Urk to retrieve a ledger object.""" + return do_call_async( + "indy_vdr_dereference", + pool_handle, + encode_str(did_url), return_type=lib_string, post_process=str, ) diff --git a/wrappers/python/indy_vdr/error.py b/wrappers/python/indy_vdr/error.py index 33fc5863..1756a793 100644 --- a/wrappers/python/indy_vdr/error.py +++ b/wrappers/python/indy_vdr/error.py @@ -16,6 +16,8 @@ class VdrErrorCode(IntEnum): POOL_REQUEST_FAILED = 31 POOL_TIMEOUT = 32 WRAPPER = 99 + RESOLVER = 9 + class VdrError(Exception): diff --git a/wrappers/python/indy_vdr/resolver.py b/wrappers/python/indy_vdr/resolver.py index 20475c0a..5dd8497e 100644 --- a/wrappers/python/indy_vdr/resolver.py +++ b/wrappers/python/indy_vdr/resolver.py @@ -4,9 +4,9 @@ class Resolver: """did:indy compliant resolver interface for a specific network.""" - def __init__(self, handle: bindings.ResolverHandle): + def __init__(self, pool_handle: bindings.PoolHandle): """Initialize the pool instance.""" - self.handle = handle + self.handle = pool_handle async def resolve(self, did: str) -> dict: """Resolve a DID to retrieve a DID Doc.""" From e3a95ab265bf0d52e1c66128e798e0a6d3a699e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20W=C3=B6rner?= Date: Tue, 15 Mar 2022 07:50:00 +0100 Subject: [PATCH 034/117] optional parameters in get_nym MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- indy-vdr-proxy/Cargo.toml | 3 ++- indy-vdr-proxy/src/handlers.rs | 24 +++++++++++++++++++++--- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/indy-vdr-proxy/Cargo.toml b/indy-vdr-proxy/Cargo.toml index 3e3835c4..ddecc084 100644 --- a/indy-vdr-proxy/Cargo.toml +++ b/indy-vdr-proxy/Cargo.toml @@ -14,7 +14,7 @@ default = ["fetch", "zmq_vendored"] [dependencies] clap = "3.1" -env_logger = "0.9" +env_logger = "0.10" futures-util = "0.3" hyper = { version = "0.14", features = ["http1", "http2", "server"] } hyper-tls = { version = "0.5", optional = true } @@ -23,6 +23,7 @@ percent-encoding = "2" serde_json = "1.0" tokio = { version = "1.0", features = ["macros", "rt-multi-thread", "signal"] } indy-vdr = { path = "../libindy_vdr", default-features = false, features = ["log"] } +url = "2.2.2" [target.'cfg(unix)'.dependencies] hyper-unix-connector = "0.2" diff --git a/indy-vdr-proxy/src/handlers.rs b/indy-vdr-proxy/src/handlers.rs index 1f3856e2..8d773770 100644 --- a/indy-vdr-proxy/src/handlers.rs +++ b/indy-vdr-proxy/src/handlers.rs @@ -1,12 +1,14 @@ extern crate percent_encoding; use std::cell::RefCell; +use std::collections::HashMap; use std::convert::TryFrom; use std::rc::Rc; use std::time::UNIX_EPOCH; use hyper::{Body, Method, Request, Response, StatusCode}; use percent_encoding::percent_decode_str; +use url::Url; use super::AppState; use indy_vdr::common::error::prelude::*; @@ -272,11 +274,16 @@ async fn get_attrib(pool: &T, dest: &str, raw: &str) -> VdrResult(pool: &T, nym: &str) -> VdrResult { +async fn get_nym( + pool: &T, + nym: &str, + seq_no: Option, + timestamp: Option, +) -> VdrResult { let nym = DidValue::from_str(nym)?; let request = pool .get_request_builder() - .build_get_nym_request(None, &nym, None, None)?; + .build_get_nym_request(None, &nym, seq_no, timestamp)?; let result = perform_ledger_request(pool, &request).await?; Ok(result.into()) } @@ -396,6 +403,11 @@ pub async fn handle_request( .filter(|p| !p.is_empty()) }); let query = req.uri().query(); + let query_pairs: HashMap<_, _> = Url::parse(req.uri().to_string().as_str()) + .unwrap() + .query_pairs() + .into_owned() + .collect(); let format = if query == Some("html") { ResponseFormat::Html } else if query == Some("raw") { @@ -481,7 +493,13 @@ pub async fn handle_request( } (&Method::GET, "nym") => { if let Some(nym) = parts.next() { - get_nym(pool, &*nym).await + let seq_no: Option = query_pairs + .get("seq_no") + .and_then(|seq_no| seq_no.as_str().parse().ok()); + let timestamp: Option = query_pairs + .get("timestamp") + .and_then(|ts| ts.as_str().parse().ok()); + get_nym(pool, &*nym, seq_no, timestamp).await } else { http_status(StatusCode::NOT_FOUND) } From c10986880466a1d311d3e3d096c886cedc8ebc73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20W=C3=B6rner?= Date: Tue, 15 Mar 2022 07:50:45 +0100 Subject: [PATCH 035/117] started clean up of ffi resolver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- libindy_vdr/src/ffi/resolver.rs | 2 +- libindy_vdr/src/resolver/resolver.rs | 28 ++++++++++++---------------- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/libindy_vdr/src/ffi/resolver.rs b/libindy_vdr/src/ffi/resolver.rs index 3dcf4e33..53c7a77d 100644 --- a/libindy_vdr/src/ffi/resolver.rs +++ b/libindy_vdr/src/ffi/resolver.rs @@ -54,7 +54,7 @@ pub extern "C" fn indy_vdr_dereference( let cb = cb.ok_or_else(|| input_err("No callback provided")).unwrap(); let pools = read_lock!(POOLS)?; let pool = pools.get(&PoolHandle(pool_handle)).ok_or_else(|| input_err("Unknown pool handle"))?; - let resolver = Resolver::new(pool); + let resolver =Resolver::new(pool); resolver .dereference( did_url.as_str(), diff --git a/libindy_vdr/src/resolver/resolver.rs b/libindy_vdr/src/resolver/resolver.rs index bab7cc69..a24de4c9 100644 --- a/libindy_vdr/src/resolver/resolver.rs +++ b/libindy_vdr/src/resolver/resolver.rs @@ -311,12 +311,12 @@ pub struct PoolRunnerResolver<'a> { } impl<'a> PoolRunnerResolver<'a> { - pub fn new(runner: &'a PoolRunner) -> PoolRunnerResolver<'a> { + pub fn new(runner: &'a PoolRunner) -> PoolRunnerResolver { PoolRunnerResolver { runner } } pub fn dereference( - &'a self, + &self, did_url: &str, callback: Callback>, ) -> VdrResult<()> { @@ -340,11 +340,7 @@ impl<'a> PoolRunnerResolver<'a> { ) } - pub fn resolve( - &'a self, - did: &str, - callback: Callback>, - ) -> VdrResult<()> { + pub fn resolve(&self, did: &str, callback: Callback>) -> VdrResult<()> { self._resolve( did, Box::new(move |result| { @@ -365,9 +361,9 @@ impl<'a> PoolRunnerResolver<'a> { } fn _resolve( - &'a self, + &self, did: &str, - callback: Callback>, + callback: Box) -> ()) + Send + 'static>, ) -> VdrResult<()> { let did_url = DidUrl::from_str(did)?; @@ -390,7 +386,7 @@ impl<'a> PoolRunnerResolver<'a> { // let did = did_url.id.clone(); if get_nym_result.diddoc_content.is_none() { // Legacy: Try to find an attached ATTRIBUTE transacation with raw endpoint - // self.fetch_legacy_endpoint( + // self._fetch_legacy_endpoint( // &did, // Box::new(move |result| { // let did_document = DidDocument::new( @@ -483,10 +479,10 @@ impl<'a> PoolRunnerResolver<'a> { ) } - fn fetch_legacy_endpoint( - &'a self, + fn _fetch_legacy_endpoint( + &self, did: &DidValue, - cb: Callback> + callback: Callback>, ) -> VdrResult<()> { let builder = RequestBuilder::default(); let request = builder.build_get_attrib_request( @@ -504,11 +500,11 @@ impl<'a> PoolRunnerResolver<'a> { let endpoint_data = parse_ledger_data(&reply_data).unwrap(); let endpoint_data: Endpoint = serde_json::from_str(endpoint_data.as_str().unwrap()).unwrap(); - cb(Ok(endpoint_data)); + callback(Ok(endpoint_data)); } - RequestResult::Failed(err) => cb(Err(err)), + RequestResult::Failed(err) => callback(Err(err)), }, - Err(err) => cb(Err(err)), + Err(err) => callback(Err(err)), }), ) } From a20a7b3357c77ae89de537c64a4a10ba7fe87c29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20W=C3=B6rner?= Date: Tue, 15 Mar 2022 08:44:25 +0100 Subject: [PATCH 036/117] remove chrono dependency and use time-rs instead MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- libindy_vdr/Cargo.toml | 1 + libindy_vdr/src/resolver/resolver.rs | 30 +++++++++++++++------------- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/libindy_vdr/Cargo.toml b/libindy_vdr/Cargo.toml index 01347f5b..ce85eb09 100644 --- a/libindy_vdr/Cargo.toml +++ b/libindy_vdr/Cargo.toml @@ -49,6 +49,7 @@ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" sha3 = "0.10" thiserror = "1.0" +time = { version = "0.3.7", features = ["parsing"] } url = "2.2.2" urlencoding = "2.1.0" zmq = "0.9" diff --git a/libindy_vdr/src/resolver/resolver.rs b/libindy_vdr/src/resolver/resolver.rs index a24de4c9..e8b05ce7 100644 --- a/libindy_vdr/src/resolver/resolver.rs +++ b/libindy_vdr/src/resolver/resolver.rs @@ -2,6 +2,8 @@ use crate::utils::Qualifiable; use chrono::{DateTime, Utc}; use futures_executor::block_on; use serde_json::Value as SJsonValue; +use time::format_description::well_known::Rfc3339; +use time::OffsetDateTime; use super::did::{DidUrl, LedgerObject, QueryParameter}; use super::did_document::{DidDocument, LEGACY_INDY_SERVICE}; @@ -197,8 +199,8 @@ fn build_request(did: &DidUrl, builder: &RequestBuilder) -> VdrResult VdrResult VdrResult = did .query .get(&QueryParameter::VersionTime) - .and_then(|d| DateTime::parse_from_rfc3339(d).ok()) - .and_then(|d| Some(d.timestamp())) + .and_then(|d| OffsetDateTime::parse(d, &Rfc3339).ok()) + .and_then(|d| Some(d.unix_timestamp())) .and_then(|d| Some(d as u64)); builder.build_get_nym_request(Option::None, &did.id, seq_no, timestamp) @@ -529,15 +531,15 @@ fn parse_ledger_data(ledger_data: &str) -> VdrResult { fn parse_or_now(datetime: Option<&String>) -> VdrResult { match datetime { Some(datetime) => { - let dt = DateTime::parse_from_rfc3339(datetime).map_err(|_| { + let dt = OffsetDateTime::parse(datetime, &Rfc3339).map_err(|_| { err_msg( VdrErrorKind::Resolver, format!("Could not parse datetime {}", datetime), ) })?; - Ok(dt.timestamp()) + Ok(dt.unix_timestamp()) } - None => Ok(Utc::now().timestamp()), + None => Ok(OffsetDateTime::now_utc().unix_timestamp()), } } @@ -570,16 +572,16 @@ mod tests { assert_eq!(constants::GET_REVOC_REG, request.txn_type); assert_eq!( - DateTime::parse_from_rfc3339(datetime_as_str) + OffsetDateTime::parse(datetime_as_str, &Rfc3339) .unwrap() - .timestamp(), + .unix_timestamp(), timestamp ); } #[rstest] fn build_get_revoc_reg_without_version_time(request_builder: RequestBuilder) { - let now = chrono::Utc::now().timestamp(); + let now = OffsetDateTime::now_utc().unix_timestamp(); let did_url_as_str = "did:indy:idunion:Dk1fRRTtNazyMuK2cr64wp/anoncreds/v0/REV_REG_ENTRY/104/revocable/a4e25e54"; let did_url = DidUrl::from_str(did_url_as_str).unwrap(); @@ -616,7 +618,7 @@ mod tests { #[rstest] fn build_get_revoc_reg_delta_request_with_from_only(request_builder: RequestBuilder) { - let now = chrono::Utc::now().timestamp(); + let now = OffsetDateTime::now_utc().unix_timestamp(); let from_as_str = "2019-12-20T19:17:47Z"; let did_url_as_str = format!("did:indy:idunion:Dk1fRRTtNazyMuK2cr64wp/anoncreds/v0/REV_REG_ENTRY/104/revocable/a4e25e54?from={}",from_as_str); let did_url = DidUrl::from_str(&did_url_as_str).unwrap(); @@ -633,7 +635,7 @@ mod tests { #[rstest] fn build_get_revoc_reg_delta_request_without_parameter(request_builder: RequestBuilder) { - let now = chrono::Utc::now().timestamp(); + let now = OffsetDateTime::now_utc().unix_timestamp(); let did_url_as_str = "did:indy:idunion:Dk1fRRTtNazyMuK2cr64wp/anoncreds/v0/REV_REG_DELTA/104/revocable/a4e25e54"; let did_url = DidUrl::from_str(did_url_as_str).unwrap(); let request = build_request(&did_url, &request_builder).unwrap(); From 6450e16460f33329aa6a0ef6add62e01045a3de9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20W=C3=B6rner?= Date: Tue, 15 Mar 2022 09:16:52 +0100 Subject: [PATCH 037/117] simplifying module imports MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- libindy_vdr/src/ffi/resolver.rs | 2 +- libindy_vdr/src/resolver/mod.rs | 8 +- libindy_vdr/src/resolver/resolver.rs | 309 ++++++++++++++------------- 3 files changed, 164 insertions(+), 155 deletions(-) diff --git a/libindy_vdr/src/ffi/resolver.rs b/libindy_vdr/src/ffi/resolver.rs index 53c7a77d..b6bb66d0 100644 --- a/libindy_vdr/src/ffi/resolver.rs +++ b/libindy_vdr/src/ffi/resolver.rs @@ -1,5 +1,5 @@ use crate::common::error::prelude::*; -use crate::resolver::resolver::PoolRunnerResolver as Resolver; +use crate::resolver::PoolRunnerResolver as Resolver; use super::error::{set_last_error, ErrorCode}; use super::pool::{PoolHandle, POOLS}; diff --git a/libindy_vdr/src/resolver/mod.rs b/libindy_vdr/src/resolver/mod.rs index 55aca841..bdf64e7f 100644 --- a/libindy_vdr/src/resolver/mod.rs +++ b/libindy_vdr/src/resolver/mod.rs @@ -1,4 +1,6 @@ -pub mod resolver; +mod resolver; -pub mod did; -pub mod did_document; +mod did; +mod did_document; + +pub use self::resolver::{PoolResolver, PoolRunnerResolver}; diff --git a/libindy_vdr/src/resolver/resolver.rs b/libindy_vdr/src/resolver/resolver.rs index e8b05ce7..55ab45ce 100644 --- a/libindy_vdr/src/resolver/resolver.rs +++ b/libindy_vdr/src/resolver/resolver.rs @@ -46,7 +46,7 @@ pub struct DereferencingResult { content_metadata: Option, } -// DID (URL) Resolver for did:indy method +// DID (URL) Resolver interface for a pool compliant with did:indy method spec pub struct PoolResolver { pool: T, } @@ -56,6 +56,7 @@ impl PoolResolver { PoolResolver { pool } } + // Dereference a DID Url and return a serialized `DereferencingResult` pub fn dereference(&self, did_url: &str) -> VdrResult { let (data, metadata) = self._resolve(did_url)?; @@ -73,6 +74,7 @@ impl PoolResolver { Ok(serde_json::to_string_pretty(&result).unwrap()) } + // Resolve a DID and return a serialized `ResolutionResult` pub fn resolve(&self, did: &str) -> VdrResult { let (data, metadata) = self._resolve(did)?; @@ -89,13 +91,14 @@ impl PoolResolver { Ok(serde_json::to_string_pretty(&result).unwrap()) } + // Internal method to resolve and dereference fn _resolve(&self, did: &str) -> VdrResult<(Result, ContentMetadata)> { let did_url = DidUrl::from_str(did)?; let builder = self.pool.get_request_builder(); let request = build_request(&did_url, &builder)?; - let ledger_data = handle_request(&self.pool, &request)?; + let ledger_data = self.handle_request(&request)?; let data = parse_ledger_data(&ledger_data)?; let (result, object_type) = match request.txn_type.as_str() { @@ -148,166 +151,30 @@ impl PoolResolver { None, None, )?; - let ledger_data = handle_request(&self.pool, &request)?; + let ledger_data = self.handle_request(&request)?; let endpoint_data = parse_ledger_data(&ledger_data)?; let endpoint_data: Endpoint = serde_json::from_str(endpoint_data.as_str().unwrap()) .map_err(|_| err_msg(VdrErrorKind::Resolver, "Could not parse endpoint data"))?; Ok(endpoint_data) } -} - -fn build_request(did: &DidUrl, builder: &RequestBuilder) -> VdrResult { - let request = if did.path.is_some() { - match LedgerObject::from_str(did.path.as_ref().unwrap().as_str())? { - LedgerObject::Schema(schema) => builder.build_get_schema_request( - None, - &SchemaId::new(&did.id, &schema.name, &schema.version), - ), - LedgerObject::ClaimDef(claim_def) => builder.build_get_cred_def_request( - None, - &CredentialDefinitionId::from_str( - format!( - "{}:3:CL:{}:{}", - &did.id, claim_def.schema_seq_no, claim_def.name - ) - .as_str(), - ) - .unwrap(), - ), - LedgerObject::RevRegDef(rev_reg_def) => builder.build_get_revoc_reg_def_request( - None, - &RevocationRegistryId::from_str( - format!( - "{}:4:{}:3:CL:{}:{}:CL_ACCUM:{}", - &did.id, - &did.id, - rev_reg_def.schema_seq_no, - rev_reg_def.claim_def_name, - rev_reg_def.tag - ) - .as_str(), - ) - .unwrap(), - ), - LedgerObject::RevRegEntry(rev_reg_entry) => { - // If From or To parameters, return RevRegDelta request - if did.query.contains_key(&QueryParameter::From) - || did.query.contains_key(&QueryParameter::To) - { - let mut from: Option = None; - if did.query.contains_key(&QueryParameter::From) { - from = did - .query - .get(&QueryParameter::From) - .and_then(|d| OffsetDateTime::parse(d, &Rfc3339).ok()) - .and_then(|d| Some(d.unix_timestamp())); - } - let to = parse_or_now(did.query.get(&QueryParameter::To))?; - - builder.build_get_revoc_reg_delta_request( - None, - &RevocationRegistryId::from_str( - format!( - "{}:4:{}:3:CL:{}:{}:CL_ACCUM:{}", - &did.id, - &did.id, - rev_reg_entry.schema_seq_no, - rev_reg_entry.claim_def_name, - rev_reg_entry.tag - ) - .as_str(), - ) - .unwrap(), - from, - to, - ) - // Else return RevRegEntry request - } else { - let timestamp = parse_or_now(did.query.get(&QueryParameter::VersionTime))?; - - builder.build_get_revoc_reg_request( - None, - &RevocationRegistryId::from_str( - format!( - "{}:4:{}:3:CL:{}:{}:CL_ACCUM:{}", - &did.id, - &did.id, - rev_reg_entry.schema_seq_no, - rev_reg_entry.claim_def_name, - rev_reg_entry.tag - ) - .as_str(), - ) - .unwrap(), - timestamp, - ) - } - } - // This path is deprecated. Deltas can be retrieved through RevRegEntry - LedgerObject::RevRegDelta(rev_reg_delta) => { - let mut from: Option = None; - if did.query.contains_key(&QueryParameter::From) { - from = did - .query - .get(&QueryParameter::From) - .and_then(|d| OffsetDateTime::parse(d, &Rfc3339).ok()) - .and_then(|d| Some(d.unix_timestamp())); - } - - let to = parse_or_now(did.query.get(&QueryParameter::To))?; - - builder.build_get_revoc_reg_delta_request( - None, - &RevocationRegistryId::from_str( - format!( - "{}:4:{}:3:CL:{}:{}:CL_ACCUM:{}", - &did.id, - &did.id, - rev_reg_delta.schema_seq_no, - rev_reg_delta.claim_def_name, - rev_reg_delta.tag - ) - .as_str(), - ) - .unwrap(), - from, - to, - ) - } + fn handle_request(&self, request: &PreparedRequest) -> VdrResult { + let (result, _timing) = block_on(self.request_transaction(&request))?; + match result { + RequestResult::Reply(data) => Ok(data), + RequestResult::Failed(error) => Err(error), } - } else { - let seq_no: Option = did - .query - .get(&QueryParameter::VersionId) - .and_then(|v| v.parse().ok()); - let timestamp: Option = did - .query - .get(&QueryParameter::VersionTime) - .and_then(|d| OffsetDateTime::parse(d, &Rfc3339).ok()) - .and_then(|d| Some(d.unix_timestamp())) - .and_then(|d| Some(d as u64)); - - builder.build_get_nym_request(Option::None, &did.id, seq_no, timestamp) - }; - request -} - -fn handle_request(pool: &T, request: &PreparedRequest) -> VdrResult { - let (result, _timing) = block_on(request_transaction(pool, &request))?; - match result { - RequestResult::Reply(data) => Ok(data), - RequestResult::Failed(error) => Err(error), } -} -async fn request_transaction( - pool: &T, - request: &PreparedRequest, -) -> VdrResult<(RequestResult, Option)> { - perform_ledger_request(pool, &request).await + async fn request_transaction( + &self, + request: &PreparedRequest, + ) -> VdrResult<(RequestResult, Option)> { + perform_ledger_request(&self.pool, &request).await + } } +// DID (URL) Resolver interface using callbacks for a PoolRunner compliant with did:indy method spec pub struct PoolRunnerResolver<'a> { runner: &'a PoolRunner, } @@ -317,6 +184,7 @@ impl<'a> PoolRunnerResolver<'a> { PoolRunnerResolver { runner } } + // Dereference a DID Url and return a serialized `DereferencingResult` pub fn dereference( &self, did_url: &str, @@ -342,6 +210,7 @@ impl<'a> PoolRunnerResolver<'a> { ) } + // Resolve a DID and return a serialized `ResolutionResult` pub fn resolve(&self, did: &str, callback: Callback>) -> VdrResult<()> { self._resolve( did, @@ -385,6 +254,7 @@ impl<'a> PoolRunnerResolver<'a> { let get_nym_result: GetNymResultV1 = serde_json::from_str(data.as_str().unwrap()).unwrap(); + // TODO: Fix fetch_legacy_endpoint // let did = did_url.id.clone(); if get_nym_result.diddoc_content.is_none() { // Legacy: Try to find an attached ATTRIBUTE transacation with raw endpoint @@ -514,6 +384,143 @@ impl<'a> PoolRunnerResolver<'a> { type Callback = Box ()) + Send>; +fn build_request(did: &DidUrl, builder: &RequestBuilder) -> VdrResult { + let request = if did.path.is_some() { + match LedgerObject::from_str(did.path.as_ref().unwrap().as_str())? { + LedgerObject::Schema(schema) => builder.build_get_schema_request( + None, + &SchemaId::new(&did.id, &schema.name, &schema.version), + ), + LedgerObject::ClaimDef(claim_def) => builder.build_get_cred_def_request( + None, + &CredentialDefinitionId::from_str( + format!( + "{}:3:CL:{}:{}", + &did.id, claim_def.schema_seq_no, claim_def.name + ) + .as_str(), + ) + .unwrap(), + ), + LedgerObject::RevRegDef(rev_reg_def) => builder.build_get_revoc_reg_def_request( + None, + &RevocationRegistryId::from_str( + format!( + "{}:4:{}:3:CL:{}:{}:CL_ACCUM:{}", + &did.id, + &did.id, + rev_reg_def.schema_seq_no, + rev_reg_def.claim_def_name, + rev_reg_def.tag + ) + .as_str(), + ) + .unwrap(), + ), + LedgerObject::RevRegEntry(rev_reg_entry) => { + // If From or To parameters, return RevRegDelta request + if did.query.contains_key(&QueryParameter::From) + || did.query.contains_key(&QueryParameter::To) + { + let mut from: Option = None; + if did.query.contains_key(&QueryParameter::From) { + from = did + .query + .get(&QueryParameter::From) + .and_then(|d| OffsetDateTime::parse(d, &Rfc3339).ok()) + .and_then(|d| Some(d.unix_timestamp())); + } + + let to = parse_or_now(did.query.get(&QueryParameter::To))?; + + builder.build_get_revoc_reg_delta_request( + None, + &RevocationRegistryId::from_str( + format!( + "{}:4:{}:3:CL:{}:{}:CL_ACCUM:{}", + &did.id, + &did.id, + rev_reg_entry.schema_seq_no, + rev_reg_entry.claim_def_name, + rev_reg_entry.tag + ) + .as_str(), + ) + .unwrap(), + from, + to, + ) + // Else return RevRegEntry request + } else { + let timestamp = parse_or_now(did.query.get(&QueryParameter::VersionTime))?; + + builder.build_get_revoc_reg_request( + None, + &RevocationRegistryId::from_str( + format!( + "{}:4:{}:3:CL:{}:{}:CL_ACCUM:{}", + &did.id, + &did.id, + rev_reg_entry.schema_seq_no, + rev_reg_entry.claim_def_name, + rev_reg_entry.tag + ) + .as_str(), + ) + .unwrap(), + timestamp, + ) + } + } + // This path is deprecated. Deltas can be retrieved through RevRegEntry + LedgerObject::RevRegDelta(rev_reg_delta) => { + let mut from: Option = None; + if did.query.contains_key(&QueryParameter::From) { + from = did + .query + .get(&QueryParameter::From) + .and_then(|d| OffsetDateTime::parse(d, &Rfc3339).ok()) + .and_then(|d| Some(d.unix_timestamp())); + } + + let to = parse_or_now(did.query.get(&QueryParameter::To))?; + + builder.build_get_revoc_reg_delta_request( + None, + &RevocationRegistryId::from_str( + format!( + "{}:4:{}:3:CL:{}:{}:CL_ACCUM:{}", + &did.id, + &did.id, + rev_reg_delta.schema_seq_no, + rev_reg_delta.claim_def_name, + rev_reg_delta.tag + ) + .as_str(), + ) + .unwrap(), + from, + to, + ) + } + } + } else { + let seq_no: Option = did + .query + .get(&QueryParameter::VersionId) + .and_then(|v| v.parse().ok()); + let timestamp: Option = did + .query + .get(&QueryParameter::VersionTime) + .and_then(|d| OffsetDateTime::parse(d, &Rfc3339).ok()) + .and_then(|d| Some(d.unix_timestamp())) + .and_then(|d| Some(d as u64)); + + builder.build_get_nym_request(Option::None, &did.id, seq_no, timestamp) + }; + request +} + fn parse_ledger_data(ledger_data: &str) -> VdrResult { let v: SJsonValue = serde_json::from_str(&ledger_data) .map_err(|_| err_msg(VdrErrorKind::Resolver, "Could not parse ledger response"))?; From a240037e117c84f1f9e3358b1eac556d2c41cf59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20W=C3=B6rner?= Date: Tue, 15 Mar 2022 09:27:37 +0100 Subject: [PATCH 038/117] format MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- libindy_vdr/src/ffi/resolver.rs | 3 --- libindy_vdr/src/resolver/mod.rs | 4 ++-- libindy_vdr/src/resolver/resolver.rs | 2 ++ 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/libindy_vdr/src/ffi/resolver.rs b/libindy_vdr/src/ffi/resolver.rs index b6bb66d0..5c02e391 100644 --- a/libindy_vdr/src/ffi/resolver.rs +++ b/libindy_vdr/src/ffi/resolver.rs @@ -6,7 +6,6 @@ use super::pool::{PoolHandle, POOLS}; use crate::ffi::c_char; use ffi_support::{rust_string_to_c, FfiStr}; - #[no_mangle] pub extern "C" fn indy_vdr_resolve( pool_handle: usize, @@ -36,12 +35,10 @@ pub extern "C" fn indy_vdr_resolve( }), )?; - Ok(ErrorCode::Success) } } - #[no_mangle] pub extern "C" fn indy_vdr_dereference( pool_handle: usize, diff --git a/libindy_vdr/src/resolver/mod.rs b/libindy_vdr/src/resolver/mod.rs index bdf64e7f..5bf29c62 100644 --- a/libindy_vdr/src/resolver/mod.rs +++ b/libindy_vdr/src/resolver/mod.rs @@ -1,6 +1,6 @@ mod resolver; -mod did; -mod did_document; +pub mod did; +pub mod did_document; pub use self::resolver::{PoolResolver, PoolRunnerResolver}; diff --git a/libindy_vdr/src/resolver/resolver.rs b/libindy_vdr/src/resolver/resolver.rs index 55ab45ce..a57f931f 100644 --- a/libindy_vdr/src/resolver/resolver.rs +++ b/libindy_vdr/src/resolver/resolver.rs @@ -58,6 +58,7 @@ impl PoolResolver { // Dereference a DID Url and return a serialized `DereferencingResult` pub fn dereference(&self, did_url: &str) -> VdrResult { + debug!("PoolResolver: Dereference DID Url {}", did_url); let (data, metadata) = self._resolve(did_url)?; let content = match data { @@ -76,6 +77,7 @@ impl PoolResolver { // Resolve a DID and return a serialized `ResolutionResult` pub fn resolve(&self, did: &str) -> VdrResult { + debug!("PoolResolver: Resolve DID {}", did); let (data, metadata) = self._resolve(did)?; let diddoc = match data { From e9c3e011f36342ecba9c3a60598cd09bf45e8098 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20W=C3=B6rner?= Date: Tue, 15 Mar 2022 11:26:21 +0100 Subject: [PATCH 039/117] ffi without fetching legacy endpoint working MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- wrappers/python/demo/test.py | 1 + 1 file changed, 1 insertion(+) diff --git a/wrappers/python/demo/test.py b/wrappers/python/demo/test.py index 28023171..1b355e24 100644 --- a/wrappers/python/demo/test.py +++ b/wrappers/python/demo/test.py @@ -193,6 +193,7 @@ async def basic_test(transactions_path): ) log("Pool Upgrade request:", req.body) + log("Resolve DID did:indy:sovrin:XvSeT51zDWVTXatLWPknWb") resolver = Resolver(pool.handle) doc = await resolver.resolve("did:indy:sovrin:XvSeT51zDWVTXatLWPknWb") From 877992847968594358f335e9bd8e5476c9f26b52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20W=C3=B6rner?= Date: Tue, 15 Mar 2022 11:54:17 +0100 Subject: [PATCH 040/117] fix query params in proxy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- .github/workflows/build.yml | 2 +- indy-vdr-proxy/src/handlers.rs | 19 +++++---- libindy_vdr/src/ffi/resolver.rs | 2 +- libindy_vdr/src/ledger/request_builder.rs | 7 +++- libindy_vdr/src/resolver/resolver.rs | 51 ++++++++++++----------- 5 files changed, 44 insertions(+), 37 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1522ad29..cdfd3daf 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -6,7 +6,7 @@ env: on: push: - branches: [main, did-indy-only, ffi-resolver] + branches: [main] pull_request: branches: [main] release: diff --git a/indy-vdr-proxy/src/handlers.rs b/indy-vdr-proxy/src/handlers.rs index 8d773770..19889937 100644 --- a/indy-vdr-proxy/src/handlers.rs +++ b/indy-vdr-proxy/src/handlers.rs @@ -8,7 +8,6 @@ use std::time::UNIX_EPOCH; use hyper::{Body, Method, Request, Response, StatusCode}; use percent_encoding::percent_decode_str; -use url::Url; use super::AppState; use indy_vdr::common::error::prelude::*; @@ -403,11 +402,15 @@ pub async fn handle_request( .filter(|p| !p.is_empty()) }); let query = req.uri().query(); - let query_pairs: HashMap<_, _> = Url::parse(req.uri().to_string().as_str()) - .unwrap() - .query_pairs() - .into_owned() - .collect(); + let query_params: HashMap = req + .uri() + .query() + .map(|v| { + url::form_urlencoded::parse(v.as_bytes()) + .into_owned() + .collect() + }) + .unwrap_or_else(HashMap::new); let format = if query == Some("html") { ResponseFormat::Html } else if query == Some("raw") { @@ -493,10 +496,10 @@ pub async fn handle_request( } (&Method::GET, "nym") => { if let Some(nym) = parts.next() { - let seq_no: Option = query_pairs + let seq_no: Option = query_params .get("seq_no") .and_then(|seq_no| seq_no.as_str().parse().ok()); - let timestamp: Option = query_pairs + let timestamp: Option = query_params .get("timestamp") .and_then(|ts| ts.as_str().parse().ok()); get_nym(pool, &*nym, seq_no, timestamp).await diff --git a/libindy_vdr/src/ffi/resolver.rs b/libindy_vdr/src/ffi/resolver.rs index 5c02e391..c1baf75c 100644 --- a/libindy_vdr/src/ffi/resolver.rs +++ b/libindy_vdr/src/ffi/resolver.rs @@ -51,7 +51,7 @@ pub extern "C" fn indy_vdr_dereference( let cb = cb.ok_or_else(|| input_err("No callback provided")).unwrap(); let pools = read_lock!(POOLS)?; let pool = pools.get(&PoolHandle(pool_handle)).ok_or_else(|| input_err("Unknown pool handle"))?; - let resolver =Resolver::new(pool); + let resolver = Resolver::new(pool); resolver .dereference( did_url.as_str(), diff --git a/libindy_vdr/src/ledger/request_builder.rs b/libindy_vdr/src/ledger/request_builder.rs index 04058af2..60f82931 100644 --- a/libindy_vdr/src/ledger/request_builder.rs +++ b/libindy_vdr/src/ledger/request_builder.rs @@ -122,7 +122,8 @@ impl RequestBuilder { )) } - /// Build a new did:indy `NYM` transaction request + /// Build a `NYM` transaction request + /// diddoc_content is only supported for did:indy compliant ledgers pub fn build_nym_request( &self, identifier: &DidValue, @@ -137,7 +138,9 @@ impl RequestBuilder { self.build(operation, Some(identifier)) } - /// Build a new did:indy `GET_NYM` transaction request + /// Build a `GET_NYM` transaction request + /// seq_no and timestamp are only supported for did:indy compliant ledgers + /// Use only one of seq_no and timestamp pub fn build_get_nym_request( &self, identifier: Option<&DidValue>, diff --git a/libindy_vdr/src/resolver/resolver.rs b/libindy_vdr/src/resolver/resolver.rs index a57f931f..abd2e124 100644 --- a/libindy_vdr/src/resolver/resolver.rs +++ b/libindy_vdr/src/resolver/resolver.rs @@ -46,7 +46,7 @@ pub struct DereferencingResult { content_metadata: Option, } -// DID (URL) Resolver interface for a pool compliant with did:indy method spec +/// DID (URL) Resolver interface for a pool compliant with did:indy method spec pub struct PoolResolver { pool: T, } @@ -56,7 +56,7 @@ impl PoolResolver { PoolResolver { pool } } - // Dereference a DID Url and return a serialized `DereferencingResult` + /// Dereference a DID Url and return a serialized `DereferencingResult` pub fn dereference(&self, did_url: &str) -> VdrResult { debug!("PoolResolver: Dereference DID Url {}", did_url); let (data, metadata) = self._resolve(did_url)?; @@ -75,7 +75,7 @@ impl PoolResolver { Ok(serde_json::to_string_pretty(&result).unwrap()) } - // Resolve a DID and return a serialized `ResolutionResult` + /// Resolve a DID and return a serialized `ResolutionResult` pub fn resolve(&self, did: &str) -> VdrResult { debug!("PoolResolver: Resolve DID {}", did); let (data, metadata) = self._resolve(did)?; @@ -176,7 +176,7 @@ impl PoolResolver { } } -// DID (URL) Resolver interface using callbacks for a PoolRunner compliant with did:indy method spec +/// DID (URL) Resolver interface using callbacks for a PoolRunner compliant with did:indy method spec pub struct PoolRunnerResolver<'a> { runner: &'a PoolRunner, } @@ -186,7 +186,7 @@ impl<'a> PoolRunnerResolver<'a> { PoolRunnerResolver { runner } } - // Dereference a DID Url and return a serialized `DereferencingResult` + /// Dereference a DID Url and return a serialized `DereferencingResult` pub fn dereference( &self, did_url: &str, @@ -212,7 +212,7 @@ impl<'a> PoolRunnerResolver<'a> { ) } - // Resolve a DID and return a serialized `ResolutionResult` + /// Resolve a DID and return a serialized `ResolutionResult` pub fn resolve(&self, did: &str, callback: Callback>) -> VdrResult<()> { self._resolve( did, @@ -233,6 +233,7 @@ impl<'a> PoolRunnerResolver<'a> { ) } + // TODO: Refactor fn _resolve( &self, did: &str, @@ -287,26 +288,26 @@ impl<'a> PoolRunnerResolver<'a> { // callback(Ok(result_with_metadata)); // }), // ); - } else { - let did_document = DidDocument::new( - &did_url.namespace, - &get_nym_result.dest, - &get_nym_result.verkey, - None, - None, - ); - - let metadata = ContentMetadata { - node_response: serde_json::from_str(&reply_data) - .unwrap(), - object_type: String::from("NYM"), - }; - - let result = Some(Result::DidDocument(did_document)); - - let result_with_metadata = (result.unwrap(), metadata); - callback(Ok(result_with_metadata)); } + + let did_document = DidDocument::new( + &did_url.namespace, + &get_nym_result.dest, + &get_nym_result.verkey, + None, + None, + ); + + let metadata = ContentMetadata { + node_response: serde_json::from_str(&reply_data) + .unwrap(), + object_type: String::from("NYM"), + }; + + let result = Some(Result::DidDocument(did_document)); + + let result_with_metadata = (result.unwrap(), metadata); + callback(Ok(result_with_metadata)); } else { let (result, object_type) = match txn_type.as_str() { constants::GET_CRED_DEF => ( From bc932c964fa4083798cf052b8bd5572c32016e93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20W=C3=B6rner?= Date: Tue, 15 Mar 2022 12:37:57 +0100 Subject: [PATCH 041/117] format.. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- indy-vdr-proxy/src/handlers.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/indy-vdr-proxy/src/handlers.rs b/indy-vdr-proxy/src/handlers.rs index 19889937..5f4804cf 100644 --- a/indy-vdr-proxy/src/handlers.rs +++ b/indy-vdr-proxy/src/handlers.rs @@ -403,14 +403,14 @@ pub async fn handle_request( }); let query = req.uri().query(); let query_params: HashMap = req - .uri() - .query() - .map(|v| { - url::form_urlencoded::parse(v.as_bytes()) - .into_owned() - .collect() - }) - .unwrap_or_else(HashMap::new); + .uri() + .query() + .map(|v| { + url::form_urlencoded::parse(v.as_bytes()) + .into_owned() + .collect() + }) + .unwrap_or_else(HashMap::new); let format = if query == Some("html") { ResponseFormat::Html } else if query == Some("raw") { From 63c4464131a40c516838a723acd8b66537d95b40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20W=C3=B6rner?= Date: Tue, 15 Mar 2022 13:35:09 +0100 Subject: [PATCH 042/117] remove some unecessary code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- indy-vdr-proxy/src/handlers.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/indy-vdr-proxy/src/handlers.rs b/indy-vdr-proxy/src/handlers.rs index 5f4804cf..2420c78a 100644 --- a/indy-vdr-proxy/src/handlers.rs +++ b/indy-vdr-proxy/src/handlers.rs @@ -272,7 +272,6 @@ async fn get_attrib(pool: &T, dest: &str, raw: &str) -> VdrResult( pool: &T, nym: &str, From 41164265f1100bd3391f14a32a937965004b3304 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20W=C3=B6rner?= Date: Tue, 15 Mar 2022 18:17:36 +0100 Subject: [PATCH 043/117] removed unecessary enum MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- libindy_vdr/src/resolver/did_document.rs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/libindy_vdr/src/resolver/did_document.rs b/libindy_vdr/src/resolver/did_document.rs index a84fe82a..79c3f0dd 100644 --- a/libindy_vdr/src/resolver/did_document.rs +++ b/libindy_vdr/src/resolver/did_document.rs @@ -39,18 +39,12 @@ impl DidCommService { #[derive(Serialize, Deserialize, PartialEq, Debug)] #[serde(rename_all = "camelCase")] -pub struct GenericService { +struct GenericService { pub id: String, pub type_: String, pub service_endpoint: String, } -#[derive(Serialize, PartialEq, Debug)] -pub enum Service { - GenericService(GenericService), - DidCommService(DidCommService), -} - #[derive(Serialize, Deserialize, PartialEq, Debug)] #[serde(rename_all = "camelCase")] pub struct DidDocument { From fb07bb226582f77b8d78b36ec29f0b13c3763c52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20W=C3=B6rner?= Date: Tue, 15 Mar 2022 20:16:58 +0100 Subject: [PATCH 044/117] add self-certification version. Try to fix wrappers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- libindy_vdr/src/ffi/ledger.rs | 15 +++++++++------ libindy_vdr/src/ffi/resolver.rs | 8 ++++---- libindy_vdr/src/ledger/request_builder.rs | 12 ++++++++++-- libindy_vdr/src/ledger/requests/nym.rs | 4 ++++ libindy_vdr/src/ledger/responses.rs | 1 + libindy_vdr/tests/nym.rs | 7 +++++-- libindy_vdr/tests/utils/helpers.rs | 1 + wrappers/golang/vdr/indy_vdr.go | 6 +++--- wrappers/python/indy_vdr/ledger.py | 11 +++++++++-- 9 files changed, 46 insertions(+), 19 deletions(-) diff --git a/libindy_vdr/src/ffi/ledger.rs b/libindy_vdr/src/ffi/ledger.rs index 59ef8dcb..4fd49942 100644 --- a/libindy_vdr/src/ffi/ledger.rs +++ b/libindy_vdr/src/ffi/ledger.rs @@ -219,8 +219,8 @@ pub extern "C" fn indy_vdr_build_get_cred_def_request( pub extern "C" fn indy_vdr_build_get_nym_request( submitter_did: FfiStr, // optional dest: FfiStr, - seq_no: i32, // optional - timestamp: i64, // optional + seq_no: i32, // optional, -1 for None + timestamp: i64, // optional, -1 for None handle_p: *mut RequestHandle, ) -> ErrorCode { catch_err! { @@ -229,8 +229,9 @@ pub extern "C" fn indy_vdr_build_get_nym_request( let builder = get_request_builder()?; let identifier = submitter_did.as_opt_str().map(DidValue::from_str).transpose()?; let dest = DidValue::from_str(dest.as_str())?; + let seq_no = if seq_no == -1 { None } else { Some(seq_no) }; let timestamp = if timestamp == -1 { None } else { Some(timestamp as u64) }; - let req = builder.build_get_nym_request(identifier.as_ref(), &dest, Some(seq_no), timestamp)?; + let req = builder.build_get_nym_request(identifier.as_ref(), &dest, seq_no, timestamp)?; let handle = add_request(req)?; unsafe { *handle_p = handle; @@ -414,7 +415,7 @@ pub extern "C" fn indy_vdr_build_nym_request( let verkey = verkey.into_opt_string(); let alias = alias.into_opt_string(); let role = role.into_opt_string(); - let req = builder.build_nym_request(&identifier, &dest, verkey, alias, role, None)?; + let req = builder.build_nym_request(&identifier, &dest, verkey, alias, role, None, None)?; let handle = add_request(req)?; unsafe { *handle_p = handle; @@ -432,7 +433,8 @@ pub extern "C" fn indy_vdr_build_nym_request( alias: FfiStr, // optional role: FfiStr, // optional diddoc_content: FfiStr, // optional - handle_p: *mut usize, + version: i32, // optional, -1 for none + handle_p: *mut RequestHandle, ) -> ErrorCode { catch_err! { trace!("Build NYM request"); @@ -444,7 +446,8 @@ pub extern "C" fn indy_vdr_build_nym_request( let alias = alias.into_opt_string(); let role = role.into_opt_string(); let diddoc_content = serde_json::from_str(diddoc_content.as_str()).with_input_err("Error deserializing diddoc_content as JSON")?; - let req = builder.build_nym_request(&identifier, &dest, verkey, alias, role, diddoc_content)?; + let version = if version == -1 { None } else { Some(version) }; + let req = builder.build_nym_request(&identifier, &dest, verkey, alias, role, diddoc_content, version)?; let handle = add_request(req)?; unsafe { *handle_p = *handle; diff --git a/libindy_vdr/src/ffi/resolver.rs b/libindy_vdr/src/ffi/resolver.rs index c1baf75c..dd3bd9c1 100644 --- a/libindy_vdr/src/ffi/resolver.rs +++ b/libindy_vdr/src/ffi/resolver.rs @@ -8,7 +8,7 @@ use ffi_support::{rust_string_to_c, FfiStr}; #[no_mangle] pub extern "C" fn indy_vdr_resolve( - pool_handle: usize, + pool_handle: PoolHandle, did: FfiStr, cb: Option, cb_id: i64, @@ -17,7 +17,7 @@ pub extern "C" fn indy_vdr_resolve( trace!("Resolve DID: {:#?}", did); let cb = cb.ok_or_else(|| input_err("No callback provided")).unwrap(); let pools = read_lock!(POOLS)?; - let pool = pools.get(&PoolHandle(pool_handle)).ok_or_else(|| input_err("Unknown pool handle"))?; + let pool = pools.get(&pool_handle).ok_or_else(|| input_err("Unknown pool handle"))?; let resolver = Resolver::new(pool); resolver .resolve( @@ -41,7 +41,7 @@ pub extern "C" fn indy_vdr_resolve( #[no_mangle] pub extern "C" fn indy_vdr_dereference( - pool_handle: usize, + pool_handle: PoolHandle, did_url: FfiStr, cb: Option, cb_id: i64, @@ -50,7 +50,7 @@ pub extern "C" fn indy_vdr_dereference( trace!("Dereference DID Url: {:#?}", did_url); let cb = cb.ok_or_else(|| input_err("No callback provided")).unwrap(); let pools = read_lock!(POOLS)?; - let pool = pools.get(&PoolHandle(pool_handle)).ok_or_else(|| input_err("Unknown pool handle"))?; + let pool = pools.get(&pool_handle).ok_or_else(|| input_err("Unknown pool handle"))?; let resolver = Resolver::new(pool); resolver .dereference( diff --git a/libindy_vdr/src/ledger/request_builder.rs b/libindy_vdr/src/ledger/request_builder.rs index 60f82931..fa5f1c6d 100644 --- a/libindy_vdr/src/ledger/request_builder.rs +++ b/libindy_vdr/src/ledger/request_builder.rs @@ -132,9 +132,17 @@ impl RequestBuilder { alias: Option, role: Option, diddoc_content: Option<::serde_json::Value>, + version: Option, ) -> VdrResult { let role = role_to_code(role)?; - let operation = NymOperation::new(dest.to_short(), verkey, alias, role, diddoc_content); + let operation = NymOperation::new( + dest.to_short(), + verkey, + alias, + role, + diddoc_content, + version, + ); self.build(operation, Some(identifier)) } @@ -719,7 +727,7 @@ mod tests { request_builder: RequestBuilder, ) { let request = request_builder - .build_nym_request(&_identifier(), &_dest(), None, None, None, None) + .build_nym_request(&_identifier(), &_dest(), None, None, None, None, None) .unwrap(); assert_eq!(request.txn_type, constants::NYM); diff --git a/libindy_vdr/src/ledger/requests/nym.rs b/libindy_vdr/src/ledger/requests/nym.rs index 89a50004..7cc9b6cd 100644 --- a/libindy_vdr/src/ledger/requests/nym.rs +++ b/libindy_vdr/src/ledger/requests/nym.rs @@ -19,6 +19,8 @@ pub struct NymOperation { pub role: Option<::serde_json::Value>, #[serde(skip_serializing_if = "Option::is_none")] pub diddoc_content: Option<::serde_json::Value>, + #[serde(skip_serializing_if = "Option::is_none")] + pub version: Option, } impl NymOperation { @@ -28,6 +30,7 @@ impl NymOperation { alias: Option, role: Option<::serde_json::Value>, diddoc_content: Option<::serde_json::Value>, + version: Option, ) -> NymOperation { NymOperation { _type: Self::get_txn_type().to_string(), @@ -36,6 +39,7 @@ impl NymOperation { alias, role, diddoc_content, + version, } } } diff --git a/libindy_vdr/src/ledger/responses.rs b/libindy_vdr/src/ledger/responses.rs index 3066787c..6042ba62 100644 --- a/libindy_vdr/src/ledger/responses.rs +++ b/libindy_vdr/src/ledger/responses.rs @@ -32,6 +32,7 @@ pub struct GetNymResultV1 { pub role: Option, pub verkey: String, pub diddoc_content: Option, + pub version: Option, } #[derive(Deserialize, Eq, PartialEq, Debug)] diff --git a/libindy_vdr/tests/nym.rs b/libindy_vdr/tests/nym.rs index b3d577af..8a25d161 100644 --- a/libindy_vdr/tests/nym.rs +++ b/libindy_vdr/tests/nym.rs @@ -34,7 +34,7 @@ mod builder { my_did: DidValue, ) { let nym_request = request_builder - .build_nym_request(&trustee_did, &my_did, None, None, None, None) + .build_nym_request(&trustee_did, &my_did, None, None, None, None, None) .unwrap(); let expected_result = json!({ @@ -61,6 +61,7 @@ mod builder { Some(ALIAS.to_string()), Some(ROLE.to_string()), Some(diddoc_content), + None, ) .unwrap(); @@ -90,6 +91,7 @@ mod builder { None, Some(String::from("")), None, + None, ) .unwrap(); @@ -110,7 +112,7 @@ mod builder { my_did: DidValue, ) { let nym_request = request_builder - .build_nym_request(&fq_trustee_did, &fq_my_did, None, None, None, None) + .build_nym_request(&fq_trustee_did, &fq_my_did, None, None, None, None, None) .unwrap(); let expected_result = json!({ @@ -137,6 +139,7 @@ mod builder { None, Some(role.to_string()), None, + None, ) .unwrap_err(); } diff --git a/libindy_vdr/tests/utils/helpers.rs b/libindy_vdr/tests/utils/helpers.rs index 5fda455e..2a32a4cd 100644 --- a/libindy_vdr/tests/utils/helpers.rs +++ b/libindy_vdr/tests/utils/helpers.rs @@ -45,6 +45,7 @@ pub fn new_ledger_identity(pool: &TestPool, role: Option) -> Identity { None, role, None, + None, ) .unwrap(); diff --git a/wrappers/golang/vdr/indy_vdr.go b/wrappers/golang/vdr/indy_vdr.go index fe636e56..785f7f04 100644 --- a/wrappers/golang/vdr/indy_vdr.go +++ b/wrappers/golang/vdr/indy_vdr.go @@ -130,10 +130,10 @@ func (r *Client) Submit(request []byte) (*ReadReply, error) { func (r *Client) GetNym(did string) (*ReadReply, error) { var nymreq C.int64_t var none *C.char - var zero32 C.int32_t - var zero64 C.int64_t + var none32 C.int32_t = -1 + var none64 C.int64_t = -1 cdid := C.CString(did) - result := C.indy_vdr_build_get_nym_request(none, cdid, zero32, zero64, &nymreq) + result := C.indy_vdr_build_get_nym_request(none, cdid, none32, none64, &nymreq) C.free(unsafe.Pointer(cdid)) if result != 0 { return nil, fmt.Errorf("invalid get nym request: (Indy error code: [%v])", result) diff --git a/wrappers/python/indy_vdr/ledger.py b/wrappers/python/indy_vdr/ledger.py index b559d434..bb97f4bf 100644 --- a/wrappers/python/indy_vdr/ledger.py +++ b/wrappers/python/indy_vdr/ledger.py @@ -287,8 +287,8 @@ def build_get_nym_request( handle = RequestHandle() did_p = encode_str(submitter_did) dest_p = encode_str(dest) - seq_no_c = (c_int32(seq_no),) - timestamp_c = (c_int64(timestamp),) + seq_no_c = c_int32(seq_no if seq_no is not None else -1) + timestamp_c = c_int64(timestamp if timestamp is not None else -1) do_call( "indy_vdr_build_get_nym_request", did_p, @@ -488,6 +488,7 @@ def build_nym_request( alias: str = None, role: str = None, diddoc_content: str = None, + version: Optional[int] = None, ) -> Request: """ Builds a NYM request to create new DID on the ledger. @@ -507,6 +508,10 @@ def build_nym_request( NETWORK_MONITOR empty string to reset role diddoc_content: (Optional) The DIDDoc content + version: (Optional) Version/method of self-certification + 0 - no self-certification enforced by the ledger + 1 - legacy self-certification + 2 - self-certification according to did:indy method spec """ handle = RequestHandle() did_p = encode_str(submitter_did) @@ -515,6 +520,7 @@ def build_nym_request( alias_p = encode_str(alias) role_p = encode_str(role) diddoc_content_p = encode_str(diddoc_content) + version = c_int32(version if version is not None else -1) do_call( "indy_vdr_build_nym_request", did_p, @@ -523,6 +529,7 @@ def build_nym_request( alias_p, role_p, diddoc_content_p, + version, byref(handle), ) return Request(handle) From 63f441fd34e249466e119e025c9dc95f1d4b951e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20W=C3=B6rner?= Date: Tue, 15 Mar 2022 21:17:20 +0100 Subject: [PATCH 045/117] fix integration tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- libindy_vdr/src/ledger/constants.rs | 8 ++++++++ libindy_vdr/tests/author_agreement.rs | 1 + libindy_vdr/tests/get_txn.rs | 1 + libindy_vdr/tests/nym.rs | 9 ++++++++- 4 files changed, 18 insertions(+), 1 deletion(-) diff --git a/libindy_vdr/src/ledger/constants.rs b/libindy_vdr/src/ledger/constants.rs index e5f09120..cb5796b3 100644 --- a/libindy_vdr/src/ledger/constants.rs +++ b/libindy_vdr/src/ledger/constants.rs @@ -103,8 +103,16 @@ pub const RS_MAPPING_TYPE_VALUE: &str = "map"; pub const RS_CRED_DEF_TYPE_VALUE: &str = "cdf"; pub const RS_PRES_DEF_TYPE_VALUE: &str = "pdf"; + pub const ROLES: [&str; 4] = [TRUSTEE, STEWARD, ENDORSER, NETWORK_MONITOR]; +// Method/version of self-certification +pub const DEFAULT: i32 = 0; // No (enforced) self-certification +pub const DID_SOV: i32 = 1; // Legacy self-certification +pub const DID_INDY: i32 = 2; // Self-certification based on did:indy method spec + +pub const SELF_CERT_VERSIONS: [i32; 3] = [DEFAULT, DID_SOV, DID_INDY]; + pub fn txn_name_to_code(txn: &str) -> Option<&str> { if REQUESTS.contains(&txn) { return Some(txn); diff --git a/libindy_vdr/tests/author_agreement.rs b/libindy_vdr/tests/author_agreement.rs index f8d901bc..ace14a9c 100644 --- a/libindy_vdr/tests/author_agreement.rs +++ b/libindy_vdr/tests/author_agreement.rs @@ -324,6 +324,7 @@ mod author_agreement { None, None, None, + None, ) .unwrap() } diff --git a/libindy_vdr/tests/get_txn.rs b/libindy_vdr/tests/get_txn.rs index bd76a5c2..72d7994e 100644 --- a/libindy_vdr/tests/get_txn.rs +++ b/libindy_vdr/tests/get_txn.rs @@ -61,6 +61,7 @@ mod get_txn { None, None, None, + None, ) .unwrap(); diff --git a/libindy_vdr/tests/nym.rs b/libindy_vdr/tests/nym.rs index 8a25d161..dd4bcf7a 100644 --- a/libindy_vdr/tests/nym.rs +++ b/libindy_vdr/tests/nym.rs @@ -206,6 +206,7 @@ mod send { None, None, None, + None, ) .unwrap(); @@ -246,6 +247,7 @@ mod send { Some(ALIAS.to_string()), Some(ROLE.to_string()), None, + None, ) .unwrap(); @@ -295,6 +297,7 @@ mod send { None, Some(role.to_string()), None, + None, ) .unwrap(); @@ -335,6 +338,7 @@ mod send { None, Some(ROLE.to_string()), None, + None, ) .unwrap(); @@ -368,6 +372,7 @@ mod send { None, Some(ROLE_REMOVE.to_string()), None, + None, ) .unwrap(); @@ -408,6 +413,7 @@ mod send { None, None, None, + None, ) .unwrap(); @@ -420,7 +426,7 @@ mod send { // Send NYM let mut nym_request = pool .request_builder() - .build_nym_request(&identity.did, &identity.did, None, None, None, None) + .build_nym_request(&identity.did, &identity.did, None, None, None, None, None) .unwrap(); identity.sign_request(&mut nym_request); @@ -444,6 +450,7 @@ mod send { None, None, None, + None, ) .unwrap(); From d00e14c86c650fd08f1264039b0a604e31bb2adc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20W=C3=B6rner?= Date: Tue, 15 Mar 2022 21:23:53 +0100 Subject: [PATCH 046/117] fmt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- libindy_vdr/src/ledger/constants.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libindy_vdr/src/ledger/constants.rs b/libindy_vdr/src/ledger/constants.rs index cb5796b3..3f97da05 100644 --- a/libindy_vdr/src/ledger/constants.rs +++ b/libindy_vdr/src/ledger/constants.rs @@ -103,13 +103,12 @@ pub const RS_MAPPING_TYPE_VALUE: &str = "map"; pub const RS_CRED_DEF_TYPE_VALUE: &str = "cdf"; pub const RS_PRES_DEF_TYPE_VALUE: &str = "pdf"; - pub const ROLES: [&str; 4] = [TRUSTEE, STEWARD, ENDORSER, NETWORK_MONITOR]; // Method/version of self-certification pub const DEFAULT: i32 = 0; // No (enforced) self-certification pub const DID_SOV: i32 = 1; // Legacy self-certification -pub const DID_INDY: i32 = 2; // Self-certification based on did:indy method spec +pub const DID_INDY: i32 = 2; // Self-certification based on did:indy method spec pub const SELF_CERT_VERSIONS: [i32; 3] = [DEFAULT, DID_SOV, DID_INDY]; From bd121f0dece9daea2a97dcfe3a3f4f52e092e8fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20W=C3=B6rner?= Date: Tue, 15 Mar 2022 22:59:56 +0100 Subject: [PATCH 047/117] nym with diddoc_Content integration test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- .github/workflows/build.yml | 8 +- ci/did-indy-pool.dockerfile | 152 ++++++++ libindy_vdr/Cargo.toml | 1 + libindy_vdr/src/ffi/ledger.rs | 10 +- libindy_vdr/src/ledger/request_builder.rs | 4 +- libindy_vdr/src/ledger/requests/nym.rs | 4 +- libindy_vdr/src/ledger/responses.rs | 9 +- libindy_vdr/src/resolver/resolver.rs | 190 +++++++--- libindy_vdr/src/resolver/utils.rs | 442 ++++++++++++++++++++++ libindy_vdr/tests/nym.rs | 62 ++- wrappers/python/.gitignore | 1 + wrappers/python/indy_vdr/bindings.py | 2 +- wrappers/python/indy_vdr/ledger.py | 6 +- 13 files changed, 822 insertions(+), 69 deletions(-) create mode 100644 ci/did-indy-pool.dockerfile create mode 100644 libindy_vdr/src/resolver/utils.rs diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cdfd3daf..956d5c69 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -6,9 +6,9 @@ env: on: push: - branches: [main] + branches: [main, did-indy, integration_test] pull_request: - branches: [main] + branches: [main, did-indy] release: types: [created] workflow_dispatch: @@ -83,12 +83,12 @@ jobs: - name: Run local node pool run: | - docker build -f ci/indy-pool.dockerfile -t test_pool --build-arg pool_ip=10.0.0.2 ci + docker build -f ci/did-indy-pool.dockerfile -t test_pool --build-arg pool_ip=10.0.0.2 ci docker network create --subnet=10.0.0.0/8 indy-sdk-network docker run -d --name indy_pool -p 9701-9708:9701-9708 --net=indy-sdk-network test_pool - name: Run tests - run: cargo test --manifest-path libindy_vdr/Cargo.toml --features local_nodes_pool + run: cargo test --manifest-path libindy_vdr/Cargo.toml --features local_nodes_pool,local_nodes_pool_did_indy build-release: name: Build library diff --git a/ci/did-indy-pool.dockerfile b/ci/did-indy-pool.dockerfile new file mode 100644 index 00000000..654263fb --- /dev/null +++ b/ci/did-indy-pool.dockerfile @@ -0,0 +1,152 @@ +FROM --platform=linux/amd64 ubuntu:20.04 + +ARG uid=1000 +# ARG user=indy + +RUN apt-get update -y && apt-get install -y \ + # common stuff + git \ + wget \ + gnupg \ + apt-transport-https \ + ca-certificates \ + apt-utils + +# ======================================================================================================== +# Update repository signing keys +# -------------------------------------------------------------------------------------------------------- +# Hyperledger +RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 9692C00E657DDE61 && \ + # Sovrin + apt-key adv --keyserver keyserver.ubuntu.com --recv-keys CE7709D068DB5E88 +# ======================================================================================================== + +# Plenum +# - https://github.com/hyperledger/indy-plenum/issues/1546 +# - Needed to pick up rocksdb=5.8.8 +RUN echo "deb https://hyperledger.jfrog.io/artifactory/indy focal dev" >> /etc/apt/sources.list && \ + echo "deb http://security.ubuntu.com/ubuntu bionic-security main" >> /etc/apt/sources.list && \ + echo "deb https://repo.sovrin.org/deb bionic master" >> /etc/apt/sources.list && \ + echo "deb https://repo.sovrin.org/sdk/deb bionic master" >> /etc/apt/sources.list + +# Sovrin +RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys CE7709D068DB5E88 + +RUN apt-get update -y && apt-get install -y \ + # Python + python3-pip \ + python3-nacl \ + # rocksdb python wrapper + rocksdb=5.8.8 \ + libgflags-dev \ + libsnappy-dev \ + zlib1g-dev \ + libbz2-dev \ + liblz4-dev \ + libgflags-dev \ + # zstd is needed for caching in github actions pipeline + zstd \ + # fpm + ruby \ + ruby-dev \ + rubygems \ + gcc \ + make \ + # Indy Node and Plenum + libssl1.0.0 \ + ursa=0.3.2-1 \ + # Indy SDK + libindy=1.15.0~1625-bionic \ + # Need to move libursa.so to parent dir + && mv /usr/lib/ursa/* /usr/lib && rm -rf /usr/lib/ursa + +RUN pip3 install -U \ + # Required by setup.py + setuptools==50.3.2 \ + # Still pinned. Needs to be update like in plenum + 'pip<10.0.0' \ + 'pyzmq==18.1.0' \ + 'supervisor~=4.2' + + +# install fpm +RUN gem install --no-document rake fpm + +RUN apt-get -y autoremove \ + && rm -rf /var/lib/apt/lists/* + +# Download, build and install indy-node +RUN git clone --single-branch --branch feature/did-indy-new https://github.com/indicio-tech/indy-node && \ + pip install -e indy-node + + +RUN echo "[supervisord]\n\ +logfile = /tmp/supervisord.log\n\ +logfile_maxbytes = 50MB\n\ +logfile_backups=10\n\ +logLevel = error\n\ +pidfile = /tmp/supervisord.pid\n\ +nodaemon = true\n\ +minfds = 1024\n\ +minprocs = 200\n\ +umask = 022\n\ +user = indy\n\ +identifier = supervisor\n\ +directory = /tmp\n\ +nocleanup = true\n\ +childlogdir = /tmp\n\ +strip_ansi = false\n\ +\n\ +[program:node1]\n\ +command=start_indy_node Node1 0.0.0.0 9701 0.0.0.0 9702\n\ +directory=/home/indy\n\ +stdout_logfile=/tmp/node1.log\n\ +stderr_logfile=/tmp/node1.log\n\ +\n\ +[program:node2]\n\ +command=start_indy_node Node2 0.0.0.0 9703 0.0.0.0 9704\n\ +directory=/home/indy\n\ +stdout_logfile=/tmp/node2.log\n\ +stderr_logfile=/tmp/node2.log\n\ +\n\ +[program:node3]\n\ +command=start_indy_node Node3 0.0.0.0 9705 0.0.0.0 9706\n\ +directory=/home/indy\n\ +stdout_logfile=/tmp/node3.log\n\ +stderr_logfile=/tmp/node3.log\n\ +\n\ +[program:node4]\n\ +command=start_indy_node Node4 0.0.0.0 9707 0.0.0.0 9708\n\ +directory=/home/indy\n\ +stdout_logfile=/tmp/node4.log\n\ +stderr_logfile=/tmp/node4.log\n"\ +>> /etc/supervisord.conf + +RUN useradd -ms /bin/bash -u $uid indy + +RUN mkdir -p \ + /etc/indy \ + /var/lib/indy/backup \ + /var/lib/indy/plugins \ + /var/log/indy \ + && chown -R indy /etc/indy /var/lib/indy /var/log/indy + +USER indy + +RUN echo "LEDGER_DIR = '/var/lib/indy'\n\ +LOG_DIR = '/var/log/indy'\n\ +KEYS_DIR = '/var/lib/indy'\n\ +GENESIS_DIR = '/var/lib/indy'\n\ +BACKUP_DIR = '/var/lib/indy/backup'\n\ +PLUGINS_DIR = '/var/lib/indy/plugins'\n\ +NODE_INFO_DIR = '/var/lib/indy'\n\ +NETWORK_NAME = 'sandbox'\n"\ +>> /etc/indy/indy_config.py + +ARG pool_ip=127.0.0.1 + +RUN generate_indy_pool_transactions --nodes 4 --clients 5 --nodeNum 1 2 3 4 --ips="$pool_ip,$pool_ip,$pool_ip,$pool_ip" + +EXPOSE 9701 9702 9703 9704 9705 9706 9707 9708 + +CMD ["/usr/local/bin/supervisord"] diff --git a/libindy_vdr/Cargo.toml b/libindy_vdr/Cargo.toml index ce85eb09..c0dd67d5 100644 --- a/libindy_vdr/Cargo.toml +++ b/libindy_vdr/Cargo.toml @@ -21,6 +21,7 @@ ffi = ["ffi-support", "logger"] logger = ["env_logger", "log"] zmq_vendored = ["zmq/vendored"] local_nodes_pool = [] +local_nodes_pool_did_indy = [] rich_schema = ["indy-data-types/rich_schema"] default = ["ffi", "log", "zmq_vendored"] diff --git a/libindy_vdr/src/ffi/ledger.rs b/libindy_vdr/src/ffi/ledger.rs index 4fd49942..c30fcd57 100644 --- a/libindy_vdr/src/ffi/ledger.rs +++ b/libindy_vdr/src/ffi/ledger.rs @@ -445,9 +445,15 @@ pub extern "C" fn indy_vdr_build_nym_request( let verkey = verkey.into_opt_string(); let alias = alias.into_opt_string(); let role = role.into_opt_string(); - let diddoc_content = serde_json::from_str(diddoc_content.as_str()).with_input_err("Error deserializing diddoc_content as JSON")?; + let diddoc_content = match diddoc_content.as_opt_str() { + Some(s) => { + let js = serde_json::from_str(s).with_input_err("Error deserializing raw value as JSON")?; + Some(js) + } + None => None, + }; let version = if version == -1 { None } else { Some(version) }; - let req = builder.build_nym_request(&identifier, &dest, verkey, alias, role, diddoc_content, version)?; + let req = builder.build_nym_request(&identifier, &dest, verkey, alias, role, diddoc_content.as_ref(), version)?; let handle = add_request(req)?; unsafe { *handle_p = *handle; diff --git a/libindy_vdr/src/ledger/request_builder.rs b/libindy_vdr/src/ledger/request_builder.rs index fa5f1c6d..8573d08a 100644 --- a/libindy_vdr/src/ledger/request_builder.rs +++ b/libindy_vdr/src/ledger/request_builder.rs @@ -131,7 +131,7 @@ impl RequestBuilder { verkey: Option, alias: Option, role: Option, - diddoc_content: Option<::serde_json::Value>, + diddoc_content: Option<&SJsonValue>, version: Option, ) -> VdrResult { let role = role_to_code(role)?; @@ -140,7 +140,7 @@ impl RequestBuilder { verkey, alias, role, - diddoc_content, + diddoc_content.map(SJsonValue::to_string), version, ); self.build(operation, Some(identifier)) diff --git a/libindy_vdr/src/ledger/requests/nym.rs b/libindy_vdr/src/ledger/requests/nym.rs index 7cc9b6cd..2fa827a9 100644 --- a/libindy_vdr/src/ledger/requests/nym.rs +++ b/libindy_vdr/src/ledger/requests/nym.rs @@ -18,7 +18,7 @@ pub struct NymOperation { #[serde(skip_serializing_if = "Option::is_none")] pub role: Option<::serde_json::Value>, #[serde(skip_serializing_if = "Option::is_none")] - pub diddoc_content: Option<::serde_json::Value>, + pub diddoc_content: Option, #[serde(skip_serializing_if = "Option::is_none")] pub version: Option, } @@ -29,7 +29,7 @@ impl NymOperation { verkey: Option, alias: Option, role: Option<::serde_json::Value>, - diddoc_content: Option<::serde_json::Value>, + diddoc_content: Option, version: Option, ) -> NymOperation { NymOperation { diff --git a/libindy_vdr/src/ledger/responses.rs b/libindy_vdr/src/ledger/responses.rs index 6042ba62..47f1f7bd 100644 --- a/libindy_vdr/src/ledger/responses.rs +++ b/libindy_vdr/src/ledger/responses.rs @@ -1,6 +1,5 @@ use crate::utils::did::DidValue; use serde::Deserialize; -use serde_json::Value as SJsonValue; use std::collections::HashMap; pub enum ResponseTypes { @@ -16,7 +15,7 @@ pub enum GetNymResult { GetNymResultV1(GetNymResultV1), } -#[derive(Deserialize, Eq, PartialEq, Debug)] +#[derive(Serialize, Deserialize, Eq, PartialEq, Debug)] pub struct GetNymResultV0 { pub identifier: Option, pub dest: DidValue, @@ -24,14 +23,16 @@ pub struct GetNymResultV0 { pub verkey: String, } -#[derive(Deserialize, Eq, PartialEq, Debug)] +#[derive(Serialize, Deserialize, Eq, PartialEq, Debug)] #[serde(rename_all = "camelCase")] pub struct GetNymResultV1 { pub identifier: Option, pub dest: DidValue, pub role: Option, pub verkey: String, - pub diddoc_content: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub diddoc_content: Option, + #[serde(skip_serializing_if = "Option::is_none")] pub version: Option, } diff --git a/libindy_vdr/src/resolver/resolver.rs b/libindy_vdr/src/resolver/resolver.rs index abd2e124..9e90d068 100644 --- a/libindy_vdr/src/resolver/resolver.rs +++ b/libindy_vdr/src/resolver/resolver.rs @@ -23,6 +23,13 @@ pub enum Result { Content(SJsonValue), } +#[derive(Serialize, Deserialize, PartialEq, Debug)] +#[serde(rename_all = "camelCase")] +pub enum Metadata { + DidDocumentMetadata(DidDocumentMetadata), + ContentMetadata(ContentMetadata), +} + #[derive(Serialize, Deserialize, PartialEq, Debug)] #[serde(rename_all = "camelCase")] pub struct ContentMetadata { @@ -30,12 +37,20 @@ pub struct ContentMetadata { object_type: String, } +#[derive(Serialize, Deserialize, PartialEq, Debug)] +#[serde(rename_all = "camelCase")] +pub struct DidDocumentMetadata { + node_response: SJsonValue, + object_type: String, + self_certification_version: Option, +} + #[derive(Serialize, Deserialize, PartialEq, Debug)] #[serde(rename_all = "camelCase")] pub struct ResolutionResult { did_resolution_metadata: Option, did_document: Option, - did_document_metadata: Option, + did_document_metadata: Option, } #[derive(Serialize, Deserialize, PartialEq, Debug)] @@ -66,10 +81,16 @@ impl PoolResolver { _ => None, }; + let md = if let Metadata::ContentMetadata(md) = metadata { + Some(md) + } else { + None + }; + let result = DereferencingResult { dereferencing_metadata: None, content_stream: content, - content_metadata: Some(metadata), + content_metadata: md, }; Ok(serde_json::to_string_pretty(&result).unwrap()) @@ -84,17 +105,24 @@ impl PoolResolver { Result::DidDocument(doc) => Some(doc.to_value()?), _ => None, }; + + let md = if let Metadata::DidDocumentMetadata(md) = metadata { + Some(md) + } else { + None + }; + let result = ResolutionResult { did_resolution_metadata: None, did_document: diddoc, - did_document_metadata: Some(metadata), + did_document_metadata: md, }; Ok(serde_json::to_string_pretty(&result).unwrap()) } // Internal method to resolve and dereference - fn _resolve(&self, did: &str) -> VdrResult<(Result, ContentMetadata)> { + fn _resolve(&self, did: &str) -> VdrResult<(Result, Metadata)> { let did_url = DidUrl::from_str(did)?; let builder = self.pool.get_request_builder(); @@ -103,7 +131,7 @@ impl PoolResolver { let ledger_data = self.handle_request(&request)?; let data = parse_ledger_data(&ledger_data)?; - let (result, object_type) = match request.txn_type.as_str() { + let (result, metadata) = match request.txn_type.as_str() { constants::GET_NYM => { let get_nym_result: GetNymResultV1 = serde_json::from_str(data.as_str().unwrap()) @@ -123,20 +151,50 @@ impl PoolResolver { endpoint, None, ); - (Result::DidDocument(did_document), String::from("NYM")) - } - constants::GET_CRED_DEF => (Result::Content(data), String::from("CRED_DEF")), - constants::GET_SCHEMA => (Result::Content(data), String::from("SCHEMA")), - constants::GET_REVOC_REG_DEF => (Result::Content(data), String::from("REVOC_REG_DEF")), - constants::GET_REVOC_REG_DELTA => { - (Result::Content(data), String::from("REVOC_REG_DELTA")) - } - _ => (Result::Content(data), String::from("UNKOWN")), - }; - let metadata = ContentMetadata { - node_response: serde_json::from_str(&ledger_data).unwrap(), - object_type, + let metadata = Metadata::DidDocumentMetadata(DidDocumentMetadata { + node_response: serde_json::from_str(&ledger_data).unwrap(), + object_type: String::from("NYM"), + self_certification_version: get_nym_result.version, + }); + + (Result::DidDocument(did_document), metadata) + } + constants::GET_CRED_DEF => ( + Result::Content(data), + Metadata::ContentMetadata(ContentMetadata { + node_response: serde_json::from_str(&ledger_data).unwrap(), + object_type: String::from("CRED_DEF"), + }), + ), + constants::GET_SCHEMA => ( + Result::Content(data), + Metadata::ContentMetadata(ContentMetadata { + node_response: serde_json::from_str(&ledger_data).unwrap(), + object_type: String::from("SCHEMA"), + }), + ), + constants::GET_REVOC_REG_DEF => ( + Result::Content(data), + Metadata::ContentMetadata(ContentMetadata { + node_response: serde_json::from_str(&ledger_data).unwrap(), + object_type: String::from("REVOC_REG_DEF"), + }), + ), + constants::GET_REVOC_REG_DELTA => ( + Result::Content(data), + Metadata::ContentMetadata(ContentMetadata { + node_response: serde_json::from_str(&ledger_data).unwrap(), + object_type: String::from("REVOC_REG_DELTA"), + }), + ), + _ => ( + Result::Content(data), + Metadata::ContentMetadata(ContentMetadata { + node_response: serde_json::from_str(&ledger_data).unwrap(), + object_type: String::from("REVOC_REG_DELTA"), + }), + ), }; let result_with_metadata = (result, metadata); @@ -201,10 +259,16 @@ impl<'a> PoolRunnerResolver<'a> { _ => None, }; + let md = if let Metadata::ContentMetadata(md) = metadata { + Some(md) + } else { + None + }; + let result = DereferencingResult { dereferencing_metadata: None, content_stream: content, - content_metadata: Some(metadata), + content_metadata: md, }; callback(Ok(serde_json::to_string_pretty(&result).unwrap())) @@ -222,10 +286,17 @@ impl<'a> PoolRunnerResolver<'a> { Result::DidDocument(doc) => Some(doc.to_value().unwrap()), _ => None, }; + + let md = if let Metadata::DidDocumentMetadata(md) = metadata { + Some(md) + } else { + None + }; + let result = ResolutionResult { did_resolution_metadata: None, did_document: diddoc, - did_document_metadata: Some(metadata), + did_document_metadata: md, }; callback(Ok(serde_json::to_string_pretty(&result).unwrap())) @@ -234,10 +305,11 @@ impl<'a> PoolRunnerResolver<'a> { } // TODO: Refactor + // TODO: Adapt according to PoolResolver. fn _resolve( &self, did: &str, - callback: Box) -> ()) + Send + 'static>, + callback: Callback>, ) -> VdrResult<()> { let did_url = DidUrl::from_str(did)?; @@ -298,50 +370,74 @@ impl<'a> PoolRunnerResolver<'a> { None, ); - let metadata = ContentMetadata { - node_response: serde_json::from_str(&reply_data) - .unwrap(), - object_type: String::from("NYM"), - }; + let metadata = + Metadata::DidDocumentMetadata(DidDocumentMetadata { + node_response: serde_json::from_str(&reply_data) + .unwrap(), + object_type: String::from("NYM"), + self_certification_version: get_nym_result.version, + }); let result = Some(Result::DidDocument(did_document)); let result_with_metadata = (result.unwrap(), metadata); callback(Ok(result_with_metadata)); } else { - let (result, object_type) = match txn_type.as_str() { + let (result, metadata) = match txn_type.as_str() { constants::GET_CRED_DEF => ( - Some(Result::Content(data)), - String::from("CRED_DEF"), + Result::Content(data), + Metadata::ContentMetadata(ContentMetadata { + node_response: serde_json::from_str( + &reply_data, + ) + .unwrap(), + object_type: String::from("CRED_DEF"), + }), ), constants::GET_SCHEMA => ( - Some(Result::Content(data)), - String::from("SCHEMA"), + Result::Content(data), + Metadata::ContentMetadata(ContentMetadata { + node_response: serde_json::from_str( + &reply_data, + ) + .unwrap(), + object_type: String::from("SCHEMA"), + }), ), constants::GET_REVOC_REG_DEF => ( - Some(Result::Content(data)), - String::from("REVOC_REG_DEF"), + Result::Content(data), + Metadata::ContentMetadata(ContentMetadata { + node_response: serde_json::from_str( + &reply_data, + ) + .unwrap(), + object_type: String::from("REVOC_REG_DEF"), + }), ), constants::GET_REVOC_REG_DELTA => ( - Some(Result::Content(data)), - String::from("REVOC_REG_DELTA"), + Result::Content(data), + Metadata::ContentMetadata(ContentMetadata { + node_response: serde_json::from_str( + &reply_data, + ) + .unwrap(), + object_type: String::from("REVOC_REG_DELTA"), + }), ), _ => ( - Some(Result::Content(data)), - String::from("UNKOWN"), + Result::Content(data), + Metadata::ContentMetadata(ContentMetadata { + node_response: serde_json::from_str( + &reply_data, + ) + .unwrap(), + object_type: String::from("REVOC_REG_DELTA"), + }), ), }; - let metadata = ContentMetadata { - node_response: serde_json::from_str(&reply_data) - .unwrap(), - object_type, - }; - - if result.is_some() { - let result_with_metadata = (result.unwrap(), metadata); - callback(Ok(result_with_metadata)); - } + let result_with_metadata = (result, metadata); + callback(Ok(result_with_metadata)); } } RequestResult::Failed(err) => callback(Err(err)), diff --git a/libindy_vdr/src/resolver/utils.rs b/libindy_vdr/src/resolver/utils.rs new file mode 100644 index 00000000..64beb55a --- /dev/null +++ b/libindy_vdr/src/resolver/utils.rs @@ -0,0 +1,442 @@ +use serde_json::Value as SJsonValue; +use time::format_description::well_known::Rfc3339; +use time::OffsetDateTime; + +use super::did::{DidUrl, LedgerObject, QueryParameter}; +use super::did_document::{DidDocument, LEGACY_INDY_SERVICE}; +use super::types::*; + +use crate::common::error::prelude::*; +use crate::ledger::constants; +use crate::ledger::identifiers::{CredentialDefinitionId, RevocationRegistryId, SchemaId}; +use crate::ledger::responses::{Endpoint, GetNymResultV1}; +use crate::ledger::RequestBuilder; +use crate::pool::helpers::perform_ledger_request; +use crate::pool::{Pool, PoolRunner, PreparedRequest, RequestResult, TimingResult}; +use crate::utils::did::DidValue; +use crate::utils::Qualifiable; + +pub fn build_request(did: &DidUrl, builder: &RequestBuilder) -> VdrResult { + let request = if did.path.is_some() { + match LedgerObject::from_str(did.path.as_ref().unwrap().as_str())? { + LedgerObject::Schema(schema) => builder.build_get_schema_request( + None, + &SchemaId::new(&did.id, &schema.name, &schema.version), + ), + LedgerObject::ClaimDef(claim_def) => builder.build_get_cred_def_request( + None, + &CredentialDefinitionId::from_str( + format!( + "{}:3:CL:{}:{}", + &did.id, claim_def.schema_seq_no, claim_def.name + ) + .as_str(), + ) + .unwrap(), + ), + LedgerObject::RevRegDef(rev_reg_def) => builder.build_get_revoc_reg_def_request( + None, + &RevocationRegistryId::from_str( + format!( + "{}:4:{}:3:CL:{}:{}:CL_ACCUM:{}", + &did.id, + &did.id, + rev_reg_def.schema_seq_no, + rev_reg_def.claim_def_name, + rev_reg_def.tag + ) + .as_str(), + ) + .unwrap(), + ), + LedgerObject::RevRegEntry(rev_reg_entry) => { + // If From or To parameters, return RevRegDelta request + if did.query.contains_key(&QueryParameter::From) + || did.query.contains_key(&QueryParameter::To) + { + let mut from: Option = None; + if did.query.contains_key(&QueryParameter::From) { + from = did + .query + .get(&QueryParameter::From) + .and_then(|d| OffsetDateTime::parse(d, &Rfc3339).ok()) + .and_then(|d| Some(d.unix_timestamp())); + } + + let to = parse_or_now(did.query.get(&QueryParameter::To))?; + + builder.build_get_revoc_reg_delta_request( + None, + &RevocationRegistryId::from_str( + format!( + "{}:4:{}:3:CL:{}:{}:CL_ACCUM:{}", + &did.id, + &did.id, + rev_reg_entry.schema_seq_no, + rev_reg_entry.claim_def_name, + rev_reg_entry.tag + ) + .as_str(), + ) + .unwrap(), + from, + to, + ) + // Else return RevRegEntry request + } else { + let timestamp = parse_or_now(did.query.get(&QueryParameter::VersionTime))?; + + builder.build_get_revoc_reg_request( + None, + &RevocationRegistryId::from_str( + format!( + "{}:4:{}:3:CL:{}:{}:CL_ACCUM:{}", + &did.id, + &did.id, + rev_reg_entry.schema_seq_no, + rev_reg_entry.claim_def_name, + rev_reg_entry.tag + ) + .as_str(), + ) + .unwrap(), + timestamp, + ) + } + } + // This path is deprecated. Deltas can be retrieved through RevRegEntry + LedgerObject::RevRegDelta(rev_reg_delta) => { + let mut from: Option = None; + if did.query.contains_key(&QueryParameter::From) { + from = did + .query + .get(&QueryParameter::From) + .and_then(|d| OffsetDateTime::parse(d, &Rfc3339).ok()) + .and_then(|d| Some(d.unix_timestamp())); + } + + let to = parse_or_now(did.query.get(&QueryParameter::To))?; + + builder.build_get_revoc_reg_delta_request( + None, + &RevocationRegistryId::from_str( + format!( + "{}:4:{}:3:CL:{}:{}:CL_ACCUM:{}", + &did.id, + &did.id, + rev_reg_delta.schema_seq_no, + rev_reg_delta.claim_def_name, + rev_reg_delta.tag + ) + .as_str(), + ) + .unwrap(), + from, + to, + ) + } + } + } else { + let seq_no: Option = did + .query + .get(&QueryParameter::VersionId) + .and_then(|v| v.parse().ok()); + let timestamp: Option = did + .query + .get(&QueryParameter::VersionTime) + .and_then(|d| OffsetDateTime::parse(d, &Rfc3339).ok()) + .and_then(|d| Some(d.unix_timestamp())) + .and_then(|d| Some(d as u64)); + + builder.build_get_nym_request(Option::None, &did.id, seq_no, timestamp) + }; + request +} + +pub fn handle_resolution_result( + namespace: &str, + ledger_data: &str, + txn_type: &str, +) -> VdrResult<(Result, Metadata)> { + let data = parse_ledger_data(&ledger_data)?; + Ok(match txn_type { + constants::GET_NYM => { + let get_nym_result: GetNymResultV1 = serde_json::from_str(data.as_str().unwrap()) + .map_err(|_| err_msg(VdrErrorKind::Resolver, "Could not parse NYM data"))?; + + let did_document = DidDocument::new( + namespace, + &get_nym_result.dest, + &get_nym_result.verkey, + None, + get_nym_result.diddoc_content.map(|v| serde_json::from_str(&v).unwrap()), + ); + + let metadata = Metadata::DidDocumentMetadata(DidDocumentMetadata { + node_response: serde_json::from_str(&ledger_data).unwrap(), + object_type: String::from("NYM"), + self_certification_version: get_nym_result.version, + }); + + (Result::DidDocument(did_document), metadata) + } + constants::GET_CRED_DEF => ( + Result::Content(data), + Metadata::ContentMetadata(ContentMetadata { + node_response: serde_json::from_str(&ledger_data).unwrap(), + object_type: String::from("CRED_DEF"), + }), + ), + constants::GET_SCHEMA => ( + Result::Content(data), + Metadata::ContentMetadata(ContentMetadata { + node_response: serde_json::from_str(&ledger_data).unwrap(), + object_type: String::from("SCHEMA"), + }), + ), + constants::GET_REVOC_REG_DEF => ( + Result::Content(data), + Metadata::ContentMetadata(ContentMetadata { + node_response: serde_json::from_str(&ledger_data).unwrap(), + object_type: String::from("REVOC_REG_DEF"), + }), + ), + constants::GET_REVOC_REG_DELTA => ( + Result::Content(data), + Metadata::ContentMetadata(ContentMetadata { + node_response: serde_json::from_str(&ledger_data).unwrap(), + object_type: String::from("REVOC_REG_DELTA"), + }), + ), + _ => ( + Result::Content(data), + Metadata::ContentMetadata(ContentMetadata { + node_response: serde_json::from_str(&ledger_data).unwrap(), + object_type: String::from("REVOC_REG_DELTA"), + }), + ), + }) +} + +pub fn parse_ledger_data(ledger_data: &str) -> VdrResult { + let v: SJsonValue = serde_json::from_str(&ledger_data) + .map_err(|_| err_msg(VdrErrorKind::Resolver, "Could not parse ledger response"))?; + let data: &SJsonValue = &v["result"]["data"]; + if *data == SJsonValue::Null { + Err(err_msg( + VdrErrorKind::Resolver, + format!("Empty data in ledger response"), + )) + } else { + Ok(data.to_owned()) + } +} + +pub fn parse_or_now(datetime: Option<&String>) -> VdrResult { + match datetime { + Some(datetime) => { + let dt = OffsetDateTime::parse(datetime, &Rfc3339).map_err(|_| { + err_msg( + VdrErrorKind::Resolver, + format!("Could not parse datetime {}", datetime), + ) + })?; + Ok(dt.unix_timestamp()) + } + None => Ok(OffsetDateTime::now_utc().unix_timestamp()), + } +} + +pub async fn handle_request(pool: &T, request: &PreparedRequest) -> VdrResult { + let (result, _timing) = request_transaction(pool, &request).await?; + match result { + RequestResult::Reply(data) => Ok(data), + RequestResult::Failed(error) => Err(error), + } +} + +pub async fn request_transaction( + pool: &T, + request: &PreparedRequest, +) -> VdrResult<(RequestResult, Option)> { + perform_ledger_request(pool, &request).await +} + +/// Fetch legacy service endpoint using ATTRIB tx +pub async fn fetch_legacy_endpoint(pool: &T, did: &DidValue) -> VdrResult { + let builder = pool.get_request_builder(); + let request = builder.build_get_attrib_request( + None, + did, + Some(String::from(LEGACY_INDY_SERVICE)), + None, + None, + )?; + let ledger_data = handle_request(pool, &request).await?; + let endpoint_data = parse_ledger_data(&ledger_data)?; + let endpoint_data: Endpoint = serde_json::from_str(endpoint_data.as_str().unwrap()) + .map_err(|_| err_msg(VdrErrorKind::Resolver, "Could not parse endpoint data"))?; + Ok(endpoint_data) +} + +pub fn fetch_legacy_endpoint_with_runner( + runner: &PoolRunner, + did: &DidValue, + callback: Callback>, +) -> VdrResult<()> { + let builder = RequestBuilder::default(); + let request = builder.build_get_attrib_request( + None, + did, + Some(String::from(LEGACY_INDY_SERVICE)), + None, + None, + )?; + runner.send_request( + request, + Box::new(move |result| match result { + Ok((res, _)) => match res { + RequestResult::Reply(reply_data) => { + let endpoint_data = parse_ledger_data(&reply_data).unwrap(); + let endpoint_data: Endpoint = + serde_json::from_str(endpoint_data.as_str().unwrap()).unwrap(); + callback(Ok(endpoint_data)); + } + RequestResult::Failed(err) => callback(Err(err)), + }, + Err(err) => callback(Err(err)), + }), + ) +} + +#[cfg(test)] +mod tests { + + use urlencoding::encode; + + use time::format_description::well_known::Rfc3339; + use time::OffsetDateTime; + + use super::*; + use rstest::*; + + use crate::pool::ProtocolVersion; + + #[fixture] + fn request_builder() -> RequestBuilder { + RequestBuilder::new(ProtocolVersion::Node1_4) + } + + #[rstest] + fn build_get_revoc_reg_request_from_version_time(request_builder: RequestBuilder) { + let datetime_as_str = "2020-12-20T19:17:47Z"; + let did_url_as_str = format!("did:indy:idunion:Dk1fRRTtNazyMuK2cr64wp/anoncreds/v0/REV_REG_ENTRY/104/revocable/a4e25e54?versionTime={}",datetime_as_str); + let did_url = DidUrl::from_str(&did_url_as_str).unwrap(); + let request = build_request(&did_url, &request_builder).unwrap(); + let timestamp = (*(request.req_json).get("operation").unwrap()) + .get("timestamp") + .unwrap() + .as_u64() + .unwrap() as i64; + assert_eq!(constants::GET_REVOC_REG, request.txn_type); + + assert_eq!( + OffsetDateTime::parse(datetime_as_str, &Rfc3339) + .unwrap() + .unix_timestamp(), + timestamp + ); + } + + #[rstest] + fn build_get_revoc_reg_without_version_time(request_builder: RequestBuilder) { + let now = OffsetDateTime::now_utc().unix_timestamp(); + + let did_url_as_str = "did:indy:idunion:Dk1fRRTtNazyMuK2cr64wp/anoncreds/v0/REV_REG_ENTRY/104/revocable/a4e25e54"; + let did_url = DidUrl::from_str(did_url_as_str).unwrap(); + let request = build_request(&did_url, &request_builder).unwrap(); + let timestamp = (*(request.req_json).get("operation").unwrap()) + .get("timestamp") + .unwrap() + .as_u64() + .unwrap() as i64; + + assert_eq!(constants::GET_REVOC_REG, request.txn_type); + assert!(timestamp >= now); + } + + #[rstest] + fn build_get_revoc_reg_request_fails_with_unparsable_version_time( + request_builder: RequestBuilder, + ) { + let datetime_as_str = "20201220T19:17:47Z"; + let did_url_as_str = format!("did:indy:idunion:Dk1fRRTtNazyMuK2cr64wp/anoncreds/v0/REV_REG_ENTRY/104/revocable/a4e25e54?versionTime={}",datetime_as_str); + let did_url = DidUrl::from_str(&did_url_as_str).unwrap(); + let _err = build_request(&did_url, &request_builder).unwrap_err(); + } + + #[rstest] + fn build_get_revoc_reg_delta_request_with_from_to(request_builder: RequestBuilder) { + let from_as_str = "2019-12-20T19:17:47Z"; + let to_as_str = "2020-12-20T19:17:47Z"; + let did_url_as_str = format!("did:indy:idunion:Dk1fRRTtNazyMuK2cr64wp/anoncreds/v0/REV_REG_ENTRY/104/revocable/a4e25e54?from={}&to={}",from_as_str, to_as_str); + let did_url = DidUrl::from_str(&did_url_as_str).unwrap(); + let request = build_request(&did_url, &request_builder).unwrap(); + assert_eq!(request.txn_type, constants::GET_REVOC_REG_DELTA); + } + + #[rstest] + fn build_get_revoc_reg_delta_request_with_from_only(request_builder: RequestBuilder) { + let now = OffsetDateTime::now_utc().unix_timestamp(); + let from_as_str = "2019-12-20T19:17:47Z"; + let did_url_as_str = format!("did:indy:idunion:Dk1fRRTtNazyMuK2cr64wp/anoncreds/v0/REV_REG_ENTRY/104/revocable/a4e25e54?from={}",from_as_str); + let did_url = DidUrl::from_str(&did_url_as_str).unwrap(); + let request = build_request(&did_url, &request_builder).unwrap(); + + let to = (*(request.req_json).get("operation").unwrap()) + .get("to") + .unwrap() + .as_u64() + .unwrap() as i64; + assert_eq!(request.txn_type, constants::GET_REVOC_REG_DELTA); + assert!(to >= now) + } + + #[rstest] + fn build_get_revoc_reg_delta_request_without_parameter(request_builder: RequestBuilder) { + let now = OffsetDateTime::now_utc().unix_timestamp(); + let did_url_as_str = "did:indy:idunion:Dk1fRRTtNazyMuK2cr64wp/anoncreds/v0/REV_REG_DELTA/104/revocable/a4e25e54"; + let did_url = DidUrl::from_str(did_url_as_str).unwrap(); + let request = build_request(&did_url, &request_builder).unwrap(); + + let to = (*(request.req_json).get("operation").unwrap()) + .get("to") + .unwrap() + .as_u64() + .unwrap() as i64; + + let from = (*(request.req_json).get("operation").unwrap()).get("from"); + assert_eq!(request.txn_type, constants::GET_REVOC_REG_DELTA); + assert!(from.is_none()); + assert!(to >= now); + } + + #[rstest] + fn build_get_schema_request_with_whitespace(request_builder: RequestBuilder) { + let name = "My Schema"; + let encoded_schema_name = encode(name).to_string(); + let did_url_string = format!( + "did:indy:idunion:Dk1fRRTtNazyMuK2cr64wp/anoncreds/v0/SCHEMA/{}/1.0", + encoded_schema_name + ); + + let did_url = DidUrl::from_str(did_url_string.as_str()).unwrap(); + let request = build_request(&did_url, &request_builder).unwrap(); + let schema_name = (*(request.req_json).get("operation").unwrap()) + .get("data") + .and_then(|v| v.get("name")) + .and_then(|v| v.as_str()) + .unwrap(); + assert_eq!(schema_name, name); + } +} diff --git a/libindy_vdr/tests/nym.rs b/libindy_vdr/tests/nym.rs index dd4bcf7a..4f77a312 100644 --- a/libindy_vdr/tests/nym.rs +++ b/libindy_vdr/tests/nym.rs @@ -52,7 +52,7 @@ mod builder { identity: Identity, diddoc_content: serde_json::Value, ) { - let copy = diddoc_content.clone(); + // let copy = diddoc_content.clone(); let nym_request = request_builder .build_nym_request( &trustee_did, @@ -60,7 +60,7 @@ mod builder { Some(identity.verkey.clone()), Some(ALIAS.to_string()), Some(ROLE.to_string()), - Some(diddoc_content), + Some(&diddoc_content), None, ) .unwrap(); @@ -71,7 +71,7 @@ mod builder { "verkey": identity.verkey, "alias": ALIAS, "role": role_to_code(Some(String::from(ROLE))).unwrap(), - "diddocContent": copy, + "diddocContent": diddoc_content.to_string(), }); helpers::check_request_operation(&nym_request, expected_result); @@ -192,7 +192,7 @@ mod builder { mod send { use super::*; use crate::utils::pool::TestPool; - use indy_vdr::ledger::constants::ROLE_REMOVE; + use indy_vdr::ledger::{constants::ROLE_REMOVE, responses::GetNymResultV1}; #[rstest] fn test_pool_send_nym_request(pool: TestPool, trustee: Identity, identity: Identity) { @@ -272,6 +272,60 @@ mod send { assert_eq!(expected_data, parse_get_nym_response(&response)); } + #[cfg(feature = "local_nodes_pool_did_indy")] + #[rstest] + fn test_pool_send_nym_request_with_diddoc_content( + pool: TestPool, + trustee: Identity, + identity: Identity, + diddoc_content: serde_json::Value, + ) { + // Send NYM + let mut nym_request = pool + .request_builder() + .build_nym_request( + &trustee.did, + &identity.did, + Some(identity.verkey.to_string()), + Some(ALIAS.to_string()), + Some(ROLE.to_string()), + Some(&diddoc_content), + None, + ) + .unwrap(); + + let nym_response = + helpers::sign_and_send_request(&trustee, &pool, &mut nym_request).unwrap(); + + // Get NYM + let get_nym_request = pool + .request_builder() + .build_get_nym_request(None, &identity.did, None, None) + .unwrap(); + + let response = pool + .send_request_with_retries(&get_nym_request, &nym_response) + .unwrap(); + + let expected_data = json!({ + "identifier": &trustee.did, + "dest": &identity.did, + "verkey": &identity.verkey, + "role": role_to_code(Some(String::from(ROLE))).unwrap(), + "diddocContent": &diddoc_content.to_string() + }); + + let data: GetNymResultV1 = serde_json::from_str( + helpers::get_response_data(&response) + .unwrap() + .as_str() + .unwrap(), + ) + .unwrap(); + + assert_eq!(expected_data, serde_json::to_value(data).unwrap()); + } + #[rstest( role, case("STEWARD"), diff --git a/wrappers/python/.gitignore b/wrappers/python/.gitignore index c3b39579..88cbc7ae 100644 --- a/wrappers/python/.gitignore +++ b/wrappers/python/.gitignore @@ -1,5 +1,6 @@ build dist +github .pytest_cache __pycache__ *.dll diff --git a/wrappers/python/indy_vdr/bindings.py b/wrappers/python/indy_vdr/bindings.py index f74e20a0..69464c9c 100644 --- a/wrappers/python/indy_vdr/bindings.py +++ b/wrappers/python/indy_vdr/bindings.py @@ -276,7 +276,7 @@ def resolve(resolver_handle: ResolverHandle, did: str) -> asyncio.Future: def dereference(pool_handle: PoolHandle, did_url: str) -> asyncio.Future: - """Dereference a DID Urk to retrieve a ledger object.""" + """Dereference a DID Url to retrieve a ledger object.""" return do_call_async( "indy_vdr_dereference", pool_handle, diff --git a/wrappers/python/indy_vdr/ledger.py b/wrappers/python/indy_vdr/ledger.py index bb97f4bf..90f6e9b0 100644 --- a/wrappers/python/indy_vdr/ledger.py +++ b/wrappers/python/indy_vdr/ledger.py @@ -488,7 +488,7 @@ def build_nym_request( alias: str = None, role: str = None, diddoc_content: str = None, - version: Optional[int] = None, + version: int = None, ) -> Request: """ Builds a NYM request to create new DID on the ledger. @@ -520,7 +520,7 @@ def build_nym_request( alias_p = encode_str(alias) role_p = encode_str(role) diddoc_content_p = encode_str(diddoc_content) - version = c_int32(version if version is not None else -1) + version_c = c_int32(version if version is not None else -1) do_call( "indy_vdr_build_nym_request", did_p, @@ -529,7 +529,7 @@ def build_nym_request( alias_p, role_p, diddoc_content_p, - version, + version_c, byref(handle), ) return Request(handle) From 8523d337f3902c3757f997bd85f00fcddcdc9009 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20W=C3=B6rner?= Date: Wed, 23 Mar 2022 11:18:34 +0100 Subject: [PATCH 048/117] refactor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- .github/workflows/build.yml | 2 +- libindy_vdr/src/resolver/did_document.rs | 28 +- libindy_vdr/src/resolver/mod.rs | 4 +- libindy_vdr/src/resolver/resolver.rs | 763 ++++------------------- libindy_vdr/src/resolver/types.rs | 50 ++ libindy_vdr/src/resolver/utils.rs | 4 +- 6 files changed, 190 insertions(+), 661 deletions(-) create mode 100644 libindy_vdr/src/resolver/types.rs diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 956d5c69..06e560f5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -6,7 +6,7 @@ env: on: push: - branches: [main, did-indy, integration_test] + branches: [main, did-indy] pull_request: branches: [main, did-indy] release: diff --git a/libindy_vdr/src/resolver/did_document.rs b/libindy_vdr/src/resolver/did_document.rs index 79c3f0dd..ede383b8 100644 --- a/libindy_vdr/src/resolver/did_document.rs +++ b/libindy_vdr/src/resolver/did_document.rs @@ -9,20 +9,20 @@ pub const DID_CORE_CONTEXT: &str = "https://www.w3.org/ns/did/v1"; #[derive(Serialize, PartialEq, Debug)] #[serde(rename_all = "camelCase")] pub struct Ed25519VerificationKey2018 { - pub id: String, - pub type_: String, - pub controller: String, - pub public_key_base58: String, + id: String, + type_: String, + controller: String, + public_key_base58: String, } #[derive(Serialize, Deserialize, PartialEq, Debug)] #[serde(rename_all = "camelCase")] pub struct DidCommService { - pub id: String, - pub type_: String, - pub recipient_keys: Vec, - pub routing_keys: Vec, - pub priority: u8, + id: String, + type_: String, + recipient_keys: Vec, + routing_keys: Vec, + priority: u8, } impl DidCommService { @@ -40,9 +40,9 @@ impl DidCommService { #[derive(Serialize, Deserialize, PartialEq, Debug)] #[serde(rename_all = "camelCase")] struct GenericService { - pub id: String, - pub type_: String, - pub service_endpoint: String, + id: String, + type_: String, + service_endpoint: String, } #[derive(Serialize, Deserialize, PartialEq, Debug)] @@ -51,8 +51,8 @@ pub struct DidDocument { namespace: String, id: String, verkey: String, - endpoint: Option, - diddoc_content: Option, + pub endpoint: Option, + pub diddoc_content: Option, } impl DidDocument { diff --git a/libindy_vdr/src/resolver/mod.rs b/libindy_vdr/src/resolver/mod.rs index 5bf29c62..25449dee 100644 --- a/libindy_vdr/src/resolver/mod.rs +++ b/libindy_vdr/src/resolver/mod.rs @@ -1,6 +1,8 @@ -mod resolver; +pub mod resolver; pub mod did; pub mod did_document; +pub mod types; +pub mod utils; pub use self::resolver::{PoolResolver, PoolRunnerResolver}; diff --git a/libindy_vdr/src/resolver/resolver.rs b/libindy_vdr/src/resolver/resolver.rs index 9e90d068..3239021b 100644 --- a/libindy_vdr/src/resolver/resolver.rs +++ b/libindy_vdr/src/resolver/resolver.rs @@ -1,65 +1,11 @@ -use crate::utils::Qualifiable; -use chrono::{DateTime, Utc}; -use futures_executor::block_on; -use serde_json::Value as SJsonValue; -use time::format_description::well_known::Rfc3339; -use time::OffsetDateTime; - -use super::did::{DidUrl, LedgerObject, QueryParameter}; -use super::did_document::{DidDocument, LEGACY_INDY_SERVICE}; -use crate::common::error::prelude::*; -use crate::ledger::responses::{Endpoint, GetNymResultV1}; - -use crate::ledger::identifiers::{CredentialDefinitionId, RevocationRegistryId, SchemaId}; -use crate::ledger::{constants, RequestBuilder}; -use crate::pool::helpers::perform_ledger_request; -use crate::pool::{Pool, PoolRunner, PreparedRequest, RequestResult, TimingResult}; -use crate::utils::did::DidValue; - -#[derive(Serialize, Deserialize, PartialEq, Debug)] -#[serde(rename_all = "camelCase")] -pub enum Result { - DidDocument(DidDocument), - Content(SJsonValue), -} - -#[derive(Serialize, Deserialize, PartialEq, Debug)] -#[serde(rename_all = "camelCase")] -pub enum Metadata { - DidDocumentMetadata(DidDocumentMetadata), - ContentMetadata(ContentMetadata), -} - -#[derive(Serialize, Deserialize, PartialEq, Debug)] -#[serde(rename_all = "camelCase")] -pub struct ContentMetadata { - node_response: SJsonValue, - object_type: String, -} - -#[derive(Serialize, Deserialize, PartialEq, Debug)] -#[serde(rename_all = "camelCase")] -pub struct DidDocumentMetadata { - node_response: SJsonValue, - object_type: String, - self_certification_version: Option, -} +use super::did::DidUrl; +use super::types::*; +use super::utils::*; -#[derive(Serialize, Deserialize, PartialEq, Debug)] -#[serde(rename_all = "camelCase")] -pub struct ResolutionResult { - did_resolution_metadata: Option, - did_document: Option, - did_document_metadata: Option, -} +use crate::common::error::prelude::*; -#[derive(Serialize, Deserialize, PartialEq, Debug)] -#[serde(rename_all = "camelCase")] -pub struct DereferencingResult { - dereferencing_metadata: Option, - content_stream: Option, - content_metadata: Option, -} +use crate::ledger::RequestBuilder; +use crate::pool::{Pool, PoolRunner, RequestResult, TimingResult}; /// DID (URL) Resolver interface for a pool compliant with did:indy method spec pub struct PoolResolver { @@ -72,9 +18,10 @@ impl PoolResolver { } /// Dereference a DID Url and return a serialized `DereferencingResult` - pub fn dereference(&self, did_url: &str) -> VdrResult { + pub async fn dereference(&self, did_url: &str) -> VdrResult { debug!("PoolResolver: Dereference DID Url {}", did_url); - let (data, metadata) = self._resolve(did_url)?; + let did_url = DidUrl::from_str(did_url)?; + let (data, metadata) = self._resolve(&did_url).await?; let content = match data { Result::Content(c) => Some(c), @@ -97,12 +44,19 @@ impl PoolResolver { } /// Resolve a DID and return a serialized `ResolutionResult` - pub fn resolve(&self, did: &str) -> VdrResult { + pub async fn resolve(&self, did: &str) -> VdrResult { debug!("PoolResolver: Resolve DID {}", did); - let (data, metadata) = self._resolve(did)?; + let did = DidUrl::from_str(did)?; + let (data, metadata) = self._resolve(&did).await?; let diddoc = match data { - Result::DidDocument(doc) => Some(doc.to_value()?), + Result::DidDocument(mut doc) => { + // Try to find legacy endpoint using a GET_ATTRIB txn if diddoc_content is none + if doc.diddoc_content.is_none() { + doc.endpoint = fetch_legacy_endpoint(&self.pool, &did.id).await.ok(); + } + Some(doc.to_value()?) + } _ => None, }; @@ -122,115 +76,16 @@ impl PoolResolver { } // Internal method to resolve and dereference - fn _resolve(&self, did: &str) -> VdrResult<(Result, Metadata)> { - let did_url = DidUrl::from_str(did)?; - + async fn _resolve(&self, did_url: &DidUrl) -> VdrResult<(Result, Metadata)> { let builder = self.pool.get_request_builder(); let request = build_request(&did_url, &builder)?; - let ledger_data = self.handle_request(&request)?; - let data = parse_ledger_data(&ledger_data)?; - - let (result, metadata) = match request.txn_type.as_str() { - constants::GET_NYM => { - let get_nym_result: GetNymResultV1 = - serde_json::from_str(data.as_str().unwrap()) - .map_err(|_| err_msg(VdrErrorKind::Resolver, "Could not parse NYM data"))?; - - let endpoint: Option = if get_nym_result.diddoc_content.is_none() { - // Legacy: Try to find an attached ATTRIBUTE transacation with raw endpoint - self.fetch_legacy_endpoint(&did_url.id).ok() - } else { - None - }; - - let did_document = DidDocument::new( - &did_url.namespace, - &get_nym_result.dest, - &get_nym_result.verkey, - endpoint, - None, - ); - - let metadata = Metadata::DidDocumentMetadata(DidDocumentMetadata { - node_response: serde_json::from_str(&ledger_data).unwrap(), - object_type: String::from("NYM"), - self_certification_version: get_nym_result.version, - }); - - (Result::DidDocument(did_document), metadata) - } - constants::GET_CRED_DEF => ( - Result::Content(data), - Metadata::ContentMetadata(ContentMetadata { - node_response: serde_json::from_str(&ledger_data).unwrap(), - object_type: String::from("CRED_DEF"), - }), - ), - constants::GET_SCHEMA => ( - Result::Content(data), - Metadata::ContentMetadata(ContentMetadata { - node_response: serde_json::from_str(&ledger_data).unwrap(), - object_type: String::from("SCHEMA"), - }), - ), - constants::GET_REVOC_REG_DEF => ( - Result::Content(data), - Metadata::ContentMetadata(ContentMetadata { - node_response: serde_json::from_str(&ledger_data).unwrap(), - object_type: String::from("REVOC_REG_DEF"), - }), - ), - constants::GET_REVOC_REG_DELTA => ( - Result::Content(data), - Metadata::ContentMetadata(ContentMetadata { - node_response: serde_json::from_str(&ledger_data).unwrap(), - object_type: String::from("REVOC_REG_DELTA"), - }), - ), - _ => ( - Result::Content(data), - Metadata::ContentMetadata(ContentMetadata { - node_response: serde_json::from_str(&ledger_data).unwrap(), - object_type: String::from("REVOC_REG_DELTA"), - }), - ), - }; - - let result_with_metadata = (result, metadata); - - Ok(result_with_metadata) - } - - fn fetch_legacy_endpoint(&self, did: &DidValue) -> VdrResult { - let builder = self.pool.get_request_builder(); - let request = builder.build_get_attrib_request( - None, - did, - Some(String::from(LEGACY_INDY_SERVICE)), - None, - None, - )?; - let ledger_data = self.handle_request(&request)?; - let endpoint_data = parse_ledger_data(&ledger_data)?; - let endpoint_data: Endpoint = serde_json::from_str(endpoint_data.as_str().unwrap()) - .map_err(|_| err_msg(VdrErrorKind::Resolver, "Could not parse endpoint data"))?; - Ok(endpoint_data) - } - - fn handle_request(&self, request: &PreparedRequest) -> VdrResult { - let (result, _timing) = block_on(self.request_transaction(&request))?; - match result { - RequestResult::Reply(data) => Ok(data), - RequestResult::Failed(error) => Err(error), - } - } + let ledger_data = handle_request(&self.pool, &request).await?; + let txn_type = request.txn_type.as_str(); + let namespace = did_url.namespace.clone(); + let result = handle_resolution_result(namespace.as_str(), &ledger_data, txn_type)?; - async fn request_transaction( - &self, - request: &PreparedRequest, - ) -> VdrResult<(RequestResult, Option)> { - perform_ledger_request(&self.pool, &request).await + Ok(result) } } @@ -250,8 +105,9 @@ impl<'a> PoolRunnerResolver<'a> { did_url: &str, callback: Callback>, ) -> VdrResult<()> { + let did_url = DidUrl::from_str(did_url)?; self._resolve( - did_url, + &did_url, Box::new(move |result| { let (data, metadata) = result.unwrap(); let content = match data { @@ -278,502 +134,121 @@ impl<'a> PoolRunnerResolver<'a> { /// Resolve a DID and return a serialized `ResolutionResult` pub fn resolve(&self, did: &str, callback: Callback>) -> VdrResult<()> { + let did = DidUrl::from_str(did)?; self._resolve( - did, + &did, Box::new(move |result| { - let (data, metadata) = result.unwrap(); - let diddoc = match data { - Result::DidDocument(doc) => Some(doc.to_value().unwrap()), - _ => None, - }; + match result { + Ok((data, metadata)) => { + match data { + // TODO: Doc needs to be mutable, when we uncomment + Result::DidDocument(doc) => { + // Try to find legacy endpoint using a GET_ATTRIB txn if diddoc_content is none + if doc.diddoc_content.is_none() { + // let did_copy = did.id.clone(); + // fetch_legacy_endpoint_with_runner( + // self.runner, + // &did_copy, + // Box::new(|result| { + // doc.endpoint = result.ok(); + // let diddoc = Some(doc.to_value().unwrap()); + // let md = if let Metadata::DidDocumentMetadata(md) = + // metadata + // { + // Some(md) + // } else { + // None + // }; + + // let result = ResolutionResult { + // did_resolution_metadata: None, + // did_document: diddoc, + // did_document_metadata: md, + // }; + + // callback(Ok( + // serde_json::to_string_pretty(&result).unwrap() + // )) + // }), + // ); + } else { + // let diddoc = Some(doc.to_value().unwrap()); + // let md = if let Metadata::DidDocumentMetadata(md) = metadata { + // Some(md) + // } else { + // None + // }; + + // let result = ResolutionResult { + // did_resolution_metadata: None, + // did_document: diddoc, + // did_document_metadata: md, + // }; + + // callback(Ok(serde_json::to_string_pretty(&result).unwrap())) + } - let md = if let Metadata::DidDocumentMetadata(md) = metadata { - Some(md) - } else { - None - }; + // For now, until if/else above is used - let result = ResolutionResult { - did_resolution_metadata: None, - did_document: diddoc, - did_document_metadata: md, - }; + let diddoc = Some(doc.to_value().unwrap()); + let md = if let Metadata::DidDocumentMetadata(md) = metadata { + Some(md) + } else { + None + }; - callback(Ok(serde_json::to_string_pretty(&result).unwrap())) + let result = ResolutionResult { + did_resolution_metadata: None, + did_document: diddoc, + did_document_metadata: md, + }; + + callback(Ok(serde_json::to_string_pretty(&result).unwrap())) + } + _ => {} + }; + } + // TODO: How to handle errors? + Err(_err) => {} + } }), - ) + )?; + Ok(()) } - // TODO: Refactor - // TODO: Adapt according to PoolResolver. fn _resolve( &self, - did: &str, + did_url: &DidUrl, callback: Callback>, ) -> VdrResult<()> { - let did_url = DidUrl::from_str(did)?; + let namespace = did_url.namespace.clone(); let builder = RequestBuilder::default(); let request = build_request(&did_url, &builder)?; let txn_type = request.txn_type.clone(); + self.runner.send_request( request, Box::new( move |result: VdrResult<(RequestResult, Option)>| { - match result { - Ok((reply, _)) => { - match reply { - RequestResult::Reply(reply_data) => { - let data = parse_ledger_data(&reply_data).unwrap(); - if txn_type.as_str() == constants::GET_NYM { - let get_nym_result: GetNymResultV1 = - serde_json::from_str(data.as_str().unwrap()).unwrap(); - - // TODO: Fix fetch_legacy_endpoint - // let did = did_url.id.clone(); - if get_nym_result.diddoc_content.is_none() { - // Legacy: Try to find an attached ATTRIBUTE transacation with raw endpoint - // self._fetch_legacy_endpoint( - // &did, - // Box::new(move |result| { - // let did_document = DidDocument::new( - // &did_url.namespace, - // &get_nym_result.dest, - // &get_nym_result.verkey, - // result.ok(), - // None, - // ); - - // let metadata = ContentMetadata { - // node_response: serde_json::from_str( - // &reply_data, - // ) - // .unwrap(), - // object_type: String::from("NYM"), - // }; - - // let result = - // Some(Result::DidDocument(did_document)); - - // let result_with_metadata = - // (result.unwrap(), metadata); - // callback(Ok(result_with_metadata)); - // }), - // ); - } - - let did_document = DidDocument::new( - &did_url.namespace, - &get_nym_result.dest, - &get_nym_result.verkey, - None, - None, - ); - - let metadata = - Metadata::DidDocumentMetadata(DidDocumentMetadata { - node_response: serde_json::from_str(&reply_data) - .unwrap(), - object_type: String::from("NYM"), - self_certification_version: get_nym_result.version, - }); - - let result = Some(Result::DidDocument(did_document)); - - let result_with_metadata = (result.unwrap(), metadata); - callback(Ok(result_with_metadata)); - } else { - let (result, metadata) = match txn_type.as_str() { - constants::GET_CRED_DEF => ( - Result::Content(data), - Metadata::ContentMetadata(ContentMetadata { - node_response: serde_json::from_str( - &reply_data, - ) - .unwrap(), - object_type: String::from("CRED_DEF"), - }), - ), - constants::GET_SCHEMA => ( - Result::Content(data), - Metadata::ContentMetadata(ContentMetadata { - node_response: serde_json::from_str( - &reply_data, - ) - .unwrap(), - object_type: String::from("SCHEMA"), - }), - ), - constants::GET_REVOC_REG_DEF => ( - Result::Content(data), - Metadata::ContentMetadata(ContentMetadata { - node_response: serde_json::from_str( - &reply_data, - ) - .unwrap(), - object_type: String::from("REVOC_REG_DEF"), - }), - ), - constants::GET_REVOC_REG_DELTA => ( - Result::Content(data), - Metadata::ContentMetadata(ContentMetadata { - node_response: serde_json::from_str( - &reply_data, - ) - .unwrap(), - object_type: String::from("REVOC_REG_DELTA"), - }), - ), - _ => ( - Result::Content(data), - Metadata::ContentMetadata(ContentMetadata { - node_response: serde_json::from_str( - &reply_data, - ) - .unwrap(), - object_type: String::from("REVOC_REG_DELTA"), - }), - ), - }; - - let result_with_metadata = (result, metadata); - callback(Ok(result_with_metadata)); - } - } - RequestResult::Failed(err) => callback(Err(err)), - } - } - Err(err) => callback(Err(err)), - } - }, - ), - ) - } - - fn _fetch_legacy_endpoint( - &self, - did: &DidValue, - callback: Callback>, - ) -> VdrResult<()> { - let builder = RequestBuilder::default(); - let request = builder.build_get_attrib_request( - None, - did, - Some(String::from(LEGACY_INDY_SERVICE)), - None, - None, - )?; - self.runner.send_request( - request, - Box::new(move |result| match result { - Ok((res, _)) => match res { - RequestResult::Reply(reply_data) => { - let endpoint_data = parse_ledger_data(&reply_data).unwrap(); - let endpoint_data: Endpoint = - serde_json::from_str(endpoint_data.as_str().unwrap()).unwrap(); - callback(Ok(endpoint_data)); + let ledger_data = match result { + Ok((reply, _)) => match reply { + RequestResult::Reply(reply_data) => Ok(reply_data), + RequestResult::Failed(err) => Err(err), + }, + Err(err) => Err(err), } - RequestResult::Failed(err) => callback(Err(err)), - }, - Err(err) => callback(Err(err)), - }), - ) - } -} + .unwrap(); -type Callback = Box ()) + Send>; - -fn build_request(did: &DidUrl, builder: &RequestBuilder) -> VdrResult { - let request = if did.path.is_some() { - match LedgerObject::from_str(did.path.as_ref().unwrap().as_str())? { - LedgerObject::Schema(schema) => builder.build_get_schema_request( - None, - &SchemaId::new(&did.id, &schema.name, &schema.version), - ), - LedgerObject::ClaimDef(claim_def) => builder.build_get_cred_def_request( - None, - &CredentialDefinitionId::from_str( - format!( - "{}:3:CL:{}:{}", - &did.id, claim_def.schema_seq_no, claim_def.name - ) - .as_str(), - ) - .unwrap(), - ), - LedgerObject::RevRegDef(rev_reg_def) => builder.build_get_revoc_reg_def_request( - None, - &RevocationRegistryId::from_str( - format!( - "{}:4:{}:3:CL:{}:{}:CL_ACCUM:{}", - &did.id, - &did.id, - rev_reg_def.schema_seq_no, - rev_reg_def.claim_def_name, - rev_reg_def.tag + let result = handle_resolution_result( + namespace.as_str(), + &ledger_data, + txn_type.as_str(), ) - .as_str(), - ) - .unwrap(), + .unwrap(); + callback(Ok(result)) + }, ), - LedgerObject::RevRegEntry(rev_reg_entry) => { - // If From or To parameters, return RevRegDelta request - if did.query.contains_key(&QueryParameter::From) - || did.query.contains_key(&QueryParameter::To) - { - let mut from: Option = None; - if did.query.contains_key(&QueryParameter::From) { - from = did - .query - .get(&QueryParameter::From) - .and_then(|d| OffsetDateTime::parse(d, &Rfc3339).ok()) - .and_then(|d| Some(d.unix_timestamp())); - } - - let to = parse_or_now(did.query.get(&QueryParameter::To))?; - - builder.build_get_revoc_reg_delta_request( - None, - &RevocationRegistryId::from_str( - format!( - "{}:4:{}:3:CL:{}:{}:CL_ACCUM:{}", - &did.id, - &did.id, - rev_reg_entry.schema_seq_no, - rev_reg_entry.claim_def_name, - rev_reg_entry.tag - ) - .as_str(), - ) - .unwrap(), - from, - to, - ) - // Else return RevRegEntry request - } else { - let timestamp = parse_or_now(did.query.get(&QueryParameter::VersionTime))?; - - builder.build_get_revoc_reg_request( - None, - &RevocationRegistryId::from_str( - format!( - "{}:4:{}:3:CL:{}:{}:CL_ACCUM:{}", - &did.id, - &did.id, - rev_reg_entry.schema_seq_no, - rev_reg_entry.claim_def_name, - rev_reg_entry.tag - ) - .as_str(), - ) - .unwrap(), - timestamp, - ) - } - } - // This path is deprecated. Deltas can be retrieved through RevRegEntry - LedgerObject::RevRegDelta(rev_reg_delta) => { - let mut from: Option = None; - if did.query.contains_key(&QueryParameter::From) { - from = did - .query - .get(&QueryParameter::From) - .and_then(|d| OffsetDateTime::parse(d, &Rfc3339).ok()) - .and_then(|d| Some(d.unix_timestamp())); - } - - let to = parse_or_now(did.query.get(&QueryParameter::To))?; - - builder.build_get_revoc_reg_delta_request( - None, - &RevocationRegistryId::from_str( - format!( - "{}:4:{}:3:CL:{}:{}:CL_ACCUM:{}", - &did.id, - &did.id, - rev_reg_delta.schema_seq_no, - rev_reg_delta.claim_def_name, - rev_reg_delta.tag - ) - .as_str(), - ) - .unwrap(), - from, - to, - ) - } - } - } else { - let seq_no: Option = did - .query - .get(&QueryParameter::VersionId) - .and_then(|v| v.parse().ok()); - let timestamp: Option = did - .query - .get(&QueryParameter::VersionTime) - .and_then(|d| OffsetDateTime::parse(d, &Rfc3339).ok()) - .and_then(|d| Some(d.unix_timestamp())) - .and_then(|d| Some(d as u64)); - - builder.build_get_nym_request(Option::None, &did.id, seq_no, timestamp) - }; - request -} - -fn parse_ledger_data(ledger_data: &str) -> VdrResult { - let v: SJsonValue = serde_json::from_str(&ledger_data) - .map_err(|_| err_msg(VdrErrorKind::Resolver, "Could not parse ledger response"))?; - let data: &SJsonValue = &v["result"]["data"]; - if *data == SJsonValue::Null { - Err(err_msg( - VdrErrorKind::Resolver, - format!("Empty data in ledger response"), - )) - } else { - Ok(data.to_owned()) - } -} - -fn parse_or_now(datetime: Option<&String>) -> VdrResult { - match datetime { - Some(datetime) => { - let dt = OffsetDateTime::parse(datetime, &Rfc3339).map_err(|_| { - err_msg( - VdrErrorKind::Resolver, - format!("Could not parse datetime {}", datetime), - ) - })?; - Ok(dt.unix_timestamp()) - } - None => Ok(OffsetDateTime::now_utc().unix_timestamp()), - } -} - -#[cfg(test)] -mod tests { - - use urlencoding::encode; - - use super::*; - use rstest::*; - - use crate::pool::ProtocolVersion; - - #[fixture] - fn request_builder() -> RequestBuilder { - RequestBuilder::new(ProtocolVersion::Node1_4) - } - - #[rstest] - fn build_get_revoc_reg_request_from_version_time(request_builder: RequestBuilder) { - let datetime_as_str = "2020-12-20T19:17:47Z"; - let did_url_as_str = format!("did:indy:idunion:Dk1fRRTtNazyMuK2cr64wp/anoncreds/v0/REV_REG_ENTRY/104/revocable/a4e25e54?versionTime={}",datetime_as_str); - let did_url = DidUrl::from_str(&did_url_as_str).unwrap(); - let request = build_request(&did_url, &request_builder).unwrap(); - let timestamp = (*(request.req_json).get("operation").unwrap()) - .get("timestamp") - .unwrap() - .as_u64() - .unwrap() as i64; - assert_eq!(constants::GET_REVOC_REG, request.txn_type); - - assert_eq!( - OffsetDateTime::parse(datetime_as_str, &Rfc3339) - .unwrap() - .unix_timestamp(), - timestamp - ); - } - - #[rstest] - fn build_get_revoc_reg_without_version_time(request_builder: RequestBuilder) { - let now = OffsetDateTime::now_utc().unix_timestamp(); - - let did_url_as_str = "did:indy:idunion:Dk1fRRTtNazyMuK2cr64wp/anoncreds/v0/REV_REG_ENTRY/104/revocable/a4e25e54"; - let did_url = DidUrl::from_str(did_url_as_str).unwrap(); - let request = build_request(&did_url, &request_builder).unwrap(); - let timestamp = (*(request.req_json).get("operation").unwrap()) - .get("timestamp") - .unwrap() - .as_u64() - .unwrap() as i64; - - assert_eq!(constants::GET_REVOC_REG, request.txn_type); - assert!(timestamp >= now); - } - - #[rstest] - fn build_get_revoc_reg_request_fails_with_unparsable_version_time( - request_builder: RequestBuilder, - ) { - let datetime_as_str = "20201220T19:17:47Z"; - let did_url_as_str = format!("did:indy:idunion:Dk1fRRTtNazyMuK2cr64wp/anoncreds/v0/REV_REG_ENTRY/104/revocable/a4e25e54?versionTime={}",datetime_as_str); - let did_url = DidUrl::from_str(&did_url_as_str).unwrap(); - let _err = build_request(&did_url, &request_builder).unwrap_err(); - } - - #[rstest] - fn build_get_revoc_reg_delta_request_with_from_to(request_builder: RequestBuilder) { - let from_as_str = "2019-12-20T19:17:47Z"; - let to_as_str = "2020-12-20T19:17:47Z"; - let did_url_as_str = format!("did:indy:idunion:Dk1fRRTtNazyMuK2cr64wp/anoncreds/v0/REV_REG_ENTRY/104/revocable/a4e25e54?from={}&to={}",from_as_str, to_as_str); - let did_url = DidUrl::from_str(&did_url_as_str).unwrap(); - let request = build_request(&did_url, &request_builder).unwrap(); - assert_eq!(request.txn_type, constants::GET_REVOC_REG_DELTA); - } - - #[rstest] - fn build_get_revoc_reg_delta_request_with_from_only(request_builder: RequestBuilder) { - let now = OffsetDateTime::now_utc().unix_timestamp(); - let from_as_str = "2019-12-20T19:17:47Z"; - let did_url_as_str = format!("did:indy:idunion:Dk1fRRTtNazyMuK2cr64wp/anoncreds/v0/REV_REG_ENTRY/104/revocable/a4e25e54?from={}",from_as_str); - let did_url = DidUrl::from_str(&did_url_as_str).unwrap(); - let request = build_request(&did_url, &request_builder).unwrap(); - - let to = (*(request.req_json).get("operation").unwrap()) - .get("to") - .unwrap() - .as_u64() - .unwrap() as i64; - assert_eq!(request.txn_type, constants::GET_REVOC_REG_DELTA); - assert!(to >= now) - } - - #[rstest] - fn build_get_revoc_reg_delta_request_without_parameter(request_builder: RequestBuilder) { - let now = OffsetDateTime::now_utc().unix_timestamp(); - let did_url_as_str = "did:indy:idunion:Dk1fRRTtNazyMuK2cr64wp/anoncreds/v0/REV_REG_DELTA/104/revocable/a4e25e54"; - let did_url = DidUrl::from_str(did_url_as_str).unwrap(); - let request = build_request(&did_url, &request_builder).unwrap(); - - let to = (*(request.req_json).get("operation").unwrap()) - .get("to") - .unwrap() - .as_u64() - .unwrap() as i64; - - let from = (*(request.req_json).get("operation").unwrap()).get("from"); - assert_eq!(request.txn_type, constants::GET_REVOC_REG_DELTA); - assert!(from.is_none()); - assert!(to >= now); - } - - #[rstest] - fn build_get_schema_request_with_whitespace(request_builder: RequestBuilder) { - let name = "My Schema"; - let encoded_schema_name = encode(name).to_string(); - let did_url_string = format!( - "did:indy:idunion:Dk1fRRTtNazyMuK2cr64wp/anoncreds/v0/SCHEMA/{}/1.0", - encoded_schema_name - ); - - let did_url = DidUrl::from_str(did_url_string.as_str()).unwrap(); - let request = build_request(&did_url, &request_builder).unwrap(); - let schema_name = (*(request.req_json).get("operation").unwrap()) - .get("data") - .and_then(|v| v.get("name")) - .and_then(|v| v.as_str()) - .unwrap(); - assert_eq!(schema_name, name); + ) } } diff --git a/libindy_vdr/src/resolver/types.rs b/libindy_vdr/src/resolver/types.rs new file mode 100644 index 00000000..6c17227f --- /dev/null +++ b/libindy_vdr/src/resolver/types.rs @@ -0,0 +1,50 @@ +use serde_json::Value as SJsonValue; + +use super::did_document::DidDocument; + +pub type Callback = Box ()) + Send>; + +#[derive(Serialize, Deserialize, PartialEq, Debug)] +#[serde(rename_all = "camelCase")] +pub enum Result { + DidDocument(DidDocument), + Content(SJsonValue), +} + +#[derive(Serialize, Deserialize, PartialEq, Debug)] +#[serde(rename_all = "camelCase")] +pub enum Metadata { + DidDocumentMetadata(DidDocumentMetadata), + ContentMetadata(ContentMetadata), +} + +#[derive(Serialize, Deserialize, PartialEq, Debug)] +#[serde(rename_all = "camelCase")] +pub struct ContentMetadata { + pub node_response: SJsonValue, + pub object_type: String, +} + +#[derive(Serialize, Deserialize, PartialEq, Debug)] +#[serde(rename_all = "camelCase")] +pub struct DidDocumentMetadata { + pub node_response: SJsonValue, + pub object_type: String, + pub self_certification_version: Option, +} + +#[derive(Serialize, Deserialize, PartialEq, Debug)] +#[serde(rename_all = "camelCase")] +pub struct ResolutionResult { + pub did_resolution_metadata: Option, + pub did_document: Option, + pub did_document_metadata: Option, +} + +#[derive(Serialize, Deserialize, PartialEq, Debug)] +#[serde(rename_all = "camelCase")] +pub struct DereferencingResult { + pub dereferencing_metadata: Option, + pub content_stream: Option, + pub content_metadata: Option, +} diff --git a/libindy_vdr/src/resolver/utils.rs b/libindy_vdr/src/resolver/utils.rs index 64beb55a..a6fcd291 100644 --- a/libindy_vdr/src/resolver/utils.rs +++ b/libindy_vdr/src/resolver/utils.rs @@ -169,7 +169,9 @@ pub fn handle_resolution_result( &get_nym_result.dest, &get_nym_result.verkey, None, - get_nym_result.diddoc_content.map(|v| serde_json::from_str(&v).unwrap()), + get_nym_result + .diddoc_content + .map(|v| serde_json::from_str(&v).unwrap()), ); let metadata = Metadata::DidDocumentMetadata(DidDocumentMetadata { From ba9de5ee409e98df3ad1674fededf29d535a18e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20W=C3=B6rner?= Date: Wed, 23 Mar 2022 11:26:45 +0100 Subject: [PATCH 049/117] add comments to go wrapper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- wrappers/golang/vdr/indy_vdr.go | 6 ++++-- wrappers/golang/vdr/writes.go | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/wrappers/golang/vdr/indy_vdr.go b/wrappers/golang/vdr/indy_vdr.go index 785f7f04..3964e97a 100644 --- a/wrappers/golang/vdr/indy_vdr.go +++ b/wrappers/golang/vdr/indy_vdr.go @@ -127,11 +127,13 @@ func (r *Client) Submit(request []byte) (*ReadReply, error) { } //GetNym fetches the NYM transaction associated with a DID +//FIXME: Expose optional seq_no and timestamp to get specific NYM versions +// on did:indy compliant ledgers func (r *Client) GetNym(did string) (*ReadReply, error) { var nymreq C.int64_t var none *C.char - var none32 C.int32_t = -1 - var none64 C.int64_t = -1 + var none32 C.int32_t = -1 // seq_no + var none64 C.int64_t = -1 // timestamp cdid := C.CString(did) result := C.indy_vdr_build_get_nym_request(none, cdid, none32, none64, &nymreq) C.free(unsafe.Pointer(cdid)) diff --git a/wrappers/golang/vdr/writes.go b/wrappers/golang/vdr/writes.go index db69b630..e910e01c 100644 --- a/wrappers/golang/vdr/writes.go +++ b/wrappers/golang/vdr/writes.go @@ -4,6 +4,7 @@ import ( "github.com/pkg/errors" ) +// FIXME: Expose optional diddoc_content and version field on did:indy compliant ledgers func (r *Client) CreateNym(did, verkey, role, from string, signer Signer) error { nymRequest := NewNym(did, verkey, from, role) From 3d61429249cc41d1d3656e239424c45ec2f66ada Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20W=C3=B6rner?= Date: Wed, 23 Mar 2022 17:40:27 +0100 Subject: [PATCH 050/117] multiple ledger support for proxy. Refresh not implemented MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- .dockerignore | 1 + README.md | 52 ++++--- indy-vdr-proxy/Cargo.toml | 5 +- indy-vdr-proxy/src/app.rs | 27 +++- indy-vdr-proxy/src/handlers.rs | 249 ++++++++++++++++++++------------ indy-vdr-proxy/src/main.rs | 194 ++++++++++++++++++------- indy-vdr-proxy/src/utils.rs | 74 ++++++++++ libindy_vdr/tests/resolver.rs | 99 +++++++++++++ libindy_vdr/tests/utils/pool.rs | 2 +- 9 files changed, 537 insertions(+), 166 deletions(-) create mode 100644 indy-vdr-proxy/src/utils.rs create mode 100644 libindy_vdr/tests/resolver.rs diff --git a/.dockerignore b/.dockerignore index 5874b8c3..455ced42 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,2 +1,3 @@ .git target +github diff --git a/README.md b/README.md index 11798e89..70075bbe 100644 --- a/README.md +++ b/README.md @@ -39,27 +39,45 @@ At a later stage it should be possible to install a precompiled 'wheel' package ## Proxy Server -The `indy-vdr-proxy` executable can be used to provide a simple REST API for interacting with the ledger. Command line options can be inspected by running `indy-vdr-proxy --help`. +The `indy-vdr-proxy` executable can be used to provide a simple REST API for interacting with one or more Indy ledgers. Command line options can be inspected by running `indy-vdr-proxy --help`. + +To start the proxy server for a single ledger use the following command: +`indy-vdr-proxy -p (-g )` + +To start the proxy server with the standard configuration of indy ledgers use the following command: +`indy-vdr-proxy -p --multiple-ledgers` +This will get the ledger configuration from `https://github.com/IDunion/indy-did-networks` + +A custom ledger configuration can be provided either by specificing a Github repo or a local folder: +`indy-vdr-proxy -p --multiple-ledgers -g ` +The structure needs to be as follows `/OPTIONAL/pool_transactions_genesis.json`, e.g. `/sovrin/staging/pool_transactions_genesis.json` Responses can be formatted in either HTML or JSON formats. HTML formatting is selected when the `text/html` content type is requested according to the Accept header (as sent by web browsers) or the request query string is set to `?html`. JSON formatting is selected otherwise, and may be explitly selected by using the query string `?raw`. For most ledger requests, JSON responses include information regarding which nodes were contacted is returned in the `X-Requests` header. -Sending prepared requests to the ledger is performed by delivering a POST request to the `/submit` endpoint, where the body of the request is the JSON-formatted payload. Additional endpoints are provided as shortcuts for ledger read transactions: - -- `/` The root path shows basic status information about the server and the ledger pool -- `/genesis` Return the current set of genesis transactions -- `/taa` Fetch the current ledger Transaction Author Agreement -- `/aml` Fetch the current ledger Acceptance Methods List (for the TAA) -- `/nym/{DID}` Fetch the NYM transaction associated with a DID -- `/attrib/{DID}/endpoint` Fetch the registered endpoint for a DID -- `/schema/{SCHEMA_ID}` Fetch a schema by its identifier -- `/cred_def/{CRED_DEF_ID}` Fetch a credential definition by its identifier -- `/rev_reg/{REV_REG_ID}` Fetch a revocation registry by its identifier -- `/rev_reg_def/{REV_REG_ID}` Fetch a revocation registry definition by its registry identifier -- `/rev_reg_delta/{REV_REG_ID}` Fetch a revocation registry delta by its registry identifier -- `/auth` Fetch all AUTH rules for the ledger -- `/auth/{TXN_TYPE}/{ADD|EDIT}` Fetch the AUTH rule for a specific transaction type and action -- `/txn/{SUBLEDGER}/{SEQ_NO}` Fetch a specific transaction by subledger identifier (0-2, or one of `pool`, `domain`, or `config`) and sequence number. +Sending prepared requests to the ledger is performed by delivering a POST request to the `{LEDGER}/submit` endpoint, where the body of the request is the JSON-formatted payload. Additional endpoints are provided as shortcuts for ledger read transactions: + +- `{LEDGER}/` The root path shows basic status information about the server and the ledger pool +- `{LEDGER}/genesis` Return the current set of genesis transactions +- `{LEDGER}/taa` Fetch the current ledger Transaction Author Agreement +- `{LEDGER}/aml` Fetch the current ledger Acceptance Methods List (for the TAA) +- `{LEDGER}/nym/{DID}` Fetch the NYM transaction associated with an unqualified DID +- `{LEDGER}/attrib/{DID}/endpoint` Fetch the registered endpoint for an unqualified DID +- `{LEDGER}/schema/{SCHEMA_ID}` Fetch a schema by its identifier +- `{LEDGER}/cred_def/{CRED_DEF_ID}` Fetch a credential definition by its identifier +- `{LEDGER}/rev_reg/{REV_REG_ID}` Fetch a revocation registry by its identifier +- `{LEDGER}/rev_reg_def/{REV_REG_ID}` Fetch a revocation registry definition by its registry identifier +- `{LEDGER}/rev_reg_delta/{REV_REG_ID}` Fetch a revocation registry delta by its registry identifier +- `{LEDGER}/auth` Fetch all AUTH rules for the ledger +- `{LEDGER}/auth/{TXN_TYPE}/{ADD|EDIT}` Fetch the AUTH rule for a specific transaction type and action +- `{LEDGER}/txn/{SUBLEDGER}/{SEQ_NO}` Fetch a specific transaction by subledger identifier (0-2, or one of `pool`, `domain`, or `config`) and sequence number. + +If the proxy server is used with a single ledger, the `{LEDGER}` part of the path must be omitted. + +### DID:Indy Resolver + +Indy VDR contains a DID Resolver to resolve DIDs and dereference DID Urls to ledger objects from configured ledgers according to the [did:indy specification](https://hyperledger.github.io/indy-did-method/). +`GET /1.0/identifiers/{DID or DID_URL}` ## Connecting to a Ledger Whether using the library or the proxy server, you will need a `genesis.txn` file containing the set of pool genesis transactions. You can run a local pool in Docker using [VON-Network](https://github.com/bcgov/von-network) or follow the [Indy-SDK instructions](https://github.com/hyperledger/indy-sdk#how-to-start-local-nodes-pool-with-docker). diff --git a/indy-vdr-proxy/Cargo.toml b/indy-vdr-proxy/Cargo.toml index ddecc084..dcac2fee 100644 --- a/indy-vdr-proxy/Cargo.toml +++ b/indy-vdr-proxy/Cargo.toml @@ -15,14 +15,17 @@ default = ["fetch", "zmq_vendored"] [dependencies] clap = "3.1" env_logger = "0.10" +futures-executor = "0.3" futures-util = "0.3" +indy-vdr = { path = "../libindy_vdr", default-features = false, features = ["log"] } +git2 = "0.14.2" hyper = { version = "0.14", features = ["http1", "http2", "server"] } hyper-tls = { version = "0.5", optional = true } log = "0.4.8" percent-encoding = "2" +regex = "1.5.4" serde_json = "1.0" tokio = { version = "1.0", features = ["macros", "rt-multi-thread", "signal"] } -indy-vdr = { path = "../libindy_vdr", default-features = false, features = ["log"] } url = "2.2.2" [target.'cfg(unix)'.dependencies] diff --git a/indy-vdr-proxy/src/app.rs b/indy-vdr-proxy/src/app.rs index 7b62f862..16143c8b 100644 --- a/indy-vdr-proxy/src/app.rs +++ b/indy-vdr-proxy/src/app.rs @@ -2,13 +2,15 @@ extern crate clap; use clap::{Arg, Command}; pub struct Config { - pub genesis: String, + pub genesis: Option, + pub namespace: String, #[cfg(unix)] pub socket: Option, pub host: Option, pub port: Option, pub init_refresh: bool, pub interval_refresh: u32, + pub is_multiple: bool, } pub fn load_config() -> Result { @@ -24,6 +26,18 @@ pub fn load_config() -> Result { .value_name("GENESIS") .help("Path to the ledger genesis transactions") ) + .arg( + Arg::new("name") + .short('n') + .long("name") + .takes_value(true) + .value_name("NAMESPACE") + .help("Namespace of ledger for DID resolution. Only needed if not multiple-ledgers") + ) + .arg( + Arg::new("multiple-ledgers") + .help("Support multiple ledgers") + ) .arg( Arg::new("host") .short('h') @@ -68,10 +82,11 @@ pub fn load_config() -> Result { let matches = app.get_matches(); - let genesis = matches - .value_of("genesis") - .unwrap_or("genesis.txn") - .to_owned(); + let genesis = matches.value_of("genesis").map(|v| v.to_owned()); + + let namespace = matches.value_of("name").unwrap_or("test").to_owned(); + + let is_multiple = matches.is_present("multiple-ledgers"); if matches.occurrences_of("socket") > 0 { if matches.occurrences_of("host") > 0 { @@ -101,11 +116,13 @@ pub fn load_config() -> Result { Ok(Config { genesis, + namespace, #[cfg(unix)] socket, host, port, init_refresh, interval_refresh, + is_multiple, }) } diff --git a/indy-vdr-proxy/src/handlers.rs b/indy-vdr-proxy/src/handlers.rs index 2420c78a..9ae6afb9 100644 --- a/indy-vdr-proxy/src/handlers.rs +++ b/indy-vdr-proxy/src/handlers.rs @@ -8,12 +8,15 @@ use std::time::UNIX_EPOCH; use hyper::{Body, Method, Request, Response, StatusCode}; use percent_encoding::percent_decode_str; +use regex::Regex; use super::AppState; use indy_vdr::common::error::prelude::*; use indy_vdr::ledger::identifiers::{CredentialDefinitionId, RevocationRegistryId, SchemaId}; use indy_vdr::pool::helpers::{perform_get_txn, perform_ledger_request}; use indy_vdr::pool::{LedgerType, Pool, PreparedRequest, RequestResult, TimingResult}; +use indy_vdr::resolver::did::DidUrl; +use indy_vdr::resolver::PoolResolver as Resolver; use indy_vdr::utils::did::DidValue; use indy_vdr::utils::Qualifiable; @@ -29,6 +32,7 @@ enum ResponseType { RequestReply(String, Option), RequestFailed(VdrError, Option), Status(StatusCode, String), + Resolver(String), } impl From<(RequestResult, Option)> for ResponseType @@ -219,6 +223,10 @@ fn format_result( format_text(msg, format, errcode, timing) } ResponseType::Status(code, msg) => format_text(msg, format, code, None), + ResponseType::Resolver(reply) => { + let reply = format_json_reply(reply, pretty); + format_text(reply, format, StatusCode::OK, None) + } }; Ok(response) } @@ -241,8 +249,12 @@ async fn get_pool_genesis(pool: &T) -> VdrResult { Ok(ResponseType::Genesis(txns.join("\n"))) } -fn get_pool_status(state: Rc>) -> VdrResult { - let opt_pool = &state.borrow().pool; +fn get_pool_status(state: Rc>, namespace: &str) -> VdrResult { + let pool_states = &state.borrow().pool_states; + let opt_pool = &pool_states + .get(namespace) + .ok_or(err_msg(VdrErrorKind::Input, "Unkown ledger"))? + .pool; let (status, mt_root, mt_size, nodes) = if let Some(pool) = opt_pool { let (mt_root, mt_size) = pool.get_merkle_tree_info(); let nodes = pool.get_node_aliases(); @@ -250,7 +262,12 @@ fn get_pool_status(state: Rc>) -> VdrResult { } else { ("init", None, None, None) }; - let last_refresh = &state.borrow().last_refresh; + let last_refresh = state + .borrow() + .pool_states + .get(namespace) + .unwrap() + .last_refresh; let last_refresh = last_refresh.map(|tm| tm.elapsed().map(|d| d.as_secs()).ok()); let result = json!({"status": status, "pool_mt_root": mt_root, "pool_mt_size": mt_size, "pool_nodes": nodes, "last_refresh": last_refresh}); @@ -434,121 +451,173 @@ pub async fn handle_request( ResponseFormat::Raw } }; + + let mut namespace = if state.borrow().is_multiple { + parts.next().unwrap_or_else(|| "".to_owned()) + } else { + let pool_states = &state.borrow().pool_states; + let (ns, _) = pool_states.into_iter().next().unwrap(); + ns.to_owned() + }; let fst = parts.next().unwrap_or_else(|| "".to_owned()); + let req_method = req.method(); if (req_method, fst.is_empty()) == (&Method::GET, true) { - return format_result(get_pool_status(state.clone()), format); + return format_result(get_pool_status(state.clone(), &namespace), format); } - let opt_pool = &state.borrow().pool; + + let resolver_regex = Regex::new("/1.0/identifiers/(.*)").unwrap(); + + let captures = resolver_regex.captures(req.uri().path()); + let did = if let Some(cap) = captures { + Some(cap.get(1).unwrap().as_str()) + } else { + None + }; + + if did.is_some() { + // FIXME: Handle error + namespace = DidUrl::from_str(did.unwrap()).unwrap().namespace; + } + + let pool_states = &state.borrow().pool_states; + // FIXME: Handle error + let pool_state = pool_states.get(&namespace).unwrap(); + + let opt_pool = pool_state.pool.clone(); let pool = match opt_pool { None => { return format_result(http_status(StatusCode::SERVICE_UNAVAILABLE), format); } Some(pool) => pool, }; - let result = match (req_method, fst.as_str()) { - // (&Method::GET, "status") => test_get_validator_info(pool, pretty).await.make_response(), - (&Method::GET, "submit") => http_status(StatusCode::METHOD_NOT_ALLOWED), - (&Method::POST, "submit") => { - let body_bytes = hyper::body::to_bytes(req.into_body()).await?; - let body = body_bytes.iter().cloned().collect::>(); - if !body.is_empty() { - submit_request(pool, body).await - } else { - http_status(StatusCode::BAD_REQUEST) + + let result = if did.is_some() { + let did = did.unwrap(); + let resolver = Resolver::new(pool); + // is DID Url + if did.find("/").is_some() { + match resolver.dereference(did).await { + Ok(result) => Ok(ResponseType::Resolver(result)), + Err(err) => http_status_msg(StatusCode::BAD_REQUEST, err.to_string()), } - } - (&Method::GET, "genesis") => get_pool_genesis(pool).await, - (&Method::GET, "taa") => get_taa(pool).await, - (&Method::GET, "aml") => get_aml(pool).await, - (&Method::GET, "attrib") => { - if let (Some(dest), Some(attrib)) = (parts.next(), parts.next()) { - // NOTE: 'endpoint' is currently the only supported attribute - get_attrib(pool, &*dest, &*attrib).await - } else { - http_status(StatusCode::NOT_FOUND) + } else { + match resolver.resolve(did).await { + Ok(result) => Ok(ResponseType::Resolver(result)), + Err(err) => http_status_msg(StatusCode::BAD_REQUEST, err.to_string()), } } - (&Method::GET, "auth") => { - if let Some(auth_type) = parts.next() { - if let Some(auth_action) = parts.next() { - get_auth_rule( - pool, - Some(auth_type.to_owned()), - Some(auth_action.to_owned()), - Some("*".to_owned()), - ) - .await + + // No DID resolution + } else { + if (req_method, fst.is_empty()) == (&Method::GET, true) { + return format_result(get_pool_status(state.clone(), &namespace), format); + } + match (req_method, fst.as_str()) { + // (&Method::GET, "status") => test_get_validator_info(pool, pretty).await.make_response(), + (&Method::GET, "submit") => http_status(StatusCode::METHOD_NOT_ALLOWED), + (&Method::POST, "submit") => { + let body_bytes = hyper::body::to_bytes(req.into_body()).await?; + let body = body_bytes.iter().cloned().collect::>(); + if !body.is_empty() { + submit_request(&pool, body).await + } else { + http_status(StatusCode::BAD_REQUEST) + } + } + (&Method::GET, "genesis") => get_pool_genesis(&pool).await, + (&Method::GET, "taa") => get_taa(&pool).await, + (&Method::GET, "aml") => get_aml(&pool).await, + (&Method::GET, "attrib") => { + if let (Some(dest), Some(attrib)) = (parts.next(), parts.next()) { + // NOTE: 'endpoint' is currently the only supported attribute + get_attrib(&pool, &*dest, &*attrib).await } else { http_status(StatusCode::NOT_FOUND) } - } else { - get_auth_rule(pool, None, None, None).await // get all } - } - (&Method::GET, "cred_def") => { - if let Some(cred_def_id) = parts.next() { - get_cred_def(pool, &*cred_def_id).await - } else { - http_status(StatusCode::NOT_FOUND) + (&Method::GET, "auth") => { + if let Some(auth_type) = parts.next() { + if let Some(auth_action) = parts.next() { + get_auth_rule( + &pool, + Some(auth_type.to_owned()), + Some(auth_action.to_owned()), + Some("*".to_owned()), + ) + .await + } else { + http_status(StatusCode::NOT_FOUND) + } + } else { + get_auth_rule(&pool, None, None, None).await // get all + } } - } - (&Method::GET, "nym") => { - if let Some(nym) = parts.next() { - let seq_no: Option = query_params - .get("seq_no") - .and_then(|seq_no| seq_no.as_str().parse().ok()); - let timestamp: Option = query_params - .get("timestamp") - .and_then(|ts| ts.as_str().parse().ok()); - get_nym(pool, &*nym, seq_no, timestamp).await - } else { - http_status(StatusCode::NOT_FOUND) + (&Method::GET, "cred_def") => { + if let Some(cred_def_id) = parts.next() { + get_cred_def(&pool, &*cred_def_id).await + } else { + http_status(StatusCode::NOT_FOUND) + } } - } - (&Method::GET, "rev_reg_def") => { - if let Some(rev_reg_def_id) = parts.next() { - get_revoc_reg_def(pool, &*rev_reg_def_id).await - } else { - http_status(StatusCode::NOT_FOUND) + (&Method::GET, "nym") => { + if let Some(nym) = parts.next() { + let seq_no: Option = query_params + .get("seq_no") + .and_then(|seq_no| seq_no.as_str().parse().ok()); + let timestamp: Option = query_params + .get("timestamp") + .and_then(|ts| ts.as_str().parse().ok()); + get_nym(&pool, &*nym, seq_no, timestamp).await + } else { + http_status(StatusCode::NOT_FOUND) + } } - } - (&Method::GET, "rev_reg") => { - if let Some(rev_reg_def_id) = parts.next() { - get_revoc_reg(pool, &*rev_reg_def_id).await - } else { - http_status(StatusCode::NOT_FOUND) + (&Method::GET, "rev_reg_def") => { + if let Some(rev_reg_def_id) = parts.next() { + get_revoc_reg_def(&pool, &*rev_reg_def_id).await + } else { + http_status(StatusCode::NOT_FOUND) + } } - } - (&Method::GET, "rev_reg_delta") => { - if let Some(rev_reg_def_id) = parts.next() { - get_revoc_reg_delta(pool, &*rev_reg_def_id).await - } else { - http_status(StatusCode::NOT_FOUND) + (&Method::GET, "rev_reg") => { + if let Some(rev_reg_def_id) = parts.next() { + get_revoc_reg(&pool, &*rev_reg_def_id).await + } else { + http_status(StatusCode::NOT_FOUND) + } } - } - (&Method::GET, "schema") => { - if let Some(schema_id) = parts.next() { - get_schema(pool, &*schema_id).await - } else { - http_status(StatusCode::NOT_FOUND) + (&Method::GET, "rev_reg_delta") => { + if let Some(rev_reg_def_id) = parts.next() { + get_revoc_reg_delta(&pool, &*rev_reg_def_id).await + } else { + http_status(StatusCode::NOT_FOUND) + } } - } - (&Method::GET, "txn") => { - if let (Some(ledger), Some(txn)) = (parts.next(), parts.next()) { - if let (Ok(ledger), Ok(txn)) = - (LedgerType::try_from(ledger.as_str()), txn.parse::()) - { - get_txn(pool, ledger, txn).await + (&Method::GET, "schema") => { + if let Some(schema_id) = parts.next() { + get_schema(&pool, &*schema_id).await + } else { + http_status(StatusCode::NOT_FOUND) + } + } + (&Method::GET, "txn") => { + if let (Some(ledger), Some(txn)) = (parts.next(), parts.next()) { + if let (Ok(ledger), Ok(txn)) = + (LedgerType::try_from(ledger.as_str()), txn.parse::()) + { + get_txn(&pool, ledger, txn).await + } else { + http_status(StatusCode::NOT_FOUND) + } } else { http_status(StatusCode::NOT_FOUND) } - } else { - http_status(StatusCode::NOT_FOUND) } + (&Method::GET, _) => http_status(StatusCode::NOT_FOUND), + _ => http_status(StatusCode::METHOD_NOT_ALLOWED), } - (&Method::GET, _) => http_status(StatusCode::NOT_FOUND), - _ => http_status(StatusCode::METHOD_NOT_ALLOWED), }; + format_result(result, format) } diff --git a/indy-vdr-proxy/src/main.rs b/indy-vdr-proxy/src/main.rs index 0365c7c8..c0a24826 100644 --- a/indy-vdr-proxy/src/main.rs +++ b/indy-vdr-proxy/src/main.rs @@ -3,16 +3,20 @@ extern crate serde_json; mod app; mod handlers; +mod utils; use std::cell::RefCell; +use std::collections::HashMap; #[cfg(unix)] use std::fs; use std::net::IpAddr; +use std::path::PathBuf; use std::process::exit; use std::rc::Rc; -use std::time::{Duration, SystemTime}; +use std::time::Duration; -use futures_util::FutureExt; +use futures_util::future::FutureExt; +use git2::Repository; #[cfg(feature = "fetch")] use hyper::body::Buf; @@ -33,6 +37,10 @@ use tokio::signal::unix::SignalKind; use indy_vdr::common::error::prelude::*; use indy_vdr::pool::{helpers::perform_refresh, LocalPool, PoolBuilder, PoolTransactions}; +use crate::utils::{ + init_pool_state_from_folder_structure, AppState, PoolState, INDY_NETWORKS_GITHUB, +}; + fn main() { let config = app::load_config().unwrap_or_else(|err| { eprintln!("{}", err); @@ -53,12 +61,6 @@ fn main() { } } -pub struct AppState { - pool: Option, - last_refresh: Option, - transactions: PoolTransactions, -} - #[cfg(feature = "fetch")] async fn fetch_transactions(genesis: String) -> VdrResult { let https = HttpsConnector::new(); @@ -95,50 +97,124 @@ async fn fetch_transactions(_genesis: String) -> VdrResult { )) } -async fn init_app_state(genesis: String) -> VdrResult { - let transactions = if genesis.starts_with("http:") || genesis.starts_with("https:") { - fetch_transactions(genesis).await? +async fn init_app_state( + genesis: Option, + namespace: String, + is_multiple: bool, +) -> VdrResult { + let mut pool_states: HashMap = HashMap::new(); + + let state = if !is_multiple { + let genesis = genesis.unwrap_or(String::from("genesis.txn")); + let transactions = if genesis.starts_with("http:") || genesis.starts_with("https:") { + fetch_transactions(genesis).await? + } else { + PoolTransactions::from_json_file(genesis.as_str())? + }; + let pool_state = PoolState { + pool: None, + last_refresh: None, + transactions, + }; + pool_states.insert(namespace, pool_state); + AppState { + is_multiple, + pool_states, + } } else { - PoolTransactions::from_json_file(genesis.as_str())? - }; - let state = AppState { - pool: None, - last_refresh: None, - transactions, + let genesis = genesis.unwrap_or(String::from(INDY_NETWORKS_GITHUB)); + let pool_states = if genesis.starts_with("https:") { + let repo_url = genesis; + let mut just_cloned = false; + let repo = + git2::Repository::discover("github").or_else(|_| -> VdrResult { + just_cloned = true; + Repository::clone(&repo_url, "github").map_err(|_err| { + err_msg(VdrErrorKind::Unexpected, "Could not clone networks repo") + }) + })?; + + // Fetch remote if not cloned just now + if !just_cloned { + let mut origin_remote = repo.find_remote("origin").map_err(|_err| { + err_msg( + VdrErrorKind::Unexpected, + "Networks repo has no remote origin", + ) + })?; + + origin_remote.fetch(&["main"], None, None).map_err(|_err| { + err_msg( + VdrErrorKind::Unexpected, + "Could not fetch from remote networks repo", + ) + })?; + } + + let path = repo.path().parent().unwrap().to_owned(); + + init_pool_state_from_folder_structure(PathBuf::from(path))? + } else { + init_pool_state_from_folder_structure(PathBuf::from(genesis))? + }; + AppState { + is_multiple, + pool_states, + } }; Ok(state) } -async fn run_pool(state: Rc>, init_refresh: bool, interval_refresh: u32) { - let mut pool = match create_pool(state.clone(), init_refresh).await { - Ok(pool) => { - state.borrow_mut().pool.replace(pool.clone()); - pool - } - Err(err) => { - eprintln!("Error initializing pool: {}", err); - return; - } - }; +async fn run_pools(state: Rc>, init_refresh: bool, interval_refresh: u32) { + let mut pool_states = HashMap::new(); + + for (namespace, pool_state) in &state.clone().borrow().pool_states { + let pool_state = match create_pool(state.clone(), namespace.as_str(), init_refresh).await { + Ok(pool) => { + let pool = Some(pool.clone()); + PoolState { + pool: pool.clone(), + last_refresh: pool_state.last_refresh.clone(), + transactions: pool_state.transactions.clone() + } + } + Err(err) => { + eprintln!("Error initializing pool: {}", err); + PoolState { + pool: None, + last_refresh: pool_state.last_refresh.clone(), + transactions: pool_state.transactions.clone() + } + } + }; + + pool_states.insert(namespace.to_owned(), pool_state); + + } + + state.borrow_mut().pool_states = pool_states; + + + let shutdown = shutdown_signal().fuse().shared(); if interval_refresh > 0 { loop { select! { - refresh_result = refresh_pool(state.clone(), &pool, interval_refresh) => { - match refresh_result { - Ok(Some(upd_pool)) => { - state.borrow_mut().pool.replace(upd_pool.clone()); - pool = upd_pool; - log::info!("Refreshed validator pool"); - } - Ok(None) => { - log::debug!("Refreshed validator pool, no change"); - } - Err(err) => { - log::error!("Error refreshing validator pool: {}", err); - } - } - } + // refresh_result = refresh_pool(state.clone(), namespace, &pool, interval_refresh) => { + // match refresh_result { + // Ok(Some(upd_pool)) => { + // state.borrow_mut().pool.replace(upd_pool.clone()); + // pool = upd_pool; + // log::info!("Refreshed validator pool"); + // } + // Ok(None) => { + // log::debug!("Refreshed validator pool, no change"); + // } + // Err(err) => { + // log::error!("Error refreshing validator pool: {}", err); + // } + // } + // } _ = shutdown.clone() => { println!("Shutting down"); break; @@ -171,11 +247,17 @@ async fn shutdown_signal() { .expect("failed to install Ctrl-C handler") } -async fn create_pool(state: Rc>, refresh: bool) -> VdrResult { - let builder = PoolBuilder::default().transactions(state.borrow().transactions.clone())?; +async fn create_pool( + state: Rc>, + namespace: &str, + refresh: bool, +) -> VdrResult { + let pool_states = &state.borrow().pool_states; + let pool_state = pool_states.get(namespace).unwrap(); + let builder = PoolBuilder::default().transactions(pool_state.transactions.clone())?; let pool = builder.into_local()?; let refresh_pool = if refresh { - refresh_pool(state, &pool, 0).await? + refresh_pool(state.clone(), namespace, &pool, 0).await? } else { None }; @@ -184,6 +266,7 @@ async fn create_pool(state: Rc>, refresh: bool) -> VdrResult>, + namespace: &str, pool: &LocalPool, delay_mins: u32, ) -> VdrResult> { @@ -193,11 +276,14 @@ async fn refresh_pool( let (txns, _timing) = perform_refresh(pool).await?; - state.borrow_mut().last_refresh.replace(SystemTime::now()); + let cloned_state = state.clone(); + let pool_states = &cloned_state.borrow().pool_states; + let pool_state = pool_states.get(namespace).unwrap(); + + let pool_txns = &mut pool_state.transactions.to_owned(); if let Some(txns) = txns { let builder = { - let pool_txns = &mut state.borrow_mut().transactions; pool_txns.extend_from_json(&txns)?; PoolBuilder::default().transactions(pool_txns.clone())? }; @@ -209,9 +295,13 @@ async fn refresh_pool( async fn init_server(config: app::Config) -> Result<(), String> { let state = Rc::new(RefCell::new( - init_app_state(config.genesis.clone()) - .await - .map_err(|err| format!("Error loading config: {}", err))?, + init_app_state( + config.genesis.clone(), + config.namespace.clone(), + config.is_multiple, + ) + .await + .map_err(|err| format!("Error loading config: {}", err))?, )); #[cfg(unix)] @@ -253,7 +343,7 @@ where I::Conn: tokio::io::AsyncRead + tokio::io::AsyncWrite + Send + Unpin, I::Error: Into>, { - let until_done = run_pool(state.clone(), config.init_refresh, config.interval_refresh); + let until_done = run_pools(state.clone(), config.init_refresh, config.interval_refresh); let svc = make_service_fn(move |_| { let state = state.clone(); async move { diff --git a/indy-vdr-proxy/src/utils.rs b/indy-vdr-proxy/src/utils.rs new file mode 100644 index 00000000..d0c1a5c6 --- /dev/null +++ b/indy-vdr-proxy/src/utils.rs @@ -0,0 +1,74 @@ +use std::collections::HashMap; +use std::fs; +use std::path::PathBuf; +use std::time::SystemTime; + +use indy_vdr::common::error::prelude::*; +use indy_vdr::pool::{LocalPool, PoolTransactions}; + +pub const INDY_NETWORKS_GITHUB: &str = "https://github.com/IDunion/indy-did-networks"; +pub const GENESIS_FILENAME: &str = "pool_transactions_genesis.json"; + +pub struct PoolState { + pub pool: Option, + pub last_refresh: Option, + pub transactions: PoolTransactions, +} + +pub struct AppState { + pub is_multiple: bool, + pub pool_states: HashMap, +} + +pub fn init_pool_state_from_folder_structure( + path: PathBuf, +) -> VdrResult> { + let mut networks = HashMap::new(); + + let entries = fs::read_dir(path).map_err(|err| { + err_msg( + VdrErrorKind::FileSystem(err), + "Could not read local networks folder", + ) + })?; + + for entry in entries { + let entry = entry.unwrap(); + // filter hidden directories starting with "." and files + if !entry.file_name().to_str().unwrap().starts_with(".") + && entry.metadata().unwrap().is_dir() + { + let namespace = entry.path().file_name().unwrap().to_owned(); + let sub_entries = fs::read_dir(entry.path()).unwrap(); + for sub_entry in sub_entries { + let sub_entry_path = sub_entry.unwrap().path(); + let sub_namespace = if sub_entry_path.is_dir() { + sub_entry_path.file_name() + } else { + None + }; + let (ledger_prefix, genesis_txns) = match sub_namespace { + Some(sub_namespace) => ( + format!( + "{}:{}", + namespace.to_str().unwrap(), + sub_namespace.to_str().unwrap() + ), + PoolTransactions::from_json_file(sub_entry_path.join(GENESIS_FILENAME))?, + ), + None => ( + String::from(namespace.to_str().unwrap()), + PoolTransactions::from_json_file(entry.path().join(GENESIS_FILENAME))?, + ), + }; + let pool_state = PoolState { + pool: None, + last_refresh: None, + transactions: genesis_txns, + }; + networks.insert(ledger_prefix, pool_state); + } + } + } + Ok(networks) +} diff --git a/libindy_vdr/tests/resolver.rs b/libindy_vdr/tests/resolver.rs new file mode 100644 index 00000000..17caf875 --- /dev/null +++ b/libindy_vdr/tests/resolver.rs @@ -0,0 +1,99 @@ +#[macro_use] +mod utils; + +inject_dependencies!(); + +#[test] +fn empty() { + // Empty test to run module +} + +#[cfg(test)] +// #[cfg(feature = "local_nodes_pool_did_indy")] +mod send_resolver { + use futures_executor::block_on; + use indy_vdr::resolver::PoolResolver as Resolver; + + use super::*; + + use crate::utils::crypto::Identity; + use crate::utils::fixtures::*; + use crate::utils::helpers; + use crate::utils::pool::TestPool; + + #[rstest] + fn test_pool_resolve_did( + pool: TestPool, + trustee: Identity, + identity: Identity, + diddoc_content: serde_json::Value, + ) { + // Send NYM + let mut nym_request = pool + .request_builder() + .build_nym_request( + &trustee.did, + &identity.did, + Some(identity.verkey.to_string()), + None, + None, + Some(&diddoc_content), + None, + ) + .unwrap(); + + let _nym_response = + helpers::sign_and_send_request(&trustee, &pool, &mut nym_request).unwrap(); + + // Resolve DID + let resolver = Resolver::new(pool.pool); + let qualified_did = format!("did:indy:test:{}", &identity.did); + let result = block_on(resolver.resolve(&qualified_did)).unwrap(); + + let v: serde_json::Value = serde_json::from_str(result.as_str()).unwrap(); + + let diddoc = &v["didDocument"]; + let metadata = &v["didDocumentMetadata"]; + + assert_eq!("NYM", metadata["objectType"]); + assert_ne!(&serde_json::Value::Null, diddoc) + } + + // #[rstest] + // fn test_pool_resolve_did_with_version_id( + // pool: TestPool, + // trustee: Identity, + // identity: Identity + // ) { + // // Send NYM + // let mut nym_request = pool + // .request_builder() + // .build_nym_request( + // &trustee.did, + // &identity.did, + // Some(identity.verkey.to_string()), + // None, + // None, + // None, + // None, + // ) + // .unwrap(); + + // let _nym_response = + // helpers::sign_and_send_request(&trustee, &pool, &mut nym_request).unwrap(); + + // // Resolve DID + // let resolver = Resolver::new(pool.pool); + // let qualified_did = format!("did:indy:test:{}", &identity.did); + // let did_url = format!("{}?versionId=1", qualified_did); + // let result = block_on(resolver.resolve(&did_url)).unwrap(); + + // let v: serde_json::Value = serde_json::from_str(result.as_str()).unwrap(); + + // let diddoc = &v["didDocument"]; + // let metadata = &v["didDocumentMetadata"]; + + // assert_eq!("NYM", metadata["objectType"]); + // assert_ne!(&serde_json::Value::Null, diddoc); + // } +} diff --git a/libindy_vdr/tests/utils/pool.rs b/libindy_vdr/tests/utils/pool.rs index cec39a88..e934cdf4 100644 --- a/libindy_vdr/tests/utils/pool.rs +++ b/libindy_vdr/tests/utils/pool.rs @@ -9,7 +9,7 @@ use indy_vdr::pool::{ use futures_executor::block_on; pub struct TestPool { - pool: SharedPool, + pub pool: SharedPool, } impl TestPool { From 340291d03a70bb3be993e1b22b0cc30e59322a8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20W=C3=B6rner?= Date: Tue, 15 Mar 2022 22:59:56 +0100 Subject: [PATCH 051/117] add selfCertificationVersion to didDocumentMetadata MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- libindy_vdr/src/resolver/resolver.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libindy_vdr/src/resolver/resolver.rs b/libindy_vdr/src/resolver/resolver.rs index 3239021b..a6bb6381 100644 --- a/libindy_vdr/src/resolver/resolver.rs +++ b/libindy_vdr/src/resolver/resolver.rs @@ -1,12 +1,12 @@ use super::did::DidUrl; -use super::types::*; -use super::utils::*; - use crate::common::error::prelude::*; use crate::ledger::RequestBuilder; use crate::pool::{Pool, PoolRunner, RequestResult, TimingResult}; +use super::types::*; +use super::utils::*; + /// DID (URL) Resolver interface for a pool compliant with did:indy method spec pub struct PoolResolver { pool: T, From 1c366df5da015aa949fae84cf46805d01836db04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20W=C3=B6rner?= Date: Wed, 23 Mar 2022 22:11:11 +0100 Subject: [PATCH 052/117] refresh MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- README.md | 4 +-- indy-vdr-proxy/src/handlers.rs | 47 ++++++++++++++++++------ indy-vdr-proxy/src/main.rs | 65 ++++++++++++++++++++++++---------- 3 files changed, 85 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index 70075bbe..87601701 100644 --- a/README.md +++ b/README.md @@ -55,8 +55,8 @@ The structure needs to be as follows `/OPTIONAL/pool_t Responses can be formatted in either HTML or JSON formats. HTML formatting is selected when the `text/html` content type is requested according to the Accept header (as sent by web browsers) or the request query string is set to `?html`. JSON formatting is selected otherwise, and may be explitly selected by using the query string `?raw`. For most ledger requests, JSON responses include information regarding which nodes were contacted is returned in the `X-Requests` header. Sending prepared requests to the ledger is performed by delivering a POST request to the `{LEDGER}/submit` endpoint, where the body of the request is the JSON-formatted payload. Additional endpoints are provided as shortcuts for ledger read transactions: - -- `{LEDGER}/` The root path shows basic status information about the server and the ledger pool +- `/` Return configured ledgers +- `{LEDGER}/` Basic status information about the server and the ledger pool - `{LEDGER}/genesis` Return the current set of genesis transactions - `{LEDGER}/taa` Fetch the current ledger Transaction Author Agreement - `{LEDGER}/aml` Fetch the current ledger Acceptance Methods List (for the TAA) diff --git a/indy-vdr-proxy/src/handlers.rs b/indy-vdr-proxy/src/handlers.rs index 9ae6afb9..009375ff 100644 --- a/indy-vdr-proxy/src/handlers.rs +++ b/indy-vdr-proxy/src/handlers.rs @@ -249,11 +249,23 @@ async fn get_pool_genesis(pool: &T) -> VdrResult { Ok(ResponseType::Genesis(txns.join("\n"))) } +fn get_ledgers(state: Rc>) -> VdrResult { + Ok(ResponseType::Json( + state + .borrow() + .pool_states + .keys() + .cloned() + .collect::>() + .join("\n"), + )) +} + fn get_pool_status(state: Rc>, namespace: &str) -> VdrResult { let pool_states = &state.borrow().pool_states; let opt_pool = &pool_states .get(namespace) - .ok_or(err_msg(VdrErrorKind::Input, "Unkown ledger"))? + .ok_or(err_msg(VdrErrorKind::Input, format!("Unkown ledger: {}", namespace)))? .pool; let (status, mt_root, mt_size, nodes) = if let Some(pool) = opt_pool { let (mt_root, mt_size) = pool.get_merkle_tree_info(); @@ -462,9 +474,6 @@ pub async fn handle_request( let fst = parts.next().unwrap_or_else(|| "".to_owned()); let req_method = req.method(); - if (req_method, fst.is_empty()) == (&Method::GET, true) { - return format_result(get_pool_status(state.clone(), &namespace), format); - } let resolver_regex = Regex::new("/1.0/identifiers/(.*)").unwrap(); @@ -476,13 +485,32 @@ pub async fn handle_request( }; if did.is_some() { - // FIXME: Handle error - namespace = DidUrl::from_str(did.unwrap()).unwrap().namespace; + namespace = match DidUrl::from_str(did.unwrap()) { + Ok(did_url) => did_url.namespace, + Err(_) => { + return format_result(http_status(StatusCode::BAD_REQUEST), format); + } + }; + } else { + if (req_method, fst.is_empty()) == (&Method::GET, true) { + if namespace == "" { + return format_result(get_ledgers(state.clone()), format); + } else { + return format_result(get_pool_status(state.clone(), &namespace), format); + } + } } let pool_states = &state.borrow().pool_states; - // FIXME: Handle error - let pool_state = pool_states.get(&namespace).unwrap(); + let pool_state = match pool_states.get(&namespace) { + Some(ps) => ps, + None => { + return format_result( + http_status_msg(StatusCode::BAD_REQUEST, "Unknown ledger"), + format, + ); + } + }; let opt_pool = pool_state.pool.clone(); let pool = match opt_pool { @@ -510,9 +538,6 @@ pub async fn handle_request( // No DID resolution } else { - if (req_method, fst.is_empty()) == (&Method::GET, true) { - return format_result(get_pool_status(state.clone(), &namespace), format); - } match (req_method, fst.as_str()) { // (&Method::GET, "status") => test_get_validator_info(pool, pretty).await.make_response(), (&Method::GET, "submit") => http_status(StatusCode::METHOD_NOT_ALLOWED), diff --git a/indy-vdr-proxy/src/main.rs b/indy-vdr-proxy/src/main.rs index c0a24826..5c2abf9d 100644 --- a/indy-vdr-proxy/src/main.rs +++ b/indy-vdr-proxy/src/main.rs @@ -13,7 +13,7 @@ use std::net::IpAddr; use std::path::PathBuf; use std::process::exit; use std::rc::Rc; -use std::time::Duration; +use std::time::{Duration, SystemTime}; use futures_util::future::FutureExt; use git2::Repository; @@ -179,7 +179,7 @@ async fn run_pools(state: Rc>, init_refresh: bool, interval_re } } Err(err) => { - eprintln!("Error initializing pool: {}", err); + eprintln!("Error initializing pool {} with error : {}", namespace, err); PoolState { pool: None, last_refresh: pool_state.last_refresh.clone(), @@ -200,21 +200,17 @@ async fn run_pools(state: Rc>, init_refresh: bool, interval_re if interval_refresh > 0 { loop { select! { - // refresh_result = refresh_pool(state.clone(), namespace, &pool, interval_refresh) => { - // match refresh_result { - // Ok(Some(upd_pool)) => { - // state.borrow_mut().pool.replace(upd_pool.clone()); - // pool = upd_pool; - // log::info!("Refreshed validator pool"); - // } - // Ok(None) => { - // log::debug!("Refreshed validator pool, no change"); - // } - // Err(err) => { - // log::error!("Error refreshing validator pool: {}", err); - // } - // } - // } + refresh_result = refresh_pools(state.clone(), interval_refresh) => { + match refresh_result { + Ok(upd_pool_states) => { + state.borrow_mut().pool_states = upd_pool_states; + log::info!("Refreshed validator pools"); + }, + Err(err) => { + log::error!("Error refreshing validator pool: {}", err); + } + } + } _ = shutdown.clone() => { println!("Shutting down"); break; @@ -264,14 +260,47 @@ async fn create_pool( Ok(refresh_pool.unwrap_or(pool)) } +async fn refresh_pools( + state: Rc>, + // pool_states: HashMap, + delay_mins: u32, +) -> VdrResult> { + let mut upd_pool_states = HashMap::new(); + let pool_states = &state.borrow().pool_states; + for (namespace, pool_state) in pool_states { + if let Some(pool) = &pool_state.pool { + let upd_pool = match refresh_pool(state.clone(), &namespace, &pool, delay_mins).await { + Ok(p) => p, + Err(err) => { + eprintln!( + "Error refreshing validator pool {} with error {}", + namespace, err + ); + None + } + }; + let upd_pool_state = PoolState { + pool: upd_pool.or(Some(pool.clone())), + last_refresh: Some(SystemTime::now()), + transactions: pool_state.transactions.clone(), + }; + + upd_pool_states.insert(namespace.to_owned(), upd_pool_state); + } + } + + Ok(upd_pool_states) +} + async fn refresh_pool( state: Rc>, namespace: &str, pool: &LocalPool, delay_mins: u32, ) -> VdrResult> { + let n_pools = state.borrow().pool_states.len() as u32; if delay_mins > 0 { - tokio::time::sleep(Duration::from_secs((delay_mins * 60) as u64)).await + tokio::time::sleep(Duration::from_secs((delay_mins * 60 / n_pools) as u64)).await } let (txns, _timing) = perform_refresh(pool).await?; From 66467489c14869ae8918a1cb700c7be35bf4cabd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20W=C3=B6rner?= Date: Wed, 23 Mar 2022 22:11:35 +0100 Subject: [PATCH 053/117] fmt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- indy-vdr-proxy/src/handlers.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/indy-vdr-proxy/src/handlers.rs b/indy-vdr-proxy/src/handlers.rs index 009375ff..80335f49 100644 --- a/indy-vdr-proxy/src/handlers.rs +++ b/indy-vdr-proxy/src/handlers.rs @@ -265,7 +265,10 @@ fn get_pool_status(state: Rc>, namespace: &str) -> VdrResult Date: Thu, 24 Mar 2022 07:14:40 +0100 Subject: [PATCH 054/117] add get nym query parameters in readme MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 87601701..8430d104 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ Sending prepared requests to the ledger is performed by delivering a POST reques - `{LEDGER}/genesis` Return the current set of genesis transactions - `{LEDGER}/taa` Fetch the current ledger Transaction Author Agreement - `{LEDGER}/aml` Fetch the current ledger Acceptance Methods List (for the TAA) -- `{LEDGER}/nym/{DID}` Fetch the NYM transaction associated with an unqualified DID +- `{LEDGER}/nym/{DID}` Fetch the NYM transaction associated with an unqualified DID. Can be used with `timestamp` or `seq_no` query parameters to fetch specific versions - `{LEDGER}/attrib/{DID}/endpoint` Fetch the registered endpoint for an unqualified DID - `{LEDGER}/schema/{SCHEMA_ID}` Fetch a schema by its identifier - `{LEDGER}/cred_def/{CRED_DEF_ID}` Fetch a credential definition by its identifier From 994799089cece79e8814c5bbc08a08f38c88fd7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20W=C3=B6rner?= Date: Thu, 24 Mar 2022 14:42:35 +0100 Subject: [PATCH 055/117] Python wrapper with multi-ledger resolver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- wrappers/python/.gitignore | 1 + wrappers/python/demo/batch_get_txn.py | 8 +- wrappers/python/demo/test.py | 22 ++++-- wrappers/python/indy_vdr/__init__.py | 2 +- wrappers/python/indy_vdr/bindings.py | 1 - wrappers/python/indy_vdr/error.py | 1 - wrappers/python/indy_vdr/pool.py | 28 +++++++ wrappers/python/indy_vdr/resolver.py | 94 ++++++++++++++++++++--- wrappers/python/indy_vdr/utils.py | 103 ++++++++++++++++++++++++++ wrappers/python/setup.py | 2 + 10 files changed, 237 insertions(+), 25 deletions(-) create mode 100644 wrappers/python/indy_vdr/utils.py diff --git a/wrappers/python/.gitignore b/wrappers/python/.gitignore index 88cbc7ae..4c34defb 100644 --- a/wrappers/python/.gitignore +++ b/wrappers/python/.gitignore @@ -1,6 +1,7 @@ build dist github +networks .pytest_cache __pycache__ *.dll diff --git a/wrappers/python/demo/batch_get_txn.py b/wrappers/python/demo/batch_get_txn.py index 65d48091..d6fd3b6e 100644 --- a/wrappers/python/demo/batch_get_txn.py +++ b/wrappers/python/demo/batch_get_txn.py @@ -4,15 +4,11 @@ import os import sys import time - +import urllib.request from asyncio import Event, Task from typing import List, NamedTuple -import urllib.request -from indy_vdr.ledger import ( - build_get_txn_request, - LedgerType, -) +from indy_vdr.ledger import LedgerType, build_get_txn_request from indy_vdr.pool import Pool, open_pool MAX_PENDING = 25 diff --git a/wrappers/python/demo/test.py b/wrappers/python/demo/test.py index 1b355e24..a36ee840 100644 --- a/wrappers/python/demo/test.py +++ b/wrappers/python/demo/test.py @@ -1,20 +1,19 @@ import asyncio import json -import sys import os +import sys import urllib.request +from indy_vdr.error import VdrError from indy_vdr.bindings import version from indy_vdr.ledger import ( + LedgerType, build_custom_request, - build_get_txn_request, build_get_acceptance_mechanisms_request, - build_get_txn_author_agreement_request, - build_get_validator_info_request, build_get_cred_def_request, build_get_revoc_reg_def_request, - build_get_revoc_reg_request, build_get_revoc_reg_delta_request, + build_get_revoc_reg_request, build_get_schema_request, build_node_request, build_pool_config_request, @@ -29,8 +28,10 @@ # build_rich_schema_request, # build_get_schema_object_by_id_request, # build_get_schema_object_by_metadata_request, + build_get_txn_author_agreement_request, + build_get_txn_request, + build_get_validator_info_request, prepare_txn_author_agreement_acceptance, - LedgerType, ) from indy_vdr.pool import Pool, open_pool from indy_vdr.resolver import Resolver @@ -196,9 +197,18 @@ async def basic_test(transactions_path): log("Resolve DID did:indy:sovrin:XvSeT51zDWVTXatLWPknWb") resolver = Resolver(pool.handle) doc = await resolver.resolve("did:indy:sovrin:XvSeT51zDWVTXatLWPknWb") + # pool_map = await open_pools(ledgers=["idunion", "sovrin:builder"]) + log("Resolve DID did:indy:idunion:ELMkCtYoz86qnJKeQqrL1M") + resolver = Resolver(autopilot=True) + doc = await resolver.resolve("did:indy:idunion:ELMkCtYoz86qnJKeQqrL1M") log(json.dumps(doc, indent=2)) + try: + doc = await resolver.resolve("did:indy:test:ELMkCtYoz86qnJKeQqrL1M") + except VdrError as err: + print(err) + # req = build_rich_schema_request( # None, "did:sov:some_hash", '{"some": 1}', "test", "version", "sch", "1.0.0" # ) diff --git a/wrappers/python/indy_vdr/__init__.py b/wrappers/python/indy_vdr/__init__.py index ddc1cdc3..f05dcdc1 100644 --- a/wrappers/python/indy_vdr/__init__.py +++ b/wrappers/python/indy_vdr/__init__.py @@ -3,7 +3,7 @@ from .bindings import set_config, set_protocol_version, version from .error import VdrError, VdrErrorCode from .ledger import LedgerType -from .pool import open_pool, Pool +from .pool import Pool, open_pool from .request import Request __all__ = [ diff --git a/wrappers/python/indy_vdr/bindings.py b/wrappers/python/indy_vdr/bindings.py index 69464c9c..35dddf95 100644 --- a/wrappers/python/indy_vdr/bindings.py +++ b/wrappers/python/indy_vdr/bindings.py @@ -22,7 +22,6 @@ from .error import VdrError, VdrErrorCode - CALLBACKS = {} LIB: CDLL = None LOGGER = logging.getLogger(__name__) diff --git a/wrappers/python/indy_vdr/error.py b/wrappers/python/indy_vdr/error.py index 1756a793..21326d45 100644 --- a/wrappers/python/indy_vdr/error.py +++ b/wrappers/python/indy_vdr/error.py @@ -17,7 +17,6 @@ class VdrErrorCode(IntEnum): POOL_TIMEOUT = 32 WRAPPER = 99 RESOLVER = 9 - class VdrError(Exception): diff --git a/wrappers/python/indy_vdr/pool.py b/wrappers/python/indy_vdr/pool.py index f4337626..0f1dc8e3 100644 --- a/wrappers/python/indy_vdr/pool.py +++ b/wrappers/python/indy_vdr/pool.py @@ -7,6 +7,7 @@ from . import bindings from .error import VdrError, VdrErrorCode from .ledger import Request, build_custom_request +from .utils import get_genesis_txns_from_did_indy_repo_by_name class Pool: @@ -176,3 +177,30 @@ async def open_pool( if not no_refresh: await pool.refresh() return pool + + +async def open_pools( + genesis_map: dict = None, + ledgers: list = None, + no_refresh: bool = False, + socks_proxy: str = None, +) -> dict: + + pool_map = dict() + + if not (bool(genesis_map) ^ bool(ledgers)): + raise VdrError( + VdrErrorCode.WRAPPER, + "Must provide one of genesis_map or ledgers", + ) + + if not genesis_map: + genesis_map = get_genesis_txns_from_did_indy_repo_by_name(ledgers) + + print(genesis_map) + for namespace, genesis_txn_path in genesis_map.items(): + + pool = await open_pool(genesis_txn_path, None, None, no_refresh, socks_proxy) + pool_map[namespace] = pool + + return pool_map diff --git a/wrappers/python/indy_vdr/resolver.py b/wrappers/python/indy_vdr/resolver.py index 5dd8497e..9686994d 100644 --- a/wrappers/python/indy_vdr/resolver.py +++ b/wrappers/python/indy_vdr/resolver.py @@ -1,19 +1,93 @@ +import json +import re +from typing import Dict + from . import bindings +from .error import VdrError, VdrErrorCode +from .pool import Pool, open_pool +from .utils import get_genesis_txns_from_did_indy_repo_by_name + +DID_INDY_PREFIX = "did:indy" +NAMESPACE_PATTERN = "((?:[a-z0-9_-]+:?){1,2})" + +DID_PATTERN = re.compile(f"^{DID_INDY_PREFIX}:{NAMESPACE_PATTERN}:(.*)") class Resolver: - """did:indy compliant resolver interface for a specific network.""" + """did:indy compliant resolver interface + + Args: + pool_map: Dict mapping ledger namespaces to pool instances + autopilot: (default = False) If enabled resolver will try to + fetch genesis txn from indy networks github when no pool instance + is configured for the DID namespace + """ + + def __init__(self, pool_map: Dict[str, Pool] = {}, autopilot=False): + """Initialize the resolver instance from a pool map.""" + self.pool_map = pool_map + self.autopilot = autopilot - def __init__(self, pool_handle: bindings.PoolHandle): - """Initialize the pool instance.""" - self.handle = pool_handle + def add_ledger(self, namespace: str, pool: Pool): + """Add a ledger to the resolver""" + self.pool_map[namespace] = pool - async def resolve(self, did: str) -> dict: + def remove_ledger(self, namespace: str): + """Remove a ledger from the resolver""" + try: + del self.pool_map[namespace] + except KeyError: + raise VdrError(VdrErrorCode.WRAPPER, f"Ledger {namespace} not configured") + + async def resolve(self, did: str) -> Dict: """Resolve a DID to retrieve a DID Doc.""" - result = await bindings.resolve(self.handle, did) - return result + namespace = get_namespace(did) + pool = self.pool_map.get(namespace) + if not pool: + if self.autopilot: + try: + pool_map = get_genesis_txns_from_did_indy_repo_by_name([namespace]) + pool = await open_pool(pool_map[namespace]) + self.add_ledger(namespace, pool) + except KeyError: + raise VdrError( + VdrErrorCode.WRAPPER, f"Unknown DID namespace: {namespace}" + ) + + else: + raise VdrError( + VdrErrorCode.WRAPPER, f"Unknown DID namespace: {namespace}" + ) + pool_handle = getattr(pool, "handle") + result = await bindings.resolve(pool_handle, did) + return json.loads(result) - async def dereference(self, did_url: str) -> dict: + async def dereference(self, did_url: str) -> Dict: """Dereference a DID Url to retrieve a ledger object.""" - result = await bindings.dereference(self.handle, did_url) - return result + namespace = get_namespace(did_url) + pool = self.pool_map.get(namespace) + if not pool: + if self.autopilot: + try: + pool_map = get_genesis_txns_from_did_indy_repo_by_name([namespace]) + pool = await open_pool(pool_map[namespace]) + self.add_ledger(namespace, pool) + except KeyError: + raise VdrError( + VdrErrorCode.WRAPPER, f"Unknown DID namespace: {namespace}" + ) + + else: + raise VdrError( + VdrErrorCode.WRAPPER, f"Unknown DID namespace: {namespace}" + ) + pool_handle = getattr(pool, "handle") + result = await bindings.dereference(pool_handle, did_url) + return json.loads(result) + + +def get_namespace(did: str) -> str: + matched = DID_PATTERN.match(did) + if not matched: + raise VdrError(VdrErrorCode.WRAPPER, f"Invalid DID: {did}") + return matched.group(1) diff --git a/wrappers/python/indy_vdr/utils.py b/wrappers/python/indy_vdr/utils.py new file mode 100644 index 00000000..bfad94b4 --- /dev/null +++ b/wrappers/python/indy_vdr/utils.py @@ -0,0 +1,103 @@ +import os +from typing import Dict, List +import urllib.request + +from .error import VdrError, VdrErrorCode + + +INDY_NETWORKS_GITHUB_RAW_BASE = ( + "https://raw.githubusercontent.com/IDunion/indy-did-networks/main" +) +GENESIS_FILENAME = "pool_transactions_genesis.json" + + +def get_genesis_txns_from_did_indy_folder( + path: str, genesis_filename: str = None +) -> Dict[str, str]: + """Retrieves mapping from local folder + + Expects a path to a folder with the following structure: + // + Default for genesis_filename is pool_transactions_genesis.json + Example: sovrin/staging/pool_transactions_genesis.json + """ + genesis_map = dict() + + genesis_filename = genesis_filename if genesis_filename else GENESIS_FILENAME + + entries = os.listdir(path) + filtered_entries = list( + filter( + lambda entry: not entry.startswith(".") + and not os.path.isfile(os.path.join(path, entry)), + entries, + ) + ) + + for entry in filtered_entries: + + entry_p = os.path.join(path, entry) + + namespace = entry + + sub_entries = os.listdir(os.path.join(path, entry)) + + for sub_entry in sub_entries: + sub_entry_p = os.path.join(entry_p, sub_entry) + sub_namespace = sub_entry if os.path.isdir(sub_entry_p) else None + + if sub_namespace: + _namespace = namespace + ":" + sub_namespace + file_p = os.path.join(sub_entry_p, GENESIS_FILENAME) + if os.path.isfile(file_p): + genesis_map[_namespace] = file_p + + else: + file_p = os.path.join(entry_p, GENESIS_FILENAME) + if os.path.isfile(file_p): + genesis_map[namespace] = file_p + + return genesis_map + + +def get_genesis_txns_from_did_indy_repo_by_name( + namespaces: List[str], genesis_filename: str = None +) -> Dict[str, str]: + """Retrieves genesis txn from standard indy networks repo given their names""" + genesis_map = dict() + + genesis_filename = genesis_filename if genesis_filename else GENESIS_FILENAME + + base_dir = "networks" + + for name in namespaces: + namespace = name + name = name.replace(":", "/") + parts = iter(name.split("/")) + main = next(parts, None) + sub = next(parts, None) + + genesis_file_url = f"{INDY_NETWORKS_GITHUB_RAW_BASE}/{name}/{genesis_filename}" + target_local_path = f"{base_dir}/{name}/{genesis_filename}" + try: + urllib.request.urlretrieve(genesis_file_url, target_local_path) + + except FileNotFoundError: + # Create directories and try again + if not os.path.isdir(f"{base_dir}"): + os.mkdir(f"{base_dir}") + if not os.path.isdir(f"{base_dir}/{main}"): + os.mkdir(f"{base_dir}/{main}") + if sub and not os.path.isdir(f"{base_dir}/{main}/{sub}"): + os.mkdir(f"{base_dir}/{main}/{sub}") + + urllib.request.urlretrieve(genesis_file_url, target_local_path) + + except urllib.error.HTTPError: + target_local_path = None + print(f"Could not fetch genesis file for {namespace}") + + if target_local_path: + genesis_map[namespace] = target_local_path + + return genesis_map diff --git a/wrappers/python/setup.py b/wrappers/python/setup.py index 7e2df3b3..361585b2 100644 --- a/wrappers/python/setup.py +++ b/wrappers/python/setup.py @@ -1,6 +1,7 @@ """Module setup.""" import runpy + from setuptools import find_packages, setup PACKAGE_NAME = "indy_vdr" @@ -23,6 +24,7 @@ "libindy_vdr.so", ] }, + extras_require={"fetch_indy_networks": ["git"]}, python_requires=">=3.6.3", classifiers=[ "Programming Language :: Python :: 3", From c45d4e89cf802ba86ca9af8ae50b5272853fa30e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20W=C3=B6rner?= Date: Thu, 24 Mar 2022 15:10:39 +0100 Subject: [PATCH 056/117] small cleanups MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- .gitignore | 2 ++ wrappers/python/demo/test.py | 17 ++++++++++++++++- wrappers/python/indy_vdr/pool.py | 3 ++- wrappers/python/indy_vdr/utils.py | 3 +-- wrappers/python/setup.py | 1 - 5 files changed, 21 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 02518e0f..f36a8a7b 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,5 @@ coverage *.tgz *.so .npmrc +github +**/networks diff --git a/wrappers/python/demo/test.py b/wrappers/python/demo/test.py index a36ee840..e64a850c 100644 --- a/wrappers/python/demo/test.py +++ b/wrappers/python/demo/test.py @@ -197,10 +197,25 @@ async def basic_test(transactions_path): log("Resolve DID did:indy:sovrin:XvSeT51zDWVTXatLWPknWb") resolver = Resolver(pool.handle) doc = await resolver.resolve("did:indy:sovrin:XvSeT51zDWVTXatLWPknWb") + + ################################################################################### + ### ### + ### DID Resolution ### + ### ### + ################################################################################### + + ## DID resolver can be initialized with a dict containing namespaces and pool instances + # pool_map = await open_pools(ledgers=["idunion", "sovrin:builder"]) + # resolver = Resolver(pool_map) + + ## In addtion the the DID resolver can be started with autopilot = True. + ## Then it will try to fetch a genesis file from the did indy networks Github repo + ## for the given did:indy namespace - log("Resolve DID did:indy:idunion:ELMkCtYoz86qnJKeQqrL1M") resolver = Resolver(autopilot=True) + + log("Resolve DID did:indy:idunion:ELMkCtYoz86qnJKeQqrL1M") doc = await resolver.resolve("did:indy:idunion:ELMkCtYoz86qnJKeQqrL1M") log(json.dumps(doc, indent=2)) diff --git a/wrappers/python/indy_vdr/pool.py b/wrappers/python/indy_vdr/pool.py index 0f1dc8e3..bc1a2032 100644 --- a/wrappers/python/indy_vdr/pool.py +++ b/wrappers/python/indy_vdr/pool.py @@ -156,7 +156,8 @@ async def open_pool( node a higher probability of being selected. A weight of zero means the node will never be selected. no_refresh: Disable the initial verifier pool refresh - socks_proxy: The socks proxy host name and port for ZMQ (example: proxy1.intranet.company.com:1080) + socks_proxy: The socks proxy host name and port for ZMQ + (example: proxy1.intranet.company.com:1080) Returns: A new `Pool` instance which may be used to submit ledger requests diff --git a/wrappers/python/indy_vdr/utils.py b/wrappers/python/indy_vdr/utils.py index bfad94b4..a8de8a05 100644 --- a/wrappers/python/indy_vdr/utils.py +++ b/wrappers/python/indy_vdr/utils.py @@ -2,8 +2,6 @@ from typing import Dict, List import urllib.request -from .error import VdrError, VdrErrorCode - INDY_NETWORKS_GITHUB_RAW_BASE = ( "https://raw.githubusercontent.com/IDunion/indy-did-networks/main" @@ -20,6 +18,7 @@ def get_genesis_txns_from_did_indy_folder( // Default for genesis_filename is pool_transactions_genesis.json Example: sovrin/staging/pool_transactions_genesis.json + """ genesis_map = dict() diff --git a/wrappers/python/setup.py b/wrappers/python/setup.py index 361585b2..35340277 100644 --- a/wrappers/python/setup.py +++ b/wrappers/python/setup.py @@ -24,7 +24,6 @@ "libindy_vdr.so", ] }, - extras_require={"fetch_indy_networks": ["git"]}, python_requires=">=3.6.3", classifiers=[ "Programming Language :: Python :: 3", From d508777cfb72e0fac02ce4eb708cc2c81450849b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20W=C3=B6rner?= Date: Thu, 24 Mar 2022 15:41:51 +0100 Subject: [PATCH 057/117] add a few more comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- wrappers/python/indy_vdr/pool.py | 20 ++++++++++++++++++-- wrappers/python/indy_vdr/resolver.py | 6 +++--- wrappers/python/indy_vdr/utils.py | 4 ++-- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/wrappers/python/indy_vdr/pool.py b/wrappers/python/indy_vdr/pool.py index bc1a2032..70728324 100644 --- a/wrappers/python/indy_vdr/pool.py +++ b/wrappers/python/indy_vdr/pool.py @@ -2,7 +2,7 @@ import json from datetime import datetime -from typing import Mapping, Sequence, Union +from typing import Dict, Mapping, Sequence, Union from . import bindings from .error import VdrError, VdrErrorCode @@ -185,7 +185,23 @@ async def open_pools( ledgers: list = None, no_refresh: bool = False, socks_proxy: str = None, -) -> dict: +) -> Dict[str, Pool]: + """Create a map of new ledger pool instances. + + Either `genesis_map` or `ledgers` must be specified, but not both. + + Args: + genesis_map: A dict mapping namespaces to ledger genesis files + ledgers: A list of ledger namespaces. Genesis files will be fetched from + did indy networks Github repo + no_refresh: Disable the initial verifier pool refresh + socks_proxy: The socks proxy host name and port for ZMQ + (example: proxy1.intranet.company.com:1080) + + Returns: + A dict of namespace to `Pool` instance mappings which may be used to + initialize a DID resolver. + """ pool_map = dict() diff --git a/wrappers/python/indy_vdr/resolver.py b/wrappers/python/indy_vdr/resolver.py index 9686994d..a14c5afc 100644 --- a/wrappers/python/indy_vdr/resolver.py +++ b/wrappers/python/indy_vdr/resolver.py @@ -14,7 +14,7 @@ class Resolver: - """did:indy compliant resolver interface + """did:indy compliant resolver interface. Args: pool_map: Dict mapping ledger namespaces to pool instances @@ -29,11 +29,11 @@ def __init__(self, pool_map: Dict[str, Pool] = {}, autopilot=False): self.autopilot = autopilot def add_ledger(self, namespace: str, pool: Pool): - """Add a ledger to the resolver""" + """Add a ledger to the resolver.""" self.pool_map[namespace] = pool def remove_ledger(self, namespace: str): - """Remove a ledger from the resolver""" + """Remove a ledger from the resolver.""" try: del self.pool_map[namespace] except KeyError: diff --git a/wrappers/python/indy_vdr/utils.py b/wrappers/python/indy_vdr/utils.py index a8de8a05..b4772487 100644 --- a/wrappers/python/indy_vdr/utils.py +++ b/wrappers/python/indy_vdr/utils.py @@ -12,7 +12,7 @@ def get_genesis_txns_from_did_indy_folder( path: str, genesis_filename: str = None ) -> Dict[str, str]: - """Retrieves mapping from local folder + """Retrieves mapping from local folder. Expects a path to a folder with the following structure: // @@ -62,7 +62,7 @@ def get_genesis_txns_from_did_indy_folder( def get_genesis_txns_from_did_indy_repo_by_name( namespaces: List[str], genesis_filename: str = None ) -> Dict[str, str]: - """Retrieves genesis txn from standard indy networks repo given their names""" + """Retrieves genesis txn from standard indy networks repo given their names.""" genesis_map = dict() genesis_filename = genesis_filename if genesis_filename else GENESIS_FILENAME From ccf115fe106d3bfabf569525470ee24bb6279d63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20W=C3=B6rner?= Date: Thu, 24 Mar 2022 19:47:23 +0100 Subject: [PATCH 058/117] remove print statement MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- wrappers/python/indy_vdr/pool.py | 1 - wrappers/python/indy_vdr/utils.py | 5 +---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/wrappers/python/indy_vdr/pool.py b/wrappers/python/indy_vdr/pool.py index 70728324..73af0fb2 100644 --- a/wrappers/python/indy_vdr/pool.py +++ b/wrappers/python/indy_vdr/pool.py @@ -214,7 +214,6 @@ async def open_pools( if not genesis_map: genesis_map = get_genesis_txns_from_did_indy_repo_by_name(ledgers) - print(genesis_map) for namespace, genesis_txn_path in genesis_map.items(): pool = await open_pool(genesis_txn_path, None, None, no_refresh, socks_proxy) diff --git a/wrappers/python/indy_vdr/utils.py b/wrappers/python/indy_vdr/utils.py index b4772487..b900dd3b 100644 --- a/wrappers/python/indy_vdr/utils.py +++ b/wrappers/python/indy_vdr/utils.py @@ -34,14 +34,13 @@ def get_genesis_txns_from_did_indy_folder( ) for entry in filtered_entries: - entry_p = os.path.join(path, entry) - namespace = entry sub_entries = os.listdir(os.path.join(path, entry)) for sub_entry in sub_entries: + sub_entry_p = os.path.join(entry_p, sub_entry) sub_namespace = sub_entry if os.path.isdir(sub_entry_p) else None @@ -50,12 +49,10 @@ def get_genesis_txns_from_did_indy_folder( file_p = os.path.join(sub_entry_p, GENESIS_FILENAME) if os.path.isfile(file_p): genesis_map[_namespace] = file_p - else: file_p = os.path.join(entry_p, GENESIS_FILENAME) if os.path.isfile(file_p): genesis_map[namespace] = file_p - return genesis_map From 096444cf2d5c82efe38501c052bd886a623fd084 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20W=C3=B6rner?= Date: Fri, 25 Mar 2022 11:58:08 +0100 Subject: [PATCH 059/117] handle legacy endpoints on wrapper layer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- libindy_vdr/src/ffi/resolver.rs | 49 ++++--- libindy_vdr/src/resolver/mod.rs | 2 +- libindy_vdr/src/resolver/resolver.rs | 200 ++++++++------------------- libindy_vdr/src/resolver/utils.rs | 73 +++------- libindy_vdr/tests/resolver.rs | 2 +- wrappers/python/demo/test.py | 6 +- wrappers/python/indy_vdr/resolver.py | 43 +++++- 7 files changed, 156 insertions(+), 219 deletions(-) diff --git a/libindy_vdr/src/ffi/resolver.rs b/libindy_vdr/src/ffi/resolver.rs index dd3bd9c1..5889b6c8 100644 --- a/libindy_vdr/src/ffi/resolver.rs +++ b/libindy_vdr/src/ffi/resolver.rs @@ -1,5 +1,5 @@ use crate::common::error::prelude::*; -use crate::resolver::PoolRunnerResolver as Resolver; +use crate::resolver::{handle_resolution_result, PoolRunnerResolver as Resolver}; use super::error::{set_last_error, ErrorCode}; use super::pool::{PoolHandle, POOLS}; @@ -18,23 +18,26 @@ pub extern "C" fn indy_vdr_resolve( let cb = cb.ok_or_else(|| input_err("No callback provided")).unwrap(); let pools = read_lock!(POOLS)?; let pool = pools.get(&pool_handle).ok_or_else(|| input_err("Unknown pool handle"))?; + let did = did.as_str().to_owned(); let resolver = Resolver::new(pool); - resolver - .resolve( - did.as_str(), - Box::new(move |result| { - let (errcode, reply) = match result { - Ok(status) => (ErrorCode::Success, status), - Err(err) => { - let code = ErrorCode::from(err.kind()); - set_last_error(Some(err)); - (code, String::new()) - } - }; - cb(cb_id, errcode, rust_string_to_c(reply)) - }), - )?; + resolver + .dereference( + did.clone(), + Box::new(move |ledger_reply| { + + let (errcode, reply) = match handle_resolution_result(ledger_reply, did) { + Ok(result) => (ErrorCode::Success, result), + Err(err) => { + let code = ErrorCode::from(err.kind()); + set_last_error(Some(err)); + (code, String::new()) + + } + }; + cb(cb_id, errcode, rust_string_to_c(reply)) + }), + )?; Ok(ErrorCode::Success) } } @@ -51,24 +54,26 @@ pub extern "C" fn indy_vdr_dereference( let cb = cb.ok_or_else(|| input_err("No callback provided")).unwrap(); let pools = read_lock!(POOLS)?; let pool = pools.get(&pool_handle).ok_or_else(|| input_err("Unknown pool handle"))?; + let did_url = did_url.as_str().to_owned(); let resolver = Resolver::new(pool); resolver .dereference( - did_url.as_str(), - Box::new(move |result| { - let (errcode, reply) = match result { - Ok(status) => (ErrorCode::Success, status), + did_url.clone(), + Box::new(move |ledger_reply| { + + let (errcode, reply) = match handle_resolution_result(ledger_reply, did_url) { + Ok(result) => (ErrorCode::Success, result), Err(err) => { + let code = ErrorCode::from(err.kind()); set_last_error(Some(err)); (code, String::new()) + } }; cb(cb_id, errcode, rust_string_to_c(reply)) }), )?; - - Ok(ErrorCode::Success) } } diff --git a/libindy_vdr/src/resolver/mod.rs b/libindy_vdr/src/resolver/mod.rs index 25449dee..a425f380 100644 --- a/libindy_vdr/src/resolver/mod.rs +++ b/libindy_vdr/src/resolver/mod.rs @@ -5,4 +5,4 @@ pub mod did_document; pub mod types; pub mod utils; -pub use self::resolver::{PoolResolver, PoolRunnerResolver}; +pub use self::resolver::{handle_resolution_result, PoolResolver, PoolRunnerResolver}; diff --git a/libindy_vdr/src/resolver/resolver.rs b/libindy_vdr/src/resolver/resolver.rs index a6bb6381..6d80f456 100644 --- a/libindy_vdr/src/resolver/resolver.rs +++ b/libindy_vdr/src/resolver/resolver.rs @@ -81,9 +81,8 @@ impl PoolResolver { let request = build_request(&did_url, &builder)?; let ledger_data = handle_request(&self.pool, &request).await?; - let txn_type = request.txn_type.as_str(); let namespace = did_url.namespace.clone(); - let result = handle_resolution_result(namespace.as_str(), &ledger_data, txn_type)?; + let result = handle_internal_resolution_result(namespace.as_str(), &ledger_data)?; Ok(result) } @@ -102,153 +101,74 @@ impl<'a> PoolRunnerResolver<'a> { /// Dereference a DID Url and return a serialized `DereferencingResult` pub fn dereference( &self, - did_url: &str, - callback: Callback>, + did_url: String, + callback: Callback, ) -> VdrResult<()> { - let did_url = DidUrl::from_str(did_url)?; - self._resolve( - &did_url, - Box::new(move |result| { - let (data, metadata) = result.unwrap(); - let content = match data { - Result::Content(c) => Some(c), - _ => None, - }; - - let md = if let Metadata::ContentMetadata(md) = metadata { - Some(md) - } else { - None - }; - - let result = DereferencingResult { - dereferencing_metadata: None, - content_stream: content, - content_metadata: md, - }; - - callback(Ok(serde_json::to_string_pretty(&result).unwrap())) - }), - ) + let did_url = DidUrl::from_str(did_url.as_str())?; + self._resolve(&did_url, callback)?; + Ok(()) } /// Resolve a DID and return a serialized `ResolutionResult` - pub fn resolve(&self, did: &str, callback: Callback>) -> VdrResult<()> { - let did = DidUrl::from_str(did)?; - self._resolve( - &did, - Box::new(move |result| { - match result { - Ok((data, metadata)) => { - match data { - // TODO: Doc needs to be mutable, when we uncomment - Result::DidDocument(doc) => { - // Try to find legacy endpoint using a GET_ATTRIB txn if diddoc_content is none - if doc.diddoc_content.is_none() { - // let did_copy = did.id.clone(); - // fetch_legacy_endpoint_with_runner( - // self.runner, - // &did_copy, - // Box::new(|result| { - // doc.endpoint = result.ok(); - // let diddoc = Some(doc.to_value().unwrap()); - // let md = if let Metadata::DidDocumentMetadata(md) = - // metadata - // { - // Some(md) - // } else { - // None - // }; - - // let result = ResolutionResult { - // did_resolution_metadata: None, - // did_document: diddoc, - // did_document_metadata: md, - // }; - - // callback(Ok( - // serde_json::to_string_pretty(&result).unwrap() - // )) - // }), - // ); - } else { - // let diddoc = Some(doc.to_value().unwrap()); - // let md = if let Metadata::DidDocumentMetadata(md) = metadata { - // Some(md) - // } else { - // None - // }; - - // let result = ResolutionResult { - // did_resolution_metadata: None, - // did_document: diddoc, - // did_document_metadata: md, - // }; - - // callback(Ok(serde_json::to_string_pretty(&result).unwrap())) - } - - // For now, until if/else above is used - - let diddoc = Some(doc.to_value().unwrap()); - let md = if let Metadata::DidDocumentMetadata(md) = metadata { - Some(md) - } else { - None - }; - - let result = ResolutionResult { - did_resolution_metadata: None, - did_document: diddoc, - did_document_metadata: md, - }; - - callback(Ok(serde_json::to_string_pretty(&result).unwrap())) - } - _ => {} - }; - } - // TODO: How to handle errors? - Err(_err) => {} - } - }), - )?; + pub fn resolve(&self, did: String, callback: Callback) -> VdrResult<()> { + let did = DidUrl::from_str(did.as_str())?; + self._resolve(&did, callback)?; Ok(()) } - fn _resolve( - &self, - did_url: &DidUrl, - callback: Callback>, - ) -> VdrResult<()> { - let namespace = did_url.namespace.clone(); + fn _resolve(&self, did_url: &DidUrl, callback: Callback) -> VdrResult<()> { + // let namespace = did_url.namespace.clone(); let builder = RequestBuilder::default(); let request = build_request(&did_url, &builder)?; - let txn_type = request.txn_type.clone(); - - self.runner.send_request( - request, - Box::new( - move |result: VdrResult<(RequestResult, Option)>| { - let ledger_data = match result { - Ok((reply, _)) => match reply { - RequestResult::Reply(reply_data) => Ok(reply_data), - RequestResult::Failed(err) => Err(err), - }, - Err(err) => Err(err), - } - .unwrap(); - - let result = handle_resolution_result( - namespace.as_str(), - &ledger_data, - txn_type.as_str(), - ) - .unwrap(); - callback(Ok(result)) - }, - ), - ) + // let txn_type = request.txn_type.clone(); + + self.runner.send_request(request, callback) + } +} + +type SendReqResponse = VdrResult<(RequestResult, Option)>; + +pub fn handle_resolution_result(result: SendReqResponse, did_url: String) -> VdrResult { + let did = DidUrl::from_str(did_url.as_str())?; + let (req_result, _timing_result) = result?; + + let ledger_data = match req_result { + RequestResult::Reply(reply_data) => Ok(reply_data), + RequestResult::Failed(err) => Err(err), + }?; + + println!("{:#?}", ledger_data); + + let namespace = did.namespace; + + let (data, metadata) = handle_internal_resolution_result(namespace.as_str(), &ledger_data)?; + + let content = match data { + Result::Content(c) => Some(c), + Result::DidDocument(doc) => doc.to_value().ok(), + }; + + match metadata { + Metadata::ContentMetadata(md) => { + let result = DereferencingResult { + dereferencing_metadata: None, + content_stream: content, + content_metadata: Some(md), + }; + + serde_json::to_string_pretty(&result) + .map_err(|err| err_msg(VdrErrorKind::Unexpected, err)) + } + Metadata::DidDocumentMetadata(md) => { + let result = ResolutionResult { + did_resolution_metadata: None, + did_document: content, + did_document_metadata: Some(md), + }; + + serde_json::to_string_pretty(&result) + .map_err(|err| err_msg(VdrErrorKind::Unexpected, err)) + } } } diff --git a/libindy_vdr/src/resolver/utils.rs b/libindy_vdr/src/resolver/utils.rs index a6fcd291..85f3f29e 100644 --- a/libindy_vdr/src/resolver/utils.rs +++ b/libindy_vdr/src/resolver/utils.rs @@ -12,7 +12,7 @@ use crate::ledger::identifiers::{CredentialDefinitionId, RevocationRegistryId, S use crate::ledger::responses::{Endpoint, GetNymResultV1}; use crate::ledger::RequestBuilder; use crate::pool::helpers::perform_ledger_request; -use crate::pool::{Pool, PoolRunner, PreparedRequest, RequestResult, TimingResult}; +use crate::pool::{Pool, PreparedRequest, RequestResult, TimingResult}; use crate::utils::did::DidValue; use crate::utils::Qualifiable; @@ -153,12 +153,16 @@ pub fn build_request(did: &DidUrl, builder: &RequestBuilder) -> VdrResult VdrResult<(Result, Metadata)> { - let data = parse_ledger_data(&ledger_data)?; + let (node_response, txn_type, data) = parse_ledger_data(&ledger_data)?; + let txn_type = txn_type + .as_str() + .ok_or("Unknown") + .unwrap() + .trim_matches('"'); Ok(match txn_type { constants::GET_NYM => { let get_nym_result: GetNymResultV1 = serde_json::from_str(data.as_str().unwrap()) @@ -175,7 +179,7 @@ pub fn handle_resolution_result( ); let metadata = Metadata::DidDocumentMetadata(DidDocumentMetadata { - node_response: serde_json::from_str(&ledger_data).unwrap(), + node_response, object_type: String::from("NYM"), self_certification_version: get_nym_result.version, }); @@ -185,52 +189,51 @@ pub fn handle_resolution_result( constants::GET_CRED_DEF => ( Result::Content(data), Metadata::ContentMetadata(ContentMetadata { - node_response: serde_json::from_str(&ledger_data).unwrap(), + node_response, object_type: String::from("CRED_DEF"), }), ), constants::GET_SCHEMA => ( Result::Content(data), Metadata::ContentMetadata(ContentMetadata { - node_response: serde_json::from_str(&ledger_data).unwrap(), + node_response, object_type: String::from("SCHEMA"), }), ), constants::GET_REVOC_REG_DEF => ( Result::Content(data), Metadata::ContentMetadata(ContentMetadata { - node_response: serde_json::from_str(&ledger_data).unwrap(), + node_response, object_type: String::from("REVOC_REG_DEF"), }), ), constants::GET_REVOC_REG_DELTA => ( Result::Content(data), Metadata::ContentMetadata(ContentMetadata { - node_response: serde_json::from_str(&ledger_data).unwrap(), + node_response, object_type: String::from("REVOC_REG_DELTA"), }), ), _ => ( Result::Content(data), Metadata::ContentMetadata(ContentMetadata { - node_response: serde_json::from_str(&ledger_data).unwrap(), - object_type: String::from("REVOC_REG_DELTA"), + node_response, + object_type: String::from("Unknown"), }), ), }) } -pub fn parse_ledger_data(ledger_data: &str) -> VdrResult { +pub fn parse_ledger_data(ledger_data: &str) -> VdrResult<(SJsonValue, SJsonValue, SJsonValue)> { let v: SJsonValue = serde_json::from_str(&ledger_data) .map_err(|_| err_msg(VdrErrorKind::Resolver, "Could not parse ledger response"))?; - let data: &SJsonValue = &v["result"]["data"]; - if *data == SJsonValue::Null { - Err(err_msg( - VdrErrorKind::Resolver, - format!("Empty data in ledger response"), - )) + // Unwrap should be safe here + let txn_type = (&v["result"]["type"]).to_owned(); + let data = (&v["result"]["data"]).to_owned(); + if data == SJsonValue::Null { + Err(err_msg(VdrErrorKind::Resolver, format!("Object not found"))) } else { - Ok(data.to_owned()) + Ok((v, txn_type, data)) } } @@ -275,42 +278,12 @@ pub async fn fetch_legacy_endpoint(pool: &T, did: &DidValue) -> VdrResu None, )?; let ledger_data = handle_request(pool, &request).await?; - let endpoint_data = parse_ledger_data(&ledger_data)?; + let (_, _, endpoint_data) = parse_ledger_data(&ledger_data)?; let endpoint_data: Endpoint = serde_json::from_str(endpoint_data.as_str().unwrap()) .map_err(|_| err_msg(VdrErrorKind::Resolver, "Could not parse endpoint data"))?; Ok(endpoint_data) } -pub fn fetch_legacy_endpoint_with_runner( - runner: &PoolRunner, - did: &DidValue, - callback: Callback>, -) -> VdrResult<()> { - let builder = RequestBuilder::default(); - let request = builder.build_get_attrib_request( - None, - did, - Some(String::from(LEGACY_INDY_SERVICE)), - None, - None, - )?; - runner.send_request( - request, - Box::new(move |result| match result { - Ok((res, _)) => match res { - RequestResult::Reply(reply_data) => { - let endpoint_data = parse_ledger_data(&reply_data).unwrap(); - let endpoint_data: Endpoint = - serde_json::from_str(endpoint_data.as_str().unwrap()).unwrap(); - callback(Ok(endpoint_data)); - } - RequestResult::Failed(err) => callback(Err(err)), - }, - Err(err) => callback(Err(err)), - }), - ) -} - #[cfg(test)] mod tests { diff --git a/libindy_vdr/tests/resolver.rs b/libindy_vdr/tests/resolver.rs index 17caf875..2995802f 100644 --- a/libindy_vdr/tests/resolver.rs +++ b/libindy_vdr/tests/resolver.rs @@ -9,7 +9,7 @@ fn empty() { } #[cfg(test)] -// #[cfg(feature = "local_nodes_pool_did_indy")] + #[cfg(feature = "local_nodes_pool_did_indy")] mod send_resolver { use futures_executor::block_on; use indy_vdr::resolver::PoolResolver as Resolver; diff --git a/wrappers/python/demo/test.py b/wrappers/python/demo/test.py index e64a850c..942c0f40 100644 --- a/wrappers/python/demo/test.py +++ b/wrappers/python/demo/test.py @@ -215,12 +215,12 @@ async def basic_test(transactions_path): resolver = Resolver(autopilot=True) - log("Resolve DID did:indy:idunion:ELMkCtYoz86qnJKeQqrL1M") - doc = await resolver.resolve("did:indy:idunion:ELMkCtYoz86qnJKeQqrL1M") + log("Resolve DID did:indy:idunion:APs6Xd2GH8FNwCaXDw6Qm2") + doc = await resolver.resolve("did:indy:idunion:Fhbr2wQrJeB1UcZeFKpG5F") log(json.dumps(doc, indent=2)) try: - doc = await resolver.resolve("did:indy:test:ELMkCtYoz86qnJKeQqrL1M") + doc = await resolver.resolve("did:indy:idunion:APs6Xd2GH8FNwCaXDw6Qm2") except VdrError as err: print(err) diff --git a/wrappers/python/indy_vdr/resolver.py b/wrappers/python/indy_vdr/resolver.py index a14c5afc..a76db1b0 100644 --- a/wrappers/python/indy_vdr/resolver.py +++ b/wrappers/python/indy_vdr/resolver.py @@ -4,6 +4,7 @@ from . import bindings from .error import VdrError, VdrErrorCode +from .ledger import build_get_attrib_request from .pool import Pool, open_pool from .utils import get_genesis_txns_from_did_indy_repo_by_name @@ -59,8 +60,46 @@ async def resolve(self, did: str) -> Dict: VdrErrorCode.WRAPPER, f"Unknown DID namespace: {namespace}" ) pool_handle = getattr(pool, "handle") - result = await bindings.resolve(pool_handle, did) - return json.loads(result) + result = json.loads(await bindings.resolve(pool_handle, did)) + + reply_data = json.loads(result["didDocumentMetadata"]["nodeResponse"]["result"]["data"]) + diddoc_content = reply_data.get("diddocContent", None) + + # Handle legacy case, where diddocContent is not present and we want to check for + # associated ATTRIB endpoints. We can't handle in this in libindy_vdr directly. + if not diddoc_content: + unqualified_did = reply_data["dest"] + req = build_get_attrib_request(None, unqualified_did, "endpoint", None, None) + res = await pool.submit_request(req) + data = res.get("data", None) + if data: + data = json.loads(data) + endpoints = data.get("endpoint", None) + + if endpoints: + services = [] + for (service_type, service_endpoint) in endpoints.items(): + if service_type == "endpoint": + + services.append({ + "id": f"did:indy:{namespace}:{unqualified_did}#did-communication", + "type": "did-communication", + "recipientKeys": [f"did:indy:{namespace}:{unqualified_did}#verkey"] , + "routingKeys": [], + "priority": 0 + }) + + else: + + services.append({ + "id": f"did:indy:{namespace}:{unqualified_did}#{service_type}", + "type": service_type, + "serviceEndpoint": service_endpoint + + }) + result["didDocument"]["services"] = services; + + return result async def dereference(self, did_url: str) -> Dict: """Dereference a DID Url to retrieve a ledger object.""" From 692b4730fc237f7c4b561147c0509f03c6a0ac6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20W=C3=B6rner?= Date: Fri, 25 Mar 2022 12:44:59 +0100 Subject: [PATCH 060/117] disable enforcement of diddoc_content validation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- libindy_vdr/src/resolver/did_document.rs | 8 ++++---- libindy_vdr/tests/resolver.rs | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libindy_vdr/src/resolver/did_document.rs b/libindy_vdr/src/resolver/did_document.rs index ede383b8..3fd85854 100644 --- a/libindy_vdr/src/resolver/did_document.rs +++ b/libindy_vdr/src/resolver/did_document.rs @@ -87,12 +87,12 @@ impl DidDocument { if self.diddoc_content.is_some() { let is_valid = validate_diddoc_content(&(self.diddoc_content.as_ref().unwrap())); - if is_valid { - merge_diddoc(&mut doc, self.diddoc_content.as_ref().unwrap()); - } else { - return Err(err_msg(VdrErrorKind::Resolver, "Invalid DIDdoc Content")); + if !is_valid { + debug!("Invalid DIDdoc Content, but validation won't be enforced."); } + merge_diddoc(&mut doc, self.diddoc_content.as_ref().unwrap()); + // Handling of legacy services } else if self.endpoint.is_some() { let mut services = Vec::new(); diff --git a/libindy_vdr/tests/resolver.rs b/libindy_vdr/tests/resolver.rs index 2995802f..deffbe84 100644 --- a/libindy_vdr/tests/resolver.rs +++ b/libindy_vdr/tests/resolver.rs @@ -9,7 +9,7 @@ fn empty() { } #[cfg(test)] - #[cfg(feature = "local_nodes_pool_did_indy")] +#[cfg(feature = "local_nodes_pool_did_indy")] mod send_resolver { use futures_executor::block_on; use indy_vdr::resolver::PoolResolver as Resolver; From d225ddf978b6c307293964ad176ce6dc038b6b2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20W=C3=B6rner?= Date: Mon, 28 Mar 2022 09:16:35 +0200 Subject: [PATCH 061/117] implement some of the clippy suggestions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- README.md | 8 +- indy-vdr-proxy/src/handlers.rs | 2 +- libindy_vdr/src/resolver/did.rs | 182 ++++++++++++----------- libindy_vdr/src/resolver/did_document.rs | 10 +- libindy_vdr/src/resolver/resolver.rs | 28 ++-- libindy_vdr/src/resolver/types.rs | 2 +- libindy_vdr/src/resolver/utils.rs | 26 ++-- 7 files changed, 135 insertions(+), 123 deletions(-) diff --git a/README.md b/README.md index 8430d104..a993fcf2 100644 --- a/README.md +++ b/README.md @@ -42,14 +42,18 @@ At a later stage it should be possible to install a precompiled 'wheel' package The `indy-vdr-proxy` executable can be used to provide a simple REST API for interacting with one or more Indy ledgers. Command line options can be inspected by running `indy-vdr-proxy --help`. To start the proxy server for a single ledger use the following command: -`indy-vdr-proxy -p (-g )` +``` +indy-vdr-proxy -p (-g ) +``` To start the proxy server with the standard configuration of indy ledgers use the following command: `indy-vdr-proxy -p --multiple-ledgers` This will get the ledger configuration from `https://github.com/IDunion/indy-did-networks` A custom ledger configuration can be provided either by specificing a Github repo or a local folder: -`indy-vdr-proxy -p --multiple-ledgers -g ` +``` +indy-vdr-proxy -p --multiple-ledgers -g +``` The structure needs to be as follows `/OPTIONAL/pool_transactions_genesis.json`, e.g. `/sovrin/staging/pool_transactions_genesis.json` Responses can be formatted in either HTML or JSON formats. HTML formatting is selected when the `text/html` content type is requested according to the Accept header (as sent by web browsers) or the request query string is set to `?html`. JSON formatting is selected otherwise, and may be explitly selected by using the query string `?raw`. For most ledger requests, JSON responses include information regarding which nodes were contacted is returned in the `X-Requests` header. diff --git a/indy-vdr-proxy/src/handlers.rs b/indy-vdr-proxy/src/handlers.rs index 80335f49..19233531 100644 --- a/indy-vdr-proxy/src/handlers.rs +++ b/indy-vdr-proxy/src/handlers.rs @@ -488,7 +488,7 @@ pub async fn handle_request( }; if did.is_some() { - namespace = match DidUrl::from_str(did.unwrap()) { + namespace = match DidUrl::parse(did.unwrap()) { Ok(did_url) => did_url.namespace, Err(_) => { return format_result(http_status(StatusCode::BAD_REQUEST), format); diff --git a/libindy_vdr/src/resolver/did.rs b/libindy_vdr/src/resolver/did.rs index 85c62c44..136e08fe 100644 --- a/libindy_vdr/src/resolver/did.rs +++ b/libindy_vdr/src/resolver/did.rs @@ -31,7 +31,7 @@ pub enum QueryParameter { } impl QueryParameter { - pub fn from_str(input: &str) -> VdrResult { + pub fn parse(input: &str) -> VdrResult { match input { "versionId" => Ok(QueryParameter::VersionId), "versionTime" => Ok(QueryParameter::VersionTime), @@ -51,7 +51,7 @@ pub enum ObjectFamily { } impl ObjectFamily { - fn from_str(input: &str) -> VdrResult { + fn parse(input: &str) -> VdrResult { match input { "anoncreds" => Ok(ObjectFamily::Anoncreds), _ => Err(err_msg( @@ -68,7 +68,7 @@ pub enum Anoncreds { } impl Anoncreds { - fn from_str(input: &str) -> VdrResult { + fn parse(input: &str) -> VdrResult { match input { "v0" => Ok(Anoncreds::AnoncredsV0), _ => Err(err_msg( @@ -90,7 +90,7 @@ impl Schema { Self { name, version } } - fn from_str(input: &str) -> VdrResult { + fn parse(input: &str) -> VdrResult { let re = Regex::new(format!(r"^{}/{}", CLIENT_DEFINED_NAME_PATTERN, VERSION_PATTERN).as_str()) .unwrap(); @@ -100,17 +100,21 @@ impl Schema { match captures { Some(cap) => Ok(Schema::new( cap.get(1) - .ok_or(err_msg( - VdrErrorKind::Resolver, - format!("Invalid DID URL path for schema {}", input), - ))? + .ok_or_else(|| { + err_msg( + VdrErrorKind::Resolver, + format!("Invalid DID URL path for schema {}", input), + ) + })? .as_str() .to_string(), cap.get(2) - .ok_or(err_msg( - VdrErrorKind::Resolver, - format!("Invalid DID URL path for schema {}", input), - ))? + .ok_or_else(|| { + err_msg( + VdrErrorKind::Resolver, + format!("Invalid DID URL path for schema {}", input), + ) + })? .as_str() .to_string(), )), @@ -136,7 +140,7 @@ impl ClaimDef { } } - fn from_str(input: &str) -> VdrResult { + fn parse(input: &str) -> VdrResult { let re = Regex::new(format!(r"^{}/{}", SEQ_NO_PATTERN, CLIENT_DEFINED_NAME_PATTERN).as_str()) .unwrap(); @@ -146,19 +150,23 @@ impl ClaimDef { match captures { Some(cap) => Ok(ClaimDef::new( cap.get(1) - .ok_or(err_msg( - VdrErrorKind::Resolver, - format!("Invalid DID URL path for claim def {}", input), - ))? + .ok_or_else(|| { + err_msg( + VdrErrorKind::Resolver, + format!("Invalid DID URL path for claim def {}", input), + ) + })? .as_str() .to_string() .parse::() .unwrap(), cap.get(2) - .ok_or(err_msg( - VdrErrorKind::Resolver, - format!("Invalid DID URL path for claim def {}", input), - ))? + .ok_or_else(|| { + err_msg( + VdrErrorKind::Resolver, + format!("Invalid DID URL path for claim def {}", input), + ) + })? .as_str() .to_string(), )), @@ -186,7 +194,7 @@ impl RevReg { } } - fn from_str(input: &str) -> VdrResult { + fn parse(input: &str) -> VdrResult { let re = Regex::new( format!(r"^{}/{}/{1}", SEQ_NO_PATTERN, CLIENT_DEFINED_NAME_PATTERN).as_str(), ) @@ -197,26 +205,32 @@ impl RevReg { match captures { Some(cap) => Ok(RevReg::new( cap.get(1) - .ok_or(err_msg( - VdrErrorKind::Resolver, - format!("Invalid DID URL path for revocation registry {}", input), - ))? + .ok_or_else(|| { + err_msg( + VdrErrorKind::Resolver, + format!("Invalid DID URL path for revocation registry {}", input), + ) + })? .as_str() .to_string() .parse::() .unwrap(), cap.get(2) - .ok_or(err_msg( - VdrErrorKind::Resolver, - format!("Invalid DID URL path for revocation registry {}", input), - ))? + .ok_or_else(|| { + err_msg( + VdrErrorKind::Resolver, + format!("Invalid DID URL path for revocation registry {}", input), + ) + })? .as_str() .to_string(), cap.get(3) - .ok_or(err_msg( - VdrErrorKind::Resolver, - format!("Invalid DID URL path for revocation registry {}", input), - ))? + .ok_or_else(|| { + err_msg( + VdrErrorKind::Resolver, + format!("Invalid DID URL path for revocation registry {}", input), + ) + })? .as_str() .to_string(), )), @@ -238,7 +252,7 @@ pub enum LedgerObject { } impl LedgerObject { - pub fn from_str(input: &str) -> VdrResult { + pub fn parse(input: &str) -> VdrResult { let re = Regex::new( format!( r"{}/{}/{}/(.+)?", @@ -253,54 +267,46 @@ impl LedgerObject { if let Some(cap) = captures { let object_family_str = cap .get(1) - .ok_or(err_msg( - VdrErrorKind::Resolver, - format!("Invalid DID URL path"), - ))? + .ok_or_else(|| err_msg(VdrErrorKind::Resolver, "Invalid DID URL path".to_string()))? .as_str(); let version = cap .get(2) - .ok_or(err_msg( - VdrErrorKind::Resolver, - format!("Invalid DID URL path"), - ))? + .ok_or_else(|| err_msg(VdrErrorKind::Resolver, "Invalid DID URL path".to_string()))? .as_str(); - let object_family = ObjectFamily::from_str(object_family_str)?; + let object_family = ObjectFamily::parse(object_family_str)?; match object_family { ObjectFamily::Anoncreds => { - let object_family_versioned = Anoncreds::from_str(version)?; + let object_family_versioned = Anoncreds::parse(version)?; match object_family_versioned { Anoncreds::AnoncredsV0 => { let ledger_object_type_str = cap .get(3) - .ok_or(err_msg( - VdrErrorKind::Resolver, - format!("Invalid DID URL path"), - ))? + .ok_or_else(|| { + err_msg(VdrErrorKind::Resolver, "Invalid DID URL path") + })? .as_str(); let ledger_object_type_specific_str = cap .get(4) - .ok_or(err_msg( - VdrErrorKind::Resolver, - format!("Invalid DID URL path"), - ))? + .ok_or_else(|| { + err_msg(VdrErrorKind::Resolver, "Invalid DID URL path") + })? .as_str(); match ledger_object_type_str { - "SCHEMA" => Ok(LedgerObject::Schema(Schema::from_str( + "SCHEMA" => Ok(LedgerObject::Schema(Schema::parse( ledger_object_type_specific_str, )?)), - "CLAIM_DEF" => Ok(LedgerObject::ClaimDef(ClaimDef::from_str( + "CLAIM_DEF" => Ok(LedgerObject::ClaimDef(ClaimDef::parse( ledger_object_type_specific_str, )?)), - "REV_REG_DEF" => Ok(LedgerObject::RevRegDef(RevReg::from_str( + "REV_REG_DEF" => Ok(LedgerObject::RevRegDef(RevReg::parse( ledger_object_type_specific_str, )?)), - "REV_REG_ENTRY" => Ok(LedgerObject::RevRegEntry(RevReg::from_str( + "REV_REG_ENTRY" => Ok(LedgerObject::RevRegEntry(RevReg::parse( ledger_object_type_specific_str, )?)), - "REV_REG_DELTA" => Ok(LedgerObject::RevRegDelta(RevReg::from_str( + "REV_REG_DELTA" => Ok(LedgerObject::RevRegDelta(RevReg::parse( ledger_object_type_specific_str, )?)), @@ -335,7 +341,7 @@ pub struct DidUrl { } impl DidUrl { - pub fn from_str(input: &str) -> VdrResult { + pub fn parse(input: &str) -> VdrResult { let did_regex = Regex::new( format!( r"{}:{}:{}([^\?]+)?(?:\?(.+))?$", @@ -351,7 +357,7 @@ impl DidUrl { let _query_pairs: HashMap<_, _> = url.query_pairs().into_owned().collect(); for (k, v) in _query_pairs.iter() { - let qp = QueryParameter::from_str(k)?; + let qp = QueryParameter::parse(k)?; query_pairs.insert(qp, v.to_string()); } @@ -384,23 +390,23 @@ mod tests { #[test] fn parse_unknown_ledger_object_fails() { - let _err = LedgerObject::from_str("/anoncreds/v0/PANTS/npdb/4.3.4").unwrap_err(); + let _err = LedgerObject::parse("/anoncreds/v0/PANTS/npdb/4.3.4").unwrap_err(); } #[test] fn parse_unknown_object_family_fails() { - let _err = LedgerObject::from_str("/othercreds/v0/SCHEMA/npdb/4.3.4").unwrap_err(); + let _err = LedgerObject::parse("/othercreds/v0/SCHEMA/npdb/4.3.4").unwrap_err(); } #[test] fn parse_unknown_anoncreds_version_fails() { - let _err = LedgerObject::from_str("/anoncreds/v5/SCHEMA/npdb/4.3.4").unwrap_err(); + let _err = LedgerObject::parse("/anoncreds/v5/SCHEMA/npdb/4.3.4").unwrap_err(); } #[test] fn parse_to_schema() { assert_eq!( - LedgerObject::from_str("/anoncreds/v0/SCHEMA/npdb/4.3.4").unwrap(), + LedgerObject::parse("/anoncreds/v0/SCHEMA/npdb/4.3.4").unwrap(), LedgerObject::Schema(Schema::new(String::from("npdb"), String::from("4.3.4"))) ) } @@ -408,7 +414,7 @@ mod tests { #[test] fn parse_to_schema_two_point_seperated_version() { assert_eq!( - LedgerObject::from_str("/anoncreds/v0/SCHEMA/npdb/4.3").unwrap(), + LedgerObject::parse("/anoncreds/v0/SCHEMA/npdb/4.3").unwrap(), LedgerObject::Schema(Schema::new(String::from("npdb"), String::from("4.3"))) ) } @@ -416,43 +422,43 @@ mod tests { #[test] fn parse_to_schema_two_digit_version() { assert_eq!( - LedgerObject::from_str("/anoncreds/v0/SCHEMA/npdb/11.3").unwrap(), + LedgerObject::parse("/anoncreds/v0/SCHEMA/npdb/11.3").unwrap(), LedgerObject::Schema(Schema::new(String::from("npdb"), String::from("11.3"))) ) } #[test] fn parse_to_schema_without_version_fails() { - let _err = LedgerObject::from_str("/anoncreds/v0/SCHEMA/npdb").unwrap_err(); + let _err = LedgerObject::parse("/anoncreds/v0/SCHEMA/npdb").unwrap_err(); } #[test] fn parse_to_schema_with_one_digit_version_fails() { - let _err = LedgerObject::from_str("/anoncreds/v0/SCHEMA/npdb/4").unwrap_err(); + let _err = LedgerObject::parse("/anoncreds/v0/SCHEMA/npdb/4").unwrap_err(); } #[test] fn parse_to_claim_def() { assert_eq!( - LedgerObject::from_str("/anoncreds/v0/CLAIM_DEF/23452/npdb").unwrap(), + LedgerObject::parse("/anoncreds/v0/CLAIM_DEF/23452/npdb").unwrap(), LedgerObject::ClaimDef(ClaimDef::new(23452, String::from("npdb"))) ) } #[test] fn parse_to_claim_def_without_seq_no_fails() { - let _err = LedgerObject::from_str("/anoncreds/v0/CLAIM_DEF/npdb").unwrap_err(); + let _err = LedgerObject::parse("/anoncreds/v0/CLAIM_DEF/npdb").unwrap_err(); } #[test] fn parse_to_claim_def_with_seq_no_as_string_fails() { - let _err = LedgerObject::from_str("/anoncreds/v0/CLAIM_DEF/myseqno/npdb").unwrap_err(); + let _err = LedgerObject::parse("/anoncreds/v0/CLAIM_DEF/myseqno/npdb").unwrap_err(); } #[test] fn parse_to_rev_reg_entry() { assert_eq!( - LedgerObject::from_str("/anoncreds/v0/REV_REG_ENTRY/104/revocable/a4e25e54").unwrap(), + LedgerObject::parse("/anoncreds/v0/REV_REG_ENTRY/104/revocable/a4e25e54").unwrap(), LedgerObject::RevRegEntry(RevReg::new( 104, String::from("revocable"), @@ -464,7 +470,7 @@ mod tests { #[test] fn parse_to_rev_reg_def() { assert_eq!( - LedgerObject::from_str( + LedgerObject::parse( "/anoncreds/v0/REV_REG_DEF/104/revocable/a4e25e54-e028-462b-a4d6-b1d1712d51a1" ) .unwrap(), @@ -482,10 +488,10 @@ mod tests { #[test] fn did_syntax_tests() { - let _err = DidUrl::from_str("did:indy:onlynamespace").unwrap_err(); + let _err = DidUrl::parse("did:indy:onlynamespace").unwrap_err(); assert_eq!( - DidUrl::from_str("did:indy:idunion:BDrEcHc8Tb4Lb2VyQZWEDE").unwrap(), + DidUrl::parse("did:indy:idunion:BDrEcHc8Tb4Lb2VyQZWEDE").unwrap(), DidUrl { namespace: String::from("idunion"), id: DidValue::new("BDrEcHc8Tb4Lb2VyQZWEDE", None), @@ -496,7 +502,7 @@ mod tests { ); assert_eq!( - DidUrl::from_str("did:indy:sovrin:staging:6cgbu8ZPoWTnR5Rv5JcSMB").unwrap(), + DidUrl::parse("did:indy:sovrin:staging:6cgbu8ZPoWTnR5Rv5JcSMB").unwrap(), DidUrl { namespace: String::from("sovrin:staging"), id: DidValue::new("6cgbu8ZPoWTnR5Rv5JcSMB", None), @@ -506,21 +512,21 @@ mod tests { } ); - let _err = DidUrl::from_str("did:indy:illegal:third:namespace:1111111111111111111111") + let _err = DidUrl::parse("did:indy:illegal:third:namespace:1111111111111111111111") .unwrap_err(); - let _err = DidUrl::from_str("did:indy:test:12345678901234567890").unwrap_err(); - let _err = DidUrl::from_str("did:indy:test:12345678901234567890123").unwrap_err(); + let _err = DidUrl::parse("did:indy:test:12345678901234567890").unwrap_err(); + let _err = DidUrl::parse("did:indy:test:12345678901234567890123").unwrap_err(); // fails because contains characters not in base58 // 0 - let _err = DidUrl::from_str("did:indy:test:0cgbu8ZPoWTnR5Rv5JcSMB").unwrap_err(); + let _err = DidUrl::parse("did:indy:test:0cgbu8ZPoWTnR5Rv5JcSMB").unwrap_err(); // O - let _err = DidUrl::from_str("did:indy:test:Ocgbu8ZPoWTnR5Rv5JcSMB").unwrap_err(); + let _err = DidUrl::parse("did:indy:test:Ocgbu8ZPoWTnR5Rv5JcSMB").unwrap_err(); // I - let _err = DidUrl::from_str("did:indy:test:Icgbu8ZPoWTnR5Rv5JcSMB").unwrap_err(); + let _err = DidUrl::parse("did:indy:test:Icgbu8ZPoWTnR5Rv5JcSMB").unwrap_err(); // l - let _err = DidUrl::from_str("did:indy:test:lcgbu8ZPoWTnR5Rv5JcSMB").unwrap_err(); + let _err = DidUrl::parse("did:indy:test:lcgbu8ZPoWTnR5Rv5JcSMB").unwrap_err(); } #[test] @@ -529,7 +535,7 @@ mod tests { q.insert(QueryParameter::VersionId, String::from("1")); assert_eq!( - DidUrl::from_str("did:indy:idunion:BDrEcHc8Tb4Lb2VyQZWEDE?versionId=1").unwrap(), + DidUrl::parse("did:indy:idunion:BDrEcHc8Tb4Lb2VyQZWEDE?versionId=1").unwrap(), DidUrl { namespace: String::from("idunion"), id: DidValue::new("BDrEcHc8Tb4Lb2VyQZWEDE", None), @@ -542,14 +548,14 @@ mod tests { #[test] fn parse_did_url_fails_with_arbitrary_query_parameter() { - let _err = DidUrl::from_str("did:indy:idunion:BDrEcHc8Tb4Lb2VyQZWEDE?hello=world") - .unwrap_err(); + let _err = + DidUrl::parse("did:indy:idunion:BDrEcHc8Tb4Lb2VyQZWEDE?hello=world").unwrap_err(); } #[test] fn parse_did_url_with_path() { assert_eq!( - DidUrl::from_str("did:indy:idunion:Dk1fRRTtNazyMuK2cr64wp/anoncreds/v0/REV_REG_DEF/104/revocable/a4e25e54-e028-462b-a4d6-b1d1712d51a1") + DidUrl::parse("did:indy:idunion:Dk1fRRTtNazyMuK2cr64wp/anoncreds/v0/REV_REG_DEF/104/revocable/a4e25e54-e028-462b-a4d6-b1d1712d51a1") .unwrap(), DidUrl { namespace: String::from("idunion"), @@ -569,7 +575,7 @@ mod tests { q.insert(QueryParameter::VersionTime, String::from("someXmlDateTime")); assert_eq!( - DidUrl::from_str("did:indy:idunion:Dk1fRRTtNazyMuK2cr64wp/anoncreds/v0/REV_REG_DEF/104/revocable/a4e25e54-e028-462b-a4d6-b1d1712d51a1?versionTime=someXmlDateTime") + DidUrl::parse("did:indy:idunion:Dk1fRRTtNazyMuK2cr64wp/anoncreds/v0/REV_REG_DEF/104/revocable/a4e25e54-e028-462b-a4d6-b1d1712d51a1?versionTime=someXmlDateTime") .unwrap(), DidUrl { namespace: String::from("idunion"), diff --git a/libindy_vdr/src/resolver/did_document.rs b/libindy_vdr/src/resolver/did_document.rs index 3fd85854..ebddcad0 100644 --- a/libindy_vdr/src/resolver/did_document.rs +++ b/libindy_vdr/src/resolver/did_document.rs @@ -77,15 +77,15 @@ impl DidDocument { "id": format!("did:indy:{}:{}", self.namespace, self.id), "verificationMethod": [Ed25519VerificationKey2018 { id: format!("did:indy:{}:{}#verkey", self.namespace, self.id), - type_: format!("Ed25519VerificationKey2018"), + type_: "Ed25519VerificationKey2018".to_string(), controller: format!("did:indy:{}:{}", self.namespace, self.id), - public_key_base58: format!("{}", self.verkey), + public_key_base58: self.verkey.to_string(), }], "authentication": [format!("did:indy:{}:{}#verkey", self.namespace, self.id)], }); if self.diddoc_content.is_some() { - let is_valid = validate_diddoc_content(&(self.diddoc_content.as_ref().unwrap())); + let is_valid = validate_diddoc_content(self.diddoc_content.as_ref().unwrap()); if !is_valid { debug!("Invalid DIDdoc Content, but validation won't be enforced."); @@ -174,8 +174,8 @@ fn merge_diddoc(base: &mut SJsonValue, content: &SJsonValue) { } fn expand_verkey(id: &str, verkey: &str) -> String { - if verkey.starts_with('~') { - format!("{}{}", id, &verkey[1..]) + if let Some(stripped) = verkey.strip_prefix('~') { + format!("{}{}", id, stripped) } else { verkey.to_string() } diff --git a/libindy_vdr/src/resolver/resolver.rs b/libindy_vdr/src/resolver/resolver.rs index 6d80f456..c7260317 100644 --- a/libindy_vdr/src/resolver/resolver.rs +++ b/libindy_vdr/src/resolver/resolver.rs @@ -8,6 +8,10 @@ use super::types::*; use super::utils::*; /// DID (URL) Resolver interface for a pool compliant with did:indy method spec +/// The resolver interface is bound to a specific indy network and does not evaluate +/// the namespace part of the DID. You need to create a resolver instance for each +/// indy network you want to support. +/// The `PoolResolver` uses async/await. pub struct PoolResolver { pool: T, } @@ -20,7 +24,7 @@ impl PoolResolver { /// Dereference a DID Url and return a serialized `DereferencingResult` pub async fn dereference(&self, did_url: &str) -> VdrResult { debug!("PoolResolver: Dereference DID Url {}", did_url); - let did_url = DidUrl::from_str(did_url)?; + let did_url = DidUrl::parse(did_url)?; let (data, metadata) = self._resolve(&did_url).await?; let content = match data { @@ -46,7 +50,7 @@ impl PoolResolver { /// Resolve a DID and return a serialized `ResolutionResult` pub async fn resolve(&self, did: &str) -> VdrResult { debug!("PoolResolver: Resolve DID {}", did); - let did = DidUrl::from_str(did)?; + let did = DidUrl::parse(did)?; let (data, metadata) = self._resolve(&did).await?; let diddoc = match data { @@ -78,7 +82,7 @@ impl PoolResolver { // Internal method to resolve and dereference async fn _resolve(&self, did_url: &DidUrl) -> VdrResult<(Result, Metadata)> { let builder = self.pool.get_request_builder(); - let request = build_request(&did_url, &builder)?; + let request = build_request(did_url, &builder)?; let ledger_data = handle_request(&self.pool, &request).await?; let namespace = did_url.namespace.clone(); @@ -89,6 +93,10 @@ impl PoolResolver { } /// DID (URL) Resolver interface using callbacks for a PoolRunner compliant with did:indy method spec +/// The PoolRunnerResolver is used for the FFI. +/// Note that the PoolRunnerResolver does not fetch an ATTRIB txn for legacy endpoint resolution. +/// If you need to use the PoolRunnerResolver, please have a look at the Python wrapper to see how +/// legacy endpoints can be resolved. pub struct PoolRunnerResolver<'a> { runner: &'a PoolRunner, } @@ -104,25 +112,21 @@ impl<'a> PoolRunnerResolver<'a> { did_url: String, callback: Callback, ) -> VdrResult<()> { - let did_url = DidUrl::from_str(did_url.as_str())?; + let did_url = DidUrl::parse(did_url.as_str())?; self._resolve(&did_url, callback)?; Ok(()) } /// Resolve a DID and return a serialized `ResolutionResult` pub fn resolve(&self, did: String, callback: Callback) -> VdrResult<()> { - let did = DidUrl::from_str(did.as_str())?; + let did = DidUrl::parse(did.as_str())?; self._resolve(&did, callback)?; Ok(()) } fn _resolve(&self, did_url: &DidUrl, callback: Callback) -> VdrResult<()> { - // let namespace = did_url.namespace.clone(); - let builder = RequestBuilder::default(); - let request = build_request(&did_url, &builder)?; - // let txn_type = request.txn_type.clone(); - + let request = build_request(did_url, &builder)?; self.runner.send_request(request, callback) } } @@ -130,7 +134,7 @@ impl<'a> PoolRunnerResolver<'a> { type SendReqResponse = VdrResult<(RequestResult, Option)>; pub fn handle_resolution_result(result: SendReqResponse, did_url: String) -> VdrResult { - let did = DidUrl::from_str(did_url.as_str())?; + let did = DidUrl::parse(did_url.as_str())?; let (req_result, _timing_result) = result?; let ledger_data = match req_result { @@ -138,8 +142,6 @@ pub fn handle_resolution_result(result: SendReqResponse, did_url: String) -> Vdr RequestResult::Failed(err) => Err(err), }?; - println!("{:#?}", ledger_data); - let namespace = did.namespace; let (data, metadata) = handle_internal_resolution_result(namespace.as_str(), &ledger_data)?; diff --git a/libindy_vdr/src/resolver/types.rs b/libindy_vdr/src/resolver/types.rs index 6c17227f..c929b8bb 100644 --- a/libindy_vdr/src/resolver/types.rs +++ b/libindy_vdr/src/resolver/types.rs @@ -2,7 +2,7 @@ use serde_json::Value as SJsonValue; use super::did_document::DidDocument; -pub type Callback = Box ()) + Send>; +pub type Callback = Box; #[derive(Serialize, Deserialize, PartialEq, Debug)] #[serde(rename_all = "camelCase")] diff --git a/libindy_vdr/src/resolver/utils.rs b/libindy_vdr/src/resolver/utils.rs index 85f3f29e..549aa4f3 100644 --- a/libindy_vdr/src/resolver/utils.rs +++ b/libindy_vdr/src/resolver/utils.rs @@ -18,7 +18,7 @@ use crate::utils::Qualifiable; pub fn build_request(did: &DidUrl, builder: &RequestBuilder) -> VdrResult { let request = if did.path.is_some() { - match LedgerObject::from_str(did.path.as_ref().unwrap().as_str())? { + match LedgerObject::parse(did.path.as_ref().unwrap().as_str())? { LedgerObject::Schema(schema) => builder.build_get_schema_request( None, &SchemaId::new(&did.id, &schema.name, &schema.version), @@ -157,7 +157,7 @@ pub fn handle_internal_resolution_result( namespace: &str, ledger_data: &str, ) -> VdrResult<(Result, Metadata)> { - let (node_response, txn_type, data) = parse_ledger_data(&ledger_data)?; + let (node_response, txn_type, data) = parse_ledger_data(ledger_data)?; let txn_type = txn_type .as_str() .ok_or("Unknown") @@ -225,13 +225,13 @@ pub fn handle_internal_resolution_result( } pub fn parse_ledger_data(ledger_data: &str) -> VdrResult<(SJsonValue, SJsonValue, SJsonValue)> { - let v: SJsonValue = serde_json::from_str(&ledger_data) + let v: SJsonValue = serde_json::from_str(ledger_data) .map_err(|_| err_msg(VdrErrorKind::Resolver, "Could not parse ledger response"))?; // Unwrap should be safe here let txn_type = (&v["result"]["type"]).to_owned(); let data = (&v["result"]["data"]).to_owned(); if data == SJsonValue::Null { - Err(err_msg(VdrErrorKind::Resolver, format!("Object not found"))) + Err(err_msg(VdrErrorKind::Resolver, "Object not found")) } else { Ok((v, txn_type, data)) } @@ -253,7 +253,7 @@ pub fn parse_or_now(datetime: Option<&String>) -> VdrResult { } pub async fn handle_request(pool: &T, request: &PreparedRequest) -> VdrResult { - let (result, _timing) = request_transaction(pool, &request).await?; + let (result, _timing) = request_transaction(pool, request).await?; match result { RequestResult::Reply(data) => Ok(data), RequestResult::Failed(error) => Err(error), @@ -264,7 +264,7 @@ pub async fn request_transaction( pool: &T, request: &PreparedRequest, ) -> VdrResult<(RequestResult, Option)> { - perform_ledger_request(pool, &request).await + perform_ledger_request(pool, request).await } /// Fetch legacy service endpoint using ATTRIB tx @@ -306,7 +306,7 @@ mod tests { fn build_get_revoc_reg_request_from_version_time(request_builder: RequestBuilder) { let datetime_as_str = "2020-12-20T19:17:47Z"; let did_url_as_str = format!("did:indy:idunion:Dk1fRRTtNazyMuK2cr64wp/anoncreds/v0/REV_REG_ENTRY/104/revocable/a4e25e54?versionTime={}",datetime_as_str); - let did_url = DidUrl::from_str(&did_url_as_str).unwrap(); + let did_url = DidUrl::parse(&did_url_as_str).unwrap(); let request = build_request(&did_url, &request_builder).unwrap(); let timestamp = (*(request.req_json).get("operation").unwrap()) .get("timestamp") @@ -328,7 +328,7 @@ mod tests { let now = OffsetDateTime::now_utc().unix_timestamp(); let did_url_as_str = "did:indy:idunion:Dk1fRRTtNazyMuK2cr64wp/anoncreds/v0/REV_REG_ENTRY/104/revocable/a4e25e54"; - let did_url = DidUrl::from_str(did_url_as_str).unwrap(); + let did_url = DidUrl::parse(did_url_as_str).unwrap(); let request = build_request(&did_url, &request_builder).unwrap(); let timestamp = (*(request.req_json).get("operation").unwrap()) .get("timestamp") @@ -346,7 +346,7 @@ mod tests { ) { let datetime_as_str = "20201220T19:17:47Z"; let did_url_as_str = format!("did:indy:idunion:Dk1fRRTtNazyMuK2cr64wp/anoncreds/v0/REV_REG_ENTRY/104/revocable/a4e25e54?versionTime={}",datetime_as_str); - let did_url = DidUrl::from_str(&did_url_as_str).unwrap(); + let did_url = DidUrl::parse(&did_url_as_str).unwrap(); let _err = build_request(&did_url, &request_builder).unwrap_err(); } @@ -355,7 +355,7 @@ mod tests { let from_as_str = "2019-12-20T19:17:47Z"; let to_as_str = "2020-12-20T19:17:47Z"; let did_url_as_str = format!("did:indy:idunion:Dk1fRRTtNazyMuK2cr64wp/anoncreds/v0/REV_REG_ENTRY/104/revocable/a4e25e54?from={}&to={}",from_as_str, to_as_str); - let did_url = DidUrl::from_str(&did_url_as_str).unwrap(); + let did_url = DidUrl::parse(&did_url_as_str).unwrap(); let request = build_request(&did_url, &request_builder).unwrap(); assert_eq!(request.txn_type, constants::GET_REVOC_REG_DELTA); } @@ -365,7 +365,7 @@ mod tests { let now = OffsetDateTime::now_utc().unix_timestamp(); let from_as_str = "2019-12-20T19:17:47Z"; let did_url_as_str = format!("did:indy:idunion:Dk1fRRTtNazyMuK2cr64wp/anoncreds/v0/REV_REG_ENTRY/104/revocable/a4e25e54?from={}",from_as_str); - let did_url = DidUrl::from_str(&did_url_as_str).unwrap(); + let did_url = DidUrl::parse(&did_url_as_str).unwrap(); let request = build_request(&did_url, &request_builder).unwrap(); let to = (*(request.req_json).get("operation").unwrap()) @@ -381,7 +381,7 @@ mod tests { fn build_get_revoc_reg_delta_request_without_parameter(request_builder: RequestBuilder) { let now = OffsetDateTime::now_utc().unix_timestamp(); let did_url_as_str = "did:indy:idunion:Dk1fRRTtNazyMuK2cr64wp/anoncreds/v0/REV_REG_DELTA/104/revocable/a4e25e54"; - let did_url = DidUrl::from_str(did_url_as_str).unwrap(); + let did_url = DidUrl::parse(did_url_as_str).unwrap(); let request = build_request(&did_url, &request_builder).unwrap(); let to = (*(request.req_json).get("operation").unwrap()) @@ -405,7 +405,7 @@ mod tests { encoded_schema_name ); - let did_url = DidUrl::from_str(did_url_string.as_str()).unwrap(); + let did_url = DidUrl::parse(did_url_string.as_str()).unwrap(); let request = build_request(&did_url, &request_builder).unwrap(); let schema_name = (*(request.req_json).get("operation").unwrap()) .get("data") From 3e35b953d653345be24d33d1a0b8fe4bb374449b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20W=C3=B6rner?= Date: Mon, 28 Mar 2022 09:34:38 +0200 Subject: [PATCH 062/117] formatting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- libindy_vdr/src/resolver/did.rs | 4 ++-- libindy_vdr/src/resolver/resolver.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libindy_vdr/src/resolver/did.rs b/libindy_vdr/src/resolver/did.rs index 136e08fe..dd33e413 100644 --- a/libindy_vdr/src/resolver/did.rs +++ b/libindy_vdr/src/resolver/did.rs @@ -267,11 +267,11 @@ impl LedgerObject { if let Some(cap) = captures { let object_family_str = cap .get(1) - .ok_or_else(|| err_msg(VdrErrorKind::Resolver, "Invalid DID URL path".to_string()))? + .ok_or_else(|| err_msg(VdrErrorKind::Resolver, "Invalid DID URL path"))? .as_str(); let version = cap .get(2) - .ok_or_else(|| err_msg(VdrErrorKind::Resolver, "Invalid DID URL path".to_string()))? + .ok_or_else(|| err_msg(VdrErrorKind::Resolver, "Invalid DID URL path"))? .as_str(); let object_family = ObjectFamily::parse(object_family_str)?; diff --git a/libindy_vdr/src/resolver/resolver.rs b/libindy_vdr/src/resolver/resolver.rs index c7260317..f7126d5a 100644 --- a/libindy_vdr/src/resolver/resolver.rs +++ b/libindy_vdr/src/resolver/resolver.rs @@ -94,7 +94,7 @@ impl PoolResolver { /// DID (URL) Resolver interface using callbacks for a PoolRunner compliant with did:indy method spec /// The PoolRunnerResolver is used for the FFI. -/// Note that the PoolRunnerResolver does not fetch an ATTRIB txn for legacy endpoint resolution. +/// Note that the PoolRunnerResolver does not fetch an ATTRIB txn for legacy endpoint resolution. /// If you need to use the PoolRunnerResolver, please have a look at the Python wrapper to see how /// legacy endpoints can be resolved. pub struct PoolRunnerResolver<'a> { From 2f4687767874f22e69c17f66fd9418072ad3f669 Mon Sep 17 00:00:00 2001 From: Dominic Woerner Date: Wed, 30 Mar 2022 10:46:23 +0200 Subject: [PATCH 063/117] fix did with query parameters Signed-off-by: Dominic Woerner --- indy-vdr-proxy/src/handlers.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/indy-vdr-proxy/src/handlers.rs b/indy-vdr-proxy/src/handlers.rs index 19233531..b39726a1 100644 --- a/indy-vdr-proxy/src/handlers.rs +++ b/indy-vdr-proxy/src/handlers.rs @@ -480,7 +480,8 @@ pub async fn handle_request( let resolver_regex = Regex::new("/1.0/identifiers/(.*)").unwrap(); - let captures = resolver_regex.captures(req.uri().path()); + let uri = req.uri().to_string(); + let captures = resolver_regex.captures(uri.as_str()); let did = if let Some(cap) = captures { Some(cap.get(1).unwrap().as_str()) } else { From 11e7d5ca56b46701260e90fadd31f490a2746a96 Mon Sep 17 00:00:00 2001 From: Dominic Woerner Date: Wed, 30 Mar 2022 10:08:47 +0200 Subject: [PATCH 064/117] Get attrib with optional seq_no and timestamp Signed-off-by: Dominic Woerner --- indy-vdr-proxy/src/handlers.rs | 18 ++++++++-- libindy_vdr/src/ffi/ledger.rs | 12 ++++--- libindy_vdr/src/ledger/request_builder.rs | 6 +++- libindy_vdr/src/ledger/requests/attrib.rs | 8 +++++ libindy_vdr/src/resolver/resolver.rs | 43 ++++++++++++++++++----- libindy_vdr/src/resolver/utils.rs | 13 ++++++- wrappers/python/indy_vdr/ledger.py | 8 +++++ wrappers/python/indy_vdr/resolver.py | 7 +++- 8 files changed, 98 insertions(+), 17 deletions(-) diff --git a/indy-vdr-proxy/src/handlers.rs b/indy-vdr-proxy/src/handlers.rs index b39726a1..f19c2497 100644 --- a/indy-vdr-proxy/src/handlers.rs +++ b/indy-vdr-proxy/src/handlers.rs @@ -291,7 +291,13 @@ fn get_pool_status(state: Rc>, namespace: &str) -> VdrResult(pool: &T, dest: &str, raw: &str) -> VdrResult { +async fn get_attrib( + pool: &T, + dest: &str, + raw: &str, + seq_no: Option, + timestamp: Option, +) -> VdrResult { let dest = DidValue::from_str(dest)?; let request = pool.get_request_builder().build_get_attrib_request( None, @@ -299,6 +305,8 @@ async fn get_attrib(pool: &T, dest: &str, raw: &str) -> VdrResult( (&Method::GET, "attrib") => { if let (Some(dest), Some(attrib)) = (parts.next(), parts.next()) { // NOTE: 'endpoint' is currently the only supported attribute - get_attrib(&pool, &*dest, &*attrib).await + let seq_no: Option = query_params + .get("seq_no") + .and_then(|seq_no| seq_no.as_str().parse().ok()); + let timestamp: Option = query_params + .get("timestamp") + .and_then(|ts| ts.as_str().parse().ok()); + get_attrib(&pool, &*dest, &*attrib, seq_no, timestamp).await } else { http_status(StatusCode::NOT_FOUND) } diff --git a/libindy_vdr/src/ffi/ledger.rs b/libindy_vdr/src/ffi/ledger.rs index c30fcd57..04cb3cad 100644 --- a/libindy_vdr/src/ffi/ledger.rs +++ b/libindy_vdr/src/ffi/ledger.rs @@ -110,9 +110,11 @@ pub extern "C" fn indy_vdr_build_attrib_request( pub extern "C" fn indy_vdr_build_get_attrib_request( submitter_did: FfiStr, // optional target_did: FfiStr, - raw: FfiStr, // optional - hash: FfiStr, // optional - enc: FfiStr, // optional + raw: FfiStr, // optional + hash: FfiStr, // optional + enc: FfiStr, // optional + seq_no: i32, // optional, -1 for None + timestamp: i64, // optional, -1 for None handle_p: *mut RequestHandle, ) -> ErrorCode { catch_err! { @@ -127,7 +129,9 @@ pub extern "C" fn indy_vdr_build_get_attrib_request( let raw = raw.into_opt_string(); let hash = hash.into_opt_string(); let enc = enc.into_opt_string(); - let req = builder.build_get_attrib_request(identifier.as_ref(), &dest, raw, hash, enc)?; + let seq_no = if seq_no == -1 { None } else { Some(seq_no) }; + let timestamp = if timestamp == -1 { None } else { Some(timestamp as u64) }; + let req = builder.build_get_attrib_request(identifier.as_ref(), &dest, raw, hash, enc, seq_no, timestamp)?; let handle = add_request(req)?; unsafe { *handle_p = handle; diff --git a/libindy_vdr/src/ledger/request_builder.rs b/libindy_vdr/src/ledger/request_builder.rs index 8573d08a..bd4e2a22 100644 --- a/libindy_vdr/src/ledger/request_builder.rs +++ b/libindy_vdr/src/ledger/request_builder.rs @@ -176,6 +176,8 @@ impl RequestBuilder { } /// Build a `GET_ATTRIB` transaction request + /// seq_no and timestamp are only supported for did:indy compliant ledgers + /// Use only one of seq_no and timestamp pub fn build_get_attrib_request( &self, identifier: Option<&DidValue>, @@ -183,8 +185,10 @@ impl RequestBuilder { raw: Option, hash: Option, enc: Option, + seq_no: Option, + timestamp: Option, ) -> VdrResult { - let operation = GetAttribOperation::new(dest.to_short(), raw, hash, enc); + let operation = GetAttribOperation::new(dest.to_short(), raw, hash, enc, seq_no, timestamp); self.build(operation, identifier) } diff --git a/libindy_vdr/src/ledger/requests/attrib.rs b/libindy_vdr/src/ledger/requests/attrib.rs index c057a1d1..42ce7037 100644 --- a/libindy_vdr/src/ledger/requests/attrib.rs +++ b/libindy_vdr/src/ledger/requests/attrib.rs @@ -51,6 +51,10 @@ pub struct GetAttribOperation { pub hash: Option, #[serde(skip_serializing_if = "Option::is_none")] pub enc: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub seq_no: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub timestamp: Option, } impl GetAttribOperation { @@ -59,6 +63,8 @@ impl GetAttribOperation { raw: Option, hash: Option, enc: Option, + seq_no: Option, + timestamp: Option, ) -> GetAttribOperation { GetAttribOperation { _type: Self::get_txn_type().to_string(), @@ -66,6 +72,8 @@ impl GetAttribOperation { raw, hash, enc, + seq_no, + timestamp, } } } diff --git a/libindy_vdr/src/resolver/resolver.rs b/libindy_vdr/src/resolver/resolver.rs index f7126d5a..cd755efc 100644 --- a/libindy_vdr/src/resolver/resolver.rs +++ b/libindy_vdr/src/resolver/resolver.rs @@ -53,23 +53,47 @@ impl PoolResolver { let did = DidUrl::parse(did)?; let (data, metadata) = self._resolve(&did).await?; + let md = if let Metadata::DidDocumentMetadata(md) = metadata { + Some(md) + } else { + None + }; + let diddoc = match data { Result::DidDocument(mut doc) => { // Try to find legacy endpoint using a GET_ATTRIB txn if diddoc_content is none if doc.diddoc_content.is_none() { - doc.endpoint = fetch_legacy_endpoint(&self.pool, &did.id).await.ok(); + let (seq_no, timestamp) = if let Some(md) = &md { + let j_seq_no = &md.node_response["result"]["seqNo"]; + let j_timestamp = &md.node_response["result"]["timestamp"]; + + let mut seq_no = None; + let mut timestamp = None; + + if *j_seq_no != serde_json::Value::Null { + seq_no = j_seq_no.as_u64().map(|v| v as i32); + } + + if *j_timestamp != serde_json::Value::Null { + timestamp = j_timestamp.as_u64(); + // Use timestamp if possible + if timestamp.is_some() { + seq_no = None; + } + } + (seq_no, timestamp) + } else { + (None, None) + }; + doc.endpoint = fetch_legacy_endpoint(&self.pool, &did.id, seq_no, timestamp) + .await + .ok(); } Some(doc.to_value()?) } _ => None, }; - let md = if let Metadata::DidDocumentMetadata(md) = metadata { - Some(md) - } else { - None - }; - let result = ResolutionResult { did_resolution_metadata: None, did_document: diddoc, @@ -83,7 +107,10 @@ impl PoolResolver { async fn _resolve(&self, did_url: &DidUrl) -> VdrResult<(Result, Metadata)> { let builder = self.pool.get_request_builder(); let request = build_request(did_url, &builder)?; - + debug!( + "PoolResolver: Prepared Request for DID {}: {:#?}", + did_url.id, request + ); let ledger_data = handle_request(&self.pool, &request).await?; let namespace = did_url.namespace.clone(); let result = handle_internal_resolution_result(namespace.as_str(), &ledger_data)?; diff --git a/libindy_vdr/src/resolver/utils.rs b/libindy_vdr/src/resolver/utils.rs index 549aa4f3..846b8e26 100644 --- a/libindy_vdr/src/resolver/utils.rs +++ b/libindy_vdr/src/resolver/utils.rs @@ -268,7 +268,12 @@ pub async fn request_transaction( } /// Fetch legacy service endpoint using ATTRIB tx -pub async fn fetch_legacy_endpoint(pool: &T, did: &DidValue) -> VdrResult { +pub async fn fetch_legacy_endpoint( + pool: &T, + did: &DidValue, + seq_no: Option, + timestamp: Option, +) -> VdrResult { let builder = pool.get_request_builder(); let request = builder.build_get_attrib_request( None, @@ -276,7 +281,13 @@ pub async fn fetch_legacy_endpoint(pool: &T, did: &DidValue) -> VdrResu Some(String::from(LEGACY_INDY_SERVICE)), None, None, + seq_no, + timestamp, )?; + debug!( + "Fetching legacy endpoint for {} with request {:#?}", + did, request + ); let ledger_data = handle_request(pool, &request).await?; let (_, _, endpoint_data) = parse_ledger_data(&ledger_data)?; let endpoint_data: Endpoint = serde_json::from_str(endpoint_data.as_str().unwrap()) diff --git a/wrappers/python/indy_vdr/ledger.py b/wrappers/python/indy_vdr/ledger.py index 90f6e9b0..6a8c4603 100644 --- a/wrappers/python/indy_vdr/ledger.py +++ b/wrappers/python/indy_vdr/ledger.py @@ -217,6 +217,8 @@ def build_get_attrib_request( raw: Optional[str], xhash: Optional[str], enc: Optional[str], + seq_no: Optional[int], + timestamp: Optional[int], ) -> str: """ Builds a GET_ATTRIB request. @@ -230,6 +232,8 @@ def build_get_attrib_request( xhash: (Optional) Requested attribute name. raw: (Optional) Requested attribute hash. enc: (Optional) Requested attribute encrypted value. + seq_no: (Optional) Version of NYM as sepecified by txn sequence number + timestamp: (Optional) Version of NYM as sepecified by timestamp """ handle = RequestHandle() @@ -238,6 +242,8 @@ def build_get_attrib_request( raw_p = encode_str(raw) hash_p = encode_str(xhash) enc_p = encode_str(enc) + seq_no_c = c_int32(seq_no if seq_no is not None else -1) + timestamp_c = c_int64(timestamp if timestamp is not None else -1) do_call( "indy_vdr_build_get_attrib_request", did_p, @@ -245,6 +251,8 @@ def build_get_attrib_request( raw_p, hash_p, enc_p, + seq_no_c, + timestamp_c, byref(handle), ) return Request(handle) diff --git a/wrappers/python/indy_vdr/resolver.py b/wrappers/python/indy_vdr/resolver.py index a76db1b0..1c5b4bb0 100644 --- a/wrappers/python/indy_vdr/resolver.py +++ b/wrappers/python/indy_vdr/resolver.py @@ -69,7 +69,12 @@ async def resolve(self, did: str) -> Dict: # associated ATTRIB endpoints. We can't handle in this in libindy_vdr directly. if not diddoc_content: unqualified_did = reply_data["dest"] - req = build_get_attrib_request(None, unqualified_did, "endpoint", None, None) + # Find out if specific version was requested + seq_no = result["didDocumentMetadata"]["nodeResponse"]["result"].get("seqNo", None) + timestamp = result["didDocumentMetadata"]["nodeResponse"]["result"].get("timestamp", None) + if timestamp: + seq_no = None + req = build_get_attrib_request(None, unqualified_did, "endpoint", None, None, seq_no, timestamp) res = await pool.submit_request(req) data = res.get("data", None) if data: From 8d73760113a3992167f1ba75ec1a2d3f5451bb6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20W=C3=B6rner?= Date: Fri, 1 Apr 2022 08:56:14 +0200 Subject: [PATCH 065/117] update local_nodes_pool attrib tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- libindy_vdr/tests/attrib.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/libindy_vdr/tests/attrib.rs b/libindy_vdr/tests/attrib.rs index 697c7b3f..be3d3f87 100644 --- a/libindy_vdr/tests/attrib.rs +++ b/libindy_vdr/tests/attrib.rs @@ -135,6 +135,8 @@ mod builder { Some(ATTRIB_RAW_DATA_FIELD.to_string()), None, None, + None, + None, ) .unwrap(); @@ -159,6 +161,8 @@ mod builder { None, Some(ATTRIB_HASH_DATA.to_string()), None, + None, + None, ) .unwrap(); @@ -183,6 +187,8 @@ mod builder { None, None, Some(ATTRIB_ENC_DATA.to_string()), + None, + None, ) .unwrap(); @@ -208,6 +214,8 @@ mod builder { None, None, Some(ATTRIB_ENC_DATA.to_string()), + None, + None, ) .unwrap(); @@ -257,6 +265,8 @@ mod send_attrib { Some(ATTRIB_RAW_DATA_FIELD.to_string()), None, None, + None, + None, ) .unwrap(); @@ -298,6 +308,8 @@ mod send_attrib { None, Some(ATTRIB_HASH_DATA.to_string()), None, + None, + None, ) .unwrap(); @@ -339,6 +351,8 @@ mod send_attrib { None, None, Some(ATTRIB_ENC_DATA.to_string()), + None, + None, ) .unwrap(); @@ -400,6 +414,8 @@ mod send_attrib { Some(ATTRIB_RAW_DATA_FIELD.to_string()), None, None, + None, + None, ) .unwrap(); From c4ac1d796999dd5348bbe566eaf02c350a8949b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20W=C3=B6rner?= Date: Tue, 29 Mar 2022 15:38:40 +0200 Subject: [PATCH 066/117] self-certification tests. Some uncommented because of indy-utils generate_did dependeny MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- ci/did-indy-pool.dockerfile | 9 +- libindy_vdr/tests/author_agreement.rs | 4 +- libindy_vdr/tests/nym.rs | 190 +++++++++++++++++++++++++- libindy_vdr/tests/utils/crypto.rs | 6 +- libindy_vdr/tests/utils/fixtures.rs | 26 +++- libindy_vdr/tests/utils/helpers.rs | 2 +- 6 files changed, 224 insertions(+), 13 deletions(-) diff --git a/ci/did-indy-pool.dockerfile b/ci/did-indy-pool.dockerfile index 654263fb..bb1770f9 100644 --- a/ci/did-indy-pool.dockerfile +++ b/ci/did-indy-pool.dockerfile @@ -75,8 +75,9 @@ RUN gem install --no-document rake fpm RUN apt-get -y autoremove \ && rm -rf /var/lib/apt/lists/* -# Download, build and install indy-node -RUN git clone --single-branch --branch feature/did-indy-new https://github.com/indicio-tech/indy-node && \ +# Download, build and install indy-node. Will invalidate cache if new HEAD +ADD https://api.github.com/repos/domwoe/indy-node/git/refs/heads/feature/did-indy-new version.json +RUN git clone --single-branch -b feature/did-indy-new https://github.com/domwoe/indy-node.git && \ pip install -e indy-node @@ -140,7 +141,9 @@ GENESIS_DIR = '/var/lib/indy'\n\ BACKUP_DIR = '/var/lib/indy/backup'\n\ PLUGINS_DIR = '/var/lib/indy/plugins'\n\ NODE_INFO_DIR = '/var/lib/indy'\n\ -NETWORK_NAME = 'sandbox'\n"\ +NETWORK_NAME = 'sandbox'\n\ +LOG_LEVEL = 'DEBUG'\n\ +logLevel = 'DEBUG'\n"\ >> /etc/indy/indy_config.py ARG pool_ip=127.0.0.1 diff --git a/libindy_vdr/tests/author_agreement.rs b/libindy_vdr/tests/author_agreement.rs index ace14a9c..94356385 100644 --- a/libindy_vdr/tests/author_agreement.rs +++ b/libindy_vdr/tests/author_agreement.rs @@ -314,7 +314,7 @@ mod author_agreement { use indy_vdr::pool::PreparedRequest; fn _build_nym_request(pool: &TestPool, trustee: &Identity) -> PreparedRequest { - let new_identity = Identity::new(None); + let new_identity = Identity::new(None, None); pool.request_builder() .build_nym_request( @@ -364,7 +364,7 @@ mod author_agreement { let _get_taa_response = helpers::taa::get_taa(&pool, &response, &taa_version); // Try to publish new NYM without accepting TAA - let new_identity = Identity::new(None); + let new_identity = Identity::new(None, None); let mut nym_request = _build_nym_request(&pool, &trustee); let err = helpers::sign_and_send_request(&trustee, &pool, &mut nym_request).unwrap_err(); diff --git a/libindy_vdr/tests/nym.rs b/libindy_vdr/tests/nym.rs index 4f77a312..4d8150e4 100644 --- a/libindy_vdr/tests/nym.rs +++ b/libindy_vdr/tests/nym.rs @@ -188,7 +188,7 @@ mod builder { } #[cfg(test)] -#[cfg(feature = "local_nodes_pool")] +// #[cfg(feature = "local_nodes_pool")] mod send { use super::*; use crate::utils::pool::TestPool; @@ -326,6 +326,190 @@ mod send { assert_eq!(expected_data, serde_json::to_value(data).unwrap()); } + // #[cfg(feature = "local_nodes_pool_did_indy")] + #[rstest] + fn test_pool_send_nym_request_with_version_2_fails( + pool: TestPool, + trustee: Identity, + identity: Identity, + ) { + // Send NYM + let mut nym_request = pool + .request_builder() + .build_nym_request( + &trustee.did, + &identity.did, // Self-cert version 1 identifier + Some(identity.verkey.to_string()), + Some(ALIAS.to_string()), + Some(ROLE.to_string()), + None, + Some(2), // Claim Self-cert version 2 + ) + .unwrap(); + + let _err = helpers::sign_and_send_request(&trustee, &pool, &mut nym_request).unwrap_err(); + } + + #[cfg(feature = "local_nodes_pool_did_indy")] + #[rstest] + fn test_pool_send_nym_request_with_non_self_cert_did_fails( + pool: TestPool, + trustee: Identity, + non_self_cert_identity: Identity, + ) { + // Send NYM + let identity = non_self_cert_identity; + let mut nym_request = pool + .request_builder() + .build_nym_request( + &trustee.did, + &identity.did, // Non self-cert identifier + Some(identity.verkey.to_string()), + Some(ALIAS.to_string()), + Some(ROLE.to_string()), + None, + Some(2), // Claim Self-cert version 2 + ) + .unwrap(); + + let _err = helpers::sign_and_send_request(&trustee, &pool, &mut nym_request).unwrap_err(); + } + + #[rstest] + fn test_pool_send_nym_request_with_non_self_cert_did_works( + pool: TestPool, + trustee: Identity, + non_self_cert_identity: Identity, + ) { + // Send NYM + let identity = non_self_cert_identity; + println!("DID: {}", identity.did); + let mut nym_request = pool + .request_builder() + .build_nym_request( + &trustee.did, + &identity.did, // Non self-cert identifier + Some(identity.verkey.to_string()), + Some(ALIAS.to_string()), + Some(ROLE.to_string()), + None, + None, + ) + .unwrap(); + + let _err = helpers::sign_and_send_request(&trustee, &pool, &mut nym_request).unwrap(); + } + + #[cfg(feature = "local_nodes_pool_did_indy")] + #[rstest] + fn test_pool_send_nym_request_with_version_0_works( + pool: TestPool, + trustee: Identity, + identity: Identity, + ) { + // Send NYM + let mut nym_request = pool + .request_builder() + .build_nym_request( + &trustee.did, + &identity.did, // Self-cert version 1 identifier + Some(identity.verkey.to_string()), + Some(ALIAS.to_string()), + Some(ROLE.to_string()), + None, + Some(0), // Claim Self-cert version 0 + ) + .unwrap(); + + let nym_response = + helpers::sign_and_send_request(&trustee, &pool, &mut nym_request).unwrap(); + + // Get NYM + let get_nym_request = pool + .request_builder() + .build_get_nym_request(None, &identity.did, None, None) + .unwrap(); + + let response = pool + .send_request_with_retries(&get_nym_request, &nym_response) + .unwrap(); + + let expected_data = json!({ + "identifier": &trustee.did, + "dest": &identity.did, + "verkey": &identity.verkey, + "role": role_to_code(Some(String::from(ROLE))).unwrap(), + "version": 0, + }); + + let data: GetNymResultV1 = serde_json::from_str( + helpers::get_response_data(&response) + .unwrap() + .as_str() + .unwrap(), + ) + .unwrap(); + + assert_eq!(expected_data, serde_json::to_value(data).unwrap()); + } + + // FIXME: Uncomment as soon as indy-utils is updated + // #[cfg(feature = "local_nodes_pool_did_indy")] + // #[rstest] + // fn test_pool_send_nym_request_with_version_2_works( + // pool: TestPool, + // trustee: Identity, + // identity_v2: Identity, + // diddoc_content: serde_json::Value, + // ) { + // // Send NYM + // let identity = identity_v2; + // let mut nym_request = pool + // .request_builder() + // .build_nym_request( + // &trustee.did, + // &identity.did, + // Some(identity.verkey.to_string()), + // Some(ALIAS.to_string()), + // Some(ROLE.to_string()), + // Some(&diddoc_content), + // Some(2), + // ) + // .unwrap(); + + // let nym_response = + // helpers::sign_and_send_request(&trustee, &pool, &mut nym_request).unwrap(); + + // // Get NYM + // let get_nym_request = pool + // .request_builder() + // .build_get_nym_request(None, &identity.did, None, None) + // .unwrap(); + + // let response = pool + // .send_request_with_retries(&get_nym_request, &nym_response) + // .unwrap(); + + // let expected_data = json!({ + // "identifier": &trustee.did, + // "dest": &identity.did, + // "verkey": &identity.verkey, + // "role": role_to_code(Some(String::from(ROLE))).unwrap(), + // "diddocContent": &diddoc_content.to_string(), + // "version": 2, + // }); + + // let data: GetNymResultV1 = serde_json::from_str( + // helpers::get_response_data(&response) + // .unwrap() + // .as_str() + // .unwrap(), + // ) + // .unwrap(); + + // assert_eq!(expected_data, serde_json::to_value(data).unwrap()); + // } + #[rstest( role, case("STEWARD"), @@ -339,7 +523,7 @@ mod send { trustee: Identity, role: &str, ) { - let new_identity = Identity::new(None); + let new_identity = Identity::new(None, None); // Send NYM let mut nym_request = pool @@ -492,7 +676,7 @@ mod send { #[rstest] fn test_pool_send_nym_request_for_wrong_signer_role(pool: TestPool) { let identity = helpers::new_ledger_identity(&pool, None); - let new_identity = Identity::new(None); + let new_identity = Identity::new(None, None); // Send NYM let mut nym_request = pool diff --git a/libindy_vdr/tests/utils/crypto.rs b/libindy_vdr/tests/utils/crypto.rs index 1597375f..bd897ddb 100644 --- a/libindy_vdr/tests/utils/crypto.rs +++ b/libindy_vdr/tests/utils/crypto.rs @@ -13,11 +13,13 @@ pub struct Identity { impl Identity { pub fn trustee() -> Identity { - Identity::new(Some(TRUSTEE_SEED)) + Identity::new(Some(TRUSTEE_SEED), None) } - pub fn new(seed: Option<[u8; 32]>) -> Identity { + pub fn new(seed: Option<[u8; 32]>, version: Option) -> Identity { let (short_did, private_key, public_key) = + // generate_did(seed.as_ref().map(|s| &s[..]), version).unwrap(); + // Use commented method, as soon as indy-utils is updated generate_did(seed.as_ref().map(|s| &s[..])).unwrap(); let verkey = public_key.as_base58().unwrap().to_string(); diff --git a/libindy_vdr/tests/utils/fixtures.rs b/libindy_vdr/tests/utils/fixtures.rs index b4bd72b9..e1395685 100644 --- a/libindy_vdr/tests/utils/fixtures.rs +++ b/libindy_vdr/tests/utils/fixtures.rs @@ -1,3 +1,6 @@ +use indy_utils::base58; +use rand::{thread_rng, Rng}; + use crate::utils::constants::*; use crate::utils::crypto::Identity; use crate::utils::pool::TestPool; @@ -8,7 +11,7 @@ use rstest::*; #[fixture] pub fn trustee() -> Identity { - Identity::new(Some(TRUSTEE_SEED)) + Identity::new(Some(TRUSTEE_SEED), None) } #[fixture] @@ -42,8 +45,27 @@ pub fn fq_my_did() -> DidValue { } #[fixture] +// did:sov self-certified DID pub fn identity() -> Identity { - Identity::new(None) + Identity::new(None, None) +} + +// FIXME: Use commented method, as soon as indy-utils is updated +// #[fixture] +// // did:indy self-certified DID +// pub fn identity_v2() -> Identity { +// Identity::new(None, Some(2)) +// } + +#[fixture] +// Generate a random DID without relation to the pubkey +pub fn non_self_cert_identity() -> Identity { + let mut id = Identity::new(None, None); + let mut rng = thread_rng(); + let rand_arr: [u8; 16] = rng.gen(); + let did = base58::encode(rand_arr); + id.did = DidValue(did); + id } #[fixture] diff --git a/libindy_vdr/tests/utils/helpers.rs b/libindy_vdr/tests/utils/helpers.rs index 2a32a4cd..1afae230 100644 --- a/libindy_vdr/tests/utils/helpers.rs +++ b/libindy_vdr/tests/utils/helpers.rs @@ -33,7 +33,7 @@ pub fn get_response_data(response: &str) -> Result { pub fn new_ledger_identity(pool: &TestPool, role: Option) -> Identity { let trustee = Identity::trustee(); - let new_identity = Identity::new(None); + let new_identity = Identity::new(None, None); // Send NYM let mut nym_request = pool From 5e8e3f93d922bb9b80687508382fe3d3fd9bea3f Mon Sep 17 00:00:00 2001 From: Dominic Woerner Date: Tue, 29 Mar 2022 17:12:16 +0200 Subject: [PATCH 067/117] small fixes Signed-off-by: Dominic Woerner --- libindy_vdr/tests/nym.rs | 2 +- libindy_vdr/tests/utils/crypto.rs | 2 +- libindy_vdr/tests/utils/fixtures.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libindy_vdr/tests/nym.rs b/libindy_vdr/tests/nym.rs index 4d8150e4..6f7b26de 100644 --- a/libindy_vdr/tests/nym.rs +++ b/libindy_vdr/tests/nym.rs @@ -326,7 +326,7 @@ mod send { assert_eq!(expected_data, serde_json::to_value(data).unwrap()); } - // #[cfg(feature = "local_nodes_pool_did_indy")] + #[cfg(feature = "local_nodes_pool_did_indy")] #[rstest] fn test_pool_send_nym_request_with_version_2_fails( pool: TestPool, diff --git a/libindy_vdr/tests/utils/crypto.rs b/libindy_vdr/tests/utils/crypto.rs index bd897ddb..d8862a97 100644 --- a/libindy_vdr/tests/utils/crypto.rs +++ b/libindy_vdr/tests/utils/crypto.rs @@ -19,7 +19,7 @@ impl Identity { pub fn new(seed: Option<[u8; 32]>, version: Option) -> Identity { let (short_did, private_key, public_key) = // generate_did(seed.as_ref().map(|s| &s[..]), version).unwrap(); - // Use commented method, as soon as indy-utils is updated + // FIXME: Use commented method, as soon as indy-utils is updated generate_did(seed.as_ref().map(|s| &s[..])).unwrap(); let verkey = public_key.as_base58().unwrap().to_string(); diff --git a/libindy_vdr/tests/utils/fixtures.rs b/libindy_vdr/tests/utils/fixtures.rs index e1395685..0f8e00c8 100644 --- a/libindy_vdr/tests/utils/fixtures.rs +++ b/libindy_vdr/tests/utils/fixtures.rs @@ -50,7 +50,7 @@ pub fn identity() -> Identity { Identity::new(None, None) } -// FIXME: Use commented method, as soon as indy-utils is updated +// FIXME: Uncomment as soon as indy-utils is updated // #[fixture] // // did:indy self-certified DID // pub fn identity_v2() -> Identity { From d9ec0a78d5ae9d38de27863cc5352cf553b9d2c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20W=C3=B6rner?= Date: Fri, 1 Apr 2022 09:25:19 +0200 Subject: [PATCH 068/117] remove debug loglevel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- ci/did-indy-pool.dockerfile | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ci/did-indy-pool.dockerfile b/ci/did-indy-pool.dockerfile index bb1770f9..69e380d7 100644 --- a/ci/did-indy-pool.dockerfile +++ b/ci/did-indy-pool.dockerfile @@ -141,9 +141,7 @@ GENESIS_DIR = '/var/lib/indy'\n\ BACKUP_DIR = '/var/lib/indy/backup'\n\ PLUGINS_DIR = '/var/lib/indy/plugins'\n\ NODE_INFO_DIR = '/var/lib/indy'\n\ -NETWORK_NAME = 'sandbox'\n\ -LOG_LEVEL = 'DEBUG'\n\ -logLevel = 'DEBUG'\n"\ +NETWORK_NAME = 'sandbox'\n"\ >> /etc/indy/indy_config.py ARG pool_ip=127.0.0.1 From 62e752da79ef617e944e49cc477fe8c83ec1786f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20W=C3=B6rner?= Date: Fri, 1 Apr 2022 10:18:47 +0200 Subject: [PATCH 069/117] attempt to harden resolver test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- libindy_vdr/tests/resolver.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/libindy_vdr/tests/resolver.rs b/libindy_vdr/tests/resolver.rs index deffbe84..d9ec9fe6 100644 --- a/libindy_vdr/tests/resolver.rs +++ b/libindy_vdr/tests/resolver.rs @@ -42,9 +42,19 @@ mod send_resolver { ) .unwrap(); - let _nym_response = + let nym_response = helpers::sign_and_send_request(&trustee, &pool, &mut nym_request).unwrap(); + // Get NYM to make sure it was written before it gets resolved + let get_nym_request = pool + .request_builder() + .build_get_nym_request(None, &identity.did, None, None) + .unwrap(); + + let _response = pool + .send_request_with_retries(&get_nym_request, &nym_response) + .unwrap(); + // Resolve DID let resolver = Resolver::new(pool.pool); let qualified_did = format!("did:indy:test:{}", &identity.did); From 22a67058975988c87ee7074f948b3968c09030dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20W=C3=B6rner?= Date: Fri, 1 Apr 2022 10:36:18 +0200 Subject: [PATCH 070/117] fmt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- libindy_vdr/tests/resolver.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libindy_vdr/tests/resolver.rs b/libindy_vdr/tests/resolver.rs index d9ec9fe6..a4672a5e 100644 --- a/libindy_vdr/tests/resolver.rs +++ b/libindy_vdr/tests/resolver.rs @@ -50,7 +50,7 @@ mod send_resolver { .request_builder() .build_get_nym_request(None, &identity.did, None, None) .unwrap(); - + let _response = pool .send_request_with_retries(&get_nym_request, &nym_response) .unwrap(); From cda296e39073511eb89d7e67fb46d57239163020 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20W=C3=B6rner?= Date: Tue, 12 Apr 2022 08:46:14 +0200 Subject: [PATCH 071/117] fix readme for indy-vdr-proxy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dominic Wörner --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a993fcf2..208bd52d 100644 --- a/README.md +++ b/README.md @@ -47,12 +47,12 @@ indy-vdr-proxy -p (-g ) ``` To start the proxy server with the standard configuration of indy ledgers use the following command: -`indy-vdr-proxy -p --multiple-ledgers` +`indy-vdr-proxy -p -- --multiple-ledgers` This will get the ledger configuration from `https://github.com/IDunion/indy-did-networks` A custom ledger configuration can be provided either by specificing a Github repo or a local folder: ``` -indy-vdr-proxy -p --multiple-ledgers -g +indy-vdr-proxy -p -g -- --multiple-ledgers ``` The structure needs to be as follows `/OPTIONAL/pool_transactions_genesis.json`, e.g. `/sovrin/staging/pool_transactions_genesis.json` From 886c62870fe71549db153c95e417075383767209 Mon Sep 17 00:00:00 2001 From: Christian Bormann Date: Tue, 25 Oct 2022 11:47:10 +0200 Subject: [PATCH 072/117] Correctly use the networks folder of the repository Signed-off-by: Christian Bormann --- wrappers/python/demo/test.py | 6 +++--- wrappers/python/indy_vdr/utils.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/wrappers/python/demo/test.py b/wrappers/python/demo/test.py index 942c0f40..cf3a4196 100644 --- a/wrappers/python/demo/test.py +++ b/wrappers/python/demo/test.py @@ -215,12 +215,12 @@ async def basic_test(transactions_path): resolver = Resolver(autopilot=True) - log("Resolve DID did:indy:idunion:APs6Xd2GH8FNwCaXDw6Qm2") - doc = await resolver.resolve("did:indy:idunion:Fhbr2wQrJeB1UcZeFKpG5F") + log("Resolve DID did:indy:idunion:test:APs6Xd2GH8FNwCaXDw6Qm2") + doc = await resolver.resolve("did:indy:idunion:test:Fhbr2wQrJeB1UcZeFKpG5F") log(json.dumps(doc, indent=2)) try: - doc = await resolver.resolve("did:indy:idunion:APs6Xd2GH8FNwCaXDw6Qm2") + doc = await resolver.resolve("did:indy:idunion:test:APs6Xd2GH8FNwCaXDw6Qm2") except VdrError as err: print(err) diff --git a/wrappers/python/indy_vdr/utils.py b/wrappers/python/indy_vdr/utils.py index b900dd3b..b556242a 100644 --- a/wrappers/python/indy_vdr/utils.py +++ b/wrappers/python/indy_vdr/utils.py @@ -73,7 +73,7 @@ def get_genesis_txns_from_did_indy_repo_by_name( main = next(parts, None) sub = next(parts, None) - genesis_file_url = f"{INDY_NETWORKS_GITHUB_RAW_BASE}/{name}/{genesis_filename}" + genesis_file_url = f"{INDY_NETWORKS_GITHUB_RAW_BASE}/networks/{name}/{genesis_filename}" target_local_path = f"{base_dir}/{name}/{genesis_filename}" try: urllib.request.urlretrieve(genesis_file_url, target_local_path) From b5c11038f957ffc911339730ca9debb2d620af6f Mon Sep 17 00:00:00 2001 From: Christian Bormann Date: Tue, 25 Oct 2022 09:29:56 +0200 Subject: [PATCH 073/117] fix verkey expansion Signed-off-by: Christian Bormann --- libindy_vdr/src/resolver/did_document.rs | 98 +++++++++++++++++++++++- 1 file changed, 94 insertions(+), 4 deletions(-) diff --git a/libindy_vdr/src/resolver/did_document.rs b/libindy_vdr/src/resolver/did_document.rs index ebddcad0..6e7eb21c 100644 --- a/libindy_vdr/src/resolver/did_document.rs +++ b/libindy_vdr/src/resolver/did_document.rs @@ -1,5 +1,6 @@ use crate::common::error::prelude::*; use crate::ledger::responses::Endpoint; +use indy_utils::base58; use serde::{Deserialize, Serialize}; use serde_json::{self, Value as SJsonValue}; @@ -173,12 +174,46 @@ fn merge_diddoc(base: &mut SJsonValue, content: &SJsonValue) { } } -fn expand_verkey(id: &str, verkey: &str) -> String { - if let Some(stripped) = verkey.strip_prefix('~') { - format!("{}{}", id, stripped) +// Returns raw verkey in case of conversion errors, otherwise 'default' indy handling +pub fn expand_verkey(id: &str, verkey: &str) -> String { + expand_verkey_indy(id, verkey).unwrap_or(verkey.to_string()) +} + +pub fn expand_verkey_indy(id: &str, verkey: &str) -> VdrResult { + // separate optional crypto_type from verkey part + let (key, key_type) = if verkey.contains(":") { + let vec: Vec<&str> = verkey.split(":").collect(); + match vec.len() { + 2 => { + let key = vec[0]; + let key_type = vec[1]; + if key.len() == 0 || key_type.len() == 0 { + return Err(input_err("Unexpected verkey format")); + } + (key, Some(key_type)) + } + _ => return Err(input_err("Unexpected verkey format")), + } + } else { + (verkey, None) + }; + // Decode parts from base58 and re-encode + let mut result: String; + if key.starts_with("~") && key.len() >= 2 { + let mut decoded = base58::decode(id)?; + let mut keys = key.chars(); + keys.next(); + let mut key_decoded = base58::decode(keys.as_str())?; + decoded.append(&mut key_decoded); + result = base58::encode(decoded); } else { - verkey.to_string() + result = verkey.to_string(); + }; + // Add key type if it was used + if key_type.is_some() && key_type.unwrap() != "" { + result = format!("{}:{}", result, key_type.unwrap()); } + Ok(result) } #[cfg(test)] @@ -187,6 +222,61 @@ mod tests { use super::*; + #[test] + fn expand_verkey_no_type() { + let id = "V4SGRU86Z58d6TV7PBUe6f"; + let verkey = "~CoRER63DVYnWZtK8uAzNbx"; + let expected_verkey = "GJ1SzoWzavQYfNL9XkaJdrQejfztN4XqdsiV4ct3LXKL"; + + let expanded_verkey = expand_verkey(id, verkey); + assert_eq!(expanded_verkey, expected_verkey) + } + + #[test] + fn expand_verkey_key_type() { + let id = "V4SGRU86Z58d6TV7PBUe6f"; + let verkey = "~CoRER63DVYnWZtK8uAzNbx:ed25519"; + let expected_verkey = "GJ1SzoWzavQYfNL9XkaJdrQejfztN4XqdsiV4ct3LXKL:ed25519"; + + let expanded_verkey = expand_verkey(id, verkey); + assert_eq!(expanded_verkey, expected_verkey) + } + + #[test] + fn expand_verkey_key_type_empty_key() { + let id = "V4SGRU86Z58d6TV7PBUe6f"; + let verkey = ":ed25519"; + + let expanded_verkey = expand_verkey(id, verkey); + assert_eq!(expanded_verkey, verkey) + } + + #[test] + fn expand_verkey_key_type_empty_type() { + let id = "V4SGRU86Z58d6TV7PBUe6f"; + let verkey = "~CoRER63DVYnWZtK8uAzNbx:"; + + let expanded_verkey = expand_verkey(id, verkey); + assert_eq!(expanded_verkey, verkey) + } + + #[test] + fn expand_verkey_key_type_nothing() { + let id = "V4SGRU86Z58d6TV7PBUe6f"; + let verkey = ":"; + + let expanded_verkey = expand_verkey(id, verkey); + assert_eq!(expanded_verkey, verkey) + } + + #[test] + fn expand_verkey_invalid() { + let id = "V4SGRU86Z58d6TV7PBUe6f"; + let verkey = "~CoRER63DVYnWZtK8uAzNb0"; + let expanded_verkey = expand_verkey(id, verkey); + assert_eq!(expanded_verkey, verkey) + } + #[test] fn serialze_diddoc_without_diddoc_content() { let doc = DidDocument::new( From bcd9830f65cfe228e85cba9dc7389bdf4743bb4e Mon Sep 17 00:00:00 2001 From: Andrew Whitehead Date: Wed, 11 Jan 2023 20:40:57 -0800 Subject: [PATCH 074/117] clean up features; remove chrono dependency Signed-off-by: Andrew Whitehead --- .github/workflows/build.yml | 12 ++++++------ libindy_vdr/Cargo.toml | 5 ++--- libindy_vdr/tests/nym.rs | 12 ++++++------ libindy_vdr/tests/resolver.rs | 2 +- 4 files changed, 15 insertions(+), 16 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 06e560f5..c9d8cb98 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -54,7 +54,7 @@ jobs: - name: Cargo fmt run: cargo fmt --all -- --check - - if: "runner.os == 'Linux'" + - if: ${{ runner.os == 'Linux' }} name: Pre-install cross run: | cargo install --bins --git https://github.com/rust-embedded/cross --tag v${{ env.CROSS_VERSION }} cross @@ -88,7 +88,7 @@ jobs: docker run -d --name indy_pool -p 9701-9708:9701-9708 --net=indy-sdk-network test_pool - name: Run tests - run: cargo test --manifest-path libindy_vdr/Cargo.toml --features local_nodes_pool,local_nodes_pool_did_indy + run: cargo test --manifest-path libindy_vdr/Cargo.toml --features local_nodes_pool,did_indy build-release: name: Build library @@ -373,7 +373,7 @@ jobs: cross build --release --target ${{matrix.target}} --package indy-vdr - name: Save library - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v2 with: name: library-${{matrix.target}} path: target/${{ matrix.target }}/release/libindy_vdr.so @@ -417,7 +417,7 @@ jobs: if: | (github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && - github.event.inputs.publish == 'true')) + github.event.inputs.publish-binaries == 'true')) steps: - name: Fetch Android libraries @@ -498,14 +498,14 @@ jobs: - name: Test python package # FIXME cross platform test the python package # maybe use the cross docker image? - if: "matrix.architecture != 'linux-aarch64'" + if: ${{ matrix.architecture != 'linux-aarch64' }} shell: sh run: | pip install dist/* python -m demo.test working-directory: wrappers/python - - if: "runner.os == 'Linux'" + - if: ${{ runner.os == 'Linux' }} name: Audit wheel run: | auditwheel show wrappers/python/dist/* | tee auditwheel.log diff --git a/libindy_vdr/Cargo.toml b/libindy_vdr/Cargo.toml index c0dd67d5..4902aa54 100644 --- a/libindy_vdr/Cargo.toml +++ b/libindy_vdr/Cargo.toml @@ -20,13 +20,12 @@ crate-type = ["staticlib", "rlib", "cdylib"] ffi = ["ffi-support", "logger"] logger = ["env_logger", "log"] zmq_vendored = ["zmq/vendored"] +did_indy = [] local_nodes_pool = [] -local_nodes_pool_did_indy = [] rich_schema = ["indy-data-types/rich_schema"] default = ["ffi", "log", "zmq_vendored"] [dependencies] -chrono = "0.4" # This is added so we can lock the version that zmq uses # 0.1.49 is broken for ios targets cmake = { version = "=0.1.48", optional = true } @@ -37,7 +36,7 @@ futures-channel = "0.3" futures-executor = "0.3" futures-util = "0.3" hex = "0.4" -hex-literal = "0.3.4" +hex-literal = "0.3" indy-data-types = "0.5" indy-utils = { version = "0.5", default-features = false, features = ["base64", "ed25519", "hash", "txn_signature"] } once_cell = "1.5" diff --git a/libindy_vdr/tests/nym.rs b/libindy_vdr/tests/nym.rs index 6f7b26de..811ac646 100644 --- a/libindy_vdr/tests/nym.rs +++ b/libindy_vdr/tests/nym.rs @@ -188,7 +188,7 @@ mod builder { } #[cfg(test)] -// #[cfg(feature = "local_nodes_pool")] +#[cfg(feature = "local_nodes_pool")] mod send { use super::*; use crate::utils::pool::TestPool; @@ -272,7 +272,7 @@ mod send { assert_eq!(expected_data, parse_get_nym_response(&response)); } - #[cfg(feature = "local_nodes_pool_did_indy")] + #[cfg(feature = "did_indy")] #[rstest] fn test_pool_send_nym_request_with_diddoc_content( pool: TestPool, @@ -326,7 +326,7 @@ mod send { assert_eq!(expected_data, serde_json::to_value(data).unwrap()); } - #[cfg(feature = "local_nodes_pool_did_indy")] + #[cfg(feature = "did_indy")] #[rstest] fn test_pool_send_nym_request_with_version_2_fails( pool: TestPool, @@ -350,7 +350,7 @@ mod send { let _err = helpers::sign_and_send_request(&trustee, &pool, &mut nym_request).unwrap_err(); } - #[cfg(feature = "local_nodes_pool_did_indy")] + #[cfg(feature = "did_indy")] #[rstest] fn test_pool_send_nym_request_with_non_self_cert_did_fails( pool: TestPool, @@ -400,7 +400,7 @@ mod send { let _err = helpers::sign_and_send_request(&trustee, &pool, &mut nym_request).unwrap(); } - #[cfg(feature = "local_nodes_pool_did_indy")] + #[cfg(feature = "did_indy")] #[rstest] fn test_pool_send_nym_request_with_version_0_works( pool: TestPool, @@ -454,7 +454,7 @@ mod send { } // FIXME: Uncomment as soon as indy-utils is updated - // #[cfg(feature = "local_nodes_pool_did_indy")] + // #[cfg(feature = "did_indy")] // #[rstest] // fn test_pool_send_nym_request_with_version_2_works( // pool: TestPool, diff --git a/libindy_vdr/tests/resolver.rs b/libindy_vdr/tests/resolver.rs index a4672a5e..fb54643f 100644 --- a/libindy_vdr/tests/resolver.rs +++ b/libindy_vdr/tests/resolver.rs @@ -9,7 +9,7 @@ fn empty() { } #[cfg(test)] -#[cfg(feature = "local_nodes_pool_did_indy")] +#[cfg(all(feature = "local_nodes_pool", feature = "did_indy"))] mod send_resolver { use futures_executor::block_on; use indy_vdr::resolver::PoolResolver as Resolver; From 98d9f22032b2e769c58f8aa2ea5791c01634d109 Mon Sep 17 00:00:00 2001 From: Andrew Whitehead Date: Thu, 23 Feb 2023 14:51:26 -0800 Subject: [PATCH 075/117] clean up warnings Signed-off-by: Andrew Whitehead --- libindy_vdr/src/resolver/did.rs | 4 +-- libindy_vdr/src/resolver/did_document.rs | 32 +++++++++--------------- libindy_vdr/src/resolver/utils.rs | 8 +++--- libindy_vdr/tests/utils/crypto.rs | 2 +- 4 files changed, 18 insertions(+), 28 deletions(-) diff --git a/libindy_vdr/src/resolver/did.rs b/libindy_vdr/src/resolver/did.rs index dd33e413..4c7edac0 100644 --- a/libindy_vdr/src/resolver/did.rs +++ b/libindy_vdr/src/resolver/did.rs @@ -368,9 +368,7 @@ impl DidUrl { let did = DidUrl { namespace: cap.get(1).unwrap().as_str().to_string(), id: DidValue::new(cap.get(2).unwrap().as_str(), Option::None), - path: cap - .get(3) - .and_then(|p| Some(decode(p.as_str()).unwrap().to_string())), + path: cap.get(3).map(|p| decode(p.as_str()).unwrap().to_string()), query: query_pairs, url: input.to_string(), }; diff --git a/libindy_vdr/src/resolver/did_document.rs b/libindy_vdr/src/resolver/did_document.rs index 6e7eb21c..a7e7df04 100644 --- a/libindy_vdr/src/resolver/did_document.rs +++ b/libindy_vdr/src/resolver/did_document.rs @@ -176,30 +176,21 @@ fn merge_diddoc(base: &mut SJsonValue, content: &SJsonValue) { // Returns raw verkey in case of conversion errors, otherwise 'default' indy handling pub fn expand_verkey(id: &str, verkey: &str) -> String { - expand_verkey_indy(id, verkey).unwrap_or(verkey.to_string()) + expand_verkey_indy(id, verkey).unwrap_or_else(|_| verkey.to_string()) } pub fn expand_verkey_indy(id: &str, verkey: &str) -> VdrResult { // separate optional crypto_type from verkey part - let (key, key_type) = if verkey.contains(":") { - let vec: Vec<&str> = verkey.split(":").collect(); - match vec.len() { - 2 => { - let key = vec[0]; - let key_type = vec[1]; - if key.len() == 0 || key_type.len() == 0 { - return Err(input_err("Unexpected verkey format")); - } - (key, Some(key_type)) - } - _ => return Err(input_err("Unexpected verkey format")), - } - } else { - (verkey, None) - }; + let mut parts = verkey.split(':'); + let key = parts.next().unwrap_or_default(); + let key_type = parts.next(); + let remain = parts.next().is_some(); + if remain || key.is_empty() || key_type == Some("") { + return Err(input_err("Unexpected verkey format")); + } // Decode parts from base58 and re-encode let mut result: String; - if key.starts_with("~") && key.len() >= 2 { + if key.starts_with('~') && key.len() >= 2 { let mut decoded = base58::decode(id)?; let mut keys = key.chars(); keys.next(); @@ -210,8 +201,9 @@ pub fn expand_verkey_indy(id: &str, verkey: &str) -> VdrResult { result = verkey.to_string(); }; // Add key type if it was used - if key_type.is_some() && key_type.unwrap() != "" { - result = format!("{}:{}", result, key_type.unwrap()); + if let Some(key_type) = key_type { + result.push(':'); + result.push_str(key_type); } Ok(result) } diff --git a/libindy_vdr/src/resolver/utils.rs b/libindy_vdr/src/resolver/utils.rs index 846b8e26..dd4271ec 100644 --- a/libindy_vdr/src/resolver/utils.rs +++ b/libindy_vdr/src/resolver/utils.rs @@ -60,7 +60,7 @@ pub fn build_request(did: &DidUrl, builder: &RequestBuilder) -> VdrResult VdrResult VdrResult, version: Option) -> Identity { + pub fn new(seed: Option<[u8; 32]>, _version: Option) -> Identity { let (short_did, private_key, public_key) = // generate_did(seed.as_ref().map(|s| &s[..]), version).unwrap(); // FIXME: Use commented method, as soon as indy-utils is updated From 0a6e38599e348dfdaed60c39bb60afa1c9369f7d Mon Sep 17 00:00:00 2001 From: Andrew Whitehead Date: Thu, 23 Feb 2023 14:54:44 -0800 Subject: [PATCH 076/117] remove did_indy feature flag Signed-off-by: Andrew Whitehead --- .github/workflows/build.yml | 2 +- libindy_vdr/Cargo.toml | 1 - libindy_vdr/src/ffi/ledger.rs | 31 +------------------------------ libindy_vdr/tests/nym.rs | 4 ---- libindy_vdr/tests/resolver.rs | 2 +- 5 files changed, 3 insertions(+), 37 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c9d8cb98..27dfa463 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -88,7 +88,7 @@ jobs: docker run -d --name indy_pool -p 9701-9708:9701-9708 --net=indy-sdk-network test_pool - name: Run tests - run: cargo test --manifest-path libindy_vdr/Cargo.toml --features local_nodes_pool,did_indy + run: cargo test --manifest-path libindy_vdr/Cargo.toml --features local_nodes_pool build-release: name: Build library diff --git a/libindy_vdr/Cargo.toml b/libindy_vdr/Cargo.toml index 4902aa54..326b5601 100644 --- a/libindy_vdr/Cargo.toml +++ b/libindy_vdr/Cargo.toml @@ -20,7 +20,6 @@ crate-type = ["staticlib", "rlib", "cdylib"] ffi = ["ffi-support", "logger"] logger = ["env_logger", "log"] zmq_vendored = ["zmq/vendored"] -did_indy = [] local_nodes_pool = [] rich_schema = ["indy-data-types/rich_schema"] default = ["ffi", "log", "zmq_vendored"] diff --git a/libindy_vdr/src/ffi/ledger.rs b/libindy_vdr/src/ffi/ledger.rs index 04cb3cad..22935e9d 100644 --- a/libindy_vdr/src/ffi/ledger.rs +++ b/libindy_vdr/src/ffi/ledger.rs @@ -400,35 +400,6 @@ pub extern "C" fn indy_vdr_build_get_validator_info_request( } } -#[cfg(not(feature = "did_indy"))] -#[no_mangle] -pub extern "C" fn indy_vdr_build_nym_request( - submitter_did: FfiStr, - dest: FfiStr, - verkey: FfiStr, // optional - alias: FfiStr, // optional - role: FfiStr, // optional - handle_p: *mut RequestHandle, -) -> ErrorCode { - catch_err! { - trace!("Build NYM request"); - check_useful_c_ptr!(handle_p); - let builder = get_request_builder()?; - let identifier = DidValue::from_str(submitter_did.as_str())?; - let dest = DidValue::from_str(dest.as_str())?; - let verkey = verkey.into_opt_string(); - let alias = alias.into_opt_string(); - let role = role.into_opt_string(); - let req = builder.build_nym_request(&identifier, &dest, verkey, alias, role, None, None)?; - let handle = add_request(req)?; - unsafe { - *handle_p = handle; - } - Ok(ErrorCode::Success) - } -} - -#[cfg(feature = "did_indy")] #[no_mangle] pub extern "C" fn indy_vdr_build_nym_request( submitter_did: FfiStr, @@ -460,7 +431,7 @@ pub extern "C" fn indy_vdr_build_nym_request( let req = builder.build_nym_request(&identifier, &dest, verkey, alias, role, diddoc_content.as_ref(), version)?; let handle = add_request(req)?; unsafe { - *handle_p = *handle; + *handle_p = handle; } Ok(ErrorCode::Success) } diff --git a/libindy_vdr/tests/nym.rs b/libindy_vdr/tests/nym.rs index 811ac646..27789cd4 100644 --- a/libindy_vdr/tests/nym.rs +++ b/libindy_vdr/tests/nym.rs @@ -272,7 +272,6 @@ mod send { assert_eq!(expected_data, parse_get_nym_response(&response)); } - #[cfg(feature = "did_indy")] #[rstest] fn test_pool_send_nym_request_with_diddoc_content( pool: TestPool, @@ -326,7 +325,6 @@ mod send { assert_eq!(expected_data, serde_json::to_value(data).unwrap()); } - #[cfg(feature = "did_indy")] #[rstest] fn test_pool_send_nym_request_with_version_2_fails( pool: TestPool, @@ -350,7 +348,6 @@ mod send { let _err = helpers::sign_and_send_request(&trustee, &pool, &mut nym_request).unwrap_err(); } - #[cfg(feature = "did_indy")] #[rstest] fn test_pool_send_nym_request_with_non_self_cert_did_fails( pool: TestPool, @@ -400,7 +397,6 @@ mod send { let _err = helpers::sign_and_send_request(&trustee, &pool, &mut nym_request).unwrap(); } - #[cfg(feature = "did_indy")] #[rstest] fn test_pool_send_nym_request_with_version_0_works( pool: TestPool, diff --git a/libindy_vdr/tests/resolver.rs b/libindy_vdr/tests/resolver.rs index fb54643f..786cfd1b 100644 --- a/libindy_vdr/tests/resolver.rs +++ b/libindy_vdr/tests/resolver.rs @@ -9,7 +9,7 @@ fn empty() { } #[cfg(test)] -#[cfg(all(feature = "local_nodes_pool", feature = "did_indy"))] +#[cfg(feature = "local_nodes_pool")] mod send_resolver { use futures_executor::block_on; use indy_vdr::resolver::PoolResolver as Resolver; From 26d7564aca9efee35fcc3dc58987923e29a335eb Mon Sep 17 00:00:00 2001 From: Andrew Whitehead Date: Thu, 23 Feb 2023 14:57:05 -0800 Subject: [PATCH 077/117] adjust header files for indy_vdr_build_nym_request parameters Signed-off-by: Andrew Whitehead --- wrappers/golang/vdr/libindy_vdr.h | 1 + .../javascript/indy-vdr-react-native/cpp/include/libindy_vdr.h | 2 ++ 2 files changed, 3 insertions(+) diff --git a/wrappers/golang/vdr/libindy_vdr.h b/wrappers/golang/vdr/libindy_vdr.h index 7397e013..6350b875 100644 --- a/wrappers/golang/vdr/libindy_vdr.h +++ b/wrappers/golang/vdr/libindy_vdr.h @@ -272,6 +272,7 @@ ErrorCode indy_vdr_build_nym_request(FfiStr submitter_did, FfiStr alias, FfiStr role, FfiStr diddoc_content, + int32_t version, RequestHandle *handle_p); ErrorCode indy_vdr_build_revoc_reg_def_request(FfiStr submitter_did, diff --git a/wrappers/javascript/indy-vdr-react-native/cpp/include/libindy_vdr.h b/wrappers/javascript/indy-vdr-react-native/cpp/include/libindy_vdr.h index 65bf7725..7bdc47e1 100644 --- a/wrappers/javascript/indy-vdr-react-native/cpp/include/libindy_vdr.h +++ b/wrappers/javascript/indy-vdr-react-native/cpp/include/libindy_vdr.h @@ -275,6 +275,8 @@ ErrorCode indy_vdr_build_nym_request(FfiStr submitter_did, FfiStr verkey, FfiStr alias, FfiStr role, + FfiStr diddoc_content, + int32_t version, RequestHandle *handle_p); ErrorCode indy_vdr_build_revoc_reg_def_request(FfiStr submitter_did, From 6357a556401b3818a1dd30db990abce2f0950d2b Mon Sep 17 00:00:00 2001 From: Andrew Whitehead Date: Thu, 23 Feb 2023 15:01:56 -0800 Subject: [PATCH 078/117] python wrapper cleanups for resolver Signed-off-by: Andrew Whitehead --- wrappers/python/demo/test.py | 22 ++++------- wrappers/python/indy_vdr/resolver.py | 55 +++++++++++++++++----------- 2 files changed, 41 insertions(+), 36 deletions(-) diff --git a/wrappers/python/demo/test.py b/wrappers/python/demo/test.py index cf3a4196..bd1a4c1b 100644 --- a/wrappers/python/demo/test.py +++ b/wrappers/python/demo/test.py @@ -194,25 +194,15 @@ async def basic_test(transactions_path): ) log("Pool Upgrade request:", req.body) - log("Resolve DID did:indy:sovrin:XvSeT51zDWVTXatLWPknWb") - resolver = Resolver(pool.handle) - doc = await resolver.resolve("did:indy:sovrin:XvSeT51zDWVTXatLWPknWb") - - ################################################################################### - ### ### - ### DID Resolution ### - ### ### - ################################################################################### - - ## DID resolver can be initialized with a dict containing namespaces and pool instances + # --- DID Resolution --- + # The DID resolver can be initialized with a dict containing namespaces and pool instances: # pool_map = await open_pools(ledgers=["idunion", "sovrin:builder"]) # resolver = Resolver(pool_map) - ## In addtion the the DID resolver can be started with autopilot = True. - ## Then it will try to fetch a genesis file from the did indy networks Github repo - ## for the given did:indy namespace - + # In addition, the the DID resolver can be started with autopilot = True. + # Then it will try to fetch a genesis file from the did indy networks Github repo + # for the given did:indy namespace. resolver = Resolver(autopilot=True) log("Resolve DID did:indy:idunion:test:APs6Xd2GH8FNwCaXDw6Qm2") @@ -224,6 +214,8 @@ async def basic_test(transactions_path): except VdrError as err: print(err) + # --- Rich Schema --- + # req = build_rich_schema_request( # None, "did:sov:some_hash", '{"some": 1}', "test", "version", "sch", "1.0.0" # ) diff --git a/wrappers/python/indy_vdr/resolver.py b/wrappers/python/indy_vdr/resolver.py index 1c5b4bb0..17d21da5 100644 --- a/wrappers/python/indy_vdr/resolver.py +++ b/wrappers/python/indy_vdr/resolver.py @@ -61,20 +61,28 @@ async def resolve(self, did: str) -> Dict: ) pool_handle = getattr(pool, "handle") result = json.loads(await bindings.resolve(pool_handle, did)) - - reply_data = json.loads(result["didDocumentMetadata"]["nodeResponse"]["result"]["data"]) + + reply_data = json.loads( + result["didDocumentMetadata"]["nodeResponse"]["result"]["data"] + ) diddoc_content = reply_data.get("diddocContent", None) # Handle legacy case, where diddocContent is not present and we want to check for - # associated ATTRIB endpoints. We can't handle in this in libindy_vdr directly. + # associated ATTRIB endpoints. We can't handle in this in libindy_vdr directly. if not diddoc_content: unqualified_did = reply_data["dest"] # Find out if specific version was requested - seq_no = result["didDocumentMetadata"]["nodeResponse"]["result"].get("seqNo", None) - timestamp = result["didDocumentMetadata"]["nodeResponse"]["result"].get("timestamp", None) + seq_no = result["didDocumentMetadata"]["nodeResponse"]["result"].get( + "seqNo", None + ) + timestamp = result["didDocumentMetadata"]["nodeResponse"]["result"].get( + "timestamp", None + ) if timestamp: seq_no = None - req = build_get_attrib_request(None, unqualified_did, "endpoint", None, None, seq_no, timestamp) + req = build_get_attrib_request( + None, unqualified_did, "endpoint", None, None, seq_no, timestamp + ) res = await pool.submit_request(req) data = res.get("data", None) if data: @@ -86,24 +94,29 @@ async def resolve(self, did: str) -> Dict: for (service_type, service_endpoint) in endpoints.items(): if service_type == "endpoint": - services.append({ - "id": f"did:indy:{namespace}:{unqualified_did}#did-communication", - "type": "did-communication", - "recipientKeys": [f"did:indy:{namespace}:{unqualified_did}#verkey"] , - "routingKeys": [], - "priority": 0 - }) - + services.append( + { + "id": f"did:indy:{namespace}:{unqualified_did}#did-communication", + "type": "did-communication", + "recipientKeys": [ + f"did:indy:{namespace}:{unqualified_did}#verkey" + ], + "routingKeys": [], + "priority": 0, + } + ) + else: - services.append({ - "id": f"did:indy:{namespace}:{unqualified_did}#{service_type}", - "type": service_type, - "serviceEndpoint": service_endpoint + services.append( + { + "id": f"did:indy:{namespace}:{unqualified_did}#{service_type}", + "type": service_type, + "serviceEndpoint": service_endpoint, + } + ) + result["didDocument"]["services"] = services - }) - result["didDocument"]["services"] = services; - return result async def dereference(self, did_url: str) -> Dict: From d632f29f4c73eb8248629bc39993573a84857bf8 Mon Sep 17 00:00:00 2001 From: Andrew Whitehead Date: Thu, 23 Feb 2023 15:40:12 -0800 Subject: [PATCH 079/117] fix merge issues Signed-off-by: Andrew Whitehead --- .github/workflows/build.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 27dfa463..e105bb2e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -6,9 +6,8 @@ env: on: push: - branches: [main, did-indy] pull_request: - branches: [main, did-indy] + branches: [main] release: types: [created] workflow_dispatch: @@ -373,7 +372,7 @@ jobs: cross build --release --target ${{matrix.target}} --package indy-vdr - name: Save library - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: library-${{matrix.target}} path: target/${{ matrix.target }}/release/libindy_vdr.so From 04faad5c819830dd545d0079bc0f451daea20f15 Mon Sep 17 00:00:00 2001 From: Andrew Whitehead Date: Thu, 23 Feb 2023 16:57:03 -0800 Subject: [PATCH 080/117] fix formatting, warnings on indy-vdr-proxy Signed-off-by: Andrew Whitehead --- indy-vdr-proxy/src/app.rs | 6 ++-- indy-vdr-proxy/src/handlers.rs | 62 ++++++++++++++-------------------- indy-vdr-proxy/src/main.rs | 40 ++++++++++------------ indy-vdr-proxy/src/utils.rs | 2 +- 4 files changed, 46 insertions(+), 64 deletions(-) diff --git a/indy-vdr-proxy/src/app.rs b/indy-vdr-proxy/src/app.rs index 16143c8b..e8f8748c 100644 --- a/indy-vdr-proxy/src/app.rs +++ b/indy-vdr-proxy/src/app.rs @@ -92,10 +92,8 @@ pub fn load_config() -> Result { if matches.occurrences_of("host") > 0 { return Err("Cannot specify both host and socket".to_owned()); } - } else { - if matches.occurrences_of("port") == 0 { - return Err("Port number or socket must be specified".to_owned()); - } + } else if matches.occurrences_of("port") == 0 { + return Err("Port number or socket must be specified".to_owned()); } #[cfg(unix)] diff --git a/indy-vdr-proxy/src/handlers.rs b/indy-vdr-proxy/src/handlers.rs index f19c2497..cda98522 100644 --- a/indy-vdr-proxy/src/handlers.rs +++ b/indy-vdr-proxy/src/handlers.rs @@ -2,7 +2,6 @@ extern crate percent_encoding; use std::cell::RefCell; use std::collections::HashMap; -use std::convert::TryFrom; use std::rc::Rc; use std::time::UNIX_EPOCH; @@ -89,7 +88,7 @@ fn format_json_reply(message: String, pretty: bool) -> String { } pub fn escape_html(val: &str) -> String { - val.replace("&", "&").replace("<", "<") + val.replace('&', "&").replace('<', "<") } fn html_template(main: String, timing: Option) -> String { @@ -265,10 +264,7 @@ fn get_pool_status(state: Rc>, namespace: &str) -> VdrResult( ResponseFormat::Html } else if query == Some("raw") { ResponseFormat::Raw - } else { - if let Some(Ok(accept)) = req.headers().get("accept").map(|h| h.to_str()) { - let accept = accept.to_ascii_lowercase(); - let html_pos = accept.find("text/html"); - let json_pos = accept.find("/json"); - match (html_pos, json_pos) { - (Some(h), Some(j)) => { - if h < j { - ResponseFormat::Html - } else { - ResponseFormat::Raw - } + } else if let Some(Ok(accept)) = req.headers().get("accept").map(|h| h.to_str()) { + let accept = accept.to_ascii_lowercase(); + let html_pos = accept.find("text/html"); + let json_pos = accept.find("/json"); + match (html_pos, json_pos) { + (Some(h), Some(j)) => { + if h < j { + ResponseFormat::Html + } else { + ResponseFormat::Raw } - (Some(_), None) => ResponseFormat::Html, - _ => ResponseFormat::Raw, } - } else { - ResponseFormat::Raw + (Some(_), None) => ResponseFormat::Html, + _ => ResponseFormat::Raw, } + } else { + ResponseFormat::Raw }; let mut namespace = if state.borrow().is_multiple { parts.next().unwrap_or_else(|| "".to_owned()) } else { let pool_states = &state.borrow().pool_states; - let (ns, _) = pool_states.into_iter().next().unwrap(); + let (ns, _) = pool_states.iter().next().unwrap(); ns.to_owned() }; let fst = parts.next().unwrap_or_else(|| "".to_owned()); @@ -490,11 +484,7 @@ pub async fn handle_request( let uri = req.uri().to_string(); let captures = resolver_regex.captures(uri.as_str()); - let did = if let Some(cap) = captures { - Some(cap.get(1).unwrap().as_str()) - } else { - None - }; + let did = captures.map(|cap| cap.get(1).unwrap().as_str()); if did.is_some() { namespace = match DidUrl::parse(did.unwrap()) { @@ -503,13 +493,11 @@ pub async fn handle_request( return format_result(http_status(StatusCode::BAD_REQUEST), format); } }; - } else { - if (req_method, fst.is_empty()) == (&Method::GET, true) { - if namespace == "" { - return format_result(get_ledgers(state.clone()), format); - } else { - return format_result(get_pool_status(state.clone(), &namespace), format); - } + } else if (req_method, fst.is_empty()) == (&Method::GET, true) { + if namespace.is_empty() { + return format_result(get_ledgers(state.clone()), format); + } else { + return format_result(get_pool_status(state.clone(), &namespace), format); } } @@ -535,8 +523,8 @@ pub async fn handle_request( let result = if did.is_some() { let did = did.unwrap(); let resolver = Resolver::new(pool); - // is DID Url - if did.find("/").is_some() { + // is DID Url + if did.find('/').is_some() { match resolver.dereference(did).await { Ok(result) => Ok(ResponseType::Resolver(result)), Err(err) => http_status_msg(StatusCode::BAD_REQUEST, err.to_string()), diff --git a/indy-vdr-proxy/src/main.rs b/indy-vdr-proxy/src/main.rs index 5c2abf9d..744eee6b 100644 --- a/indy-vdr-proxy/src/main.rs +++ b/indy-vdr-proxy/src/main.rs @@ -1,3 +1,5 @@ +#![allow(clippy::await_holding_refcell_ref)] // using a single-threaded executor + #[macro_use] extern crate serde_json; @@ -49,13 +51,13 @@ fn main() { env_logger::init(); - let mut rt = tokio::runtime::Builder::new_multi_thread() + let rt = tokio::runtime::Builder::new_multi_thread() .enable_all() .build() .expect("build runtime"); let local = tokio::task::LocalSet::new(); - if let Err(err) = local.block_on(&mut rt, init_server(config)) { + if let Err(err) = local.block_on(&rt, init_server(config)) { eprintln!("{}", err); exit(1); } @@ -105,7 +107,7 @@ async fn init_app_state( let mut pool_states: HashMap = HashMap::new(); let state = if !is_multiple { - let genesis = genesis.unwrap_or(String::from("genesis.txn")); + let genesis = genesis.unwrap_or_else(|| String::from("genesis.txn")); let transactions = if genesis.starts_with("http:") || genesis.starts_with("https:") { fetch_transactions(genesis).await? } else { @@ -122,7 +124,7 @@ async fn init_app_state( pool_states, } } else { - let genesis = genesis.unwrap_or(String::from(INDY_NETWORKS_GITHUB)); + let genesis = genesis.unwrap_or_else(|| String::from(INDY_NETWORKS_GITHUB)); let pool_states = if genesis.starts_with("https:") { let repo_url = genesis; let mut just_cloned = false; @@ -153,7 +155,7 @@ async fn init_app_state( let path = repo.path().parent().unwrap().to_owned(); - init_pool_state_from_folder_structure(PathBuf::from(path))? + init_pool_state_from_folder_structure(path)? } else { init_pool_state_from_folder_structure(PathBuf::from(genesis))? }; @@ -174,28 +176,25 @@ async fn run_pools(state: Rc>, init_refresh: bool, interval_re let pool = Some(pool.clone()); PoolState { pool: pool.clone(), - last_refresh: pool_state.last_refresh.clone(), - transactions: pool_state.transactions.clone() + last_refresh: pool_state.last_refresh, + transactions: pool_state.transactions.clone(), } } Err(err) => { eprintln!("Error initializing pool {} with error : {}", namespace, err); PoolState { pool: None, - last_refresh: pool_state.last_refresh.clone(), - transactions: pool_state.transactions.clone() + last_refresh: pool_state.last_refresh, + transactions: pool_state.transactions.clone(), } } }; pool_states.insert(namespace.to_owned(), pool_state); - } state.borrow_mut().pool_states = pool_states; - - let shutdown = shutdown_signal().fuse().shared(); if interval_refresh > 0 { loop { @@ -227,9 +226,7 @@ async fn shutdown_signal() { let mut term = tokio::signal::unix::signal(SignalKind::terminate()) .expect("failed to install SIGTERM handler"); select! { - _ = term.recv() => { - () - } + _ = term.recv() => {} ctlc = tokio::signal::ctrl_c() => { ctlc.expect("failed to install Ctrl-C handler") } @@ -269,7 +266,7 @@ async fn refresh_pools( let pool_states = &state.borrow().pool_states; for (namespace, pool_state) in pool_states { if let Some(pool) = &pool_state.pool { - let upd_pool = match refresh_pool(state.clone(), &namespace, &pool, delay_mins).await { + let upd_pool = match refresh_pool(state.clone(), namespace, pool, delay_mins).await { Ok(p) => p, Err(err) => { eprintln!( @@ -280,7 +277,7 @@ async fn refresh_pools( } }; let upd_pool_state = PoolState { - pool: upd_pool.or(Some(pool.clone())), + pool: upd_pool.or_else(|| Some(pool.clone())), last_refresh: Some(SystemTime::now()), transactions: pool_state.transactions.clone(), }; @@ -335,10 +332,9 @@ async fn init_server(config: app::Config) -> Result<(), String> { #[cfg(unix)] if let Some(socket) = &config.socket { - fs::remove_file(socket) - .map_err(|err| format!("Error removing socket: {}", err.to_string()))?; + fs::remove_file(socket).map_err(|err| format!("Error removing socket: {}", err))?; let uc: UnixConnector = tokio::net::UnixListener::bind(socket) - .map_err(|err| format!("Error binding UNIX socket: {}", err.to_string()))? + .map_err(|err| format!("Error binding UNIX socket: {}", err))? .into(); return run_server( Server::builder(uc), @@ -356,8 +352,8 @@ async fn init_server(config: app::Config) -> Result<(), String> { .parse::() .map_err(|_| "Error parsing host IP")?; let addr = (ip, config.port.unwrap()).into(); - let builder = Server::try_bind(&addr) - .map_err(|err| format!("Error binding TCP socket: {}", err.to_string()))?; + let builder = + Server::try_bind(&addr).map_err(|err| format!("Error binding TCP socket: {}", err))?; run_server(builder, state, format!("http://{}", addr), config).await } diff --git a/indy-vdr-proxy/src/utils.rs b/indy-vdr-proxy/src/utils.rs index d0c1a5c6..1b1c8642 100644 --- a/indy-vdr-proxy/src/utils.rs +++ b/indy-vdr-proxy/src/utils.rs @@ -35,7 +35,7 @@ pub fn init_pool_state_from_folder_structure( for entry in entries { let entry = entry.unwrap(); // filter hidden directories starting with "." and files - if !entry.file_name().to_str().unwrap().starts_with(".") + if !entry.file_name().to_str().unwrap().starts_with('.') && entry.metadata().unwrap().is_dir() { let namespace = entry.path().file_name().unwrap().to_owned(); From f21a882b07dd2b66eb84b10bc15ad6b2aad3bc5a Mon Sep 17 00:00:00 2001 From: Andrew Whitehead Date: Fri, 24 Feb 2023 15:35:54 -0800 Subject: [PATCH 081/117] update JS wrapper calls to indy_vdr_build_nym_request Signed-off-by: Andrew Whitehead --- .../indy-vdr-nodejs/src/NodeJSIndyVdr.ts | 14 ++++++++++++-- .../indy-vdr-nodejs/src/library/NativeBindings.ts | 2 ++ .../indy-vdr-nodejs/src/library/bindings.ts | 2 +- .../indy-vdr-shared/src/builder/NymRequest.ts | 2 ++ 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/wrappers/javascript/indy-vdr-nodejs/src/NodeJSIndyVdr.ts b/wrappers/javascript/indy-vdr-nodejs/src/NodeJSIndyVdr.ts index c5844bc5..65de5f8f 100644 --- a/wrappers/javascript/indy-vdr-nodejs/src/NodeJSIndyVdr.ts +++ b/wrappers/javascript/indy-vdr-nodejs/src/NodeJSIndyVdr.ts @@ -358,10 +358,20 @@ export class NodeJSIndyVdr implements IndyVdr { public buildNymRequest(options: NymRequestOptions): number { const requestHandle = allocateHandle() - const { dest, submitterDid, alias, role, verkey } = serializeArguments(options) + const { dest, submitterDid, alias, role, verkey, diddocContent } = serializeArguments(options) + const version = options.version || -1 this.handleError( - this.nativeIndyVdr.indy_vdr_build_nym_request(submitterDid, dest, verkey, alias, role, requestHandle) + this.nativeIndyVdr.indy_vdr_build_nym_request( + submitterDid, + dest, + verkey, + alias, + role, + diddocContent, + version, + requestHandle + ) ) return handleReturnPointer(requestHandle) diff --git a/wrappers/javascript/indy-vdr-nodejs/src/library/NativeBindings.ts b/wrappers/javascript/indy-vdr-nodejs/src/library/NativeBindings.ts index 7241037c..98fc4bf0 100644 --- a/wrappers/javascript/indy-vdr-nodejs/src/library/NativeBindings.ts +++ b/wrappers/javascript/indy-vdr-nodejs/src/library/NativeBindings.ts @@ -79,6 +79,8 @@ export interface NativeMethods { arg2: string, arg3: string, arg4: string, + arg5: string, + arg6: number, requestHandlePtr: Buffer ) => number indy_vdr_pool_create: (arg0: string, poolHandlePtr: Buffer) => number diff --git a/wrappers/javascript/indy-vdr-nodejs/src/library/bindings.ts b/wrappers/javascript/indy-vdr-nodejs/src/library/bindings.ts index 1d8aed90..4914066c 100644 --- a/wrappers/javascript/indy-vdr-nodejs/src/library/bindings.ts +++ b/wrappers/javascript/indy-vdr-nodejs/src/library/bindings.ts @@ -67,7 +67,7 @@ export const nativeBindings = { indy_vdr_build_get_validator_info_request: [FFI_ERROR_CODE, [FFI_STRING, FFI_REQUEST_HANDLE_POINTER]], indy_vdr_build_nym_request: [ FFI_ERROR_CODE, - [FFI_STRING, FFI_STRING, FFI_STRING, FFI_STRING, FFI_STRING, FFI_REQUEST_HANDLE_POINTER], + [FFI_STRING, FFI_STRING, FFI_STRING, FFI_STRING, FFI_STRING, FFI_STRING, FFI_INT32, FFI_REQUEST_HANDLE_POINTER], ], indy_vdr_build_revoc_reg_def_request: [FFI_ERROR_CODE, [FFI_STRING, FFI_STRING, FFI_REQUEST_HANDLE_POINTER]], indy_vdr_build_revoc_reg_entry_request: [ diff --git a/wrappers/javascript/indy-vdr-shared/src/builder/NymRequest.ts b/wrappers/javascript/indy-vdr-shared/src/builder/NymRequest.ts index b405f801..e633304c 100644 --- a/wrappers/javascript/indy-vdr-shared/src/builder/NymRequest.ts +++ b/wrappers/javascript/indy-vdr-shared/src/builder/NymRequest.ts @@ -8,6 +8,8 @@ export type NymRequestOptions = { verkey?: string alias?: string role?: 'STEWARD' | 'TRUSTEE' | 'ENDORSER' | 'NETWORK_MONITOR' + diddocContent?: string + version?: number } interface NymResultTxn extends WriteRequestResultTxnBase { From 9361851272579bcf0c04da9ea27ecf95168ac8fc Mon Sep 17 00:00:00 2001 From: Andrew Whitehead Date: Tue, 28 Feb 2023 12:59:12 -0800 Subject: [PATCH 082/117] use percent-encoding instead of urlencoding (already in dependencies); avoid unwrap in DidUrl::parse Signed-off-by: Andrew Whitehead --- libindy_vdr/Cargo.toml | 2 +- libindy_vdr/src/resolver/did.rs | 47 ++++++++++++++++++++----------- libindy_vdr/src/resolver/utils.rs | 5 ++-- 3 files changed, 34 insertions(+), 20 deletions(-) diff --git a/libindy_vdr/Cargo.toml b/libindy_vdr/Cargo.toml index 326b5601..0916e6ca 100644 --- a/libindy_vdr/Cargo.toml +++ b/libindy_vdr/Cargo.toml @@ -40,6 +40,7 @@ indy-data-types = "0.5" indy-utils = { version = "0.5", default-features = false, features = ["base64", "ed25519", "hash", "txn_signature"] } once_cell = "1.5" log = { version = "0.4", optional = true } +percent-encoding = "2.2" pin-utils = "0.1" rand = "0.8" regex = "1.3" @@ -50,7 +51,6 @@ sha3 = "0.10" thiserror = "1.0" time = { version = "0.3.7", features = ["parsing"] } url = "2.2.2" -urlencoding = "2.1.0" zmq = "0.9" [dependencies.ursa] diff --git a/libindy_vdr/src/resolver/did.rs b/libindy_vdr/src/resolver/did.rs index 4c7edac0..92a73777 100644 --- a/libindy_vdr/src/resolver/did.rs +++ b/libindy_vdr/src/resolver/did.rs @@ -1,10 +1,12 @@ -use crate::common::error::prelude::*; -use crate::utils::did::DidValue; +use std::collections::HashMap; + +use once_cell::sync::Lazy; +use percent_encoding::percent_decode; use regex::Regex; use url::Url; -use urlencoding::decode; -use std::collections::HashMap; +use crate::common::error::prelude::*; +use crate::utils::did::DidValue; // Patterns to build regular expressions for ledger objects static DID_INDY_PREFIX: &str = "did:indy"; @@ -22,6 +24,17 @@ static CLIENT_DEFINED_NAME_PATTERN: &str = "([\\w -]*)"; static SEQ_NO_PATTERN: &str = "(\\d*)"; static VERSION_PATTERN: &str = "((\\d*\\.){1,2}\\d*)"; +static DID_REGEX: Lazy = Lazy::new(|| { + Regex::new( + format!( + r"{}:{}:{}([^\?]+)?(?:\?(.+))?$", + DID_INDY_PREFIX, NAMESPACE_PATTERN, INDY_UNQUALIFIED_DID_PATTERN + ) + .as_str(), + ) + .unwrap() +}); + #[derive(Debug, PartialEq, Eq, Hash)] pub enum QueryParameter { VersionId, @@ -342,15 +355,6 @@ pub struct DidUrl { impl DidUrl { pub fn parse(input: &str) -> VdrResult { - let did_regex = Regex::new( - format!( - r"{}:{}:{}([^\?]+)?(?:\?(.+))?$", - DID_INDY_PREFIX, NAMESPACE_PATTERN, INDY_UNQUALIFIED_DID_PATTERN - ) - .as_str(), - ) - .unwrap(); - let url = Url::parse(input) .map_err(|_| err_msg(VdrErrorKind::Resolver, "Could not parse DID Url"))?; let mut query_pairs: HashMap = HashMap::new(); @@ -362,13 +366,22 @@ impl DidUrl { query_pairs.insert(qp, v.to_string()); } - let captures = did_regex.captures(input.trim()); + let captures = DID_REGEX.captures(input.trim()); match captures { Some(cap) => { + let path = cap + .get(3) + .map(|p| { + percent_decode(p.as_str().as_bytes()) + .decode_utf8() + .map(|p| p.into_owned()) + }) + .transpose() + .map_err(|_| err_msg(VdrErrorKind::Resolver, "Invalid DID Url path"))?; let did = DidUrl { - namespace: cap.get(1).unwrap().as_str().to_string(), - id: DidValue::new(cap.get(2).unwrap().as_str(), Option::None), - path: cap.get(3).map(|p| decode(p.as_str()).unwrap().to_string()), + namespace: cap[1].to_string(), + id: DidValue::new(&cap[2], Option::None), + path, query: query_pairs, url: input.to_string(), }; diff --git a/libindy_vdr/src/resolver/utils.rs b/libindy_vdr/src/resolver/utils.rs index dd4271ec..931492a0 100644 --- a/libindy_vdr/src/resolver/utils.rs +++ b/libindy_vdr/src/resolver/utils.rs @@ -298,7 +298,7 @@ pub async fn fetch_legacy_endpoint( #[cfg(test)] mod tests { - use urlencoding::encode; + use percent_encoding::percent_encode; use time::format_description::well_known::Rfc3339; use time::OffsetDateTime; @@ -410,7 +410,8 @@ mod tests { #[rstest] fn build_get_schema_request_with_whitespace(request_builder: RequestBuilder) { let name = "My Schema"; - let encoded_schema_name = encode(name).to_string(); + let encoded_schema_name = + percent_encode(name.as_bytes(), percent_encoding::NON_ALPHANUMERIC).to_string(); let did_url_string = format!( "did:indy:idunion:Dk1fRRTtNazyMuK2cr64wp/anoncreds/v0/SCHEMA/{}/1.0", encoded_schema_name From d790febdd8402ef82d13287453959f92bffac218 Mon Sep 17 00:00:00 2001 From: Christian Bormann Date: Wed, 1 Mar 2023 23:27:52 +0100 Subject: [PATCH 083/117] quick fix for ffi bindings Signed-off-by: Christian Bormann --- libindy_vdr/include/libindy_vdr.h | 95 +++++++++++++++++++ .../indy-vdr-nodejs/src/NodeJSIndyVdr.ts | 21 +++- .../src/library/NativeBindings.ts | 10 +- .../indy-vdr-nodejs/src/library/bindings.ts | 7 +- .../src/NativeBindings.ts | 15 +++ .../src/builder/GetAttribRequest.ts | 2 + .../src/builder/GetNymRequest.ts | 2 + 7 files changed, 145 insertions(+), 7 deletions(-) diff --git a/libindy_vdr/include/libindy_vdr.h b/libindy_vdr/include/libindy_vdr.h index 25661c1d..86b131a5 100644 --- a/libindy_vdr/include/libindy_vdr.h +++ b/libindy_vdr/include/libindy_vdr.h @@ -5,6 +5,8 @@ #include +#define DEFAULT 0 + #define DEFAULT_ACK_TIMEOUT 20 #define DEFAULT_CONN_ACTIVE_TIMEOUT 5 @@ -17,6 +19,10 @@ #define DEFAULT_REQUEST_READ_NODES 2 +#define DID_INDY 2 + +#define DID_SOV 1 + enum ErrorCode #ifdef __cplusplus : int64_t @@ -34,11 +40,27 @@ enum ErrorCode PoolNoConsensus = 30, PoolRequestFailed = 31, PoolTimeout = 32, + Resolver = 9, }; #ifndef __cplusplus typedef int64_t ErrorCode; #endif // __cplusplus +/** + * The Indy Node communication protocol version + */ +enum ProtocolVersion +#ifdef __cplusplus + : int64_t +#endif // __cplusplus + { + Node1_3 = 1, + Node1_4 = 2, +}; +#ifndef __cplusplus +typedef int64_t ProtocolVersion; +#endif // __cplusplus + /** * `FfiStr<'a>` is a safe (`#[repr(transparent)]`) wrapper around a * nul-terminated `*const c_char` (e.g. a C string). Conceptually, it is @@ -178,6 +200,8 @@ typedef struct ByteBuffer { uint8_t *data; } ByteBuffer; + + #ifdef __cplusplus extern "C" { #endif // __cplusplus @@ -195,6 +219,19 @@ ErrorCode indy_vdr_build_attrib_request(FfiStr submitter_did, FfiStr enc, RequestHandle *handle_p); +ErrorCode indy_vdr_build_auth_rule_request(FfiStr submitter_did, + FfiStr txn_type, + FfiStr action, + FfiStr field, + FfiStr old_value, + FfiStr new_value, + FfiStr constraint, + RequestHandle *handle_p); + +ErrorCode indy_vdr_build_auth_rules_request(FfiStr submitter_did, + FfiStr rules, + RequestHandle *handle_p); + ErrorCode indy_vdr_build_cred_def_request(FfiStr submitter_did, FfiStr cred_def, RequestHandle *handle_p); @@ -214,14 +251,28 @@ ErrorCode indy_vdr_build_get_attrib_request(FfiStr submitter_did, FfiStr raw, FfiStr hash, FfiStr enc, + int32_t seq_no, + int64_t timestamp, RequestHandle *handle_p); +ErrorCode indy_vdr_build_get_auth_rule_request(FfiStr submitter_did, + FfiStr auth_type, + FfiStr auth_action, + FfiStr field, + FfiStr old_value, + FfiStr new_value, + RequestHandle *handle_p); + ErrorCode indy_vdr_build_get_cred_def_request(FfiStr submitter_did, FfiStr cred_def_id, RequestHandle *handle_p); +ErrorCode indy_vdr_build_get_frozen_ledgers_request(FfiStr identifier, RequestHandle *handle_p); + ErrorCode indy_vdr_build_get_nym_request(FfiStr submitter_did, FfiStr dest, + int32_t seq_no, + int64_t timestamp, RequestHandle *handle_p); ErrorCode indy_vdr_build_get_revoc_reg_def_request(FfiStr submitter_did, @@ -268,13 +319,47 @@ ErrorCode indy_vdr_build_get_txn_request(FfiStr submitter_did, ErrorCode indy_vdr_build_get_validator_info_request(FfiStr submitter_did, RequestHandle *handle_p); +ErrorCode indy_vdr_build_ledgers_freeze_request(FfiStr identifier, + FfiStr ledgers_ids, + RequestHandle *handle_p); + +ErrorCode indy_vdr_build_node_request(FfiStr identifier, + FfiStr dest, + FfiStr data, + RequestHandle *handle_p); + ErrorCode indy_vdr_build_nym_request(FfiStr submitter_did, FfiStr dest, FfiStr verkey, FfiStr alias, FfiStr role, + FfiStr diddoc_content, + int32_t version, RequestHandle *handle_p); +ErrorCode indy_vdr_build_pool_config_request(FfiStr identifier, + int8_t writes, + int8_t force, + RequestHandle *handle_p); + +ErrorCode indy_vdr_build_pool_restart_request(FfiStr identifier, + FfiStr action, + FfiStr datetime, + RequestHandle *handle_p); + +ErrorCode indy_vdr_build_pool_upgrade_request(FfiStr identifier, + FfiStr name, + FfiStr version, + FfiStr action, + FfiStr sha256, + int32_t timeout, + FfiStr schedule, + FfiStr justification, + int8_t reinstall, + int8_t force, + FfiStr package, + RequestHandle *handle_p); + ErrorCode indy_vdr_build_revoc_reg_def_request(FfiStr submitter_did, FfiStr revoc_reg_def, RequestHandle *handle_p); @@ -307,6 +392,11 @@ ErrorCode indy_vdr_build_txn_author_agreement_request(FfiStr submitter_did, int64_t retirement_ts, RequestHandle *handle_p); +ErrorCode indy_vdr_dereference(PoolHandle pool_handle, + FfiStr did_url, + void (*cb)(int64_t cb_id, ErrorCode err, const char *response), + int64_t cb_id); + ErrorCode indy_vdr_get_current_error(const char **error_json_p); ErrorCode indy_vdr_pool_close(PoolHandle pool_handle); @@ -379,6 +469,11 @@ ErrorCode indy_vdr_request_set_signature(RequestHandle request_handle, struct By ErrorCode indy_vdr_request_set_txn_author_agreement_acceptance(RequestHandle request_handle, FfiStr acceptance); +ErrorCode indy_vdr_resolve(PoolHandle pool_handle, + FfiStr did, + void (*cb)(int64_t cb_id, ErrorCode err, const char *response), + int64_t cb_id); + ErrorCode indy_vdr_set_config(FfiStr config); ErrorCode indy_vdr_set_default_logger(void); diff --git a/wrappers/javascript/indy-vdr-nodejs/src/NodeJSIndyVdr.ts b/wrappers/javascript/indy-vdr-nodejs/src/NodeJSIndyVdr.ts index 65de5f8f..2557f5b6 100644 --- a/wrappers/javascript/indy-vdr-nodejs/src/NodeJSIndyVdr.ts +++ b/wrappers/javascript/indy-vdr-nodejs/src/NodeJSIndyVdr.ts @@ -199,10 +199,20 @@ export class NodeJSIndyVdr implements IndyVdr { public buildGetAttribRequest(options: GetAttribRequestOptions): number { const requestHandle = allocateHandle() - const { submitterDid, targetDid, raw, hash, enc } = serializeArguments(options) + const { submitterDid, targetDid, raw, hash, enc, seqNo, timestamp } = serializeArguments(options) + const convertedTimestamp = timestamp ?? -1 this.handleError( - this.nativeIndyVdr.indy_vdr_build_get_attrib_request(submitterDid, targetDid, raw, hash, enc, requestHandle) + this.nativeIndyVdr.indy_vdr_build_get_attrib_request( + submitterDid, + targetDid, + raw, + hash, + enc, + seqNo, + convertedTimestamp, + requestHandle + ) ) return handleReturnPointer(requestHandle) @@ -311,9 +321,12 @@ export class NodeJSIndyVdr implements IndyVdr { public buildGetNymRequest(options: GetNymRequestOptions): number { const requestHandle = allocateHandle() - const { dest, submitterDid } = serializeArguments(options) + const { dest, submitterDid, seqNo, timestamp } = serializeArguments(options) + const convertedTimestamp = timestamp ?? -1 - this.handleError(this.nativeIndyVdr.indy_vdr_build_get_nym_request(submitterDid, dest, requestHandle)) + this.handleError( + this.nativeIndyVdr.indy_vdr_build_get_nym_request(submitterDid, dest, seqNo, convertedTimestamp, requestHandle) + ) return handleReturnPointer(requestHandle) } diff --git a/wrappers/javascript/indy-vdr-nodejs/src/library/NativeBindings.ts b/wrappers/javascript/indy-vdr-nodejs/src/library/NativeBindings.ts index 98fc4bf0..f57f95d1 100644 --- a/wrappers/javascript/indy-vdr-nodejs/src/library/NativeBindings.ts +++ b/wrappers/javascript/indy-vdr-nodejs/src/library/NativeBindings.ts @@ -48,6 +48,8 @@ export interface NativeMethods { arg2: string, arg3: string, arg4: string, + arg5: number, + arg6: number, requestHandlePtr: Buffer ) => number indy_vdr_build_node_request: (arg0: string, arg1: string, arg2: string, requestHandlePtr: Buffer) => number @@ -70,7 +72,13 @@ export interface NativeMethods { requestHandlePtr: Buffer ) => number indy_vdr_build_get_txn_author_agreement_request: (arg0: string, arg1: string, requestHandlePtr: Buffer) => number - indy_vdr_build_get_nym_request: (arg0: string, arg1: string, requestHandlePtr: Buffer) => number + indy_vdr_build_get_nym_request: ( + arg0: string, + arg1: string, + arg2: number, + arg3: number, + requestHandlePtr: Buffer + ) => number indy_vdr_build_get_txn_request: (arg0: string, arg1: number, arg2: number, requestHandlePtr: Buffer) => number indy_vdr_build_get_validator_info_request: (arg0: string, requestHandlePtr: Buffer) => number indy_vdr_build_nym_request: ( diff --git a/wrappers/javascript/indy-vdr-nodejs/src/library/bindings.ts b/wrappers/javascript/indy-vdr-nodejs/src/library/bindings.ts index 4914066c..1f844264 100644 --- a/wrappers/javascript/indy-vdr-nodejs/src/library/bindings.ts +++ b/wrappers/javascript/indy-vdr-nodejs/src/library/bindings.ts @@ -41,10 +41,13 @@ export const nativeBindings = { ], indy_vdr_build_get_attrib_request: [ FFI_ERROR_CODE, - [FFI_STRING, FFI_STRING, FFI_STRING, FFI_STRING, FFI_STRING, FFI_REQUEST_HANDLE_POINTER], + [FFI_STRING, FFI_STRING, FFI_STRING, FFI_STRING, FFI_STRING, FFI_INT32, FFI_INT64, FFI_REQUEST_HANDLE_POINTER], ], indy_vdr_build_get_cred_def_request: [FFI_ERROR_CODE, [FFI_STRING, FFI_STRING, FFI_REQUEST_HANDLE_POINTER]], - indy_vdr_build_get_nym_request: [FFI_ERROR_CODE, [FFI_STRING, FFI_STRING, FFI_REQUEST_HANDLE_POINTER]], + indy_vdr_build_get_nym_request: [ + FFI_ERROR_CODE, + [FFI_STRING, FFI_STRING, FFI_INT32, FFI_INT64, FFI_REQUEST_HANDLE_POINTER], + ], indy_vdr_build_get_revoc_reg_def_request: [FFI_ERROR_CODE, [FFI_STRING, FFI_STRING, FFI_REQUEST_HANDLE_POINTER]], indy_vdr_build_get_revoc_reg_delta_request: [ FFI_ERROR_CODE, diff --git a/wrappers/javascript/indy-vdr-react-native/src/NativeBindings.ts b/wrappers/javascript/indy-vdr-react-native/src/NativeBindings.ts index e7b05923..2b549a6b 100644 --- a/wrappers/javascript/indy-vdr-react-native/src/NativeBindings.ts +++ b/wrappers/javascript/indy-vdr-react-native/src/NativeBindings.ts @@ -43,7 +43,13 @@ export interface NativeBindings { raw?: string hash?: string enc?: string +<<<<<<< HEAD:wrappers/javascript/indy-vdr-react-native/src/library/NativeBindings.ts }): ReturnObject +======= + seqNo?: number + timestamp?: number + }): RequestHandle +>>>>>>> 8f534e1 (quick fix for ffi bindings):wrappers/javascript/indy-vdr-shared/src/indyVdr/IndyVdrNativeBindings.ts buildCredDefRequest(options: { submitterDid: string; credentialDefinition: string }): ReturnObject @@ -79,7 +85,16 @@ export interface NativeBindings { buildDisableAllTxnAuthorAgreementsRequest(options: { submitterDid: string }): ReturnObject +<<<<<<< HEAD:wrappers/javascript/indy-vdr-react-native/src/library/NativeBindings.ts buildGetNymRequest(options: { submitterDid?: string; dest: string }): ReturnObject +======= + buildGetNymRequest(options: { + submitterDid?: string + dest: string + didDocContent?: string + version?: number + }): RequestHandle +>>>>>>> 8f534e1 (quick fix for ffi bindings):wrappers/javascript/indy-vdr-shared/src/indyVdr/IndyVdrNativeBindings.ts buildGetSchemaRequest(options: { submitterDid?: string; schemaId: string }): ReturnObject diff --git a/wrappers/javascript/indy-vdr-shared/src/builder/GetAttribRequest.ts b/wrappers/javascript/indy-vdr-shared/src/builder/GetAttribRequest.ts index 577f8f27..3cde2e68 100644 --- a/wrappers/javascript/indy-vdr-shared/src/builder/GetAttribRequest.ts +++ b/wrappers/javascript/indy-vdr-shared/src/builder/GetAttribRequest.ts @@ -8,6 +8,8 @@ export type GetAttribRequestOptions = { hash?: string raw?: string enc?: string + seqNo?: number + timestamp?: number } interface GetAttribFoundResult extends GetRequestResultFoundBase { diff --git a/wrappers/javascript/indy-vdr-shared/src/builder/GetNymRequest.ts b/wrappers/javascript/indy-vdr-shared/src/builder/GetNymRequest.ts index 6613ed82..db414bb9 100644 --- a/wrappers/javascript/indy-vdr-shared/src/builder/GetNymRequest.ts +++ b/wrappers/javascript/indy-vdr-shared/src/builder/GetNymRequest.ts @@ -5,6 +5,8 @@ import { indyVdr, IndyVdrRequest } from '../indyVdr' export type GetNymRequestOptions = { submitterDid?: string dest: string + seqNo?: number + timestamp?: number } // Get Nym somehow returns the nym data as stringified JSON. It is up to the user of the library From f6e0df3556b1ee3c0e8e18f20f4914f01e3c0d9b Mon Sep 17 00:00:00 2001 From: Christian Bormann Date: Thu, 2 Mar 2023 08:02:46 +0100 Subject: [PATCH 084/117] remove did-indy node container and re-use the existing node-container builds Signed-off-by: Christian Bormann --- .github/workflows/build.yml | 2 +- ci/did-indy-pool.dockerfile | 153 ------------------------------------ ci/indy-pool.dockerfile | 48 +---------- 3 files changed, 3 insertions(+), 200 deletions(-) delete mode 100644 ci/did-indy-pool.dockerfile diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e105bb2e..693042e7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -82,7 +82,7 @@ jobs: - name: Run local node pool run: | - docker build -f ci/did-indy-pool.dockerfile -t test_pool --build-arg pool_ip=10.0.0.2 ci + docker build -f ci/indy-pool.dockerfile -t test_pool --build-arg pool_ip=10.0.0.2 ci docker network create --subnet=10.0.0.0/8 indy-sdk-network docker run -d --name indy_pool -p 9701-9708:9701-9708 --net=indy-sdk-network test_pool diff --git a/ci/did-indy-pool.dockerfile b/ci/did-indy-pool.dockerfile deleted file mode 100644 index 69e380d7..00000000 --- a/ci/did-indy-pool.dockerfile +++ /dev/null @@ -1,153 +0,0 @@ -FROM --platform=linux/amd64 ubuntu:20.04 - -ARG uid=1000 -# ARG user=indy - -RUN apt-get update -y && apt-get install -y \ - # common stuff - git \ - wget \ - gnupg \ - apt-transport-https \ - ca-certificates \ - apt-utils - -# ======================================================================================================== -# Update repository signing keys -# -------------------------------------------------------------------------------------------------------- -# Hyperledger -RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 9692C00E657DDE61 && \ - # Sovrin - apt-key adv --keyserver keyserver.ubuntu.com --recv-keys CE7709D068DB5E88 -# ======================================================================================================== - -# Plenum -# - https://github.com/hyperledger/indy-plenum/issues/1546 -# - Needed to pick up rocksdb=5.8.8 -RUN echo "deb https://hyperledger.jfrog.io/artifactory/indy focal dev" >> /etc/apt/sources.list && \ - echo "deb http://security.ubuntu.com/ubuntu bionic-security main" >> /etc/apt/sources.list && \ - echo "deb https://repo.sovrin.org/deb bionic master" >> /etc/apt/sources.list && \ - echo "deb https://repo.sovrin.org/sdk/deb bionic master" >> /etc/apt/sources.list - -# Sovrin -RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys CE7709D068DB5E88 - -RUN apt-get update -y && apt-get install -y \ - # Python - python3-pip \ - python3-nacl \ - # rocksdb python wrapper - rocksdb=5.8.8 \ - libgflags-dev \ - libsnappy-dev \ - zlib1g-dev \ - libbz2-dev \ - liblz4-dev \ - libgflags-dev \ - # zstd is needed for caching in github actions pipeline - zstd \ - # fpm - ruby \ - ruby-dev \ - rubygems \ - gcc \ - make \ - # Indy Node and Plenum - libssl1.0.0 \ - ursa=0.3.2-1 \ - # Indy SDK - libindy=1.15.0~1625-bionic \ - # Need to move libursa.so to parent dir - && mv /usr/lib/ursa/* /usr/lib && rm -rf /usr/lib/ursa - -RUN pip3 install -U \ - # Required by setup.py - setuptools==50.3.2 \ - # Still pinned. Needs to be update like in plenum - 'pip<10.0.0' \ - 'pyzmq==18.1.0' \ - 'supervisor~=4.2' - - -# install fpm -RUN gem install --no-document rake fpm - -RUN apt-get -y autoremove \ - && rm -rf /var/lib/apt/lists/* - -# Download, build and install indy-node. Will invalidate cache if new HEAD -ADD https://api.github.com/repos/domwoe/indy-node/git/refs/heads/feature/did-indy-new version.json -RUN git clone --single-branch -b feature/did-indy-new https://github.com/domwoe/indy-node.git && \ - pip install -e indy-node - - -RUN echo "[supervisord]\n\ -logfile = /tmp/supervisord.log\n\ -logfile_maxbytes = 50MB\n\ -logfile_backups=10\n\ -logLevel = error\n\ -pidfile = /tmp/supervisord.pid\n\ -nodaemon = true\n\ -minfds = 1024\n\ -minprocs = 200\n\ -umask = 022\n\ -user = indy\n\ -identifier = supervisor\n\ -directory = /tmp\n\ -nocleanup = true\n\ -childlogdir = /tmp\n\ -strip_ansi = false\n\ -\n\ -[program:node1]\n\ -command=start_indy_node Node1 0.0.0.0 9701 0.0.0.0 9702\n\ -directory=/home/indy\n\ -stdout_logfile=/tmp/node1.log\n\ -stderr_logfile=/tmp/node1.log\n\ -\n\ -[program:node2]\n\ -command=start_indy_node Node2 0.0.0.0 9703 0.0.0.0 9704\n\ -directory=/home/indy\n\ -stdout_logfile=/tmp/node2.log\n\ -stderr_logfile=/tmp/node2.log\n\ -\n\ -[program:node3]\n\ -command=start_indy_node Node3 0.0.0.0 9705 0.0.0.0 9706\n\ -directory=/home/indy\n\ -stdout_logfile=/tmp/node3.log\n\ -stderr_logfile=/tmp/node3.log\n\ -\n\ -[program:node4]\n\ -command=start_indy_node Node4 0.0.0.0 9707 0.0.0.0 9708\n\ -directory=/home/indy\n\ -stdout_logfile=/tmp/node4.log\n\ -stderr_logfile=/tmp/node4.log\n"\ ->> /etc/supervisord.conf - -RUN useradd -ms /bin/bash -u $uid indy - -RUN mkdir -p \ - /etc/indy \ - /var/lib/indy/backup \ - /var/lib/indy/plugins \ - /var/log/indy \ - && chown -R indy /etc/indy /var/lib/indy /var/log/indy - -USER indy - -RUN echo "LEDGER_DIR = '/var/lib/indy'\n\ -LOG_DIR = '/var/log/indy'\n\ -KEYS_DIR = '/var/lib/indy'\n\ -GENESIS_DIR = '/var/lib/indy'\n\ -BACKUP_DIR = '/var/lib/indy/backup'\n\ -PLUGINS_DIR = '/var/lib/indy/plugins'\n\ -NODE_INFO_DIR = '/var/lib/indy'\n\ -NETWORK_NAME = 'sandbox'\n"\ ->> /etc/indy/indy_config.py - -ARG pool_ip=127.0.0.1 - -RUN generate_indy_pool_transactions --nodes 4 --clients 5 --nodeNum 1 2 3 4 --ips="$pool_ip,$pool_ip,$pool_ip,$pool_ip" - -EXPOSE 9701 9702 9703 9704 9705 9706 9707 9708 - -CMD ["/usr/local/bin/supervisord"] diff --git a/ci/indy-pool.dockerfile b/ci/indy-pool.dockerfile index a0885185..dab8e0f9 100644 --- a/ci/indy-pool.dockerfile +++ b/ci/indy-pool.dockerfile @@ -1,49 +1,5 @@ -FROM ubuntu:16.04 - -ARG uid=1000 - -# Install environment -RUN apt-get update -y && apt-get install -y \ - git \ - wget \ - python3.5 \ - python3-nacl \ - python3-pip \ - python3-setuptools \ - apt-transport-https \ - ca-certificates \ - software-properties-common - -RUN pip3 install -U \ - "pip~=9.0" \ - "setuptools~=50.0" \ - "supervisor~=4.2" - -RUN add-apt-repository "deb http://us.archive.ubuntu.com/ubuntu xenial main universe" && \ - apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys CE7709D068DB5E88 -ARG indy_stream=master -RUN add-apt-repository "deb https://repo.sovrin.org/deb xenial ${indy_stream}" && \ - add-apt-repository "deb https://repo.sovrin.org/sdk/deb xenial stable" - -RUN useradd -ms /bin/bash -u $uid indy - -ARG indy_plenum_ver=1.13.0.dev1032 -ARG indy_node_ver=1.13.0.dev1221 - -RUN apt-get update -y && apt-get install -y \ - libsodium18 \ - libbz2-dev \ - zlib1g-dev \ - liblz4-dev \ - libsnappy-dev \ - rocksdb=5.8.8 \ - libindy \ - ursa \ - vim - -RUN pip3 install \ - indy-plenum==${indy_plenum_ver} \ - indy-node==${indy_node_ver} +FROM ghcr.io/hyperledger/indy-node-container/indy_node:1.13.2-rc5-ubuntu20-main +RUN pip3 install "supervisor~=4.2" RUN echo "[supervisord]\n\ logfile = /tmp/supervisord.log\n\ From f81c868021d89dc5a2a98eb22d3235aff7ad457b Mon Sep 17 00:00:00 2001 From: Christian Bormann Date: Thu, 2 Mar 2023 08:06:58 +0100 Subject: [PATCH 085/117] add small bash script to create / remove the pool for local testing Signed-off-by: Christian Bormann --- test.sh | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100755 test.sh diff --git a/test.sh b/test.sh new file mode 100755 index 00000000..cc77cc88 --- /dev/null +++ b/test.sh @@ -0,0 +1,50 @@ +#/bin/bash + +readonly command=$(basename ${0}) + +help(){ + echo "Usage: $command [options]\n" + echo "Subcommands:" + echo " up" + echo " test" + echo " down" + echo "Default behavior without a subcommand is up, test, down" +} + +up(){ + docker build -f ci/indy-pool.dockerfile -t test_pool --build-arg pool_ip=10.0.0.2 ci + docker network create --subnet=10.0.0.0/8 indy-sdk-network + docker run -d --name indy_pool -p 9701-9708:9701-9708 --net=indy-sdk-network test_pool +} + +run_tests(){ + cargo test --manifest-path libindy_vdr/Cargo.toml --features local_nodes_pool +} + +down(){ + docker stop indy_pool + docker rm indy_pool + docker network rm indy-sdk-network +} + +subcommand="$1" +case $subcommand in + "-h" | "--help") + help + ;; + "up") + up + ;; + "test" | "tests") + run_tests + ;; + "down") + down + ;; + *) + up + run_tests + down + ;; +esac + From ad8308d2a9ab36eebe2a435936646a33237aba91 Mon Sep 17 00:00:00 2001 From: Christian Bormann Date: Thu, 2 Mar 2023 08:08:59 +0100 Subject: [PATCH 086/117] use bash script for the local pool tests in the github actions Signed-off-by: Christian Bormann --- .github/workflows/build.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 693042e7..6439ecdf 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -82,13 +82,15 @@ jobs: - name: Run local node pool run: | - docker build -f ci/indy-pool.dockerfile -t test_pool --build-arg pool_ip=10.0.0.2 ci - docker network create --subnet=10.0.0.0/8 indy-sdk-network - docker run -d --name indy_pool -p 9701-9708:9701-9708 --net=indy-sdk-network test_pool + ./test.sh up - name: Run tests run: cargo test --manifest-path libindy_vdr/Cargo.toml --features local_nodes_pool + - name: Stop local node pool + run: | + ./test.sh down + build-release: name: Build library needs: [checks] From 45ead4b154310717af187c726d3a1550b65080f7 Mon Sep 17 00:00:00 2001 From: Andrew Whitehead Date: Tue, 7 Mar 2023 09:14:15 -0800 Subject: [PATCH 087/117] (python) add defaults for new optional parameters Signed-off-by: Andrew Whitehead --- wrappers/python/indy_vdr/ledger.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/wrappers/python/indy_vdr/ledger.py b/wrappers/python/indy_vdr/ledger.py index 6a8c4603..e4b29a57 100644 --- a/wrappers/python/indy_vdr/ledger.py +++ b/wrappers/python/indy_vdr/ledger.py @@ -214,11 +214,11 @@ def build_get_acceptance_mechanisms_request( def build_get_attrib_request( submitter_did: Optional[str], target_did: str, - raw: Optional[str], - xhash: Optional[str], - enc: Optional[str], - seq_no: Optional[int], - timestamp: Optional[int], + raw: Optional[str] = None, + xhash: Optional[str] = None, + enc: Optional[str] = None, + seq_no: Optional[int] = None, + timestamp: Optional[int] = None, ) -> str: """ Builds a GET_ATTRIB request. @@ -279,8 +279,8 @@ def build_get_cred_def_request( def build_get_nym_request( submitter_did: Optional[str], dest: str, - seq_no: Optional[int], - timestamp: Optional[int], + seq_no: Optional[int] = None, + timestamp: Optional[int] = None, ) -> Request: """ Builds a GET_NYM request to get information about a DID (NYM). From 5169e7ef6c70cc6551b838fd402ef96cac667187 Mon Sep 17 00:00:00 2001 From: Christian Bormann Date: Mon, 27 Mar 2023 14:36:31 +0200 Subject: [PATCH 088/117] Add support for config flag transactions Signed-off-by: Christian Bormann --- libindy_vdr/src/ledger/constants.rs | 11 ++- libindy_vdr/src/ledger/request_builder.rs | 25 ++++++ libindy_vdr/src/ledger/requests/flag.rs | 69 ++++++++++++++ libindy_vdr/src/ledger/requests/mod.rs | 2 + libindy_vdr/tests/flag.rs | 104 ++++++++++++++++++++++ 5 files changed, 209 insertions(+), 2 deletions(-) create mode 100644 libindy_vdr/src/ledger/requests/flag.rs create mode 100644 libindy_vdr/tests/flag.rs diff --git a/libindy_vdr/src/ledger/constants.rs b/libindy_vdr/src/ledger/constants.rs index 3f97da05..2ce03859 100644 --- a/libindy_vdr/src/ledger/constants.rs +++ b/libindy_vdr/src/ledger/constants.rs @@ -27,6 +27,8 @@ pub const GET_VALIDATOR_INFO: &str = "119"; pub const AUTH_RULE: &str = "120"; pub const GET_AUTH_RULE: &str = "121"; pub const AUTH_RULES: &str = "122"; +pub const FLAG: &str = "130"; +pub const GET_FLAG: &str = "131"; // RichSchema objects pub const RICH_SCHEMA_CTX: &str = "200"; pub const RICH_SCHEMA: &str = "201"; @@ -38,7 +40,7 @@ pub const RICH_SCHEMA_PRES_DEF: &str = "205"; pub const GET_RICH_SCHEMA_BY_ID: &str = "300"; pub const GET_RICH_SCHEMA_BY_METADATA: &str = "301"; -pub const REQUESTS: [&str; 33] = [ +pub const REQUESTS: [&str; 35] = [ NODE, NYM, GET_TXN, @@ -66,6 +68,8 @@ pub const REQUESTS: [&str; 33] = [ DISABLE_ALL_TXN_AUTHR_AGRMTS, LEDGERS_FREEZE, GET_FROZEN_LEDGERS, + FLAG, + GET_FLAG, RICH_SCHEMA_CTX, RICH_SCHEMA, RICH_SCHEMA_ENCODING, @@ -75,7 +79,7 @@ pub const REQUESTS: [&str; 33] = [ ]; // likely matches REQUESTS_FOR_STATE_PROOFS -pub const READ_REQUESTS: [&str; 13] = [ +pub const READ_REQUESTS: [&str; 14] = [ GET_NYM, GET_TXN_AUTHR_AGRMT, GET_TXN_AUTHR_AGRMT_AML, @@ -87,6 +91,7 @@ pub const READ_REQUESTS: [&str; 13] = [ GET_REVOC_REG_DELTA, GET_AUTH_RULE, GET_TXN, + GET_FLAG, GET_RICH_SCHEMA_BY_ID, GET_RICH_SCHEMA_BY_METADATA, ]; @@ -145,6 +150,8 @@ pub fn txn_name_to_code(txn: &str) -> Option<&str> { "DISABLE_ALL_TXN_AUTHR_AGRMTS" => Some(DISABLE_ALL_TXN_AUTHR_AGRMTS), "LEDGERS_FREEZE" => Some(LEDGERS_FREEZE), "GET_FROZEN_LEDGERS" => Some(GET_FROZEN_LEDGERS), + "FLAG" => Some(FLAG), + "GET_FLAG" => Some(GET_FLAG), val => Some(val), } } diff --git a/libindy_vdr/src/ledger/request_builder.rs b/libindy_vdr/src/ledger/request_builder.rs index bd4e2a22..e222cb8c 100644 --- a/libindy_vdr/src/ledger/request_builder.rs +++ b/libindy_vdr/src/ledger/request_builder.rs @@ -20,6 +20,7 @@ use super::requests::author_agreement::{ TxnAuthorAgreementOperation, TxnAuthrAgrmtAcceptanceData, }; use super::requests::cred_def::{CredDefOperation, CredentialDefinition, GetCredDefOperation}; +use super::requests::flag::{FlagOperation, GetFlagOperation}; use super::requests::ledgers_freeze::{GetFrozenLedgersOperation, LedgersFreezeOperation}; use super::requests::node::{NodeOperation, NodeOperationData}; use super::requests::nym::{role_to_code, GetNymOperation, NymOperation}; @@ -122,6 +123,30 @@ impl RequestBuilder { )) } + /// Build a `FLAG` transaction request + pub fn build_flag_request( + &self, + identifier: &DidValue, + name: String, + value: String, + ) -> VdrResult { + let operation = FlagOperation::new(name, value); + self.build(operation, Some(identifier)) + } + + /// Build a `GET_FLAG` transaction request + /// Use only one of seq_no and timestamp + pub fn build_get_flag_request( + &self, + identifier: Option<&DidValue>, + name: String, + seq_no: Option, + timestamp: Option, + ) -> VdrResult { + let operation = GetFlagOperation::new(name, seq_no, timestamp); + self.build(operation, identifier) + } + /// Build a `NYM` transaction request /// diddoc_content is only supported for did:indy compliant ledgers pub fn build_nym_request( diff --git a/libindy_vdr/src/ledger/requests/flag.rs b/libindy_vdr/src/ledger/requests/flag.rs new file mode 100644 index 00000000..fb39f56a --- /dev/null +++ b/libindy_vdr/src/ledger/requests/flag.rs @@ -0,0 +1,69 @@ +use crate::common::error::VdrResult; +use crate::ledger::requests::get_sp_key_marker; + +use super::constants::{FLAG, GET_FLAG}; +use super::{ProtocolVersion, RequestType}; + +#[derive(Serialize, PartialEq, Debug)] +#[serde(rename_all = "camelCase")] +pub struct FlagOperation { + pub _type: String, + pub name: String, + pub value: String, +} + +impl FlagOperation { + pub fn new(name: String, value: String) -> FlagOperation { + FlagOperation { + _type: Self::get_txn_type().to_string(), + name, + value, + } + } +} + +impl RequestType for FlagOperation { + fn get_txn_type<'a>() -> &'a str { + FLAG + } +} + +#[derive(Serialize, PartialEq, Debug)] +#[serde(rename_all = "camelCase")] +pub struct GetFlagOperation { + pub _type: String, + pub name: String, + #[serde(skip_serializing_if = "Option::is_none")] + pub seq_no: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub timestamp: Option, +} + +impl GetFlagOperation { + pub fn new(name: String, seq_no: Option, timestamp: Option) -> GetFlagOperation { + GetFlagOperation { + _type: Self::get_txn_type().to_string(), + name, + seq_no, + timestamp, + } + } +} + +impl RequestType for GetFlagOperation { + fn get_txn_type<'a>() -> &'a str { + GET_FLAG + } + + fn get_sp_key(&self, _protocol_version: ProtocolVersion) -> VdrResult>> { + if !self.name.is_empty() { + let marker = get_sp_key_marker(2, _protocol_version); + return Ok(Some( + format!("{}:{}", marker, self.name.to_string()) + .as_bytes() + .to_vec(), + )); + } + Ok(None) + } +} diff --git a/libindy_vdr/src/ledger/requests/mod.rs b/libindy_vdr/src/ledger/requests/mod.rs index d9ffe488..5ec5c24c 100644 --- a/libindy_vdr/src/ledger/requests/mod.rs +++ b/libindy_vdr/src/ledger/requests/mod.rs @@ -6,6 +6,8 @@ pub mod auth_rule; pub mod author_agreement; /// Credential definition operations pub mod cred_def; +/// FLAG transactions operations +pub mod flag; /// Frozen Ledger operations pub mod ledgers_freeze; /// NODE transactions operations diff --git a/libindy_vdr/tests/flag.rs b/libindy_vdr/tests/flag.rs new file mode 100644 index 00000000..329ac74b --- /dev/null +++ b/libindy_vdr/tests/flag.rs @@ -0,0 +1,104 @@ +#[macro_use] +mod utils; + +inject_dependencies!(); + +use indy_vdr::ledger::constants; +use indy_vdr::utils::did::DidValue; + +use crate::utils::fixtures::*; +use crate::utils::helpers; + +const FLAG_NAME: &'static str = r#"REV_STRATEGY_USE_COMPAT_ORDERING"#; +const FLAG_VALUE: &'static str = r#"True"#; + +#[test] +fn empty() { + // Empty test to run module +} + +#[cfg(test)] +mod builder { + use super::*; + use indy_vdr::ledger::RequestBuilder; + + mod flag { + use super::*; + + #[rstest] + fn test_pool_build_flag(request_builder: RequestBuilder, trustee_did: DidValue) { + let flag_request = request_builder + .build_flag_request(&trustee_did, FLAG_NAME.to_string(), FLAG_VALUE.to_string()) + .unwrap(); + + let expected_result = json!({ + "type": constants::FLAG, + "name": FLAG_NAME, + "value": FLAG_VALUE, + }); + + helpers::check_request_operation(&flag_request, expected_result); + } + } + + mod get_flag { + use super::*; + + #[rstest] + fn test_pool_build_get_flag(request_builder: RequestBuilder) { + let attrib_request = request_builder + .build_get_flag_request(None, FLAG_NAME.to_string(), None, None) + .unwrap(); + + let expected_result = json!({ + "type": constants::GET_FLAG, + "name": FLAG_NAME, + }); + + helpers::check_request_operation(&attrib_request, expected_result); + } + } +} + +#[cfg(test)] +#[cfg(feature = "local_nodes_pool")] +mod send_flag { + use super::*; + use crate::utils::crypto::Identity; + use crate::utils::pool::TestPool; + + #[rstest] + fn test_pool_send_flag(pool: TestPool, trustee: Identity) { + // Create Flag Request + let mut flag_request = pool + .request_builder() + .build_flag_request(&trustee.did, FLAG_NAME.to_string(), FLAG_VALUE.to_string()) + .unwrap(); + // Send Flag Request + let flag_response = + helpers::sign_and_send_request(&trustee, &pool, &mut flag_request).unwrap(); + + // Create get_flag request -> This should return the FLAG_VALUE written previously + let get_flag_request = pool + .request_builder() + .build_get_flag_request(None, FLAG_NAME.to_string(), None, None) + .unwrap(); + let response = pool + .send_request_with_retries(&get_flag_request, &flag_response) + .unwrap(); + let data = helpers::get_response_data(&response).unwrap(); + assert_eq!(data["value"].as_str().unwrap(), FLAG_VALUE.to_string()); + + // Crate historic get_flag request -> this should error (transaction did not exist at that pont in time) + let timestamp = data["lut"].as_u64().unwrap(); + let get_flag_request = pool + .request_builder() + .build_get_flag_request(None, FLAG_NAME.to_string(), None, Some(timestamp - 1)) + .unwrap(); + let response = pool + .send_request_with_retries(&get_flag_request, &flag_response) + .unwrap(); + let data = helpers::get_response_data(&response); + assert_eq!(true, data.is_err()) + } +} From 73500e1746c2419801d157c34f2a2feddb05397e Mon Sep 17 00:00:00 2001 From: Andrew Whitehead Date: Thu, 30 Mar 2023 14:23:10 -0700 Subject: [PATCH 089/117] fix merge issues Signed-off-by: Andrew Whitehead --- .../indy-vdr-react-native/src/NativeBindings.ts | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/wrappers/javascript/indy-vdr-react-native/src/NativeBindings.ts b/wrappers/javascript/indy-vdr-react-native/src/NativeBindings.ts index 2b549a6b..f41f4597 100644 --- a/wrappers/javascript/indy-vdr-react-native/src/NativeBindings.ts +++ b/wrappers/javascript/indy-vdr-react-native/src/NativeBindings.ts @@ -43,13 +43,9 @@ export interface NativeBindings { raw?: string hash?: string enc?: string -<<<<<<< HEAD:wrappers/javascript/indy-vdr-react-native/src/library/NativeBindings.ts - }): ReturnObject -======= seqNo?: number timestamp?: number - }): RequestHandle ->>>>>>> 8f534e1 (quick fix for ffi bindings):wrappers/javascript/indy-vdr-shared/src/indyVdr/IndyVdrNativeBindings.ts + }): ReturnObject buildCredDefRequest(options: { submitterDid: string; credentialDefinition: string }): ReturnObject @@ -85,16 +81,12 @@ export interface NativeBindings { buildDisableAllTxnAuthorAgreementsRequest(options: { submitterDid: string }): ReturnObject -<<<<<<< HEAD:wrappers/javascript/indy-vdr-react-native/src/library/NativeBindings.ts - buildGetNymRequest(options: { submitterDid?: string; dest: string }): ReturnObject -======= buildGetNymRequest(options: { submitterDid?: string dest: string didDocContent?: string version?: number - }): RequestHandle ->>>>>>> 8f534e1 (quick fix for ffi bindings):wrappers/javascript/indy-vdr-shared/src/indyVdr/IndyVdrNativeBindings.ts + }): ReturnObject buildGetSchemaRequest(options: { submitterDid?: string; schemaId: string }): ReturnObject From 6b90fc1559209b3f209764dbd61049ac5338d537 Mon Sep 17 00:00:00 2001 From: Andrew Whitehead Date: Wed, 19 Jul 2023 11:51:16 -0700 Subject: [PATCH 090/117] restrict time crate version Signed-off-by: Andrew Whitehead --- .github/workflows/build.yml | 5 +++++ libindy_vdr/Cargo.toml | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6439ecdf..6988d234 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -6,6 +6,7 @@ env: on: push: + branches: [main] pull_request: branches: [main] release: @@ -23,6 +24,10 @@ on: default: false type: boolean +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: checks: name: Run checks diff --git a/libindy_vdr/Cargo.toml b/libindy_vdr/Cargo.toml index 0916e6ca..02345beb 100644 --- a/libindy_vdr/Cargo.toml +++ b/libindy_vdr/Cargo.toml @@ -49,7 +49,7 @@ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" sha3 = "0.10" thiserror = "1.0" -time = { version = "0.3.7", features = ["parsing"] } +time = { version = "=0.3.20", features = ["parsing"] } url = "2.2.2" zmq = "0.9" From 673f8254c800cc5f8618ea309f1d2e73b29d83fc Mon Sep 17 00:00:00 2001 From: Andrew Whitehead Date: Wed, 19 Jul 2023 12:27:47 -0700 Subject: [PATCH 091/117] fix default value for seqNo in GetNymRequest Signed-off-by: Andrew Whitehead --- wrappers/javascript/indy-vdr-nodejs/src/NodeJSIndyVdr.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/wrappers/javascript/indy-vdr-nodejs/src/NodeJSIndyVdr.ts b/wrappers/javascript/indy-vdr-nodejs/src/NodeJSIndyVdr.ts index 2557f5b6..79b88b9f 100644 --- a/wrappers/javascript/indy-vdr-nodejs/src/NodeJSIndyVdr.ts +++ b/wrappers/javascript/indy-vdr-nodejs/src/NodeJSIndyVdr.ts @@ -322,10 +322,17 @@ export class NodeJSIndyVdr implements IndyVdr { public buildGetNymRequest(options: GetNymRequestOptions): number { const requestHandle = allocateHandle() const { dest, submitterDid, seqNo, timestamp } = serializeArguments(options) + const convertedSeqNo = seqNo ?? -1 const convertedTimestamp = timestamp ?? -1 this.handleError( - this.nativeIndyVdr.indy_vdr_build_get_nym_request(submitterDid, dest, seqNo, convertedTimestamp, requestHandle) + this.nativeIndyVdr.indy_vdr_build_get_nym_request( + submitterDid, + dest, + convertedSeqNo, + convertedTimestamp, + requestHandle + ) ) return handleReturnPointer(requestHandle) From 8992332698879527f1eb4183918b0166e62b826e Mon Sep 17 00:00:00 2001 From: Andrew Whitehead Date: Thu, 27 Jul 2023 09:58:25 -0700 Subject: [PATCH 092/117] move test script Signed-off-by: Andrew Whitehead --- .github/workflows/build.yml | 4 ++-- test.sh => ci/test.sh | 0 2 files changed, 2 insertions(+), 2 deletions(-) rename test.sh => ci/test.sh (100%) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6988d234..bfd90275 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -87,14 +87,14 @@ jobs: - name: Run local node pool run: | - ./test.sh up + ./ci/test.sh up - name: Run tests run: cargo test --manifest-path libindy_vdr/Cargo.toml --features local_nodes_pool - name: Stop local node pool run: | - ./test.sh down + ./ci/test.sh down build-release: name: Build library diff --git a/test.sh b/ci/test.sh similarity index 100% rename from test.sh rename to ci/test.sh From 944cd3342dd665dff20f4731636f4a2a3cb4b34f Mon Sep 17 00:00:00 2001 From: Andrew Whitehead Date: Thu, 27 Jul 2023 09:59:42 -0700 Subject: [PATCH 093/117] misc cleanups Signed-off-by: Andrew Whitehead --- libindy_vdr/src/common/error.rs | 2 +- libindy_vdr/src/ffi/resolver.rs | 89 +++++++++---------- libindy_vdr/src/ledger/request_builder.rs | 6 +- libindy_vdr/src/resolver/mod.rs | 4 +- .../src/resolver/{resolver.rs => pool.rs} | 4 +- libindy_vdr/src/resolver/utils.rs | 7 +- 6 files changed, 52 insertions(+), 60 deletions(-) rename libindy_vdr/src/resolver/{resolver.rs => pool.rs} (98%) diff --git a/libindy_vdr/src/common/error.rs b/libindy_vdr/src/common/error.rs index 632cd1ce..326b5118 100644 --- a/libindy_vdr/src/common/error.rs +++ b/libindy_vdr/src/common/error.rs @@ -46,7 +46,7 @@ pub enum VdrErrorKind { PoolRequestFailed(String), #[error("Pool timeout")] PoolTimeout, - #[error("Resolver error ")] + #[error("Resolver error")] Resolver, } diff --git a/libindy_vdr/src/ffi/resolver.rs b/libindy_vdr/src/ffi/resolver.rs index 5889b6c8..c4d612a1 100644 --- a/libindy_vdr/src/ffi/resolver.rs +++ b/libindy_vdr/src/ffi/resolver.rs @@ -14,30 +14,27 @@ pub extern "C" fn indy_vdr_resolve( cb_id: i64, ) -> ErrorCode { catch_err! { - trace!("Resolve DID: {:#?}", did); - let cb = cb.ok_or_else(|| input_err("No callback provided")).unwrap(); - let pools = read_lock!(POOLS)?; - let pool = pools.get(&pool_handle).ok_or_else(|| input_err("Unknown pool handle"))?; - let did = did.as_str().to_owned(); - let resolver = Resolver::new(pool); - resolver - .dereference( - did.clone(), - Box::new(move |ledger_reply| { - - let (errcode, reply) = match handle_resolution_result(ledger_reply, did) { - Ok(result) => (ErrorCode::Success, result), - Err(err) => { - - let code = ErrorCode::from(err.kind()); - set_last_error(Some(err)); - (code, String::new()) - - } - }; - cb(cb_id, errcode, rust_string_to_c(reply)) - }), - )?; + trace!("Resolve DID: {:#?}", did); + let cb = cb.ok_or_else(|| input_err("No callback provided"))?; + let pools = read_lock!(POOLS)?; + let pool = pools.get(&pool_handle).ok_or_else(|| input_err("Unknown pool handle"))?; + let did = did.as_str().to_owned(); + let resolver = Resolver::new(pool); + resolver + .dereference( + did.clone(), + Box::new(move |ledger_reply| { + let (errcode, reply) = match handle_resolution_result(ledger_reply, did) { + Ok(result) => (ErrorCode::Success, result), + Err(err) => { + let code = ErrorCode::from(err.kind()); + set_last_error(Some(err)); + (code, String::new()) + } + }; + cb(cb_id, errcode, rust_string_to_c(reply)) + }), + )?; Ok(ErrorCode::Success) } } @@ -50,30 +47,26 @@ pub extern "C" fn indy_vdr_dereference( cb_id: i64, ) -> ErrorCode { catch_err! { - trace!("Dereference DID Url: {:#?}", did_url); - let cb = cb.ok_or_else(|| input_err("No callback provided")).unwrap(); - let pools = read_lock!(POOLS)?; - let pool = pools.get(&pool_handle).ok_or_else(|| input_err("Unknown pool handle"))?; - let did_url = did_url.as_str().to_owned(); - let resolver = Resolver::new(pool); - resolver - .dereference( - did_url.clone(), - Box::new(move |ledger_reply| { - - let (errcode, reply) = match handle_resolution_result(ledger_reply, did_url) { - Ok(result) => (ErrorCode::Success, result), - Err(err) => { - - let code = ErrorCode::from(err.kind()); - set_last_error(Some(err)); - (code, String::new()) - - } - }; - cb(cb_id, errcode, rust_string_to_c(reply)) - }), - )?; + trace!("Dereference DID Url: {:#?}", did_url); + let cb = cb.ok_or_else(|| input_err("No callback provided"))?; + let pools = read_lock!(POOLS)?; + let pool = pools.get(&pool_handle).ok_or_else(|| input_err("Unknown pool handle"))?; + let did_url = did_url.as_str().to_owned(); + let resolver = Resolver::new(pool); + resolver.dereference( + did_url.clone(), + Box::new(move |ledger_reply| { + let (errcode, reply) = match handle_resolution_result(ledger_reply, did_url) { + Ok(result) => (ErrorCode::Success, result), + Err(err) => { + let code = ErrorCode::from(err.kind()); + set_last_error(Some(err)); + (code, String::new()) + } + }; + cb(cb_id, errcode, rust_string_to_c(reply)) + }), + )?; Ok(ErrorCode::Success) } } diff --git a/libindy_vdr/src/ledger/request_builder.rs b/libindy_vdr/src/ledger/request_builder.rs index e222cb8c..0a497a85 100644 --- a/libindy_vdr/src/ledger/request_builder.rs +++ b/libindy_vdr/src/ledger/request_builder.rs @@ -712,7 +712,7 @@ mod tests { #[fixture] fn prepared_request(request_json: String) -> PreparedRequest { - PreparedRequest::from_request_json(&request_json).unwrap() + PreparedRequest::from_request_json(request_json).unwrap() } #[fixture] @@ -730,7 +730,7 @@ mod tests { #[rstest] fn test_prepared_request_from_request_json(request_json: String) { - let request = PreparedRequest::from_request_json(&request_json).unwrap(); + let request = PreparedRequest::from_request_json(request_json).unwrap(); assert_eq!(request.protocol_version, _protocol_version()); assert_eq!(request.txn_type, TYPE); assert_eq!(request.req_id, REQ_ID.to_string()); @@ -748,7 +748,7 @@ mod tests { mut request: serde_json::Value, ) { request[field] = serde_json::Value::Null; - let _err = PreparedRequest::from_request_json(&request.to_string()).unwrap_err(); + let _err = PreparedRequest::from_request_json(request.to_string()).unwrap_err(); } #[rstest] diff --git a/libindy_vdr/src/resolver/mod.rs b/libindy_vdr/src/resolver/mod.rs index a425f380..aac84685 100644 --- a/libindy_vdr/src/resolver/mod.rs +++ b/libindy_vdr/src/resolver/mod.rs @@ -1,8 +1,8 @@ -pub mod resolver; +pub mod pool; pub mod did; pub mod did_document; pub mod types; pub mod utils; -pub use self::resolver::{handle_resolution_result, PoolResolver, PoolRunnerResolver}; +pub use self::pool::{handle_resolution_result, PoolResolver, PoolRunnerResolver}; diff --git a/libindy_vdr/src/resolver/resolver.rs b/libindy_vdr/src/resolver/pool.rs similarity index 98% rename from libindy_vdr/src/resolver/resolver.rs rename to libindy_vdr/src/resolver/pool.rs index cd755efc..e7ad5e9b 100644 --- a/libindy_vdr/src/resolver/resolver.rs +++ b/libindy_vdr/src/resolver/pool.rs @@ -70,11 +70,11 @@ impl PoolResolver { let mut seq_no = None; let mut timestamp = None; - if *j_seq_no != serde_json::Value::Null { + if !j_seq_no.is_null() { seq_no = j_seq_no.as_u64().map(|v| v as i32); } - if *j_timestamp != serde_json::Value::Null { + if !j_timestamp.is_null() { timestamp = j_timestamp.as_u64(); // Use timestamp if possible if timestamp.is_some() { diff --git a/libindy_vdr/src/resolver/utils.rs b/libindy_vdr/src/resolver/utils.rs index 931492a0..af37bbf1 100644 --- a/libindy_vdr/src/resolver/utils.rs +++ b/libindy_vdr/src/resolver/utils.rs @@ -227,10 +227,9 @@ pub fn handle_internal_resolution_result( pub fn parse_ledger_data(ledger_data: &str) -> VdrResult<(SJsonValue, SJsonValue, SJsonValue)> { let v: SJsonValue = serde_json::from_str(ledger_data) .map_err(|_| err_msg(VdrErrorKind::Resolver, "Could not parse ledger response"))?; - // Unwrap should be safe here - let txn_type = (&v["result"]["type"]).to_owned(); - let data = (&v["result"]["data"]).to_owned(); - if data == SJsonValue::Null { + let txn_type = v["result"]["type"].to_owned(); + let data = v["result"]["data"].to_owned(); + if data.is_null() { Err(err_msg(VdrErrorKind::Resolver, "Object not found")) } else { Ok((v, txn_type, data)) From 31177537cdb7a9088e8e5600804e94996b4b1493 Mon Sep 17 00:00:00 2001 From: Andrew Whitehead Date: Thu, 27 Jul 2023 09:59:54 -0700 Subject: [PATCH 094/117] enable tests Signed-off-by: Andrew Whitehead --- libindy_vdr/tests/nym.rs | 112 ++++++++++++++-------------- libindy_vdr/tests/resolver.rs | 74 +++++++++--------- libindy_vdr/tests/utils/fixtures.rs | 11 ++- 3 files changed, 97 insertions(+), 100 deletions(-) diff --git a/libindy_vdr/tests/nym.rs b/libindy_vdr/tests/nym.rs index 27789cd4..5b5c69fe 100644 --- a/libindy_vdr/tests/nym.rs +++ b/libindy_vdr/tests/nym.rs @@ -449,62 +449,60 @@ mod send { assert_eq!(expected_data, serde_json::to_value(data).unwrap()); } - // FIXME: Uncomment as soon as indy-utils is updated - // #[cfg(feature = "did_indy")] - // #[rstest] - // fn test_pool_send_nym_request_with_version_2_works( - // pool: TestPool, - // trustee: Identity, - // identity_v2: Identity, - // diddoc_content: serde_json::Value, - // ) { - // // Send NYM - // let identity = identity_v2; - // let mut nym_request = pool - // .request_builder() - // .build_nym_request( - // &trustee.did, - // &identity.did, - // Some(identity.verkey.to_string()), - // Some(ALIAS.to_string()), - // Some(ROLE.to_string()), - // Some(&diddoc_content), - // Some(2), - // ) - // .unwrap(); - - // let nym_response = - // helpers::sign_and_send_request(&trustee, &pool, &mut nym_request).unwrap(); - - // // Get NYM - // let get_nym_request = pool - // .request_builder() - // .build_get_nym_request(None, &identity.did, None, None) - // .unwrap(); - - // let response = pool - // .send_request_with_retries(&get_nym_request, &nym_response) - // .unwrap(); - - // let expected_data = json!({ - // "identifier": &trustee.did, - // "dest": &identity.did, - // "verkey": &identity.verkey, - // "role": role_to_code(Some(String::from(ROLE))).unwrap(), - // "diddocContent": &diddoc_content.to_string(), - // "version": 2, - // }); - - // let data: GetNymResultV1 = serde_json::from_str( - // helpers::get_response_data(&response) - // .unwrap() - // .as_str() - // .unwrap(), - // ) - // .unwrap(); - - // assert_eq!(expected_data, serde_json::to_value(data).unwrap()); - // } + #[rstest] + fn test_pool_send_nym_request_with_version_2_works( + pool: TestPool, + trustee: Identity, + identity_v2: Identity, + diddoc_content: serde_json::Value, + ) { + // Send NYM + let identity = identity_v2; + let mut nym_request = pool + .request_builder() + .build_nym_request( + &trustee.did, + &identity.did, + Some(identity.verkey.to_string()), + Some(ALIAS.to_string()), + Some(ROLE.to_string()), + Some(&diddoc_content), + Some(2), + ) + .unwrap(); + + let nym_response = + helpers::sign_and_send_request(&trustee, &pool, &mut nym_request).unwrap(); + + // Get NYM + let get_nym_request = pool + .request_builder() + .build_get_nym_request(None, &identity.did, None, None) + .unwrap(); + + let response = pool + .send_request_with_retries(&get_nym_request, &nym_response) + .unwrap(); + + let expected_data = json!({ + "identifier": &trustee.did, + "dest": &identity.did, + "verkey": &identity.verkey, + "role": role_to_code(Some(String::from(ROLE))).unwrap(), + "diddocContent": &diddoc_content.to_string(), + "version": 2, + }); + + let data: GetNymResultV1 = serde_json::from_str( + helpers::get_response_data(&response) + .unwrap() + .as_str() + .unwrap(), + ) + .unwrap(); + + assert_eq!(expected_data, serde_json::to_value(data).unwrap()); + } #[rstest( role, @@ -707,7 +705,7 @@ mod send { fn parse_get_nym_response(response: &str) -> serde_json::Value { let data = helpers::get_response_data(response).unwrap(); - let data: serde_json::Value = serde_json::from_str(&data.as_str().unwrap()).unwrap(); + let data: serde_json::Value = serde_json::from_str(data.as_str().unwrap()).unwrap(); json!({ "dest": data["dest"], "verkey": data["verkey"], diff --git a/libindy_vdr/tests/resolver.rs b/libindy_vdr/tests/resolver.rs index 786cfd1b..058ba6c6 100644 --- a/libindy_vdr/tests/resolver.rs +++ b/libindy_vdr/tests/resolver.rs @@ -69,41 +69,41 @@ mod send_resolver { assert_ne!(&serde_json::Value::Null, diddoc) } - // #[rstest] - // fn test_pool_resolve_did_with_version_id( - // pool: TestPool, - // trustee: Identity, - // identity: Identity - // ) { - // // Send NYM - // let mut nym_request = pool - // .request_builder() - // .build_nym_request( - // &trustee.did, - // &identity.did, - // Some(identity.verkey.to_string()), - // None, - // None, - // None, - // None, - // ) - // .unwrap(); - - // let _nym_response = - // helpers::sign_and_send_request(&trustee, &pool, &mut nym_request).unwrap(); - - // // Resolve DID - // let resolver = Resolver::new(pool.pool); - // let qualified_did = format!("did:indy:test:{}", &identity.did); - // let did_url = format!("{}?versionId=1", qualified_did); - // let result = block_on(resolver.resolve(&did_url)).unwrap(); - - // let v: serde_json::Value = serde_json::from_str(result.as_str()).unwrap(); - - // let diddoc = &v["didDocument"]; - // let metadata = &v["didDocumentMetadata"]; - - // assert_eq!("NYM", metadata["objectType"]); - // assert_ne!(&serde_json::Value::Null, diddoc); - // } + #[rstest] + fn test_pool_resolve_did_with_version_id( + pool: TestPool, + trustee: Identity, + identity: Identity, + ) { + // Send NYM + let mut nym_request = pool + .request_builder() + .build_nym_request( + &trustee.did, + &identity.did, + Some(identity.verkey.to_string()), + None, + None, + None, + None, + ) + .unwrap(); + + let _nym_response = + helpers::sign_and_send_request(&trustee, &pool, &mut nym_request).unwrap(); + + // Resolve DID + let resolver = Resolver::new(pool.pool); + let qualified_did = format!("did:indy:test:{}", &identity.did); + let did_url = format!("{}?versionId=1", qualified_did); + let result = block_on(resolver.resolve(&did_url)).unwrap(); + + let v: serde_json::Value = serde_json::from_str(result.as_str()).unwrap(); + + let diddoc = &v["didDocument"]; + let metadata = &v["didDocumentMetadata"]; + + assert_eq!("NYM", metadata["objectType"]); + assert_ne!(&serde_json::Value::Null, diddoc); + } } diff --git a/libindy_vdr/tests/utils/fixtures.rs b/libindy_vdr/tests/utils/fixtures.rs index 0f8e00c8..630ab4f3 100644 --- a/libindy_vdr/tests/utils/fixtures.rs +++ b/libindy_vdr/tests/utils/fixtures.rs @@ -50,12 +50,11 @@ pub fn identity() -> Identity { Identity::new(None, None) } -// FIXME: Uncomment as soon as indy-utils is updated -// #[fixture] -// // did:indy self-certified DID -// pub fn identity_v2() -> Identity { -// Identity::new(None, Some(2)) -// } +#[fixture] +// did:indy self-certified DID +pub fn identity_v2() -> Identity { + Identity::new(None, Some(2)) +} #[fixture] // Generate a random DID without relation to the pubkey From 2979752e1ad4d6fd0222628c441b5bd4e71a89d2 Mon Sep 17 00:00:00 2001 From: Andrew Whitehead Date: Thu, 27 Jul 2023 10:56:37 -0700 Subject: [PATCH 095/117] update dependencies Signed-off-by: Andrew Whitehead --- libindy_vdr/Cargo.toml | 21 +++++++++++++++------ libindy_vdr/tests/utils/crypto.rs | 6 ++---- libindy_vdr/tests/utils/helpers.rs | 2 +- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/libindy_vdr/Cargo.toml b/libindy_vdr/Cargo.toml index 02345beb..b7a5ca40 100644 --- a/libindy_vdr/Cargo.toml +++ b/libindy_vdr/Cargo.toml @@ -1,7 +1,9 @@ [package] name = "indy-vdr" version = "0.4.0-dev.16" -authors = ["Hyperledger Indy Contributors "] +authors = [ + "Hyperledger Indy Contributors ", +] description = "A library for interacting with Hyperledger Indy Node, a distributed ledger for self-sovereign identity (https://www.hyperledger.org/use/hyperledger-indy)." edition = "2021" rust-version = "1.63" @@ -35,9 +37,14 @@ futures-channel = "0.3" futures-executor = "0.3" futures-util = "0.3" hex = "0.4" -hex-literal = "0.3" -indy-data-types = "0.5" -indy-utils = { version = "0.5", default-features = false, features = ["base64", "ed25519", "hash", "txn_signature"] } +hex-literal = "0.4" +indy-data-types = { version = "0.6", features = ["merkle_tree"] } +indy-utils = { version = "0.5.2", default-features = false, features = [ + "base64", + "ed25519", + "hash", + "txn_signature", +] } once_cell = "1.5" log = { version = "0.4", optional = true } percent-encoding = "2.2" @@ -59,7 +66,9 @@ default-features = false features = ["bls_bn254"] [dev-dependencies] -rstest = "0.16" +rstest = "0.18" time = "0.3" -indy-data-types = { version = "0.5", default-features = false, features = ["rich_schema"] } +indy-data-types = { version = "0.6", default-features = false, features = [ + "rich_schema", +] } indy-test-utils = { version = "0.1" } diff --git a/libindy_vdr/tests/utils/crypto.rs b/libindy_vdr/tests/utils/crypto.rs index 35a12a81..e1c2f74e 100644 --- a/libindy_vdr/tests/utils/crypto.rs +++ b/libindy_vdr/tests/utils/crypto.rs @@ -16,11 +16,9 @@ impl Identity { Identity::new(Some(TRUSTEE_SEED), None) } - pub fn new(seed: Option<[u8; 32]>, _version: Option) -> Identity { + pub fn new(seed: Option<[u8; 32]>, version: Option) -> Identity { let (short_did, private_key, public_key) = - // generate_did(seed.as_ref().map(|s| &s[..]), version).unwrap(); - // FIXME: Use commented method, as soon as indy-utils is updated - generate_did(seed.as_ref().map(|s| &s[..])).unwrap(); + generate_did(seed.as_ref().map(|s| &s[..]), version).unwrap(); let verkey = public_key.as_base58().unwrap().to_string(); diff --git a/libindy_vdr/tests/utils/helpers.rs b/libindy_vdr/tests/utils/helpers.rs index 1afae230..f1d3862b 100644 --- a/libindy_vdr/tests/utils/helpers.rs +++ b/libindy_vdr/tests/utils/helpers.rs @@ -289,7 +289,7 @@ pub mod revoc_reg { pub fn revoc_reg_entry_value() -> serde_json::Value { json!({ - "accum": "1 0000000000000000000000000000000000000000000000000000000000000000 1 0000000000000000000000000000000000000000000000000000000000000000 1 0000000000000000000000000000000000000000000000000000000000000000 1 0000000000000000000000000000000000000000000000000000000000000000 1 0000000000000000000000000000000000000000000000000000000000000000 1 0000000000000000000000000000000000000000000000000000000000000000" + "accum": "21 121E4902163FA84792C3E4C2E604C82ED26BD38E1E2F5F01C225FBA626E32643E 21 142EAE10B26DE9509795080384CA7FB7CDBF1930123B074316C4CE57C0E31BA18 6 6F0359B45CAB4B6BD99B1E84F5A3B2B898C85FE5FA70587A2B50BB7D3E96F6AA 4 10D027488E3C9EE878D6C22B3E03E0CC7383AFB886FAC4C4A3AE2A4102B59C93 6 573ADA67E24E89B506C8524AAD657D0D96B0490D3889E3EF4919A0C347D08D43 4 285EB88031AE201869561751CF761E71D482FC01795746CB7BE81B8FDAB7DAA9" }) } From b6336fc18e0c04c544fcc963c2462e098ad26b24 Mon Sep 17 00:00:00 2001 From: Andrew Whitehead Date: Thu, 27 Jul 2023 11:33:17 -0700 Subject: [PATCH 096/117] vendored openssl Signed-off-by: Andrew Whitehead --- libindy_vdr/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libindy_vdr/Cargo.toml b/libindy_vdr/Cargo.toml index b7a5ca40..0956f059 100644 --- a/libindy_vdr/Cargo.toml +++ b/libindy_vdr/Cargo.toml @@ -38,7 +38,7 @@ futures-executor = "0.3" futures-util = "0.3" hex = "0.4" hex-literal = "0.4" -indy-data-types = { version = "0.6", features = ["merkle_tree"] } +indy-data-types = { version = "0.6", features = ["merkle_tree", "vendored"] } indy-utils = { version = "0.5.2", default-features = false, features = [ "base64", "ed25519", From e56e1f2eeb3b865b8caa8f94f67f10b29096a392 Mon Sep 17 00:00:00 2001 From: Andrew Whitehead Date: Thu, 27 Jul 2023 12:27:59 -0700 Subject: [PATCH 097/117] clean up warnings Signed-off-by: Andrew Whitehead --- indy-vdr-proxy/src/handlers.rs | 16 ++++++++-------- indy-vdr-proxy/src/main.rs | 2 +- .../src/ledger/requests/author_agreement.rs | 8 +++++++- libindy_vdr/src/ledger/requests/flag.rs | 4 +--- .../src/ledger/requests/validator_info.rs | 6 ++++++ libindy_vdr/src/pool/genesis.rs | 14 +++++++------- libindy_vdr/src/pool/handlers/consensus.rs | 2 +- libindy_vdr/src/pool/networker/zmq.rs | 8 ++++---- libindy_vdr/src/pool/types.rs | 2 +- libindy_vdr/src/state_proof/mod.rs | 12 ++++++------ libindy_vdr/src/state_proof/node.rs | 2 +- libindy_vdr/src/state_proof/types.rs | 9 ++------- libindy_vdr/tests/flag.rs | 4 ++-- 13 files changed, 47 insertions(+), 42 deletions(-) diff --git a/indy-vdr-proxy/src/handlers.rs b/indy-vdr-proxy/src/handlers.rs index cda98522..561387f8 100644 --- a/indy-vdr-proxy/src/handlers.rs +++ b/indy-vdr-proxy/src/handlers.rs @@ -421,7 +421,7 @@ async fn submit_request(pool: &T, message: Vec) -> VdrResult( +pub async fn handle_request( req: Request, state: Rc>, ) -> Result, hyper::Error> { @@ -562,7 +562,7 @@ pub async fn handle_request( let timestamp: Option = query_params .get("timestamp") .and_then(|ts| ts.as_str().parse().ok()); - get_attrib(&pool, &*dest, &*attrib, seq_no, timestamp).await + get_attrib(&pool, &dest, &attrib, seq_no, timestamp).await } else { http_status(StatusCode::NOT_FOUND) } @@ -586,7 +586,7 @@ pub async fn handle_request( } (&Method::GET, "cred_def") => { if let Some(cred_def_id) = parts.next() { - get_cred_def(&pool, &*cred_def_id).await + get_cred_def(&pool, &cred_def_id).await } else { http_status(StatusCode::NOT_FOUND) } @@ -599,35 +599,35 @@ pub async fn handle_request( let timestamp: Option = query_params .get("timestamp") .and_then(|ts| ts.as_str().parse().ok()); - get_nym(&pool, &*nym, seq_no, timestamp).await + get_nym(&pool, &nym, seq_no, timestamp).await } else { http_status(StatusCode::NOT_FOUND) } } (&Method::GET, "rev_reg_def") => { if let Some(rev_reg_def_id) = parts.next() { - get_revoc_reg_def(&pool, &*rev_reg_def_id).await + get_revoc_reg_def(&pool, &rev_reg_def_id).await } else { http_status(StatusCode::NOT_FOUND) } } (&Method::GET, "rev_reg") => { if let Some(rev_reg_def_id) = parts.next() { - get_revoc_reg(&pool, &*rev_reg_def_id).await + get_revoc_reg(&pool, &rev_reg_def_id).await } else { http_status(StatusCode::NOT_FOUND) } } (&Method::GET, "rev_reg_delta") => { if let Some(rev_reg_def_id) = parts.next() { - get_revoc_reg_delta(&pool, &*rev_reg_def_id).await + get_revoc_reg_delta(&pool, &rev_reg_def_id).await } else { http_status(StatusCode::NOT_FOUND) } } (&Method::GET, "schema") => { if let Some(schema_id) = parts.next() { - get_schema(&pool, &*schema_id).await + get_schema(&pool, &schema_id).await } else { http_status(StatusCode::NOT_FOUND) } diff --git a/indy-vdr-proxy/src/main.rs b/indy-vdr-proxy/src/main.rs index 744eee6b..4b112c35 100644 --- a/indy-vdr-proxy/src/main.rs +++ b/indy-vdr-proxy/src/main.rs @@ -374,7 +374,7 @@ where async move { let state = state.clone(); Ok::<_, hyper::Error>(service_fn(move |req| { - handlers::handle_request::(req, state.to_owned()) + handlers::handle_request(req, state.to_owned()) })) } }); diff --git a/libindy_vdr/src/ledger/requests/author_agreement.rs b/libindy_vdr/src/ledger/requests/author_agreement.rs index bf91ebca..bcebfc5b 100644 --- a/libindy_vdr/src/ledger/requests/author_agreement.rs +++ b/libindy_vdr/src/ledger/requests/author_agreement.rs @@ -120,7 +120,7 @@ impl RequestType for GetTxnAuthorAgreementOperation { } } -#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)] +#[derive(Debug, Clone, Default, Deserialize, Serialize, PartialEq)] pub struct AcceptanceMechanisms(pub HashMap); impl AcceptanceMechanisms { @@ -225,6 +225,12 @@ impl DisableAllTxnAuthorAgreementsOperation { } } +impl Default for DisableAllTxnAuthorAgreementsOperation { + fn default() -> Self { + Self::new() + } +} + impl RequestType for DisableAllTxnAuthorAgreementsOperation { fn get_txn_type<'a>() -> &'a str { DISABLE_ALL_TXN_AUTHR_AGRMTS diff --git a/libindy_vdr/src/ledger/requests/flag.rs b/libindy_vdr/src/ledger/requests/flag.rs index fb39f56a..c8b5ccce 100644 --- a/libindy_vdr/src/ledger/requests/flag.rs +++ b/libindy_vdr/src/ledger/requests/flag.rs @@ -59,9 +59,7 @@ impl RequestType for GetFlagOperation { if !self.name.is_empty() { let marker = get_sp_key_marker(2, _protocol_version); return Ok(Some( - format!("{}:{}", marker, self.name.to_string()) - .as_bytes() - .to_vec(), + format!("{}:{}", marker, self.name).as_bytes().to_vec(), )); } Ok(None) diff --git a/libindy_vdr/src/ledger/requests/validator_info.rs b/libindy_vdr/src/ledger/requests/validator_info.rs index 591e850d..be6dcf79 100644 --- a/libindy_vdr/src/ledger/requests/validator_info.rs +++ b/libindy_vdr/src/ledger/requests/validator_info.rs @@ -15,6 +15,12 @@ impl GetValidatorInfoOperation { } } +impl Default for GetValidatorInfoOperation { + fn default() -> Self { + Self::new() + } +} + impl RequestType for GetValidatorInfoOperation { fn get_txn_type<'a>() -> &'a str { GET_VALIDATOR_INFO diff --git a/libindy_vdr/src/pool/genesis.rs b/libindy_vdr/src/pool/genesis.rs index 8874c980..2a4003a0 100644 --- a/libindy_vdr/src/pool/genesis.rs +++ b/libindy_vdr/src/pool/genesis.rs @@ -276,7 +276,7 @@ pub fn build_verifiers(txn_map: NodeTransactionMap) -> VdrResult { .to_vec(); let client_addr = match (&txn.txn.data.data.client_ip, &txn.txn.data.data.client_port) { - (&Some(ref client_ip), &Some(ref client_port)) => { + (Some(ref client_ip), Some(ref client_port)) => { format!("tcp://{}:{}", client_ip, client_port) } _ => { @@ -288,7 +288,7 @@ pub fn build_verifiers(txn_map: NodeTransactionMap) -> VdrResult { }; let node_addr = match (&txn.txn.data.data.node_ip, &txn.txn.data.data.node_port) { - (&Some(ref node_ip), &Some(ref node_port)) => { + (Some(ref node_ip), Some(ref node_port)) => { format!("tcp://{}:{}", node_ip, node_port) } _ => { @@ -379,7 +379,7 @@ mod tests { } pub fn _merkle_tree() -> MerkleTree { - PoolTransactions::from_json_transactions(&_transactions()) + PoolTransactions::from_json_transactions(_transactions()) .unwrap() .merkle_tree() .unwrap() @@ -390,7 +390,7 @@ mod tests { let transaction = GenesisTransactions::new(None); let transactions: PoolTransactions = - PoolTransactions::from_json_transactions(&transaction.transactions).unwrap(); + PoolTransactions::from_json_transactions(transaction.transactions).unwrap(); assert_eq!( transactions.encode_json().unwrap(), @@ -403,7 +403,7 @@ mod tests { let mut transaction = GenesisTransactions::new(None); let file = transaction.store_to_file(); - let transactions: PoolTransactions = PoolTransactions::from_json_file(&file).unwrap(); + let transactions: PoolTransactions = PoolTransactions::from_json_file(file).unwrap(); assert_eq!( transactions.encode_json().unwrap(), @@ -418,12 +418,12 @@ mod tests { transaction.store_to_file() }; - let _err = PoolTransactions::from_json_file(&file).unwrap_err(); + let _err = PoolTransactions::from_json_file(file).unwrap_err(); } #[test] fn test_pool_transactions_from_file_for_invalid_transactions() { - let mut txns = GenesisTransactions::from_transactions(&[r#"{invalid}"#]); + let mut txns = GenesisTransactions::from_transactions([r#"{invalid}"#]); let _err = PoolTransactions::from_json_file(txns.store_to_file()).unwrap_err(); } diff --git a/libindy_vdr/src/pool/handlers/consensus.rs b/libindy_vdr/src/pool/handlers/consensus.rs index a056899f..7ab98009 100644 --- a/libindy_vdr/src/pool/handlers/consensus.rs +++ b/libindy_vdr/src/pool/handlers/consensus.rs @@ -77,7 +77,7 @@ pub async fn handle_consensus_request( && check_state_proof( result, f, - &*DEFAULT_GENERATOR, + &DEFAULT_GENERATOR, &node_keys, &raw_msg, state_proof_key.as_deref(), diff --git a/libindy_vdr/src/pool/networker/zmq.rs b/libindy_vdr/src/pool/networker/zmq.rs index 57ffd99e..aebc1c5c 100644 --- a/libindy_vdr/src/pool/networker/zmq.rs +++ b/libindy_vdr/src/pool/networker/zmq.rs @@ -512,7 +512,7 @@ impl ZMQConnection { } fn fetch_event(&self, index: usize, poll_item: &zmq::PollItem) -> Option { - if let (&Some(ref s), rn) = (&self.sockets[index], &self.remotes[index]) { + if let (Some(ref s), rn) = (&self.sockets[index], &self.remotes[index]) { if poll_item.is_readable() { if let Ok(Ok(msg)) = s.recv_string(zmq::DONTWAIT) { trace!("Socket reply {} {}", &rn.name, &msg); @@ -645,7 +645,7 @@ impl ZMQConnection { && !self .socket_timeouts .keys() - .any(|&(ref req_id_timeout, _)| req_id == req_id_timeout) + .any(|(ref req_id_timeout, _)| req_id == req_id_timeout) { self.set_idle_timeout(req_id.to_string()) } @@ -655,7 +655,7 @@ impl ZMQConnection { .socket_timeouts .keys() .cloned() - .filter(|&(ref req_id_timeout, _)| req_id == req_id_timeout) + .filter(|(ref req_id_timeout, _)| req_id == req_id_timeout) .collect(); keys_to_remove.iter().for_each(|key| { self.socket_timeouts.remove(key); @@ -721,7 +721,7 @@ impl RemoteNode { socks_proxy: Option, ) -> VdrResult { let s = ctx.socket(zmq::SocketType::DEALER)?; - s.set_identity(base64::encode(&key_pair.public_key).as_bytes())?; + s.set_identity(base64::encode(key_pair.public_key).as_bytes())?; s.set_curve_secretkey(&key_pair.secret_key)?; s.set_curve_publickey(&key_pair.public_key)?; s.set_curve_serverkey( diff --git a/libindy_vdr/src/pool/types.rs b/libindy_vdr/src/pool/types.rs index 203075ba..f7b313e3 100644 --- a/libindy_vdr/src/pool/types.rs +++ b/libindy_vdr/src/pool/types.rs @@ -559,7 +559,7 @@ impl Message { } pub fn serialize(&self) -> VdrResult { - serde_json::to_value(&self).with_input_err("Cannot serialize message") + serde_json::to_value(self).with_input_err("Cannot serialize message") } } diff --git a/libindy_vdr/src/state_proof/mod.rs b/libindy_vdr/src/state_proof/mod.rs index 4dc0aff0..8690bc5e 100644 --- a/libindy_vdr/src/state_proof/mod.rs +++ b/libindy_vdr/src/state_proof/mod.rs @@ -732,7 +732,7 @@ fn _parse_reply_for_sp( let proof = if let Some(path) = parsed_data["auditPath"].as_array() { let path_str = json!(path).to_string(); trace!("parse_reply_for_builtin_sp: proof: {:?}", path); - base64::encode(&path_str) + base64::encode(path_str) } else { return Err(input_err("No proof")); }; @@ -928,7 +928,7 @@ fn _verify_merkle_tree( return false; } let seq_no = in_closure! { - let key = base64::decode(&key).map_err_string()?; + let key = base64::decode(key).map_err_string()?; let key = std::str::from_utf8(&key).map_err_string()?; key.parse::().map_err_string() }; @@ -1103,7 +1103,7 @@ fn _verify_proof_range( } else { vals_with_from.as_slice() }; - let vals_prepared: Vec<(String, Option)> = vals_slice.iter().map(|&(_, ref pair)| pair.clone()).collect(); + let vals_prepared: Vec<(String, Option)> = vals_slice.iter().map(|(_, ref pair)| pair.clone()).collect(); vals_prepared[..] == kvs[..] }).unwrap_or(false) } @@ -2008,7 +2008,7 @@ mod tests { } }); - let nodes_str = base64::encode(&json!(["1", "2"]).to_string()); + let nodes_str = base64::encode(json!(["1", "2"]).to_string()); let mut parsed_sps = super::parse_generic_reply_for_proof_checking(json_msg, "", Some("2".as_bytes()), None) @@ -2045,7 +2045,7 @@ mod tests { } }); - let nodes_str = base64::encode(&json!(["1", "2"]).to_string()); + let nodes_str = base64::encode(json!(["1", "2"]).to_string()); let mut parsed_sps = super::parse_generic_reply_for_proof_checking(json_msg, "", Some("2".as_bytes()), None) @@ -2108,7 +2108,7 @@ mod tests { } }); - let nodes_str = base64::encode(&json!(["1", "2"]).to_string()); + let nodes_str = base64::encode(json!(["1", "2"]).to_string()); let mut parsed_sps = super::parse_generic_reply_for_proof_checking(json_msg, "", Some("2".as_bytes()), None) diff --git a/libindy_vdr/src/state_proof/node.rs b/libindy_vdr/src/state_proof/node.rs index 89827527..1fae618f 100644 --- a/libindy_vdr/src/state_proof/node.rs +++ b/libindy_vdr/src/state_proof/node.rs @@ -476,6 +476,6 @@ mod tests { #[test] fn node_serialize_works_for_emtpy() { - assert_eq!(base64::encode(&rlp::encode_list(&[Node::Blank])), "wYA="); + assert_eq!(base64::encode(rlp::encode_list(&[Node::Blank])), "wYA="); } } diff --git a/libindy_vdr/src/state_proof/types.rs b/libindy_vdr/src/state_proof/types.rs index 2c0eef44..05c2e325 100644 --- a/libindy_vdr/src/state_proof/types.rs +++ b/libindy_vdr/src/state_proof/types.rs @@ -35,10 +35,11 @@ pub struct KeyValueSimpleData { } /// Options for the common state proof check process -#[derive(Serialize, Deserialize, Debug, Eq, PartialEq)] +#[derive(Serialize, Deserialize, Debug, Default, Eq, PartialEq)] #[serde(tag = "type")] pub enum KeyValueSimpleDataVerificationType { /* key should be base64-encoded string */ + #[default] Simple, /* key should be plain string */ NumericalSuffixAscendingNoGaps(NumericalSuffixAscendingNoGapsData), @@ -46,12 +47,6 @@ pub enum KeyValueSimpleDataVerificationType { MerkleTree(u64), } -impl Default for KeyValueSimpleDataVerificationType { - fn default() -> Self { - KeyValueSimpleDataVerificationType::Simple - } -} - #[derive(Serialize, Deserialize, Debug, Eq, PartialEq)] pub struct NumericalSuffixAscendingNoGapsData { pub from: Option, diff --git a/libindy_vdr/tests/flag.rs b/libindy_vdr/tests/flag.rs index 329ac74b..dd36eac2 100644 --- a/libindy_vdr/tests/flag.rs +++ b/libindy_vdr/tests/flag.rs @@ -9,8 +9,8 @@ use indy_vdr::utils::did::DidValue; use crate::utils::fixtures::*; use crate::utils::helpers; -const FLAG_NAME: &'static str = r#"REV_STRATEGY_USE_COMPAT_ORDERING"#; -const FLAG_VALUE: &'static str = r#"True"#; +const FLAG_NAME: &str = r#"REV_STRATEGY_USE_COMPAT_ORDERING"#; +const FLAG_VALUE: &str = r#"True"#; #[test] fn empty() { From 950d6a0f6555684e128528c0665549364e5b3929 Mon Sep 17 00:00:00 2001 From: Andrew Whitehead Date: Thu, 27 Jul 2023 12:28:14 -0700 Subject: [PATCH 098/117] fix build error on windows Signed-off-by: Andrew Whitehead --- .github/workflows/build.yml | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index bfd90275..83c99c55 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -142,17 +142,22 @@ jobs: shared-key: deps save-if: false - - name: Build - shell: sh + - if: ${{ matrix.use_cross }} + name: Build (cross) + run: | + cargo install --bins --git https://github.com/rust-embedded/cross --tag v${{ env.CROSS_VERSION }} cross + cross build --lib --release --target ${{ matrix.target }} + + - if: ${{ !matrix.use_cross && matrix.architecture == 'darwin-universal' }} + name: Build (mac) + run: ./build-universal.sh + + # Requires using the default shell on Windows, otherwise it will complain: + # "This perl implementation doesn't produce Windows like paths" + - if: ${{ !matrix.use_cross && matrix.architecture != 'darwin-universal' }} + name: Build (standard) run: | - if [ -n "${{ matrix.use_cross }}" ]; then - cargo install --bins --git https://github.com/rust-embedded/cross --tag v${{ env.CROSS_VERSION }} cross - cross build --lib --release --target ${{ matrix.target }} - elif [ "${{ matrix.architecture }}" == "darwin-universal" ]; then - ./build-universal.sh - else - cargo build --lib --release --target ${{ matrix.target }} - fi + cargo build --lib --release --target ${{ matrix.target }} - name: Upload library artifacts uses: actions/upload-artifact@v3 From ac121e8857e8a659ea5a04c2226d80fb8e1feffd Mon Sep 17 00:00:00 2001 From: Andrew Whitehead Date: Thu, 27 Jul 2023 12:51:04 -0700 Subject: [PATCH 099/117] adjust versionId test Signed-off-by: Andrew Whitehead --- libindy_vdr/tests/resolver.rs | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/libindy_vdr/tests/resolver.rs b/libindy_vdr/tests/resolver.rs index 058ba6c6..a3b46154 100644 --- a/libindy_vdr/tests/resolver.rs +++ b/libindy_vdr/tests/resolver.rs @@ -9,7 +9,7 @@ fn empty() { } #[cfg(test)] -#[cfg(feature = "local_nodes_pool")] +// #[cfg(feature = "local_nodes_pool")] mod send_resolver { use futures_executor::block_on; use indy_vdr::resolver::PoolResolver as Resolver; @@ -89,13 +89,26 @@ mod send_resolver { ) .unwrap(); - let _nym_response = + let nym_response = helpers::sign_and_send_request(&trustee, &pool, &mut nym_request).unwrap(); + println!("nym response: {nym_response}"); + + // Get NYM to make sure it was written before it gets resolved + let get_nym_request = pool + .request_builder() + .build_get_nym_request(None, &identity.did, None, None) + .unwrap(); + + let response = pool + .send_request_with_retries(&get_nym_request, &nym_response) + .unwrap(); + println!("get nym response: {nym_response}"); + let seq_no = TestPool::extract_seq_no_from_reply(response.as_str()).unwrap(); // Resolve DID let resolver = Resolver::new(pool.pool); let qualified_did = format!("did:indy:test:{}", &identity.did); - let did_url = format!("{}?versionId=1", qualified_did); + let did_url = format!("{}?versionId={}", qualified_did, seq_no); let result = block_on(resolver.resolve(&did_url)).unwrap(); let v: serde_json::Value = serde_json::from_str(result.as_str()).unwrap(); From 1994640ee01086f9964570b966b88ecc2811b7f1 Mon Sep 17 00:00:00 2001 From: Andrew Whitehead Date: Fri, 4 Aug 2023 14:03:33 -0700 Subject: [PATCH 100/117] update base64 dependency Signed-off-by: Andrew Whitehead --- libindy_vdr/Cargo.toml | 2 +- libindy_vdr/src/utils/base64.rs | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/libindy_vdr/Cargo.toml b/libindy_vdr/Cargo.toml index 71237242..fdb07536 100644 --- a/libindy_vdr/Cargo.toml +++ b/libindy_vdr/Cargo.toml @@ -30,7 +30,7 @@ default = ["ffi", "log", "zmq_vendored"] # This is added so we can lock the version that zmq uses # 0.1.49 is broken for ios targets cmake = { version = "=0.1.48", optional = true } -base64_rs = { package = "base64", version = "0.13" } +base64_rs = { package = "base64", version = "0.21" } bs58 = "0.5" etcommon-rlp = "0.2.4" env_logger = { version = "0.10", optional = true } diff --git a/libindy_vdr/src/utils/base64.rs b/libindy_vdr/src/utils/base64.rs index f5012d37..6d721a88 100644 --- a/libindy_vdr/src/utils/base64.rs +++ b/libindy_vdr/src/utils/base64.rs @@ -1,18 +1,19 @@ -use base64_rs as base64; - -pub use base64::encode; +use base64_rs::Engine; use super::ConversionError; pub fn decode>(val: T) -> Result, ConversionError> { - Ok(base64::decode(val).map_err(|err| ("Error decoding base64 data", err))?) + Ok(base64_rs::engine::general_purpose::STANDARD + .decode(val) + .map_err(|err| ("Error decoding base64 data", err))?) } pub fn decode_urlsafe>(val: T) -> Result, ConversionError> { - Ok(base64::decode_config(val, base64::URL_SAFE) + Ok(base64_rs::engine::general_purpose::URL_SAFE + .decode(val) .map_err(|err| ("Error decoding base64-URL data", err))?) } pub fn encode_urlsafe>(val: T) -> String { - base64::encode_config(val, base64::URL_SAFE) + base64_rs::engine::general_purpose::URL_SAFE.encode(val) } From 37d95f7da652a1737a523ed22eb83774bf9edb14 Mon Sep 17 00:00:00 2001 From: Andrew Whitehead Date: Fri, 4 Aug 2023 16:03:54 -0700 Subject: [PATCH 101/117] update to indy-utils 0.6, indy-data-types 0.6.1 Signed-off-by: Andrew Whitehead --- libindy_vdr/Cargo.toml | 11 ++- libindy_vdr/src/ledger/request_builder.rs | 6 +- libindy_vdr/src/ledger/requests/attrib.rs | 5 +- libindy_vdr/src/ledger/requests/nym.rs | 6 +- libindy_vdr/src/state_proof/mod.rs | 113 +++++++++++----------- libindy_vdr/src/utils/base64.rs | 4 + libindy_vdr/src/utils/mod.rs | 1 - libindy_vdr/src/utils/txn_signature.rs | 9 +- libindy_vdr/tests/resolver.rs | 2 +- 9 files changed, 82 insertions(+), 75 deletions(-) diff --git a/libindy_vdr/Cargo.toml b/libindy_vdr/Cargo.toml index fdb07536..c0e4d493 100644 --- a/libindy_vdr/Cargo.toml +++ b/libindy_vdr/Cargo.toml @@ -40,10 +40,12 @@ futures-executor = "0.3" futures-util = "0.3" hex = "0.4" hex-literal = "0.4" -indy-data-types = { version = "0.6", features = ["merkle_tree", "vendored"] } -indy-utils = { version = "0.5.2", default-features = false, features = [ +indy-data-types = { version = "0.6.1", default-features = false, features = [ + "anoncreds", + "merkle_tree", +] } +indy-utils = { version = "0.6", default-features = false, features = [ "ed25519", - "hash", ] } once_cell = "1.5" log = { version = "0.4", optional = true } @@ -54,6 +56,7 @@ regex = "1.3" rmp-serde = "1.0" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" +sha2 = "0.10" sha3 = "0.10" thiserror = "1.0" time = { version = "=0.3.20", features = ["parsing"] } @@ -68,7 +71,7 @@ features = ["bls_bn254"] [dev-dependencies] rstest = "0.18" time = "0.3" -indy-data-types = { version = "0.6", default-features = false, features = [ +indy-data-types = { version = "0.6.1", default-features = false, features = [ "rich_schema", ] } indy-test-utils = { version = "0.1" } diff --git a/libindy_vdr/src/ledger/request_builder.rs b/libindy_vdr/src/ledger/request_builder.rs index 0a497a85..bd94fdf5 100644 --- a/libindy_vdr/src/ledger/request_builder.rs +++ b/libindy_vdr/src/ledger/request_builder.rs @@ -1,10 +1,10 @@ use hex::FromHex; use serde_json::{self, Value as SJsonValue}; +use sha2::{Digest, Sha256}; use crate::common::error::prelude::*; use crate::pool::{new_request_id, PreparedRequest, ProtocolVersion, RequestMethod}; use crate::utils::did::{DidValue, DEFAULT_LIBINDY_DID}; -use crate::utils::hash::SHA256; use crate::utils::Qualifiable; #[cfg(any(feature = "rich_schema", test))] @@ -56,7 +56,7 @@ fn datetime_to_date_timestamp(time: u64) -> u64 { fn calculate_hash(text: &str, version: &str) -> VdrResult> { let content: String = version.to_string() + text; - Ok(SHA256::digest(content.as_bytes())) + Ok(Sha256::digest(content.as_bytes()).to_vec()) } fn compare_hash(text: &str, version: &str, hash: &str) -> VdrResult<()> { @@ -149,6 +149,7 @@ impl RequestBuilder { /// Build a `NYM` transaction request /// diddoc_content is only supported for did:indy compliant ledgers + #[allow(clippy::too_many_arguments)] pub fn build_nym_request( &self, identifier: &DidValue, @@ -203,6 +204,7 @@ impl RequestBuilder { /// Build a `GET_ATTRIB` transaction request /// seq_no and timestamp are only supported for did:indy compliant ledgers /// Use only one of seq_no and timestamp + #[allow(clippy::too_many_arguments)] pub fn build_get_attrib_request( &self, identifier: Option<&DidValue>, diff --git a/libindy_vdr/src/ledger/requests/attrib.rs b/libindy_vdr/src/ledger/requests/attrib.rs index 42ce7037..7b4f4b95 100644 --- a/libindy_vdr/src/ledger/requests/attrib.rs +++ b/libindy_vdr/src/ledger/requests/attrib.rs @@ -1,8 +1,9 @@ +use sha2::{Digest, Sha256}; + use super::constants::{ATTRIB, GET_ATTR}; use super::did::ShortDidValue; use super::{get_sp_key_marker, ProtocolVersion, RequestType}; use crate::common::error::VdrResult; -use crate::utils::hash::SHA256; #[derive(Serialize, PartialEq, Debug)] pub struct AttribOperation { @@ -91,7 +92,7 @@ impl RequestType for GetAttribOperation { .or(self.hash.as_ref()) { let marker = get_sp_key_marker(1, protocol_version); - let hash = SHA256::digest(attr_name.as_bytes()); + let hash = Sha256::digest(attr_name.as_bytes()); return Ok(Some( format!("{}:{}:{}", &*self.dest, marker, hex::encode(hash)) .as_bytes() diff --git a/libindy_vdr/src/ledger/requests/nym.rs b/libindy_vdr/src/ledger/requests/nym.rs index 2fa827a9..33b3eec7 100644 --- a/libindy_vdr/src/ledger/requests/nym.rs +++ b/libindy_vdr/src/ledger/requests/nym.rs @@ -1,9 +1,9 @@ -use crate::common::error::{input_err, VdrResult}; -use crate::utils::hash::SHA256; +use sha2::{Digest, Sha256}; use super::constants::{GET_NYM, NYM}; use super::did::ShortDidValue; use super::{ProtocolVersion, RequestType}; +use crate::common::error::{input_err, VdrResult}; use crate::ledger::constants::{ENDORSER, NETWORK_MONITOR, ROLES, ROLE_REMOVE, STEWARD, TRUSTEE}; #[derive(Serialize, PartialEq, Debug)] @@ -82,7 +82,7 @@ impl RequestType for GetNymOperation { } fn get_sp_key(&self, _protocol_version: ProtocolVersion) -> VdrResult>> { - let hash = SHA256::digest(self.dest.as_bytes()); + let hash = Sha256::digest(self.dest.as_bytes()).to_vec(); Ok(Some(hash)) } } diff --git a/libindy_vdr/src/state_proof/mod.rs b/libindy_vdr/src/state_proof/mod.rs index 8690bc5e..467ae682 100644 --- a/libindy_vdr/src/state_proof/mod.rs +++ b/libindy_vdr/src/state_proof/mod.rs @@ -7,18 +7,16 @@ pub(crate) mod types; use std::collections::HashMap; use std::time::{SystemTime, UNIX_EPOCH}; +use indy_data_types::merkle_tree::{MerkleTree, Positioned}; use rlp::UntrustedRlp; use serde_json::Value as SJsonValue; +use sha2::{Digest, Sha256}; use ursa::bls::{Bls, Generator, MultiSignature, VerKey}; use crate::common::error::prelude::*; use crate::pool::{ProtocolVersion, VerifierKeys}; use crate::utils::base58; use crate::utils::base64; -use crate::utils::hash::{ - TreeHash, - SHA256::{self, DigestType as Sha256}, -}; use self::constants::{ REQUESTS_FOR_MULTI_STATE_PROOFS, REQUESTS_FOR_STATE_PROOFS, @@ -81,6 +79,7 @@ where } } +#[allow(clippy::too_many_arguments)] pub(crate) fn check_state_proof( msg_result: &SJsonValue, f: usize, @@ -395,7 +394,7 @@ pub(crate) fn parse_key_from_request_for_builtin_sp( ); let marker = if is_node_1_3 { '\x01' } else { '1' }; - let hash = SHA256::digest(attr_name.as_bytes()); + let hash = Sha256::digest(attr_name.as_bytes()); format!(":{}:{}", marker, hex::encode(hash)) } else { trace!("parse_key_from_request_for_builtin_sp: <<< GET_ATTR No key suffix"); @@ -563,7 +562,7 @@ pub(crate) fn parse_key_from_request_for_builtin_sp( let key_prefix = match type_ { constants::GET_NYM => { if let Some(dest) = dest { - SHA256::digest(dest.as_bytes()) + Sha256::digest(dest.as_bytes()).to_vec() } else { debug!("parse_key_from_request_for_builtin_sp: <<< No dest"); return None; @@ -905,6 +904,23 @@ fn _verify_merkle_tree( kvs: &[(String, Option)], length: u64, ) -> bool { + let (key, value) = &kvs[0]; + if value.is_none() { + debug!("No value for merkle tree hash"); + return false; + } + let seq_no = in_closure! { + let key = base64::decode(key).map_err_string()?; + let key = std::str::from_utf8(&key).map_err_string()?; + key.parse::().map_err_string() + }; + let seq_no = unwrap_or_map_return!(seq_no, |err| { + debug!("Error while parsing merkle tree seq_no: {}", err); + false + }); + + let turns = _calculate_turns(length, seq_no - 1); + let nodes = match std::str::from_utf8(proof_nodes) { Ok(res) => res, Err(err) => { @@ -922,22 +938,6 @@ fn _verify_merkle_tree( trace!("_verify_merkle_tree >> hashes: {:?}", hashes); - let (key, value) = &kvs[0]; - if value.is_none() { - debug!("No value for merkle tree hash"); - return false; - } - let seq_no = in_closure! { - let key = base64::decode(key).map_err_string()?; - let key = std::str::from_utf8(&key).map_err_string()?; - key.parse::().map_err_string() - }; - let seq_no = unwrap_or_map_return!(seq_no, |err| { - debug!("Error while parsing merkle tree seq_no: {}", err); - false - }); - - let turns = _calculate_turns(length, seq_no - 1); trace!( "_verify_merkle_tree >> seq_no: {}, turns: {:?}", seq_no, @@ -949,49 +949,45 @@ fn _verify_merkle_tree( return false; } - let hashes_with_turns = hashes.iter().zip(turns).collect::>(); + let mut path = Vec::with_capacity(hashes.len()); + for (hash, t_right) in hashes.into_iter().zip(turns) { + let hash = unwrap_or_return!(base58::decode(hash), { + debug!("Error decoding hash as base58"); + false + }); + path.push(if t_right { + Positioned::Right(hash) + } else { + Positioned::Left(hash) + }); + } - let hash = in_closure! { + let leaf_value = in_closure! { let val = value.as_ref().unwrap(); let val = serde_json::from_str::(val).map_err_string()?; - let val = rmp_serde::to_vec(&val).map_err_string()?; - Sha256::hash_leaf(&val).map_err_string() + rmp_serde::to_vec(&val).map_err_string() }; - let mut hash = unwrap_or_map_return!(hash, |err| { - debug!("Error while hashing merkle tree leaf: {:?}", err); + let leaf_value = unwrap_or_map_return!(leaf_value, |err| { + debug!("Error while decoding merkle tree leaf: {:?}", err); false }); - trace!("Hashed leaf in b58: {}", base58::encode(&hash)); + trace!("Leaf value: {}", base58::encode(&leaf_value)); - for (next_hash, turn_right) in hashes_with_turns { - let _next_hash = unwrap_or_return!(base58::decode(next_hash), { - debug!("Error decoding next hash as base58"); + match MerkleTree::check_inclusion_proof(root_hash, &leaf_value, &path) { + Ok(true) => { + trace!("Matched root hash: {}", base58::encode(root_hash)); + true + } + Ok(false) => { + debug!("Merkle tree hash mismatch"); false - }); - let turned_hash = if turn_right { - Sha256::hash_nodes(&hash, &_next_hash) - } else { - Sha256::hash_nodes(&_next_hash, &hash) - }; - hash = unwrap_or_map_return!(turned_hash, |err| { - debug!("Error while hashing: {:?}", err); + } + Err(err) => { + trace!("Error checking merkle tree root hash: {}", err); false - }) - } - - let result = hash.as_slice() == root_hash; - if !result { - debug!( - "Merkle tree hash mismatch: {} != {}", - base58::encode(hash), - base58::encode(root_hash) - ); - } else { - trace!("Matched root hash: {}", base58::encode(root_hash)) + } } - - result } // true is right @@ -1067,6 +1063,7 @@ fn _verify_proof_range( }; // Preparation of data for verification // Fetch numerical suffixes + #[allow(clippy::type_complexity)] let vals_for_sort_check: Vec))>> = vals.into_iter() .filter(|(key, _)| key.starts_with(prefix)) .map(|(key, value)| { @@ -1212,14 +1209,14 @@ fn _parse_reply_for_proof_value( value["txn"]["data"]["raw"] = SJsonValue::from(""); } else { value["txn"]["data"]["raw"] = - SJsonValue::from(hex::encode(SHA256::digest(raw.as_bytes()))); + SJsonValue::from(hex::encode(Sha256::digest(raw.as_bytes()))); } } else if let Some(enc) = value["txn"]["data"]["enc"].as_str() { if enc.is_empty() { value["txn"]["data"]["enc"] = SJsonValue::from(""); } else { value["txn"]["data"]["enc"] = - SJsonValue::from(hex::encode(SHA256::digest(enc.as_bytes()))); + SJsonValue::from(hex::encode(Sha256::digest(enc.as_bytes()))); } } } @@ -1230,7 +1227,7 @@ fn _parse_reply_for_proof_value( value["verkey"] = parsed_data["verkey"].clone(); } constants::GET_ATTR => { - value["val"] = SJsonValue::String(hex::encode(SHA256::digest(data.as_bytes()))); + value["val"] = SJsonValue::String(hex::encode(Sha256::digest(data.as_bytes()))); } constants::GET_CRED_DEF | constants::GET_REVOC_REG_DEF @@ -1297,7 +1294,7 @@ fn _parse_reply_for_proof_value( fn _calculate_taa_digest(text: &str, version: &str) -> VdrResult> { let content: String = version.to_string() + text; - Ok(SHA256::digest(content.as_bytes())) + Ok(Sha256::digest(content.as_bytes()).to_vec()) } fn _is_full_taa_state_value_expected(expected_state_key: &[u8]) -> bool { diff --git a/libindy_vdr/src/utils/base64.rs b/libindy_vdr/src/utils/base64.rs index 6d721a88..aa9a2a68 100644 --- a/libindy_vdr/src/utils/base64.rs +++ b/libindy_vdr/src/utils/base64.rs @@ -8,6 +8,10 @@ pub fn decode>(val: T) -> Result, ConversionError> { .map_err(|err| ("Error decoding base64 data", err))?) } +pub fn encode>(val: T) -> String { + base64_rs::engine::general_purpose::STANDARD.encode(val) +} + pub fn decode_urlsafe>(val: T) -> Result, ConversionError> { Ok(base64_rs::engine::general_purpose::URL_SAFE .decode(val) diff --git a/libindy_vdr/src/utils/mod.rs b/libindy_vdr/src/utils/mod.rs index d5f9bb44..544bcc23 100644 --- a/libindy_vdr/src/utils/mod.rs +++ b/libindy_vdr/src/utils/mod.rs @@ -7,6 +7,5 @@ pub mod txn_signature; // re-exports pub use indy_utils::did; -pub(crate) use indy_utils::hash; pub use indy_utils::keys; pub use indy_utils::{qualifiable, ConversionError, Qualifiable, Validatable, ValidationError}; diff --git a/libindy_vdr/src/utils/txn_signature.rs b/libindy_vdr/src/utils/txn_signature.rs index 690df2a5..7e84f6e8 100644 --- a/libindy_vdr/src/utils/txn_signature.rs +++ b/libindy_vdr/src/utils/txn_signature.rs @@ -1,6 +1,7 @@ use serde_json::Value as SJsonValue; +use sha2::{Digest, Sha256}; -use super::{hash::SHA256, ValidationError}; +use super::ValidationError; const ATTRIB: &str = "100"; const GET_ATTR: &str = "104"; @@ -25,7 +26,7 @@ fn _serialize_signature( SJsonValue::Number(value) => Ok(value.to_string()), SJsonValue::String(value) => Ok(value.to_string()), SJsonValue::Array(array) => array - .into_iter() + .iter() .map(|element| _serialize_signature(element, false, _type)) .collect::, ValidationError>>() .map(|res| res.join(",")), @@ -47,8 +48,8 @@ fn _serialize_signature( && (key == "raw" || key == "hash" || key == "enc") { // do it only for attribute related request - let hash = SHA256::digest( - &value + let hash = Sha256::digest( + value .as_str() .ok_or_else(|| invalid!("Cannot update hash context"))? .as_bytes(), diff --git a/libindy_vdr/tests/resolver.rs b/libindy_vdr/tests/resolver.rs index a3b46154..b518274f 100644 --- a/libindy_vdr/tests/resolver.rs +++ b/libindy_vdr/tests/resolver.rs @@ -9,7 +9,7 @@ fn empty() { } #[cfg(test)] -// #[cfg(feature = "local_nodes_pool")] +#[cfg(feature = "local_nodes_pool")] mod send_resolver { use futures_executor::block_on; use indy_vdr::resolver::PoolResolver as Resolver; From 84b859c130c7fc84947902c20553b2ebe224a8d1 Mon Sep 17 00:00:00 2001 From: Andrew Whitehead Date: Fri, 4 Aug 2023 16:04:42 -0700 Subject: [PATCH 102/117] fix warnings Signed-off-by: Andrew Whitehead --- libindy_vdr/src/pool/handlers/status.rs | 47 +++++++++++++------------ libindy_vdr/src/pool/networker/zmq.rs | 1 + libindy_vdr/src/state_proof/node.rs | 1 + 3 files changed, 27 insertions(+), 22 deletions(-) diff --git a/libindy_vdr/src/pool/handlers/status.rs b/libindy_vdr/src/pool/handlers/status.rs index b1db6f8d..1241cbb9 100644 --- a/libindy_vdr/src/pool/handlers/status.rs +++ b/libindy_vdr/src/pool/handlers/status.rs @@ -1,4 +1,5 @@ use futures_util::stream::StreamExt; +use std::cmp::Ordering; use crate::common::error::prelude::*; use crate::common::merkle_tree::MerkleTree; @@ -131,30 +132,32 @@ fn try_to_catch_up( let cur_mt_size = merkle_tree.count(); let cur_mt_hash = base58::encode(merkle_tree.root_hash()); - if target_mt_size == cur_mt_size { - if cur_mt_hash.eq(target_mt_root) { - Ok(CatchupProgress::NotNeeded) - } else { - Err(input_err( - "Ledger merkle tree is not acceptable for current tree.", - )) + match target_mt_size.cmp(&cur_mt_size) { + Ordering::Equal => { + if cur_mt_hash.eq(target_mt_root) { + Ok(CatchupProgress::NotNeeded) + } else { + Err(input_err( + "Ledger merkle tree is not acceptable for current tree.", + )) + } } - } else if target_mt_size > cur_mt_size { - let target_mt_root = base58::decode(target_mt_root) - .with_input_err("Can't parse target MerkleTree hash from nodes responses")?; + Ordering::Greater => { + let target_mt_root = base58::decode(target_mt_root) + .with_input_err("Can't parse target MerkleTree hash from nodes responses")?; - match *hashes { - None => (), - Some(ref hashes) => { - check_cons_proofs(merkle_tree, hashes, &target_mt_root, target_mt_size)? - } - }; + match *hashes { + None => (), + Some(ref hashes) => { + check_cons_proofs(merkle_tree, hashes, &target_mt_root, target_mt_size)? + } + }; - Ok(CatchupProgress::ShouldBeStarted( - target_mt_root, - target_mt_size, - )) - } else { - Err(input_err("Local merkle tree greater than mt from ledger")) + Ok(CatchupProgress::ShouldBeStarted( + target_mt_root, + target_mt_size, + )) + } + _ => Err(input_err("Local merkle tree greater than mt from ledger")), } } diff --git a/libindy_vdr/src/pool/networker/zmq.rs b/libindy_vdr/src/pool/networker/zmq.rs index aebc1c5c..ef3c1905 100644 --- a/libindy_vdr/src/pool/networker/zmq.rs +++ b/libindy_vdr/src/pool/networker/zmq.rs @@ -447,6 +447,7 @@ impl ZMQThread { }) } + #[allow(clippy::type_complexity)] fn get_timeout(&self) -> (Option<(ZMQConnectionHandle, Option<(String, String)>)>, i64) { self.pool_connections .iter() diff --git a/libindy_vdr/src/state_proof/node.rs b/libindy_vdr/src/state_proof/node.rs index 1fae618f..8b3bdae9 100644 --- a/libindy_vdr/src/state_proof/node.rs +++ b/libindy_vdr/src/state_proof/node.rs @@ -146,6 +146,7 @@ impl rlp::Decodable for Node { type NodeHash = GenericArray::OutputSize>; pub type TrieDB<'a> = HashMap; +#[allow(clippy::needless_lifetimes)] impl Node { pub fn get_hash(&self) -> NodeHash { let encoded = rlp::encode(self); From bd7c05bf28f7ae8f6ce4567f347fddb46acf77ae Mon Sep 17 00:00:00 2001 From: Andrew Whitehead Date: Tue, 8 Aug 2023 10:52:10 -0700 Subject: [PATCH 103/117] switch to indy-blssignatures Signed-off-by: Andrew Whitehead --- libindy_vdr/src/config/constants.rs | 14 ++++---- libindy_vdr/src/pool/types.rs | 55 +++++++++++++++++++---------- libindy_vdr/src/state_proof/mod.rs | 2 +- libindy_vdr/src/state_proof/node.rs | 16 ++++----- 4 files changed, 51 insertions(+), 36 deletions(-) diff --git a/libindy_vdr/src/config/constants.rs b/libindy_vdr/src/config/constants.rs index d46f61c3..563a17fa 100644 --- a/libindy_vdr/src/config/constants.rs +++ b/libindy_vdr/src/config/constants.rs @@ -1,6 +1,5 @@ -use hex_literal::hex; +use indy_blssignatures::Generator; use once_cell::sync::Lazy; -use ursa::bls::Generator; use crate::pool::ProtocolVersion; @@ -14,12 +13,13 @@ pub const DEFAULT_PROTOCOL_VERSION: ProtocolVersion = ProtocolVersion::Node1_4; pub static DEFAULT_GENERATOR: Lazy = Lazy::new(|| { Generator::from_bytes( - &hex!( + &hex::decode( "16cb6e1f1b7803f30ab2c661196fe199af17d8ed193d98a3d0fa17638a3a1b831df541918f0e5acd - 0576998bfdb839318349b8acbb4106fe93e6a3d35a3f008107e2c4a7c9a5049f2cc9f9d7ced5049f - 4336f67843c5dc32ad940e397e252df7176a8f76fd15d536bc8d294ac7040f6cc8d560dad13de88c - 3dfa7260ec363452" - )[..], + 0576998bfdb839318349b8acbb4106fe93e6a3d35a3f008107e2c4a7c9a5049f2cc9f9d7ced5049f + 4336f67843c5dc32ad940e397e252df7176a8f76fd15d536bc8d294ac7040f6cc8d560dad13de88c + 3dfa7260ec363452", + ) + .unwrap(), ) .unwrap() }); diff --git a/libindy_vdr/src/pool/types.rs b/libindy_vdr/src/pool/types.rs index f7b313e3..bfe0d85a 100644 --- a/libindy_vdr/src/pool/types.rs +++ b/libindy_vdr/src/pool/types.rs @@ -1,10 +1,11 @@ use std::cmp::Eq; use std::collections::HashMap; use std::convert::{TryFrom, TryInto}; +use std::str::FromStr; +pub use indy_blssignatures::VerKey as BlsVerKey; use serde::{ser::SerializeMap, Deserialize, Deserializer, Serialize, Serializer}; use serde_json::{self, Value as SJsonValue}; -pub use ursa::bls::VerKey as BlsVerKey; use crate::common::error::prelude::*; use crate::common::merkle_tree::MerkleTree; @@ -32,16 +33,20 @@ impl ProtocolVersion { value.try_into() } - pub fn from_str(value: &str) -> VdrResult { + pub fn to_id(&self) -> i64 { + *self as i64 + } +} + +impl FromStr for ProtocolVersion { + type Err = VdrError; + + fn from_str(value: &str) -> VdrResult { let value = value .parse::() .map_input_err(|| format!("Invalid protocol version: {}", value))?; Self::from_id(value) } - - pub fn to_id(&self) -> i64 { - *self as i64 - } } impl TryFrom for ProtocolVersion { @@ -56,6 +61,14 @@ impl TryFrom for ProtocolVersion { } } +impl TryFrom<&str> for ProtocolVersion { + type Error = VdrError; + + fn try_from(value: &str) -> VdrResult { + Self::from_str(value) + } +} + impl PartialEq for ProtocolVersion { fn eq(&self, other: &i64) -> bool { (*self as i64) == *other @@ -93,9 +106,23 @@ impl LedgerType { pub fn from_id(value: i32) -> VdrResult { value.try_into() } +} - pub fn from_str(value: &str) -> VdrResult { - value.try_into() +impl FromStr for LedgerType { + type Err = VdrError; + + fn from_str(value: &str) -> VdrResult { + match value.to_ascii_uppercase().as_str() { + "POOL" => Ok(LedgerType::POOL), + "DOMAIN" => Ok(LedgerType::DOMAIN), + "CONFIG" => Ok(LedgerType::CONFIG), + _ => { + let ival = value + .parse::() + .map_input_err(|| format!("Unknown ledger type: {}", value))?; + Self::try_from(ival) + } + } } } @@ -116,17 +143,7 @@ impl TryFrom<&str> for LedgerType { type Error = VdrError; fn try_from(value: &str) -> VdrResult { - match value.to_ascii_uppercase().as_str() { - "POOL" => Ok(LedgerType::POOL), - "DOMAIN" => Ok(LedgerType::DOMAIN), - "CONFIG" => Ok(LedgerType::CONFIG), - _ => { - let ival = value - .parse::() - .map_input_err(|| format!("Unknown ledger type: {}", value))?; - Self::try_from(ival) - } - } + Self::from_str(value) } } diff --git a/libindy_vdr/src/state_proof/mod.rs b/libindy_vdr/src/state_proof/mod.rs index 467ae682..f54a6700 100644 --- a/libindy_vdr/src/state_proof/mod.rs +++ b/libindy_vdr/src/state_proof/mod.rs @@ -7,11 +7,11 @@ pub(crate) mod types; use std::collections::HashMap; use std::time::{SystemTime, UNIX_EPOCH}; +use indy_blssignatures::{Bls, Generator, MultiSignature, VerKey}; use indy_data_types::merkle_tree::{MerkleTree, Positioned}; use rlp::UntrustedRlp; use serde_json::Value as SJsonValue; use sha2::{Digest, Sha256}; -use ursa::bls::{Bls, Generator, MultiSignature, VerKey}; use crate::common::error::prelude::*; use crate::pool::{ProtocolVersion, VerifierKeys}; diff --git a/libindy_vdr/src/state_proof/node.rs b/libindy_vdr/src/state_proof/node.rs index 8b3bdae9..7e5e4954 100644 --- a/libindy_vdr/src/state_proof/node.rs +++ b/libindy_vdr/src/state_proof/node.rs @@ -109,21 +109,19 @@ impl rlp::Decodable for Node { } } RlpPrototype::List(Node::FULL_SIZE) => { - let mut nodes: [Option>; Node::RADIX] = [ - None, None, None, None, None, None, None, None, None, None, None, None, None, - None, None, None, - ]; - for i in 0..Node::RADIX { - let cur = rlp.at(i)?; + let mut nodes: [Option>; Node::RADIX] = Default::default(); + for (idx, node) in nodes.iter_mut().enumerate() { + let cur = rlp.at(idx)?; match cur.prototype()? { RlpPrototype::Data(0) => continue, _ => { - nodes[i] = Some(Box::new(cur.as_val()?)); + *node = Some(Box::new(cur.as_val()?)); } } } - let value: Option> = if !rlp.at(Node::RADIX)?.is_empty() { - Some(rlp.at(Node::RADIX)?.as_val()?) + let tail = rlp.at(Node::RADIX)?; + let value: Option> = if !tail.is_empty() { + Some(tail.as_val()?) } else { None }; From 00d67f8baf6629afa6d4bc2f45c72ec00805e837 Mon Sep 17 00:00:00 2001 From: Andrew Whitehead Date: Tue, 8 Aug 2023 10:53:13 -0700 Subject: [PATCH 104/117] no need to alias base64 crate Signed-off-by: Andrew Whitehead --- libindy_vdr/Cargo.toml | 9 ++------- libindy_vdr/src/utils/base64.rs | 10 +++++----- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/libindy_vdr/Cargo.toml b/libindy_vdr/Cargo.toml index c0e4d493..36ba909a 100644 --- a/libindy_vdr/Cargo.toml +++ b/libindy_vdr/Cargo.toml @@ -30,7 +30,7 @@ default = ["ffi", "log", "zmq_vendored"] # This is added so we can lock the version that zmq uses # 0.1.49 is broken for ios targets cmake = { version = "=0.1.48", optional = true } -base64_rs = { package = "base64", version = "0.21" } +base64 = "0.21" bs58 = "0.5" etcommon-rlp = "0.2.4" env_logger = { version = "0.10", optional = true } @@ -39,7 +39,7 @@ futures-channel = "0.3" futures-executor = "0.3" futures-util = "0.3" hex = "0.4" -hex-literal = "0.4" +indy-blssignatures = "0.1" indy-data-types = { version = "0.6.1", default-features = false, features = [ "anoncreds", "merkle_tree", @@ -63,11 +63,6 @@ time = { version = "=0.3.20", features = ["parsing"] } url = "2.2.2" zmq = "0.9" -[dependencies.ursa] -version = "0.3.5" -default-features = false -features = ["bls_bn254"] - [dev-dependencies] rstest = "0.18" time = "0.3" diff --git a/libindy_vdr/src/utils/base64.rs b/libindy_vdr/src/utils/base64.rs index aa9a2a68..41b42951 100644 --- a/libindy_vdr/src/utils/base64.rs +++ b/libindy_vdr/src/utils/base64.rs @@ -1,23 +1,23 @@ -use base64_rs::Engine; +use base64::Engine; use super::ConversionError; pub fn decode>(val: T) -> Result, ConversionError> { - Ok(base64_rs::engine::general_purpose::STANDARD + Ok(base64::engine::general_purpose::STANDARD .decode(val) .map_err(|err| ("Error decoding base64 data", err))?) } pub fn encode>(val: T) -> String { - base64_rs::engine::general_purpose::STANDARD.encode(val) + base64::engine::general_purpose::STANDARD.encode(val) } pub fn decode_urlsafe>(val: T) -> Result, ConversionError> { - Ok(base64_rs::engine::general_purpose::URL_SAFE + Ok(base64::engine::general_purpose::URL_SAFE .decode(val) .map_err(|err| ("Error decoding base64-URL data", err))?) } pub fn encode_urlsafe>(val: T) -> String { - base64_rs::engine::general_purpose::URL_SAFE.encode(val) + base64::engine::general_purpose::URL_SAFE.encode(val) } From 014ae7a4d3e9cc73e13c04a3cea3114813a01e15 Mon Sep 17 00:00:00 2001 From: Andrew Whitehead Date: Tue, 8 Aug 2023 10:53:36 -0700 Subject: [PATCH 105/117] move unit test Signed-off-by: Andrew Whitehead --- libindy_vdr/src/pool/handlers/mod.rs | 15 +++++++++++++++ libindy_vdr/src/pool/pool.rs | 16 ---------------- libindy_vdr/tests/utils/mod.rs | 2 -- 3 files changed, 15 insertions(+), 18 deletions(-) diff --git a/libindy_vdr/src/pool/handlers/mod.rs b/libindy_vdr/src/pool/handlers/mod.rs index ae58a3fa..2ee4b250 100644 --- a/libindy_vdr/src/pool/handlers/mod.rs +++ b/libindy_vdr/src/pool/handlers/mod.rs @@ -223,3 +223,18 @@ pub(crate) fn build_pool_catchup_request( }; Ok(Message::CatchupReq(cr)) } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn min_consensus_works() { + assert_eq!(min_consensus(0), 0); + assert_eq!(min_consensus(3), 0); + assert_eq!(min_consensus(4), 1); + assert_eq!(min_consensus(5), 1); + assert_eq!(min_consensus(6), 1); + assert_eq!(min_consensus(7), 2); + } +} diff --git a/libindy_vdr/src/pool/pool.rs b/libindy_vdr/src/pool/pool.rs index 2af9ae82..c9ff643a 100644 --- a/libindy_vdr/src/pool/pool.rs +++ b/libindy_vdr/src/pool/pool.rs @@ -849,21 +849,5 @@ mod tests { f.sync_all().unwrap(); } } - - mod other { - use super::*; - - #[test] - fn get_f_works() { - test::cleanup_storage("get_f_works"); - - assert_eq!(_get_f(0), 0); - assert_eq!(_get_f(3), 0); - assert_eq!(_get_f(4), 1); - assert_eq!(_get_f(5), 1); - assert_eq!(_get_f(6), 1); - assert_eq!(_get_f(7), 2); - } - } */ } diff --git a/libindy_vdr/tests/utils/mod.rs b/libindy_vdr/tests/utils/mod.rs index e0817193..87af5c94 100644 --- a/libindy_vdr/tests/utils/mod.rs +++ b/libindy_vdr/tests/utils/mod.rs @@ -7,8 +7,6 @@ pub mod pool; macro_rules! inject_dependencies { () => { - extern crate indy_vdr; - extern crate ursa; #[allow(unused_imports)] use serde_json::json; #[allow(unused_imports)] From b279653df3cec913f2958769ee9f2fdae3bbc162 Mon Sep 17 00:00:00 2001 From: Andrew Whitehead Date: Tue, 8 Aug 2023 10:55:53 -0700 Subject: [PATCH 106/117] remove unused tests Signed-off-by: Andrew Whitehead --- libindy_vdr/src/pool/pool.rs | 641 ----------------------------------- 1 file changed, 641 deletions(-) diff --git a/libindy_vdr/src/pool/pool.rs b/libindy_vdr/src/pool/pool.rs index c9ff643a..826669f7 100644 --- a/libindy_vdr/src/pool/pool.rs +++ b/libindy_vdr/src/pool/pool.rs @@ -209,645 +209,4 @@ mod tests { let found = choose_nodes(&verifiers, Some(&weights)); assert_eq!(found, ["c", "b"]); } - - /* - // use crate::services::pool::events::MockUpdateHandler; - use crate::services::pool::networker::MockNetworker; - use crate::services::pool::request_handler::tests::MockRequestHandler; - use crate::services::pool::types::{ - next_command_handle, next_pool_handle, Message, Reply, ReplyResultV1, ReplyTxnV1, ReplyV1, - ResponseMetadata, - }; - use crate::utils::test; - use crate::utils::test::test_pool_create_poolfile; - - use super::*; - - const TEST_POOL_CONFIG: PoolConfig = PoolConfig::default(); - - mod pool { - use super::*; - - #[test] - pub fn pool_new_works() { - let _p: Pool = - Pool::new(next_pool_handle(), &TEST_POOL_CONFIG); - } - - #[test] - pub fn pool_get_id_works() { - let id = next_pool_handle(); - let p: Pool = Pool::new(id, &TEST_POOL_CONFIG); - assert_eq!(id, p.get_id()); - } - } - - mod pool_sm { - use std::io::Write; - - use serde_json; - - use super::*; - - #[test] - pub fn pool_wrapper_new_inactive_works() { - let _p: PoolSM = PoolSM::new( - next_pool_handle(), - &TEST_POOL_CONFIG, - Rc::new(RefCell::new(MockNetworker::new(0, 0, vec![]))), - ); - } - - #[test] - pub fn pool_wrapper_check_cache_works() { - test::cleanup_storage("pool_wrapper_check_cache_works"); - - _write_genesis_txns("pool_wrapper_check_cache_works"); - - let p: PoolSM = PoolSM::new( - next_pool_handle(), - &TEST_POOL_CONFIG, - Rc::new(RefCell::new(MockNetworker::new(0, 0, vec![]))), - ); - let cmd_id: CommandHandle = next_command_handle(); - let p = p.handle_event(PoolEvent::CheckCache(cmd_id)); - assert_match!(PoolState::GettingCatchupTarget(_), p.state); - - test::cleanup_storage("pool_wrapper_check_cache_works"); - } - - #[test] - pub fn pool_wrapper_check_cache_works_for_no_pool_created() { - let p: PoolSM = PoolSM::new( - next_pool_handle(), - &TEST_POOL_CONFIG, - Rc::new(RefCell::new(MockNetworker::new(0, 0, vec![]))), - ); - let cmd_id: CommandHandle = next_command_handle(); - let p = p.handle_event(PoolEvent::CheckCache(cmd_id)); - assert_match!(PoolState::Terminated(_), p.state); - } - - #[test] - pub fn pool_wrapper_terminated_close_works() { - let p: PoolSM = PoolSM::new( - next_pool_handle(), - &TEST_POOL_CONFIG, - Rc::new(RefCell::new(MockNetworker::new(0, 0, vec![]))), - ); - let cmd_id: CommandHandle = next_command_handle(); - let p = p.handle_event(PoolEvent::CheckCache(cmd_id)); - let cmd_id: CommandHandle = next_command_handle(); - let p = p.handle_event(PoolEvent::Close(cmd_id)); - assert_match!(PoolState::Closed(_), p.state); - } - - #[test] - pub fn pool_wrapper_terminated_refresh_works() { - test::cleanup_pool("pool_wrapper_terminated_refresh_works"); - let p: PoolSM = PoolSM::new( - next_pool_handle(), - &TEST_POOL_CONFIG, - Rc::new(RefCell::new(MockNetworker::new(0, 0, vec![]))), - ); - let cmd_id: CommandHandle = next_command_handle(); - let p = p.handle_event(PoolEvent::CheckCache(cmd_id)); - - _write_genesis_txns("pool_wrapper_terminated_refresh_works"); - - let cmd_id: CommandHandle = next_command_handle(); - let p = p.handle_event(PoolEvent::Refresh(cmd_id)); - assert_match!(PoolState::GettingCatchupTarget(_), p.state); - test::cleanup_pool("pool_wrapper_terminated_refresh_works"); - } - - #[test] - pub fn pool_wrapper_terminated_timeout_works() { - let p: PoolSM = PoolSM { - id: next_pool_handle(), - config: TEST_POOL_CONFIG, - state: PoolState::Terminated(TerminatedState { - networker: Rc::new(RefCell::new(MockNetworker::new(0, 0, vec![]))), - }), - }; - - let p = p.handle_event(PoolEvent::Timeout("".to_string(), "".to_string())); - assert_match!(PoolState::Terminated(_), p.state); - match p.state { - PoolState::Terminated(state) => { - assert_eq!(state.networker.borrow().events.len(), 1); - let event = state.networker.borrow_mut().events.remove(0); - assert_match!(Some(NetworkerEvent::Timeout), event); - } - _ => assert!(false), - } - } - - #[test] - pub fn pool_wrapper_close_works_from_inactive() { - let p: PoolSM = PoolSM::new( - next_pool_handle(), - &TEST_POOL_CONFIG, - Rc::new(RefCell::new(MockNetworker::new(0, 0, vec![]))), - ); - let cmd_id: CommandHandle = next_command_handle(); - let p = p.handle_event(PoolEvent::Close(cmd_id)); - assert_match!(PoolState::Closed(_), p.state); - } - - #[test] - pub fn pool_wrapper_close_works_from_getting_catchup_target() { - test::cleanup_storage("pool_wrapper_close_works_from_getting_catchup_target"); - - _write_genesis_txns("pool_wrapper_close_works_from_getting_catchup_target"); - - let p: PoolSM = PoolSM::new( - next_pool_handle(), - &TEST_POOL_CONFIG, - Rc::new(RefCell::new(MockNetworker::new(0, 0, vec![]))), - ); - let cmd_id: CommandHandle = next_command_handle(); - let p = p.handle_event(PoolEvent::CheckCache(cmd_id)); - let cmd_id: CommandHandle = next_command_handle(); - let p = p.handle_event(PoolEvent::Close(cmd_id)); - assert_match!(PoolState::Closed(_), p.state); - - test::cleanup_storage("pool_wrapper_close_works_from_getting_catchup_target"); - } - - #[test] - pub fn pool_wrapper_catchup_target_not_found_works() { - test::cleanup_storage("pool_wrapper_catchup_target_not_found_works"); - - _write_genesis_txns("pool_wrapper_catchup_target_not_found_works"); - - let p: PoolSM = PoolSM::new( - next_pool_handle(), - &TEST_POOL_CONFIG, - Rc::new(RefCell::new(MockNetworker::new(0, 0, vec![]))), - ); - let cmd_id: CommandHandle = next_command_handle(); - let p = p.handle_event(PoolEvent::CheckCache(cmd_id)); - let p = p.handle_event(PoolEvent::CatchupTargetNotFound(err_msg( - VdrErrorKind::PoolTimeout, - "Pool timeout", - ))); - assert_match!(PoolState::Terminated(_), p.state); - - test::cleanup_storage("pool_wrapper_catchup_target_not_found_works"); - } - - #[test] - pub fn pool_wrapper_getting_catchup_target_synced_works() { - test::cleanup_storage("pool_wrapper_getting_catchup_target_synced_works"); - - _write_genesis_txns("pool_wrapper_getting_catchup_target_synced_works"); - - let p: PoolSM = PoolSM::new( - next_pool_handle(), - &TEST_POOL_CONFIG, - Rc::new(RefCell::new(MockNetworker::new(0, 0, vec![]))), - ); - let cmd_id: CommandHandle = next_command_handle(); - let p = p.handle_event(PoolEvent::CheckCache(cmd_id)); - let p = p.handle_event(PoolEvent::Synced(MerkleTree::from_vec(vec![]).unwrap())); - assert_match!(PoolState::Active(_), p.state); - - test::cleanup_storage("pool_wrapper_getting_catchup_target_synced_works"); - } - - /* - FIXME changes protocol version - #[test] - pub fn pool_wrapper_getting_catchup_target_synced_works_for_node_state_error() { - test::cleanup_storage( - "pool_wrapper_getting_catchup_target_synced_works_for_node_state_error", - ); - - ProtocolVersion::set(2); - _write_genesis_txns( - "pool_wrapper_getting_catchup_target_synced_works_for_node_state_error", - ); - - let p: PoolSM = PoolSM::new( - next_pool_handle(), - &TEST_POOL_CONFIG, - Rc::new(RefCell::new(MockNetworker::new(0, 0, vec![]))), - ); - let cmd_id: CommandHandle = next_command_handle(); - let p = p.handle_event(PoolEvent::CheckCache(cmd_id)); - ProtocolVersion::set(1); - let p = p.handle_event(PoolEvent::Synced( - merkle_tree_factory::create( - "pool_wrapper_getting_catchup_target_synced_works_for_node_state_error", - ) - .unwrap(), - )); - assert_match!(PoolState::Terminated(_), p.state); - - test::cleanup_storage( - "pool_wrapper_getting_catchup_target_synced_works_for_node_state_error", - ); - } - */ - - #[test] - pub fn pool_wrapper_getting_catchup_target_catchup_target_found_works() { - test::cleanup_storage("pool_wrapper_getting_catchup_target_catchup_target_found_works"); - - _write_genesis_txns("pool_wrapper_getting_catchup_target_catchup_target_found_works"); - - let mt = merkle_tree_factory::create( - "pool_wrapper_getting_catchup_target_catchup_target_found_works", - ) - .unwrap(); - - let p: PoolSM = PoolSM::new( - next_pool_handle(), - &TEST_POOL_CONFIG, - Rc::new(RefCell::new(MockNetworker::new(0, 0, vec![]))), - ); - let cmd_id: CommandHandle = next_command_handle(); - let p = p.handle_event(PoolEvent::CheckCache(cmd_id)); - let p = p.handle_event(PoolEvent::CatchupTargetFound( - mt.root_hash().to_vec(), - mt.count, - mt, - )); - assert_match!(PoolState::SyncCatchup(_), p.state); - - test::cleanup_storage("pool_wrapper_getting_catchup_target_catchup_target_found_works"); - } - - /* - FIXME changed protocol version - #[test] - pub fn pool_wrapper_getting_catchup_target_catchup_target_found_works_for_node_state_error() - { - test::cleanup_storage("pool_wrapper_getting_catchup_target_catchup_target_found_works_for_node_state_error"); - - ProtocolVersion::set(2); - _write_genesis_txns("pool_wrapper_getting_catchup_target_catchup_target_found_works_for_node_state_error"); - - let mt = merkle_tree_factory::create("pool_wrapper_getting_catchup_target_catchup_target_found_works_for_node_state_error").unwrap(); - - let p: PoolSM = PoolSM::new( - next_pool_handle(), - &TEST_POOL_CONFIG, - Rc::new(RefCell::new(MockNetworker::new(0, 0, vec![]))), - ); - let cmd_id: CommandHandle = next_command_handle(); - let p = p.handle_event(PoolEvent::CheckCache(cmd_id)); - ProtocolVersion::set(1); - let p = p.handle_event(PoolEvent::CatchupTargetFound( - mt.root_hash().to_vec(), - mt.count, - mt, - )); - assert_match!(PoolState::Terminated(_), p.state); - - test::cleanup_storage("pool_wrapper_getting_catchup_target_catchup_target_found_works_for_node_state_error"); - } - */ - - #[test] - pub fn pool_wrapper_sync_catchup_close_works() { - test::cleanup_storage("pool_wrapper_sync_catchup_close_works"); - - _write_genesis_txns("pool_wrapper_sync_catchup_close_works"); - - let mt = merkle_tree_factory::create("pool_wrapper_sync_catchup_close_works").unwrap(); - - let p: PoolSM = PoolSM::new( - next_pool_handle(), - &TEST_POOL_CONFIG, - Rc::new(RefCell::new(MockNetworker::new(0, 0, vec![]))), - ); - let cmd_id: CommandHandle = next_command_handle(); - let p = p.handle_event(PoolEvent::CheckCache(cmd_id)); - let p = p.handle_event(PoolEvent::CatchupTargetFound( - mt.root_hash().to_vec(), - mt.count, - mt, - )); - let cmd_id: CommandHandle = next_command_handle(); - let p = p.handle_event(PoolEvent::Close(cmd_id)); - assert_match!(PoolState::Closed(_), p.state); - - test::cleanup_storage("pool_wrapper_sync_catchup_close_works"); - } - - #[test] - pub fn pool_wrapper_sync_catchup_synced_works() { - test::cleanup_storage("pool_wrapper_sync_catchup_synced_works"); - - _write_genesis_txns("pool_wrapper_sync_catchup_synced_works"); - - let mt = merkle_tree_factory::create("pool_wrapper_sync_catchup_synced_works").unwrap(); - - let p: PoolSM = PoolSM::new( - next_pool_handle(), - &TEST_POOL_CONFIG, - Rc::new(RefCell::new(MockNetworker::new(0, 0, vec![]))), - ); - let cmd_id: CommandHandle = next_command_handle(); - let p = p.handle_event(PoolEvent::CheckCache(cmd_id)); - let p = p.handle_event(PoolEvent::CatchupTargetFound( - mt.root_hash().to_vec(), - mt.count, - mt, - )); - let p = p.handle_event(PoolEvent::Synced( - merkle_tree_factory::create("pool_wrapper_sync_catchup_synced_works").unwrap(), - )); - assert_match!(PoolState::Active(_), p.state); - - test::cleanup_storage("pool_wrapper_sync_catchup_synced_works"); - } - - /* - FIXME changes protocol version - #[test] - pub fn pool_wrapper_sync_catchup_synced_works_for_node_state_error() { - test::cleanup_storage("pool_wrapper_sync_catchup_synced_works_for_node_state_error"); - - ProtocolVersion::set(2); - _write_genesis_txns("pool_wrapper_sync_catchup_synced_works_for_node_state_error"); - - let mt = merkle_tree_factory::create( - "pool_wrapper_sync_catchup_synced_works_for_node_state_error", - ) - .unwrap(); - - let p: PoolSM = PoolSM::new( - next_pool_handle(), - &TEST_POOL_CONFIG, - Rc::new(RefCell::new(MockNetworker::new(0, 0, vec![]))), - ); - let cmd_id: CommandHandle = next_command_handle(); - let p = p.handle_event(PoolEvent::CheckCache(cmd_id)); - let p = p.handle_event(PoolEvent::CatchupTargetFound( - mt.root_hash().to_vec(), - mt.count, - mt, - )); - ProtocolVersion::set(1); - let p = p.handle_event(PoolEvent::Synced( - merkle_tree_factory::create( - "pool_wrapper_sync_catchup_synced_works_for_node_state_error", - ) - .unwrap(), - )); - assert_match!(PoolState::Terminated(_), p.state); - - test::cleanup_storage("pool_wrapper_sync_catchup_synced_works_for_node_state_error"); - } - */ - - #[test] - pub fn pool_wrapper_active_send_request_works() { - test::cleanup_storage("pool_wrapper_active_send_request_works"); - - _write_genesis_txns("pool_wrapper_active_send_request_works"); - - let req = json!({ - "reqId": 1, - "operation": { - "type": "1" - } - }) - .to_string(); - - let p: PoolSM = PoolSM::new( - next_pool_handle(), - &TEST_POOL_CONFIG, - Rc::new(RefCell::new(MockNetworker::new(0, 0, vec![]))), - ); - let cmd_id: CommandHandle = next_command_handle(); - let p = p.handle_event(PoolEvent::CheckCache(cmd_id)); - let p = p.handle_event(PoolEvent::Synced(MerkleTree::from_vec(vec![]).unwrap())); - let cmd_id: CommandHandle = next_command_handle(); - let p = p.handle_event(PoolEvent::SendRequest(cmd_id, req, None, None)); - assert_match!(PoolState::Active(_), p.state); - match p.state { - PoolState::Active(state) => { - assert_eq!(state.request_handlers.len(), 1); - assert!(state.request_handlers.contains_key("1")); - } - _ => assert!(false), - }; - - test::cleanup_storage("pool_wrapper_active_send_request_works"); - } - - #[test] - pub fn pool_wrapper_active_send_request_works_for_no_req_id() { - test::cleanup_storage("pool_wrapper_active_send_request_works_for_no_req_id"); - - _write_genesis_txns("pool_wrapper_active_send_request_works_for_no_req_id"); - - let req = json!({ - "operation": { - "type": "1" - } - }) - .to_string(); - - let p: PoolSM = PoolSM::new( - next_pool_handle(), - &TEST_POOL_CONFIG, - Rc::new(RefCell::new(MockNetworker::new(0, 0, vec![]))), - ); - let cmd_id: CommandHandle = next_command_handle(); - let p = p.handle_event(PoolEvent::CheckCache(cmd_id)); - let p = p.handle_event(PoolEvent::Synced(MerkleTree::from_vec(vec![]).unwrap())); - let cmd_id: CommandHandle = next_command_handle(); - let p = p.handle_event(PoolEvent::SendRequest(cmd_id, req, None, None)); - assert_match!(PoolState::Active(_), p.state); - match p.state { - PoolState::Active(state) => { - assert_eq!(state.request_handlers.len(), 0); - } - _ => assert!(false), - }; - - test::cleanup_storage("pool_wrapper_active_send_request_works_for_no_req_id"); - } - - #[test] - pub fn pool_wrapper_active_node_reply_works() { - test::cleanup_storage("pool_wrapper_active_node_reply_works"); - - _write_genesis_txns("pool_wrapper_active_node_reply_works"); - - let req = json!({ - "reqId": 1, - "operation": { - "type": "1" - } - }) - .to_string(); - - let rep = Message::Reply(Reply::ReplyV1(ReplyV1 { - result: ReplyResultV1 { - txn: ReplyTxnV1 { - metadata: ResponseMetadata { req_id: 1 }, - }, - }, - })); - - let rep = serde_json::to_string(&rep).unwrap(); - - let p: PoolSM = PoolSM::new( - next_pool_handle(), - &TEST_POOL_CONFIG, - Rc::new(RefCell::new(MockNetworker::new(0, 0, vec![]))), - ); - let cmd_id: CommandHandle = next_command_handle(); - let p = p.handle_event(PoolEvent::CheckCache(cmd_id)); - let p = p.handle_event(PoolEvent::Synced(MerkleTree::from_vec(vec![]).unwrap())); - let cmd_id: CommandHandle = next_command_handle(); - let p = p.handle_event(PoolEvent::SendRequest(cmd_id, req, None, None)); - let p = p.handle_event(PoolEvent::NodeReply(rep, "node".to_string())); - assert_match!(PoolState::Active(_), p.state); - match p.state { - PoolState::Active(state) => { - assert_eq!(state.request_handlers.len(), 0); - } - _ => assert!(false), - }; - - test::cleanup_storage("pool_wrapper_active_node_reply_works"); - } - - #[test] - pub fn pool_wrapper_sends_requests_to_two_nodes() { - test::cleanup_storage("pool_wrapper_sends_requests_to_two_nodes"); - - _write_genesis_txns("pool_wrapper_sends_requests_to_two_nodes"); - - let req = json!({ - "reqId": 1, - "operation": { - "type": "105" - } - }) - .to_string(); - - let p: PoolSM = PoolSM::new( - next_pool_handle(), - &TEST_POOL_CONFIG, - Rc::new(RefCell::new(MockNetworker::new(0, 0, vec![]))), - ); - let cmd_id: CommandHandle = next_command_handle(); - let p = p.handle_event(PoolEvent::CheckCache(cmd_id)); - let p = p.handle_event(PoolEvent::Synced(MerkleTree::from_vec(vec![]).unwrap())); - let cmd_id: CommandHandle = next_command_handle(); - let p = p.handle_event(PoolEvent::SendRequest(cmd_id, req, None, None)); - assert_match!(PoolState::Active(_), p.state); - match p.state { - PoolState::Active(state) => { - assert_eq!(state.networker.borrow().events.len(), 2); - } - _ => assert!(false), - }; - - test::cleanup_storage("pool_wrapper_sends_requests_to_two_nodes"); - } - - #[test] - pub fn pool_wrapper_active_node_reply_works_for_no_request() { - test::cleanup_storage("pool_wrapper_active_node_reply_works_for_no_request"); - - _write_genesis_txns("pool_wrapper_active_node_reply_works_for_no_request"); - - let req = json!({ - "reqId": 1, - "operation": { - "type": "1" - } - }) - .to_string(); - - let rep = Message::Reply(Reply::ReplyV1(ReplyV1 { - result: ReplyResultV1 { - txn: ReplyTxnV1 { - metadata: ResponseMetadata { req_id: 2 }, - }, - }, - })); - - let rep = serde_json::to_string(&rep).unwrap(); - - let p: PoolSM = PoolSM::new( - next_pool_handle(), - &TEST_POOL_CONFIG, - Rc::new(RefCell::new(MockNetworker::new(0, 0, vec![]))), - ); - let cmd_id: CommandHandle = next_command_handle(); - let p = p.handle_event(PoolEvent::CheckCache(cmd_id)); - let p = p.handle_event(PoolEvent::Synced(MerkleTree::from_vec(vec![]).unwrap())); - let cmd_id: CommandHandle = next_command_handle(); - let p = p.handle_event(PoolEvent::SendRequest(cmd_id, req, None, None)); - let p = p.handle_event(PoolEvent::NodeReply(rep, "node".to_string())); - assert_match!(PoolState::Active(_), p.state); - match p.state { - PoolState::Active(state) => { - assert_eq!(state.request_handlers.len(), 1); - assert!(state.request_handlers.contains_key("1")); - } - _ => assert!(false), - }; - - test::cleanup_storage("pool_wrapper_active_node_reply_works_for_no_request"); - } - - #[test] - pub fn pool_wrapper_active_node_reply_works_for_invalid_reply() { - test::cleanup_storage("pool_wrapper_active_node_reply_works_for_invalid_reply"); - - _write_genesis_txns("pool_wrapper_active_node_reply_works_for_invalid_reply"); - - let req = json!({ - "reqId": 1, - "operation": { - "type": "1" - } - }) - .to_string(); - - let rep = r#"{}"#; - - let p: PoolSM = PoolSM::new( - next_pool_handle(), - &TEST_POOL_CONFIG, - Rc::new(RefCell::new(MockNetworker::new(0, 0, vec![]))), - ); - let cmd_id: CommandHandle = next_command_handle(); - let p = p.handle_event(PoolEvent::CheckCache(cmd_id)); - let p = p.handle_event(PoolEvent::Synced(MerkleTree::from_vec(vec![]).unwrap())); - let cmd_id: CommandHandle = next_command_handle(); - let p = p.handle_event(PoolEvent::SendRequest(cmd_id, req, None, None)); - let p = p.handle_event(PoolEvent::NodeReply(rep.to_string(), "node".to_string())); - assert_match!(PoolState::Active(_), p.state); - match p.state { - PoolState::Active(state) => { - assert_eq!(state.request_handlers.len(), 1); - } - _ => assert!(false), - }; - - test::cleanup_storage("pool_wrapper_active_node_reply_works_for_invalid_reply"); - } - - fn _write_genesis_txns(pool_name: &str) { - let txns = test::gen_txns().join("\n"); - - let mut f = test_pool_create_poolfile(pool_name); - f.write(txns.as_bytes()).unwrap(); - f.flush().unwrap(); - f.sync_all().unwrap(); - } - } - */ } From 9a5fb16bb860b343f2d2cf71b0ad07b00fef8aa4 Mon Sep 17 00:00:00 2001 From: Andrew Whitehead Date: Tue, 8 Aug 2023 10:57:28 -0700 Subject: [PATCH 107/117] fix warning Signed-off-by: Andrew Whitehead --- libindy_vdr/src/pool/builder.rs | 2 +- libindy_vdr/src/pool/helpers.rs | 2 +- libindy_vdr/src/pool/{pool.rs => manager.rs} | 0 libindy_vdr/src/pool/mod.rs | 6 +++--- 4 files changed, 5 insertions(+), 5 deletions(-) rename libindy_vdr/src/pool/{pool.rs => manager.rs} (100%) diff --git a/libindy_vdr/src/pool/builder.rs b/libindy_vdr/src/pool/builder.rs index 8216cc70..e56aec8a 100644 --- a/libindy_vdr/src/pool/builder.rs +++ b/libindy_vdr/src/pool/builder.rs @@ -1,6 +1,6 @@ use super::genesis::PoolTransactions; +use super::manager::{LocalPool, SharedPool}; use super::networker::{MakeLocal, MakeShared, ZMQNetworkerFactory}; -use super::pool::{LocalPool, SharedPool}; use super::runner::PoolRunner; use crate::common::error::prelude::*; diff --git a/libindy_vdr/src/pool/helpers.rs b/libindy_vdr/src/pool/helpers.rs index ec0acb00..f699b16d 100644 --- a/libindy_vdr/src/pool/helpers.rs +++ b/libindy_vdr/src/pool/helpers.rs @@ -8,7 +8,7 @@ use super::handlers::{ build_pool_catchup_request, build_pool_status_request, handle_catchup_request, handle_consensus_request, handle_full_request, handle_status_request, CatchupTarget, }; -use super::pool::Pool; +use super::manager::Pool; use super::requests::{PreparedRequest, RequestMethod}; use super::types::{NodeReplies, RequestResult, TimingResult}; diff --git a/libindy_vdr/src/pool/pool.rs b/libindy_vdr/src/pool/manager.rs similarity index 100% rename from libindy_vdr/src/pool/pool.rs rename to libindy_vdr/src/pool/manager.rs diff --git a/libindy_vdr/src/pool/mod.rs b/libindy_vdr/src/pool/mod.rs index 38b0a6b1..44b84759 100644 --- a/libindy_vdr/src/pool/mod.rs +++ b/libindy_vdr/src/pool/mod.rs @@ -4,10 +4,10 @@ mod genesis; pub(crate) mod handlers; /// Methods for performing requests against the verifier pool pub mod helpers; +/// General verifier pool management +mod manager; /// Pool networker traits and implementations pub mod networker; -/// General verifier pool management -mod pool; /// Data types and traits for handling pending verifier pool requests mod requests; /// A pool executor that processes events in its own thread @@ -16,7 +16,7 @@ mod types; pub use self::builder::PoolBuilder; pub use self::genesis::PoolTransactions; -pub use self::pool::{LocalPool, Pool, PoolImpl, SharedPool}; +pub use self::manager::{LocalPool, Pool, PoolImpl, SharedPool}; pub use self::requests::{ new_request_id, PoolRequest, PoolRequestImpl, PreparedRequest, RequestMethod, }; From ec234afce8a27e761bd7dae35a9f80a98736f7f1 Mon Sep 17 00:00:00 2001 From: Andrew Whitehead Date: Wed, 9 Aug 2023 10:02:21 -0700 Subject: [PATCH 108/117] fix string formatting Signed-off-by: Andrew Whitehead --- libindy_vdr/src/config/constants.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libindy_vdr/src/config/constants.rs b/libindy_vdr/src/config/constants.rs index 563a17fa..21e8c8e5 100644 --- a/libindy_vdr/src/config/constants.rs +++ b/libindy_vdr/src/config/constants.rs @@ -14,9 +14,9 @@ pub const DEFAULT_PROTOCOL_VERSION: ProtocolVersion = ProtocolVersion::Node1_4; pub static DEFAULT_GENERATOR: Lazy = Lazy::new(|| { Generator::from_bytes( &hex::decode( - "16cb6e1f1b7803f30ab2c661196fe199af17d8ed193d98a3d0fa17638a3a1b831df541918f0e5acd - 0576998bfdb839318349b8acbb4106fe93e6a3d35a3f008107e2c4a7c9a5049f2cc9f9d7ced5049f - 4336f67843c5dc32ad940e397e252df7176a8f76fd15d536bc8d294ac7040f6cc8d560dad13de88c + "16cb6e1f1b7803f30ab2c661196fe199af17d8ed193d98a3d0fa17638a3a1b831df541918f0e5acd\ + 0576998bfdb839318349b8acbb4106fe93e6a3d35a3f008107e2c4a7c9a5049f2cc9f9d7ced5049f\ + 4336f67843c5dc32ad940e397e252df7176a8f76fd15d536bc8d294ac7040f6cc8d560dad13de88c\ 3dfa7260ec363452", ) .unwrap(), From c72023842dcd8db4d0109b8454f580f92eae254e Mon Sep 17 00:00:00 2001 From: Andrew Whitehead Date: Wed, 9 Aug 2023 10:02:32 -0700 Subject: [PATCH 109/117] add test of bls signature validation on state proof Signed-off-by: Andrew Whitehead --- libindy_vdr/src/state_proof/mod.rs | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/libindy_vdr/src/state_proof/mod.rs b/libindy_vdr/src/state_proof/mod.rs index f54a6700..0a6b6b9b 100644 --- a/libindy_vdr/src/state_proof/mod.rs +++ b/libindy_vdr/src/state_proof/mod.rs @@ -1307,6 +1307,8 @@ fn _if_rev_delta_multi_state_proof_expected(sp_key: &[u8]) -> bool { #[cfg(test)] mod tests { + use crate::{config::constants::DEFAULT_GENERATOR, pool::VerifierKey}; + use super::*; use hex::FromHex; @@ -2269,4 +2271,29 @@ mod tests { }) ); } + + #[test] + fn check_state_proof_valid() { + let raw_msg = r#"{"op":"REPLY","result":{"identifier":"LibindyDid111111111111","reqId":1691520834828315000,"type":"3","data":{"reqSignature":{},"txn":{"data":{"dest":"V4SGRU86Z58d6TV7PBUe6f","role":"0","verkey":"~CoRER63DVYnWZtK8uAzNbx"},"metadata":{},"type":"1"},"txnMetadata":{"seqNo":1},"ver":"1","rootHash":"DxX9E3XxEPHbb3JjakcmSduPc2bBcWsFhZZGp5aa842q","auditPath":["3XtSyZ8CQPJUYbc5mFKvUendLZSt4ybG2Y4zRtJEewSL","96irBGYpWrTvrVATexGGvktPrT3WicixwT8BtoZTtkYX","HqXD3TkLbpRuRU7CrrvrBeZwKuNFVCfta1ez7X7jGjtF","3fsGMWtrpYdNiLZKRKGmhGUJTUkdC2yn2yNd8MPGjwdq","BwS8ttPxJXQ4yn5RDy6spyxrFRZkukr9dbs9bjfskz1U","3wvhiYWLX3fRwGp1SoLeMQas6xtRHK8n7a3WqLPiwyMc","8oJHS289uuhcmgrvrzVtXvRGFfoXRnTWZnHQRYopDtUG","B5yx8ExTWjkgaDHuYWbosaoPhuq15uBx1jmp6npp6cKa","41vHGCg6qKUEtLAveyeWLMNdhZoH89Ym6xymFvSj64ER","APznt6o24yBWCNs5tVF4fC6h6rMz1Joj9BYWQuXJH1V5","3EByMrinqTxqaC7VEnQj4bKn29Gg357MoaTJxhZJvAbv","CV3xU14oTyGxemt6ZzLGhcBoTEcQ9MivEgo4fREPJbax","9MvXyCYNaPnTWV5ZW6E8hkPnjEurmTGmzTTUJJ9sGZ3L","8T7istFjSSxgYzZoxcJLtBm1hW48kTpGXBqbXMigopZ5"],"ledgerSize":12713},"state_proof":{"multi_signature":{"signature":"RRM4P551uBWUUZrz1AnspaL2n4ar65WBLn1ANS2XUPWir8bEq5LWdowmdjYvp3scEHPEMxGgJTB5ffVevBsoMVgtyB2SUxr6ZTAAtmE73RETGVwRCQnz3k2gEGaYyAxVSon51RHW5Jg9hEgyMWR2j3aib5o7fFDZFhBy2oB1bS46go","participants":["Node3","Node2","Node1"],"value":{"ledger_id":1,"pool_state_root_hash":"7siDH8Qanh82UviK4zjBSfLXcoCvLaeGkrByi1ow9Tsm","state_root_hash":"8AasPY2KBtPLiVnvePAZhPZKAfRozAR9CBUYAXFBhdXo","timestamp":1691520806,"txn_root_hash":"DxX9E3XxEPHbb3JjakcmSduPc2bBcWsFhZZGp5aa842q"}}},"seqNo":1}}"#; + let f = 1; + let mut bls_keys = HashMap::new(); + bls_keys.insert("Node1".to_owned(), VerifierKey::from_bytes(&hex::decode("20e085f100560896f50ea75e681a780275e9e39d645fcf8a48bc771dd41e304d099f5a5c009f5ac95776c7534ac4ec2550a0fa0da8422aa4b28a5ab76b34ba16054995a826fceef2fc619732c6971e5ca39a49f41b117e33868551c8f3f481751e34851a6c913a6f4e8c1d5ae13ac5460b69378b7d94a07f46fa92445dc8eecd").unwrap()).unwrap()); + bls_keys.insert("Node2".to_owned(), VerifierKey::from_bytes(&hex::decode("14b2c1cb385e56510cc8f050317580bcaf792ba555f29f7a8454d4367d63ea8020e9a34506a173320a5d0a4dff36cdda7d1d7848495e8e0c2a420d55c5704efc0dd8cec3869e061728abc55ce9948085358c1661799a2e289ea2fda0d8d083640ade487d5787924a6ed0cd7cbe727b9296ea66e8acc7b47fa9e1254ac6ee2827").unwrap()).unwrap()); + bls_keys.insert("Node3".to_owned(), VerifierKey::from_bytes(&hex::decode("187945bb8673691a57fa719dbc93653c909f359da42281b22b2b2e2748abc4d71ff796348e496d6be919bc3710f1b11d04fe9c436fb3c80ac5da556e94a73ba617d9180856dd73c6c30b9716ec0546ccebda8a80cd9058c88af45079a45ad35921cb2e6488caab9c4f35dbef9efdc22ece8769c60f82b38c78d547f7ad866016").unwrap()).unwrap()); + bls_keys.insert("Node4".to_owned(), VerifierKey::from_bytes(&hex::decode("136feaf1ad5b81d70de5c5287b0ef24746b8db60dba8ec502aeb213ae5c9f1900b59ff8e6f38e00e5d4cf2a45fb3317a0ccfc710806d368acb2267e097ed696611cc9295d2bbca32d1e176f026a66f02f70a8851ec71f2f4321dc62f00b5cf071f32e6fc3a1f63278360c7dd8285224ed482ff59ab5063aee3117a111fc9ffd2").unwrap()).unwrap()); + let reply: serde_json::Value = serde_json::from_str(raw_msg).unwrap(); + let msg_result = &reply["result"]; + assert!(check_state_proof( + msg_result, + f, + &DEFAULT_GENERATOR, + &bls_keys, + raw_msg, + Some(&[49]), + (None, Some(0)), + 1691520806, + 300, + None, + )); + } } From 5be5cab22b4cfbce103d68ec4b737edb71b31fab Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 9 Aug 2023 20:39:45 +0000 Subject: [PATCH 110/117] Bump word-wrap from 1.2.3 to 1.2.5 in /wrappers/javascript Bumps [word-wrap](https://github.com/jonschlinkert/word-wrap) from 1.2.3 to 1.2.5. - [Release notes](https://github.com/jonschlinkert/word-wrap/releases) - [Commits](https://github.com/jonschlinkert/word-wrap/compare/1.2.3...1.2.5) --- updated-dependencies: - dependency-name: word-wrap dependency-type: indirect ... Signed-off-by: dependabot[bot] --- wrappers/javascript/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wrappers/javascript/yarn.lock b/wrappers/javascript/yarn.lock index 4af0963e..d509cef4 100644 --- a/wrappers/javascript/yarn.lock +++ b/wrappers/javascript/yarn.lock @@ -6826,9 +6826,9 @@ wide-align@^1.1.2: string-width "^1.0.2 || 2 || 3 || 4" word-wrap@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" - integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== + version "1.2.5" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34" + integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== wrap-ansi@^6.2.0: version "6.2.0" From 8f81e1f0a3cc1b5c6571f0d265038fedc37b7db0 Mon Sep 17 00:00:00 2001 From: Andrew Whitehead Date: Wed, 9 Aug 2023 14:46:21 -0700 Subject: [PATCH 111/117] add enums for ledger role, ledger role update action Signed-off-by: Andrew Whitehead --- libindy_vdr/src/ffi/ledger.rs | 13 +- libindy_vdr/src/ledger/constants.rs | 201 ++++++++++++++++++- libindy_vdr/src/ledger/request_builder.rs | 7 +- libindy_vdr/src/ledger/requests/auth_rule.rs | 3 +- libindy_vdr/src/ledger/requests/nym.rs | 27 +-- libindy_vdr/tests/auth_rule.rs | 4 +- libindy_vdr/tests/nym.rs | 33 +-- libindy_vdr/tests/utils/helpers.rs | 5 +- 8 files changed, 216 insertions(+), 77 deletions(-) diff --git a/libindy_vdr/src/ffi/ledger.rs b/libindy_vdr/src/ffi/ledger.rs index 22935e9d..70390c6d 100644 --- a/libindy_vdr/src/ffi/ledger.rs +++ b/libindy_vdr/src/ffi/ledger.rs @@ -1,4 +1,7 @@ +use std::str::FromStr; + use crate::common::error::prelude::*; +use crate::ledger::constants::UpdateRole; #[cfg(any(feature = "rich_schema", test))] use crate::ledger::identifiers::RichSchemaId; use crate::ledger::identifiers::{CredentialDefinitionId, RevocationRegistryId, SchemaId}; @@ -419,14 +422,8 @@ pub extern "C" fn indy_vdr_build_nym_request( let dest = DidValue::from_str(dest.as_str())?; let verkey = verkey.into_opt_string(); let alias = alias.into_opt_string(); - let role = role.into_opt_string(); - let diddoc_content = match diddoc_content.as_opt_str() { - Some(s) => { - let js = serde_json::from_str(s).with_input_err("Error deserializing raw value as JSON")?; - Some(js) - } - None => None, - }; + let role = role.as_opt_str().map(UpdateRole::from_str).transpose()?; + let diddoc_content = diddoc_content.as_opt_str().map(serde_json::from_str).transpose().with_input_err("Error deserializing raw value as JSON")?; let version = if version == -1 { None } else { Some(version) }; let req = builder.build_nym_request(&identifier, &dest, verkey, alias, role, diddoc_content.as_ref(), version)?; let handle = add_request(req)?; diff --git a/libindy_vdr/src/ledger/constants.rs b/libindy_vdr/src/ledger/constants.rs index 2ce03859..65b49448 100644 --- a/libindy_vdr/src/ledger/constants.rs +++ b/libindy_vdr/src/ledger/constants.rs @@ -1,3 +1,8 @@ +use serde::{de::Visitor, Deserialize, Deserializer, Serialize, Serializer}; +use std::{fmt, str::FromStr}; + +use crate::common::error::{input_err, VdrError}; + pub const NODE: &str = "0"; pub const NYM: &str = "1"; pub const GET_TXN: &str = "3"; @@ -29,6 +34,7 @@ pub const GET_AUTH_RULE: &str = "121"; pub const AUTH_RULES: &str = "122"; pub const FLAG: &str = "130"; pub const GET_FLAG: &str = "131"; + // RichSchema objects pub const RICH_SCHEMA_CTX: &str = "200"; pub const RICH_SCHEMA: &str = "201"; @@ -96,11 +102,11 @@ pub const READ_REQUESTS: [&str; 14] = [ GET_RICH_SCHEMA_BY_METADATA, ]; -pub const TRUSTEE: &str = "0"; -pub const STEWARD: &str = "2"; -pub const ENDORSER: &str = "101"; -pub const NETWORK_MONITOR: &str = "201"; -pub const ROLE_REMOVE: &str = ""; +pub const ROLE_TRUSTEE: usize = 0; +pub const ROLE_STEWARD: usize = 2; +pub const ROLE_ENDORSER: usize = 101; +pub const ROLE_NETWORK_MONITOR: usize = 201; + pub const RS_SCHEMA_TYPE_VALUE: &str = "sch"; pub const RS_ENCODING_TYPE_VALUE: &str = "enc"; pub const RS_CONTEXT_TYPE_VALUE: &str = "ctx"; @@ -108,14 +114,187 @@ pub const RS_MAPPING_TYPE_VALUE: &str = "map"; pub const RS_CRED_DEF_TYPE_VALUE: &str = "cdf"; pub const RS_PRES_DEF_TYPE_VALUE: &str = "pdf"; -pub const ROLES: [&str; 4] = [TRUSTEE, STEWARD, ENDORSER, NETWORK_MONITOR]; - // Method/version of self-certification -pub const DEFAULT: i32 = 0; // No (enforced) self-certification -pub const DID_SOV: i32 = 1; // Legacy self-certification -pub const DID_INDY: i32 = 2; // Self-certification based on did:indy method spec +/// No (enforced) self-certification +pub const CERT_DEFAULT: i32 = 0; +/// Legacy self-certification +pub const CERT_DID_SOV: i32 = 1; +/// Self-certification based on did:indy method spec +pub const CERT_DID_INDY: i32 = 2; + +pub const SELF_CERT_VERSIONS: [i32; 3] = [CERT_DEFAULT, CERT_DID_SOV, CERT_DID_INDY]; + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[repr(usize)] +pub enum LedgerRole { + Trustee, + Steward, + Endorser, + NetworkMonitor, + Custom(usize), +} + +impl LedgerRole { + pub fn to_usize(self) -> usize { + match self { + Self::Trustee => ROLE_TRUSTEE, + Self::Steward => ROLE_STEWARD, + Self::Endorser => ROLE_ENDORSER, + Self::NetworkMonitor => ROLE_NETWORK_MONITOR, + Self::Custom(val) => val, + } + } +} + +impl fmt::Display for LedgerRole { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let ident = match self { + Self::Trustee => "TRUSTEE", + Self::Steward => "STEWARD", + Self::Endorser => "ENDORSER", + Self::NetworkMonitor => "NETWORK_MONITOR", + Self::Custom(role) => return write!(f, "{}", role), + }; + f.write_str(ident) + } +} + +impl FromStr for LedgerRole { + type Err = VdrError; + + fn from_str(value: &str) -> Result { + match value { + "TRUSTEE" => Ok(Self::Trustee), + "STEWARD" => Ok(Self::Steward), + "TRUST_ANCHOR" | "ENDORSER" => Ok(Self::Endorser), + "NETWORK_MONITOR" => Ok(Self::NetworkMonitor), + _ => { + if let Ok(role) = value.parse::() { + Ok(Self::from(role)) + } else { + Err(input_err(format!("Invalid ledger role: {value}"))) + } + } + } + } +} + +impl From for LedgerRole { + fn from(value: usize) -> Self { + match value { + ROLE_TRUSTEE => Self::Trustee, + ROLE_STEWARD => Self::Steward, + ROLE_ENDORSER => Self::Endorser, + ROLE_NETWORK_MONITOR => Self::NetworkMonitor, + other => Self::Custom(other), + } + } +} + +impl From for usize { + fn from(value: LedgerRole) -> Self { + value.to_usize() + } +} + +impl<'d> Deserialize<'d> for LedgerRole { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'d>, + { + struct Vis; -pub const SELF_CERT_VERSIONS: [i32; 3] = [DEFAULT, DID_SOV, DID_INDY]; + impl<'v> Visitor<'v> for Vis { + type Value = LedgerRole; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("expected a ledger role identifier") + } + + fn visit_str(self, v: &str) -> Result + where + E: serde::de::Error, + { + LedgerRole::from_str(v).map_err(|e| E::custom(e.to_string())) + } + } + + deserializer.deserialize_any(Vis) + } +} + +impl Serialize for LedgerRole { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serializer.collect_str(&self.to_usize()) + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum UpdateRole { + Reset, + Set(LedgerRole), +} + +impl FromStr for UpdateRole { + type Err = VdrError; + + fn from_str(value: &str) -> Result { + match value { + "" => Ok(Self::Reset), + _ => LedgerRole::from_str(value).map(Self::Set), + } + } +} + +impl<'d> Deserialize<'d> for UpdateRole { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'d>, + { + struct Vis; + + impl<'v> Visitor<'v> for Vis { + type Value = UpdateRole; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("expected a ledger role identifier") + } + + fn visit_none(self) -> Result + where + E: serde::de::Error, + { + Ok(UpdateRole::Reset) + } + + fn visit_str(self, v: &str) -> Result + where + E: serde::de::Error, + { + LedgerRole::from_str(v) + .map_err(|e| E::custom(e.to_string())) + .map(UpdateRole::Set) + } + } + + deserializer.deserialize_any(Vis) + } +} + +impl Serialize for UpdateRole { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + match self { + Self::Reset => serializer.serialize_none(), + Self::Set(role) => serializer.collect_str(&role.to_usize()), + } + } +} pub fn txn_name_to_code(txn: &str) -> Option<&str> { if REQUESTS.contains(&txn) { diff --git a/libindy_vdr/src/ledger/request_builder.rs b/libindy_vdr/src/ledger/request_builder.rs index bd94fdf5..c37e3dc2 100644 --- a/libindy_vdr/src/ledger/request_builder.rs +++ b/libindy_vdr/src/ledger/request_builder.rs @@ -23,7 +23,7 @@ use super::requests::cred_def::{CredDefOperation, CredentialDefinition, GetCredD use super::requests::flag::{FlagOperation, GetFlagOperation}; use super::requests::ledgers_freeze::{GetFrozenLedgersOperation, LedgersFreezeOperation}; use super::requests::node::{NodeOperation, NodeOperationData}; -use super::requests::nym::{role_to_code, GetNymOperation, NymOperation}; +use super::requests::nym::{GetNymOperation, NymOperation}; use super::requests::pool::{ PoolConfigOperation, PoolRestartOperation, PoolUpgradeOperation, Schedule, }; @@ -47,7 +47,7 @@ use super::requests::txn::GetTxnOperation; use super::requests::validator_info::GetValidatorInfoOperation; use super::requests::{Request, RequestType}; -use super::constants::txn_name_to_code; +use super::constants::{txn_name_to_code, UpdateRole}; fn datetime_to_date_timestamp(time: u64) -> u64 { const SEC_IN_DAY: u64 = 86400; @@ -156,11 +156,10 @@ impl RequestBuilder { dest: &DidValue, verkey: Option, alias: Option, - role: Option, + role: Option, diddoc_content: Option<&SJsonValue>, version: Option, ) -> VdrResult { - let role = role_to_code(role)?; let operation = NymOperation::new( dest.to_short(), verkey, diff --git a/libindy_vdr/src/ledger/requests/auth_rule.rs b/libindy_vdr/src/ledger/requests/auth_rule.rs index 6a2ac063..80960836 100644 --- a/libindy_vdr/src/ledger/requests/auth_rule.rs +++ b/libindy_vdr/src/ledger/requests/auth_rule.rs @@ -4,6 +4,7 @@ use std::ops::Not; use super::constants::{AUTH_RULE, AUTH_RULES, GET_AUTH_RULE}; use super::{ProtocolVersion, RequestType}; use crate::common::error::prelude::*; +use crate::ledger::constants::LedgerRole; #[allow(non_camel_case_types)] #[derive(Deserialize, Debug, Serialize, PartialEq)] @@ -54,7 +55,7 @@ pub enum Constraint { #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] pub struct RoleConstraint { pub sig_count: u32, - pub role: Option, + pub role: Option, #[serde(skip_serializing_if = "Option::is_none")] pub metadata: Option, #[serde(default)] diff --git a/libindy_vdr/src/ledger/requests/nym.rs b/libindy_vdr/src/ledger/requests/nym.rs index 33b3eec7..3a1e7d2c 100644 --- a/libindy_vdr/src/ledger/requests/nym.rs +++ b/libindy_vdr/src/ledger/requests/nym.rs @@ -3,8 +3,8 @@ use sha2::{Digest, Sha256}; use super::constants::{GET_NYM, NYM}; use super::did::ShortDidValue; use super::{ProtocolVersion, RequestType}; -use crate::common::error::{input_err, VdrResult}; -use crate::ledger::constants::{ENDORSER, NETWORK_MONITOR, ROLES, ROLE_REMOVE, STEWARD, TRUSTEE}; +use crate::common::error::VdrResult; +use crate::ledger::constants::UpdateRole; #[derive(Serialize, PartialEq, Debug)] #[serde(rename_all = "camelCase")] @@ -16,7 +16,7 @@ pub struct NymOperation { #[serde(skip_serializing_if = "Option::is_none")] pub alias: Option, #[serde(skip_serializing_if = "Option::is_none")] - pub role: Option<::serde_json::Value>, + pub role: Option, #[serde(skip_serializing_if = "Option::is_none")] pub diddoc_content: Option, #[serde(skip_serializing_if = "Option::is_none")] @@ -28,7 +28,7 @@ impl NymOperation { dest: ShortDidValue, verkey: Option, alias: Option, - role: Option<::serde_json::Value>, + role: Option, diddoc_content: Option, version: Option, ) -> NymOperation { @@ -86,22 +86,3 @@ impl RequestType for GetNymOperation { Ok(Some(hash)) } } - -pub fn role_to_code(role: Option) -> VdrResult> { - if let Some(r) = role { - Ok(Some(if r == ROLE_REMOVE { - serde_json::Value::Null - } else { - json!(match r.as_str() { - "STEWARD" => STEWARD, - "TRUSTEE" => TRUSTEE, - "TRUST_ANCHOR" | "ENDORSER" => ENDORSER, - "NETWORK_MONITOR" => NETWORK_MONITOR, - role if ROLES.contains(&role) => role, - role => return Err(input_err(format!("Invalid role: {}", role))), - }) - })) - } else { - Ok(None) - } -} diff --git a/libindy_vdr/tests/auth_rule.rs b/libindy_vdr/tests/auth_rule.rs index 95689c80..de771e14 100644 --- a/libindy_vdr/tests/auth_rule.rs +++ b/libindy_vdr/tests/auth_rule.rs @@ -19,7 +19,7 @@ const VALUE: &str = "0"; fn _role_constraint() -> Constraint { Constraint::RoleConstraint(RoleConstraint { sig_count: 1, - role: Some(constants::TRUSTEE.to_string()), + role: Some(constants::LedgerRole::Trustee), metadata: Some(json!({})), need_to_be_owner: false, off_ledger_signature: false, @@ -35,7 +35,7 @@ fn _complex_constraint() -> Constraint { _role_constraint(), Constraint::RoleConstraint(RoleConstraint { sig_count: 2, - role: Some("2".to_string()), + role: Some(constants::LedgerRole::Custom(2)), metadata: None, need_to_be_owner: true, off_ledger_signature: false, diff --git a/libindy_vdr/tests/nym.rs b/libindy_vdr/tests/nym.rs index 5b5c69fe..9c63a6d2 100644 --- a/libindy_vdr/tests/nym.rs +++ b/libindy_vdr/tests/nym.rs @@ -4,7 +4,7 @@ mod utils; inject_dependencies!(); use indy_vdr::ledger::constants; -use indy_vdr::ledger::requests::nym::role_to_code; +use indy_vdr::ledger::constants::LedgerRole; use indy_vdr::utils::did::DidValue; use crate::utils::crypto::Identity; @@ -12,7 +12,7 @@ use crate::utils::fixtures::*; use crate::utils::helpers; const ALIAS: &str = "alias"; -const ROLE: &str = "TRUSTEE"; +const ROLE: LedgerRole = LedgerRole::Trustee; #[test] fn empty() { @@ -25,6 +25,8 @@ mod builder { use indy_vdr::ledger::RequestBuilder; mod nym { + use indy_vdr::ledger::constants::UpdateRole; + use super::*; #[rstest] @@ -59,7 +61,7 @@ mod builder { &identity.did, Some(identity.verkey.clone()), Some(ALIAS.to_string()), - Some(ROLE.to_string()), + Some(UpdateRole::Set(ROLE)), Some(&diddoc_content), None, ) @@ -70,7 +72,7 @@ mod builder { "dest": identity.did, "verkey": identity.verkey, "alias": ALIAS, - "role": role_to_code(Some(String::from(ROLE))).unwrap(), + "role": ROLE.to_usize().to_string(), "diddocContent": diddoc_content.to_string(), }); @@ -89,7 +91,7 @@ mod builder { &my_did, None, None, - Some(String::from("")), + Some(UpdateRole::Reset), None, None, ) @@ -122,27 +124,6 @@ mod builder { helpers::check_request_operation(&nym_request, expected_result); } - - #[rstest] - fn test_build_nym_request_works_for_invalid_role( - request_builder: RequestBuilder, - trustee_did: DidValue, - identity: Identity, - ) { - let role = "INALID_ROLE_ALIAS"; - - let _err = request_builder - .build_nym_request( - &trustee_did, - &identity.did, - Some(identity.verkey), - None, - Some(role.to_string()), - None, - None, - ) - .unwrap_err(); - } } mod get_nym { diff --git a/libindy_vdr/tests/utils/helpers.rs b/libindy_vdr/tests/utils/helpers.rs index f1d3862b..3f206840 100644 --- a/libindy_vdr/tests/utils/helpers.rs +++ b/libindy_vdr/tests/utils/helpers.rs @@ -1,6 +1,7 @@ use crate::utils::crypto::Identity; use crate::utils::pool::TestPool; use indy_vdr::common::error::VdrResult; +use indy_vdr::ledger::constants::{LedgerRole, UpdateRole}; use indy_vdr::pool::{NodeReplies, PreparedRequest}; use indy_vdr::utils::did::DidValue; use rand::distributions::Alphanumeric; @@ -31,7 +32,7 @@ pub fn get_response_data(response: &str) -> Result { Err(String::from("Cannot get response data")) } -pub fn new_ledger_identity(pool: &TestPool, role: Option) -> Identity { +pub fn new_ledger_identity(pool: &TestPool, role: Option) -> Identity { let trustee = Identity::trustee(); let new_identity = Identity::new(None, None); @@ -43,7 +44,7 @@ pub fn new_ledger_identity(pool: &TestPool, role: Option) -> Identity { &new_identity.did, Some(new_identity.verkey.to_string()), None, - role, + role.map(UpdateRole::Set), None, None, ) From bc28c828ca2cd0729893e0ee55ac26436cfeb683 Mon Sep 17 00:00:00 2001 From: Andrew Whitehead Date: Wed, 9 Aug 2023 14:58:26 -0700 Subject: [PATCH 112/117] fix tests Signed-off-by: Andrew Whitehead --- libindy_vdr/src/ledger/constants.rs | 4 +++ libindy_vdr/tests/cred_def.rs | 2 +- libindy_vdr/tests/endorse_transaction.rs | 5 ++-- libindy_vdr/tests/flag.rs | 2 +- libindy_vdr/tests/nym.rs | 38 +++++++++++++----------- libindy_vdr/tests/resolver.rs | 2 -- libindy_vdr/tests/revoc_reg.rs | 18 +++++------ libindy_vdr/tests/schema.rs | 2 +- 8 files changed, 37 insertions(+), 36 deletions(-) diff --git a/libindy_vdr/src/ledger/constants.rs b/libindy_vdr/src/ledger/constants.rs index 65b49448..93852811 100644 --- a/libindy_vdr/src/ledger/constants.rs +++ b/libindy_vdr/src/ledger/constants.rs @@ -144,6 +144,10 @@ impl LedgerRole { Self::Custom(val) => val, } } + + pub fn to_code(self) -> String { + self.to_usize().to_string() + } } impl fmt::Display for LedgerRole { diff --git a/libindy_vdr/tests/cred_def.rs b/libindy_vdr/tests/cred_def.rs index 3c92b860..f1df1c7e 100644 --- a/libindy_vdr/tests/cred_def.rs +++ b/libindy_vdr/tests/cred_def.rs @@ -89,7 +89,7 @@ mod send_cred_def { #[rstest] fn test_pool_send_cred_def_requests(pool: TestPool) { - let identity = helpers::new_ledger_identity(&pool, Some(String::from("TRUSTEE"))); + let identity = helpers::new_ledger_identity(&pool, Some(constants::LedgerRole::Trustee)); let schema = helpers::schema::default_schema(&identity.did); let (_schema_id, schema_seq_no) = helpers::schema::publish(&identity, &pool, &schema); diff --git a/libindy_vdr/tests/endorse_transaction.rs b/libindy_vdr/tests/endorse_transaction.rs index 4a7595bb..8c982763 100644 --- a/libindy_vdr/tests/endorse_transaction.rs +++ b/libindy_vdr/tests/endorse_transaction.rs @@ -16,10 +16,11 @@ mod endorse_transaction { use crate::utils::fixtures::*; use crate::utils::helpers; use crate::utils::pool::TestPool; + use indy_vdr::ledger::constants; #[rstest] fn test_pool_send_request_by_endorser(pool: TestPool) { - let endorser = helpers::new_ledger_identity(&pool, Some(String::from("ENDORSER"))); + let endorser = helpers::new_ledger_identity(&pool, Some(constants::LedgerRole::Endorser)); // Endorse Schema. Multi sign + Multi Sign. let author = helpers::new_ledger_identity(&pool, None); @@ -48,7 +49,7 @@ mod endorse_transaction { #[rstest] fn test_pool_send_request_by_endorser_for_missed_one_of_signatures(pool: TestPool) { let author = helpers::new_ledger_identity(&pool, None); - let endorser = helpers::new_ledger_identity(&pool, Some(String::from("ENDORSER"))); + let endorser = helpers::new_ledger_identity(&pool, Some(constants::LedgerRole::Endorser)); // Endorse Schema signed by author only diff --git a/libindy_vdr/tests/flag.rs b/libindy_vdr/tests/flag.rs index dd36eac2..dd2d3226 100644 --- a/libindy_vdr/tests/flag.rs +++ b/libindy_vdr/tests/flag.rs @@ -99,6 +99,6 @@ mod send_flag { .send_request_with_retries(&get_flag_request, &flag_response) .unwrap(); let data = helpers::get_response_data(&response); - assert_eq!(true, data.is_err()) + assert!(data.is_err()) } } diff --git a/libindy_vdr/tests/nym.rs b/libindy_vdr/tests/nym.rs index 9c63a6d2..2f7b4a63 100644 --- a/libindy_vdr/tests/nym.rs +++ b/libindy_vdr/tests/nym.rs @@ -72,7 +72,7 @@ mod builder { "dest": identity.did, "verkey": identity.verkey, "alias": ALIAS, - "role": ROLE.to_usize().to_string(), + "role": ROLE.to_code(), "diddocContent": diddoc_content.to_string(), }); @@ -173,7 +173,8 @@ mod builder { mod send { use super::*; use crate::utils::pool::TestPool; - use indy_vdr::ledger::{constants::ROLE_REMOVE, responses::GetNymResultV1}; + use indy_vdr::ledger::{constants::UpdateRole, responses::GetNymResultV1}; + use std::str::FromStr; #[rstest] fn test_pool_send_nym_request(pool: TestPool, trustee: Identity, identity: Identity) { @@ -226,7 +227,7 @@ mod send { &identity.did, Some(identity.verkey.to_string()), Some(ALIAS.to_string()), - Some(ROLE.to_string()), + Some(UpdateRole::Set(ROLE)), None, None, ) @@ -248,7 +249,7 @@ mod send { let expected_data = json!({ "dest": &identity.did, "verkey": &identity.verkey, - "role": role_to_code(Some(String::from(ROLE))).unwrap(), + "role": ROLE.to_code(), }); assert_eq!(expected_data, parse_get_nym_response(&response)); } @@ -268,7 +269,7 @@ mod send { &identity.did, Some(identity.verkey.to_string()), Some(ALIAS.to_string()), - Some(ROLE.to_string()), + Some(UpdateRole::Set(ROLE)), Some(&diddoc_content), None, ) @@ -291,7 +292,7 @@ mod send { "identifier": &trustee.did, "dest": &identity.did, "verkey": &identity.verkey, - "role": role_to_code(Some(String::from(ROLE))).unwrap(), + "role": ROLE.to_code(), "diddocContent": &diddoc_content.to_string() }); @@ -320,7 +321,7 @@ mod send { &identity.did, // Self-cert version 1 identifier Some(identity.verkey.to_string()), Some(ALIAS.to_string()), - Some(ROLE.to_string()), + Some(UpdateRole::Set(ROLE)), None, Some(2), // Claim Self-cert version 2 ) @@ -344,7 +345,7 @@ mod send { &identity.did, // Non self-cert identifier Some(identity.verkey.to_string()), Some(ALIAS.to_string()), - Some(ROLE.to_string()), + Some(UpdateRole::Set(ROLE)), None, Some(2), // Claim Self-cert version 2 ) @@ -369,7 +370,7 @@ mod send { &identity.did, // Non self-cert identifier Some(identity.verkey.to_string()), Some(ALIAS.to_string()), - Some(ROLE.to_string()), + Some(UpdateRole::Set(ROLE)), None, None, ) @@ -392,7 +393,7 @@ mod send { &identity.did, // Self-cert version 1 identifier Some(identity.verkey.to_string()), Some(ALIAS.to_string()), - Some(ROLE.to_string()), + Some(UpdateRole::Set(ROLE)), None, Some(0), // Claim Self-cert version 0 ) @@ -415,7 +416,7 @@ mod send { "identifier": &trustee.did, "dest": &identity.did, "verkey": &identity.verkey, - "role": role_to_code(Some(String::from(ROLE))).unwrap(), + "role": ROLE.to_code(), "version": 0, }); @@ -446,7 +447,7 @@ mod send { &identity.did, Some(identity.verkey.to_string()), Some(ALIAS.to_string()), - Some(ROLE.to_string()), + Some(UpdateRole::Set(ROLE)), Some(&diddoc_content), Some(2), ) @@ -469,7 +470,7 @@ mod send { "identifier": &trustee.did, "dest": &identity.did, "verkey": &identity.verkey, - "role": role_to_code(Some(String::from(ROLE))).unwrap(), + "role": ROLE.to_code(), "diddocContent": &diddoc_content.to_string(), "version": 2, }); @@ -499,6 +500,7 @@ mod send { role: &str, ) { let new_identity = Identity::new(None, None); + let upd_role = UpdateRole::from_str(role).unwrap(); // Send NYM let mut nym_request = pool @@ -508,7 +510,7 @@ mod send { &new_identity.did, Some(new_identity.verkey.to_string()), None, - Some(role.to_string()), + Some(upd_role), None, None, ) @@ -530,7 +532,7 @@ mod send { let expected_data = json!({ "dest": &new_identity.did, "verkey": &new_identity.verkey, - "role": role_to_code(Some(role.to_string())).unwrap(), + "role": LedgerRole::from_str(role).unwrap().to_code(), }); assert_eq!(expected_data, parse_get_nym_response(&response)); } @@ -549,7 +551,7 @@ mod send { &identity.did, Some(identity.verkey.to_string()), None, - Some(ROLE.to_string()), + Some(UpdateRole::Set(ROLE)), None, None, ) @@ -571,7 +573,7 @@ mod send { let expected_data = json!({ "dest": &identity.did, "verkey": &identity.verkey, - "role": role_to_code(Some(String::from(ROLE))).unwrap(), + "role": ROLE.to_code(), }); assert_eq!(expected_data, parse_get_nym_response(&response)); @@ -583,7 +585,7 @@ mod send { &identity.did, None, None, - Some(ROLE_REMOVE.to_string()), + Some(UpdateRole::Reset), None, None, ) diff --git a/libindy_vdr/tests/resolver.rs b/libindy_vdr/tests/resolver.rs index b518274f..aa4a7d46 100644 --- a/libindy_vdr/tests/resolver.rs +++ b/libindy_vdr/tests/resolver.rs @@ -14,8 +14,6 @@ mod send_resolver { use futures_executor::block_on; use indy_vdr::resolver::PoolResolver as Resolver; - use super::*; - use crate::utils::crypto::Identity; use crate::utils::fixtures::*; use crate::utils::helpers; diff --git a/libindy_vdr/tests/revoc_reg.rs b/libindy_vdr/tests/revoc_reg.rs index d7c4b09c..9f52eca8 100644 --- a/libindy_vdr/tests/revoc_reg.rs +++ b/libindy_vdr/tests/revoc_reg.rs @@ -181,7 +181,7 @@ mod send_revoc_reg { #[rstest] fn test_pool_send_revoc_reg_def_def_requests(pool: TestPool) { - let identity = helpers::new_ledger_identity(&pool, Some(String::from("TRUSTEE"))); + let identity = helpers::new_ledger_identity(&pool, Some(constants::LedgerRole::Trustee)); let schema = helpers::schema::default_schema(&identity.did); let (_schema_id, schema_seq_no) = helpers::schema::publish(&identity, &pool, &schema); @@ -349,13 +349,11 @@ mod send_revoc_reg { ) -> String { let get_revoc_reg = pool .request_builder() - .build_get_revoc_reg_request(None, &revoc_reg_id, timestamp) + .build_get_revoc_reg_request(None, revoc_reg_id, timestamp) .unwrap(); - let response = pool - .send_request_with_retries(&get_revoc_reg, revoc_reg_entry_response) - .unwrap(); - response + pool.send_request_with_retries(&get_revoc_reg, revoc_reg_entry_response) + .unwrap() } fn _get_revocation_registry_delta( @@ -367,13 +365,11 @@ mod send_revoc_reg { ) -> String { let get_revoc_reg_delta = pool .request_builder() - .build_get_revoc_reg_delta_request(None, &revoc_reg_id, from, to) + .build_get_revoc_reg_delta_request(None, revoc_reg_id, from, to) .unwrap(); - let response = pool - .send_request_with_retries(&get_revoc_reg_delta, revoc_reg_entry_response) - .unwrap(); - response + pool.send_request_with_retries(&get_revoc_reg_delta, revoc_reg_entry_response) + .unwrap() } fn _extract_txn_time_from_reply(reply: &str) -> u64 { diff --git a/libindy_vdr/tests/schema.rs b/libindy_vdr/tests/schema.rs index ff8df964..ed78a3be 100644 --- a/libindy_vdr/tests/schema.rs +++ b/libindy_vdr/tests/schema.rs @@ -130,7 +130,7 @@ mod send_schema { #[rstest] fn test_pool_schema_requests(pool: TestPool) { - let identity = helpers::new_ledger_identity(&pool, Some(String::from("TRUSTEE"))); + let identity = helpers::new_ledger_identity(&pool, Some(constants::LedgerRole::Endorser)); let schema = helpers::schema::default_schema(&identity.did); // Send Schema From b93884301984f1e47680e62e973e98a38ee2ce68 Mon Sep 17 00:00:00 2001 From: Andrew Whitehead Date: Wed, 9 Aug 2023 17:15:09 -0700 Subject: [PATCH 113/117] update JS dependencies Signed-off-by: Andrew Whitehead --- wrappers/javascript/yarn.lock | 3824 ++++++++++++++++++--------------- 1 file changed, 2051 insertions(+), 1773 deletions(-) diff --git a/wrappers/javascript/yarn.lock b/wrappers/javascript/yarn.lock index d509cef4..f351b024 100644 --- a/wrappers/javascript/yarn.lock +++ b/wrappers/javascript/yarn.lock @@ -2,319 +2,316 @@ # yarn lockfile v1 -"@ampproject/remapping@^2.1.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.0.tgz#56c133824780de3174aed5ab6834f3026790154d" - integrity sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w== +"@aashutoshrathi/word-wrap@^1.2.3": + version "1.2.6" + resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" + integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== + +"@ampproject/remapping@^2.2.0": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.1.tgz#99e8e11851128b8702cd57c33684f1d0f260b630" + integrity sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg== dependencies: - "@jridgewell/gen-mapping" "^0.1.0" + "@jridgewell/gen-mapping" "^0.3.0" "@jridgewell/trace-mapping" "^0.3.9" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789" - integrity sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg== +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.22.10", "@babel/code-frame@^7.22.5": + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.10.tgz#1c20e612b768fefa75f6e90d6ecb86329247f0a3" + integrity sha512-/KKIMG4UEL35WmI9OlvMhurwtytjvXoFcGNrOvyG9zIzA8YmPjVtIZUf7b05+TPO7G7/GEmLHDaoCgACHl9hhA== dependencies: - "@babel/highlight" "^7.16.7" + "@babel/highlight" "^7.22.10" + chalk "^2.4.2" -"@babel/compat-data@^7.13.11", "@babel/compat-data@^7.17.0", "@babel/compat-data@^7.17.10": - version "7.17.10" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.17.10.tgz#711dc726a492dfc8be8220028b1b92482362baab" - integrity sha512-GZt/TCsG70Ms19gfZO1tM4CVnXsPgEPBCpJu+Qz3L0LUDsY5nZqFZglIoPC1kIYOtNBZlrnFT+klg12vFGZXrw== +"@babel/compat-data@^7.20.5", "@babel/compat-data@^7.22.6", "@babel/compat-data@^7.22.9": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.22.9.tgz#71cdb00a1ce3a329ce4cbec3a44f9fef35669730" + integrity sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ== "@babel/core@^7.1.6", "@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.12.9", "@babel/core@^7.14.0", "@babel/core@^7.17.9": - version "7.17.10" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.17.10.tgz#74ef0fbf56b7dfc3f198fc2d927f4f03e12f4b05" - integrity sha512-liKoppandF3ZcBnIYFjfSDHZLKdLHGJRkoWtG8zQyGJBQfIYobpnVGI5+pLBNtS6psFLDzyq8+h5HiVljW9PNA== - dependencies: - "@ampproject/remapping" "^2.1.0" - "@babel/code-frame" "^7.16.7" - "@babel/generator" "^7.17.10" - "@babel/helper-compilation-targets" "^7.17.10" - "@babel/helper-module-transforms" "^7.17.7" - "@babel/helpers" "^7.17.9" - "@babel/parser" "^7.17.10" - "@babel/template" "^7.16.7" - "@babel/traverse" "^7.17.10" - "@babel/types" "^7.17.10" + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.22.10.tgz#aad442c7bcd1582252cb4576747ace35bc122f35" + integrity sha512-fTmqbbUBAwCcre6zPzNngvsI0aNrPZe77AeqvDxWM9Nm+04RrJ3CAmGHA9f7lJQY6ZMhRztNemy4uslDxTX4Qw== + dependencies: + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.22.10" + "@babel/generator" "^7.22.10" + "@babel/helper-compilation-targets" "^7.22.10" + "@babel/helper-module-transforms" "^7.22.9" + "@babel/helpers" "^7.22.10" + "@babel/parser" "^7.22.10" + "@babel/template" "^7.22.5" + "@babel/traverse" "^7.22.10" + "@babel/types" "^7.22.10" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.2" - json5 "^2.2.1" - semver "^6.3.0" + json5 "^2.2.2" + semver "^6.3.1" -"@babel/generator@^7.14.0", "@babel/generator@^7.17.10", "@babel/generator@^7.7.2": - version "7.17.10" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.17.10.tgz#c281fa35b0c349bbe9d02916f4ae08fc85ed7189" - integrity sha512-46MJZZo9y3o4kmhBVc7zW7i8dtR1oIK/sdO5NcfcZRhTGYi+KKJRtHNgsU6c4VUcJmUNV/LQdebD/9Dlv4K+Tg== +"@babel/generator@^7.14.0", "@babel/generator@^7.22.10", "@babel/generator@^7.7.2": + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.22.10.tgz#c92254361f398e160645ac58831069707382b722" + integrity sha512-79KIf7YiWjjdZ81JnLujDRApWtl7BxTqWD88+FFdQEIOG8LJ0etDOM7CXuIgGJa55sGOwZVwuEsaLEm0PJ5/+A== dependencies: - "@babel/types" "^7.17.10" - "@jridgewell/gen-mapping" "^0.1.0" + "@babel/types" "^7.22.10" + "@jridgewell/gen-mapping" "^0.3.2" + "@jridgewell/trace-mapping" "^0.3.17" jsesc "^2.5.1" -"@babel/helper-annotate-as-pure@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz#bb2339a7534a9c128e3102024c60760a3a7f3862" - integrity sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw== - dependencies: - "@babel/types" "^7.16.7" +"@babel/helper-annotate-as-pure@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz#e7f06737b197d580a01edf75d97e2c8be99d3882" + integrity sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-builder-binary-assignment-operator-visitor@^7.22.5": + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.10.tgz#573e735937e99ea75ea30788b57eb52fab7468c9" + integrity sha512-Av0qubwDQxC56DoUReVDeLfMEjYYSN1nZrTUrWkXd7hpU73ymRANkbuDm3yni9npkn+RXy9nNbEJZEzXr7xrfQ== + dependencies: + "@babel/types" "^7.22.10" + +"@babel/helper-compilation-targets@^7.20.7", "@babel/helper-compilation-targets@^7.22.10", "@babel/helper-compilation-targets@^7.22.5", "@babel/helper-compilation-targets@^7.22.6": + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.10.tgz#01d648bbc25dd88f513d862ee0df27b7d4e67024" + integrity sha512-JMSwHD4J7SLod0idLq5PKgI+6g/hLD/iuWBq08ZX49xE14VpVEojJ5rHWptpirV2j020MvypRLAXAO50igCJ5Q== + dependencies: + "@babel/compat-data" "^7.22.9" + "@babel/helper-validator-option" "^7.22.5" + browserslist "^4.21.9" + lru-cache "^5.1.1" + semver "^6.3.1" + +"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.22.10": + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.10.tgz#dd2612d59eac45588021ac3d6fa976d08f4e95a3" + integrity sha512-5IBb77txKYQPpOEdUdIhBx8VrZyDCQ+H82H0+5dX1TmuscP5vJKEE3cKurjtIw/vFwzbVH48VweE78kVDBrqjA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-function-name" "^7.22.5" + "@babel/helper-member-expression-to-functions" "^7.22.5" + "@babel/helper-optimise-call-expression" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.9" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + semver "^6.3.1" + +"@babel/helper-create-regexp-features-plugin@^7.22.5": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.9.tgz#9d8e61a8d9366fe66198f57c40565663de0825f6" + integrity sha512-+svjVa/tFwsNSG4NEy1h85+HQ5imbT92Q5/bgtS7P0GTQlP8WuFdqsiABmQouhiFGyV66oGxZFpeYHza1rNsKw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + regexpu-core "^5.3.1" + semver "^6.3.1" + +"@babel/helper-define-polyfill-provider@^0.4.2": + version "0.4.2" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.2.tgz#82c825cadeeeee7aad237618ebbe8fa1710015d7" + integrity sha512-k0qnnOqHn5dK9pZpfD5XXZ9SojAITdCKRn2Lp6rnDGzIbaP0rHyMPk/4wsSxVBVz4RfN0q6VpXWP2pDGIoQ7hw== + dependencies: + "@babel/helper-compilation-targets" "^7.22.6" + "@babel/helper-plugin-utils" "^7.22.5" + debug "^4.1.1" + lodash.debounce "^4.0.8" + resolve "^1.14.2" -"@babel/helper-builder-binary-assignment-operator-visitor@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.16.7.tgz#38d138561ea207f0f69eb1626a418e4f7e6a580b" - integrity sha512-C6FdbRaxYjwVu/geKW4ZeQ0Q31AftgRcdSnZ5/jsH6BzCJbtvXvhpfkbkThYSuutZA7nCXpPR6AD9zd1dprMkA== - dependencies: - "@babel/helper-explode-assignable-expression" "^7.16.7" - "@babel/types" "^7.16.7" +"@babel/helper-environment-visitor@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz#f06dd41b7c1f44e1f8da6c4055b41ab3a09a7e98" + integrity sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q== -"@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.16.7", "@babel/helper-compilation-targets@^7.17.10": - version "7.17.10" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.17.10.tgz#09c63106d47af93cf31803db6bc49fef354e2ebe" - integrity sha512-gh3RxjWbauw/dFiU/7whjd0qN9K6nPJMqe6+Er7rOavFh0CQUSwhAE3IcTho2rywPJFxej6TUUHDkWcYI6gGqQ== +"@babel/helper-function-name@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz#ede300828905bb15e582c037162f99d5183af1be" + integrity sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ== dependencies: - "@babel/compat-data" "^7.17.10" - "@babel/helper-validator-option" "^7.16.7" - browserslist "^4.20.2" - semver "^6.3.0" + "@babel/template" "^7.22.5" + "@babel/types" "^7.22.5" -"@babel/helper-create-class-features-plugin@^7.16.7": - version "7.17.9" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.17.9.tgz#71835d7fb9f38bd9f1378e40a4c0902fdc2ea49d" - integrity sha512-kUjip3gruz6AJKOq5i3nC6CoCEEF/oHH3cp6tOZhB+IyyyPyW0g1Gfsxn3mkk6S08pIA2y8GQh609v9G/5sHVQ== +"@babel/helper-hoist-variables@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz#c01a007dac05c085914e8fb652b339db50d823bb" + integrity sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw== dependencies: - "@babel/helper-annotate-as-pure" "^7.16.7" - "@babel/helper-environment-visitor" "^7.16.7" - "@babel/helper-function-name" "^7.17.9" - "@babel/helper-member-expression-to-functions" "^7.17.7" - "@babel/helper-optimise-call-expression" "^7.16.7" - "@babel/helper-replace-supers" "^7.16.7" - "@babel/helper-split-export-declaration" "^7.16.7" + "@babel/types" "^7.22.5" -"@babel/helper-create-regexp-features-plugin@^7.16.7": - version "7.17.0" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.17.0.tgz#1dcc7d40ba0c6b6b25618997c5dbfd310f186fe1" - integrity sha512-awO2So99wG6KnlE+TPs6rn83gCz5WlEePJDTnLEqbchMVrBeAujURVphRdigsk094VhvZehFoNOihSlcBjwsXA== +"@babel/helper-member-expression-to-functions@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.22.5.tgz#0a7c56117cad3372fbf8d2fb4bf8f8d64a1e76b2" + integrity sha512-aBiH1NKMG0H2cGZqspNvsaBe6wNGjbJjuLy29aU+eDZjSbbN53BaxlpB02xm9v34pLTZ1nIQPFYn2qMZoa5BQQ== dependencies: - "@babel/helper-annotate-as-pure" "^7.16.7" - regexpu-core "^5.0.1" + "@babel/types" "^7.22.5" + +"@babel/helper-module-imports@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz#1a8f4c9f4027d23f520bd76b364d44434a72660c" + integrity sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg== + dependencies: + "@babel/types" "^7.22.5" -"@babel/helper-define-polyfill-provider@^0.3.1": - version "0.3.1" - resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.1.tgz#52411b445bdb2e676869e5a74960d2d3826d2665" - integrity sha512-J9hGMpJQmtWmj46B3kBHmL38UhJGhYX7eqkcq+2gsstyYt341HmPeWspihX43yVRA0mS+8GGk2Gckc7bY/HCmA== - dependencies: - "@babel/helper-compilation-targets" "^7.13.0" - "@babel/helper-module-imports" "^7.12.13" - "@babel/helper-plugin-utils" "^7.13.0" - "@babel/traverse" "^7.13.0" - debug "^4.1.1" - lodash.debounce "^4.0.8" - resolve "^1.14.2" - semver "^6.1.2" - -"@babel/helper-environment-visitor@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz#ff484094a839bde9d89cd63cba017d7aae80ecd7" - integrity sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag== - dependencies: - "@babel/types" "^7.16.7" - -"@babel/helper-explode-assignable-expression@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.16.7.tgz#12a6d8522fdd834f194e868af6354e8650242b7a" - integrity sha512-KyUenhWMC8VrxzkGP0Jizjo4/Zx+1nNZhgocs+gLzyZyB8SHidhoq9KK/8Ato4anhwsivfkBLftky7gvzbZMtQ== +"@babel/helper-module-transforms@^7.22.5", "@babel/helper-module-transforms@^7.22.9": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.22.9.tgz#92dfcb1fbbb2bc62529024f72d942a8c97142129" + integrity sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ== + dependencies: + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-module-imports" "^7.22.5" + "@babel/helper-simple-access" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/helper-validator-identifier" "^7.22.5" + +"@babel/helper-optimise-call-expression@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz#f21531a9ccbff644fdd156b4077c16ff0c3f609e" + integrity sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.8.0": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz#dd7ee3735e8a313b9f7b05a773d892e88e6d7295" + integrity sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg== + +"@babel/helper-remap-async-to-generator@^7.22.5": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.9.tgz#53a25b7484e722d7efb9c350c75c032d4628de82" + integrity sha512-8WWC4oR4Px+tr+Fp0X3RHDVfINGpF3ad1HIbrc8A77epiR6eMMc6jsgozkzT2uDiOOdoS9cLIQ+XD2XvI2WSmQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-wrap-function" "^7.22.9" + +"@babel/helper-replace-supers@^7.22.5", "@babel/helper-replace-supers@^7.22.9": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.22.9.tgz#cbdc27d6d8d18cd22c81ae4293765a5d9afd0779" + integrity sha512-LJIKvvpgPOPUThdYqcX6IXRuIcTkcAub0IaDRGCZH0p5GPUp7PhRU9QVgFcDDd51BaPkk77ZjqFwh6DZTAEmGg== + dependencies: + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-member-expression-to-functions" "^7.22.5" + "@babel/helper-optimise-call-expression" "^7.22.5" + +"@babel/helper-simple-access@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz#4938357dc7d782b80ed6dbb03a0fba3d22b1d5de" + integrity sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-skip-transparent-expression-wrappers@^7.20.0", "@babel/helper-skip-transparent-expression-wrappers@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz#007f15240b5751c537c40e77abb4e89eeaaa8847" + integrity sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-split-export-declaration@^7.22.6": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz#322c61b7310c0997fe4c323955667f18fcefb91c" + integrity sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-string-parser@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz#533f36457a25814cf1df6488523ad547d784a99f" + integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw== + +"@babel/helper-validator-identifier@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz#9544ef6a33999343c8740fa51350f30eeaaaf193" + integrity sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ== + +"@babel/helper-validator-option@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz#de52000a15a177413c8234fa3a8af4ee8102d0ac" + integrity sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw== + +"@babel/helper-wrap-function@^7.22.9": + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.22.10.tgz#d845e043880ed0b8c18bd194a12005cb16d2f614" + integrity sha512-OnMhjWjuGYtdoO3FmsEFWvBStBAe2QOgwOLsLNDjN+aaiMD8InJk1/O3HSD8lkqTjCgg5YI34Tz15KNNA3p+nQ== + dependencies: + "@babel/helper-function-name" "^7.22.5" + "@babel/template" "^7.22.5" + "@babel/types" "^7.22.10" + +"@babel/helpers@^7.22.10": + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.22.10.tgz#ae6005c539dfbcb5cd71fb51bfc8a52ba63bc37a" + integrity sha512-a41J4NW8HyZa1I1vAndrraTlPZ/eZoga2ZgS7fEr0tZJGVU4xqdE80CEm0CcNjha5EZ8fTBYLKHF0kqDUuAwQw== dependencies: - "@babel/types" "^7.16.7" - -"@babel/helper-function-name@^7.16.7", "@babel/helper-function-name@^7.17.9": - version "7.17.9" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.17.9.tgz#136fcd54bc1da82fcb47565cf16fd8e444b1ff12" - integrity sha512-7cRisGlVtiVqZ0MW0/yFB4atgpGLWEHUVYnb448hZK4x+vih0YO5UoS11XIYtZYqHd0dIPMdUSv8q5K4LdMnIg== - dependencies: - "@babel/template" "^7.16.7" - "@babel/types" "^7.17.0" - -"@babel/helper-hoist-variables@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz#86bcb19a77a509c7b77d0e22323ef588fa58c246" - integrity sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg== - dependencies: - "@babel/types" "^7.16.7" - -"@babel/helper-member-expression-to-functions@^7.16.7", "@babel/helper-member-expression-to-functions@^7.17.7": - version "7.17.7" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.17.7.tgz#a34013b57d8542a8c4ff8ba3f747c02452a4d8c4" - integrity sha512-thxXgnQ8qQ11W2wVUObIqDL4p148VMxkt5T/qpN5k2fboRyzFGFmKsTGViquyM5QHKUy48OZoca8kw4ajaDPyw== - dependencies: - "@babel/types" "^7.17.0" - -"@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz#25612a8091a999704461c8a222d0efec5d091437" - integrity sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg== - dependencies: - "@babel/types" "^7.16.7" - -"@babel/helper-module-transforms@^7.17.7": - version "7.17.7" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.17.7.tgz#3943c7f777139e7954a5355c815263741a9c1cbd" - integrity sha512-VmZD99F3gNTYB7fJRDTi+u6l/zxY0BE6OIxPSU7a50s6ZUQkHwSDmV92FfM+oCG0pZRVojGYhkR8I0OGeCVREw== - dependencies: - "@babel/helper-environment-visitor" "^7.16.7" - "@babel/helper-module-imports" "^7.16.7" - "@babel/helper-simple-access" "^7.17.7" - "@babel/helper-split-export-declaration" "^7.16.7" - "@babel/helper-validator-identifier" "^7.16.7" - "@babel/template" "^7.16.7" - "@babel/traverse" "^7.17.3" - "@babel/types" "^7.17.0" - -"@babel/helper-optimise-call-expression@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.7.tgz#a34e3560605abbd31a18546bd2aad3e6d9a174f2" - integrity sha512-EtgBhg7rd/JcnpZFXpBy0ze1YRfdm7BnBX4uKMBd3ixa3RGAE002JZB66FJyNH7g0F38U05pXmA5P8cBh7z+1w== - dependencies: - "@babel/types" "^7.16.7" - -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.13.0", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.8.0": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz#aa3a8ab4c3cceff8e65eb9e73d87dc4ff320b2f5" - integrity sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA== - -"@babel/helper-remap-async-to-generator@^7.16.8": - version "7.16.8" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.16.8.tgz#29ffaade68a367e2ed09c90901986918d25e57e3" - integrity sha512-fm0gH7Flb8H51LqJHy3HJ3wnE1+qtYR2A99K06ahwrawLdOFsCEWjZOrYricXJHoPSudNKxrMBUPEIPxiIIvBw== - dependencies: - "@babel/helper-annotate-as-pure" "^7.16.7" - "@babel/helper-wrap-function" "^7.16.8" - "@babel/types" "^7.16.8" - -"@babel/helper-replace-supers@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.16.7.tgz#e9f5f5f32ac90429c1a4bdec0f231ef0c2838ab1" - integrity sha512-y9vsWilTNaVnVh6xiJfABzsNpgDPKev9HnAgz6Gb1p6UUwf9NepdlsV7VXGCftJM+jqD5f7JIEubcpLjZj5dBw== - dependencies: - "@babel/helper-environment-visitor" "^7.16.7" - "@babel/helper-member-expression-to-functions" "^7.16.7" - "@babel/helper-optimise-call-expression" "^7.16.7" - "@babel/traverse" "^7.16.7" - "@babel/types" "^7.16.7" - -"@babel/helper-simple-access@^7.17.7": - version "7.17.7" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.17.7.tgz#aaa473de92b7987c6dfa7ce9a7d9674724823367" - integrity sha512-txyMCGroZ96i+Pxr3Je3lzEJjqwaRC9buMUgtomcrLe5Nd0+fk1h0LLA+ixUF5OW7AhHuQ7Es1WcQJZmZsz2XA== - dependencies: - "@babel/types" "^7.17.0" - -"@babel/helper-skip-transparent-expression-wrappers@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.16.0.tgz#0ee3388070147c3ae051e487eca3ebb0e2e8bb09" - integrity sha512-+il1gTy0oHwUsBQZyJvukbB4vPMdcYBrFHa0Uc4AizLxbq6BOYC51Rv4tWocX9BLBDLZ4kc6qUFpQ6HRgL+3zw== - dependencies: - "@babel/types" "^7.16.0" - -"@babel/helper-split-export-declaration@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz#0b648c0c42da9d3920d85ad585f2778620b8726b" - integrity sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw== - dependencies: - "@babel/types" "^7.16.7" - -"@babel/helper-validator-identifier@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad" - integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw== - -"@babel/helper-validator-option@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz#b203ce62ce5fe153899b617c08957de860de4d23" - integrity sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ== - -"@babel/helper-wrap-function@^7.16.8": - version "7.16.8" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.16.8.tgz#58afda087c4cd235de92f7ceedebca2c41274200" - integrity sha512-8RpyRVIAW1RcDDGTA+GpPAwV22wXCfKOoM9bet6TLkGIFTkRQSkH1nMQ5Yet4MpoXe1ZwHPVtNasc2w0uZMqnw== - dependencies: - "@babel/helper-function-name" "^7.16.7" - "@babel/template" "^7.16.7" - "@babel/traverse" "^7.16.8" - "@babel/types" "^7.16.8" - -"@babel/helpers@^7.17.9": - version "7.17.9" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.17.9.tgz#b2af120821bfbe44f9907b1826e168e819375a1a" - integrity sha512-cPCt915ShDWUEzEp3+UNRktO2n6v49l5RSnG9M5pS24hA+2FAc5si+Pn1i4VVbQQ+jh+bIZhPFQOJOzbrOYY1Q== - dependencies: - "@babel/template" "^7.16.7" - "@babel/traverse" "^7.17.9" - "@babel/types" "^7.17.0" - -"@babel/highlight@^7.16.7": - version "7.17.9" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.17.9.tgz#61b2ee7f32ea0454612def4fccdae0de232b73e3" - integrity sha512-J9PfEKCbFIv2X5bjTMiZu6Vf341N05QIY+d6FvVKynkG1S7G0j3I0QoRtWIrXhZ+/Nlb5Q0MzqL7TokEJ5BNHg== - dependencies: - "@babel/helper-validator-identifier" "^7.16.7" - chalk "^2.0.0" + "@babel/template" "^7.22.5" + "@babel/traverse" "^7.22.10" + "@babel/types" "^7.22.10" + +"@babel/highlight@^7.22.10": + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.10.tgz#02a3f6d8c1cb4521b2fd0ab0da8f4739936137d7" + integrity sha512-78aUtVcT7MUscr0K5mIEnkwxPE0MaxkR5RxRwuHaQ+JuU5AmTPhY+do2mdzVTnIJJpyBglql2pehuBIWHug+WQ== + dependencies: + "@babel/helper-validator-identifier" "^7.22.5" + chalk "^2.4.2" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.1.6", "@babel/parser@^7.14.0", "@babel/parser@^7.14.7", "@babel/parser@^7.16.7", "@babel/parser@^7.17.10": - version "7.17.10" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.17.10.tgz#873b16db82a8909e0fbd7f115772f4b739f6ce78" - integrity sha512-n2Q6i+fnJqzOaq2VkdXxy2TCPCWQZHiCo0XqmrCvDWcZQKRyZzYi4Z0yxlBuN0w+r2ZHmre+Q087DSrw3pbJDQ== +"@babel/parser@^7.1.0", "@babel/parser@^7.1.6", "@babel/parser@^7.14.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.22.10", "@babel/parser@^7.22.5": + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.10.tgz#e37634f9a12a1716136c44624ef54283cabd3f55" + integrity sha512-lNbdGsQb9ekfsnjFGhEiF4hfFqGgfOP3H3d27re3n+CGhNuTSUEQdfWk556sTLNTloczcdM5TYF2LhzmDQKyvQ== "@babel/plugin-proposal-class-properties@^7.0.0", "@babel/plugin-proposal-class-properties@^7.1.0": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.7.tgz#925cad7b3b1a2fcea7e59ecc8eb5954f961f91b0" - integrity sha512-IobU0Xme31ewjYOShSIqd/ZGM/r/cuOz2z0MDbNrhF5FW+ZVgi0f2lyeoj9KFPDOAqsYxmLWZte1WOwlvY9aww== + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz#b110f59741895f7ec21a6fff696ec46265c446a3" + integrity sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ== dependencies: - "@babel/helper-create-class-features-plugin" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-create-class-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-proposal-export-default-from@^7.0.0": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.16.7.tgz#a40ab158ca55627b71c5513f03d3469026a9e929" - integrity sha512-+cENpW1rgIjExn+o5c8Jw/4BuH4eGKKYvkMB8/0ZxFQ9mC0t4z09VsPIwNg6waF69QYC81zxGeAsREGuqQoKeg== + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.22.5.tgz#825924eda1fad382c3de4db6fe1711b6fa03362f" + integrity sha512-UCe1X/hplyv6A5g2WnQ90tnHRvYL29dabCWww92lO7VdfMVTVReBTRrhiMrKQejHD9oVkdnRdwYuzUZkBVQisg== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/plugin-syntax-export-default-from" "^7.16.7" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-export-default-from" "^7.22.5" "@babel/plugin-proposal-nullish-coalescing-operator@^7.0.0", "@babel/plugin-proposal-nullish-coalescing-operator@^7.1.0": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.16.7.tgz#141fc20b6857e59459d430c850a0011e36561d99" - integrity sha512-aUOrYU3EVtjf62jQrCj63pYZ7k6vns2h/DQvHPWGmsJRYzWXZ6/AsfgpiRy6XiuIDADhJzP2Q9MwSMKauBQ+UQ== + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz#fdd940a99a740e577d6c753ab6fbb43fdb9467e1" + integrity sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" "@babel/plugin-proposal-object-rest-spread@^7.0.0": - version "7.17.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.17.3.tgz#d9eb649a54628a51701aef7e0ea3d17e2b9dd390" - integrity sha512-yuL5iQA/TbZn+RGAfxQXfi7CNLmKi1f8zInn4IgobuCWcAb7i+zj4TYzQ9l8cEzVyJ89PDGuqxK1xZpUDISesw== + version "7.20.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz#aa662940ef425779c75534a5c41e9d936edc390a" + integrity sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg== dependencies: - "@babel/compat-data" "^7.17.0" - "@babel/helper-compilation-targets" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/compat-data" "^7.20.5" + "@babel/helper-compilation-targets" "^7.20.7" + "@babel/helper-plugin-utils" "^7.20.2" "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-transform-parameters" "^7.16.7" + "@babel/plugin-transform-parameters" "^7.20.7" "@babel/plugin-proposal-optional-catch-binding@^7.0.0": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.16.7.tgz#c623a430674ffc4ab732fd0a0ae7722b67cb74cf" - integrity sha512-eMOH/L4OvWSZAE1VkHbr1vckLG1WUcHGJSLqqQwl2GaUqG6QjddvrOaTUMNYiv77H5IKPMZ9U9P7EaHwvAShfA== + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz#f9400d0e6a3ea93ba9ef70b09e72dd6da638a2cb" + integrity sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" "@babel/plugin-proposal-optional-chaining@^7.0.0", "@babel/plugin-proposal-optional-chaining@^7.1.0": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.7.tgz#7cd629564724816c0e8a969535551f943c64c39a" - integrity sha512-eC3xy+ZrUcBtP7x+sq62Q/HYd674pPTb/77XZMb5wbDPGWIdUbSr4Agr052+zaUPSb+gGRnjxXfKFvx5iMJ+DA== + version "7.21.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz#886f5c8978deb7d30f678b2e24346b287234d3ea" + integrity sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" + "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0" "@babel/plugin-syntax-optional-chaining" "^7.8.3" "@babel/plugin-syntax-async-generators@^7.8.4": @@ -345,19 +342,19 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-export-default-from@^7.0.0", "@babel/plugin-syntax-export-default-from@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.16.7.tgz#fa89cf13b60de2c3f79acdc2b52a21174c6de060" - integrity sha512-4C3E4NsrLOgftKaTYTULhHsuQrGv3FHrBzOMDiS7UYKIpgGBkAdawg4h+EI8zPeK9M0fiIIh72hIwsI24K7MbA== +"@babel/plugin-syntax-export-default-from@^7.0.0", "@babel/plugin-syntax-export-default-from@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.22.5.tgz#ac3a24b362a04415a017ab96b9b4483d0e2a6e44" + integrity sha512-ODAqWWXB/yReh/jVQDag/3/tl6lgBueQkk/TcfW/59Oykm4c8a55XloX0CTk2k2VJiFWMgHby9xNX29IbCv9dQ== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-syntax-flow@^7.0.0", "@babel/plugin-syntax-flow@^7.16.7", "@babel/plugin-syntax-flow@^7.2.0": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.16.7.tgz#202b147e5892b8452bbb0bb269c7ed2539ab8832" - integrity sha512-UDo3YGQO0jH6ytzVwgSLv9i/CzMcUjbKenL67dTrAZPPv6GFAtDhe6jqnvmoKzC/7htNTohhos+onPtDMqJwaQ== +"@babel/plugin-syntax-flow@^7.0.0", "@babel/plugin-syntax-flow@^7.2.0", "@babel/plugin-syntax-flow@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.22.5.tgz#163b820b9e7696ce134df3ee716d9c0c98035859" + integrity sha512-9RdCl0i+q0QExayk2nOS7853w08yLucnnPML6EN9S8fgMPVtdLDCdx/cOQ/i44Lb9UeQX9A35yaqBBOMMZxPxQ== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-import-meta@^7.8.3": version "7.10.4" @@ -373,12 +370,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-jsx@^7.0.0", "@babel/plugin-syntax-jsx@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.16.7.tgz#50b6571d13f764266a113d77c82b4a6508bbe665" - integrity sha512-Esxmk7YjA8QysKeT3VhTXvF6y77f/a91SIs4pWb4H2eWGQkCKFgQaG6hdoEVZtGsrAcb2K5BW66XsOErD4WU3Q== +"@babel/plugin-syntax-jsx@^7.0.0", "@babel/plugin-syntax-jsx@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz#a6b68e84fb76e759fc3b93e901876ffabbe1d918" + integrity sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-logical-assignment-operators@^7.8.3": version "7.10.4" @@ -429,275 +426,280 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-syntax-typescript@^7.16.7", "@babel/plugin-syntax-typescript@^7.7.2": - version "7.17.10" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.17.10.tgz#80031e6042cad6a95ed753f672ebd23c30933195" - integrity sha512-xJefea1DWXW09pW4Tm9bjwVlPDyYA2it3fWlmEjpYz6alPvTUjL0EOzNzI/FEOyI3r4/J7uVH5UqKgl1TQ5hqQ== +"@babel/plugin-syntax-typescript@^7.22.5", "@babel/plugin-syntax-typescript@^7.7.2": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.22.5.tgz#aac8d383b062c5072c647a31ef990c1d0af90272" + integrity sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-transform-arrow-functions@^7.0.0": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.16.7.tgz#44125e653d94b98db76369de9c396dc14bef4154" - integrity sha512-9ffkFFMbvzTvv+7dTp/66xvZAWASuPD5Tl9LK3Z9vhOmANo6j94rik+5YMBt4CwHVMWLWpMsriIc2zsa3WW3xQ== + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.22.5.tgz#e5ba566d0c58a5b2ba2a8b795450641950b71958" + integrity sha512-26lTNXoVRdAnsaDXPpvCNUq+OVWEVC6bx7Vvz9rC53F2bagUWW4u4ii2+h8Fejfh7RYqPxn+libeFBBck9muEw== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-transform-async-to-generator@^7.0.0": - version "7.16.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.16.8.tgz#b83dff4b970cf41f1b819f8b49cc0cfbaa53a808" - integrity sha512-MtmUmTJQHCnyJVrScNzNlofQJ3dLFuobYn3mwOTKHnSCMtbNsqvF71GQmJfFjdrXSsAA7iysFmYWw4bXZ20hOg== + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.22.5.tgz#c7a85f44e46f8952f6d27fe57c2ed3cc084c3775" + integrity sha512-b1A8D8ZzE/VhNDoV1MSJTnpKkCG5bJo+19R4o4oy03zM7ws8yEMK755j61Dc3EyvdysbqH5BOOTquJ7ZX9C6vQ== dependencies: - "@babel/helper-module-imports" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/helper-remap-async-to-generator" "^7.16.8" + "@babel/helper-module-imports" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-remap-async-to-generator" "^7.22.5" "@babel/plugin-transform-block-scoped-functions@^7.0.0": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.16.7.tgz#4d0d57d9632ef6062cdf354bb717102ee042a620" - integrity sha512-JUuzlzmF40Z9cXyytcbZEZKckgrQzChbQJw/5PuEHYeqzCsvebDx0K0jWnIIVcmmDOAVctCgnYs0pMcrYj2zJg== + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.22.5.tgz#27978075bfaeb9fa586d3cb63a3d30c1de580024" + integrity sha512-tdXZ2UdknEKQWKJP1KMNmuF5Lx3MymtMN/pvA+p/VEkhK8jVcQ1fzSy8KM9qRYhAf2/lV33hoMPKI/xaI9sADA== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-transform-block-scoping@^7.0.0": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.16.7.tgz#f50664ab99ddeaee5bc681b8f3a6ea9d72ab4f87" - integrity sha512-ObZev2nxVAYA4bhyusELdo9hb3H+A56bxH3FZMbEImZFiEDYVHXQSJ1hQKFlDnlt8G9bBrCZ5ZpURZUrV4G5qQ== + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.22.10.tgz#88a1dccc3383899eb5e660534a76a22ecee64faa" + integrity sha512-1+kVpGAOOI1Albt6Vse7c8pHzcZQdQKW+wJH+g8mCaszOdDVwRXa/slHPqIw+oJAJANTKDMuM2cBdV0Dg618Vg== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-transform-classes@^7.0.0": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.16.7.tgz#8f4b9562850cd973de3b498f1218796eb181ce00" - integrity sha512-WY7og38SFAGYRe64BrjKf8OrE6ulEHtr5jEYaZMwox9KebgqPi67Zqz8K53EKk1fFEJgm96r32rkKZ3qA2nCWQ== - dependencies: - "@babel/helper-annotate-as-pure" "^7.16.7" - "@babel/helper-environment-visitor" "^7.16.7" - "@babel/helper-function-name" "^7.16.7" - "@babel/helper-optimise-call-expression" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/helper-replace-supers" "^7.16.7" - "@babel/helper-split-export-declaration" "^7.16.7" + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.22.6.tgz#e04d7d804ed5b8501311293d1a0e6d43e94c3363" + integrity sha512-58EgM6nuPNG6Py4Z3zSuu0xWu2VfodiMi72Jt5Kj2FECmaYk1RrTXA45z6KBFsu9tRgwQDwIiY4FXTt+YsSFAQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-compilation-targets" "^7.22.6" + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-function-name" "^7.22.5" + "@babel/helper-optimise-call-expression" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" globals "^11.1.0" "@babel/plugin-transform-computed-properties@^7.0.0": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.16.7.tgz#66dee12e46f61d2aae7a73710f591eb3df616470" - integrity sha512-gN72G9bcmenVILj//sv1zLNaPyYcOzUho2lIJBMh/iakJ9ygCo/hEF9cpGb61SCMEDxbbyBoVQxrt+bWKu5KGw== + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.22.5.tgz#cd1e994bf9f316bd1c2dafcd02063ec261bb3869" + integrity sha512-4GHWBgRf0krxPX+AaPtgBAlTgTeZmqDynokHOX7aqqAB4tHs3U2Y02zH6ETFdLZGcg9UQSD1WCmkVrE9ErHeOg== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/template" "^7.22.5" "@babel/plugin-transform-destructuring@^7.0.0": - version "7.17.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.17.7.tgz#49dc2675a7afa9a5e4c6bdee636061136c3408d1" - integrity sha512-XVh0r5yq9sLR4vZ6eVZe8FKfIcSgaTBxVBRSYokRj2qksf6QerYnTxz9/GTuKTH/n/HwLP7t6gtlybHetJ/6hQ== + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.22.10.tgz#38e2273814a58c810b6c34ea293be4973c4eb5e2" + integrity sha512-dPJrL0VOyxqLM9sritNbMSGx/teueHF/htMKrPT7DNxccXxRDPYqlgPFFdr8u+F+qUZOkZoXue/6rL5O5GduEw== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-transform-exponentiation-operator@^7.0.0": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.16.7.tgz#efa9862ef97e9e9e5f653f6ddc7b665e8536fe9b" - integrity sha512-8UYLSlyLgRixQvlYH3J2ekXFHDFLQutdy7FfFAMm3CPZ6q9wHCwnUyiXpQCe3gVVnQlHc5nsuiEVziteRNTXEA== + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.22.5.tgz#402432ad544a1f9a480da865fda26be653e48f6a" + integrity sha512-vIpJFNM/FjZ4rh1myqIya9jXwrwwgFRHPjT3DkUA9ZLHuzox8jiXkOLvwm1H+PQIP3CqfC++WPKeuDi0Sjdj1g== dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-flow-strip-types@^7.0.0", "@babel/plugin-transform-flow-strip-types@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.16.7.tgz#291fb140c78dabbf87f2427e7c7c332b126964b8" - integrity sha512-mzmCq3cNsDpZZu9FADYYyfZJIOrSONmHcop2XEKPdBNMa4PDC4eEvcOvzZaCNcjKu72v0XQlA5y1g58aLRXdYg== +"@babel/plugin-transform-flow-strip-types@^7.0.0", "@babel/plugin-transform-flow-strip-types@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.22.5.tgz#0bb17110c7bf5b35a60754b2f00c58302381dee2" + integrity sha512-tujNbZdxdG0/54g/oua8ISToaXTFBf8EnSb5PgQSciIXWOWKX3S4+JR7ZE9ol8FZwf9kxitzkGQ+QWeov/mCiA== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/plugin-syntax-flow" "^7.16.7" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-flow" "^7.22.5" "@babel/plugin-transform-for-of@^7.0.0": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.16.7.tgz#649d639d4617dff502a9a158c479b3b556728d8c" - integrity sha512-/QZm9W92Ptpw7sjI9Nx1mbcsWz33+l8kuMIQnDwgQBG5s3fAfQvkRjQ7NqXhtNcKOnPkdICmUHyCaWW06HCsqg== + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.22.5.tgz#ab1b8a200a8f990137aff9a084f8de4099ab173f" + integrity sha512-3kxQjX1dU9uudwSshyLeEipvrLjBCVthCgeTp6CzE/9JYrlAIaeekVxRpCWsDDfYTfRZRoCeZatCQvwo+wvK8A== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-transform-function-name@^7.0.0": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.16.7.tgz#5ab34375c64d61d083d7d2f05c38d90b97ec65cf" - integrity sha512-SU/C68YVwTRxqWj5kgsbKINakGag0KTgq9f2iZEXdStoAbOzLHEBRYzImmA6yFo8YZhJVflvXmIHUO7GWHmxxA== + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.22.5.tgz#935189af68b01898e0d6d99658db6b164205c143" + integrity sha512-UIzQNMS0p0HHiQm3oelztj+ECwFnj+ZRV4KnguvlsD2of1whUeM6o7wGNj6oLwcDoAXQ8gEqfgC24D+VdIcevg== dependencies: - "@babel/helper-compilation-targets" "^7.16.7" - "@babel/helper-function-name" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-compilation-targets" "^7.22.5" + "@babel/helper-function-name" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-transform-literals@^7.0.0": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.16.7.tgz#254c9618c5ff749e87cb0c0cef1a0a050c0bdab1" - integrity sha512-6tH8RTpTWI0s2sV6uq3e/C9wPo4PTqqZps4uF0kzQ9/xPLFQtipynvmT1g/dOfEJ+0EQsHhkQ/zyRId8J2b8zQ== + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.22.5.tgz#e9341f4b5a167952576e23db8d435849b1dd7920" + integrity sha512-fTLj4D79M+mepcw3dgFBTIDYpbcB9Sm0bpm4ppXPaO+U+PKFFyV9MGRvS0gvGw62sd10kT5lRMKXAADb9pWy8g== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-transform-member-expression-literals@^7.0.0": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.16.7.tgz#6e5dcf906ef8a098e630149d14c867dd28f92384" - integrity sha512-mBruRMbktKQwbxaJof32LT9KLy2f3gH+27a5XSuXo6h7R3vqltl0PgZ80C8ZMKw98Bf8bqt6BEVi3svOh2PzMw== + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.22.5.tgz#4fcc9050eded981a468347dd374539ed3e058def" + integrity sha512-RZEdkNtzzYCFl9SE9ATaUMTj2hqMb4StarOJLrZRbqqU4HSBE7UlBw9WBWQiDzrJZJdUWiMTVDI6Gv/8DPvfew== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-modules-commonjs@^7.0.0", "@babel/plugin-transform-modules-commonjs@^7.1.0": - version "7.17.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.17.9.tgz#274be1a2087beec0254d4abd4d86e52442e1e5b6" - integrity sha512-2TBFd/r2I6VlYn0YRTz2JdazS+FoUuQ2rIFHoAxtyP/0G3D82SBLaRq9rnUkpqlLg03Byfl/+M32mpxjO6KaPw== +"@babel/plugin-transform-modules-commonjs@^7.0.0", "@babel/plugin-transform-modules-commonjs@^7.1.0", "@babel/plugin-transform-modules-commonjs@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.22.5.tgz#7d9875908d19b8c0536085af7b053fd5bd651bfa" + integrity sha512-B4pzOXj+ONRmuaQTg05b3y/4DuFz3WcCNAXPLb2Q0GT0TrGKGxNKV4jwsXts+StaM0LQczZbOpj8o1DLPDJIiA== dependencies: - "@babel/helper-module-transforms" "^7.17.7" - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/helper-simple-access" "^7.17.7" - babel-plugin-dynamic-import-node "^2.3.3" + "@babel/helper-module-transforms" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-simple-access" "^7.22.5" "@babel/plugin-transform-object-assign@^7.0.0": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.16.7.tgz#5fe08d63dccfeb6a33aa2638faf98e5c584100f8" - integrity sha512-R8mawvm3x0COTJtveuoqZIjNypn2FjfvXZr4pSQ8VhEFBuQGBz4XhHasZtHXjgXU4XptZ4HtGof3NoYc93ZH9Q== + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.22.5.tgz#290c1b9555dcea48bb2c29ad94237777600d04f9" + integrity sha512-iDhx9ARkXq4vhZ2CYOSnQXkmxkDgosLi3J8Z17mKz7LyzthtkdVchLD7WZ3aXeCuvJDOW3+1I5TpJmwIbF9MKQ== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-transform-object-super@^7.0.0": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.16.7.tgz#ac359cf8d32cf4354d27a46867999490b6c32a94" - integrity sha512-14J1feiQVWaGvRxj2WjyMuXS2jsBkgB3MdSN5HuC2G5nRspa5RK9COcs82Pwy5BuGcjb+fYaUj94mYcOj7rCvw== + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.22.5.tgz#794a8d2fcb5d0835af722173c1a9d704f44e218c" + integrity sha512-klXqyaT9trSjIUrcsYIfETAzmOEZL3cBYqOYLJxBHfMFFggmXOv+NYSX/Jbs9mzMVESw/WycLFPRx8ba/b2Ipw== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/helper-replace-supers" "^7.16.7" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.5" -"@babel/plugin-transform-parameters@^7.0.0", "@babel/plugin-transform-parameters@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.16.7.tgz#a1721f55b99b736511cb7e0152f61f17688f331f" - integrity sha512-AT3MufQ7zZEhU2hwOA11axBnExW0Lszu4RL/tAlUJBuNoRak+wehQW8h6KcXOcgjY42fHtDxswuMhMjFEuv/aw== +"@babel/plugin-transform-parameters@^7.0.0", "@babel/plugin-transform-parameters@^7.20.7": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.22.5.tgz#c3542dd3c39b42c8069936e48717a8d179d63a18" + integrity sha512-AVkFUBurORBREOmHRKo06FjHYgjrabpdqRSwq6+C7R5iTCZOsM4QbcB27St0a4U6fffyAOqh3s/qEfybAhfivg== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-transform-property-literals@^7.0.0": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.16.7.tgz#2dadac85155436f22c696c4827730e0fe1057a55" - integrity sha512-z4FGr9NMGdoIl1RqavCqGG+ZuYjfZ/hkCIeuH6Do7tXmSm0ls11nYVSJqFEUOSJbDab5wC6lRE/w6YjVcr6Hqw== + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.22.5.tgz#b5ddabd73a4f7f26cd0e20f5db48290b88732766" + integrity sha512-TiOArgddK3mK/x1Qwf5hay2pxI6wCZnvQqrFSqbtg1GLl2JcNMitVH/YnqjP+M31pLUeTfzY1HAXFDnUBV30rQ== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-transform-react-display-name@^7.0.0": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.16.7.tgz#7b6d40d232f4c0f550ea348593db3b21e2404340" - integrity sha512-qgIg8BcZgd0G/Cz916D5+9kqX0c7nPZyXaP8R2tLNN5tkyIZdG5fEwBrxwplzSnjC1jvQmyMNVwUCZPcbGY7Pg== + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.22.5.tgz#3c4326f9fce31c7968d6cb9debcaf32d9e279a2b" + integrity sha512-PVk3WPYudRF5z4GKMEYUrLjPl38fJSKNaEOkFuoprioowGuWN6w2RKznuFNSlJx7pzzXXStPUnNSOEO0jL5EVw== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-transform-react-jsx-self@^7.0.0": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.16.7.tgz#f432ad0cba14c4a1faf44f0076c69e42a4d4479e" - integrity sha512-oe5VuWs7J9ilH3BCCApGoYjHoSO48vkjX2CbA5bFVhIuO2HKxA3vyF7rleA4o6/4rTDbk6r8hBW7Ul8E+UZrpA== + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.22.5.tgz#ca2fdc11bc20d4d46de01137318b13d04e481d8e" + integrity sha512-nTh2ogNUtxbiSbxaT4Ds6aXnXEipHweN9YRgOX/oNXdf0cCrGn/+2LozFa3lnPV5D90MkjhgckCPBrsoSc1a7g== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-transform-react-jsx-source@^7.0.0": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.16.7.tgz#1879c3f23629d287cc6186a6c683154509ec70c0" - integrity sha512-rONFiQz9vgbsnaMtQlZCjIRwhJvlrPET8TabIUK2hzlXw9B9s2Ieaxte1SCOOXMbWRHodbKixNf3BLcWVOQ8Bw== + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.22.5.tgz#49af1615bfdf6ed9d3e9e43e425e0b2b65d15b6c" + integrity sha512-yIiRO6yobeEIaI0RTbIr8iAK9FcBHLtZq0S89ZPjDLQXBA4xvghaKqI0etp/tF3htTM0sazJKKLz9oEiGRtu7w== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-transform-react-jsx@^7.0.0": - version "7.17.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.17.3.tgz#eac1565da176ccb1a715dae0b4609858808008c1" - integrity sha512-9tjBm4O07f7mzKSIlEmPdiE6ub7kfIe6Cd+w+oQebpATfTQMAgW+YOuWxogbKVTulA+MEO7byMeIUtQ1z+z+ZQ== + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.22.5.tgz#932c291eb6dd1153359e2a90cb5e557dcf068416" + integrity sha512-rog5gZaVbUip5iWDMTYbVM15XQq+RkUKhET/IHR6oizR+JEoN6CAfTTuHcK4vwUyzca30qqHqEpzBOnaRMWYMA== dependencies: - "@babel/helper-annotate-as-pure" "^7.16.7" - "@babel/helper-module-imports" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/plugin-syntax-jsx" "^7.16.7" - "@babel/types" "^7.17.0" + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-module-imports" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-jsx" "^7.22.5" + "@babel/types" "^7.22.5" "@babel/plugin-transform-regenerator@^7.0.0": - version "7.17.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.17.9.tgz#0a33c3a61cf47f45ed3232903683a0afd2d3460c" - integrity sha512-Lc2TfbxR1HOyn/c6b4Y/b6NHoTb67n/IoWLxTu4kC7h4KQnWlhCq2S8Tx0t2SVvv5Uu87Hs+6JEJ5kt2tYGylQ== + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.22.10.tgz#8ceef3bd7375c4db7652878b0241b2be5d0c3cca" + integrity sha512-F28b1mDt8KcT5bUyJc/U9nwzw6cV+UmTeRlXYIl2TNqMMJif0Jeey9/RQ3C4NOd2zp0/TRsDns9ttj2L523rsw== dependencies: - regenerator-transform "^0.15.0" + "@babel/helper-plugin-utils" "^7.22.5" + regenerator-transform "^0.15.2" "@babel/plugin-transform-runtime@^7.0.0": - version "7.17.10" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.17.10.tgz#b89d821c55d61b5e3d3c3d1d636d8d5a81040ae1" - integrity sha512-6jrMilUAJhktTr56kACL8LnWC5hx3Lf27BS0R0DSyW/OoJfb/iTHeE96V3b1dgKG3FSFdd/0culnYWMkjcKCig== - dependencies: - "@babel/helper-module-imports" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" - babel-plugin-polyfill-corejs2 "^0.3.0" - babel-plugin-polyfill-corejs3 "^0.5.0" - babel-plugin-polyfill-regenerator "^0.3.0" - semver "^6.3.0" + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.22.10.tgz#89eda6daf1d3af6f36fb368766553054c8d7cd46" + integrity sha512-RchI7HePu1eu0CYNKHHHQdfenZcM4nz8rew5B1VWqeRKdcwW5aQ5HeG9eTUbWiAS1UrmHVLmoxTWHt3iLD/NhA== + dependencies: + "@babel/helper-module-imports" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + babel-plugin-polyfill-corejs2 "^0.4.5" + babel-plugin-polyfill-corejs3 "^0.8.3" + babel-plugin-polyfill-regenerator "^0.5.2" + semver "^6.3.1" "@babel/plugin-transform-shorthand-properties@^7.0.0": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.16.7.tgz#e8549ae4afcf8382f711794c0c7b6b934c5fbd2a" - integrity sha512-hah2+FEnoRoATdIb05IOXf+4GzXYTq75TVhIn1PewihbpyrNWUt2JbudKQOETWw6QpLe+AIUpJ5MVLYTQbeeUg== + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.22.5.tgz#6e277654be82b5559fc4b9f58088507c24f0c624" + integrity sha512-vM4fq9IXHscXVKzDv5itkO1X52SmdFBFcMIBZ2FRn2nqVYqw6dBexUgMvAjHW+KXpPPViD/Yo3GrDEBaRC0QYA== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-transform-spread@^7.0.0": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.16.7.tgz#a303e2122f9f12e0105daeedd0f30fb197d8ff44" - integrity sha512-+pjJpgAngb53L0iaA5gU/1MLXJIfXcYepLgXB3esVRf4fqmj8f2cxM3/FKaHsZms08hFQJkFccEWuIpm429TXg== + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.22.5.tgz#6487fd29f229c95e284ba6c98d65eafb893fea6b" + integrity sha512-5ZzDQIGyvN4w8+dMmpohL6MBo+l2G7tfC/O2Dg7/hjpgeWvUx8FzfeOKxGog9IimPa4YekaQ9PlDqTLOljkcxg== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" "@babel/plugin-transform-sticky-regex@^7.0.0": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.16.7.tgz#c84741d4f4a38072b9a1e2e3fd56d359552e8660" - integrity sha512-NJa0Bd/87QV5NZZzTuZG5BPJjLYadeSZ9fO6oOUoL4iQx+9EEuw/eEM92SrsT19Yc2jgB1u1hsjqDtH02c3Drw== + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.22.5.tgz#295aba1595bfc8197abd02eae5fc288c0deb26aa" + integrity sha512-zf7LuNpHG0iEeiyCNwX4j3gDg1jgt1k3ZdXBKbZSoA3BbGQGvMiSvfbZRR3Dr3aeJe3ooWFZxOOG3IRStYp2Bw== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-transform-template-literals@^7.0.0": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.16.7.tgz#f3d1c45d28967c8e80f53666fc9c3e50618217ab" - integrity sha512-VwbkDDUeenlIjmfNeDX/V0aWrQH2QiVyJtwymVQSzItFDTpxfyJh3EVaQiS0rIN/CqbLGr0VcGmuwyTdZtdIsA== + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.22.5.tgz#8f38cf291e5f7a8e60e9f733193f0bcc10909bff" + integrity sha512-5ciOehRNf+EyUeewo8NkbQiUs4d6ZxiHo6BcBcnFlgiJfu16q0bQUw9Jvo0b0gBKFG1SMhDSjeKXSYuJLeFSMA== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-typescript@^7.16.7", "@babel/plugin-transform-typescript@^7.5.0": - version "7.16.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.16.8.tgz#591ce9b6b83504903fa9dd3652c357c2ba7a1ee0" - integrity sha512-bHdQ9k7YpBDO2d0NVfkj51DpQcvwIzIusJ7mEUaMlbZq3Kt/U47j24inXZHQ5MDiYpCs+oZiwnXyKedE8+q7AQ== +"@babel/plugin-transform-typescript@^7.22.5", "@babel/plugin-transform-typescript@^7.5.0": + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.22.10.tgz#aadd98fab871f0bb5717bcc24c31aaaa455af923" + integrity sha512-7++c8I/ymsDo4QQBAgbraXLzIM6jmfao11KgIBEYZRReWzNWH9NtNgJcyrZiXsOPh523FQm6LfpLyy/U5fn46A== dependencies: - "@babel/helper-create-class-features-plugin" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/plugin-syntax-typescript" "^7.16.7" + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-create-class-features-plugin" "^7.22.10" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-typescript" "^7.22.5" "@babel/plugin-transform-unicode-regex@^7.0.0": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.16.7.tgz#0f7aa4a501198976e25e82702574c34cfebe9ef2" - integrity sha512-oC5tYYKw56HO75KZVLQ+R/Nl3Hro9kf8iG0hXoaHP7tjAyCpvqBiSNe6vGrZni1Z6MggmUOC6A7VP7AVmw225Q== + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.22.5.tgz#ce7e7bb3ef208c4ff67e02a22816656256d7a183" + integrity sha512-028laaOKptN5vHJf9/Arr/HiJekMd41hOEZYvNsrsXqJ7YPYuX2bQxh31fkZzGmq3YqHRJzYFFAVYvKfMPKqyg== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-create-regexp-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" "@babel/preset-flow@^7.0.0": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/preset-flow/-/preset-flow-7.16.7.tgz#7fd831323ab25eeba6e4b77a589f680e30581cbd" - integrity sha512-6ceP7IyZdUYQ3wUVqyRSQXztd1YmFHWI4Xv11MIqAlE4WqxBSd/FZ61V9k+TS5Gd4mkHOtQtPp9ymRpxH4y1Ug== + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/preset-flow/-/preset-flow-7.22.5.tgz#876f24ab6b38bd79703a93f32020ca2162312784" + integrity sha512-ta2qZ+LSiGCrP5pgcGt8xMnnkXQrq8Sa4Ulhy06BOlF5QbLw9q5hIx7bn5MrsvyTGAfh6kTOo07Q+Pfld/8Y5Q== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/helper-validator-option" "^7.16.7" - "@babel/plugin-transform-flow-strip-types" "^7.16.7" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-validator-option" "^7.22.5" + "@babel/plugin-transform-flow-strip-types" "^7.22.5" "@babel/preset-typescript@^7.1.0": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.16.7.tgz#ab114d68bb2020afc069cd51b37ff98a046a70b9" - integrity sha512-WbVEmgXdIyvzB77AQjGBEyYPZx+8tTsO50XtfozQrkW8QB2rLJpH2lgx0TRw5EJrBxOZQ+wCcyPVQvS8tjEHpQ== + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.22.5.tgz#16367d8b01d640e9a507577ed4ee54e0101e51c8" + integrity sha512-YbPaal9LxztSGhmndR46FmAbkJ/1fAsw293tSU+I5E5h+cnJ3d4GTwyUgGYmOXJYdGA+uNePle4qbaRzj2NISQ== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/helper-validator-option" "^7.16.7" - "@babel/plugin-transform-typescript" "^7.16.7" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-validator-option" "^7.22.5" + "@babel/plugin-syntax-jsx" "^7.22.5" + "@babel/plugin-transform-modules-commonjs" "^7.22.5" + "@babel/plugin-transform-typescript" "^7.22.5" "@babel/register@^7.0.0": - version "7.17.7" - resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.17.7.tgz#5eef3e0f4afc07e25e847720e7b987ae33f08d0b" - integrity sha512-fg56SwvXRifootQEDQAu1mKdjh5uthPzdO0N6t358FktfL4XjAVXuH58ULoiW8mesxiOgNIrxiImqEwv0+hRRA== + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.22.5.tgz#e4d8d0f615ea3233a27b5c6ada6750ee59559939" + integrity sha512-vV6pm/4CijSQ8Y47RH5SopXzursN35RQINfGJkmOlcpAtGuf94miFvIPhCKGQN7WGIcsgG1BHEX2KVdTYwTwUQ== dependencies: clone-deep "^4.0.1" find-cache-dir "^2.0.0" @@ -705,44 +707,50 @@ pirates "^4.0.5" source-map-support "^0.5.16" +"@babel/regjsgen@^0.8.0": + version "0.8.0" + resolved "https://registry.yarnpkg.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310" + integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== + "@babel/runtime@^7.12.5", "@babel/runtime@^7.17.9", "@babel/runtime@^7.8.4": - version "7.17.9" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.9.tgz#d19fbf802d01a8cb6cf053a64e472d42c434ba72" - integrity sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg== - dependencies: - regenerator-runtime "^0.13.4" - -"@babel/template@^7.0.0", "@babel/template@^7.16.7", "@babel/template@^7.3.3": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.7.tgz#8d126c8701fde4d66b264b3eba3d96f07666d155" - integrity sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w== - dependencies: - "@babel/code-frame" "^7.16.7" - "@babel/parser" "^7.16.7" - "@babel/types" "^7.16.7" - -"@babel/traverse@^7.13.0", "@babel/traverse@^7.14.0", "@babel/traverse@^7.16.7", "@babel/traverse@^7.16.8", "@babel/traverse@^7.17.10", "@babel/traverse@^7.17.3", "@babel/traverse@^7.17.9", "@babel/traverse@^7.7.2": - version "7.17.10" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.17.10.tgz#1ee1a5ac39f4eac844e6cf855b35520e5eb6f8b5" - integrity sha512-VmbrTHQteIdUUQNTb+zE12SHS/xQVIShmBPhlNP12hD5poF2pbITW1Z4172d03HegaQWhLffdkRJYtAzp0AGcw== - dependencies: - "@babel/code-frame" "^7.16.7" - "@babel/generator" "^7.17.10" - "@babel/helper-environment-visitor" "^7.16.7" - "@babel/helper-function-name" "^7.17.9" - "@babel/helper-hoist-variables" "^7.16.7" - "@babel/helper-split-export-declaration" "^7.16.7" - "@babel/parser" "^7.17.10" - "@babel/types" "^7.17.10" + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.10.tgz#ae3e9631fd947cb7e3610d3e9d8fef5f76696682" + integrity sha512-21t/fkKLMZI4pqP2wlmsQAWnYW1PDyKyyUV4vCi+B25ydmdaYTKXPwCj0BzSUnZf4seIiYvSA3jcZ3gdsMFkLQ== + dependencies: + regenerator-runtime "^0.14.0" + +"@babel/template@^7.0.0", "@babel/template@^7.22.5", "@babel/template@^7.3.3": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.5.tgz#0c8c4d944509875849bd0344ff0050756eefc6ec" + integrity sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw== + dependencies: + "@babel/code-frame" "^7.22.5" + "@babel/parser" "^7.22.5" + "@babel/types" "^7.22.5" + +"@babel/traverse@^7.14.0", "@babel/traverse@^7.22.10", "@babel/traverse@^7.7.2": + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.22.10.tgz#20252acb240e746d27c2e82b4484f199cf8141aa" + integrity sha512-Q/urqV4pRByiNNpb/f5OSv28ZlGJiFiiTh+GAHktbIrkPhPbl90+uW6SmpoLyZqutrg9AEaEf3Q/ZBRHBXgxig== + dependencies: + "@babel/code-frame" "^7.22.10" + "@babel/generator" "^7.22.10" + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-function-name" "^7.22.5" + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/parser" "^7.22.10" + "@babel/types" "^7.22.10" debug "^4.1.0" globals "^11.1.0" -"@babel/types@^7.0.0", "@babel/types@^7.16.0", "@babel/types@^7.16.7", "@babel/types@^7.16.8", "@babel/types@^7.17.0", "@babel/types@^7.17.10", "@babel/types@^7.3.0", "@babel/types@^7.3.3": - version "7.17.10" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.17.10.tgz#d35d7b4467e439fcf06d195f8100e0fea7fc82c4" - integrity sha512-9O26jG0mBYfGkUYCYZRnBwbVLd1UZOICEr2Em6InB6jVfsAv1GKgwXHmrSg+WFWDmeKTA6vyTZiN8tCSM5Oo3A== +"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.22.10", "@babel/types@^7.22.5", "@babel/types@^7.3.3": + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.22.10.tgz#4a9e76446048f2c66982d1a989dd12b8a2d2dc03" + integrity sha512-obaoigiLrlDZ7TUQln/8m4mSqIW2QFeOrCQc9r+xsaHGNoplVNYlRVpsfE8Vj35GEm2ZH4ZhrNYogs/3fj85kg== dependencies: - "@babel/helper-validator-identifier" "^7.16.7" + "@babel/helper-string-parser" "^7.22.5" + "@babel/helper-validator-identifier" "^7.22.5" to-fast-properties "^2.0.0" "@bcoe/v8-coverage@^0.2.3": @@ -758,33 +766,45 @@ exec-sh "^0.3.2" minimist "^1.2.0" -"@cspotcode/source-map-consumer@0.8.0": - version "0.8.0" - resolved "https://registry.yarnpkg.com/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz#33bf4b7b39c178821606f669bbc447a6a629786b" - integrity sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg== +"@cspotcode/source-map-support@^0.8.0": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" + integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== + dependencies: + "@jridgewell/trace-mapping" "0.3.9" -"@cspotcode/source-map-support@0.7.0": - version "0.7.0" - resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz#4789840aa859e46d2f3173727ab707c66bf344f5" - integrity sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA== +"@eslint-community/eslint-utils@^4.2.0": + version "4.4.0" + resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" + integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== dependencies: - "@cspotcode/source-map-consumer" "0.8.0" + eslint-visitor-keys "^3.3.0" -"@eslint/eslintrc@^1.2.2": - version "1.2.2" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.2.2.tgz#4989b9e8c0216747ee7cca314ae73791bb281aae" - integrity sha512-lTVWHs7O2hjBFZunXTZYnYqtB9GakA1lnxIf+gKq2nY5gxkkNi/lQvveW6t8gFdOHTg6nG50Xs95PrLqVpcaLg== +"@eslint-community/regexpp@^4.4.0", "@eslint-community/regexpp@^4.6.1": + version "4.6.2" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.6.2.tgz#1816b5f6948029c5eaacb0703b850ee0cb37d8f8" + integrity sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw== + +"@eslint/eslintrc@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.1.tgz#18d635e24ad35f7276e8a49d135c7d3ca6a46f93" + integrity sha512-9t7ZA7NGGK8ckelF0PQCfcxIUzs1Md5rrO6U/c+FIQNanea5UZC0wqKXH4vHBccmu4ZJgZ2idtPeW7+Q2npOEA== dependencies: ajv "^6.12.4" debug "^4.3.2" - espree "^9.3.1" - globals "^13.9.0" + espree "^9.6.0" + globals "^13.19.0" ignore "^5.2.0" import-fresh "^3.2.1" js-yaml "^4.1.0" - minimatch "^3.0.4" + minimatch "^3.1.2" strip-json-comments "^3.1.1" +"@eslint/js@^8.46.0": + version "8.46.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.46.0.tgz#3f7802972e8b6fe3f88ed1aabc74ec596c456db6" + integrity sha512-a8TLtmPi8xzPkCbp/OGFUo5yhRkHM2Ko9kOWP4znJr0WAhWyThaw3PnwX4vOTWOAMsV2uRt32PPDcEz63esSaA== + "@hapi/hoek@^9.0.0": version "9.3.0" resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.3.0.tgz#8368869dcb735be2e7f5cb7647de78e167a251fb" @@ -797,14 +817,19 @@ dependencies: "@hapi/hoek" "^9.0.0" -"@humanwhocodes/config-array@^0.9.2": - version "0.9.5" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.9.5.tgz#2cbaf9a89460da24b5ca6531b8bbfc23e1df50c7" - integrity sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw== +"@humanwhocodes/config-array@^0.11.10": + version "0.11.10" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.10.tgz#5a3ffe32cc9306365fb3fd572596cd602d5e12d2" + integrity sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ== dependencies: "@humanwhocodes/object-schema" "^1.2.1" debug "^4.1.1" - minimatch "^3.0.4" + minimatch "^3.0.5" + +"@humanwhocodes/module-importer@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" + integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== "@humanwhocodes/object-schema@^1.2.1": version "1.2.1" @@ -827,49 +852,49 @@ resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== -"@jest/console@^28.0.2": - version "28.0.2" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-28.0.2.tgz#d11e8b43ae431ae9b3112656848417ae4008fcad" - integrity sha512-tiRpnMeeyQuuzgL5UNSeiqMwF8UOWPbAE5rzcu/1zyq4oPG2Ox6xm4YCOruwbp10F8odWc+XwVxTyGzMSLMqxA== +"@jest/console@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-28.1.3.tgz#2030606ec03a18c31803b8a36382762e447655df" + integrity sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw== dependencies: - "@jest/types" "^28.0.2" + "@jest/types" "^28.1.3" "@types/node" "*" chalk "^4.0.0" - jest-message-util "^28.0.2" - jest-util "^28.0.2" + jest-message-util "^28.1.3" + jest-util "^28.1.3" slash "^3.0.0" -"@jest/core@^28.0.3": - version "28.0.3" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-28.0.3.tgz#2b8223914ef6ae16ff740e65235ef8ef49c46d52" - integrity sha512-cCQW06vEZ+5r50SB06pOnSWsOBs7F+lswPYnKKfBz1ncLlj1sMqmvjgam8q40KhlZ8Ut4eNAL2Hvfx4BKIO2FA== +"@jest/core@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-28.1.3.tgz#0ebf2bd39840f1233cd5f2d1e6fc8b71bd5a1ac7" + integrity sha512-CIKBrlaKOzA7YG19BEqCw3SLIsEwjZkeJzf5bdooVnW4bH5cktqe3JX+G2YV1aK5vP8N9na1IGWFzYaTp6k6NA== dependencies: - "@jest/console" "^28.0.2" - "@jest/reporters" "^28.0.3" - "@jest/test-result" "^28.0.2" - "@jest/transform" "^28.0.3" - "@jest/types" "^28.0.2" + "@jest/console" "^28.1.3" + "@jest/reporters" "^28.1.3" + "@jest/test-result" "^28.1.3" + "@jest/transform" "^28.1.3" + "@jest/types" "^28.1.3" "@types/node" "*" ansi-escapes "^4.2.1" chalk "^4.0.0" ci-info "^3.2.0" exit "^0.1.2" graceful-fs "^4.2.9" - jest-changed-files "^28.0.2" - jest-config "^28.0.3" - jest-haste-map "^28.0.2" - jest-message-util "^28.0.2" + jest-changed-files "^28.1.3" + jest-config "^28.1.3" + jest-haste-map "^28.1.3" + jest-message-util "^28.1.3" jest-regex-util "^28.0.2" - jest-resolve "^28.0.3" - jest-resolve-dependencies "^28.0.3" - jest-runner "^28.0.3" - jest-runtime "^28.0.3" - jest-snapshot "^28.0.3" - jest-util "^28.0.2" - jest-validate "^28.0.2" - jest-watcher "^28.0.2" + jest-resolve "^28.1.3" + jest-resolve-dependencies "^28.1.3" + jest-runner "^28.1.3" + jest-runtime "^28.1.3" + jest-snapshot "^28.1.3" + jest-util "^28.1.3" + jest-validate "^28.1.3" + jest-watcher "^28.1.3" micromatch "^4.0.4" - pretty-format "^28.0.2" + pretty-format "^28.1.3" rimraf "^3.0.0" slash "^3.0.0" strip-ansi "^6.0.0" @@ -881,63 +906,63 @@ dependencies: "@jest/types" "^27.5.1" -"@jest/environment@^28.0.2": - version "28.0.2" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-28.0.2.tgz#a865949d876b2d364b979bbc0a46338ffd23de26" - integrity sha512-IvI7dEfqVEffDYlw9FQfVBt6kXt/OI38V7QUIur0ulOQgzpKYJDVvLzj4B1TVmHWTGW5tcnJdlZ3hqzV6/I9Qg== +"@jest/environment@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-28.1.3.tgz#abed43a6b040a4c24fdcb69eab1f97589b2d663e" + integrity sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA== dependencies: - "@jest/fake-timers" "^28.0.2" - "@jest/types" "^28.0.2" + "@jest/fake-timers" "^28.1.3" + "@jest/types" "^28.1.3" "@types/node" "*" - jest-mock "^28.0.2" + jest-mock "^28.1.3" -"@jest/expect-utils@^28.0.2": - version "28.0.2" - resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-28.0.2.tgz#0a055868d225261eac82a12013e2e0735238774d" - integrity sha512-YryfH2zN5c7M8eLtn9oTBRj1sfD+X4cHNXJnTejqCveOS33wADEZUxJ7de5++lRvByNpRpfAnc8zTK7yrUJqgA== +"@jest/expect-utils@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-28.1.3.tgz#58561ce5db7cd253a7edddbc051fb39dda50f525" + integrity sha512-wvbi9LUrHJLn3NlDW6wF2hvIMtd4JUl2QNVrjq+IBSHirgfrR3o9RnVtxzdEGO2n9JyIWwHnLfby5KzqBGg2YA== dependencies: jest-get-type "^28.0.2" -"@jest/expect@^28.0.3": - version "28.0.3" - resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-28.0.3.tgz#80e0233bee62586e1112f904d28b904dd1143ef2" - integrity sha512-VEzZr85bqNomgayQkR7hWG5HnbZYWYWagQriZsixhLmOzU6PCpMP61aeVhkCoRrg7ri5f7JDpeTPzDAajIwFHw== +"@jest/expect@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-28.1.3.tgz#9ac57e1d4491baca550f6bdbd232487177ad6a72" + integrity sha512-lzc8CpUbSoE4dqT0U+g1qODQjBRHPpCPXissXD4mS9+sWQdmmpeJ9zSH1rS1HEkrsMN0fb7nKrJ9giAR1d3wBw== dependencies: - expect "^28.0.2" - jest-snapshot "^28.0.3" + expect "^28.1.3" + jest-snapshot "^28.1.3" -"@jest/fake-timers@^28.0.2": - version "28.0.2" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-28.0.2.tgz#d36e62bc58f39d65ea6adac1ff7749e63aff05f3" - integrity sha512-R75yUv+WeybPa4ZVhX9C+8XN0TKjUoceUX+/QEaDVQGxZZOK50eD74cs7iMDTtpodh00d8iLlc9197vgF6oZjA== +"@jest/fake-timers@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-28.1.3.tgz#230255b3ad0a3d4978f1d06f70685baea91c640e" + integrity sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw== dependencies: - "@jest/types" "^28.0.2" - "@sinonjs/fake-timers" "^9.1.1" + "@jest/types" "^28.1.3" + "@sinonjs/fake-timers" "^9.1.2" "@types/node" "*" - jest-message-util "^28.0.2" - jest-mock "^28.0.2" - jest-util "^28.0.2" + jest-message-util "^28.1.3" + jest-mock "^28.1.3" + jest-util "^28.1.3" -"@jest/globals@^28.0.3": - version "28.0.3" - resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-28.0.3.tgz#70f68a06c863d1c9d14aea151c69b9690e3efeb4" - integrity sha512-q/zXYI6CKtTSIt1WuTHBYizJhH7K8h+xG5PE3C0oawLlPIvUMDYmpj0JX0XsJwPRLCsz/fYXHZVG46AaEhSPmw== +"@jest/globals@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-28.1.3.tgz#a601d78ddc5fdef542728309894895b4a42dc333" + integrity sha512-XFU4P4phyryCXu1pbcqMO0GSQcYe1IsalYCDzRNyhetyeyxMcIxa11qPNDpVNLeretItNqEmYYQn1UYz/5x1NA== dependencies: - "@jest/environment" "^28.0.2" - "@jest/expect" "^28.0.3" - "@jest/types" "^28.0.2" + "@jest/environment" "^28.1.3" + "@jest/expect" "^28.1.3" + "@jest/types" "^28.1.3" -"@jest/reporters@^28.0.3": - version "28.0.3" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-28.0.3.tgz#9996189e5552e37fcdffe0f41c07754f5d2ea854" - integrity sha512-xrbIc7J/xwo+D7AY3enAR9ZWYCmJ8XIkstTukTGpKDph0gLl/TJje9jl3dssvE4KJzYqMKiSrnE5Nt68I4fTEg== +"@jest/reporters@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-28.1.3.tgz#9adf6d265edafc5fc4a434cfb31e2df5a67a369a" + integrity sha512-JuAy7wkxQZVNU/V6g9xKzCGC5LVXx9FDcABKsSXp5MiKPEE2144a/vXTEDoyzjUpZKfVwp08Wqg5A4WfTMAzjg== dependencies: "@bcoe/v8-coverage" "^0.2.3" - "@jest/console" "^28.0.2" - "@jest/test-result" "^28.0.2" - "@jest/transform" "^28.0.3" - "@jest/types" "^28.0.2" - "@jridgewell/trace-mapping" "^0.3.7" + "@jest/console" "^28.1.3" + "@jest/test-result" "^28.1.3" + "@jest/transform" "^28.1.3" + "@jest/types" "^28.1.3" + "@jridgewell/trace-mapping" "^0.3.13" "@types/node" "*" chalk "^4.0.0" collect-v8-coverage "^1.0.0" @@ -949,65 +974,67 @@ istanbul-lib-report "^3.0.0" istanbul-lib-source-maps "^4.0.0" istanbul-reports "^3.1.3" - jest-util "^28.0.2" - jest-worker "^28.0.2" + jest-message-util "^28.1.3" + jest-util "^28.1.3" + jest-worker "^28.1.3" slash "^3.0.0" string-length "^4.0.1" + strip-ansi "^6.0.0" terminal-link "^2.0.0" - v8-to-istanbul "^9.0.0" + v8-to-istanbul "^9.0.1" -"@jest/schemas@^28.0.2": - version "28.0.2" - resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-28.0.2.tgz#08c30df6a8d07eafea0aef9fb222c5e26d72e613" - integrity sha512-YVDJZjd4izeTDkij00vHHAymNXQ6WWsdChFRK86qck6Jpr3DCL5W3Is3vslviRlP+bLuMYRLbdp98amMvqudhA== +"@jest/schemas@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-28.1.3.tgz#ad8b86a66f11f33619e3d7e1dcddd7f2d40ff905" + integrity sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg== dependencies: - "@sinclair/typebox" "^0.23.3" + "@sinclair/typebox" "^0.24.1" -"@jest/source-map@^28.0.2": - version "28.0.2" - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-28.0.2.tgz#914546f4410b67b1d42c262a1da7e0406b52dc90" - integrity sha512-Y9dxC8ZpN3kImkk0LkK5XCEneYMAXlZ8m5bflmSL5vrwyeUpJfentacCUg6fOb8NOpOO7hz2+l37MV77T6BFPw== +"@jest/source-map@^28.1.2": + version "28.1.2" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-28.1.2.tgz#7fe832b172b497d6663cdff6c13b0a920e139e24" + integrity sha512-cV8Lx3BeStJb8ipPHnqVw/IM2VCMWO3crWZzYodSIkxXnRcXJipCdx1JCK0K5MsJJouZQTH73mzf4vgxRaH9ww== dependencies: - "@jridgewell/trace-mapping" "^0.3.7" + "@jridgewell/trace-mapping" "^0.3.13" callsites "^3.0.0" graceful-fs "^4.2.9" -"@jest/test-result@^28.0.2": - version "28.0.2" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-28.0.2.tgz#bc8e15a95347e3c2149572ae06a5a6fed939c522" - integrity sha512-4EUqgjq9VzyUiVTvZfI9IRJD6t3NYBNP4f+Eq8Zr93+hkJ0RrGU4OBTw8tfNzidKX+bmuYzn8FxqpxOPIGGCMA== +"@jest/test-result@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-28.1.3.tgz#5eae945fd9f4b8fcfce74d239e6f725b6bf076c5" + integrity sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg== dependencies: - "@jest/console" "^28.0.2" - "@jest/types" "^28.0.2" + "@jest/console" "^28.1.3" + "@jest/types" "^28.1.3" "@types/istanbul-lib-coverage" "^2.0.0" collect-v8-coverage "^1.0.0" -"@jest/test-sequencer@^28.0.2": - version "28.0.2" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-28.0.2.tgz#7669b7d8ff2aa7a8221b11bb37cce552de81b1bb" - integrity sha512-zhnZ8ydkZQTPL7YucB86eOlD79zPy5EGSUKiR2Iv93RVEDU6OEP33kwDBg70ywOcxeJGDRhyo09q7TafNCBiIg== +"@jest/test-sequencer@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-28.1.3.tgz#9d0c283d906ac599c74bde464bc0d7e6a82886c3" + integrity sha512-NIMPEqqa59MWnDi1kvXXpYbqsfQmSJsIbnd85mdVGkiDfQ9WQQTXOLsvISUfonmnBT+w85WEgneCigEEdHDFxw== dependencies: - "@jest/test-result" "^28.0.2" + "@jest/test-result" "^28.1.3" graceful-fs "^4.2.9" - jest-haste-map "^28.0.2" + jest-haste-map "^28.1.3" slash "^3.0.0" -"@jest/transform@^28.0.3": - version "28.0.3" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-28.0.3.tgz#591fb5ebc1d84db5c5f21e1225c7406c35f5eb1e" - integrity sha512-+Y0ikI7SwoW/YbK8t9oKwC70h4X2Gd0OVuz5tctRvSV/EDQU00AAkoqevXgPSSFimUmp/sp7Yl8s/1bExDqOIg== +"@jest/transform@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-28.1.3.tgz#59d8098e50ab07950e0f2fc0fc7ec462371281b0" + integrity sha512-u5dT5di+oFI6hfcLOHGTAfmUxFRrjK+vnaP0kkVow9Md/M7V/MxqQMOz/VV25UZO8pzeA9PjfTpOu6BDuwSPQA== dependencies: "@babel/core" "^7.11.6" - "@jest/types" "^28.0.2" - "@jridgewell/trace-mapping" "^0.3.7" + "@jest/types" "^28.1.3" + "@jridgewell/trace-mapping" "^0.3.13" babel-plugin-istanbul "^6.1.1" chalk "^4.0.0" convert-source-map "^1.4.0" fast-json-stable-stringify "^2.0.0" graceful-fs "^4.2.9" - jest-haste-map "^28.0.2" + jest-haste-map "^28.1.3" jest-regex-util "^28.0.2" - jest-util "^28.0.2" + jest-util "^28.1.3" micromatch "^4.0.4" pirates "^4.0.4" slash "^3.0.0" @@ -1035,42 +1062,43 @@ "@types/yargs" "^16.0.0" chalk "^4.0.0" -"@jest/types@^28.0.2": - version "28.0.2" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-28.0.2.tgz#70b9538c1863fb060b2f438ca008b5563d00c5b4" - integrity sha512-hi3jUdm9iht7I2yrV5C4s3ucCJHUP8Eh3W6rQ1s4n/Qw9rQgsda4eqCt+r3BKRi7klVmZfQlMx1nGlzNMP2d8A== +"@jest/types@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-28.1.3.tgz#b05de80996ff12512bc5ceb1d208285a7d11748b" + integrity sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ== dependencies: - "@jest/schemas" "^28.0.2" + "@jest/schemas" "^28.1.3" "@types/istanbul-lib-coverage" "^2.0.0" "@types/istanbul-reports" "^3.0.0" "@types/node" "*" "@types/yargs" "^17.0.8" chalk "^4.0.0" -"@jridgewell/gen-mapping@^0.1.0": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz#e5d2e450306a9491e3bd77e323e38d7aff315996" - integrity sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w== +"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" + integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== dependencies: - "@jridgewell/set-array" "^1.0.0" + "@jridgewell/set-array" "^1.0.1" "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.9" -"@jridgewell/resolve-uri@^3.0.3": - version "3.0.6" - resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.0.6.tgz#4ac237f4dabc8dd93330386907b97591801f7352" - integrity sha512-R7xHtBSNm+9SyvpJkdQl+qrM3Hm2fea3Ef197M3mUug+v+yR+Rhfbs7PBtcBUVnIWJ4JcAdjvij+c8hXS9p5aw== +"@jridgewell/resolve-uri@^3.0.3", "@jridgewell/resolve-uri@^3.1.0": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" + integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== -"@jridgewell/set-array@^1.0.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.0.tgz#1179863356ac8fbea64a5a4bcde93a4871012c01" - integrity sha512-SfJxIxNVYLTsKwzB3MoOQ1yxf4w/E6MdkvTgrgAt1bfxjSrLUoHMKrDOykwN14q65waezZIdqDneUIPh4/sKxg== +"@jridgewell/set-array@^1.0.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" + integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== -"@jridgewell/sourcemap-codec@^1.4.10": - version "1.4.11" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz#771a1d8d744eeb71b6adb35808e1a6c7b9b8c8ec" - integrity sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg== +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14": + version "1.4.15" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" + integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== -"@jridgewell/trace-mapping@^0.3.7", "@jridgewell/trace-mapping@^0.3.9": +"@jridgewell/trace-mapping@0.3.9": version "0.3.9" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== @@ -1078,10 +1106,18 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" +"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.13", "@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9": + version "0.3.19" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz#f8a3249862f91be48d3127c3cfe992f79b4b8811" + integrity sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + "@mapbox/node-pre-gyp@^1.0.10": - version "1.0.10" - resolved "https://registry.yarnpkg.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.10.tgz#8e6735ccebbb1581e5a7e652244cadc8a844d03c" - integrity sha512-4ySo4CjzStuprMwk35H5pPbkymjv1SF3jGLj6rAHp/xT/RF7TL7bd9CTm1xDY49K2qF7jmR/g7k+SkLETP6opA== + version "1.0.11" + resolved "https://registry.yarnpkg.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz#417db42b7f5323d79e93b34a6d7a2a12c0df43fa" + integrity sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ== dependencies: detect-libc "^2.0.0" https-proxy-agent "^5.0.0" @@ -1106,7 +1142,7 @@ resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== -"@nodelib/fs.walk@^1.2.3": +"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": version "1.2.8" resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== @@ -1122,22 +1158,22 @@ serve-static "^1.13.1" "@react-native-community/cli-hermes@^6.3.0": - version "6.3.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-hermes/-/cli-hermes-6.3.0.tgz#92b2f07d08626a60f6893c3e3d57c1538c8fb5a7" - integrity sha512-Uhbm9bubyZLZ12vFCIfWbE/Qi3SBTbYIN/TC08EudTLhv/KbPomCQnmFsnJ7AXQFuOZJs73mBxoEAYSbRbwyVA== + version "6.3.1" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-hermes/-/cli-hermes-6.3.1.tgz#a4c3b4b07a1775f7012baf6d5a0b059da2ffac00" + integrity sha512-+tMJsEsVX0WyylnoFE7uPoMu1aTAChaA62Y32dwWgAa1Fx6YrpPkC9d6wvYSBe9md/4mTtRher+ooBcuov6JHw== dependencies: - "@react-native-community/cli-platform-android" "^6.3.0" - "@react-native-community/cli-tools" "^6.2.0" + "@react-native-community/cli-platform-android" "^6.3.1" + "@react-native-community/cli-tools" "^6.2.1" chalk "^4.1.2" hermes-profile-transformer "^0.0.6" ip "^1.1.5" -"@react-native-community/cli-platform-android@^6.0.0", "@react-native-community/cli-platform-android@^6.3.0": - version "6.3.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-6.3.0.tgz#ab7d156bd69a392493323eeaba839a874c0e201f" - integrity sha512-d5ufyYcvrZoHznYm5bjBXaiHIJv552t5gYtQpnUsxBhHSQ8QlaNmlLUyeSPRDfOw4ND9b0tPHqs4ufwx6vp/fQ== +"@react-native-community/cli-platform-android@^6.0.0", "@react-native-community/cli-platform-android@^6.3.1": + version "6.3.1" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-6.3.1.tgz#8d35c809ddaf3b6c5d4ef9ff9c814a25a55259aa" + integrity sha512-n5A64RI1ty4ScZCel/3JYY9Anl857dPsUZ86Dwc1GxrbflSB5/+hcCMg5DCNcnJRa4Hdv95SAR5pMmtAjOXApA== dependencies: - "@react-native-community/cli-tools" "^6.2.0" + "@react-native-community/cli-tools" "^6.2.1" chalk "^4.1.2" execa "^1.0.0" fs-extra "^8.1.0" @@ -1149,11 +1185,11 @@ xmldoc "^1.1.2" "@react-native-community/cli-platform-ios@^6.0.0": - version "6.2.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-6.2.0.tgz#ceaa23995511a8e400b506632ac7e6a66a17ec2a" - integrity sha512-k15MhExxLiLDDZOeuPgvTxbp0CsoLQQpk2Du0HjZDePqqWcKJylQqMZru1o8HuQHPcEr+b71HIs5V+lKyFYpfg== + version "6.2.1" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-6.2.1.tgz#852a7dc520071ac55fead3c78daa6a0060dde72f" + integrity sha512-5vwLRfTbIVUsO86AUPmR5vkp+7t4gTH2+SwRo0DKqBGBQ3hraA3dlWu0nzh99eQKQhCiFLB1WJPAi3zY03lK4w== dependencies: - "@react-native-community/cli-tools" "^6.2.0" + "@react-native-community/cli-tools" "^6.2.1" chalk "^4.1.2" glob "^7.1.3" js-yaml "^3.13.1" @@ -1193,10 +1229,10 @@ serve-static "^1.13.1" ws "^1.1.0" -"@react-native-community/cli-tools@^6.2.0": - version "6.2.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-6.2.0.tgz#8f4adc2d83ab96e5654348533c8fa602742c4fce" - integrity sha512-08ssz4GMEnRxC/1FgTTN/Ud7mExQi5xMphItPjfHiTxpZPhrFn+IMx6mya0ncFEhhxQ207wYlJMRLPRRdBZ8oA== +"@react-native-community/cli-tools@^6.2.0", "@react-native-community/cli-tools@^6.2.1": + version "6.2.1" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-6.2.1.tgz#6f7ada6559846b49fb9fcfed522399b232976ada" + integrity sha512-7RbOkZLT/3YG8CAYYM70ajRKIOgVxK/b4t9KNsPq+2uen99MGezfeglC8s1cs3vBNVVxCo0a2JbXg18bUd8eqA== dependencies: appdirsjs "^1.2.4" chalk "^4.1.2" @@ -1205,7 +1241,7 @@ node-fetch "^2.6.0" open "^6.2.0" semver "^6.3.0" - shell-quote "1.6.1" + shell-quote "^1.7.3" "@react-native-community/cli-types@^6.0.0": version "6.0.0" @@ -1273,7 +1309,7 @@ dependencies: "@hapi/hoek" "^9.0.0" -"@sideway/formula@^3.0.0": +"@sideway/formula@^3.0.1": version "3.0.1" resolved "https://registry.yarnpkg.com/@sideway/formula/-/formula-3.0.1.tgz#80fcbcbaf7ce031e0ef2dd29b1bfc7c3f583611f" integrity sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg== @@ -1283,19 +1319,19 @@ resolved "https://registry.yarnpkg.com/@sideway/pinpoint/-/pinpoint-2.0.0.tgz#cff8ffadc372ad29fd3f78277aeb29e632cc70df" integrity sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ== -"@sinclair/typebox@^0.23.3": - version "0.23.5" - resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.23.5.tgz#93f7b9f4e3285a7a9ade7557d9a8d36809cbc47d" - integrity sha512-AFBVi/iT4g20DHoujvMH1aEDn8fGJh4xsRGCP6d8RpLPMqsNPvW01Jcn0QysXTsg++/xj25NmJsGyH9xug/wKg== +"@sinclair/typebox@^0.24.1": + version "0.24.51" + resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.24.51.tgz#645f33fe4e02defe26f2f5c0410e1c094eac7f5f" + integrity sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA== "@sinonjs/commons@^1.7.0": - version "1.8.3" - resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.3.tgz#3802ddd21a50a949b6721ddd72da36e67e7f1b2d" - integrity sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ== + version "1.8.6" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.6.tgz#80c516a4dc264c2a69115e7578d62581ff455ed9" + integrity sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ== dependencies: type-detect "4.0.8" -"@sinonjs/fake-timers@^9.1.1": +"@sinonjs/fake-timers@^9.1.2": version "9.1.2" resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz#4eaab737fab77332ab132d396a3c0d364bd0ea8c" integrity sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw== @@ -1303,32 +1339,32 @@ "@sinonjs/commons" "^1.7.0" "@tsconfig/node10@^1.0.7": - version "1.0.8" - resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.8.tgz#c1e4e80d6f964fbecb3359c43bd48b40f7cadad9" - integrity sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg== + version "1.0.9" + resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2" + integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA== "@tsconfig/node12@^1.0.7": - version "1.0.9" - resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.9.tgz#62c1f6dee2ebd9aead80dc3afa56810e58e1a04c" - integrity sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw== + version "1.0.11" + resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d" + integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== "@tsconfig/node14@^1.0.0": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.1.tgz#95f2d167ffb9b8d2068b0b235302fafd4df711f2" - integrity sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg== + version "1.0.3" + resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1" + integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== "@tsconfig/node16@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.2.tgz#423c77877d0569db20e1fc80885ac4118314010e" - integrity sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA== + version "1.0.4" + resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9" + integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA== "@types/babel__core@^7.1.14": - version "7.1.19" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.19.tgz#7b497495b7d1b4812bdb9d02804d0576f43ee460" - integrity sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw== + version "7.20.1" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.1.tgz#916ecea274b0c776fec721e333e55762d3a9614b" + integrity sha512-aACu/U/omhdk15O4Nfb+fHgH/z3QsfQzpnvRZhYhThms83ZnAOZz7zZAWO7mn2yyNQaA4xTO8GLK3uqFU4bYYw== dependencies: - "@babel/parser" "^7.1.0" - "@babel/types" "^7.0.0" + "@babel/parser" "^7.20.7" + "@babel/types" "^7.20.7" "@types/babel__generator" "*" "@types/babel__template" "*" "@types/babel__traverse" "*" @@ -1349,38 +1385,38 @@ "@babel/types" "^7.0.0" "@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": - version "7.17.1" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.17.1.tgz#1a0e73e8c28c7e832656db372b779bfd2ef37314" - integrity sha512-kVzjari1s2YVi77D3w1yuvohV2idweYXMCDzqBiVNN63TcDWrIlTVOYpqVrvbbyOE/IyzBoTKF0fdnLPEORFxA== + version "7.20.1" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.20.1.tgz#dd6f1d2411ae677dcb2db008c962598be31d6acf" + integrity sha512-MitHFXnhtgwsGZWtT68URpOvLN4EREih1u3QtQiN4VdAxWKRVvGCSvw/Qth0M0Qq3pJpnGOu5JaM/ydK7OGbqg== dependencies: - "@babel/types" "^7.3.0" + "@babel/types" "^7.20.7" "@types/eslint@^8.4.1": - version "8.4.1" - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.4.1.tgz#c48251553e8759db9e656de3efc846954ac32304" - integrity sha512-GE44+DNEyxxh2Kc6ro/VkIj+9ma0pO0bwv9+uHSyBrikYOHr8zYcdPvnBOp1aw8s+CjRvuSx7CyWqRrNFQ59mA== + version "8.44.2" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.44.2.tgz#0d21c505f98a89b8dd4d37fa162b09da6089199a" + integrity sha512-sdPRb9K6iL5XZOmBubg8yiFp5yS/JdUDQsq5e6h95km91MCYMuvp7mh1fjPEYUhvHepKpZOjnEaMBR4PxjWDzg== dependencies: "@types/estree" "*" "@types/json-schema" "*" "@types/estree@*": - version "0.0.51" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40" - integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== + version "1.0.1" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.1.tgz#aa22750962f3bf0e79d753d3cc067f010c95f194" + integrity sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA== "@types/ffi-napi@^4.0.5": - version "4.0.5" - resolved "https://registry.yarnpkg.com/@types/ffi-napi/-/ffi-napi-4.0.5.tgz#0b2dc2d549361947a117d55156ff34fd9632c3df" - integrity sha512-WDPpCcHaPhHmP1FIw3ds/+OLt8bYQ/h3SO7o+8kH771PL21kHVzTwii7+WyMBXMQrBsR6xVU2y7w+h+9ggpaQw== + version "4.0.7" + resolved "https://registry.yarnpkg.com/@types/ffi-napi/-/ffi-napi-4.0.7.tgz#b3a9beeae160c74adca801ca1c9defb1ec0a1a32" + integrity sha512-2CvLfgxCUUSj7qVab6/uFLyVpgVd2gEV4H/TQEHHn6kZTV8iTesz9uo0bckhwzsh71atutOv8P3JmvRX2ZvpZg== dependencies: "@types/node" "*" "@types/ref-napi" "*" "@types/ref-struct-di" "*" "@types/graceful-fs@^4.1.2", "@types/graceful-fs@^4.1.3": - version "4.1.5" - resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.5.tgz#21ffba0d98da4350db64891f92a9e5db3cdb4e15" - integrity sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw== + version "4.1.6" + resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.6.tgz#e14b2576a1c25026b7f02ede1de3b84c3a1efeae" + integrity sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw== dependencies: "@types/node" "*" @@ -1404,32 +1440,37 @@ "@types/istanbul-lib-report" "*" "@types/jest@^27.4.1": - version "27.4.1" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-27.4.1.tgz#185cbe2926eaaf9662d340cc02e548ce9e11ab6d" - integrity sha512-23iPJADSmicDVrWk+HT58LMJtzLAnB2AgIzplQuq/bSrGaxCrlvRFjGbXmamnnk/mAmCdLStiGqggu28ocUyiw== + version "27.5.2" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-27.5.2.tgz#ec49d29d926500ffb9fd22b84262e862049c026c" + integrity sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA== dependencies: jest-matcher-utils "^27.0.0" pretty-format "^27.0.0" "@types/json-schema@*", "@types/json-schema@^7.0.9": - version "7.0.11" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" - integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== + version "7.0.12" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.12.tgz#d70faba7039d5fca54c83c7dbab41051d2b6f6cb" + integrity sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA== "@types/json5@^0.0.29": version "0.0.29" resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" - integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= + integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== -"@types/node@*", "@types/node@^17.0.26": - version "17.0.31" - resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.31.tgz#a5bb84ecfa27eec5e1c802c6bbf8139bdb163a5d" - integrity sha512-AR0x5HbXGqkEx9CadRH3EBYx/VkiUgZIhP4wvPn/+5KIsgpNoyFaRlVe0Zlx9gRtg8fA06a9tskE2MSN7TcG4Q== +"@types/node@*": + version "20.4.9" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.4.9.tgz#c7164e0f8d3f12dfae336af0b1f7fdec8c6b204f" + integrity sha512-8e2HYcg7ohnTUbHk8focoklEQYvemQmu9M/f43DZVx43kHn0tE3BY/6gSDxS7k0SprtS0NHvj+L80cGLnoOUcQ== + +"@types/node@^17.0.26": + version "17.0.45" + resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.45.tgz#2c0fafd78705e7a18b7906b5201a522719dc5190" + integrity sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw== "@types/prettier@^2.1.5": - version "2.6.0" - resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.6.0.tgz#efcbd41937f9ae7434c714ab698604822d890759" - integrity sha512-G/AdOadiZhnJp0jXCaBQU449W2h716OW/EoXeYkCytxKL06X1WCXB4DZpp8TpZ8eyIJVS1cw4lrlkkSYU21cDw== + version "2.7.3" + resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.3.tgz#3e51a17e291d01d17d3fc61422015a933af7a08f" + integrity sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA== "@types/prop-types@*": version "15.7.5" @@ -1437,25 +1478,25 @@ integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w== "@types/react-native@^0.67.0": - version "0.67.6" - resolved "https://registry.yarnpkg.com/@types/react-native/-/react-native-0.67.6.tgz#9a7de5feba6065aec9f44f9a1e8f6e55ee5d015c" - integrity sha512-NM6atxrefIXMLE/PyQ1bIQjQ/lWLdls3uVxItzKvNUUVZlGqgn/uGN4MarM9quSf90uSqJYPIAeAgTtBTUjhgg== + version "0.67.21" + resolved "https://registry.yarnpkg.com/@types/react-native/-/react-native-0.67.21.tgz#d7a46cb1a1e5c9cdc8d83efefe9e54dc179d7126" + integrity sha512-p++6s9efGcIPjDJFxlfXS9zCb2ZVMhDM3eaEUqjmn9InVM1NhquyQlDABn6yZUAhBMqqoor62CXNKR0wC6sPKA== dependencies: - "@types/react" "*" + "@types/react" "^17" -"@types/react@*": - version "18.0.8" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.8.tgz#a051eb380a9fbcaa404550543c58e1cf5ce4ab87" - integrity sha512-+j2hk9BzCOrrOSJASi5XiOyBbERk9jG5O73Ya4M0env5Ixi6vUNli4qy994AINcEF+1IEHISYFfIT4zwr++LKw== +"@types/react@^16.9.19": + version "16.14.45" + resolved "https://registry.yarnpkg.com/@types/react/-/react-16.14.45.tgz#c505c96adf959971fc97b4687187c871765a6ae4" + integrity sha512-XFtKkY3yuPO5VJSE6Lru9yLkVQvYE+l6NbmLp6IWCg4jo5S8Ijbpke8wC9q4NmQ5pJErT8KKboG5eY7n5n718A== dependencies: "@types/prop-types" "*" "@types/scheduler" "*" csstype "^3.0.2" -"@types/react@^16.9.19": - version "16.14.25" - resolved "https://registry.yarnpkg.com/@types/react/-/react-16.14.25.tgz#d003f712c7563fdef5a87327f1892825af375608" - integrity sha512-cXRVHd7vBT5v1is72mmvmsg9stZrbJO04DJqFeh3Yj2tVKO6vmxg5BI+ybI6Ls7ROXRG3aFbZj9x0WA3ZAoDQw== +"@types/react@^17": + version "17.0.64" + resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.64.tgz#468162c66c33ddb4548eb1a0e36682028d9e9a62" + integrity sha512-IlgbX/vglDTwrCRgad6fTCzOT+D/5C0xwuvrzfuqfhg9gJrkFqAGADpUFlEtqbrP1IEo9QLSbo41MaFfoIu9Aw== dependencies: "@types/prop-types" "*" "@types/scheduler" "*" @@ -1469,23 +1510,28 @@ "@types/ref-napi" "*" "@types/ref-napi@*": - version "3.0.4" - resolved "https://registry.yarnpkg.com/@types/ref-napi/-/ref-napi-3.0.4.tgz#d7edc063b244c85767867ce1167ec2d7051728a1" - integrity sha512-ng8SCmdZbz1GHaW3qgGoX9IaHoIvgMqgBHLe3sv18NbAkHVgnjRW8fJq51VTUm4lnJyLu60q9/002o7qjOg13g== + version "3.0.7" + resolved "https://registry.yarnpkg.com/@types/ref-napi/-/ref-napi-3.0.7.tgz#20adc93a7a2f9f992dfb17409fd748e6f4bf403d" + integrity sha512-CzPwr36VkezSpaJGdQX/UrczMSDsDgsWQQFEfQkS799Ft7n/s183a53lsql7RwVq+Ik4yLEgI84pRnLC0XXRlA== dependencies: "@types/node" "*" "@types/ref-struct-di@*", "@types/ref-struct-di@^1.1.6": - version "1.1.6" - resolved "https://registry.yarnpkg.com/@types/ref-struct-di/-/ref-struct-di-1.1.6.tgz#9775753b24ba5bf248dd66d79d4fdb7cebef6e95" - integrity sha512-+Sa2H3ynDYo2ungR3d5kmNetlkAYNqQVjJvs1k7i6zvo7Zu/qb+OsrXU54RuiOYJCwY9piN+hOd4YRRaiEOqgw== + version "1.1.9" + resolved "https://registry.yarnpkg.com/@types/ref-struct-di/-/ref-struct-di-1.1.9.tgz#cdca2cefbb8a907ac9eb9d6a7f19cfae00bfa092" + integrity sha512-B1FsB1BhG1VLx0+IqBaAPXEPH0wCOb+Glaaw/i+nRUwDKFtSqWOziGnTRw05RyrBbrDsMiM0tVWmaujrs016Sw== dependencies: "@types/ref-napi" "*" "@types/scheduler@*": - version "0.16.2" - resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39" - integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew== + version "0.16.3" + resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.3.tgz#cef09e3ec9af1d63d2a6cc5b383a737e24e6dcf5" + integrity sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ== + +"@types/semver@^7.3.12": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.0.tgz#591c1ce3a702c45ee15f47a42ade72c2fd78978a" + integrity sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw== "@types/stack-utils@^2.0.0": version "2.0.1" @@ -1498,105 +1544,114 @@ integrity sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA== "@types/yargs@^15.0.0": - version "15.0.14" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.14.tgz#26d821ddb89e70492160b66d10a0eb6df8f6fb06" - integrity sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ== + version "15.0.15" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.15.tgz#e609a2b1ef9e05d90489c2f5f45bbfb2be092158" + integrity sha512-IziEYMU9XoVj8hWg7k+UJrXALkGFjWJhn5QFEv9q4p+v40oZhSuC135M38st8XPjICL7Ey4TV64ferBGUoJhBg== dependencies: "@types/yargs-parser" "*" "@types/yargs@^16.0.0": - version "16.0.4" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.4.tgz#26aad98dd2c2a38e421086ea9ad42b9e51642977" - integrity sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw== + version "16.0.5" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.5.tgz#12cc86393985735a283e387936398c2f9e5f88e3" + integrity sha512-AxO/ADJOBFJScHbWhq2xAhlWP24rY4aCEG/NFaMvbT3X2MgRsLjhjQwsn0Zi5zn0LG9jUhCCZMeX9Dkuw6k+vQ== dependencies: "@types/yargs-parser" "*" "@types/yargs@^17.0.8": - version "17.0.10" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.10.tgz#591522fce85d8739bca7b8bb90d048e4478d186a" - integrity sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA== + version "17.0.24" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.24.tgz#b3ef8d50ad4aa6aecf6ddc97c580a00f5aa11902" + integrity sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw== dependencies: "@types/yargs-parser" "*" "@typescript-eslint/eslint-plugin@^5.11.0": - version "5.21.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.21.0.tgz#bfc22e0191e6404ab1192973b3b4ea0461c1e878" - integrity sha512-fTU85q8v5ZLpoZEyn/u1S2qrFOhi33Edo2CZ0+q1gDaWWm0JuPh3bgOyU8lM0edIEYgKLDkPFiZX2MOupgjlyg== - dependencies: - "@typescript-eslint/scope-manager" "5.21.0" - "@typescript-eslint/type-utils" "5.21.0" - "@typescript-eslint/utils" "5.21.0" - debug "^4.3.2" - functional-red-black-tree "^1.0.1" - ignore "^5.1.8" - regexpp "^3.2.0" - semver "^7.3.5" + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz#aeef0328d172b9e37d9bab6dbc13b87ed88977db" + integrity sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag== + dependencies: + "@eslint-community/regexpp" "^4.4.0" + "@typescript-eslint/scope-manager" "5.62.0" + "@typescript-eslint/type-utils" "5.62.0" + "@typescript-eslint/utils" "5.62.0" + debug "^4.3.4" + graphemer "^1.4.0" + ignore "^5.2.0" + natural-compare-lite "^1.4.0" + semver "^7.3.7" tsutils "^3.21.0" "@typescript-eslint/parser@^5.11.0": - version "5.21.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.21.0.tgz#6cb72673dbf3e1905b9c432175a3c86cdaf2071f" - integrity sha512-8RUwTO77hstXUr3pZoWZbRQUxXcSXafZ8/5gpnQCfXvgmP9gpNlRGlWzvfbEQ14TLjmtU8eGnONkff8U2ui2Eg== + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.62.0.tgz#1b63d082d849a2fcae8a569248fbe2ee1b8a56c7" + integrity sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA== dependencies: - "@typescript-eslint/scope-manager" "5.21.0" - "@typescript-eslint/types" "5.21.0" - "@typescript-eslint/typescript-estree" "5.21.0" - debug "^4.3.2" + "@typescript-eslint/scope-manager" "5.62.0" + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/typescript-estree" "5.62.0" + debug "^4.3.4" -"@typescript-eslint/scope-manager@5.21.0": - version "5.21.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.21.0.tgz#a4b7ed1618f09f95e3d17d1c0ff7a341dac7862e" - integrity sha512-XTX0g0IhvzcH/e3393SvjRCfYQxgxtYzL3UREteUneo72EFlt7UNoiYnikUtmGVobTbhUDByhJ4xRBNe+34kOQ== +"@typescript-eslint/scope-manager@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz#d9457ccc6a0b8d6b37d0eb252a23022478c5460c" + integrity sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w== dependencies: - "@typescript-eslint/types" "5.21.0" - "@typescript-eslint/visitor-keys" "5.21.0" + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/visitor-keys" "5.62.0" -"@typescript-eslint/type-utils@5.21.0": - version "5.21.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.21.0.tgz#ff89668786ad596d904c21b215e5285da1b6262e" - integrity sha512-MxmLZj0tkGlkcZCSE17ORaHl8Th3JQwBzyXL/uvC6sNmu128LsgjTX0NIzy+wdH2J7Pd02GN8FaoudJntFvSOw== +"@typescript-eslint/type-utils@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz#286f0389c41681376cdad96b309cedd17d70346a" + integrity sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew== dependencies: - "@typescript-eslint/utils" "5.21.0" - debug "^4.3.2" + "@typescript-eslint/typescript-estree" "5.62.0" + "@typescript-eslint/utils" "5.62.0" + debug "^4.3.4" tsutils "^3.21.0" -"@typescript-eslint/types@5.21.0": - version "5.21.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.21.0.tgz#8cdb9253c0dfce3f2ab655b9d36c03f72e684017" - integrity sha512-XnOOo5Wc2cBlq8Lh5WNvAgHzpjnEzxn4CJBwGkcau7b/tZ556qrWXQz4DJyChYg8JZAD06kczrdgFPpEQZfDsA== +"@typescript-eslint/types@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.62.0.tgz#258607e60effa309f067608931c3df6fed41fd2f" + integrity sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ== -"@typescript-eslint/typescript-estree@5.21.0": - version "5.21.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.21.0.tgz#9f0c233e28be2540eaed3df050f0d54fb5aa52de" - integrity sha512-Y8Y2T2FNvm08qlcoSMoNchh9y2Uj3QmjtwNMdRQkcFG7Muz//wfJBGBxh8R7HAGQFpgYpdHqUpEoPQk+q9Kjfg== +"@typescript-eslint/typescript-estree@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz#7d17794b77fabcac615d6a48fb143330d962eb9b" + integrity sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA== dependencies: - "@typescript-eslint/types" "5.21.0" - "@typescript-eslint/visitor-keys" "5.21.0" - debug "^4.3.2" - globby "^11.0.4" + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/visitor-keys" "5.62.0" + debug "^4.3.4" + globby "^11.1.0" is-glob "^4.0.3" - semver "^7.3.5" + semver "^7.3.7" tsutils "^3.21.0" -"@typescript-eslint/utils@5.21.0": - version "5.21.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.21.0.tgz#51d7886a6f0575e23706e5548c7e87bce42d7c18" - integrity sha512-q/emogbND9wry7zxy7VYri+7ydawo2HDZhRZ5k6yggIvXa7PvBbAAZ4PFH/oZLem72ezC4Pr63rJvDK/sTlL8Q== +"@typescript-eslint/utils@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.62.0.tgz#141e809c71636e4a75daa39faed2fb5f4b10df86" + integrity sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ== dependencies: + "@eslint-community/eslint-utils" "^4.2.0" "@types/json-schema" "^7.0.9" - "@typescript-eslint/scope-manager" "5.21.0" - "@typescript-eslint/types" "5.21.0" - "@typescript-eslint/typescript-estree" "5.21.0" + "@types/semver" "^7.3.12" + "@typescript-eslint/scope-manager" "5.62.0" + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/typescript-estree" "5.62.0" eslint-scope "^5.1.1" - eslint-utils "^3.0.0" + semver "^7.3.7" -"@typescript-eslint/visitor-keys@5.21.0": - version "5.21.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.21.0.tgz#453fb3662409abaf2f8b1f65d515699c888dd8ae" - integrity sha512-SX8jNN+iHqAF0riZQMkm7e8+POXa/fXw5cxL+gjpyP+FI+JVNhii53EmQgDAfDcBpFekYSlO0fGytMQwRiMQCA== +"@typescript-eslint/visitor-keys@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz#2174011917ce582875954ffe2f6912d5931e353e" + integrity sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw== dependencies: - "@typescript-eslint/types" "5.21.0" - eslint-visitor-keys "^3.0.0" + "@typescript-eslint/types" "5.62.0" + eslint-visitor-keys "^3.3.0" + +"@xmldom/xmldom@^0.8.8": + version "0.8.10" + resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.8.10.tgz#a1337ca426aa61cef9fe15b5b28e340a72f6fa99" + integrity sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw== abbrev@1: version "1.1.1" @@ -1613,7 +1668,7 @@ abort-controller@^3.0.0: absolute-path@^0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/absolute-path/-/absolute-path-0.0.0.tgz#a78762fbdadfb5297be99b15d35a785b2f095bf7" - integrity sha1-p4di+9rftSl76ZsV01p4Wy8JW/c= + integrity sha512-HQiug4c+/s3WOvEnDRxXVmNtSG5s2gJM9r19BTcqjp7BWcE48PB+Y2G6jE65kqI0LpsQeMZygt/b60Gi4KxGyA== accepts@^1.3.7, accepts@~1.3.5, accepts@~1.3.7: version "1.3.8" @@ -1623,7 +1678,7 @@ accepts@^1.3.7, accepts@~1.3.5, accepts@~1.3.7: mime-types "~2.1.34" negotiator "0.6.3" -acorn-jsx@^5.3.1: +acorn-jsx@^5.3.2: version "5.3.2" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== @@ -1633,10 +1688,10 @@ acorn-walk@^8.1.1: resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== -acorn@^8.4.1, acorn@^8.7.0: - version "8.7.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.1.tgz#0197122c843d1bf6d0a5e83220a788f278f63c30" - integrity sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A== +acorn@^8.4.1, acorn@^8.9.0: + version "8.10.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" + integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== agent-base@6: version "6.0.2" @@ -1645,7 +1700,7 @@ agent-base@6: dependencies: debug "4" -ajv@^6.10.0, ajv@^6.12.4: +ajv@^6.12.4: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -1714,17 +1769,17 @@ anymatch@^2.0.0: normalize-path "^2.1.1" anymatch@^3.0.3: - version "3.1.2" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" - integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== dependencies: normalize-path "^3.0.0" picomatch "^2.0.4" appdirsjs@^1.2.4: - version "1.2.6" - resolved "https://registry.yarnpkg.com/appdirsjs/-/appdirsjs-1.2.6.tgz#fccf9ee543315492867cacfcfd4a2b32257d30ac" - integrity sha512-D8wJNkqMCeQs3kLasatELsddox/Xqkhp+J07iXGyL54fVN7oc+nmNfYzGuCs1IEP6uBw+TfpuO3JKwc+lECy4w== + version "1.2.7" + resolved "https://registry.yarnpkg.com/appdirsjs/-/appdirsjs-1.2.7.tgz#50b4b7948a26ba6090d4aede2ae2dc2b051be3b3" + integrity sha512-Quji6+8kLBC3NnBeo14nPDq0+2jUs5s3/xEye+udFHumHhRk4M7aAMXp/PBJqkKYGuuyR9M/6Dq7d2AViiGmhw== "aproba@^1.0.3 || ^2.0.0": version "2.0.0" @@ -1759,7 +1814,7 @@ argparse@^2.0.1: arr-diff@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" - integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= + integrity sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA== arr-flatten@^1.1.0: version "1.1.0" @@ -1769,42 +1824,35 @@ arr-flatten@^1.1.0: arr-union@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" - integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= + integrity sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q== -array-filter@~0.0.0: - version "0.0.1" - resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-0.0.1.tgz#7da8cf2e26628ed732803581fd21f67cacd2eeec" - integrity sha1-fajPLiZijtcygDWB/SH2fKzS7uw= +array-buffer-byte-length@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz#fabe8bc193fea865f317fe7807085ee0dee5aead" + integrity sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A== + dependencies: + call-bind "^1.0.2" + is-array-buffer "^3.0.1" -array-includes@^3.1.4: - version "3.1.4" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.4.tgz#f5b493162c760f3539631f005ba2bb46acb45ba9" - integrity sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw== +array-includes@^3.1.6: + version "3.1.6" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.6.tgz#9e9e720e194f198266ba9e18c29e6a9b0e4b225f" + integrity sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw== dependencies: call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.1" - get-intrinsic "^1.1.1" + define-properties "^1.1.4" + es-abstract "^1.20.4" + get-intrinsic "^1.1.3" is-string "^1.0.7" array-index@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/array-index/-/array-index-1.0.0.tgz#ec56a749ee103e4e08c790b9c353df16055b97f9" - integrity sha1-7FanSe4QPk4Ix5C5w1PfFgVbl/k= + integrity sha512-jesyNbBkLQgGZMSwA1FanaFjalb1mZUGxGeUEkSDidzgrbjBGhvizJkaItdhkt8eIHFOJC7nDsrXk+BaehTdRw== dependencies: debug "^2.2.0" es6-symbol "^3.0.2" -array-map@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/array-map/-/array-map-0.0.0.tgz#88a2bab73d1cf7bcd5c1b118a003f66f665fa662" - integrity sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI= - -array-reduce@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/array-reduce/-/array-reduce-0.0.0.tgz#173899d3ffd1c7d9383e4479525dbe278cab5f2b" - integrity sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys= - array-union@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" @@ -1813,27 +1861,60 @@ array-union@^2.1.0: array-unique@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" - integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= + integrity sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ== -array.prototype.flat@^1.2.5: - version "1.3.0" - resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz#0b0c1567bf57b38b56b4c97b8aa72ab45e4adc7b" - integrity sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw== +array.prototype.findlastindex@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.2.tgz#bc229aef98f6bd0533a2bc61ff95209875526c9b" + integrity sha512-tb5thFFlUcp7NdNF6/MpDk/1r/4awWG1FIz3YqDf+/zJSTezBb+/5WViH41obXULHVpDzoiCLpJ/ZO9YbJMsdw== dependencies: call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + es-shim-unscopables "^1.0.0" + get-intrinsic "^1.1.3" + +array.prototype.flat@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz#ffc6576a7ca3efc2f46a143b9d1dda9b4b3cf5e2" + integrity sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" es-shim-unscopables "^1.0.0" +array.prototype.flatmap@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz#1aae7903c2100433cb8261cd4ed310aab5c4a183" + integrity sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + es-shim-unscopables "^1.0.0" + +arraybuffer.prototype.slice@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.1.tgz#9b5ea3868a6eebc30273da577eb888381c0044bb" + integrity sha512-09x0ZWFEjj4WD8PDbykUwo3t9arLn8NIzmmYEJFpYekOAQjpkGSyrQhNoRTcwwcFRu+ycWF78QZ63oWTqSjBcw== + dependencies: + array-buffer-byte-length "^1.0.0" + call-bind "^1.0.2" + define-properties "^1.2.0" + get-intrinsic "^1.2.1" + is-array-buffer "^3.0.2" + is-shared-array-buffer "^1.0.2" + asap@~2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" - integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= + integrity sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA== assign-symbols@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" - integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= + integrity sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw== ast-types@0.14.2: version "0.14.2" @@ -1864,31 +1945,29 @@ atob@^2.1.2: resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== +available-typed-arrays@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" + integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== + babel-core@^7.0.0-bridge.0: version "7.0.0-bridge.0" resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-7.0.0-bridge.0.tgz#95a492ddd90f9b4e9a4a1da14eb335b87b634ece" integrity sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg== -babel-jest@^28.0.3: - version "28.0.3" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-28.0.3.tgz#843dc170da5b9671d4054ada9fdcd28f85f92a6e" - integrity sha512-S0ADyYdcrt5fp9YldRYWCUHdk1BKt9AkvBkLWBoNAEV9NoWZPIj5+MYhPcGgTS65mfv3a+Ymf2UqgWoAVd41cA== +babel-jest@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-28.1.3.tgz#c1187258197c099072156a0a121c11ee1e3917d5" + integrity sha512-epUaPOEWMk3cWX0M/sPvCHHCe9fMFAa/9hXEgKP8nFfNl/jlGkE9ucq9NqkZGXLDduCJYS0UvSlPUwC0S+rH6Q== dependencies: - "@jest/transform" "^28.0.3" + "@jest/transform" "^28.1.3" "@types/babel__core" "^7.1.14" babel-plugin-istanbul "^6.1.1" - babel-preset-jest "^28.0.2" + babel-preset-jest "^28.1.3" chalk "^4.0.0" graceful-fs "^4.2.9" slash "^3.0.0" -babel-plugin-dynamic-import-node@^2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz#84fda19c976ec5c6defef57f9427b3def66e17a3" - integrity sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ== - dependencies: - object.assign "^4.1.0" - babel-plugin-istanbul@^6.1.1: version "6.1.1" resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" @@ -1900,10 +1979,10 @@ babel-plugin-istanbul@^6.1.1: istanbul-lib-instrument "^5.0.4" test-exclude "^6.0.0" -babel-plugin-jest-hoist@^28.0.2: - version "28.0.2" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-28.0.2.tgz#9307d03a633be6fc4b1a6bc5c3a87e22bd01dd3b" - integrity sha512-Kizhn/ZL+68ZQHxSnHyuvJv8IchXD62KQxV77TBDV/xoBFBOfgRAk97GNs6hXdTTCiVES9nB2I6+7MXXrk5llQ== +babel-plugin-jest-hoist@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-28.1.3.tgz#1952c4d0ea50f2d6d794353762278d1d8cca3fbe" + integrity sha512-Ys3tUKAmfnkRUpPdpa98eYrAR0nV+sSFUZZEGuQ2EbFd1y4SOLtD5QDNHAq+bb9a+bbXvYQC4b+ID/THIMcU6Q== dependencies: "@babel/template" "^7.3.3" "@babel/types" "^7.3.3" @@ -1921,29 +2000,29 @@ babel-plugin-module-resolver@^4.0.0: reselect "^4.0.0" resolve "^1.13.1" -babel-plugin-polyfill-corejs2@^0.3.0: - version "0.3.1" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.1.tgz#440f1b70ccfaabc6b676d196239b138f8a2cfba5" - integrity sha512-v7/T6EQcNfVLfcN2X8Lulb7DjprieyLWJK/zOWH5DUYcAgex9sP3h25Q+DLsX9TloXe3y1O8l2q2Jv9q8UVB9w== +babel-plugin-polyfill-corejs2@^0.4.5: + version "0.4.5" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.5.tgz#8097b4cb4af5b64a1d11332b6fb72ef5e64a054c" + integrity sha512-19hwUH5FKl49JEsvyTcoHakh6BE0wgXLLptIyKZ3PijHc/Ci521wygORCUCCred+E/twuqRyAkE02BAWPmsHOg== dependencies: - "@babel/compat-data" "^7.13.11" - "@babel/helper-define-polyfill-provider" "^0.3.1" - semver "^6.1.1" + "@babel/compat-data" "^7.22.6" + "@babel/helper-define-polyfill-provider" "^0.4.2" + semver "^6.3.1" -babel-plugin-polyfill-corejs3@^0.5.0: - version "0.5.2" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.2.tgz#aabe4b2fa04a6e038b688c5e55d44e78cd3a5f72" - integrity sha512-G3uJih0XWiID451fpeFaYGVuxHEjzKTHtc9uGFEjR6hHrvNzeS/PX+LLLcetJcytsB5m4j+K3o/EpXJNb/5IEQ== +babel-plugin-polyfill-corejs3@^0.8.3: + version "0.8.3" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.3.tgz#b4f719d0ad9bb8e0c23e3e630c0c8ec6dd7a1c52" + integrity sha512-z41XaniZL26WLrvjy7soabMXrfPWARN25PZoriDEiLMxAp50AUW3t35BGQUMg5xK3UrpVTtagIDklxYa+MhiNA== dependencies: - "@babel/helper-define-polyfill-provider" "^0.3.1" - core-js-compat "^3.21.0" + "@babel/helper-define-polyfill-provider" "^0.4.2" + core-js-compat "^3.31.0" -babel-plugin-polyfill-regenerator@^0.3.0: - version "0.3.1" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.1.tgz#2c0678ea47c75c8cc2fbb1852278d8fb68233990" - integrity sha512-Y2B06tvgHYt1x0yz17jGkGeeMr5FeKUu+ASJ+N6nB5lQ8Dapfg42i0OVrf8PNGJ3zKL4A23snMi1IRwrqqND7A== +babel-plugin-polyfill-regenerator@^0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.2.tgz#80d0f3e1098c080c8b5a65f41e9427af692dc326" + integrity sha512-tAlOptU0Xj34V1Y2PNTL4Y0FOJMDB6bZmoW39FeCQIhigGLkqu3Fj6uiXpxIf6Ij274ENdYx64y6Au+ZKlb1IA== dependencies: - "@babel/helper-define-polyfill-provider" "^0.3.1" + "@babel/helper-define-polyfill-provider" "^0.4.2" babel-plugin-syntax-trailing-function-commas@^7.0.0-beta.0: version "7.0.0-beta.0" @@ -2001,12 +2080,12 @@ babel-preset-fbjs@^3.4.0: "@babel/plugin-transform-template-literals" "^7.0.0" babel-plugin-syntax-trailing-function-commas "^7.0.0-beta.0" -babel-preset-jest@^28.0.2: - version "28.0.2" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-28.0.2.tgz#d8210fe4e46c1017e9fa13d7794b166e93aa9f89" - integrity sha512-sYzXIdgIXXroJTFeB3S6sNDWtlJ2dllCdTEsnZ65ACrMojj3hVNFRmnJ1HZtomGi+Be7aqpY/HJ92fr8OhKVkQ== +babel-preset-jest@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-28.1.3.tgz#5dfc20b99abed5db994406c2b9ab94c73aaa419d" + integrity sha512-L+fupJvlWAHbQfn74coNX3zf60LXMJsezNvvx8eIh7iOR1luJ1poxYgQk1F8PYtNq/6QODDHCqsSnTFSWC491A== dependencies: - babel-plugin-jest-hoist "^28.0.2" + babel-plugin-jest-hoist "^28.1.3" babel-preset-current-node-syntax "^1.0.0" balanced-match@^1.0.0: @@ -2082,16 +2161,15 @@ braces@^3.0.2: dependencies: fill-range "^7.0.1" -browserslist@^4.20.2, browserslist@^4.20.3: - version "4.20.3" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.20.3.tgz#eb7572f49ec430e054f56d52ff0ebe9be915f8bf" - integrity sha512-NBhymBQl1zM0Y5dQT/O+xiLP9/rzOIQdKM/eMJBAq7yBgaB6krIYLGejrwVYnSHZdqjscB1SPuAjHwxjvN6Wdg== +browserslist@^4.21.9: + version "4.21.10" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.10.tgz#dbbac576628c13d3b2231332cb2ec5a46e015bb0" + integrity sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ== dependencies: - caniuse-lite "^1.0.30001332" - electron-to-chromium "^1.4.118" - escalade "^3.1.1" - node-releases "^2.0.3" - picocolors "^1.0.0" + caniuse-lite "^1.0.30001517" + electron-to-chromium "^1.4.477" + node-releases "^2.0.13" + update-browserslist-db "^1.0.11" bser@2.1.1: version "2.1.1" @@ -2108,7 +2186,7 @@ buffer-from@^1.0.0: bytes@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" - integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= + integrity sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw== cache-base@^1.0.1: version "1.0.1" @@ -2136,21 +2214,21 @@ call-bind@^1.0.0, call-bind@^1.0.2: caller-callsite@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134" - integrity sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ= + integrity sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ== dependencies: callsites "^2.0.0" caller-path@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4" - integrity sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ= + integrity sha512-MCL3sf6nCSXOwCTzvPKhN18TU7AHTvdtam8DAogxcrJ8Rjfbbg7Lgng64H9Iy+vUV6VGFClN/TyxBkAebLRR4A== dependencies: caller-callsite "^2.0.0" callsites@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" - integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= + integrity sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ== callsites@^3.0.0: version "3.1.0" @@ -2167,10 +2245,10 @@ camelcase@^6.0.0, camelcase@^6.2.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== -caniuse-lite@^1.0.30001332: - version "1.0.30001335" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001335.tgz#899254a0b70579e5a957c32dced79f0727c61f2a" - integrity sha512-ddP1Tgm7z2iIxu6QTtbZUv6HJxSaV/PZeSrWFZtbY4JZ69tOeNhBCl3HyRQgeNZKE5AOn1kpV7fhljigy0Ty3w== +caniuse-lite@^1.0.30001517: + version "1.0.30001519" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001519.tgz#3e7b8b8a7077e78b0eb054d69e6edf5c7df35601" + integrity sha512-0QHgqR+Jv4bxHMp8kZ1Kn8CH55OikjKJ6JmKkZYP1F3D7w+lnFXF70nG5eNfsZS89jadi5Ywy5UCSKLAglIRkg== capture-exit@^2.0.0: version "2.0.0" @@ -2179,7 +2257,7 @@ capture-exit@^2.0.0: dependencies: rsvp "^4.8.4" -chalk@^2.0.0, chalk@^2.0.1, chalk@^2.4.2: +chalk@^2.0.1, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -2212,14 +2290,14 @@ ci-info@^2.0.0: integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== ci-info@^3.2.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.3.0.tgz#b4ed1fb6818dea4803a55c623041f9165d2066b2" - integrity sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw== + version "3.8.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.8.0.tgz#81408265a5380c929f0bc665d62256628ce9ef91" + integrity sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw== cjs-module-lexer@^1.0.0: - version "1.2.2" - resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz#9f84ba3244a512f3a54e5277e8eef4c489864e40" - integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA== + version "1.2.3" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz#6c370ab19f8a3394e318fe682686ec0ac684d107" + integrity sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ== class-utils@^0.3.5: version "0.3.6" @@ -2234,14 +2312,14 @@ class-utils@^0.3.5: cli-cursor@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" - integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= + integrity sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw== dependencies: restore-cursor "^2.0.0" cli-spinners@^2.0.0: - version "2.6.1" - resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.6.1.tgz#adc954ebe281c37a6319bfa401e6dd2488ffb70d" - integrity sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g== + version "2.9.0" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.9.0.tgz#5881d0ad96381e117bbe07ad91f2008fe6ffd8db" + integrity sha512-4/aL9X3Wh0yiMQlE+eeRhWP6vclO3QRtw1JHKIT0FFUs5FjpFmESqtMvYZ0+lbzBw900b95mS0hohy+qn2VK/g== cliui@^6.0.0: version "6.0.0" @@ -2252,13 +2330,13 @@ cliui@^6.0.0: strip-ansi "^6.0.0" wrap-ansi "^6.2.0" -cliui@^7.0.2: - version "7.0.4" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" - integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== +cliui@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" + integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== dependencies: string-width "^4.2.0" - strip-ansi "^6.0.0" + strip-ansi "^6.0.1" wrap-ansi "^7.0.0" clone-deep@^4.0.1: @@ -2273,22 +2351,22 @@ clone-deep@^4.0.1: clone@^1.0.2: version "1.0.4" resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" - integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= + integrity sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg== co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" - integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= + integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== collect-v8-coverage@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59" - integrity sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg== + version "1.0.2" + resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz#c0b29bcd33bcd0779a1344c2136051e6afd3d9e9" + integrity sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q== collection-visit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" - integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= + integrity sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw== dependencies: map-visit "^1.0.0" object-visit "^1.0.0" @@ -2310,7 +2388,7 @@ color-convert@^2.0.1: color-name@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== color-name@~1.1.4: version "1.1.4" @@ -2350,7 +2428,7 @@ commander@~2.13.0: commondir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" - integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= + integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== component-emitter@^1.2.1: version "1.3.0" @@ -2380,7 +2458,7 @@ compression@^1.7.1: concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== connect@^3.6.5: version "3.7.0" @@ -2398,24 +2476,21 @@ console-control-strings@^1.0.0, console-control-strings@^1.1.0: integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ== convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" - integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== - dependencies: - safe-buffer "~5.1.1" + version "1.9.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" + integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== copy-descriptor@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" - integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= + integrity sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw== -core-js-compat@^3.21.0: - version "3.22.3" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.22.3.tgz#9b10d786052d042bc97ee8df9c0d1fb6a49c2005" - integrity sha512-wliMbvPI2idgFWpFe7UEyHMvu6HWgW8WA+HnDRtgzoSDYvXFMpoGX1H3tPDDXrcfUSyXafCLDd7hOeMQHEZxGw== +core-js-compat@^3.31.0: + version "3.32.0" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.32.0.tgz#f41574b6893ab15ddb0ac1693681bd56c8550a90" + integrity sha512-7a9a3D1k4UCVKnLhrgALyFcP7YCsLOQIxPd0dKjf/6GuPcgyiGP70ewWdCGrSK7evyhymi0qO4EqCmSJofDeYw== dependencies: - browserslist "^4.20.3" - semver "7.0.0" + browserslist "^4.21.9" core-util-is@~1.0.0: version "1.0.3" @@ -2465,9 +2540,9 @@ cross-spawn@^7.0.1, cross-spawn@^7.0.2, cross-spawn@^7.0.3: which "^2.0.1" csstype@^3.0.2: - version "3.0.11" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.11.tgz#d66700c5eacfac1940deb4e3ee5642792d85cd33" - integrity sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw== + version "3.1.2" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.2.tgz#1d4bf9d572f11c14031f0436e1c10bc1f571f50b" + integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ== d@1, d@^1.0.1: version "1.0.1" @@ -2478,11 +2553,11 @@ d@1, d@^1.0.1: type "^1.0.1" dayjs@^1.8.15: - version "1.11.1" - resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.1.tgz#90b33a3dda3417258d48ad2771b415def6545eb0" - integrity sha512-ER7EjqVAMkRRsxNCC5YqJ9d9VQYuWdGt7aiH2qA5R5wt8ZmWaP2dLUSIK6y/kVzLMlmh1Tvu5xUf4M/wdGJ5KA== + version "1.11.9" + resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.9.tgz#9ca491933fadd0a60a2c19f6c237c03517d71d1a" + integrity sha512-QvzAURSbQ0pKdIye2txOzNaHmxtUBXerpY0FJsFXUMKbIZeFm5ht1LS/jFsrncjnmtv8HsG0W2g6c0zUjZWmpA== -debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.9: +debug@2.6.9, debug@^2.2.0, debug@^2.3.3: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== @@ -2506,17 +2581,17 @@ debug@^3.1.0, debug@^3.2.7: decamelize@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= + integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== decode-uri-component@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" - integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= + version "0.2.2" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz#e69dbe25d37941171dd540e024c444cd5188e1e9" + integrity sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ== dedent@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" - integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= + integrity sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA== deep-is@^0.1.3: version "0.1.4" @@ -2529,21 +2604,21 @@ deepmerge@^3.2.0: integrity sha512-GRQOafGHwMHpjPx9iCvTgpu9NojZ49q794EEL94JVEw6VaeA8XTUyBKvAkOOjBX9oJNiV6G3P+T+tihFjo2TqA== deepmerge@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" - integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== + version "4.3.1" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" + integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== defaults@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" - integrity sha1-xlYFHpgX2f8I7YgUd/P+QBnz730= + version "1.0.4" + resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.4.tgz#b0b02062c1e2aa62ff5d9528f0f98baa90978d7a" + integrity sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A== dependencies: clone "^1.0.2" -define-properties@^1.1.3: - version "1.1.4" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1" - integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA== +define-properties@^1.1.3, define-properties@^1.1.4, define-properties@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.0.tgz#52988570670c9eacedd8064f4a990f2405849bd5" + integrity sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA== dependencies: has-property-descriptors "^1.0.0" object-keys "^1.1.1" @@ -2551,14 +2626,14 @@ define-properties@^1.1.3: define-property@^0.2.5: version "0.2.5" resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" - integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= + integrity sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA== dependencies: is-descriptor "^0.1.0" define-property@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" - integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= + integrity sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA== dependencies: is-descriptor "^1.0.0" @@ -2578,7 +2653,7 @@ delegates@^1.0.0: denodeify@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/denodeify/-/denodeify-1.2.1.tgz#3a36287f5034e699e7577901052c2e6c94251631" - integrity sha1-OjYof1A05pnnV3kBBSwubJQlFjE= + integrity sha512-KNTihKNmQENUZeKu5fzfpzRqR5S2VMp4gl9RFHiWzj9DfvYQPMJ6XHKNaQxaGCXwPk6y9yme3aUoaiAe+KX+vg== depd@2.0.0: version "2.0.0" @@ -2591,9 +2666,9 @@ destroy@1.2.0: integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== detect-libc@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.1.tgz#e1897aa88fa6ad197862937fbc0441ef352ee0cd" - integrity sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w== + version "2.0.2" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.2.tgz#8ccf2ba9315350e1241b88d0ac3b0e1fbd99605d" + integrity sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw== detect-newline@^3.0.0: version "3.1.0" @@ -2605,10 +2680,10 @@ diff-sequences@^27.5.1: resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.5.1.tgz#eaecc0d327fd68c8d9672a1e64ab8dccb2ef5327" integrity sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ== -diff-sequences@^28.0.2: - version "28.0.2" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-28.0.2.tgz#40f8d4ffa081acbd8902ba35c798458d0ff1af41" - integrity sha512-YtEoNynLDFCRznv/XDalsKGSZDoj0U5kLnXvY0JSq3nBboRrZXjD81+eSiwi+nzcZDwedMmcowcxNwwgFW23mQ== +diff-sequences@^28.1.1: + version "28.1.1" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-28.1.1.tgz#9989dc731266dc2903457a70e996f3a041913ac6" + integrity sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw== diff@^4.0.1: version "4.0.2" @@ -2639,12 +2714,12 @@ doctrine@^3.0.0: ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" - integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= + integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== -electron-to-chromium@^1.4.118: - version "1.4.129" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.129.tgz#c675793885721beefff99da50f57c6525c2cd238" - integrity sha512-GgtN6bsDtHdtXJtlMYZWGB/uOyjZWjmRDumXTas7dGBaB9zUyCjzHet1DY2KhyHN8R0GLbzZWqm4efeddqqyRQ== +electron-to-chromium@^1.4.477: + version "1.4.489" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.489.tgz#840ebe32def1ab7b3a49e876ff84c070f76154ed" + integrity sha512-QNx+cirm4ENixfdSk9rp/3HKpjlxHFsmDoHtU1IiXdkJcpkKrd/o20LT5h1f3Qz+yfTMb4Ji3YDT/IvJkNfEkA== emittery@^0.10.2: version "0.10.2" @@ -2659,7 +2734,7 @@ emoji-regex@^8.0.0: encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" - integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= + integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== end-of-stream@^1.1.0: version "1.4.4" @@ -2669,9 +2744,9 @@ end-of-stream@^1.1.0: once "^1.4.0" envinfo@^7.7.2: - version "7.8.1" - resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.8.1.tgz#06377e3e5f4d379fea7ac592d5ad8927e0c4d475" - integrity sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw== + version "7.10.0" + resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.10.0.tgz#55146e3909cc5fe63c22da63fb15b05aeac35b13" + integrity sha512-ZtUjZO6l5mwTHvc1L9+1q5p/R3wTopcfqMW8r5t8SJSKqeVI/LtajORwRFEKpEFuekjD0VBjwu1HMxL4UalIRw== error-ex@^1.3.1: version "1.3.2" @@ -2681,11 +2756,11 @@ error-ex@^1.3.1: is-arrayish "^0.2.1" error-stack-parser@^2.0.6: - version "2.0.7" - resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-2.0.7.tgz#b0c6e2ce27d0495cf78ad98715e0cad1219abb57" - integrity sha512-chLOW0ZGRf4s8raLrDxa5sdkvPec5YdvwbFnqJme4rk0rFajP8mPtrDL1+I+CwrQDCjswDA5sREX7jYQDQs9vA== + version "2.1.4" + resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-2.1.4.tgz#229cb01cdbfa84440bfa91876285b94680188286" + integrity sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ== dependencies: - stackframe "^1.1.1" + stackframe "^1.3.4" errorhandler@^1.5.0: version "1.5.1" @@ -2695,31 +2770,59 @@ errorhandler@^1.5.0: accepts "~1.3.7" escape-html "~1.0.3" -es-abstract@^1.19.1, es-abstract@^1.19.2: - version "1.19.5" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.19.5.tgz#a2cb01eb87f724e815b278b0dd0d00f36ca9a7f1" - integrity sha512-Aa2G2+Rd3b6kxEUKTF4TaW67czBLyAv3z7VOhYRU50YBx+bbsYZ9xQP4lMNazePuFlybXI0V4MruPos7qUo5fA== +es-abstract@^1.19.0, es-abstract@^1.20.4, es-abstract@^1.21.2: + version "1.22.1" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.22.1.tgz#8b4e5fc5cefd7f1660f0f8e1a52900dfbc9d9ccc" + integrity sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw== dependencies: + array-buffer-byte-length "^1.0.0" + arraybuffer.prototype.slice "^1.0.1" + available-typed-arrays "^1.0.5" call-bind "^1.0.2" + es-set-tostringtag "^2.0.1" es-to-primitive "^1.2.1" - function-bind "^1.1.1" - get-intrinsic "^1.1.1" + function.prototype.name "^1.1.5" + get-intrinsic "^1.2.1" get-symbol-description "^1.0.0" + globalthis "^1.0.3" + gopd "^1.0.1" has "^1.0.3" + has-property-descriptors "^1.0.0" + has-proto "^1.0.1" has-symbols "^1.0.3" - internal-slot "^1.0.3" - is-callable "^1.2.4" + internal-slot "^1.0.5" + is-array-buffer "^3.0.2" + is-callable "^1.2.7" is-negative-zero "^2.0.2" is-regex "^1.1.4" is-shared-array-buffer "^1.0.2" is-string "^1.0.7" + is-typed-array "^1.1.10" is-weakref "^1.0.2" - object-inspect "^1.12.0" + object-inspect "^1.12.3" object-keys "^1.1.1" - object.assign "^4.1.2" - string.prototype.trimend "^1.0.4" - string.prototype.trimstart "^1.0.4" - unbox-primitive "^1.0.1" + object.assign "^4.1.4" + regexp.prototype.flags "^1.5.0" + safe-array-concat "^1.0.0" + safe-regex-test "^1.0.0" + string.prototype.trim "^1.2.7" + string.prototype.trimend "^1.0.6" + string.prototype.trimstart "^1.0.6" + typed-array-buffer "^1.0.0" + typed-array-byte-length "^1.0.0" + typed-array-byte-offset "^1.0.0" + typed-array-length "^1.0.4" + unbox-primitive "^1.0.2" + which-typed-array "^1.1.10" + +es-set-tostringtag@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz#338d502f6f674301d710b80c8592de8a15f09cd8" + integrity sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg== + dependencies: + get-intrinsic "^1.1.3" + has "^1.0.3" + has-tostringtag "^1.0.0" es-shim-unscopables@^1.0.0: version "1.0.0" @@ -2738,9 +2841,9 @@ es-to-primitive@^1.2.1: is-symbol "^1.0.2" es5-ext@^0.10.35, es5-ext@^0.10.50: - version "0.10.61" - resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.61.tgz#311de37949ef86b6b0dcea894d1ffedb909d3269" - integrity sha512-yFhIqQAzu2Ca2I4SE2Au3rxVfmohU9Y7wqGR+s7+H7krk26NXhIRAZDgqd6xqjCEFUomDEA3/Bo/7fKmIkW1kA== + version "0.10.62" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.62.tgz#5e6adc19a6da524bf3d1e02bbc8960e5eb49a9a5" + integrity sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA== dependencies: es6-iterator "^2.0.3" es6-symbol "^3.1.3" @@ -2749,7 +2852,7 @@ es5-ext@^0.10.35, es5-ext@^0.10.50: es6-iterator@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" - integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c= + integrity sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g== dependencies: d "1" es5-ext "^0.10.35" @@ -2771,12 +2874,12 @@ escalade@^3.1.1: escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" - integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= + integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== escape-string-regexp@^2.0.0: version "2.0.0" @@ -2789,17 +2892,18 @@ escape-string-regexp@^4.0.0: integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== eslint-config-prettier@^8.3.0: - version "8.5.0" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz#5a81680ec934beca02c7b1a61cf8ca34b66feab1" - integrity sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q== + version "8.10.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz#3a06a662130807e2502fc3ff8b4143d8a0658e11" + integrity sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg== -eslint-import-resolver-node@^0.3.6: - version "0.3.6" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz#4048b958395da89668252001dbd9eca6b83bacbd" - integrity sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw== +eslint-import-resolver-node@^0.3.7: + version "0.3.9" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz#d4eaac52b8a2e7c3cd1903eb00f7e053356118ac" + integrity sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g== dependencies: debug "^3.2.7" - resolve "^1.20.0" + is-core-module "^2.13.0" + resolve "^1.22.4" eslint-import-resolver-typescript@^2.5.0: version "2.7.1" @@ -2812,37 +2916,41 @@ eslint-import-resolver-typescript@^2.5.0: resolve "^1.22.0" tsconfig-paths "^3.14.1" -eslint-module-utils@^2.7.3: - version "2.7.3" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz#ad7e3a10552fdd0642e1e55292781bd6e34876ee" - integrity sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ== +eslint-module-utils@^2.8.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz#e439fee65fc33f6bba630ff621efc38ec0375c49" + integrity sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw== dependencies: debug "^3.2.7" - find-up "^2.1.0" eslint-plugin-import@^2.25.4: - version "2.26.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz#f812dc47be4f2b72b478a021605a59fc6fe8b88b" - integrity sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA== - dependencies: - array-includes "^3.1.4" - array.prototype.flat "^1.2.5" - debug "^2.6.9" + version "2.28.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.28.0.tgz#8d66d6925117b06c4018d491ae84469eb3cb1005" + integrity sha512-B8s/n+ZluN7sxj9eUf7/pRFERX0r5bnFA2dCaLHy2ZeaQEAz0k+ZZkFWRFHJAqxfxQDx6KLv9LeIki7cFdwW+Q== + dependencies: + array-includes "^3.1.6" + array.prototype.findlastindex "^1.2.2" + array.prototype.flat "^1.3.1" + array.prototype.flatmap "^1.3.1" + debug "^3.2.7" doctrine "^2.1.0" - eslint-import-resolver-node "^0.3.6" - eslint-module-utils "^2.7.3" + eslint-import-resolver-node "^0.3.7" + eslint-module-utils "^2.8.0" has "^1.0.3" - is-core-module "^2.8.1" + is-core-module "^2.12.1" is-glob "^4.0.3" minimatch "^3.1.2" - object.values "^1.1.5" - resolve "^1.22.0" - tsconfig-paths "^3.14.1" + object.fromentries "^2.0.6" + object.groupby "^1.0.0" + object.values "^1.1.6" + resolve "^1.22.3" + semver "^6.3.1" + tsconfig-paths "^3.14.2" eslint-plugin-prettier@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-4.0.0.tgz#8b99d1e4b8b24a762472b4567992023619cb98e0" - integrity sha512-98MqmCJ7vJodoQK359bqQWaxOE0CS8paAz/GgjaZLyex4TTk3g9HugoO89EqWCrFiOqn9EVvcoo7gZzONCWVwQ== + version "4.2.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz#651cbb88b1dab98bfd42f017a12fa6b2d993f94b" + integrity sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ== dependencies: prettier-linter-helpers "^1.0.0" @@ -2854,90 +2962,80 @@ eslint-scope@^5.1.1: esrecurse "^4.3.0" estraverse "^4.1.1" -eslint-scope@^7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.1.1.tgz#fff34894c2f65e5226d3041ac480b4513a163642" - integrity sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw== +eslint-scope@^7.2.2: + version "7.2.2" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f" + integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg== dependencies: esrecurse "^4.3.0" estraverse "^5.2.0" -eslint-utils@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672" - integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA== - dependencies: - eslint-visitor-keys "^2.0.0" - -eslint-visitor-keys@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" - integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== - -eslint-visitor-keys@^3.0.0, eslint-visitor-keys@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826" - integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== +eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.2: + version "3.4.2" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.2.tgz#8c2095440eca8c933bedcadf16fefa44dbe9ba5f" + integrity sha512-8drBzUEyZ2llkpCA67iYrgEssKDUu68V8ChqqOfFupIaG/LCVPUT+CoGJpT77zJprs4T/W7p07LP7zAIMuweVw== eslint@^8.8.0: - version "8.14.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.14.0.tgz#62741f159d9eb4a79695b28ec4989fcdec623239" - integrity sha512-3/CE4aJX7LNEiE3i6FeodHmI/38GZtWCsAtsymScmzYapx8q1nVVb+eLcLSzATmCPXw5pT4TqVs1E0OmxAd9tw== - dependencies: - "@eslint/eslintrc" "^1.2.2" - "@humanwhocodes/config-array" "^0.9.2" - ajv "^6.10.0" + version "8.46.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.46.0.tgz#a06a0ff6974e53e643acc42d1dcf2e7f797b3552" + integrity sha512-cIO74PvbW0qU8e0mIvk5IV3ToWdCq5FYG6gWPHHkx6gNdjlbAYvtfHmlCMXxjcoVaIdwy/IAt3+mDkZkfvb2Dg== + dependencies: + "@eslint-community/eslint-utils" "^4.2.0" + "@eslint-community/regexpp" "^4.6.1" + "@eslint/eslintrc" "^2.1.1" + "@eslint/js" "^8.46.0" + "@humanwhocodes/config-array" "^0.11.10" + "@humanwhocodes/module-importer" "^1.0.1" + "@nodelib/fs.walk" "^1.2.8" + ajv "^6.12.4" chalk "^4.0.0" cross-spawn "^7.0.2" debug "^4.3.2" doctrine "^3.0.0" escape-string-regexp "^4.0.0" - eslint-scope "^7.1.1" - eslint-utils "^3.0.0" - eslint-visitor-keys "^3.3.0" - espree "^9.3.1" - esquery "^1.4.0" + eslint-scope "^7.2.2" + eslint-visitor-keys "^3.4.2" + espree "^9.6.1" + esquery "^1.4.2" esutils "^2.0.2" fast-deep-equal "^3.1.3" file-entry-cache "^6.0.1" - functional-red-black-tree "^1.0.1" - glob-parent "^6.0.1" - globals "^13.6.0" + find-up "^5.0.0" + glob-parent "^6.0.2" + globals "^13.19.0" + graphemer "^1.4.0" ignore "^5.2.0" - import-fresh "^3.0.0" imurmurhash "^0.1.4" is-glob "^4.0.0" + is-path-inside "^3.0.3" js-yaml "^4.1.0" json-stable-stringify-without-jsonify "^1.0.1" levn "^0.4.1" lodash.merge "^4.6.2" - minimatch "^3.0.4" + minimatch "^3.1.2" natural-compare "^1.4.0" - optionator "^0.9.1" - regexpp "^3.2.0" + optionator "^0.9.3" strip-ansi "^6.0.1" - strip-json-comments "^3.1.0" text-table "^0.2.0" - v8-compile-cache "^2.0.3" -espree@^9.3.1: - version "9.3.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-9.3.1.tgz#8793b4bc27ea4c778c19908e0719e7b8f4115bcd" - integrity sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ== +espree@^9.6.0, espree@^9.6.1: + version "9.6.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" + integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== dependencies: - acorn "^8.7.0" - acorn-jsx "^5.3.1" - eslint-visitor-keys "^3.3.0" + acorn "^8.9.0" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^3.4.1" esprima@^4.0.0, esprima@~4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== -esquery@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" - integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== +esquery@^1.4.2: + version "1.5.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" + integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== dependencies: estraverse "^5.1.0" @@ -2966,7 +3064,7 @@ esutils@^2.0.2: etag@~1.8.1: version "1.8.1" resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" - integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= + integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== event-target-shim@^5.0.0, event-target-shim@^5.0.1: version "5.0.1" @@ -3009,12 +3107,12 @@ execa@^5.0.0: exit@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" - integrity sha1-BjJjj42HfMghB9MKD/8aF8uhzQw= + integrity sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ== expand-brackets@^2.1.4: version "2.1.4" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" - integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= + integrity sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA== dependencies: debug "^2.3.3" define-property "^0.2.5" @@ -3024,35 +3122,35 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" -expect@^28.0.2: - version "28.0.2" - resolved "https://registry.yarnpkg.com/expect/-/expect-28.0.2.tgz#86f0d6fa971bc533faf68d4d103d00f343d6a4b3" - integrity sha512-X0qIuI/zKv98k34tM+uGeOgAC73lhs4vROF9MkPk94C1zujtwv4Cla8SxhWn0G1OwvG9gLLL7RjFBkwGVaZ83w== +expect@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/expect/-/expect-28.1.3.tgz#90a7c1a124f1824133dd4533cce2d2bdcb6603ec" + integrity sha512-eEh0xn8HlsuOBxFgIss+2mX85VAS4Qy3OSkjV7rlBWljtA4oWH37glVGyOZSZvErDT/yBywZdPGwCXuTvSG85g== dependencies: - "@jest/expect-utils" "^28.0.2" + "@jest/expect-utils" "^28.1.3" jest-get-type "^28.0.2" - jest-matcher-utils "^28.0.2" - jest-message-util "^28.0.2" - jest-util "^28.0.2" + jest-matcher-utils "^28.1.3" + jest-message-util "^28.1.3" + jest-util "^28.1.3" ext@^1.1.2: - version "1.6.0" - resolved "https://registry.yarnpkg.com/ext/-/ext-1.6.0.tgz#3871d50641e874cc172e2b53f919842d19db4c52" - integrity sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg== + version "1.7.0" + resolved "https://registry.yarnpkg.com/ext/-/ext-1.7.0.tgz#0ea4383c0103d60e70be99e9a7f11027a33c4f5f" + integrity sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw== dependencies: - type "^2.5.0" + type "^2.7.2" extend-shallow@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" - integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= + integrity sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug== dependencies: is-extendable "^0.1.0" extend-shallow@^3.0.0, extend-shallow@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" - integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= + integrity sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q== dependencies: assign-symbols "^1.0.0" is-extendable "^1.0.1" @@ -3077,14 +3175,14 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== fast-diff@^1.1.2: - version "1.2.0" - resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" - integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== + version "1.3.0" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.3.0.tgz#ece407fa550a64d638536cd727e129c61616e0f0" + integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw== fast-glob@^3.2.9: - version "3.2.11" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9" - integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew== + version "3.3.1" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.1.tgz#784b4e897340f3dbbef17413b3f11acf03c874c4" + integrity sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg== dependencies: "@nodelib/fs.stat" "^2.0.2" "@nodelib/fs.walk" "^1.2.3" @@ -3100,19 +3198,19 @@ fast-json-stable-stringify@^2.0.0: fast-levenshtein@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== fastq@^1.6.0: - version "1.13.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" - integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== + version "1.15.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" + integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== dependencies: reusify "^1.0.4" fb-watchman@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.1.tgz#fc84fb39d2709cf3ff6d743706157bb5708a8a85" - integrity sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg== + version "2.0.2" + resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.2.tgz#e9524ee6b5c77e9e5001af0f85f3adbb8623255c" + integrity sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA== dependencies: bser "2.1.1" @@ -3138,7 +3236,7 @@ file-entry-cache@^6.0.1: fill-range@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" - integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= + integrity sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ== dependencies: extend-shallow "^2.0.1" is-number "^3.0.0" @@ -3182,13 +3280,6 @@ find-cache-dir@^2.0.0: make-dir "^2.0.0" pkg-dir "^3.0.0" -find-up@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" - integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= - dependencies: - locate-path "^2.0.0" - find-up@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" @@ -3204,6 +3295,14 @@ find-up@^4.0.0, find-up@^4.1.0: locate-path "^5.0.0" path-exists "^4.0.0" +find-up@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + flat-cache@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" @@ -3213,41 +3312,48 @@ flat-cache@^3.0.4: rimraf "^3.0.2" flatted@^3.1.0: - version "3.2.5" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.5.tgz#76c8584f4fc843db64702a6bd04ab7a8bd666da3" - integrity sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg== + version "3.2.7" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787" + integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== flow-parser@0.*: - version "0.176.3" - resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.176.3.tgz#a12d9c79ff1e857b70c9574c3e88be06d2f96181" - integrity sha512-KDzHEoEtc/kbW7NzujhfFkcTCdNi6VK91UpcdT3tc3yEAQdh4JXAEY/0TVJKipjRuVm8E2FxX/3B5Xpm3EFWXA== + version "0.214.0" + resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.214.0.tgz#455efc841ec015c62f6dec022cf6c61480f231a2" + integrity sha512-RW1Dh6BuT14DA7+gtNRKzgzvG3GTPdrceHCi4ddZ9VFGQ9HtO5L8wzxMGsor7XtInIrbWZZCSak0oxnBF7tApw== flow-parser@^0.121.0: version "0.121.0" resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.121.0.tgz#9f9898eaec91a9f7c323e9e992d81ab5c58e618f" integrity sha512-1gIBiWJNR0tKUNv8gZuk7l9rVX06OuLzY9AoGio7y/JT4V1IZErEMEq2TJS+PFcw/y0RshZ1J/27VfK1UQzYVg== +for-each@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" + integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== + dependencies: + is-callable "^1.1.3" + for-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" - integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= + integrity sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ== fragment-cache@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" - integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= + integrity sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA== dependencies: map-cache "^0.2.2" fresh@0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" - integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= + integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== fs-extra@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-1.0.0.tgz#cd3ce5f7e7cb6145883fcae3191e9877f8587950" - integrity sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA= + integrity sha512-VerQV6vEKuhDWD2HGOybV6v5I73syoc/cXAbKlgTC7M/oFVEtklWlp9QH2Ijw3IaWDOQcMkldSPa7zXy79Z/UQ== dependencies: graceful-fs "^4.1.2" jsonfile "^2.1.0" @@ -3272,7 +3378,7 @@ fs-minipass@^2.0.0: fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== fsevents@^2.1.2, fsevents@^2.3.2: version "2.3.2" @@ -3284,10 +3390,20 @@ function-bind@^1.1.1: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== -functional-red-black-tree@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= +function.prototype.name@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.5.tgz#cce0505fe1ffb80503e6f9e46cc64e46a12a9621" + integrity sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.0" + functions-have-names "^1.2.2" + +functions-have-names@^1.2.2, functions-have-names@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" + integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== gauge@^3.0.0: version "3.0.2" @@ -3314,14 +3430,15 @@ get-caller-file@^2.0.1, get-caller-file@^2.0.5: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== -get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" - integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== +get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.1.tgz#d295644fed4505fc9cde952c37ee12b477a83d82" + integrity sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw== dependencies: function-bind "^1.1.1" has "^1.0.3" - has-symbols "^1.0.1" + has-proto "^1.0.1" + has-symbols "^1.0.3" get-package-type@^0.1.0: version "0.1.0" @@ -3363,7 +3480,7 @@ get-uv-event-loop-napi-h@^1.0.5: get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" - integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= + integrity sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA== glob-parent@^5.1.2: version "5.1.2" @@ -3372,7 +3489,7 @@ glob-parent@^5.1.2: dependencies: is-glob "^4.0.1" -glob-parent@^6.0.1: +glob-parent@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== @@ -3380,14 +3497,14 @@ glob-parent@^6.0.1: is-glob "^4.0.3" glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, glob@^7.2.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" - integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" inherits "2" - minimatch "^3.0.4" + minimatch "^3.1.1" once "^1.3.0" path-is-absolute "^1.0.0" @@ -3396,14 +3513,21 @@ globals@^11.1.0: resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== -globals@^13.6.0, globals@^13.9.0: - version "13.13.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.13.0.tgz#ac32261060d8070e2719dd6998406e27d2b5727b" - integrity sha512-EQ7Q18AJlPwp3vUDL4mKA0KXrXyNIQyWon6T6XQiBQF0XHvRsiCSrWmmeATpUzdJN2HhWZU6Pdl0a9zdep5p6A== +globals@^13.19.0: + version "13.20.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.20.0.tgz#ea276a1e508ffd4f1612888f9d1bad1e2717bf82" + integrity sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ== dependencies: type-fest "^0.20.2" -globby@^11.0.4: +globalthis@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.3.tgz#5852882a52b80dc301b0660273e1ed082f0b6ccf" + integrity sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA== + dependencies: + define-properties "^1.1.3" + +globby@^11.1.0: version "11.1.0" resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== @@ -3415,10 +3539,22 @@ globby@^11.0.4: merge2 "^1.4.1" slash "^3.0.0" +gopd@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" + integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== + dependencies: + get-intrinsic "^1.1.3" + graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.3, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.9: - version "4.2.10" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" - integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== + version "4.2.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + +graphemer@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" + integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== has-bigints@^1.0.1, has-bigints@^1.0.2: version "1.0.2" @@ -3428,7 +3564,7 @@ has-bigints@^1.0.1, has-bigints@^1.0.2: has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== has-flag@^4.0.0: version "4.0.0" @@ -3442,7 +3578,12 @@ has-property-descriptors@^1.0.0: dependencies: get-intrinsic "^1.1.1" -has-symbols@^1.0.1, has-symbols@^1.0.2, has-symbols@^1.0.3: +has-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" + integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== + +has-symbols@^1.0.2, has-symbols@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== @@ -3462,7 +3603,7 @@ has-unicode@^2.0.1: has-value@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" - integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= + integrity sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q== dependencies: get-value "^2.0.3" has-values "^0.1.4" @@ -3471,7 +3612,7 @@ has-value@^0.3.1: has-value@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" - integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= + integrity sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw== dependencies: get-value "^2.0.6" has-values "^1.0.0" @@ -3480,12 +3621,12 @@ has-value@^1.0.0: has-values@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" - integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= + integrity sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ== has-values@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" - integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= + integrity sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ== dependencies: is-number "^3.0.0" kind-of "^4.0.0" @@ -3543,10 +3684,10 @@ human-signals@^2.1.0: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== -ignore@^5.1.8, ignore@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" - integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== +ignore@^5.2.0: + version "5.2.4" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" + integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== image-size@^0.6.0: version "0.6.3" @@ -3556,12 +3697,12 @@ image-size@^0.6.0: import-fresh@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" - integrity sha1-2BNVwVYS04bGH53dOSLUMEgipUY= + integrity sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg== dependencies: caller-path "^2.0.0" resolve-from "^3.0.0" -import-fresh@^3.0.0, import-fresh@^3.2.1: +import-fresh@^3.2.1: version "3.3.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== @@ -3580,12 +3721,12 @@ import-local@^3.0.2: imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== dependencies: once "^1.3.0" wrappy "1" @@ -3595,12 +3736,12 @@ inherits@2, inherits@2.0.4, inherits@^2.0.3, inherits@~2.0.3: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== -internal-slot@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" - integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA== +internal-slot@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.5.tgz#f2a2ee21f668f8627a4667f309dc0f4fb6674986" + integrity sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ== dependencies: - get-intrinsic "^1.1.0" + get-intrinsic "^1.2.0" has "^1.0.3" side-channel "^1.0.4" @@ -3612,14 +3753,14 @@ invariant@^2.2.4: loose-envify "^1.0.0" ip@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" - integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= + version "1.1.8" + resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.8.tgz#ae05948f6b075435ed3307acce04629da8cdbf48" + integrity sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg== is-accessor-descriptor@^0.1.6: version "0.1.6" resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" - integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= + integrity sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A== dependencies: kind-of "^3.0.2" @@ -3630,10 +3771,19 @@ is-accessor-descriptor@^1.0.0: dependencies: kind-of "^6.0.0" +is-array-buffer@^3.0.1, is-array-buffer@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.2.tgz#f2653ced8412081638ecb0ebbd0c41c6e0aecbbe" + integrity sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.2.0" + is-typed-array "^1.1.10" + is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= + integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== is-bigint@^1.0.1: version "1.0.4" @@ -3655,10 +3805,10 @@ is-buffer@^1.1.5: resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== -is-callable@^1.1.4, is-callable@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945" - integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w== +is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" + integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== is-ci@^2.0.0: version "2.0.0" @@ -3667,17 +3817,17 @@ is-ci@^2.0.0: dependencies: ci-info "^2.0.0" -is-core-module@^2.8.1: - version "2.9.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.9.0.tgz#e1c34429cd51c6dd9e09e0799e396e27b19a9c69" - integrity sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A== +is-core-module@^2.12.1, is-core-module@^2.13.0: + version "2.13.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.0.tgz#bb52aa6e2cbd49a30c2ba68c42bf3435ba6072db" + integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ== dependencies: has "^1.0.3" is-data-descriptor@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" - integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= + integrity sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg== dependencies: kind-of "^3.0.2" @@ -3716,12 +3866,12 @@ is-descriptor@^1.0.0, is-descriptor@^1.0.2: is-directory@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" - integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= + integrity sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw== is-extendable@^0.1.0, is-extendable@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" - integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= + integrity sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw== is-extendable@^1.0.1: version "1.0.1" @@ -3733,12 +3883,12 @@ is-extendable@^1.0.1: is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== is-fullwidth-code-point@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= + integrity sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w== is-fullwidth-code-point@^3.0.0: version "3.0.0" @@ -3772,7 +3922,7 @@ is-number-object@^1.0.4: is-number@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" - integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= + integrity sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg== dependencies: kind-of "^3.0.2" @@ -3781,6 +3931,11 @@ is-number@^7.0.0: resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== +is-path-inside@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== + is-plain-object@^2.0.3, is-plain-object@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" @@ -3806,7 +3961,7 @@ is-shared-array-buffer@^1.0.2: is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" - integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= + integrity sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ== is-stream@^2.0.0: version "2.0.1" @@ -3827,6 +3982,13 @@ is-symbol@^1.0.2, is-symbol@^1.0.3: dependencies: has-symbols "^1.0.2" +is-typed-array@^1.1.10, is-typed-array@^1.1.9: + version "1.1.12" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.12.tgz#d0bab5686ef4a76f7a73097b95470ab199c57d4a" + integrity sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg== + dependencies: + which-typed-array "^1.1.11" + is-weakref@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" @@ -3842,29 +4004,34 @@ is-windows@^1.0.2: is-wsl@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" - integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= + integrity sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw== isarray@1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== + +isarray@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" + integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== isobject@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" - integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= + integrity sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA== dependencies: isarray "1.0.0" isobject@^3.0.0, isobject@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" - integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= + integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: version "3.2.0" @@ -3872,9 +4039,9 @@ istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.0.tgz#31d18bdd127f825dd02ea7bfdfd906f8ab840e9f" - integrity sha512-6Lthe1hqXHBNsqvgDzGO6l03XNeu3CrG4RqQ1KM9+l5+jNGpEJfIELx1NS3SEHmJQA8np/u+E4EPRKRiu6m19A== + version "5.2.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz#d10c8885c2125574e1c231cacadf955675e1ce3d" + integrity sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg== dependencies: "@babel/core" "^7.12.3" "@babel/parser" "^7.14.7" @@ -3883,12 +4050,12 @@ istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: semver "^6.3.0" istanbul-lib-report@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#7518fe52ea44de372f460a76b5ecda9ffb73d8a6" - integrity sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw== + version "3.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz#908305bac9a5bd175ac6a74489eafd0fc2445a7d" + integrity sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw== dependencies: istanbul-lib-coverage "^3.0.0" - make-dir "^3.0.0" + make-dir "^4.0.0" supports-color "^7.1.0" istanbul-lib-source-maps@^4.0.0: @@ -3901,89 +4068,89 @@ istanbul-lib-source-maps@^4.0.0: source-map "^0.6.1" istanbul-reports@^3.1.3: - version "3.1.4" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.4.tgz#1b6f068ecbc6c331040aab5741991273e609e40c" - integrity sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw== + version "3.1.6" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.6.tgz#2544bcab4768154281a2f0870471902704ccaa1a" + integrity sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg== dependencies: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" -jest-changed-files@^28.0.2: - version "28.0.2" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-28.0.2.tgz#7d7810660a5bd043af9e9cfbe4d58adb05e91531" - integrity sha512-QX9u+5I2s54ZnGoMEjiM2WeBvJR2J7w/8ZUmH2um/WLAuGAYFQcsVXY9+1YL6k0H/AGUdH8pXUAv6erDqEsvIA== +jest-changed-files@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-28.1.3.tgz#d9aeee6792be3686c47cb988a8eaf82ff4238831" + integrity sha512-esaOfUWJXk2nfZt9SPyC8gA1kNfdKLkQWyzsMlqq8msYSlNKfmZxfRgZn4Cd4MGVUF+7v6dBs0d5TOAKa7iIiA== dependencies: execa "^5.0.0" - throat "^6.0.1" + p-limit "^3.1.0" -jest-circus@^28.0.3: - version "28.0.3" - resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-28.0.3.tgz#45f77090b4b9fe5c1b84f72816868c9d4c0f57b1" - integrity sha512-HJ3rUCm3A3faSy7KVH5MFCncqJLtrjEFkTPn9UIcs4Kq77+TXqHsOaI+/k73aHe6DJQigLUXq9rCYj3MYFlbIw== +jest-circus@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-28.1.3.tgz#d14bd11cf8ee1a03d69902dc47b6bd4634ee00e4" + integrity sha512-cZ+eS5zc79MBwt+IhQhiEp0OeBddpc1n8MBo1nMB8A7oPMKEO+Sre+wHaLJexQUj9Ya/8NOBY0RESUgYjB6fow== dependencies: - "@jest/environment" "^28.0.2" - "@jest/expect" "^28.0.3" - "@jest/test-result" "^28.0.2" - "@jest/types" "^28.0.2" + "@jest/environment" "^28.1.3" + "@jest/expect" "^28.1.3" + "@jest/test-result" "^28.1.3" + "@jest/types" "^28.1.3" "@types/node" "*" chalk "^4.0.0" co "^4.6.0" dedent "^0.7.0" is-generator-fn "^2.0.0" - jest-each "^28.0.2" - jest-matcher-utils "^28.0.2" - jest-message-util "^28.0.2" - jest-runtime "^28.0.3" - jest-snapshot "^28.0.3" - jest-util "^28.0.2" - pretty-format "^28.0.2" + jest-each "^28.1.3" + jest-matcher-utils "^28.1.3" + jest-message-util "^28.1.3" + jest-runtime "^28.1.3" + jest-snapshot "^28.1.3" + jest-util "^28.1.3" + p-limit "^3.1.0" + pretty-format "^28.1.3" slash "^3.0.0" stack-utils "^2.0.3" - throat "^6.0.1" -jest-cli@^28.0.3: - version "28.0.3" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-28.0.3.tgz#4a4e55078ec772e0ea2583dd4c4b38fb306dc556" - integrity sha512-NCPTEONCnhYGo1qzPP4OOcGF04YasM5GZSwQLI1HtEluxa3ct4U65IbZs6DSRt8XN1Rq0jhXwv02m5lHB28Uyg== +jest-cli@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-28.1.3.tgz#558b33c577d06de55087b8448d373b9f654e46b2" + integrity sha512-roY3kvrv57Azn1yPgdTebPAXvdR2xfezaKKYzVxZ6It/5NCxzJym6tUI5P1zkdWhfUYkxEI9uZWcQdaFLo8mJQ== dependencies: - "@jest/core" "^28.0.3" - "@jest/test-result" "^28.0.2" - "@jest/types" "^28.0.2" + "@jest/core" "^28.1.3" + "@jest/test-result" "^28.1.3" + "@jest/types" "^28.1.3" chalk "^4.0.0" exit "^0.1.2" graceful-fs "^4.2.9" import-local "^3.0.2" - jest-config "^28.0.3" - jest-util "^28.0.2" - jest-validate "^28.0.2" + jest-config "^28.1.3" + jest-util "^28.1.3" + jest-validate "^28.1.3" prompts "^2.0.1" yargs "^17.3.1" -jest-config@^28.0.3: - version "28.0.3" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-28.0.3.tgz#9c0556d60d692153a6bc8652974182c22db9244f" - integrity sha512-3gWOEHwGpNhyYOk9vnUMv94x15QcdjACm7A3lERaluwnyD6d1WZWe9RFCShgIXVOHzRfG1hWxsI2U0gKKSGgDQ== +jest-config@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-28.1.3.tgz#e315e1f73df3cac31447eed8b8740a477392ec60" + integrity sha512-MG3INjByJ0J4AsNBm7T3hsuxKQqFIiRo/AUqb1q9LRKI5UU6Aar9JHbr9Ivn1TVwfUD9KirRoM/T6u8XlcQPHQ== dependencies: "@babel/core" "^7.11.6" - "@jest/test-sequencer" "^28.0.2" - "@jest/types" "^28.0.2" - babel-jest "^28.0.3" + "@jest/test-sequencer" "^28.1.3" + "@jest/types" "^28.1.3" + babel-jest "^28.1.3" chalk "^4.0.0" ci-info "^3.2.0" deepmerge "^4.2.2" glob "^7.1.3" graceful-fs "^4.2.9" - jest-circus "^28.0.3" - jest-environment-node "^28.0.2" + jest-circus "^28.1.3" + jest-environment-node "^28.1.3" jest-get-type "^28.0.2" jest-regex-util "^28.0.2" - jest-resolve "^28.0.3" - jest-runner "^28.0.3" - jest-util "^28.0.2" - jest-validate "^28.0.2" + jest-resolve "^28.1.3" + jest-runner "^28.1.3" + jest-util "^28.1.3" + jest-validate "^28.1.3" micromatch "^4.0.4" parse-json "^5.2.0" - pretty-format "^28.0.2" + pretty-format "^28.1.3" slash "^3.0.0" strip-json-comments "^3.1.1" @@ -3997,45 +4164,45 @@ jest-diff@^27.5.1: jest-get-type "^27.5.1" pretty-format "^27.5.1" -jest-diff@^28.0.2: - version "28.0.2" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-28.0.2.tgz#a543c90082560cd6cb14c5f28c39e6d4618ad7a6" - integrity sha512-33Rnf821Y54OAloav0PGNWHlbtEorXpjwchnToyyWbec10X74FOW7hGfvrXLGz7xOe2dz0uo9JVFAHHj/2B5pg== +jest-diff@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-28.1.3.tgz#948a192d86f4e7a64c5264ad4da4877133d8792f" + integrity sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw== dependencies: chalk "^4.0.0" - diff-sequences "^28.0.2" + diff-sequences "^28.1.1" jest-get-type "^28.0.2" - pretty-format "^28.0.2" + pretty-format "^28.1.3" -jest-docblock@^28.0.2: - version "28.0.2" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-28.0.2.tgz#3cab8abea53275c9d670cdca814fc89fba1298c2" - integrity sha512-FH10WWw5NxLoeSdQlJwu+MTiv60aXV/t8KEwIRGEv74WARE1cXIqh1vGdy2CraHuWOOrnzTWj/azQKqW4fO7xg== +jest-docblock@^28.1.1: + version "28.1.1" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-28.1.1.tgz#6f515c3bf841516d82ecd57a62eed9204c2f42a8" + integrity sha512-3wayBVNiOYx0cwAbl9rwm5kKFP8yHH3d/fkEaL02NPTkDojPtheGB7HZSFY4wzX+DxyrvhXz0KSCVksmCknCuA== dependencies: detect-newline "^3.0.0" -jest-each@^28.0.2: - version "28.0.2" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-28.0.2.tgz#fcf6843e9afe5a3f2d0b1c02aab1f41889d92f1d" - integrity sha512-/W5Wc0b+ipR36kDaLngdVEJ/5UYPOITK7rW0djTlCCQdMuWpCFJweMW4TzAoJ6GiRrljPL8FwiyOSoSHKrda2w== +jest-each@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-28.1.3.tgz#bdd1516edbe2b1f3569cfdad9acd543040028f81" + integrity sha512-arT1z4sg2yABU5uogObVPvSlSMQlDA48owx07BDPAiasW0yYpYHYOo4HHLz9q0BVzDVU4hILFjzJw0So9aCL/g== dependencies: - "@jest/types" "^28.0.2" + "@jest/types" "^28.1.3" chalk "^4.0.0" jest-get-type "^28.0.2" - jest-util "^28.0.2" - pretty-format "^28.0.2" + jest-util "^28.1.3" + pretty-format "^28.1.3" -jest-environment-node@^28.0.2: - version "28.0.2" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-28.0.2.tgz#bd58e192b8f36a37e52c52fac812bd24b360c0b9" - integrity sha512-o9u5UHZ+NCuIoa44KEF0Behhsz/p1wMm0WumsZfWR1k4IVoWSt3aN0BavSC5dd26VxSGQvkrCnJxxOzhhUEG3Q== +jest-environment-node@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-28.1.3.tgz#7e74fe40eb645b9d56c0c4b70ca4357faa349be5" + integrity sha512-ugP6XOhEpjAEhGYvp5Xj989ns5cB1K6ZdjBYuS30umT4CQEETaxSiPcZ/E1kFktX4GkrcM4qu07IIlDYX1gp+A== dependencies: - "@jest/environment" "^28.0.2" - "@jest/fake-timers" "^28.0.2" - "@jest/types" "^28.0.2" + "@jest/environment" "^28.1.3" + "@jest/fake-timers" "^28.1.3" + "@jest/types" "^28.1.3" "@types/node" "*" - jest-mock "^28.0.2" - jest-util "^28.0.2" + jest-mock "^28.1.3" + jest-util "^28.1.3" jest-get-type@^26.3.0: version "26.3.0" @@ -4073,32 +4240,32 @@ jest-haste-map@^26.5.2: optionalDependencies: fsevents "^2.1.2" -jest-haste-map@^28.0.2: - version "28.0.2" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-28.0.2.tgz#0c768f43680013cfd2a4471a3ec76c47bfb9e7c6" - integrity sha512-EokdL7l5uk4TqWGawwrIt8w3tZNcbeiRxmKGEURf42pl+/rWJy3sCJlon5HBhJXZTW978jk6600BLQOI7i25Ig== +jest-haste-map@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-28.1.3.tgz#abd5451129a38d9841049644f34b034308944e2b" + integrity sha512-3S+RQWDXccXDKSWnkHa/dPwt+2qwA8CJzR61w3FoYCvoo3Pn8tvGcysmMF0Bj0EX5RYvAI2EIvC57OmotfdtKA== dependencies: - "@jest/types" "^28.0.2" + "@jest/types" "^28.1.3" "@types/graceful-fs" "^4.1.3" "@types/node" "*" anymatch "^3.0.3" fb-watchman "^2.0.0" graceful-fs "^4.2.9" jest-regex-util "^28.0.2" - jest-util "^28.0.2" - jest-worker "^28.0.2" + jest-util "^28.1.3" + jest-worker "^28.1.3" micromatch "^4.0.4" - walker "^1.0.7" + walker "^1.0.8" optionalDependencies: fsevents "^2.3.2" -jest-leak-detector@^28.0.2: - version "28.0.2" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-28.0.2.tgz#cbde3d22d09bd690ececdc2ed01c608435328456" - integrity sha512-UGaSPYtxKXl/YKacq6juRAKmMp1z2os8NaU8PSC+xvNikmu3wF6QFrXrihMM4hXeMr9HuNotBrQZHmzDY8KIBQ== +jest-leak-detector@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-28.1.3.tgz#a6685d9b074be99e3adee816ce84fd30795e654d" + integrity sha512-WFVJhnQsiKtDEo5lG2mM0v40QWnBM+zMdHHyJs8AWZ7J0QZJS59MsyKeJHWhpBZBH32S48FOVvGyOFT1h0DlqA== dependencies: jest-get-type "^28.0.2" - pretty-format "^28.0.2" + pretty-format "^28.1.3" jest-matcher-utils@^27.0.0: version "27.5.1" @@ -4110,43 +4277,43 @@ jest-matcher-utils@^27.0.0: jest-get-type "^27.5.1" pretty-format "^27.5.1" -jest-matcher-utils@^28.0.2: - version "28.0.2" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-28.0.2.tgz#eb461af204b6d0f05281e9228094f0ab7e9e8537" - integrity sha512-SxtTiI2qLJHFtOz/bySStCnwCvISAuxQ/grS+74dfTy5AuJw3Sgj9TVUvskcnImTfpzLoMCDJseRaeRrVYbAOA== +jest-matcher-utils@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-28.1.3.tgz#5a77f1c129dd5ba3b4d7fc20728806c78893146e" + integrity sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw== dependencies: chalk "^4.0.0" - jest-diff "^28.0.2" + jest-diff "^28.1.3" jest-get-type "^28.0.2" - pretty-format "^28.0.2" + pretty-format "^28.1.3" -jest-message-util@^28.0.2: - version "28.0.2" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-28.0.2.tgz#f3cf36be72be4c4c4058cb34bd6673996d26dee3" - integrity sha512-knK7XyojvwYh1XiF2wmVdskgM/uN11KsjcEWWHfnMZNEdwXCrqB4sCBO94F4cfiAwCS8WFV6CDixDwPlMh/wdA== +jest-message-util@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-28.1.3.tgz#232def7f2e333f1eecc90649b5b94b0055e7c43d" + integrity sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g== dependencies: "@babel/code-frame" "^7.12.13" - "@jest/types" "^28.0.2" + "@jest/types" "^28.1.3" "@types/stack-utils" "^2.0.0" chalk "^4.0.0" graceful-fs "^4.2.9" micromatch "^4.0.4" - pretty-format "^28.0.2" + pretty-format "^28.1.3" slash "^3.0.0" stack-utils "^2.0.3" -jest-mock@^28.0.2: - version "28.0.2" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-28.0.2.tgz#059b500b34c1dd76474ebcdeccc249fe4dd0249f" - integrity sha512-vfnJ4zXRB0i24jOTGtQJyl26JKsgBKtqRlCnsrORZbG06FToSSn33h2x/bmE8XxqxkLWdZBRo+/65l8Vi3nD+g== +jest-mock@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-28.1.3.tgz#d4e9b1fc838bea595c77ab73672ebf513ab249da" + integrity sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA== dependencies: - "@jest/types" "^28.0.2" + "@jest/types" "^28.1.3" "@types/node" "*" jest-pnp-resolver@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c" - integrity sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w== + version "1.2.3" + resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz#930b1546164d4ad5937d5540e711d4d38d4cad2e" + integrity sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w== jest-regex-util@^26.0.0: version "26.0.0" @@ -4158,81 +4325,81 @@ jest-regex-util@^28.0.2: resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-28.0.2.tgz#afdc377a3b25fb6e80825adcf76c854e5bf47ead" integrity sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw== -jest-resolve-dependencies@^28.0.3: - version "28.0.3" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-28.0.3.tgz#76d8f59f7e76ba36d76a1677eeaaed24560da7e0" - integrity sha512-lCgHMm0/5p0qHemrOzm7kI6JDei28xJwIf7XOEcv1HeAVHnsON8B8jO/woqlU+/GcOXb58ymieYqhk3zjGWnvQ== +jest-resolve-dependencies@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-28.1.3.tgz#8c65d7583460df7275c6ea2791901fa975c1fe66" + integrity sha512-qa0QO2Q0XzQoNPouMbCc7Bvtsem8eQgVPNkwn9LnS+R2n8DaVDPL/U1gngC0LTl1RYXJU0uJa2BMC2DbTfFrHA== dependencies: jest-regex-util "^28.0.2" - jest-snapshot "^28.0.3" + jest-snapshot "^28.1.3" -jest-resolve@^28.0.3: - version "28.0.3" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-28.0.3.tgz#63f8e6b53e40f265b3ca9116195221dd43e3d16d" - integrity sha512-lfgjd9JhEjpjIN3HLUfdysdK+A7ePQoYmd7WL9DUEWqdnngb1rF56eee6iDXJxl/3eSolpP43VD7VrhjL3NsoQ== +jest-resolve@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-28.1.3.tgz#cfb36100341ddbb061ec781426b3c31eb51aa0a8" + integrity sha512-Z1W3tTjE6QaNI90qo/BJpfnvpxtaFTFw5CDgwpyE/Kz8U/06N1Hjf4ia9quUhCh39qIGWF1ZuxFiBiJQwSEYKQ== dependencies: chalk "^4.0.0" graceful-fs "^4.2.9" - jest-haste-map "^28.0.2" + jest-haste-map "^28.1.3" jest-pnp-resolver "^1.2.2" - jest-util "^28.0.2" - jest-validate "^28.0.2" + jest-util "^28.1.3" + jest-validate "^28.1.3" resolve "^1.20.0" resolve.exports "^1.1.0" slash "^3.0.0" -jest-runner@^28.0.3: - version "28.0.3" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-28.0.3.tgz#a8a409c685ad3081a44b149b2eb04bc4d47faaf9" - integrity sha512-4OsHMjBLtYUWCENucAQ4Za0jGfEbOFi/Fusv6dzUuaweqx8apb4+5p2LR2yvgF4StFulmxyC238tGLftfu+zBA== +jest-runner@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-28.1.3.tgz#5eee25febd730b4713a2cdfd76bdd5557840f9a1" + integrity sha512-GkMw4D/0USd62OVO0oEgjn23TM+YJa2U2Wu5zz9xsQB1MxWKDOlrnykPxnMsN0tnJllfLPinHTka61u0QhaxBA== dependencies: - "@jest/console" "^28.0.2" - "@jest/environment" "^28.0.2" - "@jest/test-result" "^28.0.2" - "@jest/transform" "^28.0.3" - "@jest/types" "^28.0.2" + "@jest/console" "^28.1.3" + "@jest/environment" "^28.1.3" + "@jest/test-result" "^28.1.3" + "@jest/transform" "^28.1.3" + "@jest/types" "^28.1.3" "@types/node" "*" chalk "^4.0.0" emittery "^0.10.2" graceful-fs "^4.2.9" - jest-docblock "^28.0.2" - jest-environment-node "^28.0.2" - jest-haste-map "^28.0.2" - jest-leak-detector "^28.0.2" - jest-message-util "^28.0.2" - jest-resolve "^28.0.3" - jest-runtime "^28.0.3" - jest-util "^28.0.2" - jest-watcher "^28.0.2" - jest-worker "^28.0.2" + jest-docblock "^28.1.1" + jest-environment-node "^28.1.3" + jest-haste-map "^28.1.3" + jest-leak-detector "^28.1.3" + jest-message-util "^28.1.3" + jest-resolve "^28.1.3" + jest-runtime "^28.1.3" + jest-util "^28.1.3" + jest-watcher "^28.1.3" + jest-worker "^28.1.3" + p-limit "^3.1.0" source-map-support "0.5.13" - throat "^6.0.1" - -jest-runtime@^28.0.3: - version "28.0.3" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-28.0.3.tgz#02346a34de0ac61d23bdb0e8c035ad973d7bb087" - integrity sha512-7FtPUmvbZEHLOdjsF6dyHg5Pe4E0DU+f3Vvv8BPzVR7mQA6nFR4clQYLAPyJGnsUvN8WRWn+b5a5SVwnj1WaGg== - dependencies: - "@jest/environment" "^28.0.2" - "@jest/fake-timers" "^28.0.2" - "@jest/globals" "^28.0.3" - "@jest/source-map" "^28.0.2" - "@jest/test-result" "^28.0.2" - "@jest/transform" "^28.0.3" - "@jest/types" "^28.0.2" + +jest-runtime@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-28.1.3.tgz#a57643458235aa53e8ec7821949e728960d0605f" + integrity sha512-NU+881ScBQQLc1JHG5eJGU7Ui3kLKrmwCPPtYsJtBykixrM2OhVQlpMmFWJjMyDfdkGgBMNjXCGB/ebzsgNGQw== + dependencies: + "@jest/environment" "^28.1.3" + "@jest/fake-timers" "^28.1.3" + "@jest/globals" "^28.1.3" + "@jest/source-map" "^28.1.2" + "@jest/test-result" "^28.1.3" + "@jest/transform" "^28.1.3" + "@jest/types" "^28.1.3" chalk "^4.0.0" cjs-module-lexer "^1.0.0" collect-v8-coverage "^1.0.0" execa "^5.0.0" glob "^7.1.3" graceful-fs "^4.2.9" - jest-haste-map "^28.0.2" - jest-message-util "^28.0.2" - jest-mock "^28.0.2" + jest-haste-map "^28.1.3" + jest-message-util "^28.1.3" + jest-mock "^28.1.3" jest-regex-util "^28.0.2" - jest-resolve "^28.0.3" - jest-snapshot "^28.0.3" - jest-util "^28.0.2" + jest-resolve "^28.1.3" + jest-snapshot "^28.1.3" + jest-util "^28.1.3" slash "^3.0.0" strip-bom "^4.0.0" @@ -4244,33 +4411,33 @@ jest-serializer@^26.6.2: "@types/node" "*" graceful-fs "^4.2.4" -jest-snapshot@^28.0.3: - version "28.0.3" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-28.0.3.tgz#9a768d0c617d070e87c1bd37240f22b344616154" - integrity sha512-nVzAAIlAbrMuvVUrS1YxmAeo1TfSsDDU+K5wv/Ow56MBp+L+Y71ksAbwRp3kGCgZAz4oOXcAMPAwtT9Yh1hlQQ== +jest-snapshot@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-28.1.3.tgz#17467b3ab8ddb81e2f605db05583d69388fc0668" + integrity sha512-4lzMgtiNlc3DU/8lZfmqxN3AYD6GGLbl+72rdBpXvcV+whX7mDrREzkPdp2RnmfIiWBg1YbuFSkXduF2JcafJg== dependencies: "@babel/core" "^7.11.6" "@babel/generator" "^7.7.2" "@babel/plugin-syntax-typescript" "^7.7.2" "@babel/traverse" "^7.7.2" "@babel/types" "^7.3.3" - "@jest/expect-utils" "^28.0.2" - "@jest/transform" "^28.0.3" - "@jest/types" "^28.0.2" + "@jest/expect-utils" "^28.1.3" + "@jest/transform" "^28.1.3" + "@jest/types" "^28.1.3" "@types/babel__traverse" "^7.0.6" "@types/prettier" "^2.1.5" babel-preset-current-node-syntax "^1.0.0" chalk "^4.0.0" - expect "^28.0.2" + expect "^28.1.3" graceful-fs "^4.2.9" - jest-diff "^28.0.2" + jest-diff "^28.1.3" jest-get-type "^28.0.2" - jest-haste-map "^28.0.2" - jest-matcher-utils "^28.0.2" - jest-message-util "^28.0.2" - jest-util "^28.0.2" + jest-haste-map "^28.1.3" + jest-matcher-utils "^28.1.3" + jest-message-util "^28.1.3" + jest-util "^28.1.3" natural-compare "^1.4.0" - pretty-format "^28.0.2" + pretty-format "^28.1.3" semver "^7.3.5" jest-util@^26.6.2: @@ -4285,12 +4452,12 @@ jest-util@^26.6.2: is-ci "^2.0.0" micromatch "^4.0.2" -jest-util@^28.0.2: - version "28.0.2" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-28.0.2.tgz#8e22cdd6e0549e0a393055f0e2da7eacc334b143" - integrity sha512-EVdpIRCC8lzqhp9A0u0aAKlsFIzufK6xKxNK7awsnebTdOP4hpyQW5o6Ox2qPl8gbeUKYF+POLyItaND53kpGA== +jest-util@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-28.1.3.tgz#f4f932aa0074f0679943220ff9cbba7e497028b0" + integrity sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ== dependencies: - "@jest/types" "^28.0.2" + "@jest/types" "^28.1.3" "@types/node" "*" chalk "^4.0.0" ci-info "^3.2.0" @@ -4309,30 +4476,30 @@ jest-validate@^26.5.2: leven "^3.1.0" pretty-format "^26.6.2" -jest-validate@^28.0.2: - version "28.0.2" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-28.0.2.tgz#58bb7e826c054a8bb3b54c05f73758d96cf6dbef" - integrity sha512-nr0UOvCTtxP0YPdsk01Gk7e7c0xIiEe2nncAe3pj0wBfUvAykTVrMrdeASlAJnlEQCBuwN/GF4hKoCzbkGNCNw== +jest-validate@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-28.1.3.tgz#e322267fd5e7c64cea4629612c357bbda96229df" + integrity sha512-SZbOGBWEsaTxBGCOpsRWlXlvNkvTkY0XxRfh7zYmvd8uL5Qzyg0CHAXiXKROflh801quA6+/DsT4ODDthOC/OA== dependencies: - "@jest/types" "^28.0.2" + "@jest/types" "^28.1.3" camelcase "^6.2.0" chalk "^4.0.0" jest-get-type "^28.0.2" leven "^3.1.0" - pretty-format "^28.0.2" + pretty-format "^28.1.3" -jest-watcher@^28.0.2: - version "28.0.2" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-28.0.2.tgz#649fa24df531d4071be5784b6274d494d788c88b" - integrity sha512-uIVJLpQ/5VTGQWBiBatHsi7jrCqHjHl0e0dFHMWzwuIfUbdW/muk0DtSr0fteY2T7QTFylv+7a5Rm8sBKrE12Q== +jest-watcher@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-28.1.3.tgz#c6023a59ba2255e3b4c57179fc94164b3e73abd4" + integrity sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g== dependencies: - "@jest/test-result" "^28.0.2" - "@jest/types" "^28.0.2" + "@jest/test-result" "^28.1.3" + "@jest/types" "^28.1.3" "@types/node" "*" ansi-escapes "^4.2.1" chalk "^4.0.0" emittery "^0.10.2" - jest-util "^28.0.2" + jest-util "^28.1.3" string-length "^4.0.1" jest-worker@^26.0.0, jest-worker@^26.6.2: @@ -4344,23 +4511,24 @@ jest-worker@^26.0.0, jest-worker@^26.6.2: merge-stream "^2.0.0" supports-color "^7.0.0" -jest-worker@^28.0.2: - version "28.0.2" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-28.0.2.tgz#75f7e5126541289ba02e9c1a67e46349ddb8141d" - integrity sha512-pijNxfjxT0tGAx+8+OzZ+eayVPCwy/rsZFhebmC0F4YnXu1EHPEPxg7utL3m5uX3EaFH1/jwDxGa1EbjJCST2g== +jest-worker@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-28.1.3.tgz#7e3c4ce3fa23d1bb6accb169e7f396f98ed4bb98" + integrity sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g== dependencies: "@types/node" "*" merge-stream "^2.0.0" supports-color "^8.0.0" jest@^28.0.2: - version "28.0.3" - resolved "https://registry.yarnpkg.com/jest/-/jest-28.0.3.tgz#92a7d6ee097b61de4ba2db7f3ab723e81a99b32d" - integrity sha512-uS+T5J3w5xyzd1KSJCGKhCo8WTJXbNl86f5SW11wgssbandJOVLRKKUxmhdFfmKxhPeksl1hHZ0HaA8VBzp7xA== + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest/-/jest-28.1.3.tgz#e9c6a7eecdebe3548ca2b18894a50f45b36dfc6b" + integrity sha512-N4GT5on8UkZgH0O5LUavMRV1EDEhNTL0KEfRmDIeZHSV7p2XgLoY9t9VDUgL6o+yfdgYHVxuz81G8oB9VG5uyA== dependencies: - "@jest/core" "^28.0.3" + "@jest/core" "^28.1.3" + "@jest/types" "^28.1.3" import-local "^3.0.2" - jest-cli "^28.0.3" + jest-cli "^28.1.3" jetifier@^1.6.2: version "1.6.8" @@ -4368,14 +4536,14 @@ jetifier@^1.6.2: integrity sha512-3Zi16h6L5tXDRQJTb221cnRoVG9/9OvreLdLU2/ZjRv/GILL+2Cemt0IKvkowwkDpvouAU1DQPOJ7qaiHeIdrw== joi@^17.2.1: - version "17.6.0" - resolved "https://registry.yarnpkg.com/joi/-/joi-17.6.0.tgz#0bb54f2f006c09a96e75ce687957bd04290054b2" - integrity sha512-OX5dG6DTbcr/kbMFj0KGYxuew69HPcAE3K/sZpEV2nP6e/j/C0HV+HNiBPCASxdx5T7DMoa0s8UeHWMnb6n2zw== + version "17.9.2" + resolved "https://registry.yarnpkg.com/joi/-/joi-17.9.2.tgz#8b2e4724188369f55451aebd1d0b1d9482470690" + integrity sha512-Itk/r+V4Dx0V3c7RLFdRh12IOjySm2/WGPMubBT92cQvRfYZhPM2W0hZlctjj72iES8jsRCwp7S/cRmWBnJ4nw== dependencies: "@hapi/hoek" "^9.0.0" "@hapi/topo" "^5.0.0" "@sideway/address" "^4.1.3" - "@sideway/formula" "^3.0.0" + "@sideway/formula" "^3.0.1" "@sideway/pinpoint" "^2.0.0" "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: @@ -4436,7 +4604,7 @@ jsesc@^2.5.1: jsesc@~0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" - integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= + integrity sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA== json-parse-better-errors@^1.0.1: version "1.0.2" @@ -4456,55 +4624,50 @@ json-schema-traverse@^0.4.1: json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" - integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= + integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== json5@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" - integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE= + integrity sha512-4xrs1aW+6N5DalkqSVA8fxh458CXvR99WU8WLKmq4v8eWAL86Xo3BVqyd3SkA9wEVjCMqyvvRRkshAdOnBp5rw== -json5@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" - integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== +json5@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593" + integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA== dependencies: minimist "^1.2.0" -json5@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" - integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== +json5@^2.2.2: + version "2.2.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== jsonfile@^2.1.0: version "2.4.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" - integrity sha1-NzaitCi4e72gzIO1P6PWM6NcKug= + integrity sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw== optionalDependencies: graceful-fs "^4.1.6" jsonfile@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" - integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= + integrity sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg== optionalDependencies: graceful-fs "^4.1.6" -jsonify@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" - integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= - kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" - integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= + integrity sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ== dependencies: is-buffer "^1.1.5" kind-of@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" - integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= + integrity sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw== dependencies: is-buffer "^1.1.5" @@ -4521,7 +4684,7 @@ kind-of@^6.0.0, kind-of@^6.0.2: klaw@^1.0.0: version "1.3.1" resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439" - integrity sha1-QIhDO0azsbolnXh4XY6W9zugJDk= + integrity sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw== optionalDependencies: graceful-fs "^4.1.9" @@ -4548,14 +4711,6 @@ lines-and-columns@^1.1.6: resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== -locate-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" - integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= - dependencies: - p-locate "^2.0.0" - path-exists "^3.0.0" - locate-path@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" @@ -4571,10 +4726,17 @@ locate-path@^5.0.0: dependencies: p-locate "^4.1.0" +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + lodash.debounce@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" - integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= + integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== lodash.merge@^4.6.2: version "4.6.2" @@ -4584,7 +4746,7 @@ lodash.merge@^4.6.2: lodash.throttle@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4" - integrity sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ= + integrity sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ== lodash@^4.17.14, lodash@^4.17.15: version "4.17.21" @@ -4614,6 +4776,13 @@ loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0: dependencies: js-tokens "^3.0.0 || ^4.0.0" +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + lru-cache@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" @@ -4629,13 +4798,20 @@ make-dir@^2.0.0, make-dir@^2.1.0: pify "^4.0.1" semver "^5.6.0" -make-dir@^3.0.0, make-dir@^3.1.0: +make-dir@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== dependencies: semver "^6.0.0" +make-dir@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-4.0.0.tgz#c3c2307a771277cd9638305f915c29ae741b614e" + integrity sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw== + dependencies: + semver "^7.5.3" + make-error@^1.1.1: version "1.3.6" resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" @@ -4651,12 +4827,12 @@ makeerror@1.0.12: map-cache@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" - integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= + integrity sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg== map-visit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" - integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= + integrity sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w== dependencies: object-visit "^1.0.0" @@ -4995,7 +5171,7 @@ mimic-fn@^2.1.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== -minimatch@^3.0.2, minimatch@^3.0.4, minimatch@^3.1.2: +minimatch@^3.0.2, minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== @@ -5003,17 +5179,22 @@ minimatch@^3.0.2, minimatch@^3.0.4, minimatch@^3.1.2: brace-expansion "^1.1.7" minimist@^1.1.1, minimist@^1.2.0, minimist@^1.2.6: - version "1.2.6" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" - integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== + version "1.2.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== minipass@^3.0.0: - version "3.3.4" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.4.tgz#ca99f95dd77c43c7a76bf51e6d200025eee0ffae" - integrity sha512-I9WPbWHCGu8W+6k1ZiGpPu0GkoKBeorkfKNuAFBNS1HNFJvke82sxvI5bzcCNpWPorkOO5QQ+zomzzwRxejXiw== + version "3.3.6" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.6.tgz#7bba384db3a1520d18c9c0e5251c3444e95dd94a" + integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw== dependencies: yallist "^4.0.0" +minipass@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-5.0.0.tgz#3e9788ffb90b694a5d0ec94479a45b5d8738133d" + integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ== + minizlib@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" @@ -5045,7 +5226,7 @@ mkdirp@^1.0.3: ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== ms@2.1.2: version "2.1.2" @@ -5074,10 +5255,15 @@ nanomatch@^1.2.9: snapdragon "^0.8.1" to-regex "^3.0.1" +natural-compare-lite@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz#17b09581988979fddafe0201e931ba933c96cbb4" + integrity sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g== + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= + integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== negotiator@0.6.3: version "0.6.3" @@ -5112,31 +5298,31 @@ node-addon-api@^3.0.0: node-dir@^0.1.17: version "0.1.17" resolved "https://registry.yarnpkg.com/node-dir/-/node-dir-0.1.17.tgz#5f5665d93351335caabef8f1c554516cf5f1e4e5" - integrity sha1-X1Zl2TNRM1yqvvjxxVRRbPXx5OU= + integrity sha512-tmPX422rYgofd4epzrNoOXiE8XFZYOcCq1vD7MAXCDO+O+zndlA2ztdKKMa+EeuBG5tHETpr4ml4RGgpqDCCAg== dependencies: minimatch "^3.0.2" node-fetch@^2.2.0, node-fetch@^2.6.0, node-fetch@^2.6.7: - version "2.6.7" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" - integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== + version "2.6.12" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.12.tgz#02eb8e22074018e3d5a83016649d04df0e348fba" + integrity sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g== dependencies: whatwg-url "^5.0.0" node-gyp-build@^4.2.1: - version "4.4.0" - resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.4.0.tgz#42e99687ce87ddeaf3a10b99dc06abc11021f3f4" - integrity sha512-amJnQCcgtRVw9SvoebO3BKGESClrfXGCUTX9hSn1OuGQTQBOZmVd0Z0OlecpuRksKvbsUqALE8jls/ErClAPuQ== + version "4.6.0" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.6.0.tgz#0c52e4cbf54bbd28b709820ef7b6a3c2d6209055" + integrity sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ== node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" - integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs= + integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== -node-releases@^2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.4.tgz#f38252370c43854dc48aa431c766c6c398f40476" - integrity sha512-gbMzqQtTtDz/00jQzZ21PQzdI9PyLYqUSvD0p3naOhX4odFji0ZxYdnVwPTxmSwkmxhcFImpozceidSG+AgoPQ== +node-releases@^2.0.13: + version "2.0.13" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.13.tgz#d5ed1627c23e3461e819b02e57b75e4899b1c81d" + integrity sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ== node-stream-zip@^1.9.1: version "1.15.0" @@ -5153,7 +5339,7 @@ nopt@^5.0.0: normalize-path@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" - integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= + integrity sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w== dependencies: remove-trailing-separator "^1.0.1" @@ -5165,7 +5351,7 @@ normalize-path@^3.0.0: npm-run-path@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" - integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= + integrity sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw== dependencies: path-key "^2.0.0" @@ -5199,21 +5385,21 @@ ob1@0.66.2: object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== object-copy@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" - integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= + integrity sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ== dependencies: copy-descriptor "^0.1.0" define-property "^0.2.5" kind-of "^3.0.3" -object-inspect@^1.12.0, object-inspect@^1.9.0: - version "1.12.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.0.tgz#6e2c120e868fd1fd18cb4f18c31741d0d6e776f0" - integrity sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g== +object-inspect@^1.12.3, object-inspect@^1.9.0: + version "1.12.3" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.3.tgz#ba62dffd67ee256c8c086dfae69e016cd1f198b9" + integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g== object-keys@^1.1.1: version "1.1.1" @@ -5223,35 +5409,54 @@ object-keys@^1.1.1: object-visit@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" - integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= + integrity sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA== dependencies: isobject "^3.0.0" -object.assign@^4.1.0, object.assign@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" - integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== +object.assign@^4.1.4: + version "4.1.4" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.4.tgz#9673c7c7c351ab8c4d0b516f4343ebf4dfb7799f" + integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ== dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - has-symbols "^1.0.1" + call-bind "^1.0.2" + define-properties "^1.1.4" + has-symbols "^1.0.3" object-keys "^1.1.1" +object.fromentries@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.6.tgz#cdb04da08c539cffa912dcd368b886e0904bfa73" + integrity sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + +object.groupby@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/object.groupby/-/object.groupby-1.0.0.tgz#cb29259cf90f37e7bac6437686c1ea8c916d12a9" + integrity sha512-70MWG6NfRH9GnbZOikuhPPYzpUpof9iW2J9E4dW7FXTqPNb6rllE6u39SKwwiNh8lCwX3DDb5OgcKGiEBrTTyw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.21.2" + get-intrinsic "^1.2.1" + object.pick@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" - integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= + integrity sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ== dependencies: isobject "^3.0.1" -object.values@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.5.tgz#959f63e3ce9ef108720333082131e4a459b716ac" - integrity sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg== +object.values@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.6.tgz#4abbaa71eba47d63589d402856f908243eea9b1d" + integrity sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw== dependencies: call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.1" + define-properties "^1.1.4" + es-abstract "^1.20.4" on-finished@2.4.1: version "2.4.1" @@ -5263,7 +5468,7 @@ on-finished@2.4.1: on-finished@~2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" - integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= + integrity sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww== dependencies: ee-first "1.1.1" @@ -5275,14 +5480,14 @@ on-headers@~1.0.2: once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== dependencies: wrappy "1" onetime@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" - integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ= + integrity sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ== dependencies: mimic-fn "^1.0.0" @@ -5300,22 +5505,22 @@ open@^6.2.0: dependencies: is-wsl "^1.1.0" -optionator@^0.9.1: - version "0.9.1" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" - integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== +optionator@^0.9.3: + version "0.9.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" + integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg== dependencies: + "@aashutoshrathi/word-wrap" "^1.2.3" deep-is "^0.1.3" fast-levenshtein "^2.0.6" levn "^0.4.1" prelude-ls "^1.2.1" type-check "^0.4.0" - word-wrap "^1.2.3" options@>=0.0.5: version "0.0.6" resolved "https://registry.yarnpkg.com/options/-/options-0.0.6.tgz#ec22d312806bb53e731773e7cdaefcf1c643128f" - integrity sha1-7CLTEoBrtT5zF3Pnza788cZDEo8= + integrity sha512-bOj3L1ypm++N+n7CEbbe473A414AB7z+amKYshRb//iuL3MpdDCLhPnw6aVTdKB9g5ZRVHIEp8eUln6L2NUStg== ora@^3.4.0: version "3.4.0" @@ -5332,19 +5537,12 @@ ora@^3.4.0: os-tmpdir@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= + integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g== p-finally@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" - integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= - -p-limit@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" - integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== - dependencies: - p-try "^1.0.0" + integrity sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow== p-limit@^2.0.0, p-limit@^2.2.0: version "2.3.0" @@ -5353,12 +5551,12 @@ p-limit@^2.0.0, p-limit@^2.2.0: dependencies: p-try "^2.0.0" -p-locate@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" - integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= +p-limit@^3.0.2, p-limit@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== dependencies: - p-limit "^1.1.0" + yocto-queue "^0.1.0" p-locate@^3.0.0: version "3.0.0" @@ -5374,10 +5572,12 @@ p-locate@^4.1.0: dependencies: p-limit "^2.2.0" -p-try@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" - integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" p-try@^2.0.0: version "2.2.0" @@ -5394,7 +5594,7 @@ parent-module@^1.0.0: parse-json@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" - integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= + integrity sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw== dependencies: error-ex "^1.3.1" json-parse-better-errors "^1.0.1" @@ -5417,12 +5617,12 @@ parseurl@~1.3.3: pascalcase@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" - integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= + integrity sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw== path-exists@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= + integrity sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ== path-exists@^4.0.0: version "4.0.0" @@ -5432,12 +5632,12 @@ path-exists@^4.0.0: path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== path-key@^2.0.0, path-key@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" - integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= + integrity sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw== path-key@^3.0.0, path-key@^3.1.0: version "3.1.1" @@ -5470,9 +5670,9 @@ pify@^4.0.1: integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== pirates@^4.0.4, pirates@^4.0.5: - version "4.0.5" - resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b" - integrity sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ== + version "4.0.6" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9" + integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg== pkg-dir@^3.0.0: version "3.0.0" @@ -5496,17 +5696,18 @@ pkg-up@^3.1.0: find-up "^3.0.0" plist@^3.0.2, plist@^3.0.5: - version "3.0.5" - resolved "https://registry.yarnpkg.com/plist/-/plist-3.0.5.tgz#2cbeb52d10e3cdccccf0c11a63a85d830970a987" - integrity sha512-83vX4eYdQp3vP9SxuYgEM/G/pJQqLUz/V/xzPrzruLs7fz7jxGQ1msZ/mg1nwZxUSuOp4sb+/bEIbRrbzZRxDA== + version "3.1.0" + resolved "https://registry.yarnpkg.com/plist/-/plist-3.1.0.tgz#797a516a93e62f5bde55e0b9cc9c967f860893c9" + integrity sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ== dependencies: + "@xmldom/xmldom" "^0.8.8" base64-js "^1.5.1" - xmlbuilder "^9.0.7" + xmlbuilder "^15.1.1" posix-character-classes@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" - integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= + integrity sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg== prelude-ls@^1.2.1: version "1.2.1" @@ -5520,11 +5721,16 @@ prettier-linter-helpers@^1.0.0: dependencies: fast-diff "^1.1.2" -prettier@2.6.2, prettier@^2.5.1, prettier@^2.6.2: +prettier@2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.6.2.tgz#e26d71a18a74c3d0f0597f55f01fb6c06c206032" integrity sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew== +prettier@^2.5.1, prettier@^2.6.2: + version "2.8.8" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" + integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== + pretty-format@^26.5.2, pretty-format@^26.6.2: version "26.6.2" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-26.6.2.tgz#e35c2705f14cb7fe2fe94fa078345b444120fc93" @@ -5544,12 +5750,12 @@ pretty-format@^27.0.0, pretty-format@^27.5.1: ansi-styles "^5.0.0" react-is "^17.0.1" -pretty-format@^28.0.2: - version "28.0.2" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-28.0.2.tgz#6a24d71cbb61a5e5794ba7513fe22101675481bc" - integrity sha512-UmGZ1IERwS3yY35LDMTaBUYI1w4udZDdJGGT/DqQeKG9ZLDn7/K2Jf/JtYSRiHCCKMHvUA+zsEGSmHdpaVp1yw== +pretty-format@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-28.1.3.tgz#c9fba8cedf99ce50963a11b27d982a9ae90970d5" + integrity sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q== dependencies: - "@jest/schemas" "^28.0.2" + "@jest/schemas" "^28.1.3" ansi-regex "^5.0.1" ansi-styles "^5.0.0" react-is "^18.0.0" @@ -5560,9 +5766,9 @@ process-nextick-args@~2.0.0: integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== promise@^8.0.3: - version "8.1.0" - resolved "https://registry.yarnpkg.com/promise/-/promise-8.1.0.tgz#697c25c3dfe7435dd79fcd58c38a135888eaf05e" - integrity sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q== + version "8.3.0" + resolved "https://registry.yarnpkg.com/promise/-/promise-8.3.0.tgz#8cb333d1edeb61ef23869fbb8a4ea0279ab60e0a" + integrity sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg== dependencies: asap "~2.0.6" @@ -5592,9 +5798,9 @@ pump@^3.0.0: once "^1.3.1" punycode@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + version "2.3.0" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" + integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== queue-microtask@^1.2.2: version "1.2.3" @@ -5625,9 +5831,9 @@ react-is@^17.0.1: integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== react-is@^18.0.0: - version "18.1.0" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.1.0.tgz#61aaed3096d30eacf2a2127118b5b41387d32a67" - integrity sha512-Fl7FuabXsJnV5Q1qIOQwx/sagGF18kogb4gpfcG4gjLBWO0WDiiz1ko/ExayuxE7InyQkBLkxRFG5oxY6Uu3Kg== + version "18.2.0" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" + integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== react-native-codegen@^0.0.8: version "0.0.8" @@ -5688,18 +5894,18 @@ react@17.0.2: object-assign "^4.1.1" readable-stream@^3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" - integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + version "3.6.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== dependencies: inherits "^2.0.3" string_decoder "^1.1.1" util-deprecate "^1.0.1" readable-stream@~2.3.6: - version "2.3.7" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" - integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + version "2.3.8" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" + integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== dependencies: core-util-is "~1.0.0" inherits "~2.0.3" @@ -5712,7 +5918,7 @@ readable-stream@~2.3.6: readline@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/readline/-/readline-1.3.0.tgz#c580d77ef2cfc8752b132498060dc9793a7ac01c" - integrity sha1-xYDXfvLPyHUrEySYBg3JeTp6wBw= + integrity sha512-k2d6ACCkiNYz222Fs/iNze30rRJ1iIicW7JuX/7/cozvih6YCkFZH+J6mAFDVgv0dRBaAyr4jDqC95R2y4IADg== recast@^0.20.3: version "0.20.5" @@ -5749,10 +5955,10 @@ ref-struct-di@^1.1.0, ref-struct-di@^1.1.1: dependencies: debug "^3.1.0" -regenerate-unicode-properties@^10.0.1: - version "10.0.1" - resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.0.1.tgz#7f442732aa7934a3740c779bb9b3340dccc1fb56" - integrity sha512-vn5DU6yg6h8hP/2OkQo3K7uVILvY4iu0oI4t3HFa81UPkhGJwkRwM10JEc3upjdhHjs/k8GJY1sRBhk5sr69Bw== +regenerate-unicode-properties@^10.1.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz#7c3192cab6dd24e21cb4461e5ddd7dd24fa8374c" + integrity sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ== dependencies: regenerate "^1.4.2" @@ -5761,15 +5967,20 @@ regenerate@^1.4.2: resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== -regenerator-runtime@^0.13.2, regenerator-runtime@^0.13.4: - version "0.13.9" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" - integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== +regenerator-runtime@^0.13.2: + version "0.13.11" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" + integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== -regenerator-transform@^0.15.0: - version "0.15.0" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.0.tgz#cbd9ead5d77fae1a48d957cf889ad0586adb6537" - integrity sha512-LsrGtPmbYg19bcPHwdtmXwbW+TqNvtY4riE3P83foeHRroMbH6/2ddFBfab3t7kbzc7v7p4wbkIecHImqt0QNg== +regenerator-runtime@^0.14.0: + version "0.14.0" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz#5e19d68eb12d486f797e15a3c6a918f7cec5eb45" + integrity sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA== + +regenerator-transform@^0.15.2: + version "0.15.2" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.2.tgz#5bbae58b522098ebdf09bca2f83838929001c7a4" + integrity sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg== dependencies: "@babel/runtime" "^7.8.4" @@ -5781,39 +5992,38 @@ regex-not@^1.0.0, regex-not@^1.0.2: extend-shallow "^3.0.2" safe-regex "^1.1.0" -regexpp@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" - integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== +regexp.prototype.flags@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz#fe7ce25e7e4cca8db37b6634c8a2c7009199b9cb" + integrity sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + functions-have-names "^1.2.3" -regexpu-core@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.0.1.tgz#c531122a7840de743dcf9c83e923b5560323ced3" - integrity sha512-CriEZlrKK9VJw/xQGJpQM5rY88BtuL8DM+AEwvcThHilbxiTAy8vq4iJnd2tqq8wLmjbGZzP7ZcKFjbGkmEFrw== +regexpu-core@^5.3.1: + version "5.3.2" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.3.2.tgz#11a2b06884f3527aec3e93dbbf4a3b958a95546b" + integrity sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ== dependencies: + "@babel/regjsgen" "^0.8.0" regenerate "^1.4.2" - regenerate-unicode-properties "^10.0.1" - regjsgen "^0.6.0" - regjsparser "^0.8.2" + regenerate-unicode-properties "^10.1.0" + regjsparser "^0.9.1" unicode-match-property-ecmascript "^2.0.0" - unicode-match-property-value-ecmascript "^2.0.0" + unicode-match-property-value-ecmascript "^2.1.0" -regjsgen@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.6.0.tgz#83414c5354afd7d6627b16af5f10f41c4e71808d" - integrity sha512-ozE883Uigtqj3bx7OhL1KNbCzGyW2NQZPl6Hs09WTvCuZD5sTI4JY58bkbQWa/Y9hxIsvJ3M8Nbf7j54IqeZbA== - -regjsparser@^0.8.2: - version "0.8.4" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.8.4.tgz#8a14285ffcc5de78c5b95d62bbf413b6bc132d5f" - integrity sha512-J3LABycON/VNEu3abOviqGHuB/LOtOQj8SKmfP9anY5GfAVw/SPjwzSjxGjbZXIxbGfqTHtJw58C2Li/WkStmA== +regjsparser@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.9.1.tgz#272d05aa10c7c1f67095b1ff0addae8442fc5709" + integrity sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ== dependencies: jsesc "~0.5.0" remove-trailing-separator@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" - integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= + integrity sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw== repeat-element@^1.1.2: version "1.1.4" @@ -5823,12 +6033,12 @@ repeat-element@^1.1.2: repeat-string@^1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" - integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= + integrity sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w== require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== require-main-filename@^2.0.0: version "2.0.0" @@ -5836,9 +6046,9 @@ require-main-filename@^2.0.0: integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== reselect@^4.0.0: - version "4.1.5" - resolved "https://registry.yarnpkg.com/reselect/-/reselect-4.1.5.tgz#852c361247198da6756d07d9296c2b51eddb79f6" - integrity sha512-uVdlz8J7OO+ASpBYoz1Zypgx0KasCY20H+N8JD13oUMtPvSHQuscrHop4KbXrbsBcdB9Ds7lVK7eRkBIfO43vQ== + version "4.1.8" + resolved "https://registry.yarnpkg.com/reselect/-/reselect-4.1.8.tgz#3f5dc671ea168dccdeb3e141236f69f02eaec524" + integrity sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ== resolve-cwd@^3.0.0: version "3.0.0" @@ -5850,7 +6060,7 @@ resolve-cwd@^3.0.0: resolve-from@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" - integrity sha1-six699nWiBvItuZTM17rywoYh0g= + integrity sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw== resolve-from@^4.0.0: version "4.0.0" @@ -5865,26 +6075,26 @@ resolve-from@^5.0.0: resolve-url@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" - integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= + integrity sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg== resolve.exports@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.0.tgz#5ce842b94b05146c0e03076985d1d0e7e48c90c9" - integrity sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ== + version "1.1.1" + resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.1.tgz#05cfd5b3edf641571fd46fa608b610dda9ead999" + integrity sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ== -resolve@^1.13.1, resolve@^1.14.2, resolve@^1.20.0, resolve@^1.22.0: - version "1.22.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198" - integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw== +resolve@^1.13.1, resolve@^1.14.2, resolve@^1.20.0, resolve@^1.22.0, resolve@^1.22.3, resolve@^1.22.4: + version "1.22.4" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.4.tgz#1dc40df46554cdaf8948a486a10f6ba1e2026c34" + integrity sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg== dependencies: - is-core-module "^2.8.1" + is-core-module "^2.13.0" path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" restore-cursor@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" - integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368= + integrity sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q== dependencies: onetime "^2.0.0" signal-exit "^3.0.2" @@ -5916,7 +6126,7 @@ rimraf@^3.0.0, rimraf@^3.0.2: rimraf@~2.2.6: version "2.2.8" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.2.8.tgz#e439be2aaee327321952730f99a8929e4fc50582" - integrity sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI= + integrity sha512-R5KMKHnPAQaZMqLOsyuyUmcIjSeDm+73eoqQpaXA7AZ22BL+6C+1mcUscgOsNd8WVlJuvlgAPsegcx7pjlV0Dg== rimraf@~2.6.2: version "2.6.3" @@ -5937,6 +6147,16 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" +safe-array-concat@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.0.0.tgz#2064223cba3c08d2ee05148eedbc563cd6d84060" + integrity sha512-9dVEFruWIsnie89yym+xWTAYASdpw3CJV7Li/6zBewGf9z2i1j31rP6jnY0pHEO4QZh6N0K11bFjWmdR8UGdPQ== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.2.0" + has-symbols "^1.0.3" + isarray "^2.0.5" + safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" @@ -5947,10 +6167,19 @@ safe-buffer@~5.2.0: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== +safe-regex-test@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.0.tgz#793b874d524eb3640d1873aad03596db2d4f2295" + integrity sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.3" + is-regex "^1.1.4" + safe-regex@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" - integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= + integrity sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg== dependencies: ret "~0.1.10" @@ -5969,7 +6198,7 @@ sane@^4.0.3: minimist "^1.1.1" walker "~1.0.5" -sax@^1.2.1: +sax@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== @@ -5982,22 +6211,17 @@ scheduler@^0.20.2: loose-envify "^1.1.0" object-assign "^4.1.1" -semver@7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" - integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== - semver@^5.5.0, semver@^5.6.0: version "5.7.2" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== -semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0: +semver@^6.0.0, semver@^6.3.0, semver@^6.3.1: version "6.3.1" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.3.5: +semver@^7.3.5, semver@^7.3.7, semver@^7.5.3: version "7.5.4" resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== @@ -6026,7 +6250,7 @@ send@0.18.0: serialize-error@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-2.1.0.tgz#50b679d5635cdf84667bdc8e59af4e5b81d5f60a" - integrity sha1-ULZ51WNc34Rme9yOWa9OW4HV9go= + integrity sha512-ghgmKt5o4Tly5yEG/UJp8qTd0AN7Xalw4XBtDEKP655B699qMEtra1WlXeE6WIvdEG481JvRxULKsInq/iNysw== serve-static@^1.13.1: version "1.15.0" @@ -6041,7 +6265,7 @@ serve-static@^1.13.1: set-blocking@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== set-value@^2.0.0, set-value@^2.0.1: version "2.0.1" @@ -6068,7 +6292,7 @@ shallow-clone@^3.0.0: shebang-command@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" - integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= + integrity sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg== dependencies: shebang-regex "^1.0.0" @@ -6082,27 +6306,17 @@ shebang-command@^2.0.0: shebang-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" - integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= + integrity sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ== shebang-regex@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== -shell-quote@1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.6.1.tgz#f4781949cce402697127430ea3b3c5476f481767" - integrity sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c= - dependencies: - array-filter "~0.0.0" - array-map "~0.0.0" - array-reduce "~0.0.0" - jsonify "~0.0.0" - -shell-quote@^1.6.1: - version "1.7.3" - resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.3.tgz#aa40edac170445b9a431e17bb62c0b881b9c4123" - integrity sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw== +shell-quote@^1.6.1, shell-quote@^1.7.3: + version "1.8.1" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.1.tgz#6dbf4db75515ad5bac63b4f1894c3a154c766680" + integrity sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA== side-channel@^1.0.4: version "1.0.4" @@ -6211,7 +6425,7 @@ source-map-url@^0.4.0: source-map@^0.5.6: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= + integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: version "0.6.1" @@ -6219,9 +6433,9 @@ source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== source-map@^0.7.3: - version "0.7.3" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" - integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== + version "0.7.4" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.4.tgz#a9bbe705c9d8846f4e08ff6765acf0f1b0898656" + integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA== split-string@^3.0.1, split-string@^3.0.2: version "3.1.0" @@ -6233,19 +6447,19 @@ split-string@^3.0.1, split-string@^3.0.2: sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== stack-utils@^2.0.3: - version "2.0.5" - resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.5.tgz#d25265fca995154659dbbfba3b49254778d2fdd5" - integrity sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA== + version "2.0.6" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.6.tgz#aaf0748169c02fc33c8232abccf933f54a1cc34f" + integrity sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ== dependencies: escape-string-regexp "^2.0.0" -stackframe@^1.1.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.2.1.tgz#1033a3473ee67f08e2f2fc8eba6aef4f845124e1" - integrity sha512-h88QkzREN/hy8eRdyNhhsO7RSJ5oyTqxxmmn0dzBIMUclZsjpfmrsg81vp8mjjAs2vAZ72nyWxRUwSwmh0e4xg== +stackframe@^1.3.4: + version "1.3.4" + resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.3.4.tgz#b881a004c8c149a5e8efef37d51b16e412943310" + integrity sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw== stacktrace-parser@^0.1.3: version "0.1.10" @@ -6257,7 +6471,7 @@ stacktrace-parser@^0.1.3: static-extend@^0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" - integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= + integrity sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g== dependencies: define-property "^0.2.5" object-copy "^0.1.0" @@ -6270,12 +6484,12 @@ statuses@2.0.1: statuses@~1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" - integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= + integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== stream-buffers@2.2.x: version "2.2.0" resolved "https://registry.yarnpkg.com/stream-buffers/-/stream-buffers-2.2.0.tgz#91d5f5130d1cef96dcfa7f726945188741d09ee4" - integrity sha1-kdX1Ew0c75bc+n9yaUUYh0HQnuQ= + integrity sha512-uyQK/mx5QjHun80FLJTfaWE7JtwfRMKBLkMne6udYOmvH0CawotVa7TfgYHzAnpphn4+TweIx1QKMnRIbipmUg== string-length@^4.0.1: version "4.0.2" @@ -6294,21 +6508,32 @@ string-length@^4.0.1: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -string.prototype.trimend@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80" - integrity sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A== +string.prototype.trim@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz#a68352740859f6893f14ce3ef1bb3037f7a90533" + integrity sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg== dependencies: call-bind "^1.0.2" - define-properties "^1.1.3" + define-properties "^1.1.4" + es-abstract "^1.20.4" -string.prototype.trimstart@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed" - integrity sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw== +string.prototype.trimend@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz#c4a27fa026d979d79c04f17397f250a462944533" + integrity sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ== dependencies: call-bind "^1.0.2" - define-properties "^1.1.3" + define-properties "^1.1.4" + es-abstract "^1.20.4" + +string.prototype.trimstart@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz#e90ab66aa8e4007d92ef591bbf3cd422c56bdcf4" + integrity sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" string_decoder@^1.1.1: version "1.3.0" @@ -6341,7 +6566,7 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1: strip-bom@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= + integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== strip-bom@^4.0.0: version "4.0.0" @@ -6351,14 +6576,14 @@ strip-bom@^4.0.0: strip-eof@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" - integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= + integrity sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q== strip-final-newline@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== -strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: +strip-json-comments@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== @@ -6390,9 +6615,9 @@ supports-color@^8.0.0: has-flag "^4.0.0" supports-hyperlinks@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz#4f77b42488765891774b70c79babd87f9bd594bb" - integrity sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ== + version "2.3.0" + resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz#3943544347c1ff90b15effb03fc14ae45ec10624" + integrity sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA== dependencies: has-flag "^4.0.0" supports-color "^7.0.0" @@ -6403,13 +6628,13 @@ supports-preserve-symlinks-flag@^1.0.0: integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== tar@^6.1.11: - version "6.1.12" - resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.12.tgz#3b742fb05669b55671fb769ab67a7791ea1a62e6" - integrity sha512-jU4TdemS31uABHd+Lt5WEYJuzn+TJTCBLljvIAHZOz6M9Os5pJ4dD+vRFLxPa/n3T0iEFzpi+0x1UfuDZYbRMw== + version "6.1.15" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.15.tgz#c9738b0b98845a3b344d334b8fa3041aaba53a69" + integrity sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A== dependencies: chownr "^2.0.0" fs-minipass "^2.0.0" - minipass "^3.0.0" + minipass "^5.0.0" minizlib "^2.1.1" mkdirp "^1.0.3" yallist "^4.0.0" @@ -6417,7 +6642,7 @@ tar@^6.1.11: temp@0.8.3: version "0.8.3" resolved "https://registry.yarnpkg.com/temp/-/temp-0.8.3.tgz#e0c6bc4d26b903124410e4fed81103014dfc1f59" - integrity sha1-4Ma8TSa5AxJEEOT+2BEDAU38H1k= + integrity sha512-jtnWJs6B1cZlHs9wPG7BrowKxZw/rf6+UpGAkr8AaYmiTyTO7zQlLoST8zx/8TcUPnZmeBoB+H8ARuHZaSijVw== dependencies: os-tmpdir "^1.0.0" rimraf "~2.2.6" @@ -6449,18 +6674,13 @@ test-exclude@^6.0.0: text-table@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= + integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== throat@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/throat/-/throat-5.0.0.tgz#c5199235803aad18754a667d659b5e72ce16764b" integrity sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA== -throat@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/throat/-/throat-6.0.1.tgz#d514fedad95740c12c2d7fc70ea863eb51ade375" - integrity sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w== - through2@^2.0.1: version "2.0.5" resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" @@ -6477,19 +6697,19 @@ tmpl@1.0.5: to-fast-properties@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" - integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= + integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== to-object-path@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" - integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= + integrity sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg== dependencies: kind-of "^3.0.2" to-regex-range@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" - integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= + integrity sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg== dependencies: is-number "^3.0.0" repeat-string "^1.6.1" @@ -6519,14 +6739,14 @@ toidentifier@1.0.1: tr46@~0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" - integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o= + integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== ts-node@^10.7.0: - version "10.7.0" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.7.0.tgz#35d503d0fab3e2baa672a0e94f4b40653c2463f5" - integrity sha512-TbIGS4xgJoX2i3do417KSaep1uRAW/Lu+WAL2doDHC0D6ummjirVOXU5/7aiZotbQ5p1Zp9tP7U6cYhA0O7M8A== + version "10.9.1" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" + integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw== dependencies: - "@cspotcode/source-map-support" "0.7.0" + "@cspotcode/source-map-support" "^0.8.0" "@tsconfig/node10" "^1.0.7" "@tsconfig/node12" "^1.0.7" "@tsconfig/node14" "^1.0.0" @@ -6537,16 +6757,16 @@ ts-node@^10.7.0: create-require "^1.1.0" diff "^4.0.1" make-error "^1.1.1" - v8-compile-cache-lib "^3.0.0" + v8-compile-cache-lib "^3.0.1" yn "3.1.1" -tsconfig-paths@^3.14.1: - version "3.14.1" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz#ba0734599e8ea36c862798e920bcf163277b137a" - integrity sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ== +tsconfig-paths@^3.14.1, tsconfig-paths@^3.14.2: + version "3.14.2" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz#6e32f1f79412decd261f92d633a9dc1cfa99f088" + integrity sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g== dependencies: "@types/json5" "^0.0.29" - json5 "^1.0.1" + json5 "^1.0.2" minimist "^1.2.6" strip-bom "^3.0.0" @@ -6556,9 +6776,9 @@ tslib@^1.8.1: integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== tslib@^2.0.1: - version "2.4.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" - integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== + version "2.6.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.1.tgz#fd8c9a0ff42590b25703c0acb3de3d3f4ede0410" + integrity sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig== tsutils@^3.21.0: version "3.21.0" @@ -6599,15 +6819,54 @@ type@^1.0.1: resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== -type@^2.5.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/type/-/type-2.6.0.tgz#3ca6099af5981d36ca86b78442973694278a219f" - integrity sha512-eiDBDOmkih5pMbo9OqsqPRGMljLodLcwd5XD5JbtNB0o89xZAwynY9EdCDsJU7LtcVCClu9DvM7/0Ep1hYX3EQ== +type@^2.7.2: + version "2.7.2" + resolved "https://registry.yarnpkg.com/type/-/type-2.7.2.tgz#2376a15a3a28b1efa0f5350dcf72d24df6ef98d0" + integrity sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw== + +typed-array-buffer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz#18de3e7ed7974b0a729d3feecb94338d1472cd60" + integrity sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.2.1" + is-typed-array "^1.1.10" + +typed-array-byte-length@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz#d787a24a995711611fb2b87a4052799517b230d0" + integrity sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA== + dependencies: + call-bind "^1.0.2" + for-each "^0.3.3" + has-proto "^1.0.1" + is-typed-array "^1.1.10" + +typed-array-byte-offset@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz#cbbe89b51fdef9cd6aaf07ad4707340abbc4ea0b" + integrity sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + for-each "^0.3.3" + has-proto "^1.0.1" + is-typed-array "^1.1.10" + +typed-array-length@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.4.tgz#89d83785e5c4098bec72e08b319651f0eac9c1bb" + integrity sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng== + dependencies: + call-bind "^1.0.2" + for-each "^0.3.3" + is-typed-array "^1.1.9" typescript@~4.9.4: - version "4.9.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.4.tgz#a2a3d2756c079abda241d75f149df9d561091e78" - integrity sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg== + version "4.9.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" + integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== uglify-es@^3.1.9: version "3.3.9" @@ -6620,9 +6879,9 @@ uglify-es@^3.1.9: ultron@1.0.x: version "1.0.2" resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.0.2.tgz#ace116ab557cd197386a4e88f4685378c8b2e4fa" - integrity sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po= + integrity sha512-QMpnpVtYaWEeY+MwKDN/UdKlE/LsFZXM5lO1u7GaZzNgmIbGixHEmVMIKT+vqYOALu3m5GYQy9kz4Xu4IVn7Ow== -unbox-primitive@^1.0.1: +unbox-primitive@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== @@ -6645,15 +6904,15 @@ unicode-match-property-ecmascript@^2.0.0: unicode-canonical-property-names-ecmascript "^2.0.0" unicode-property-aliases-ecmascript "^2.0.0" -unicode-match-property-value-ecmascript@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz#1a01aa57247c14c568b89775a54938788189a714" - integrity sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw== +unicode-match-property-value-ecmascript@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz#cb5fffdcd16a05124f5a4b0bf7c3770208acbbe0" + integrity sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA== unicode-property-aliases-ecmascript@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz#0a36cb9a585c4f6abd51ad1deddb285c165297c8" - integrity sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ== + version "2.1.0" + resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz#43d41e3be698bd493ef911077c9b131f827e8ccd" + integrity sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w== union-value@^1.0.0: version "1.0.1" @@ -6673,16 +6932,24 @@ universalify@^0.1.0: unpipe@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" - integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= + integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== unset-value@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" - integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= + integrity sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ== dependencies: has-value "^0.3.1" isobject "^3.0.0" +update-browserslist-db@^1.0.11: + version "1.0.11" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz#9a2a641ad2907ae7b3616506f4b977851db5b940" + integrity sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + uri-js@^4.2.2: version "4.4.1" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" @@ -6693,19 +6960,19 @@ uri-js@^4.2.2: urix@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" - integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= + integrity sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg== use-subscription@^1.0.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/use-subscription/-/use-subscription-1.7.0.tgz#c7505263315deac9fd2581cdf4ab1e3ff2585d0f" - integrity sha512-87x6MjiIVE/BWqtxfiRvM6jfvGudN+UeVOnWi7qKYp2c0YJn5+Z5Jt0kZw6Tt+8hs7kw/BWo2WBhizJSAZsQJA== + version "1.8.0" + resolved "https://registry.yarnpkg.com/use-subscription/-/use-subscription-1.8.0.tgz#f118938c29d263c2bce12fc5585d3fe694d4dbce" + integrity sha512-LISuG0/TmmoDoCRmV5XAqYkd3UCBNM0ML3gGBndze65WITcsExCD3DTvXXTLyNcOC0heFQZzluW88bN/oC1DQQ== dependencies: - use-sync-external-store "^1.1.0" + use-sync-external-store "^1.2.0" -use-sync-external-store@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.1.0.tgz#3343c3fe7f7e404db70f8c687adf5c1652d34e82" - integrity sha512-SEnieB2FPKEVne66NpXPd1Np4R1lTNKfjuy3XdIoPQKYBAFdzbzSZlSn1KJZUiihQLQC5Znot4SBz1EOTBwQAQ== +use-sync-external-store@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a" + integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA== use@^3.1.0: version "3.1.1" @@ -6715,48 +6982,43 @@ use@^3.1.0: util-deprecate@^1.0.1, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== utils-merge@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" - integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= + integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== uuid@^3.3.2: version "3.4.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== -v8-compile-cache-lib@^3.0.0: +v8-compile-cache-lib@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== -v8-compile-cache@^2.0.3: - version "2.3.0" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" - integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== - -v8-to-istanbul@^9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.0.0.tgz#be0dae58719fc53cb97e5c7ac1d7e6d4f5b19511" - integrity sha512-HcvgY/xaRm7isYmyx+lFKA4uQmfUbN0J4M0nNItvzTvH/iQ9kW5j/t4YSR+Ge323/lrgDAWJoF46tzGQHwBHFw== +v8-to-istanbul@^9.0.1: + version "9.1.0" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz#1b83ed4e397f58c85c266a570fc2558b5feb9265" + integrity sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA== dependencies: - "@jridgewell/trace-mapping" "^0.3.7" + "@jridgewell/trace-mapping" "^0.3.12" "@types/istanbul-lib-coverage" "^2.0.1" convert-source-map "^1.6.0" vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" - integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= + integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== vlq@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/vlq/-/vlq-1.0.1.tgz#c003f6e7c0b4c1edd623fd6ee50bbc0d6a1de468" integrity sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w== -walker@^1.0.7, walker@~1.0.5: +walker@^1.0.7, walker@^1.0.8, walker@~1.0.5: version "1.0.8" resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ== @@ -6766,24 +7028,24 @@ walker@^1.0.7, walker@~1.0.5: wcwidth@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" - integrity sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g= + integrity sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg== dependencies: defaults "^1.0.3" webidl-conversions@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" - integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE= + integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== whatwg-fetch@^3.0.0: - version "3.6.2" - resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz#dced24f37f2624ed0281725d51d0e2e3fe677f8c" - integrity sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA== + version "3.6.17" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.6.17.tgz#009bbbfc122b227b74ba1ff31536b3a1a0e0e212" + integrity sha512-c4ghIvG6th0eudYwKZY5keb81wtFz9/WeAHAoy8+r18kcWlitUIrmGFQ2rWEl4UCKUilD3zCLHOIPheHx5ypRQ== whatwg-url@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" - integrity sha1-lmRU6HZUYuN2RNNib2dCzotwll0= + integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== dependencies: tr46 "~0.0.3" webidl-conversions "^3.0.0" @@ -6800,9 +7062,20 @@ which-boxed-primitive@^1.0.2: is-symbol "^1.0.3" which-module@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" - integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= + version "2.0.1" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.1.tgz#776b1fe35d90aebe99e8ac15eb24093389a4a409" + integrity sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ== + +which-typed-array@^1.1.10, which-typed-array@^1.1.11: + version "1.1.11" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.11.tgz#99d691f23c72aab6768680805a271b69761ed61a" + integrity sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + for-each "^0.3.3" + gopd "^1.0.1" + has-tostringtag "^1.0.0" which@^1.2.9: version "1.3.1" @@ -6825,11 +7098,6 @@ wide-align@^1.1.2: dependencies: string-width "^1.0.2 || 2 || 3 || 4" -word-wrap@^1.2.3: - version "1.2.5" - resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34" - integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== - wrap-ansi@^6.2.0: version "6.2.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" @@ -6851,7 +7119,7 @@ wrap-ansi@^7.0.0: wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== write-file-atomic@^2.3.0: version "2.4.3" @@ -6863,9 +7131,9 @@ write-file-atomic@^2.3.0: signal-exit "^3.0.2" write-file-atomic@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-4.0.1.tgz#9faa33a964c1c85ff6f849b80b42a88c2c537c8f" - integrity sha512-nSKUxgAbyioruk6hU87QzVbY279oYT6uiwgDoujth2ju4mJ+TZau7SQBhtbTmUyuNYTuXnSyRn66FV0+eCgcrQ== + version "4.0.2" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-4.0.2.tgz#a9df01ae5b77858a027fd2e80768ee433555fcfd" + integrity sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg== dependencies: imurmurhash "^0.1.4" signal-exit "^3.0.7" @@ -6886,9 +7154,9 @@ ws@^6.1.4: async-limiter "~1.0.0" ws@^7: - version "7.5.7" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.7.tgz#9e0ac77ee50af70d58326ecff7e85eb3fa375e67" - integrity sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A== + version "7.5.9" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591" + integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== xcode@^2.0.0: version "2.1.0" @@ -6898,17 +7166,17 @@ xcode@^2.0.0: simple-plist "^1.0.0" uuid "^3.3.2" -xmlbuilder@^9.0.7: - version "9.0.7" - resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d" - integrity sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0= +xmlbuilder@^15.1.1: + version "15.1.1" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-15.1.1.tgz#9dcdce49eea66d8d10b42cae94a79c3c8d0c2ec5" + integrity sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg== xmldoc@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/xmldoc/-/xmldoc-1.1.2.tgz#6666e029fe25470d599cd30e23ff0d1ed50466d7" - integrity sha512-ruPC/fyPNck2BD1dpz0AZZyrEwMOrWTO5lDdIXS91rs3wtm4j+T8Rp2o+zoOYkkAxJTZRPOSnOGei1egoRmKMQ== + version "1.3.0" + resolved "https://registry.yarnpkg.com/xmldoc/-/xmldoc-1.3.0.tgz#7823225b096c74036347c9ec5924d06b6a3cebab" + integrity sha512-y7IRWW6PvEnYQZNZFMRLNJw+p3pezM4nKYPfr15g4OOW9i8VpeydycFuipE2297OvZnh3jSb2pxOt9QpkZUVng== dependencies: - sax "^1.2.1" + sax "^1.2.4" xtend@~4.0.1: version "4.0.2" @@ -6925,6 +7193,11 @@ y18n@^5.0.5: resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + yallist@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" @@ -6938,10 +7211,10 @@ yargs-parser@^18.1.2: camelcase "^5.0.0" decamelize "^1.2.0" -yargs-parser@^21.0.0: - version "21.0.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.0.1.tgz#0267f286c877a4f0f728fceb6f8a3e4cb95c6e35" - integrity sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg== +yargs-parser@^21.1.1: + version "21.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" + integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== yargs@^15.1.0, yargs@^15.3.1: version "15.4.1" @@ -6961,19 +7234,24 @@ yargs@^15.1.0, yargs@^15.3.1: yargs-parser "^18.1.2" yargs@^17.3.1: - version "17.4.1" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.4.1.tgz#ebe23284207bb75cee7c408c33e722bfb27b5284" - integrity sha512-WSZD9jgobAg3ZKuCQZSa3g9QOJeCCqLoLAykiWgmXnDo9EPnn4RPf5qVTtzgOx66o6/oqhcA5tHtJXpG8pMt3g== + version "17.7.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" + integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== dependencies: - cliui "^7.0.2" + cliui "^8.0.1" escalade "^3.1.1" get-caller-file "^2.0.5" require-directory "^2.1.1" string-width "^4.2.3" y18n "^5.0.5" - yargs-parser "^21.0.0" + yargs-parser "^21.1.1" yn@3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== From 7f55d801bdb7efa897ac349e5c9da59849c5252f Mon Sep 17 00:00:00 2001 From: Andrew Whitehead Date: Wed, 9 Aug 2023 16:30:53 -0700 Subject: [PATCH 114/117] fix lint errors Signed-off-by: Andrew Whitehead --- .../src/indyVdr/IndyVdrPool.ts | 2 +- .../indy-vdr-shared/src/types/IndyVdr.ts | 20 +++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/wrappers/javascript/indy-vdr-shared/src/indyVdr/IndyVdrPool.ts b/wrappers/javascript/indy-vdr-shared/src/indyVdr/IndyVdrPool.ts index 8cb54a9b..52884f1c 100644 --- a/wrappers/javascript/indy-vdr-shared/src/indyVdr/IndyVdrPool.ts +++ b/wrappers/javascript/indy-vdr-shared/src/indyVdr/IndyVdrPool.ts @@ -1,5 +1,5 @@ -import type { PoolStatus, Transactions, Verifiers } from '../types' import type { IndyVdrRequest, RequestResponseType } from './IndyVdrRequest' +import type { PoolStatus, Transactions, Verifiers } from '../types' import { indyVdr } from './indyVdr' diff --git a/wrappers/javascript/indy-vdr-shared/src/types/IndyVdr.ts b/wrappers/javascript/indy-vdr-shared/src/types/IndyVdr.ts index b56af0b5..9ab893e6 100644 --- a/wrappers/javascript/indy-vdr-shared/src/types/IndyVdr.ts +++ b/wrappers/javascript/indy-vdr-shared/src/types/IndyVdr.ts @@ -1,3 +1,13 @@ +import type { PrepareTxnAuthorAgreementAcceptanceOptions } from './builderTypes' +import type { + PoolHandle, + PoolStatus, + PoolSubmitActionOptions, + PoolSubmitRequestOptions, + RequestHandle, + Transactions, + Verifiers, +} from './types' import type { AcceptanceMechanismsRequestOptions, AttribRequestOptions, @@ -28,16 +38,6 @@ import type { RequestSetSignatureOptions, RequestSetTxnAuthorAgreementAcceptanceOptions, } from '../indyVdr' -import type { PrepareTxnAuthorAgreementAcceptanceOptions } from './builderTypes' -import type { - PoolHandle, - PoolStatus, - PoolSubmitActionOptions, - PoolSubmitRequestOptions, - RequestHandle, - Transactions, - Verifiers, -} from './types' // TODO: proper documentation export interface IndyVdr { From 619291ce21e4255059eba898d2398da48029dfe6 Mon Sep 17 00:00:00 2001 From: Alexey Lunin Date: Thu, 10 Aug 2023 13:46:23 +0300 Subject: [PATCH 115/117] Change arguments order in calling indy_vdr_build_get_attrib_request at buildGetAttribRequest Signed-off-by: Alexey Lunin --- wrappers/javascript/indy-vdr-react-native/cpp/indyVdr.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wrappers/javascript/indy-vdr-react-native/cpp/indyVdr.cpp b/wrappers/javascript/indy-vdr-react-native/cpp/indyVdr.cpp index 6e728bb4..d646d859 100644 --- a/wrappers/javascript/indy-vdr-react-native/cpp/indyVdr.cpp +++ b/wrappers/javascript/indy-vdr-react-native/cpp/indyVdr.cpp @@ -107,8 +107,9 @@ jsi::Value buildGetAttribRequest(jsi::Runtime &rt, jsi::Object options) { ErrorCode code = indy_vdr_build_get_attrib_request( submitterDid.length() > 0 ? submitterDid.c_str() : nullptr, - targetDid.c_str(), hash.length() > 0 ? hash.c_str() : nullptr, + targetDid.c_str(), raw.length() > 0 ? raw.c_str() : nullptr, + hash.length() > 0 ? hash.c_str() : nullptr, enc.length() > 0 ? enc.c_str() : nullptr, &out); return createReturnValue(rt, code, &out); From f04ecc6b84382fa2580f4ce8ba4965530f3544f7 Mon Sep 17 00:00:00 2001 From: Alexey Lunin Date: Thu, 10 Aug 2023 13:47:42 +0300 Subject: [PATCH 116/117] make submitterDid as optional at buildGetAcceptanceMechanismsRequest as it defined optional in indy-vdr-shared Signed-off-by: Alexey Lunin --- wrappers/javascript/indy-vdr-react-native/cpp/indyVdr.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wrappers/javascript/indy-vdr-react-native/cpp/indyVdr.cpp b/wrappers/javascript/indy-vdr-react-native/cpp/indyVdr.cpp index 6e728bb4..018ad0c9 100644 --- a/wrappers/javascript/indy-vdr-react-native/cpp/indyVdr.cpp +++ b/wrappers/javascript/indy-vdr-react-native/cpp/indyVdr.cpp @@ -64,7 +64,7 @@ jsi::Value buildAcceptanceMechanismsRequest(jsi::Runtime &rt, jsi::Value buildGetAcceptanceMechanismsRequest(jsi::Runtime &rt, jsi::Object options) { - auto submitterDid = jsiToValue(rt, options, "submitterDid"); + auto submitterDid = jsiToValue(rt, options, "submitterDid", true); auto timestamp = jsiToValue(rt, options, "timestamp", true); auto version = jsiToValue(rt, options, "version", true); From c978eb1e2e126dbc6e022818ab0b3eba421d083e Mon Sep 17 00:00:00 2001 From: Miroslav Kovar Date: Thu, 10 Aug 2023 21:14:51 +0200 Subject: [PATCH 117/117] Fix build Signed-off-by: Miroslav Kovar --- indy-vdr-proxy-client/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indy-vdr-proxy-client/Cargo.toml b/indy-vdr-proxy-client/Cargo.toml index 7244abb5..d9b6b097 100644 --- a/indy-vdr-proxy-client/Cargo.toml +++ b/indy-vdr-proxy-client/Cargo.toml @@ -7,6 +7,6 @@ edition = "2021" [dependencies] reqwest = { version = "0.11.17", default-features = false, features = ["json"] } -indy-vdr = { file = "../libindy_vdr" } +indy-vdr = { path = "../libindy_vdr" } serde_json = "1.0.96" url = "2.3.1"