From b7d7b132e645f7beae2c41b45e55ffb4c69ad222 Mon Sep 17 00:00:00 2001 From: "artem.ivanov" Date: Fri, 16 Feb 2024 17:52:11 +0400 Subject: [PATCH] Added optional network name to client config. Signed-off-by: artem.ivanov --- vdr/src/client/client.rs | 33 ++++++- .../cl/credential_definition_registry.rs | 95 ++++++++++--------- vdr/src/contracts/cl/schema_registry.rs | 72 +++++++------- .../cl/types/credential_definition.rs | 29 +++++- .../cl/types/credential_definition_id.rs | 52 +++++++++- vdr/src/contracts/cl/types/schema.rs | 25 ++++- vdr/src/contracts/cl/types/schema_id.rs | 48 +++++++++- vdr/src/contracts/did/types/did.rs | 6 +- .../migration/legacy_mapping_registry.rs | 6 +- vdr/uniffi/src/ffi/client.rs | 2 + vdr/wasm/demo/node/src/main.ts | 3 +- vdr/wasm/src/client.rs | 2 + vdr/wrappers/python/demo/test.py | 7 +- .../python/indy_besu_vdr/indy_besu_vdr.py | 8 +- 14 files changed, 286 insertions(+), 102 deletions(-) diff --git a/vdr/src/client/client.rs b/vdr/src/client/client.rs index 6aee120c..ec553924 100644 --- a/vdr/src/client/client.rs +++ b/vdr/src/client/client.rs @@ -23,6 +23,7 @@ pub struct LedgerClient { chain_id: u64, client: Box, contracts: HashMap>, + network: Option, quorum_handler: Option, } @@ -32,6 +33,7 @@ impl LedgerClient { /// # Params /// - `chain_id` - chain id of network (chain ID is part of the transaction signing process to protect against transaction replay attack) /// - `rpc_node` - string - RPC node endpoint + /// - `network` - string - Name of the network /// - `contract_configs` - [ContractSpec] specifications for contracts deployed on the network /// - `quorum_config` - Option<[QuorumConfig]> quorum configuration. Can be None if quorum check is not needed /// @@ -43,6 +45,7 @@ impl LedgerClient { chain_id: u64, rpc_node: &str, contract_configs: &[ContractConfig], + network: Option<&str>, quorum_config: Option<&QuorumConfig>, ) -> VdrResult { let client = Box::new(Web3Client::new(rpc_node)?); @@ -58,6 +61,7 @@ impl LedgerClient { chain_id, client, contracts, + network: network.map(String::from), quorum_handler, }; Ok(ledger_client) @@ -161,6 +165,9 @@ impl LedgerClient { pub(crate) fn chain_id(&self) -> u64 { self.chain_id } + pub(crate) fn network(&self) -> Option<&String> { + self.network.as_ref() + } #[logfn(Info)] #[logfn_inputs(Debug)] @@ -257,6 +264,7 @@ pub mod test { ]; pub const DEFAULT_NONCE: u64 = 0; pub const INVALID_ADDRESS: &str = "123"; + pub const TEST_NETWORK: &str = "test"; pub static CONFIG: Lazy = Lazy::new(|| read_config()); @@ -338,7 +346,14 @@ pub mod test { } pub fn client() -> LedgerClient { - LedgerClient::new(CONFIG.chain_id, &CONFIG.node_address, &contracts(), None).unwrap() + LedgerClient::new( + CONFIG.chain_id, + &CONFIG.node_address, + &contracts(), + Some(TEST_NETWORK), + None, + ) + .unwrap() } pub fn mock_client() -> LedgerClient { @@ -347,6 +362,7 @@ pub mod test { CONFIG.chain_id, &CONFIG.node_address, &contracts(), + Some(TEST_NETWORK), Some(&QuorumConfig::default()), ) .unwrap(); @@ -363,6 +379,7 @@ pub mod test { CONFIG.chain_id, &CONFIG.node_address, &contracts(), + Some(TEST_NETWORK), Some(&QuorumConfig::default()), ) .unwrap(); @@ -386,9 +403,15 @@ pub mod test { #[test] fn create_client_invalid_node_address() { - let client_err = LedgerClient::new(CONFIG.chain_id, "..", &contracts(), None) - .err() - .unwrap(); + let client_err = LedgerClient::new( + CONFIG.chain_id, + "..", + &contracts(), + Some(TEST_NETWORK), + None, + ) + .err() + .unwrap(); assert!(matches!( client_err, | VdrError::ClientNodeUnreachable { .. } @@ -432,6 +455,7 @@ pub mod test { CONFIG.chain_id, &CONFIG.node_address, &contract_config, + Some(TEST_NETWORK), None, ) .err() @@ -553,6 +577,7 @@ pub mod test { CONFIG.chain_id, wrong_node_address, &contracts(), + None, Some(&QuorumConfig::default()), ) .unwrap(); diff --git a/vdr/src/contracts/cl/credential_definition_registry.rs b/vdr/src/contracts/cl/credential_definition_registry.rs index fcef87df..da077fe6 100644 --- a/vdr/src/contracts/cl/credential_definition_registry.rs +++ b/vdr/src/contracts/cl/credential_definition_registry.rs @@ -4,7 +4,7 @@ use crate::{ client::LedgerClient, contracts::cl::types::{ credential_definition::{CredentialDefinition, CredentialDefinitionRecord}, - credential_definition_id::CredentialDefinitionId, + credential_definition_id::{CredentialDefinitionId, ParsedCredentialDefinitionId}, }, error::VdrResult, types::{ @@ -38,14 +38,13 @@ pub async fn build_create_credential_definition_transaction( ) -> VdrResult { credential_definition.validate()?; let identity = Address::try_from(&credential_definition.issuer_id)?; - let id = credential_definition.id(); TransactionBuilder::new() .set_contract(CONTRACT_NAME) .set_method(METHOD_CREATE_CREDENTIAL_DEFINITION) .add_param(&identity)? - .add_param(&id)? - .add_param(&credential_definition.issuer_id)? - .add_param(&credential_definition.schema_id)? + .add_param(&credential_definition.id().without_network()?)? + .add_param(&credential_definition.issuer_id.without_network()?)? + .add_param(&credential_definition.schema_id.without_network()?)? .add_param(credential_definition)? .set_type(TransactionType::Write) .set_from(from) @@ -69,7 +68,6 @@ pub async fn build_create_credential_definition_endorsing_data( ) -> VdrResult { credential_definition.validate()?; let identity = Address::try_from(&credential_definition.issuer_id)?; - let id = credential_definition.id(); TransactionEndorsingDataBuilder::new() .set_contract(CONTRACT_NAME) .set_identity(&identity) @@ -77,9 +75,9 @@ pub async fn build_create_credential_definition_endorsing_data( .add_param(&MethodStringParam::from( METHOD_CREATE_CREDENTIAL_DEFINITION, ))? - .add_param(&id)? - .add_param(&credential_definition.issuer_id)? - .add_param(&credential_definition.schema_id)? + .add_param(&credential_definition.id().without_network()?)? + .add_param(&credential_definition.issuer_id.without_network()?)? + .add_param(&credential_definition.schema_id.without_network()?)? .add_param(credential_definition)? .build(client) .await @@ -106,7 +104,6 @@ pub async fn build_create_credential_definition_signed_transaction( ) -> VdrResult { credential_definition.validate()?; let identity = Address::try_from(&credential_definition.issuer_id)?; - let id = credential_definition.id(); TransactionBuilder::new() .set_contract(CONTRACT_NAME) .set_method(METHOD_CREATE_CREDENTIAL_DEFINITION_SIGNED) @@ -114,9 +111,9 @@ pub async fn build_create_credential_definition_signed_transaction( .add_param(&signature.v())? .add_param(&signature.r())? .add_param(&signature.s())? - .add_param(&id)? - .add_param(&credential_definition.issuer_id)? - .add_param(&credential_definition.schema_id)? + .add_param(&credential_definition.id().without_network()?)? + .add_param(&credential_definition.issuer_id.without_network()?)? + .add_param(&credential_definition.schema_id.without_network()?)? .add_param(credential_definition)? .set_type(TransactionType::Write) .set_from(from) @@ -142,7 +139,7 @@ pub async fn build_resolve_credential_definition_transaction( TransactionBuilder::new() .set_contract(CONTRACT_NAME) .set_method(METHOD_RESOLVE_CREDENTIAL_DEFINITION) - .add_param(id)? + .add_param(&id.without_network()?)? .set_type(TransactionType::Read) .build(client) .await @@ -181,6 +178,14 @@ pub async fn resolve_credential_definition( client: &LedgerClient, id: &CredentialDefinitionId, ) -> VdrResult { + let parsed_id = ParsedCredentialDefinitionId::try_from(id)?; + match (parsed_id.network.as_ref(), client.network()) { + (Some(schema_network), Some(client_network)) if schema_network != client_network => { + return Err(VdrError::InvalidCredentialDefinition(format!("Network of request credential definition id {} does not match to the client network {}", schema_network, client_network))); + } + _ => {} + }; + let transaction = build_resolve_credential_definition_transaction(client, id).await?; let response = client.submit_transaction(&transaction).await?; @@ -235,6 +240,7 @@ pub mod test { &SchemaId::from(SCHEMA_ID), Some(CREDENTIAL_DEFINITION_TAG), ); + println!("cred_def {:?}", cred_def); let transaction = build_create_credential_definition_transaction(&client, &TEST_ACCOUNT, &cred_def) .await @@ -247,37 +253,36 @@ pub mod test { chain_id: CONFIG.chain_id, data: vec![ 182, 196, 9, 117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 240, 226, 219, 108, 141, - 198, 198, 129, 187, 93, 106, 209, 33, 161, 7, 243, 0, 233, 178, 181, 190, 177, - 72, 242, 21, 171, 224, 191, 86, 212, 4, 12, 89, 70, 109, 83, 153, 187, 19, 51, - 18, 37, 31, 233, 114, 33, 60, 132, 133, 72, 249, 229, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 160, 34, - 27, 23, 130, 143, 227, 3, 94, 147, 14, 185, 63, 10, 50, 145, 115, 71, 104, 106, - 145, 232, 190, 123, 84, 240, 64, 217, 94, 167, 52, 119, 152, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 198, 198, 129, 187, 93, 106, 209, 33, 161, 7, 243, 0, 233, 178, 181, 2, 105, + 77, 198, 175, 52, 100, 14, 236, 5, 92, 96, 213, 30, 127, 142, 109, 135, 11, + 231, 119, 100, 109, 44, 92, 49, 82, 133, 141, 241, 182, 157, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 160, + 157, 102, 193, 205, 103, 90, 204, 163, 183, 21, 33, 209, 148, 81, 176, 246, 13, + 62, 210, 245, 196, 121, 156, 18, 158, 90, 17, 4, 158, 115, 117, 188, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 59, 100, 105, 100, 58, 101, 116, 104, 114, 58, 116, 101, 115, - 116, 110, 101, 116, 58, 48, 120, 102, 48, 101, 50, 100, 98, 54, 99, 56, 100, - 99, 54, 99, 54, 56, 49, 98, 98, 53, 100, 54, 97, 100, 49, 50, 49, 97, 49, 48, - 55, 102, 51, 48, 48, 101, 57, 98, 50, 98, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 42, - 123, 34, 105, 115, 115, 117, 101, 114, 73, 100, 34, 58, 34, 100, 105, 100, 58, - 101, 116, 104, 114, 58, 116, 101, 115, 116, 110, 101, 116, 58, 48, 120, 102, - 48, 101, 50, 100, 98, 54, 99, 56, 100, 99, 54, 99, 54, 56, 49, 98, 98, 53, 100, - 54, 97, 100, 49, 50, 49, 97, 49, 48, 55, 102, 51, 48, 48, 101, 57, 98, 50, 98, - 53, 34, 44, 34, 115, 99, 104, 101, 109, 97, 73, 100, 34, 58, 34, 100, 105, 100, - 58, 101, 116, 104, 114, 58, 116, 101, 115, 116, 110, 101, 116, 58, 48, 120, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 51, 100, 105, 100, 58, 101, 116, 104, 114, 58, 48, 120, 102, 48, 101, 50, 100, 98, 54, 99, 56, 100, 99, 54, 99, 54, 56, 49, 98, 98, 53, 100, 54, 97, 100, 49, 50, 49, 97, 49, 48, 55, 102, 51, 48, 48, 101, 57, 98, 50, - 98, 53, 47, 97, 110, 111, 110, 99, 114, 101, 100, 115, 47, 118, 48, 47, 83, 67, - 72, 69, 77, 65, 47, 70, 49, 68, 67, 108, 97, 70, 69, 122, 105, 51, 116, 47, 49, - 46, 48, 46, 48, 34, 44, 34, 99, 114, 101, 100, 68, 101, 102, 84, 121, 112, 101, - 34, 58, 34, 67, 76, 34, 44, 34, 116, 97, 103, 34, 58, 34, 100, 101, 102, 97, - 117, 108, 116, 34, 44, 34, 118, 97, 108, 117, 101, 34, 58, 123, 34, 110, 34, - 58, 34, 55, 55, 57, 46, 46, 46, 51, 57, 55, 34, 44, 34, 114, 99, 116, 120, 116, - 34, 58, 34, 55, 55, 52, 46, 46, 46, 57, 55, 55, 34, 44, 34, 115, 34, 58, 34, - 55, 53, 48, 46, 46, 56, 57, 51, 34, 44, 34, 122, 34, 58, 34, 54, 51, 50, 46, - 46, 46, 48, 48, 53, 34, 125, 125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, + 98, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 42, 123, 34, 105, + 115, 115, 117, 101, 114, 73, 100, 34, 58, 34, 100, 105, 100, 58, 101, 116, 104, + 114, 58, 116, 101, 115, 116, 110, 101, 116, 58, 48, 120, 102, 48, 101, 50, 100, + 98, 54, 99, 56, 100, 99, 54, 99, 54, 56, 49, 98, 98, 53, 100, 54, 97, 100, 49, + 50, 49, 97, 49, 48, 55, 102, 51, 48, 48, 101, 57, 98, 50, 98, 53, 34, 44, 34, + 115, 99, 104, 101, 109, 97, 73, 100, 34, 58, 34, 100, 105, 100, 58, 101, 116, + 104, 114, 58, 116, 101, 115, 116, 110, 101, 116, 58, 48, 120, 102, 48, 101, 50, + 100, 98, 54, 99, 56, 100, 99, 54, 99, 54, 56, 49, 98, 98, 53, 100, 54, 97, 100, + 49, 50, 49, 97, 49, 48, 55, 102, 51, 48, 48, 101, 57, 98, 50, 98, 53, 47, 97, + 110, 111, 110, 99, 114, 101, 100, 115, 47, 118, 48, 47, 83, 67, 72, 69, 77, 65, + 47, 70, 49, 68, 67, 108, 97, 70, 69, 122, 105, 51, 116, 47, 49, 46, 48, 46, 48, + 34, 44, 34, 99, 114, 101, 100, 68, 101, 102, 84, 121, 112, 101, 34, 58, 34, 67, + 76, 34, 44, 34, 116, 97, 103, 34, 58, 34, 100, 101, 102, 97, 117, 108, 116, 34, + 44, 34, 118, 97, 108, 117, 101, 34, 58, 123, 34, 110, 34, 58, 34, 55, 55, 57, + 46, 46, 46, 51, 57, 55, 34, 44, 34, 114, 99, 116, 120, 116, 34, 58, 34, 55, 55, + 52, 46, 46, 46, 57, 55, 55, 34, 44, 34, 115, 34, 58, 34, 55, 53, 48, 46, 46, + 56, 57, 51, 34, 44, 34, 122, 34, 58, 34, 54, 51, 50, 46, 46, 46, 48, 48, 53, + 34, 125, 125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ], signature: RwLock::new(None), hash: None, @@ -335,9 +340,9 @@ pub mod test { nonce: None, chain_id: CONFIG.chain_id, data: vec![ - 159, 136, 157, 181, 190, 177, 72, 242, 21, 171, 224, 191, 86, 212, 4, 12, 89, - 70, 109, 83, 153, 187, 19, 51, 18, 37, 31, 233, 114, 33, 60, 132, 133, 72, 249, - 229, + 159, 136, 157, 181, 2, 105, 77, 198, 175, 52, 100, 14, 236, 5, 92, 96, 213, 30, + 127, 142, 109, 135, 11, 231, 119, 100, 109, 44, 92, 49, 82, 133, 141, 241, 182, + 157, ], signature: RwLock::new(None), hash: None, diff --git a/vdr/src/contracts/cl/schema_registry.rs b/vdr/src/contracts/cl/schema_registry.rs index 00250805..d754fcf1 100644 --- a/vdr/src/contracts/cl/schema_registry.rs +++ b/vdr/src/contracts/cl/schema_registry.rs @@ -4,7 +4,7 @@ use crate::{ client::LedgerClient, contracts::cl::types::{ schema::{Schema, SchemaRecord}, - schema_id::SchemaId, + schema_id::{ParsedSchemaId, SchemaId}, }, error::VdrResult, types::{ @@ -37,13 +37,12 @@ pub async fn build_create_schema_transaction( ) -> VdrResult { schema.validate()?; let identity = Address::try_from(&schema.issuer_id)?; - let id = schema.id(); TransactionBuilder::new() .set_contract(CONTRACT_NAME) .set_method(METHOD_CREATE_SCHEMA) .add_param(&identity)? - .add_param(&id)? - .add_param(&schema.issuer_id)? + .add_param(&schema.id().without_network()?)? + .add_param(&schema.issuer_id.without_network()?)? .add_param(schema)? .set_type(TransactionType::Write) .set_from(from) @@ -67,14 +66,13 @@ pub async fn build_create_schema_endorsing_data( ) -> VdrResult { schema.validate()?; let identity = Address::try_from(&schema.issuer_id)?; - let id = schema.id(); TransactionEndorsingDataBuilder::new() .set_contract(CONTRACT_NAME) .set_identity(&identity) .add_param(&identity)? .add_param(&MethodStringParam::from(METHOD_CREATE_SCHEMA))? - .add_param(&id)? - .add_param(&schema.issuer_id)? + .add_param(&schema.id().without_network()?)? + .add_param(&schema.issuer_id.without_network()?)? .add_param(schema)? .build(client) .await @@ -101,7 +99,6 @@ pub async fn build_create_schema_signed_transaction( ) -> VdrResult { schema.validate()?; let identity = Address::try_from(&schema.issuer_id)?; - let id = schema.id(); TransactionBuilder::new() .set_contract(CONTRACT_NAME) .set_method(METHOD_CREATE_SCHEMA_SIGNED) @@ -109,8 +106,8 @@ pub async fn build_create_schema_signed_transaction( .add_param(&signature.v())? .add_param(&signature.r())? .add_param(&signature.s())? - .add_param(&id)? - .add_param(&schema.issuer_id)? + .add_param(&schema.id().without_network()?)? + .add_param(&schema.issuer_id.without_network()?)? .add_param(schema)? .set_type(TransactionType::Write) .set_from(sender) @@ -135,7 +132,7 @@ pub async fn build_resolve_schema_transaction( TransactionBuilder::new() .set_contract(CONTRACT_NAME) .set_method(METHOD_RESOLVE_SCHEMA) - .add_param(id)? + .add_param(&id.without_network()?)? .set_type(TransactionType::Read) .build(client) .await @@ -169,6 +166,17 @@ pub fn parse_resolve_schema_result(client: &LedgerClient, bytes: &[u8]) -> VdrRe #[logfn(Info)] #[logfn_inputs(Debug)] pub async fn resolve_schema(client: &LedgerClient, id: &SchemaId) -> VdrResult { + let parsed_id = ParsedSchemaId::try_from(id)?; + match (parsed_id.network.as_ref(), client.network()) { + (Some(schema_network), Some(client_network)) if schema_network != client_network => { + return Err(VdrError::InvalidSchema(format!( + "Network of request schema id {} does not match to the client network {}", + schema_network, client_network + ))); + } + _ => {} + }; + let transaction = build_resolve_schema_transaction(client, id).await?; let response = client.submit_transaction(&transaction).await?; if response.is_empty() { @@ -224,26 +232,26 @@ pub mod test { chain_id: CONFIG.chain_id, data: vec![ 131, 211, 251, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 240, 226, 219, 108, 141, - 198, 198, 129, 187, 93, 106, 209, 33, 161, 7, 243, 0, 233, 178, 181, 34, 27, - 23, 130, 143, 227, 3, 94, 147, 14, 185, 63, 10, 50, 145, 115, 71, 104, 106, - 145, 232, 190, 123, 84, 240, 64, 217, 94, 167, 52, 119, 152, 0, 0, 0, 0, 0, 0, + 198, 198, 129, 187, 93, 106, 209, 33, 161, 7, 243, 0, 233, 178, 181, 157, 102, + 193, 205, 103, 90, 204, 163, 183, 21, 33, 209, 148, 81, 176, 246, 13, 62, 210, + 245, 196, 121, 156, 18, 158, 90, 17, 4, 158, 115, 117, 188, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, 100, 105, 100, 58, 101, 116, 104, 114, 58, - 116, 101, 115, 116, 110, 101, 116, 58, 48, 120, 102, 48, 101, 50, 100, 98, 54, - 99, 56, 100, 99, 54, 99, 54, 56, 49, 98, 98, 53, 100, 54, 97, 100, 49, 50, 49, - 97, 49, 48, 55, 102, 51, 48, 48, 101, 57, 98, 50, 98, 53, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 141, 123, 34, 105, 115, 115, 117, 101, 114, 73, 100, 34, 58, 34, 100, - 105, 100, 58, 101, 116, 104, 114, 58, 116, 101, 115, 116, 110, 101, 116, 58, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 100, 105, 100, 58, 101, 116, 104, 114, 58, 48, 120, 102, 48, 101, 50, 100, 98, 54, 99, 56, 100, 99, 54, 99, 54, 56, 49, 98, 98, 53, 100, 54, 97, 100, 49, 50, 49, 97, 49, 48, 55, 102, 51, 48, 48, 101, - 57, 98, 50, 98, 53, 34, 44, 34, 110, 97, 109, 101, 34, 58, 34, 70, 49, 68, 67, - 108, 97, 70, 69, 122, 105, 51, 116, 34, 44, 34, 118, 101, 114, 115, 105, 111, - 110, 34, 58, 34, 49, 46, 48, 46, 48, 34, 44, 34, 97, 116, 116, 114, 78, 97, - 109, 101, 115, 34, 58, 91, 34, 70, 105, 114, 115, 116, 32, 78, 97, 109, 101, - 34, 93, 125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 57, 98, 50, 98, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 141, + 123, 34, 105, 115, 115, 117, 101, 114, 73, 100, 34, 58, 34, 100, 105, 100, 58, + 101, 116, 104, 114, 58, 116, 101, 115, 116, 110, 101, 116, 58, 48, 120, 102, + 48, 101, 50, 100, 98, 54, 99, 56, 100, 99, 54, 99, 54, 56, 49, 98, 98, 53, 100, + 54, 97, 100, 49, 50, 49, 97, 49, 48, 55, 102, 51, 48, 48, 101, 57, 98, 50, 98, + 53, 34, 44, 34, 110, 97, 109, 101, 34, 58, 34, 70, 49, 68, 67, 108, 97, 70, 69, + 122, 105, 51, 116, 34, 44, 34, 118, 101, 114, 115, 105, 111, 110, 34, 58, 34, + 49, 46, 48, 46, 48, 34, 44, 34, 97, 116, 116, 114, 78, 97, 109, 101, 115, 34, + 58, 91, 34, 70, 105, 114, 115, 116, 32, 78, 97, 109, 101, 34, 93, 125, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ], signature: RwLock::new(None), hash: None, @@ -252,9 +260,9 @@ pub mod test { } #[rstest] - #[case::name_not_provided("", SCHEMA_VERSION, &SCHEMA_ATTRIBUTES)] - #[case::version_not_provided(SCHEMA_NAME, "", &SCHEMA_ATTRIBUTES)] - #[case::attributes_not_provided(SCHEMA_NAME, SCHEMA_VERSION, &HashSet::new())] + #[case::name_not_provided("", SCHEMA_VERSION, & SCHEMA_ATTRIBUTES)] + #[case::version_not_provided(SCHEMA_NAME, "", & SCHEMA_ATTRIBUTES)] + #[case::attributes_not_provided(SCHEMA_NAME, SCHEMA_VERSION, & HashSet::new())] async fn build_create_schema_transaction_errors( #[case] name: &str, #[case] version: &str, @@ -291,9 +299,9 @@ pub mod test { nonce: None, chain_id: CONFIG.chain_id, data: vec![ - 174, 190, 203, 28, 34, 27, 23, 130, 143, 227, 3, 94, 147, 14, 185, 63, 10, 50, - 145, 115, 71, 104, 106, 145, 232, 190, 123, 84, 240, 64, 217, 94, 167, 52, 119, - 152, + 174, 190, 203, 28, 157, 102, 193, 205, 103, 90, 204, 163, 183, 21, 33, 209, + 148, 81, 176, 246, 13, 62, 210, 245, 196, 121, 156, 18, 158, 90, 17, 4, 158, + 115, 117, 188, ], signature: RwLock::new(None), hash: None, diff --git a/vdr/src/contracts/cl/types/credential_definition.rs b/vdr/src/contracts/cl/types/credential_definition.rs index d65e46fe..58e7fb15 100644 --- a/vdr/src/contracts/cl/types/credential_definition.rs +++ b/vdr/src/contracts/cl/types/credential_definition.rs @@ -29,11 +29,27 @@ pub struct CredentialDefinition { } impl CredentialDefinition { + pub fn new( + issuer_id: DID, + schema_id: SchemaId, + cred_def_type: SignatureType, + tag: String, + value: serde_json::Value, + ) -> CredentialDefinition { + CredentialDefinition { + issuer_id, + schema_id, + cred_def_type, + tag, + value, + } + } + pub fn id(&self) -> CredentialDefinitionId { - CredentialDefinitionId::build(&self.issuer_id, &self.schema_id, &self.tag) + CredentialDefinitionId::build(&self.issuer_id, &self.schema_id.unique_id(), &self.tag) } - pub fn validate(&self) -> VdrResult<()> { + pub(crate) fn validate(&self) -> VdrResult<()> { if self.tag.is_empty() { return Err(VdrError::InvalidCredentialDefinition( "Tag is not provided".to_string(), @@ -48,6 +64,15 @@ impl CredentialDefinition { Ok(()) } + + pub fn from_string(value: &str) -> VdrResult { + serde_json::from_str(value).map_err(|err| { + VdrError::InvalidCredentialDefinition(format!( + "Unable to parse Credential Definition from JSON. Err: {:?}", + err.to_string() + )) + }) + } } #[derive(Debug, Default, Clone, PartialEq, Deserialize, Serialize)] diff --git a/vdr/src/contracts/cl/types/credential_definition_id.rs b/vdr/src/contracts/cl/types/credential_definition_id.rs index efd66e94..da42660d 100644 --- a/vdr/src/contracts/cl/types/credential_definition_id.rs +++ b/vdr/src/contracts/cl/types/credential_definition_id.rs @@ -1,5 +1,6 @@ -use crate::{contracts::did::types::did::DID, types::ContractParam, SchemaId, VdrError}; +use crate::{contracts::did::types::did::DID, types::ContractParam, VdrError, VdrResult}; +use crate::contracts::types::did::ParsedDid; use serde_derive::{Deserialize, Serialize}; use sha3::Digest; @@ -9,22 +10,26 @@ pub struct CredentialDefinitionId(String); impl CredentialDefinitionId { const ID_PATH: &'static str = "anoncreds/v0/CLAIM_DEF"; - pub fn build(issuer_id: &DID, schema_id: &SchemaId, tag: &str) -> CredentialDefinitionId { + pub fn build(issuer_id: &DID, schema_id: &str, tag: &str) -> CredentialDefinitionId { CredentialDefinitionId::from( format!( "{}/{}/{}/{}", issuer_id.as_ref(), Self::ID_PATH, - schema_id.unique_id(), + schema_id, tag ) .as_str(), ) } - pub fn hash(&self) -> Vec { + pub(crate) fn hash(&self) -> Vec { sha3::Keccak256::digest(self.0.as_bytes()).to_vec() } + + pub fn without_network(&self) -> VdrResult { + ParsedCredentialDefinitionId::try_from(self)?.as_short_id() + } } impl TryFrom<&CredentialDefinitionId> for ContractParam { @@ -52,3 +57,42 @@ impl ToString for CredentialDefinitionId { self.0.to_string() } } + +#[derive(Debug, Default, Clone, PartialEq, Deserialize, Serialize)] +pub(crate) struct ParsedCredentialDefinitionId { + pub(crate) issuer_id: DID, + pub(crate) schema_id: String, + pub(crate) tag: String, + pub(crate) network: Option, +} + +impl ParsedCredentialDefinitionId { + pub(crate) fn as_short_id(&self) -> VdrResult { + Ok(CredentialDefinitionId::build( + &self.issuer_id.without_network()?, + &self.schema_id, + &self.tag, + )) + } +} + +impl TryFrom<&CredentialDefinitionId> for ParsedCredentialDefinitionId { + type Error = VdrError; + + fn try_from(cred_def_id: &CredentialDefinitionId) -> Result { + let parts = cred_def_id.as_ref().split('/').collect::>(); + if parts.len() != 6 { + return Err(VdrError::CommonInvalidData( + "Invalid credential definition id provided".to_string(), + )); + } + let issuer_id = DID::from(parts[0]); + let parsed_issuer_id = ParsedDid::try_from(&issuer_id)?; + Ok(ParsedCredentialDefinitionId { + issuer_id: DID::from(parts[0]), + schema_id: parts[3].to_string(), + tag: parts[4].to_string(), + network: parsed_issuer_id.network, + }) + } +} diff --git a/vdr/src/contracts/cl/types/schema.rs b/vdr/src/contracts/cl/types/schema.rs index fdf91f72..db6ec790 100644 --- a/vdr/src/contracts/cl/types/schema.rs +++ b/vdr/src/contracts/cl/types/schema.rs @@ -26,11 +26,25 @@ pub struct Schema { } impl Schema { + pub fn new( + issuer_id: DID, + name: String, + version: String, + attr_names: HashSet, + ) -> Schema { + Schema { + issuer_id, + name, + version, + attr_names, + } + } + pub fn id(&self) -> SchemaId { SchemaId::build(&self.issuer_id, &self.name, &self.version) } - pub fn validate(&self) -> VdrResult<()> { + pub(crate) fn validate(&self) -> VdrResult<()> { if self.name.is_empty() { return Err(VdrError::InvalidSchema("Name is not provided".to_string())); } @@ -49,6 +63,15 @@ impl Schema { Ok(()) } + + pub fn from_string(value: &str) -> VdrResult { + serde_json::from_str(value).map_err(|err| { + VdrError::InvalidSchema(format!( + "Unable to parse Schema from JSON. Err: {:?}", + err.to_string() + )) + }) + } } #[derive(Debug, Default, Clone, PartialEq, Deserialize, Serialize)] diff --git a/vdr/src/contracts/cl/types/schema_id.rs b/vdr/src/contracts/cl/types/schema_id.rs index f5b4e7f5..da763ced 100644 --- a/vdr/src/contracts/cl/types/schema_id.rs +++ b/vdr/src/contracts/cl/types/schema_id.rs @@ -1,5 +1,6 @@ -use crate::{contracts::did::types::did::DID, types::ContractParam, VdrError}; +use crate::{contracts::did::types::did::DID, types::ContractParam, VdrError, VdrResult}; +use crate::contracts::types::did::ParsedDid; use serde_derive::{Deserialize, Serialize}; use sha3::Digest; @@ -28,9 +29,13 @@ impl SchemaId { self.0.replace(Self::ID_PATH, "").replace('/', ":") } - pub fn hash(&self) -> Vec { + pub(crate) fn hash(&self) -> Vec { sha3::Keccak256::digest(self.0.as_bytes()).to_vec() } + + pub fn without_network(&self) -> VdrResult { + ParsedSchemaId::try_from(self)?.as_short_id() + } } impl TryFrom<&SchemaId> for ContractParam { @@ -58,3 +63,42 @@ impl ToString for SchemaId { self.0.to_string() } } + +#[derive(Debug, Default, Clone, PartialEq, Deserialize, Serialize)] +pub(crate) struct ParsedSchemaId { + pub(crate) issuer_id: DID, + pub(crate) name: String, + pub(crate) version: String, + pub(crate) network: Option, +} + +impl ParsedSchemaId { + pub(crate) fn as_short_id(&self) -> VdrResult { + Ok(SchemaId::build( + &self.issuer_id.without_network()?, + &self.name, + &self.version, + )) + } +} + +impl TryFrom<&SchemaId> for ParsedSchemaId { + type Error = VdrError; + + fn try_from(schema_id: &SchemaId) -> Result { + let parts = schema_id.as_ref().split('/').collect::>(); + if parts.len() != 6 { + return Err(VdrError::CommonInvalidData( + "Invalid schema id provided".to_string(), + )); + } + let issuer_id = DID::from(parts[0]); + let parsed_issuer_id = ParsedDid::try_from(&issuer_id)?; + Ok(ParsedSchemaId { + issuer_id: DID::from(parts[0]), + name: parts[3].to_string(), + version: parts[4].to_string(), + network: parsed_issuer_id.network, + }) + } +} diff --git a/vdr/src/contracts/did/types/did.rs b/vdr/src/contracts/did/types/did.rs index 78afc4cd..9e67286a 100644 --- a/vdr/src/contracts/did/types/did.rs +++ b/vdr/src/contracts/did/types/did.rs @@ -1,4 +1,4 @@ -use crate::{types::ContractOutput, ContractParam, VdrError}; +use crate::{types::ContractOutput, ContractParam, VdrError, VdrResult}; use serde_derive::{Deserialize, Serialize}; pub const DID_PREFIX: &str = "did"; @@ -14,6 +14,10 @@ impl DID { DID(format!("{}:{}:{}", DID_PREFIX, method, id)) } } + + pub fn without_network(&self) -> VdrResult { + Ok(ParsedDid::try_from(self)?.as_short_did()) + } } impl From<&str> for DID { diff --git a/vdr/src/contracts/migration/legacy_mapping_registry.rs b/vdr/src/contracts/migration/legacy_mapping_registry.rs index 79e1680f..871431b2 100644 --- a/vdr/src/contracts/migration/legacy_mapping_registry.rs +++ b/vdr/src/contracts/migration/legacy_mapping_registry.rs @@ -52,7 +52,7 @@ pub async fn build_create_did_mapping_transaction( .set_method(METHOD_CREATE_DID_MAPPING) .add_param(&identity)? .add_param(legacy_identifier)? - .add_param(did)? + .add_param(&did.without_network()?)? .add_param(legacy_verkey)? .add_param(ed25519_signature)? .set_type(TransactionType::Write) @@ -88,7 +88,7 @@ pub async fn build_create_did_mapping_endorsing_data( .add_param(&identity)? .add_param(&MethodStringParam::from(METHOD_CREATE_DID_MAPPING))? .add_param(legacy_identifier)? - .add_param(did)? + .add_param(&did.without_network()?)? .add_param(legacy_verkey)? .add_param(ed25519_signature)? .build(client) @@ -130,7 +130,7 @@ pub async fn build_create_did_mapping_signed_transaction( .add_param(&signature.r())? .add_param(&signature.s())? .add_param(legacy_identifier)? - .add_param(did)? + .add_param(&did.without_network()?)? .add_param(legacy_verkey)? .add_param(ed25519_signature)? .set_type(TransactionType::Write) diff --git a/vdr/uniffi/src/ffi/client.rs b/vdr/uniffi/src/ffi/client.rs index f17de2ed..ba76c229 100644 --- a/vdr/uniffi/src/ffi/client.rs +++ b/vdr/uniffi/src/ffi/client.rs @@ -21,6 +21,7 @@ impl LedgerClient { chain_id: u64, node_address: String, contract_configs: Vec, + network: Option, quorum_config: Option, ) -> VdrResult { let contract_configs: Vec = contract_configs @@ -32,6 +33,7 @@ impl LedgerClient { chain_id, &node_address, &contract_configs, + network.as_deref(), quorum_config.as_ref(), )?; Ok(LedgerClient { client }) diff --git a/vdr/wasm/demo/node/src/main.ts b/vdr/wasm/demo/node/src/main.ts index 2df82c43..16dcd502 100644 --- a/vdr/wasm/demo/node/src/main.ts +++ b/vdr/wasm/demo/node/src/main.ts @@ -14,6 +14,7 @@ const identity = { address: '0xce70ce892768d46caf120b600dec29ed20198982', secret: Uint8Array.from([126, 218, 51, 235, 106, 56, 168, 226, 49, 234, 92, 61, 233, 13, 242, 75, 137, 130, 228, 222, 148, 239, 14, 63, 135, 13, 140, 163, 134, 166, 49, 50]) } +const network = 'test' function sign(message: Uint8Array, key: Uint8Array) { let signature = secp256k1.ecdsaSign(message, key) @@ -44,7 +45,7 @@ async function demo() { ] - const client = new LedgerClient(config.chainId, config.nodeAddress, contractConfigs, null) + const client = new LedgerClient(config.chainId, config.nodeAddress, contractConfigs, network, null) const status = await client.ping() console.log('Status: ' + JSON.stringify(status, null, 2)) diff --git a/vdr/wasm/src/client.rs b/vdr/wasm/src/client.rs index e4834c5c..03e6c0b7 100644 --- a/vdr/wasm/src/client.rs +++ b/vdr/wasm/src/client.rs @@ -21,6 +21,7 @@ impl LedgerClientWrapper { chain_id: u32, node_address: String, contract_configs: JsValue, + network: Option, quorum_config: JsValue, ) -> Result { console_error_panic_hook::set_once(); @@ -32,6 +33,7 @@ impl LedgerClientWrapper { chain_id as u64, &node_address, &contract_configs, + network.as_deref(), quorum_config.as_ref(), ) .as_js()?; diff --git a/vdr/wrappers/python/demo/test.py b/vdr/wrappers/python/demo/test.py index a652bd92..5408e1be 100644 --- a/vdr/wrappers/python/demo/test.py +++ b/vdr/wrappers/python/demo/test.py @@ -7,10 +7,6 @@ from eth_keys import keys from indy_besu_vdr import * -# chain id of the running network -chain_id = 1337 -# address of an RPC node connected to the network -node_address = 'http://127.0.0.1:8545' # Account address to use for sending transactions trustee = { "address": '0xf0e2db6c8dc6c681bb5d6ad121a107f300e9b2b5', @@ -20,6 +16,7 @@ "address": '0xce70ce892768d46caf120b600dec29ed20198982', "secret": '7eda33eb6a38a8e231ea5c3de90df24b8982e4de94ef0e3f870d8ca386a63132' } +network = 'test' project_root = f"{os.getcwd()}/../../.." def sign(secret: str, data: bytes): @@ -50,7 +47,7 @@ async def demo(): ContractConfig(did_contract_address, did_contract_spec_path, None), ContractConfig(schema_contract_address, schema_contract_spec_path, None), ] - client = LedgerClient(config["chainId"], config["nodeAddress"], contract_configs, None) + client = LedgerClient(config["chainId"], config["nodeAddress"], contract_configs, network, None) status = await client.ping() print(' Status: ' + str(status)) diff --git a/vdr/wrappers/python/indy_besu_vdr/indy_besu_vdr.py b/vdr/wrappers/python/indy_besu_vdr/indy_besu_vdr.py index c5c704af..74a37750 100644 --- a/vdr/wrappers/python/indy_besu_vdr/indy_besu_vdr.py +++ b/vdr/wrappers/python/indy_besu_vdr/indy_besu_vdr.py @@ -633,7 +633,7 @@ def _uniffi_check_api_checksums(lib): raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_indy_besu_vdr_uniffi_checksum_constructor_eventquery_new() != 57276: raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - if lib.uniffi_indy_besu_vdr_uniffi_checksum_constructor_ledgerclient_new() != 17350: + if lib.uniffi_indy_besu_vdr_uniffi_checksum_constructor_ledgerclient_new() != 954: raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_indy_besu_vdr_uniffi_checksum_constructor_transaction_new() != 38765: raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") @@ -676,6 +676,7 @@ def _uniffi_check_api_checksums(lib): _UniffiRustBuffer, _UniffiRustBuffer, _UniffiRustBuffer, + _UniffiRustBuffer, ctypes.POINTER(_UniffiRustCallStatus), ) _UniffiLib.uniffi_indy_besu_vdr_uniffi_fn_constructor_ledgerclient_new.restype = ctypes.c_void_p @@ -1949,19 +1950,22 @@ def submit_transaction(self, transaction: "Transaction"): class LedgerClient: _pointer: ctypes.c_void_p - def __init__(self, chain_id: "int",node_address: "str",contract_configs: "typing.List[ContractConfig]",quorum_config: "typing.Optional[QuorumConfig]"): + def __init__(self, chain_id: "int",node_address: "str",contract_configs: "typing.List[ContractConfig]",network: "typing.Optional[str]",quorum_config: "typing.Optional[QuorumConfig]"): _UniffiConverterUInt64.check_lower(chain_id) _UniffiConverterString.check_lower(node_address) _UniffiConverterSequenceTypeContractConfig.check_lower(contract_configs) + _UniffiConverterOptionalString.check_lower(network) + _UniffiConverterOptionalTypeQuorumConfig.check_lower(quorum_config) self._pointer = _rust_call_with_error(_UniffiConverterTypeVdrError,_UniffiLib.uniffi_indy_besu_vdr_uniffi_fn_constructor_ledgerclient_new, _UniffiConverterUInt64.lower(chain_id), _UniffiConverterString.lower(node_address), _UniffiConverterSequenceTypeContractConfig.lower(contract_configs), + _UniffiConverterOptionalString.lower(network), _UniffiConverterOptionalTypeQuorumConfig.lower(quorum_config)) def __del__(self):