From 1a52f44961c89f938723852cc05d2213583b9fa8 Mon Sep 17 00:00:00 2001 From: Alexander Cyon Date: Thu, 23 Jan 2025 09:20:36 +0100 Subject: [PATCH 01/25] [no ci] WIP --- ...ests_securify_shield_securified_entitiy.rs | 166 ++++++++++++++++++ .../src/manifests_security_shield/mod.rs | 2 + 2 files changed, 168 insertions(+) create mode 100644 crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entitiy.rs diff --git a/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entitiy.rs b/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entitiy.rs new file mode 100644 index 000000000..c995ee4d3 --- /dev/null +++ b/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entitiy.rs @@ -0,0 +1,166 @@ +use profile_supporting_types::AnySecurifiedEntity; + +use crate::prelude::*; + +pub trait TransactionManifestSecurifySecurifiedEntity: Sized { + fn apply_security_shield_for_securified_entity( + securified_entity: AnySecurifiedEntity, + input: TransactionManifestApplySecurityShieldSecurifiedInput, + ) -> Result; +} + +impl TransactionManifestSecurifySecurifiedEntity for TransactionManifest { + fn apply_security_shield_for_securified_entity( + _securified_entity: AnySecurifiedEntity, + _input: TransactionManifestApplySecurityShieldSecurifiedInput, + ) -> Result { + // let TransactionManifestApplySecurityShieldSecurifiedInput { + // security_structure_of_factor_instances, + // apply_shield_manifest_kind, + // } = input.clone(); + + // let builder = ManifestBuilder::new(); + // let access_controller_address = securified_entity + // .securified_entity_control + // .access_controller_address; + + // let should_start_recovery = + // apply_shield_manifest_kind.should_confirm_recovery(); + // if should_start_recovery { + // // builder.call_method(access_controller_address, , arguments) + // todo!(); + // } + todo!("Implement in coming PR") + } +} + +impl TransactionManifestApplySecurityShieldKindSelector { + fn should_confirm_recovery_with_explicit(&self) -> bool { + match self { + Self::PrimaryAndRecoveryWithExplicitConfirmation => true, + Self::PrimaryAndRecoveryWithTimedAutoConfirm => false, + Self::PrimaryAndExplicitConfirmation => true, + Self::PrimaryWithTimedAutoConfirm => false, + Self::RecoveryAndExplicitConfirmation => true, + Self::RecoveryWithTimedAutoConfirm => false, + } + } + fn should_confirm_recovery_with_time(&self) -> bool { + match self { + Self::PrimaryAndRecoveryWithExplicitConfirmation => false, + Self::PrimaryAndRecoveryWithTimedAutoConfirm => true, + Self::PrimaryAndExplicitConfirmation => false, + Self::PrimaryWithTimedAutoConfirm => true, + Self::RecoveryAndExplicitConfirmation => false, + Self::RecoveryWithTimedAutoConfirm => true, + } + } + fn should_confirm_recovery(&self) -> bool { + self.should_confirm_recovery_with_explicit() + || self.should_confirm_recovery_with_time() + } +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum TransactionManifestApplySecurityShieldKindSelector { + /// (Primary Recovery Confirmation) + PrimaryAndRecoveryWithExplicitConfirmation, + + /// (Primary Recovery Time) + PrimaryAndRecoveryWithTimedAutoConfirm, + + /// (Primary Confirmation) + PrimaryAndExplicitConfirmation, + + /// (Primary Time) ‼️ REQUIRES "Dugong" ‼️ + PrimaryWithTimedAutoConfirm, + + /// (Recovery Confirmation) + RecoveryAndExplicitConfirmation, + + /// (Recovery Time) + RecoveryWithTimedAutoConfirm, +} + +#[derive(Debug, Clone)] +pub struct TransactionManifestApplySecurityShieldAnyInput { + pub security_structure_of_factor_instances: + SecurityStructureOfFactorInstances, + pub apply_shield_manifest_kind: + Option, +} +impl TransactionManifestApplySecurityShieldAnyInput { + fn new( + security_structure_of_factor_instances: + SecurityStructureOfFactorInstances, + apply_shield_manifest_kind: impl Into< + Option, + >, + ) -> Self { + Self { + security_structure_of_factor_instances, + apply_shield_manifest_kind: apply_shield_manifest_kind.into(), + } + } + pub fn for_securified( + security_structure_of_factor_instances: + SecurityStructureOfFactorInstances, + apply_shield_manifest_kind: TransactionManifestApplySecurityShieldKindSelector, + ) -> Self { + Self::new( + security_structure_of_factor_instances, + apply_shield_manifest_kind, + ) + } + pub fn as_securified( + &self, + ) -> Result { + let apply_shield_manifest_kind = self + .apply_shield_manifest_kind + .clone() + .ok_or(CommonError::Unknown)?; // TODO: replace with proper error + Ok(TransactionManifestApplySecurityShieldSecurifiedInput { + security_structure_of_factor_instances: self + .security_structure_of_factor_instances + .clone(), + apply_shield_manifest_kind, + }) + } + pub fn for_unsecurified( + security_structure_of_factor_instances: + SecurityStructureOfFactorInstances, + ) -> Self { + Self::new(security_structure_of_factor_instances, None) + } + + pub fn as_unsecurified( + &self, + ) -> Result { + Ok(TransactionManifestApplySecurityShieldUnsecurifiedInput { + security_structure_of_factor_instances: self + .security_structure_of_factor_instances + .clone(), + }) + } +} + +#[derive(Debug, Clone)] +pub struct TransactionManifestApplySecurityShieldSecurifiedInput { + pub security_structure_of_factor_instances: + SecurityStructureOfFactorInstances, + pub apply_shield_manifest_kind: + TransactionManifestApplySecurityShieldKindSelector, +} + +impl TransactionManifestApplySecurityShieldSecurifiedInput { + pub fn new( + security_structure_of_factor_instances: + SecurityStructureOfFactorInstances, + apply_shield_manifest_kind: TransactionManifestApplySecurityShieldKindSelector, + ) -> Self { + Self { + security_structure_of_factor_instances, + apply_shield_manifest_kind, + } + } +} diff --git a/crates/transaction/manifests/src/manifests_security_shield/mod.rs b/crates/transaction/manifests/src/manifests_security_shield/mod.rs index 8e47aa265..3193d4cc9 100644 --- a/crates/transaction/manifests/src/manifests_security_shield/mod.rs +++ b/crates/transaction/manifests/src/manifests_security_shield/mod.rs @@ -1,6 +1,8 @@ #[allow(clippy::module_inception)] mod manifests_security_shield; mod top_up_access_controller_xrd_vault; +mod manifests_securify_shield_securified_entitiy; pub use manifests_security_shield::*; pub use top_up_access_controller_xrd_vault::*; +pub use manifests_securify_shield_securified_entitiy::*; From fdea7487e32e3d4c2a8b6f3d42b6384ba18c6b54 Mon Sep 17 00:00:00 2001 From: Alexander Cyon Date: Thu, 23 Jan 2025 09:58:39 +0100 Subject: [PATCH 02/25] [no ci] wip --- ...ests_securify_shield_securified_entity.rs} | 7 +++-- ...ts_securify_shield_unsecurified_entity.rs} | 30 +++---------------- .../src/manifests_security_shield/mod.rs | 11 +++---- .../manifests_security_shield/set_rola_key.rs | 30 +++++++++++++++++++ 4 files changed, 45 insertions(+), 33 deletions(-) rename crates/transaction/manifests/src/manifests_security_shield/{manifests_securify_shield_securified_entitiy.rs => manifests_securify_shield_securified_entity.rs} (97%) rename crates/transaction/manifests/src/manifests_security_shield/{manifests_security_shield.rs => manifests_securify_shield_unsecurified_entity.rs} (92%) create mode 100644 crates/transaction/manifests/src/manifests_security_shield/set_rola_key.rs diff --git a/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entitiy.rs b/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs similarity index 97% rename from crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entitiy.rs rename to crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs index c995ee4d3..c506b57e0 100644 --- a/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entitiy.rs +++ b/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs @@ -1,8 +1,11 @@ +#![allow(dead_code)] use profile_supporting_types::AnySecurifiedEntity; use crate::prelude::*; -pub trait TransactionManifestSecurifySecurifiedEntity: Sized { +pub trait TransactionManifestSecurifySecurifiedEntity: + Sized + TransactionManifestSetRolaKey +{ fn apply_security_shield_for_securified_entity( securified_entity: AnySecurifiedEntity, input: TransactionManifestApplySecurityShieldSecurifiedInput, @@ -30,7 +33,7 @@ impl TransactionManifestSecurifySecurifiedEntity for TransactionManifest { // // builder.call_method(access_controller_address, , arguments) // todo!(); // } - todo!("Implement in coming PR") + todo!("implement me") } } diff --git a/crates/transaction/manifests/src/manifests_security_shield/manifests_security_shield.rs b/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_unsecurified_entity.rs similarity index 92% rename from crates/transaction/manifests/src/manifests_security_shield/manifests_security_shield.rs rename to crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_unsecurified_entity.rs index 43d797ccf..78735b693 100644 --- a/crates/transaction/manifests/src/manifests_security_shield/manifests_security_shield.rs +++ b/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_unsecurified_entity.rs @@ -8,7 +8,6 @@ use radix_engine_interface::blueprints::{ }, account::AccountSecurifyManifestInput as ScryptoAccountSecurifyManifestInput, }; -use radix_transactions::prelude::ManifestBuilder; use crate::prelude::*; @@ -29,37 +28,16 @@ impl TransactionManifestApplySecurityShieldUnsecurifiedInput { } } -pub trait TransactionManifestSecurifyEntity: Sized { +pub trait TransactionManifestSecurifyUnsecurifiedEntity: + Sized + TransactionManifestSetRolaKey +{ fn apply_security_shield_for_unsecurified_entity( unsecurified_entity: AnyUnsecurifiedEntity, input: TransactionManifestApplySecurityShieldUnsecurifiedInput, ) -> Result; - - fn set_rola_key( - builder: ManifestBuilder, - authentication_signing_factor_instance: &HierarchicalDeterministicFactorInstance, - entity_address: &AddressOfAccountOrPersona, - ) -> ManifestBuilder; } -impl TransactionManifestSecurifyEntity for TransactionManifest { - fn set_rola_key( - builder: ManifestBuilder, - authentication_signing_factor_instance: - &HierarchicalDeterministicFactorInstance, - entity_address: &AddressOfAccountOrPersona, - ) -> ManifestBuilder { - let rola_key_hash = PublicKeyHash::hash( - authentication_signing_factor_instance.public_key(), - ); - let owner_key_hashes = vec![rola_key_hash]; - Self::set_owner_keys_hashes_on_builder( - entity_address, - owner_key_hashes, - builder, - ) - } - +impl TransactionManifestSecurifyUnsecurifiedEntity for TransactionManifest { /// We do NOT top of XRD vault of AccessController - yet! /// Host will need to call the function: /// `modify_manifest_add_withdraw_of_xrd_for_access_controller_xrd_vault_top_up_paid_by_account` diff --git a/crates/transaction/manifests/src/manifests_security_shield/mod.rs b/crates/transaction/manifests/src/manifests_security_shield/mod.rs index 3193d4cc9..2af88dd1a 100644 --- a/crates/transaction/manifests/src/manifests_security_shield/mod.rs +++ b/crates/transaction/manifests/src/manifests_security_shield/mod.rs @@ -1,8 +1,9 @@ -#[allow(clippy::module_inception)] -mod manifests_security_shield; +mod manifests_securify_shield_securified_entity; +mod manifests_securify_shield_unsecurified_entity; +mod set_rola_key; mod top_up_access_controller_xrd_vault; -mod manifests_securify_shield_securified_entitiy; -pub use manifests_security_shield::*; +pub use manifests_securify_shield_securified_entity::*; +pub use manifests_securify_shield_unsecurified_entity::*; +pub use set_rola_key::*; pub use top_up_access_controller_xrd_vault::*; -pub use manifests_securify_shield_securified_entitiy::*; diff --git a/crates/transaction/manifests/src/manifests_security_shield/set_rola_key.rs b/crates/transaction/manifests/src/manifests_security_shield/set_rola_key.rs new file mode 100644 index 000000000..bf96273c7 --- /dev/null +++ b/crates/transaction/manifests/src/manifests_security_shield/set_rola_key.rs @@ -0,0 +1,30 @@ +use radix_transactions::prelude::ManifestBuilder; + +use crate::prelude::*; + +pub trait TransactionManifestSetRolaKey: Sized { + fn set_rola_key( + builder: ManifestBuilder, + authentication_signing_factor_instance: &HierarchicalDeterministicFactorInstance, + entity_address: &AddressOfAccountOrPersona, + ) -> ManifestBuilder; +} + +impl TransactionManifestSetRolaKey for TransactionManifest { + fn set_rola_key( + builder: ManifestBuilder, + authentication_signing_factor_instance: + &HierarchicalDeterministicFactorInstance, + entity_address: &AddressOfAccountOrPersona, + ) -> ManifestBuilder { + let rola_key_hash = PublicKeyHash::hash( + authentication_signing_factor_instance.public_key(), + ); + let owner_key_hashes = vec![rola_key_hash]; + Self::set_owner_keys_hashes_on_builder( + entity_address, + owner_key_hashes, + builder, + ) + } +} From 90159251a91628506b09add37cbe46861b9d1874 Mon Sep 17 00:00:00 2001 From: Alexander Cyon Date: Thu, 23 Jan 2025 10:54:00 +0100 Subject: [PATCH 03/25] [no ci] wip --- .../src/abstract_securified_entity.rs | 4 + ...fests_securify_shield_securified_entity.rs | 100 ++++++++++++++---- 2 files changed, 83 insertions(+), 21 deletions(-) diff --git a/crates/profile/models/supporting-types/src/abstract_securified_entity.rs b/crates/profile/models/supporting-types/src/abstract_securified_entity.rs index b99ca27e0..bf2733322 100644 --- a/crates/profile/models/supporting-types/src/abstract_securified_entity.rs +++ b/crates/profile/models/supporting-types/src/abstract_securified_entity.rs @@ -62,6 +62,10 @@ impl Into::::into(self.entity.address()) } + pub fn current_authentication_signing_factor_instance(&self) -> HierarchicalDeterministicFactorInstance { +self.securified_entity_control().authentication_signing_factor_instance() + } + pub fn veci(&self) -> Option { self.securified_entity_control() .veci() diff --git a/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs b/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs index c506b57e0..cc9f7bc0d 100644 --- a/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs +++ b/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs @@ -4,40 +4,96 @@ use profile_supporting_types::AnySecurifiedEntity; use crate::prelude::*; pub trait TransactionManifestSecurifySecurifiedEntity: - Sized + TransactionManifestSetRolaKey + TransactionManifestSetRolaKey { fn apply_security_shield_for_securified_entity( securified_entity: AnySecurifiedEntity, input: TransactionManifestApplySecurityShieldSecurifiedInput, - ) -> Result; + ) -> Result; + + fn _update_shield_exercising_recovery_and_explicit_confirmation( + builder: ScryptoTransactionManifestBuilder, + securified_entity: &AnySecurifiedEntity, + input: &TransactionManifestApplySecurityShieldSecurifiedInput, + ) -> Result { + todo!() + } } impl TransactionManifestSecurifySecurifiedEntity for TransactionManifest { fn apply_security_shield_for_securified_entity( - _securified_entity: AnySecurifiedEntity, - _input: TransactionManifestApplySecurityShieldSecurifiedInput, + securified_entity: AnySecurifiedEntity, + input: TransactionManifestApplySecurityShieldSecurifiedInput, ) -> Result { - // let TransactionManifestApplySecurityShieldSecurifiedInput { - // security_structure_of_factor_instances, - // apply_shield_manifest_kind, - // } = input.clone(); - - // let builder = ManifestBuilder::new(); - // let access_controller_address = securified_entity - // .securified_entity_control - // .access_controller_address; - - // let should_start_recovery = - // apply_shield_manifest_kind.should_confirm_recovery(); - // if should_start_recovery { - // // builder.call_method(access_controller_address, , arguments) - // todo!(); - // } - todo!("implement me") + let TransactionManifestApplySecurityShieldSecurifiedInput { + security_structure_of_factor_instances, + apply_shield_manifest_kind: kind, + } = input.clone(); + + let entity_address = securified_entity.entity.address(); + + let mut builder = ScryptoTransactionManifestBuilder::new(); + + use TransactionManifestApplySecurityShieldKindSelector::*; + builder = match kind { + PrimaryAndRecoveryWithExplicitConfirmation => Self::_update_shield_exercising_recovery_and_explicit_confirmation(builder, &securified_entity, &input)?, + PrimaryAndRecoveryWithTimedAutoConfirm => todo!(), + PrimaryAndExplicitConfirmation => todo!(), + PrimaryWithTimedAutoConfirm => todo!(), + RecoveryAndExplicitConfirmation => todo!(), + RecoveryWithTimedAutoConfirm => todo!(), + }; + + // Set Rola Key + let should_set_rola_key = security_structure_of_factor_instances + .authentication_signing_factor_instance + != securified_entity + .current_authentication_signing_factor_instance(); + if should_set_rola_key { + if kind.can_set_rola_key() { + builder = TransactionManifest::set_rola_key( + builder, + &security_structure_of_factor_instances + .authentication_signing_factor_instance, + &entity_address, + ); + } else { + return Err(CommonError::Unknown); // TODO: new error variant + } + } + + let manifest = TransactionManifest::sargon_built( + builder, + securified_entity.network_id(), + ); + + // N.B. + // We do NOT top of XRD vault of AccessController - yet! + // Host will need to call the function: + // `modify_manifest_add_withdraw_of_xrd_for_access_controller_xrd_vault_top_up_paid_by_account` + // after user has selected account to pay in wallet GUI. + // (and as usual also call `modify_manifest_lock_fee`) + + Ok(manifest) } } impl TransactionManifestApplySecurityShieldKindSelector { + fn can_exercise_primary_role(&self) -> bool { + match self { + Self::PrimaryAndRecoveryWithExplicitConfirmation => true, + Self::PrimaryAndRecoveryWithTimedAutoConfirm => true, + Self::PrimaryAndExplicitConfirmation => true, + Self::PrimaryWithTimedAutoConfirm => true, + Self::RecoveryAndExplicitConfirmation => false, + Self::RecoveryWithTimedAutoConfirm => false, + } + } + + fn can_set_rola_key(&self) -> bool { + self.can_exercise_primary_role() + } + fn should_confirm_recovery_with_explicit(&self) -> bool { match self { Self::PrimaryAndRecoveryWithExplicitConfirmation => true, @@ -48,6 +104,7 @@ impl TransactionManifestApplySecurityShieldKindSelector { Self::RecoveryWithTimedAutoConfirm => false, } } + fn should_confirm_recovery_with_time(&self) -> bool { match self { Self::PrimaryAndRecoveryWithExplicitConfirmation => false, @@ -58,6 +115,7 @@ impl TransactionManifestApplySecurityShieldKindSelector { Self::RecoveryWithTimedAutoConfirm => true, } } + fn should_confirm_recovery(&self) -> bool { self.should_confirm_recovery_with_explicit() || self.should_confirm_recovery_with_time() From e7fd884560a2171285a589355abcf65ee4e5cc51 Mon Sep 17 00:00:00 2001 From: Alexander Cyon Date: Fri, 24 Jan 2025 09:59:07 +0100 Subject: [PATCH 04/25] first initial impl of manifests for updating securified entities --- .../src/abstract_securified_entity.rs | 7 +- ...ccess_controller_factors_and_time_input.rs | 100 +++++++++ ...fests_securify_shield_securified_entity.rs | 204 ++++-------------- ...sts_securify_shield_unsecurified_entity.rs | 44 +--- .../src/manifests_security_shield/mod.rs | 10 + ...anifest_apply_security_shield_any_input.rs | 63 ++++++ ...ion_manifest_apply_security_shield_kind.rs | 134 ++++++++++++ ..._apply_security_shield_securified_input.rs | 21 ++ ...nsaction_manifest_owner_badge_producing.rs | 65 ++++++ 9 files changed, 442 insertions(+), 206 deletions(-) create mode 100644 crates/transaction/manifests/src/manifests_security_shield/access_controller_factors_and_time_input.rs create mode 100644 crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_apply_security_shield_any_input.rs create mode 100644 crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_apply_security_shield_kind.rs create mode 100644 crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_apply_security_shield_securified_input.rs create mode 100644 crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_owner_badge_producing.rs diff --git a/crates/profile/models/supporting-types/src/abstract_securified_entity.rs b/crates/profile/models/supporting-types/src/abstract_securified_entity.rs index bf2733322..829412f5c 100644 --- a/crates/profile/models/supporting-types/src/abstract_securified_entity.rs +++ b/crates/profile/models/supporting-types/src/abstract_securified_entity.rs @@ -62,8 +62,11 @@ impl Into::::into(self.entity.address()) } - pub fn current_authentication_signing_factor_instance(&self) -> HierarchicalDeterministicFactorInstance { -self.securified_entity_control().authentication_signing_factor_instance() + pub fn current_authentication_signing_factor_instance( + &self, + ) -> HierarchicalDeterministicFactorInstance { + self.securified_entity_control() + .authentication_signing_factor_instance() } pub fn veci(&self) -> Option { diff --git a/crates/transaction/manifests/src/manifests_security_shield/access_controller_factors_and_time_input.rs b/crates/transaction/manifests/src/manifests_security_shield/access_controller_factors_and_time_input.rs new file mode 100644 index 000000000..b079b289f --- /dev/null +++ b/crates/transaction/manifests/src/manifests_security_shield/access_controller_factors_and_time_input.rs @@ -0,0 +1,100 @@ +use crate::prelude::*; +use radix_engine_interface::blueprints::access_controller::{ + AccessControllerInitiateRecoveryAsPrimaryInput as ScryptoAccessControllerInitiateRecoveryAsPrimaryInput, + AccessControllerInitiateRecoveryAsRecoveryInput as ScryptoAccessControllerInitiateRecoveryAsRecoveryInput, + AccessControllerQuickConfirmPrimaryRoleRecoveryProposalInput as ScryptoAccessControllerQuickConfirmPrimaryRoleRecoveryProposalInput, + AccessControllerQuickConfirmRecoveryRoleRecoveryProposalInput as ScryptoAccessControllerQuickConfirmRecoveryRoleRecoveryProposalInput, + AccessControllerTimedConfirmRecoveryInput as ScryptoAccessControllerTimedConfirmRecoveryInput, +}; + +#[derive(Debug, Clone)] +pub struct AccessControllerFactorsAndTimeInput { + rule_set: ScryptoRuleSet, + timed_recovery_delay_in_minutes: u32, +} + +impl AccessControllerFactorsAndTimeInput { + pub fn new( + security_structure_of_factor_instances: &SecurityStructureOfFactorInstances, + ) -> Self { + let rule_set = ScryptoRuleSet::from( + security_structure_of_factor_instances + .matrix_of_factors + .clone(), + ); + + let timed_recovery_delay_in_minutes = + security_structure_of_factor_instances + .timed_recovery_delay_in_minutes(); + + Self { + rule_set, + timed_recovery_delay_in_minutes, + } + } +} + +impl From<&AccessControllerFactorsAndTimeInput> + for ScryptoAccessControllerInitiateRecoveryAsRecoveryInput +{ + fn from(value: &AccessControllerFactorsAndTimeInput) -> Self { + Self { + rule_set: value.rule_set.clone(), + timed_recovery_delay_in_minutes: Some( + value.timed_recovery_delay_in_minutes, + ), + } + } +} + +impl From<&AccessControllerFactorsAndTimeInput> + for ScryptoAccessControllerInitiateRecoveryAsPrimaryInput +{ + fn from(value: &AccessControllerFactorsAndTimeInput) -> Self { + Self { + rule_set: value.rule_set.clone(), + timed_recovery_delay_in_minutes: Some( + value.timed_recovery_delay_in_minutes, + ), + } + } +} + +impl From<&AccessControllerFactorsAndTimeInput> + for ScryptoAccessControllerQuickConfirmRecoveryRoleRecoveryProposalInput +{ + fn from(value: &AccessControllerFactorsAndTimeInput) -> Self { + Self { + rule_set: value.rule_set.clone(), + timed_recovery_delay_in_minutes: Some( + value.timed_recovery_delay_in_minutes, + ), + } + } +} + +impl From<&AccessControllerFactorsAndTimeInput> + for ScryptoAccessControllerQuickConfirmPrimaryRoleRecoveryProposalInput +{ + fn from(value: &AccessControllerFactorsAndTimeInput) -> Self { + Self { + rule_set: value.rule_set.clone(), + timed_recovery_delay_in_minutes: Some( + value.timed_recovery_delay_in_minutes, + ), + } + } +} + +impl From<&AccessControllerFactorsAndTimeInput> + for ScryptoAccessControllerTimedConfirmRecoveryInput +{ + fn from(value: &AccessControllerFactorsAndTimeInput) -> Self { + Self { + rule_set: value.rule_set.clone(), + timed_recovery_delay_in_minutes: Some( + value.timed_recovery_delay_in_minutes, + ), + } + } +} diff --git a/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs b/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs index cc9f7bc0d..4ed37cd8a 100644 --- a/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs +++ b/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs @@ -1,7 +1,8 @@ #![allow(dead_code)] -use profile_supporting_types::AnySecurifiedEntity; - use crate::prelude::*; +use std::ops::Deref; + +use profile_supporting_types::AnySecurifiedEntity; pub trait TransactionManifestSecurifySecurifiedEntity: TransactionManifestSetRolaKey @@ -10,14 +11,6 @@ pub trait TransactionManifestSecurifySecurifiedEntity: securified_entity: AnySecurifiedEntity, input: TransactionManifestApplySecurityShieldSecurifiedInput, ) -> Result; - - fn _update_shield_exercising_recovery_and_explicit_confirmation( - builder: ScryptoTransactionManifestBuilder, - securified_entity: &AnySecurifiedEntity, - input: &TransactionManifestApplySecurityShieldSecurifiedInput, - ) -> Result { - todo!() - } } impl TransactionManifestSecurifySecurifiedEntity for TransactionManifest { @@ -32,23 +25,46 @@ impl TransactionManifestSecurifySecurifiedEntity for TransactionManifest { let entity_address = securified_entity.entity.address(); - let mut builder = ScryptoTransactionManifestBuilder::new(); + // ACCESS_CONTROLLER_CREATE_PROOF_IDENT + let mut builder = TransactionManifest::produce_owner_badge( + ScryptoTransactionManifestBuilder::new(), + &securified_entity.entity, + ); + + let access_controller_address = securified_entity + .securified_entity_control + .access_controller_address; + + let factors_and_time_input = &AccessControllerFactorsAndTimeInput::new( + &security_structure_of_factor_instances, + ); - use TransactionManifestApplySecurityShieldKindSelector::*; - builder = match kind { - PrimaryAndRecoveryWithExplicitConfirmation => Self::_update_shield_exercising_recovery_and_explicit_confirmation(builder, &securified_entity, &input)?, - PrimaryAndRecoveryWithTimedAutoConfirm => todo!(), - PrimaryAndExplicitConfirmation => todo!(), - PrimaryWithTimedAutoConfirm => todo!(), - RecoveryAndExplicitConfirmation => todo!(), - RecoveryWithTimedAutoConfirm => todo!(), - }; + // INITIATE RECOVERY + let (init_method, init_input) = + kind.input_for_initialization(factors_and_time_input); + builder = builder.call_method( + access_controller_address.scrypto(), + init_method, + (init_input.deref(),), + ); + + // CONFIRM RECOVERY + // TODO: for timed, should we really call it here, now? Should + // we not call it AFTER the time has elapsed??? + let (confirm_method, confirm_input) = + kind.input_for_confirm(factors_and_time_input); + builder = builder.call_method( + access_controller_address.scrypto(), + confirm_method, + (confirm_input.deref(),), + ); // Set Rola Key let should_set_rola_key = security_structure_of_factor_instances .authentication_signing_factor_instance != securified_entity .current_authentication_signing_factor_instance(); + if should_set_rola_key { if kind.can_set_rola_key() { builder = TransactionManifest::set_rola_key( @@ -77,151 +93,3 @@ impl TransactionManifestSecurifySecurifiedEntity for TransactionManifest { Ok(manifest) } } - -impl TransactionManifestApplySecurityShieldKindSelector { - fn can_exercise_primary_role(&self) -> bool { - match self { - Self::PrimaryAndRecoveryWithExplicitConfirmation => true, - Self::PrimaryAndRecoveryWithTimedAutoConfirm => true, - Self::PrimaryAndExplicitConfirmation => true, - Self::PrimaryWithTimedAutoConfirm => true, - Self::RecoveryAndExplicitConfirmation => false, - Self::RecoveryWithTimedAutoConfirm => false, - } - } - - fn can_set_rola_key(&self) -> bool { - self.can_exercise_primary_role() - } - - fn should_confirm_recovery_with_explicit(&self) -> bool { - match self { - Self::PrimaryAndRecoveryWithExplicitConfirmation => true, - Self::PrimaryAndRecoveryWithTimedAutoConfirm => false, - Self::PrimaryAndExplicitConfirmation => true, - Self::PrimaryWithTimedAutoConfirm => false, - Self::RecoveryAndExplicitConfirmation => true, - Self::RecoveryWithTimedAutoConfirm => false, - } - } - - fn should_confirm_recovery_with_time(&self) -> bool { - match self { - Self::PrimaryAndRecoveryWithExplicitConfirmation => false, - Self::PrimaryAndRecoveryWithTimedAutoConfirm => true, - Self::PrimaryAndExplicitConfirmation => false, - Self::PrimaryWithTimedAutoConfirm => true, - Self::RecoveryAndExplicitConfirmation => false, - Self::RecoveryWithTimedAutoConfirm => true, - } - } - - fn should_confirm_recovery(&self) -> bool { - self.should_confirm_recovery_with_explicit() - || self.should_confirm_recovery_with_time() - } -} - -#[derive(Clone, Debug, PartialEq, Eq)] -pub enum TransactionManifestApplySecurityShieldKindSelector { - /// (Primary Recovery Confirmation) - PrimaryAndRecoveryWithExplicitConfirmation, - - /// (Primary Recovery Time) - PrimaryAndRecoveryWithTimedAutoConfirm, - - /// (Primary Confirmation) - PrimaryAndExplicitConfirmation, - - /// (Primary Time) ‼️ REQUIRES "Dugong" ‼️ - PrimaryWithTimedAutoConfirm, - - /// (Recovery Confirmation) - RecoveryAndExplicitConfirmation, - - /// (Recovery Time) - RecoveryWithTimedAutoConfirm, -} - -#[derive(Debug, Clone)] -pub struct TransactionManifestApplySecurityShieldAnyInput { - pub security_structure_of_factor_instances: - SecurityStructureOfFactorInstances, - pub apply_shield_manifest_kind: - Option, -} -impl TransactionManifestApplySecurityShieldAnyInput { - fn new( - security_structure_of_factor_instances: - SecurityStructureOfFactorInstances, - apply_shield_manifest_kind: impl Into< - Option, - >, - ) -> Self { - Self { - security_structure_of_factor_instances, - apply_shield_manifest_kind: apply_shield_manifest_kind.into(), - } - } - pub fn for_securified( - security_structure_of_factor_instances: - SecurityStructureOfFactorInstances, - apply_shield_manifest_kind: TransactionManifestApplySecurityShieldKindSelector, - ) -> Self { - Self::new( - security_structure_of_factor_instances, - apply_shield_manifest_kind, - ) - } - pub fn as_securified( - &self, - ) -> Result { - let apply_shield_manifest_kind = self - .apply_shield_manifest_kind - .clone() - .ok_or(CommonError::Unknown)?; // TODO: replace with proper error - Ok(TransactionManifestApplySecurityShieldSecurifiedInput { - security_structure_of_factor_instances: self - .security_structure_of_factor_instances - .clone(), - apply_shield_manifest_kind, - }) - } - pub fn for_unsecurified( - security_structure_of_factor_instances: - SecurityStructureOfFactorInstances, - ) -> Self { - Self::new(security_structure_of_factor_instances, None) - } - - pub fn as_unsecurified( - &self, - ) -> Result { - Ok(TransactionManifestApplySecurityShieldUnsecurifiedInput { - security_structure_of_factor_instances: self - .security_structure_of_factor_instances - .clone(), - }) - } -} - -#[derive(Debug, Clone)] -pub struct TransactionManifestApplySecurityShieldSecurifiedInput { - pub security_structure_of_factor_instances: - SecurityStructureOfFactorInstances, - pub apply_shield_manifest_kind: - TransactionManifestApplySecurityShieldKindSelector, -} - -impl TransactionManifestApplySecurityShieldSecurifiedInput { - pub fn new( - security_structure_of_factor_instances: - SecurityStructureOfFactorInstances, - apply_shield_manifest_kind: TransactionManifestApplySecurityShieldKindSelector, - ) -> Self { - Self { - security_structure_of_factor_instances, - apply_shield_manifest_kind, - } - } -} diff --git a/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_unsecurified_entity.rs b/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_unsecurified_entity.rs index 78735b693..5da3eb591 100644 --- a/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_unsecurified_entity.rs +++ b/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_unsecurified_entity.rs @@ -1,12 +1,9 @@ use profile_supporting_types::AnyUnsecurifiedEntity; use radix_common::prelude::ACCESS_CONTROLLER_PACKAGE as SCRYPTO_ACCESS_CONTROLLER_PACKAGE; -use radix_engine_interface::blueprints::{ - access_controller::{ - AccessControllerCreateManifestInput as ScryptoAccessControllerCreateManifestInput, - ACCESS_CONTROLLER_BLUEPRINT as SCRYPTO_ACCESS_CONTROLLER_BLUEPRINT, - ACCESS_CONTROLLER_CREATE_IDENT as SCRYPTO_ACCESS_CONTROLLER_CREATE_IDENT, - }, - account::AccountSecurifyManifestInput as ScryptoAccountSecurifyManifestInput, +use radix_engine_interface::blueprints::access_controller::{ + AccessControllerCreateManifestInput as ScryptoAccessControllerCreateManifestInput, + ACCESS_CONTROLLER_BLUEPRINT as SCRYPTO_ACCESS_CONTROLLER_BLUEPRINT, + ACCESS_CONTROLLER_CREATE_IDENT as SCRYPTO_ACCESS_CONTROLLER_CREATE_IDENT, }; use crate::prelude::*; @@ -55,34 +52,11 @@ impl TransactionManifestSecurifyUnsecurifiedEntity for TransactionManifest { security_structure_of_factor_instances .assert_has_entity_kind(entity_address.get_entity_kind())?; - let (security_entity_identifier, owner_badge) = - if entity_address.is_identity() { - ( - SCRYPTO_IDENTITY_SECURIFY_IDENT, - SCRYPTO_IDENTITY_OWNER_BADGE, - ) - } else { - (SCRYPTO_ACCOUNT_SECURIFY_IDENT, SCRYPTO_ACCOUNT_OWNER_BADGE) - }; - - let mut builder = ScryptoTransactionManifestBuilder::new(); - // Securify the entity which will return an entity owner badge onto the worktop. - let owner_badge_bucket_name = "owner_badge_bucket"; - { - builder = builder.call_method( - &entity_address, - security_entity_identifier, - ScryptoAccountSecurifyManifestInput {}, - ); - - // Create a bucket out of the entity owner badge. - builder = builder.take_from_worktop( - owner_badge, - 1, - owner_badge_bucket_name, - ); - }; + let (mut builder, owner_badge_bucket) = Self::put_owner_badge_in_bucket( + ScryptoTransactionManifestBuilder::new(), + &unsecurified_entity.entity, + ); // Create an access controller for the entity. builder = { @@ -109,8 +83,6 @@ impl TransactionManifestSecurifyUnsecurifiedEntity for TransactionManifest { .clone(), ); - let owner_badge_bucket = builder.bucket(owner_badge_bucket_name); - builder.call_function( SCRYPTO_ACCESS_CONTROLLER_PACKAGE, SCRYPTO_ACCESS_CONTROLLER_BLUEPRINT, diff --git a/crates/transaction/manifests/src/manifests_security_shield/mod.rs b/crates/transaction/manifests/src/manifests_security_shield/mod.rs index 2af88dd1a..28de95015 100644 --- a/crates/transaction/manifests/src/manifests_security_shield/mod.rs +++ b/crates/transaction/manifests/src/manifests_security_shield/mod.rs @@ -1,9 +1,19 @@ +mod access_controller_factors_and_time_input; mod manifests_securify_shield_securified_entity; mod manifests_securify_shield_unsecurified_entity; mod set_rola_key; mod top_up_access_controller_xrd_vault; +mod transaction_manifest_apply_security_shield_any_input; +mod transaction_manifest_apply_security_shield_kind; +mod transaction_manifest_apply_security_shield_securified_input; +mod transaction_manifest_owner_badge_producing; +pub use access_controller_factors_and_time_input::*; pub use manifests_securify_shield_securified_entity::*; pub use manifests_securify_shield_unsecurified_entity::*; pub use set_rola_key::*; pub use top_up_access_controller_xrd_vault::*; +pub use transaction_manifest_apply_security_shield_any_input::*; +pub use transaction_manifest_apply_security_shield_kind::*; +pub use transaction_manifest_apply_security_shield_securified_input::*; +pub use transaction_manifest_owner_badge_producing::*; diff --git a/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_apply_security_shield_any_input.rs b/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_apply_security_shield_any_input.rs new file mode 100644 index 000000000..bb07f6fde --- /dev/null +++ b/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_apply_security_shield_any_input.rs @@ -0,0 +1,63 @@ +use crate::prelude::*; + +#[derive(Debug, Clone)] +pub struct TransactionManifestApplySecurityShieldAnyInput { + pub security_structure_of_factor_instances: + SecurityStructureOfFactorInstances, + pub apply_shield_manifest_kind: + Option, +} +impl TransactionManifestApplySecurityShieldAnyInput { + fn new( + security_structure_of_factor_instances: + SecurityStructureOfFactorInstances, + apply_shield_manifest_kind: impl Into< + Option, + >, + ) -> Self { + Self { + security_structure_of_factor_instances, + apply_shield_manifest_kind: apply_shield_manifest_kind.into(), + } + } + pub fn for_securified( + security_structure_of_factor_instances: + SecurityStructureOfFactorInstances, + apply_shield_manifest_kind: TransactionManifestApplySecurityShieldKind, + ) -> Self { + Self::new( + security_structure_of_factor_instances, + apply_shield_manifest_kind, + ) + } + pub fn as_securified( + &self, + ) -> Result { + let apply_shield_manifest_kind = self + .apply_shield_manifest_kind + .clone() + .ok_or(CommonError::Unknown)?; // TODO: replace with proper error + Ok(TransactionManifestApplySecurityShieldSecurifiedInput { + security_structure_of_factor_instances: self + .security_structure_of_factor_instances + .clone(), + apply_shield_manifest_kind, + }) + } + pub fn for_unsecurified( + security_structure_of_factor_instances: + SecurityStructureOfFactorInstances, + ) -> Self { + Self::new(security_structure_of_factor_instances, None) + } + + pub fn as_unsecurified( + &self, + ) -> Result { + Ok(TransactionManifestApplySecurityShieldUnsecurifiedInput { + security_structure_of_factor_instances: self + .security_structure_of_factor_instances + .clone(), + }) + } +} diff --git a/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_apply_security_shield_kind.rs b/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_apply_security_shield_kind.rs new file mode 100644 index 000000000..e6258eb60 --- /dev/null +++ b/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_apply_security_shield_kind.rs @@ -0,0 +1,134 @@ +use crate::prelude::*; + +use radix_engine_interface::blueprints::access_controller::{ + AccessControllerInitiateRecoveryAsPrimaryInput as ScryptoAccessControllerInitiateRecoveryAsPrimaryInput, + AccessControllerInitiateRecoveryAsRecoveryInput as ScryptoAccessControllerInitiateRecoveryAsRecoveryInput, + AccessControllerQuickConfirmPrimaryRoleRecoveryProposalInput as ScryptoAccessControllerQuickConfirmPrimaryRoleRecoveryProposalInput, + AccessControllerQuickConfirmRecoveryRoleRecoveryProposalInput as ScryptoAccessControllerQuickConfirmRecoveryRoleRecoveryProposalInput, + AccessControllerTimedConfirmRecoveryInput as ScryptoAccessControllerTimedConfirmRecoveryInput, + ACCESS_CONTROLLER_INITIATE_RECOVERY_AS_PRIMARY_IDENT as SCRYPTO_ACCESS_CONTROLLER_INITIATE_RECOVERY_AS_PRIMARY_IDENT, + ACCESS_CONTROLLER_INITIATE_RECOVERY_AS_RECOVERY_IDENT as SCRYPTO_ACCESS_CONTROLLER_INITIATE_RECOVERY_AS_RECOVERY_IDENT, + ACCESS_CONTROLLER_QUICK_CONFIRM_PRIMARY_ROLE_RECOVERY_PROPOSAL_IDENT as SCRYPTO_ACCESS_CONTROLLER_QUICK_CONFIRM_PRIMARY_ROLE_RECOVERY_PROPOSAL_IDENT, + ACCESS_CONTROLLER_QUICK_CONFIRM_RECOVERY_ROLE_RECOVERY_PROPOSAL_IDENT as SCRYPTO_ACCESS_CONTROLLER_QUICK_CONFIRM_RECOVERY_ROLE_RECOVERY_PROPOSAL_IDENT, + ACCESS_CONTROLLER_TIMED_CONFIRM_RECOVERY_IDENT as SCRYPTO_ACCESS_CONTROLLER_TIMED_CONFIRM_RECOVERY_IDENT, +}; + +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum TransactionManifestApplySecurityShieldKind { + /// (Primary Recovery Confirmation) + PrimaryAndRecoveryWithExplicitConfirmation, + + /// (Primary Recovery Time) + PrimaryAndRecoveryWithTimedAutoConfirm, + + /// (Primary Confirmation) + PrimaryAndExplicitConfirmation, + + /// (Primary Time) ‼️ REQUIRES "Dugong" ‼️ + PrimaryWithTimedAutoConfirm, + + /// (Recovery Confirmation) + RecoveryAndExplicitConfirmation, + + /// (Recovery Time) + RecoveryWithTimedAutoConfirm, +} + +use radix_common::prelude::ManifestEncode; +use radix_common::prelude::ManifestSborTuple; +// Trickery to allow `Box` - which is not allowed it seems, +// but this solves it, since in Scrypto they impl ResolvableArguments for ManifestEncode + ManifestSborTuple +pub trait CallMethodInput: ManifestEncode + ManifestSborTuple {} +impl CallMethodInput for T {} + +impl TransactionManifestApplySecurityShieldKind { + fn can_exercise_primary_role(&self) -> bool { + match self { + Self::PrimaryAndRecoveryWithExplicitConfirmation => true, + Self::PrimaryAndRecoveryWithTimedAutoConfirm => true, + Self::PrimaryAndExplicitConfirmation => true, + Self::PrimaryWithTimedAutoConfirm => true, + Self::RecoveryAndExplicitConfirmation => false, + Self::RecoveryWithTimedAutoConfirm => false, + } + } + + fn can_exercise_recovery_role(&self) -> bool { + match self { + Self::PrimaryAndRecoveryWithExplicitConfirmation => true, + Self::PrimaryAndRecoveryWithTimedAutoConfirm => true, + Self::PrimaryAndExplicitConfirmation => false, + Self::PrimaryWithTimedAutoConfirm => false, + Self::RecoveryAndExplicitConfirmation => true, + Self::RecoveryWithTimedAutoConfirm => true, + } + } + + /// Explicitly means "not using time, but use quick confirmation" + fn can_exercise_confirmation_role_explicitly(&self) -> bool { + match self { + Self::PrimaryAndRecoveryWithExplicitConfirmation => true, + Self::PrimaryAndRecoveryWithTimedAutoConfirm => false, + Self::PrimaryAndExplicitConfirmation => true, + Self::PrimaryWithTimedAutoConfirm => false, + Self::RecoveryAndExplicitConfirmation => true, + Self::RecoveryWithTimedAutoConfirm => false, + } + } + + pub fn can_set_rola_key(&self) -> bool { + self.can_exercise_primary_role() + } + + pub fn input_for_initialization( + &self, + factors_and_time: &AccessControllerFactorsAndTimeInput, + ) -> (&'static str, Box) { + if self.can_exercise_recovery_role() { + ( + SCRYPTO_ACCESS_CONTROLLER_INITIATE_RECOVERY_AS_RECOVERY_IDENT, + Box::new( + ScryptoAccessControllerInitiateRecoveryAsRecoveryInput::from( + factors_and_time, + ), + ), + ) + } else if self.can_exercise_primary_role() { + ( + SCRYPTO_ACCESS_CONTROLLER_INITIATE_RECOVERY_AS_PRIMARY_IDENT, + Box::new( + ScryptoAccessControllerInitiateRecoveryAsPrimaryInput::from( + factors_and_time, + ), + ), + ) + } else { + unreachable!( + "No kind exists which disallows for both primary and recovery" + ) + } + } + + pub fn input_for_confirm( + &self, + factors_and_time: &AccessControllerFactorsAndTimeInput, + ) -> (&'static str, Box) { + if self.can_exercise_confirmation_role_explicitly() { + if self.can_exercise_recovery_role() { + (SCRYPTO_ACCESS_CONTROLLER_QUICK_CONFIRM_RECOVERY_ROLE_RECOVERY_PROPOSAL_IDENT, Box::new(ScryptoAccessControllerQuickConfirmRecoveryRoleRecoveryProposalInput::from(factors_and_time))) + } else { + (SCRYPTO_ACCESS_CONTROLLER_QUICK_CONFIRM_PRIMARY_ROLE_RECOVERY_PROPOSAL_IDENT, Box::new(ScryptoAccessControllerQuickConfirmPrimaryRoleRecoveryProposalInput::from(factors_and_time))) + } + } else { + // Time based + ( + SCRYPTO_ACCESS_CONTROLLER_TIMED_CONFIRM_RECOVERY_IDENT, + Box::new( + ScryptoAccessControllerTimedConfirmRecoveryInput::from( + factors_and_time, + ), + ), + ) + } + } +} diff --git a/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_apply_security_shield_securified_input.rs b/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_apply_security_shield_securified_input.rs new file mode 100644 index 000000000..a9d2b369d --- /dev/null +++ b/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_apply_security_shield_securified_input.rs @@ -0,0 +1,21 @@ +use crate::prelude::*; + +#[derive(Debug, Clone)] +pub struct TransactionManifestApplySecurityShieldSecurifiedInput { + pub security_structure_of_factor_instances: + SecurityStructureOfFactorInstances, + pub apply_shield_manifest_kind: TransactionManifestApplySecurityShieldKind, +} + +impl TransactionManifestApplySecurityShieldSecurifiedInput { + pub fn new( + security_structure_of_factor_instances: + SecurityStructureOfFactorInstances, + apply_shield_manifest_kind: TransactionManifestApplySecurityShieldKind, + ) -> Self { + Self { + security_structure_of_factor_instances, + apply_shield_manifest_kind, + } + } +} diff --git a/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_owner_badge_producing.rs b/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_owner_badge_producing.rs new file mode 100644 index 000000000..ee5de6fa8 --- /dev/null +++ b/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_owner_badge_producing.rs @@ -0,0 +1,65 @@ +use std::borrow::Borrow; + +use radix_engine_interface::blueprints::access_controller::ACCESS_CONTROLLER_CREATE_PROOF_IDENT; + +use crate::prelude::*; + +impl TransactionManifestOwnerBadgeProducing for TransactionManifest {} + +pub trait TransactionManifestOwnerBadgeProducing { + fn put_owner_badge_in_bucket( + builder: ScryptoTransactionManifestBuilder, + owner: impl Borrow, + ) -> (ScryptoTransactionManifestBuilder, ScryptoManifestBucket) { + let owner = owner.borrow(); + let is_account = owner.is_account_entity(); + let owner_badge_bucket_name = "owner_badge_bucket"; + let owner_badge = if is_account { + SCRYPTO_ACCOUNT_OWNER_BADGE + } else { + SCRYPTO_IDENTITY_OWNER_BADGE + }; + let mut builder = Self::produce_owner_badge(builder, owner); + // Create a bucket out of the entity owner badge. + builder = + builder.take_from_worktop(owner_badge, 1, owner_badge_bucket_name); + + let owner_badge_bucket = builder.bucket(owner_badge_bucket_name); + + (builder, owner_badge_bucket) + } + + fn produce_owner_badge( + builder: ScryptoTransactionManifestBuilder, + owner: impl Borrow, + ) -> ScryptoTransactionManifestBuilder { + let mut builder = builder; + let owner = owner.borrow(); + + let is_account = owner.is_account_entity(); + + match owner.security_state() { + EntitySecurityState::Securified { value } => { + builder = builder.call_method( + value.access_controller_address.scrypto(), + ACCESS_CONTROLLER_CREATE_PROOF_IDENT, + (), + ); + } + EntitySecurityState::Unsecured { value: _ } => { + let securify_entity_identifier = if is_account { + SCRYPTO_ACCOUNT_SECURIFY_IDENT + } else { + SCRYPTO_IDENTITY_SECURIFY_IDENT + }; + builder = builder.call_method( + owner.address().scrypto(), + securify_entity_identifier, + (), + ); + } + } + + builder + } +} From 54e9967f982584bb3b47120bedee22df2373bda4 Mon Sep 17 00:00:00 2001 From: Alexander Cyon Date: Fri, 24 Jan 2025 10:27:16 +0100 Subject: [PATCH 05/25] remove unused input type --- .../src/manifests_security_shield/mod.rs | 2 - ...anifest_apply_security_shield_any_input.rs | 63 ------------------- 2 files changed, 65 deletions(-) delete mode 100644 crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_apply_security_shield_any_input.rs diff --git a/crates/transaction/manifests/src/manifests_security_shield/mod.rs b/crates/transaction/manifests/src/manifests_security_shield/mod.rs index 28de95015..be47a8b22 100644 --- a/crates/transaction/manifests/src/manifests_security_shield/mod.rs +++ b/crates/transaction/manifests/src/manifests_security_shield/mod.rs @@ -3,7 +3,6 @@ mod manifests_securify_shield_securified_entity; mod manifests_securify_shield_unsecurified_entity; mod set_rola_key; mod top_up_access_controller_xrd_vault; -mod transaction_manifest_apply_security_shield_any_input; mod transaction_manifest_apply_security_shield_kind; mod transaction_manifest_apply_security_shield_securified_input; mod transaction_manifest_owner_badge_producing; @@ -13,7 +12,6 @@ pub use manifests_securify_shield_securified_entity::*; pub use manifests_securify_shield_unsecurified_entity::*; pub use set_rola_key::*; pub use top_up_access_controller_xrd_vault::*; -pub use transaction_manifest_apply_security_shield_any_input::*; pub use transaction_manifest_apply_security_shield_kind::*; pub use transaction_manifest_apply_security_shield_securified_input::*; pub use transaction_manifest_owner_badge_producing::*; diff --git a/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_apply_security_shield_any_input.rs b/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_apply_security_shield_any_input.rs deleted file mode 100644 index bb07f6fde..000000000 --- a/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_apply_security_shield_any_input.rs +++ /dev/null @@ -1,63 +0,0 @@ -use crate::prelude::*; - -#[derive(Debug, Clone)] -pub struct TransactionManifestApplySecurityShieldAnyInput { - pub security_structure_of_factor_instances: - SecurityStructureOfFactorInstances, - pub apply_shield_manifest_kind: - Option, -} -impl TransactionManifestApplySecurityShieldAnyInput { - fn new( - security_structure_of_factor_instances: - SecurityStructureOfFactorInstances, - apply_shield_manifest_kind: impl Into< - Option, - >, - ) -> Self { - Self { - security_structure_of_factor_instances, - apply_shield_manifest_kind: apply_shield_manifest_kind.into(), - } - } - pub fn for_securified( - security_structure_of_factor_instances: - SecurityStructureOfFactorInstances, - apply_shield_manifest_kind: TransactionManifestApplySecurityShieldKind, - ) -> Self { - Self::new( - security_structure_of_factor_instances, - apply_shield_manifest_kind, - ) - } - pub fn as_securified( - &self, - ) -> Result { - let apply_shield_manifest_kind = self - .apply_shield_manifest_kind - .clone() - .ok_or(CommonError::Unknown)?; // TODO: replace with proper error - Ok(TransactionManifestApplySecurityShieldSecurifiedInput { - security_structure_of_factor_instances: self - .security_structure_of_factor_instances - .clone(), - apply_shield_manifest_kind, - }) - } - pub fn for_unsecurified( - security_structure_of_factor_instances: - SecurityStructureOfFactorInstances, - ) -> Self { - Self::new(security_structure_of_factor_instances, None) - } - - pub fn as_unsecurified( - &self, - ) -> Result { - Ok(TransactionManifestApplySecurityShieldUnsecurifiedInput { - security_structure_of_factor_instances: self - .security_structure_of_factor_instances - .clone(), - }) - } -} From 20cbf2a32c128fc8f6e9f0f4a05ac659e409ed2a Mon Sep 17 00:00:00 2001 From: Alexander Cyon Date: Fri, 24 Jan 2025 10:31:09 +0100 Subject: [PATCH 06/25] remove unused input types --- ...on_os_apply_security_shield_interaction.rs | 3 +- ...fests_securify_shield_securified_entity.rs | 14 +++---- ...sts_securify_shield_unsecurified_entity.rs | 42 ++++--------------- .../src/manifests_security_shield/mod.rs | 2 - ..._apply_security_shield_securified_input.rs | 21 ---------- 5 files changed, 16 insertions(+), 66 deletions(-) delete mode 100644 crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_apply_security_shield_securified_input.rs diff --git a/crates/system/os/factors/src/apply_security_shield/sargon_os_apply_security_shield_interaction.rs b/crates/system/os/factors/src/apply_security_shield/sargon_os_apply_security_shield_interaction.rs index 30e6d19e2..cd4805c20 100644 --- a/crates/system/os/factors/src/apply_security_shield/sargon_os_apply_security_shield_interaction.rs +++ b/crates/system/os/factors/src/apply_security_shield/sargon_os_apply_security_shield_interaction.rs @@ -30,10 +30,9 @@ impl OsApplySecurityShieldInteraction for SargonOS { .map(|e| { let provisional = e.entity.get_provisional().expect("Entity should have a provisional config set since we applied shield above"); let derived = provisional.as_factor_instances_derived().expect("Should have derived factors"); - let input = TransactionManifestApplySecurityShieldUnsecurifiedInput::new(derived.clone()); TransactionManifest::apply_security_shield_for_unsecurified_entity( e, - input, + derived.clone() ) }).collect::>>()?; diff --git a/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs b/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs index 4ed37cd8a..0e49ed1b1 100644 --- a/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs +++ b/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs @@ -9,20 +9,20 @@ pub trait TransactionManifestSecurifySecurifiedEntity: { fn apply_security_shield_for_securified_entity( securified_entity: AnySecurifiedEntity, - input: TransactionManifestApplySecurityShieldSecurifiedInput, + security_structure_of_factor_instances: + SecurityStructureOfFactorInstances, + apply_shield_manifest_kind: TransactionManifestApplySecurityShieldKind, ) -> Result; } impl TransactionManifestSecurifySecurifiedEntity for TransactionManifest { fn apply_security_shield_for_securified_entity( securified_entity: AnySecurifiedEntity, - input: TransactionManifestApplySecurityShieldSecurifiedInput, + security_structure_of_factor_instances: + SecurityStructureOfFactorInstances, + apply_shield_manifest_kind: TransactionManifestApplySecurityShieldKind, ) -> Result { - let TransactionManifestApplySecurityShieldSecurifiedInput { - security_structure_of_factor_instances, - apply_shield_manifest_kind: kind, - } = input.clone(); - + let kind = apply_shield_manifest_kind; let entity_address = securified_entity.entity.address(); // ACCESS_CONTROLLER_CREATE_PROOF_IDENT diff --git a/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_unsecurified_entity.rs b/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_unsecurified_entity.rs index 5da3eb591..93276e08b 100644 --- a/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_unsecurified_entity.rs +++ b/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_unsecurified_entity.rs @@ -8,29 +8,13 @@ use radix_engine_interface::blueprints::access_controller::{ use crate::prelude::*; -#[derive(Debug, Clone)] -pub struct TransactionManifestApplySecurityShieldUnsecurifiedInput { - pub security_structure_of_factor_instances: - SecurityStructureOfFactorInstances, -} - -impl TransactionManifestApplySecurityShieldUnsecurifiedInput { - pub fn new( - security_structure_of_factor_instances: - SecurityStructureOfFactorInstances, - ) -> Self { - Self { - security_structure_of_factor_instances, - } - } -} - pub trait TransactionManifestSecurifyUnsecurifiedEntity: Sized + TransactionManifestSetRolaKey { fn apply_security_shield_for_unsecurified_entity( unsecurified_entity: AnyUnsecurifiedEntity, - input: TransactionManifestApplySecurityShieldUnsecurifiedInput, + security_structure_of_factor_instances: + SecurityStructureOfFactorInstances, ) -> Result; } @@ -42,12 +26,10 @@ impl TransactionManifestSecurifyUnsecurifiedEntity for TransactionManifest { /// (and as usual also call `modify_manifest_lock_fee`) fn apply_security_shield_for_unsecurified_entity( unsecurified_entity: AnyUnsecurifiedEntity, - input: TransactionManifestApplySecurityShieldUnsecurifiedInput, + security_structure_of_factor_instances: + SecurityStructureOfFactorInstances, ) -> Result { let entity_address = unsecurified_entity.address(); - let TransactionManifestApplySecurityShieldUnsecurifiedInput { - security_structure_of_factor_instances, - } = input.clone(); security_structure_of_factor_instances .assert_has_entity_kind(entity_address.get_entity_kind())?; @@ -142,9 +124,7 @@ mod tests { let manifest = TransactionManifest::apply_security_shield_for_unsecurified_entity( AnyUnsecurifiedEntity::new(entity.clone().into()).unwrap(), - TransactionManifestApplySecurityShieldUnsecurifiedInput::new( - security_structure_of_factor_instances.clone(), - ), + security_structure_of_factor_instances.clone(), ) .unwrap(); manifest_eq(manifest.clone(), expected_manifest_str); @@ -223,9 +203,7 @@ mod tests { let manifest = TransactionManifest::apply_security_shield_for_unsecurified_entity( AnyUnsecurifiedEntity::new(entity.clone().into()).unwrap(), - TransactionManifestApplySecurityShieldUnsecurifiedInput::new( - security_structure_of_factor_instances.clone(), - ), + security_structure_of_factor_instances.clone(), ) .unwrap(); manifest_eq(manifest, expected_manifest_str); @@ -255,9 +233,7 @@ mod tests { TransactionManifest::apply_security_shield_for_unsecurified_entity( AnyUnsecurifiedEntity::new(Account::sample_other().into()) .unwrap(), - TransactionManifestApplySecurityShieldUnsecurifiedInput::new( - SecurityStructureOfFactorInstances::sample_other(), - ), + SecurityStructureOfFactorInstances::sample_other(), ); assert_eq!(manifest, Err(CommonError::SecurityStructureOfFactorInstancesEntityDiscrepancyInEntityKind { entity_kind_of_entity: CAP26EntityKind::Account.to_string(), entity_kind_of_factor_instances: CAP26EntityKind::Identity.to_string() })); } @@ -268,9 +244,7 @@ mod tests { TransactionManifest::apply_security_shield_for_unsecurified_entity( AnyUnsecurifiedEntity::new(Persona::sample_other().into()) .unwrap(), - TransactionManifestApplySecurityShieldUnsecurifiedInput::new( - SecurityStructureOfFactorInstances::sample(), - ), + SecurityStructureOfFactorInstances::sample(), ); assert_eq!(manifest, Err(CommonError::SecurityStructureOfFactorInstancesEntityDiscrepancyInEntityKind { entity_kind_of_entity: CAP26EntityKind::Identity.to_string(), entity_kind_of_factor_instances: CAP26EntityKind::Account.to_string() })); } diff --git a/crates/transaction/manifests/src/manifests_security_shield/mod.rs b/crates/transaction/manifests/src/manifests_security_shield/mod.rs index be47a8b22..3c0dc562b 100644 --- a/crates/transaction/manifests/src/manifests_security_shield/mod.rs +++ b/crates/transaction/manifests/src/manifests_security_shield/mod.rs @@ -4,7 +4,6 @@ mod manifests_securify_shield_unsecurified_entity; mod set_rola_key; mod top_up_access_controller_xrd_vault; mod transaction_manifest_apply_security_shield_kind; -mod transaction_manifest_apply_security_shield_securified_input; mod transaction_manifest_owner_badge_producing; pub use access_controller_factors_and_time_input::*; @@ -13,5 +12,4 @@ pub use manifests_securify_shield_unsecurified_entity::*; pub use set_rola_key::*; pub use top_up_access_controller_xrd_vault::*; pub use transaction_manifest_apply_security_shield_kind::*; -pub use transaction_manifest_apply_security_shield_securified_input::*; pub use transaction_manifest_owner_badge_producing::*; diff --git a/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_apply_security_shield_securified_input.rs b/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_apply_security_shield_securified_input.rs deleted file mode 100644 index a9d2b369d..000000000 --- a/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_apply_security_shield_securified_input.rs +++ /dev/null @@ -1,21 +0,0 @@ -use crate::prelude::*; - -#[derive(Debug, Clone)] -pub struct TransactionManifestApplySecurityShieldSecurifiedInput { - pub security_structure_of_factor_instances: - SecurityStructureOfFactorInstances, - pub apply_shield_manifest_kind: TransactionManifestApplySecurityShieldKind, -} - -impl TransactionManifestApplySecurityShieldSecurifiedInput { - pub fn new( - security_structure_of_factor_instances: - SecurityStructureOfFactorInstances, - apply_shield_manifest_kind: TransactionManifestApplySecurityShieldKind, - ) -> Self { - Self { - security_structure_of_factor_instances, - apply_shield_manifest_kind, - } - } -} From 4d8fc6df92d4f69936cbd557a637a0f7842de592 Mon Sep 17 00:00:00 2001 From: Alexander Cyon Date: Fri, 24 Jan 2025 12:00:01 +0100 Subject: [PATCH 07/25] add modify_manifest_add_lock_fee_against_xrd_vault_of_access_controller --- Cargo.lock | 1 + .../common/numeric/src/decimal/decimal192.rs | 2 +- ...on_os_apply_security_shield_interaction.rs | 8 ++- crates/transaction/manifests/Cargo.toml | 1 + ..._against_xrd_vault_of_access_controller.rs | 52 +++++++++++++++++++ ...fests_securify_shield_securified_entity.rs | 15 ++++++ .../src/manifests_security_shield/mod.rs | 2 + ...ion_manifest_apply_security_shield_kind.rs | 6 ++- 8 files changed, 83 insertions(+), 4 deletions(-) create mode 100644 crates/transaction/manifests/src/manifests_security_shield/lock_fee_against_xrd_vault_of_access_controller.rs diff --git a/Cargo.lock b/Cargo.lock index e93fef64c..d12cd9632 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2451,6 +2451,7 @@ dependencies = [ "core-utils", "derive_more", "enum-as-inner", + "enum-iterator", "factors", "gateway-models", "hierarchical-deterministic", diff --git a/crates/common/numeric/src/decimal/decimal192.rs b/crates/common/numeric/src/decimal/decimal192.rs index 5490e5c1f..2131b0088 100644 --- a/crates/common/numeric/src/decimal/decimal192.rs +++ b/crates/common/numeric/src/decimal/decimal192.rs @@ -59,7 +59,7 @@ impl Decimal { self.0 } - fn from_native(decimal: ScryptoDecimal192) -> Self { + pub const fn from_native(decimal: ScryptoDecimal192) -> Self { Self(decimal) } diff --git a/crates/system/os/factors/src/apply_security_shield/sargon_os_apply_security_shield_interaction.rs b/crates/system/os/factors/src/apply_security_shield/sargon_os_apply_security_shield_interaction.rs index cd4805c20..48704c7a1 100644 --- a/crates/system/os/factors/src/apply_security_shield/sargon_os_apply_security_shield_interaction.rs +++ b/crates/system/os/factors/src/apply_security_shield/sargon_os_apply_security_shield_interaction.rs @@ -41,8 +41,12 @@ impl OsApplySecurityShieldInteraction for SargonOS { .iter() .map(|e| { let provisional = e.entity.get_provisional().expect("Entity should have a provisional config set since we applied shield above"); - let _derived = provisional.as_factor_instances_derived().expect("Should have derived factors"); - todo!("Implement TransactionManifest::apply_security_shield_for_securified_entity") + let derived = provisional.as_factor_instances_derived().expect("Should have derived factors"); + TransactionManifest::apply_security_shield_for_securified_entity( + e, + derived.clone(), + TransactionManifestApplySecurityShieldKind::PrimaryAndRecoveryWithExplicitConfirmation + ) }).collect::>>()?; Ok(DappToWalletInteractionBatchOfTransactions::new( diff --git a/crates/transaction/manifests/Cargo.toml b/crates/transaction/manifests/Cargo.toml index 766f95e5f..2a412d8b1 100644 --- a/crates/transaction/manifests/Cargo.toml +++ b/crates/transaction/manifests/Cargo.toml @@ -33,6 +33,7 @@ sbor = { workspace = true } # === EXTERNAL DEPENDENCIES === derive_more = { workspace = true } enum-as-inner = { workspace = true } +enum-iterator = { workspace = true } itertools = { workspace = true } paste = { workspace = true } pretty_assertions = { workspace = true } diff --git a/crates/transaction/manifests/src/manifests_security_shield/lock_fee_against_xrd_vault_of_access_controller.rs b/crates/transaction/manifests/src/manifests_security_shield/lock_fee_against_xrd_vault_of_access_controller.rs new file mode 100644 index 000000000..372656a3b --- /dev/null +++ b/crates/transaction/manifests/src/manifests_security_shield/lock_fee_against_xrd_vault_of_access_controller.rs @@ -0,0 +1,52 @@ +use profile_supporting_types::AnySecurifiedEntity; +use radix_engine_interface::blueprints::access_controller::{ + AccessControllerLockRecoveryFeeInput as ScryptoAccessControllerLockRecoveryFeeInput, + ACCESS_CONTROLLER_LOCK_RECOVERY_FEE_IDENT as SCRYPTO_ACCESS_CONTROLLER_LOCK_RECOVERY_FEE_IDENT, +}; +use radix_transactions::prelude::ManifestBuilder; + +use crate::prelude::*; + +pub trait TransactionManifestLockFeeAgainstXrdVaultOfAccessController { + /// Locks transaction fee against the XRD vault of the access controller of + /// `entity_applying_shield` - either AC of an Account or of a Persona. + /// + /// We need to call this later when we have made a preview/dry-run of the + /// `manifest` to get the actual fee to lock. + /// + /// `manifest` was produced by `apply_security_shield_for_securified_entity`. + /// + /// In fact will will be locking fee for 6 flavours of transaction manifest + /// which updates the security shield of an entity, as returned by + /// `TransactionManifestApplySecurityShieldKind::all()`, and we could try to + /// be smart and run preview of each six to get a total fee to lock, but we + /// will not do that, we will just lock the fee for the biggest one. Since + /// only the required amount is drawn. + /// + /// Only relevant for securified entities - since it is only securified entities + /// which have an access controller to lock against. + fn modify_manifest_add_lock_fee_against_xrd_vault_of_access_controller( + manifest: TransactionManifest, + fee: Decimal192, + // TODO: remove `entity_applying_shield`, this should be read out from the manifest in a throwing function, `manifest.get_address_of_entity_applying_shield()` or similar which Omar need to provide us with, oh well we need the account here, so elsewhere, in SargonOS where we have access to Profile we would call `manifest.get_address_of_entity_applying_shield` and then lookup the entity. + entity_applying_shield: AnySecurifiedEntity, + ) -> TransactionManifest { + let mut builder = ManifestBuilder::with_manifest(manifest); + let access_controller_address = entity_applying_shield + .securified_entity_control + .access_controller_address; + // Lock fee against XRD vault of the access controller + builder = builder.call_method( + access_controller_address.scrypto(), + SCRYPTO_ACCESS_CONTROLLER_LOCK_RECOVERY_FEE_IDENT, + ScryptoAccessControllerLockRecoveryFeeInput { + amount: ScryptoDecimal192::from(fee), + }, + ); + + TransactionManifest::sargon_built( + builder, + entity_applying_shield.entity.network_id(), + ) + } +} diff --git a/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs b/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs index 0e49ed1b1..d48b7763b 100644 --- a/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs +++ b/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs @@ -16,6 +16,16 @@ pub trait TransactionManifestSecurifySecurifiedEntity: } impl TransactionManifestSecurifySecurifiedEntity for TransactionManifest { + /// Updates the security shield of a securified entity to `security_structure_of_factor_instances`. + /// + /// Also conditionally updates the Rola key of the entity - if it is new. + /// + /// Later once we have got a preview from Gateway - we will need to call: + /// * `modify_manifest_add_lock_fee_against_xrd_vault_of_access_controller` + /// + /// And when we know the fee we can calculate how much to top up the XRD vault of the AccessController + /// and call + /// * `modify_manifest_add_withdraw_of_xrd_for_access_controller_xrd_vault_top_up_paid_by_account` fn apply_security_shield_for_securified_entity( securified_entity: AnySecurifiedEntity, security_structure_of_factor_instances: @@ -84,6 +94,11 @@ impl TransactionManifestSecurifySecurifiedEntity for TransactionManifest { ); // N.B. + // We will not lock fee against the XRD vault yet - we will do that + // later when we have made a preview/dry-run of the `manifest` to get + // the estimated fee to lock, by calling `modify_manifest_add_lock_fee_against_xrd_vault_of_access_controller` + // + // Furthermore: // We do NOT top of XRD vault of AccessController - yet! // Host will need to call the function: // `modify_manifest_add_withdraw_of_xrd_for_access_controller_xrd_vault_top_up_paid_by_account` diff --git a/crates/transaction/manifests/src/manifests_security_shield/mod.rs b/crates/transaction/manifests/src/manifests_security_shield/mod.rs index 3c0dc562b..da87c4b60 100644 --- a/crates/transaction/manifests/src/manifests_security_shield/mod.rs +++ b/crates/transaction/manifests/src/manifests_security_shield/mod.rs @@ -1,4 +1,5 @@ mod access_controller_factors_and_time_input; +mod lock_fee_against_xrd_vault_of_access_controller; mod manifests_securify_shield_securified_entity; mod manifests_securify_shield_unsecurified_entity; mod set_rola_key; @@ -7,6 +8,7 @@ mod transaction_manifest_apply_security_shield_kind; mod transaction_manifest_owner_badge_producing; pub use access_controller_factors_and_time_input::*; +pub use lock_fee_against_xrd_vault_of_access_controller::*; pub use manifests_securify_shield_securified_entity::*; pub use manifests_securify_shield_unsecurified_entity::*; pub use set_rola_key::*; diff --git a/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_apply_security_shield_kind.rs b/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_apply_security_shield_kind.rs index e6258eb60..7e9debf2c 100644 --- a/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_apply_security_shield_kind.rs +++ b/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_apply_security_shield_kind.rs @@ -13,7 +13,7 @@ use radix_engine_interface::blueprints::access_controller::{ ACCESS_CONTROLLER_TIMED_CONFIRM_RECOVERY_IDENT as SCRYPTO_ACCESS_CONTROLLER_TIMED_CONFIRM_RECOVERY_IDENT, }; -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Clone, Debug, PartialEq, Eq, Hash, enum_iterator::Sequence)] pub enum TransactionManifestApplySecurityShieldKind { /// (Primary Recovery Confirmation) PrimaryAndRecoveryWithExplicitConfirmation, @@ -42,6 +42,10 @@ pub trait CallMethodInput: ManifestEncode + ManifestSborTuple {} impl CallMethodInput for T {} impl TransactionManifestApplySecurityShieldKind { + pub fn all() -> IndexSet { + enum_iterator::all::().collect() + } + fn can_exercise_primary_role(&self) -> bool { match self { Self::PrimaryAndRecoveryWithExplicitConfirmation => true, From f2babd1420ed7fc1a6cb7ae56f70eefa985250c5 Mon Sep 17 00:00:00 2001 From: Alexander Cyon Date: Fri, 24 Jan 2025 13:40:37 +0100 Subject: [PATCH 08/25] fix typos --- .../lock_fee_against_xrd_vault_of_access_controller.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/crates/transaction/manifests/src/manifests_security_shield/lock_fee_against_xrd_vault_of_access_controller.rs b/crates/transaction/manifests/src/manifests_security_shield/lock_fee_against_xrd_vault_of_access_controller.rs index 372656a3b..9e960af71 100644 --- a/crates/transaction/manifests/src/manifests_security_shield/lock_fee_against_xrd_vault_of_access_controller.rs +++ b/crates/transaction/manifests/src/manifests_security_shield/lock_fee_against_xrd_vault_of_access_controller.rs @@ -16,12 +16,11 @@ pub trait TransactionManifestLockFeeAgainstXrdVaultOfAccessController { /// /// `manifest` was produced by `apply_security_shield_for_securified_entity`. /// - /// In fact will will be locking fee for 6 flavours of transaction manifest + /// In fact we will be locking fee for 6 flavours of transaction manifest /// which updates the security shield of an entity, as returned by /// `TransactionManifestApplySecurityShieldKind::all()`, and we could try to - /// be smart and run preview of each six to get a total fee to lock, but we - /// will not do that, we will just lock the fee for the biggest one. Since - /// only the required amount is drawn. + /// be smart and run preview of each six to get a minimial fee per manifest, + /// but we will avoid that complexity. /// /// Only relevant for securified entities - since it is only securified entities /// which have an access controller to lock against. From 12704e224277f9f10071c3f2663f083d5d08ded2 Mon Sep 17 00:00:00 2001 From: Alexander Cyon Date: Fri, 24 Jan 2025 13:48:11 +0100 Subject: [PATCH 09/25] doc --- .../access_controller_factors_and_time_input.rs | 6 ++++++ ...ction_manifest_apply_security_shield_kind.rs | 17 +++++++++++++++++ ...ransaction_manifest_owner_badge_producing.rs | 3 +++ 3 files changed, 26 insertions(+) diff --git a/crates/transaction/manifests/src/manifests_security_shield/access_controller_factors_and_time_input.rs b/crates/transaction/manifests/src/manifests_security_shield/access_controller_factors_and_time_input.rs index b079b289f..29f64db13 100644 --- a/crates/transaction/manifests/src/manifests_security_shield/access_controller_factors_and_time_input.rs +++ b/crates/transaction/manifests/src/manifests_security_shield/access_controller_factors_and_time_input.rs @@ -7,9 +7,15 @@ use radix_engine_interface::blueprints::access_controller::{ AccessControllerTimedConfirmRecoveryInput as ScryptoAccessControllerTimedConfirmRecoveryInput, }; +/// An ephemeral DTO that is used to create the input for the access controller +/// methods that require factors and time - which we create from a +/// `SecurityStructureOfFactorInstances` #[derive(Debug, Clone)] pub struct AccessControllerFactorsAndTimeInput { + /// RuleSet is Scrypto representation of the security structure's + /// MatrixOfFactors rule_set: ScryptoRuleSet, + /// The timed recovery delay in minutes we get from `SecurityStructureOfFactorInstances`. timed_recovery_delay_in_minutes: u32, } diff --git a/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_apply_security_shield_kind.rs b/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_apply_security_shield_kind.rs index 7e9debf2c..f050defde 100644 --- a/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_apply_security_shield_kind.rs +++ b/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_apply_security_shield_kind.rs @@ -13,6 +13,12 @@ use radix_engine_interface::blueprints::access_controller::{ ACCESS_CONTROLLER_TIMED_CONFIRM_RECOVERY_IDENT as SCRYPTO_ACCESS_CONTROLLER_TIMED_CONFIRM_RECOVERY_IDENT, }; +/// A "selector" of which combination of Roles we can exercise with used +/// to build different flavours of TransactionManifest for the Security Shield +/// update. +/// +/// Each combination of roles allows us to skip signing with certain factors +/// and still be able to recover + confirm the AccessController update. #[derive(Clone, Debug, PartialEq, Eq, Hash, enum_iterator::Sequence)] pub enum TransactionManifestApplySecurityShieldKind { /// (Primary Recovery Confirmation) @@ -46,6 +52,7 @@ impl TransactionManifestApplySecurityShieldKind { enum_iterator::all::().collect() } + /// If this combination of roles references the `Primary` role or not. fn can_exercise_primary_role(&self) -> bool { match self { Self::PrimaryAndRecoveryWithExplicitConfirmation => true, @@ -57,6 +64,7 @@ impl TransactionManifestApplySecurityShieldKind { } } + /// If this combination of roles references the `Recovery` role or not. fn can_exercise_recovery_role(&self) -> bool { match self { Self::PrimaryAndRecoveryWithExplicitConfirmation => true, @@ -68,6 +76,8 @@ impl TransactionManifestApplySecurityShieldKind { } } + /// If this combination of roles references the `Confirmation` role or not. + /// /// Explicitly means "not using time, but use quick confirmation" fn can_exercise_confirmation_role_explicitly(&self) -> bool { match self { @@ -80,10 +90,13 @@ impl TransactionManifestApplySecurityShieldKind { } } + /// If we can set the ROLA key for this combination of roles. pub fn can_set_rola_key(&self) -> bool { self.can_exercise_primary_role() } + /// Returns method identifier and input for **initiating** recovery + /// on an AccessController - depending on which roles we can exercise. pub fn input_for_initialization( &self, factors_and_time: &AccessControllerFactorsAndTimeInput, @@ -113,6 +126,10 @@ impl TransactionManifestApplySecurityShieldKind { } } + /// Returns method identifier and input for **confirm** recovery + /// on an AccessController - depending on which roles we can exercise. + /// + /// **MUST** use the analogous method which was used to initiate recovery. pub fn input_for_confirm( &self, factors_and_time: &AccessControllerFactorsAndTimeInput, diff --git a/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_owner_badge_producing.rs b/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_owner_badge_producing.rs index ee5de6fa8..cde0b894d 100644 --- a/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_owner_badge_producing.rs +++ b/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_owner_badge_producing.rs @@ -7,6 +7,7 @@ use crate::prelude::*; impl TransactionManifestOwnerBadgeProducing for TransactionManifest {} pub trait TransactionManifestOwnerBadgeProducing { + /// Produces and puts the owner badge in a Bucket and returns the bucket. fn put_owner_badge_in_bucket( builder: ScryptoTransactionManifestBuilder, owner: impl Borrow, @@ -29,6 +30,8 @@ pub trait TransactionManifestOwnerBadgeProducing { (builder, owner_badge_bucket) } + /// Produce the owner badge + /// TODO: Ask Omar if this is correct for Securified entityes. fn produce_owner_badge( builder: ScryptoTransactionManifestBuilder, owner: impl Borrow, From 58fc8cbd3231cef5c8b648aa486e2f3031304afd Mon Sep 17 00:00:00 2001 From: Alexander Cyon Date: Fri, 24 Jan 2025 14:09:54 +0100 Subject: [PATCH 10/25] split out confirm of time based to be done later. --- .../confirm_timed_recovery.rs | 27 +++++++++++++++++++ ...fests_securify_shield_securified_entity.rs | 23 +++++++++------- .../src/manifests_security_shield/mod.rs | 2 ++ ...ion_manifest_apply_security_shield_kind.rs | 24 +++++++---------- 4 files changed, 51 insertions(+), 25 deletions(-) create mode 100644 crates/transaction/manifests/src/manifests_security_shield/confirm_timed_recovery.rs diff --git a/crates/transaction/manifests/src/manifests_security_shield/confirm_timed_recovery.rs b/crates/transaction/manifests/src/manifests_security_shield/confirm_timed_recovery.rs new file mode 100644 index 000000000..a6892f86d --- /dev/null +++ b/crates/transaction/manifests/src/manifests_security_shield/confirm_timed_recovery.rs @@ -0,0 +1,27 @@ +use crate::prelude::*; + +// use radix_engine_interface::blueprints::access_controller::{ +// AccessControllerTimedConfirmRecoveryInput as ScryptoAccessControllerTimedConfirmRecoveryInput, +// ACCESS_CONTROLLER_TIMED_CONFIRM_RECOVERY_IDENT as SCRYPTO_ACCESS_CONTROLLER_TIMED_CONFIRM_RECOVERY_IDENT, +// }; + +pub trait TransactionManifestConfirmTimedRecovery { + /// TBD + /// TODO: Figure out how to do this... + /// since `AccessControllerTimedConfirmRecoveryInput` need the input of + /// the factors and time which was used to start recovery - which could not + /// be quick confirmed. We need to figure out how we best represent this + /// in Profile. Perhaps a new variant on ProvisionalSecurityConfig? Something + /// like: + /// `WaitingForTimedRecovery(SecurityStructureOfFactorInstances)` + fn confirm_timed_recovery() -> Result; + // { + // builder.call_method( + // access_controller, + // SCRYPTO_ACCESS_CONTROLLER_TIMED_CONFIRM_RECOVERY_IDENT, + // ScryptoAccessControllerTimedConfirmRecoveryInput::from( + // factors_and_time, + // ), + // ); + // } +} diff --git a/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs b/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs index d48b7763b..630e389df 100644 --- a/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs +++ b/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs @@ -26,6 +26,9 @@ impl TransactionManifestSecurifySecurifiedEntity for TransactionManifest { /// And when we know the fee we can calculate how much to top up the XRD vault of the AccessController /// and call /// * `modify_manifest_add_withdraw_of_xrd_for_access_controller_xrd_vault_top_up_paid_by_account` + /// + /// For timed confirmation - much later (`timed_recovery_delay_in_minutes` later ) the + /// host app will need to call `confirm_timed_recovery` fn apply_security_shield_for_securified_entity( securified_entity: AnySecurifiedEntity, security_structure_of_factor_instances: @@ -58,16 +61,16 @@ impl TransactionManifestSecurifySecurifiedEntity for TransactionManifest { (init_input.deref(),), ); - // CONFIRM RECOVERY - // TODO: for timed, should we really call it here, now? Should - // we not call it AFTER the time has elapsed??? - let (confirm_method, confirm_input) = - kind.input_for_confirm(factors_and_time_input); - builder = builder.call_method( - access_controller_address.scrypto(), - confirm_method, - (confirm_input.deref(),), - ); + // QUICK CONFIRM RECOVERY - Only if we can exercise the confirmation role explicitly. + if let Some((confirm_method, confirm_input)) = + kind.input_for_quick_confirm(factors_and_time_input) + { + builder = builder.call_method( + access_controller_address.scrypto(), + confirm_method, + (confirm_input.deref(),), + ); + } // Set Rola Key let should_set_rola_key = security_structure_of_factor_instances diff --git a/crates/transaction/manifests/src/manifests_security_shield/mod.rs b/crates/transaction/manifests/src/manifests_security_shield/mod.rs index da87c4b60..0098531ec 100644 --- a/crates/transaction/manifests/src/manifests_security_shield/mod.rs +++ b/crates/transaction/manifests/src/manifests_security_shield/mod.rs @@ -1,4 +1,5 @@ mod access_controller_factors_and_time_input; +mod confirm_timed_recovery; mod lock_fee_against_xrd_vault_of_access_controller; mod manifests_securify_shield_securified_entity; mod manifests_securify_shield_unsecurified_entity; @@ -8,6 +9,7 @@ mod transaction_manifest_apply_security_shield_kind; mod transaction_manifest_owner_badge_producing; pub use access_controller_factors_and_time_input::*; +pub use confirm_timed_recovery::*; pub use lock_fee_against_xrd_vault_of_access_controller::*; pub use manifests_securify_shield_securified_entity::*; pub use manifests_securify_shield_unsecurified_entity::*; diff --git a/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_apply_security_shield_kind.rs b/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_apply_security_shield_kind.rs index f050defde..4fceeeb77 100644 --- a/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_apply_security_shield_kind.rs +++ b/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_apply_security_shield_kind.rs @@ -5,12 +5,10 @@ use radix_engine_interface::blueprints::access_controller::{ AccessControllerInitiateRecoveryAsRecoveryInput as ScryptoAccessControllerInitiateRecoveryAsRecoveryInput, AccessControllerQuickConfirmPrimaryRoleRecoveryProposalInput as ScryptoAccessControllerQuickConfirmPrimaryRoleRecoveryProposalInput, AccessControllerQuickConfirmRecoveryRoleRecoveryProposalInput as ScryptoAccessControllerQuickConfirmRecoveryRoleRecoveryProposalInput, - AccessControllerTimedConfirmRecoveryInput as ScryptoAccessControllerTimedConfirmRecoveryInput, ACCESS_CONTROLLER_INITIATE_RECOVERY_AS_PRIMARY_IDENT as SCRYPTO_ACCESS_CONTROLLER_INITIATE_RECOVERY_AS_PRIMARY_IDENT, ACCESS_CONTROLLER_INITIATE_RECOVERY_AS_RECOVERY_IDENT as SCRYPTO_ACCESS_CONTROLLER_INITIATE_RECOVERY_AS_RECOVERY_IDENT, ACCESS_CONTROLLER_QUICK_CONFIRM_PRIMARY_ROLE_RECOVERY_PROPOSAL_IDENT as SCRYPTO_ACCESS_CONTROLLER_QUICK_CONFIRM_PRIMARY_ROLE_RECOVERY_PROPOSAL_IDENT, ACCESS_CONTROLLER_QUICK_CONFIRM_RECOVERY_ROLE_RECOVERY_PROPOSAL_IDENT as SCRYPTO_ACCESS_CONTROLLER_QUICK_CONFIRM_RECOVERY_ROLE_RECOVERY_PROPOSAL_IDENT, - ACCESS_CONTROLLER_TIMED_CONFIRM_RECOVERY_IDENT as SCRYPTO_ACCESS_CONTROLLER_TIMED_CONFIRM_RECOVERY_IDENT, }; /// A "selector" of which combination of Roles we can exercise with used @@ -130,26 +128,22 @@ impl TransactionManifestApplySecurityShieldKind { /// on an AccessController - depending on which roles we can exercise. /// /// **MUST** use the analogous method which was used to initiate recovery. - pub fn input_for_confirm( + pub fn input_for_quick_confirm( &self, factors_and_time: &AccessControllerFactorsAndTimeInput, - ) -> (&'static str, Box) { + ) -> Option<(&'static str, Box)> { if self.can_exercise_confirmation_role_explicitly() { - if self.can_exercise_recovery_role() { + Some(if self.can_exercise_recovery_role() { (SCRYPTO_ACCESS_CONTROLLER_QUICK_CONFIRM_RECOVERY_ROLE_RECOVERY_PROPOSAL_IDENT, Box::new(ScryptoAccessControllerQuickConfirmRecoveryRoleRecoveryProposalInput::from(factors_and_time))) } else { (SCRYPTO_ACCESS_CONTROLLER_QUICK_CONFIRM_PRIMARY_ROLE_RECOVERY_PROPOSAL_IDENT, Box::new(ScryptoAccessControllerQuickConfirmPrimaryRoleRecoveryProposalInput::from(factors_and_time))) - } + }) } else { - // Time based - ( - SCRYPTO_ACCESS_CONTROLLER_TIMED_CONFIRM_RECOVERY_IDENT, - Box::new( - ScryptoAccessControllerTimedConfirmRecoveryInput::from( - factors_and_time, - ), - ), - ) + // Time based cannot happen yet - host (user) need to wait the specified + // amount of time (factors_and_time.time) before calling this method. + // So host will need to schedule a notification for user so that host + // can call this method after the time has elapsed. + None } } } From 4007bae8eedc9b237bc85554defb106d3fe1d294 Mon Sep 17 00:00:00 2001 From: Alexander Cyon Date: Fri, 24 Jan 2025 14:48:56 +0100 Subject: [PATCH 11/25] Replace bad wording 'auto_confirm' with 'timed_confirm' to make it clear that it does not happen automagically. --- .../models/app-preferences/src/security.rs | 4 +- .../entity_security_state.rs | 4 +- .../secured_entity_control.rs | 4 +- .../abstract_matrix_builder_or_built.rs | 9 ++- .../matrices/builder/error.rs | 4 +- .../matrices/builder/matrix_builder.rs | 33 ++++---- .../builder/matrix_builder_unit_tests.rs | 16 ++-- .../matrices/builder/matrix_template.rs | 8 +- .../matrices/matrix_of_factor_instances.rs | 12 ++- .../matrices/matrix_of_factor_source_ids.rs | 12 +-- .../matrices/matrix_of_factor_sources.rs | 2 +- .../security_shield_builder.rs | 35 ++++++--- .../security_shield_builder_rule_violation.rs | 8 +- .../security_structure_of_factor_instances.rs | 4 +- ...security_structure_of_factor_source_ids.rs | 4 +- .../security_structure_of_factor_sources.rs | 2 +- .../security-structures/src/time_period.rs | 2 +- ...ion_manifest_apply_security_shield_kind.rs | 77 +++++++++++++++---- .../matrices/decl_matrix_macro.rs | 8 +- .../security_shield_builder.rs | 37 +++++---- .../security_shield_builder_rule_violation.rs | 4 +- 21 files changed, 182 insertions(+), 107 deletions(-) diff --git a/crates/profile/models/app-preferences/src/security.rs b/crates/profile/models/app-preferences/src/security.rs index f2c84984c..2d0162299 100644 --- a/crates/profile/models/app-preferences/src/security.rs +++ b/crates/profile/models/app-preferences/src/security.rs @@ -247,7 +247,7 @@ mod tests { } ] }, - "numberOfDaysUntilAutoConfirm": 14 + "numberOfDaysUntilTimedConfirmationIsCallable": 14 } }, { @@ -304,7 +304,7 @@ mod tests { } ] }, - "numberOfDaysUntilAutoConfirm": 14 + "numberOfDaysUntilTimedConfirmationIsCallable": 14 } } ] diff --git a/crates/profile/models/base-entity/src/entity_security_state/entity_security_state.rs b/crates/profile/models/base-entity/src/entity_security_state/entity_security_state.rs index 05e10e1af..6e72dc823 100644 --- a/crates/profile/models/base-entity/src/entity_security_state/entity_security_state.rs +++ b/crates/profile/models/base-entity/src/entity_security_state/entity_security_state.rs @@ -382,7 +382,7 @@ mod tests { } ] }, - "numberOfDaysUntilAutoConfirm": 14 + "numberOfDaysUntilTimedConfirmationIsCallable": 14 }, "authenticationSigningFactorInstance": { "factorSourceID": { @@ -508,7 +508,7 @@ mod tests { } ] }, - "numberOfDaysUntilAutoConfirm": 14 + "numberOfDaysUntilTimedConfirmationIsCallable": 14 }, "authenticationSigningFactorInstance": { "factorSourceID": { diff --git a/crates/profile/models/base-entity/src/entity_security_state/secured_entity_control/secured_entity_control.rs b/crates/profile/models/base-entity/src/entity_security_state/secured_entity_control/secured_entity_control.rs index 7b1cd4892..336dcbbb7 100644 --- a/crates/profile/models/base-entity/src/entity_security_state/secured_entity_control/secured_entity_control.rs +++ b/crates/profile/models/base-entity/src/entity_security_state/secured_entity_control/secured_entity_control.rs @@ -349,7 +349,7 @@ mod tests { } ] }, - "numberOfDaysUntilAutoConfirm": 14 + "numberOfDaysUntilTimedConfirmationIsCallable": 14 }, "authenticationSigningFactorInstance": { "factorSourceID": { @@ -475,7 +475,7 @@ mod tests { } ] }, - "numberOfDaysUntilAutoConfirm": 14 + "numberOfDaysUntilTimedConfirmationIsCallable": 14 }, "authenticationSigningFactorInstance": { "factorSourceID": { diff --git a/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/abstract_matrix_builder_or_built.rs b/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/abstract_matrix_builder_or_built.rs index 70bb418d4..49c2ac28f 100644 --- a/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/abstract_matrix_builder_or_built.rs +++ b/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/abstract_matrix_builder_or_built.rs @@ -39,13 +39,14 @@ pub struct AbstractMatrixBuilderOrBuilt< pub(crate) confirmation_role: AbstractRoleBuilderOrBuilt<{ ROLE_CONFIRMATION }, MODE_OF_ROLE, FACTOR>, - pub number_of_days_until_auto_confirm: u16, + pub number_of_days_until_timed_confirmation_is_callable: u16, } impl AbstractMatrixBuilderOrBuilt { - pub const DEFAULT_NUMBER_OF_DAYS_UNTIL_AUTO_CONFIRM: u16 = 14; + pub const DEFAULT_NUMBER_OF_DAYS_UNTIL_TIMED_CONFIRMATION_IS_CALLABLE: u16 = + 14; /// # Safety /// Rust memory safe, but marked "unsafe" since it might allow for unsafe @@ -109,13 +110,13 @@ impl MODE_OF_ROLE, FACTOR, >, - number_of_days_until_auto_confirm: u16, + number_of_days_until_timed_confirmation_is_callable: u16, ) -> Self { Self { primary_role, recovery_role, confirmation_role, - number_of_days_until_auto_confirm, + number_of_days_until_timed_confirmation_is_callable, } } } diff --git a/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/builder/error.rs b/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/builder/error.rs index 9b39b7a16..63e17e5b8 100644 --- a/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/builder/error.rs +++ b/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/builder/error.rs @@ -17,8 +17,8 @@ pub enum MatrixRolesInCombinationBasicViolation { #[error("The factor source was not found in any role")] FactorSourceNotFoundInAnyRole, - #[error("The number of days until auto confirm must be greater than zero")] - NumberOfDaysUntilAutoConfirmMustBeGreaterThanZero, + #[error("The number of days until timed confirm is callable must be greater than zero")] + NumberOfDaysUntilTimeBasedConfirmationMustBeGreaterThanZero, } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, thiserror::Error)] diff --git a/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/builder/matrix_builder.rs b/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/builder/matrix_builder.rs index 1e942feb9..3ffa06d3e 100644 --- a/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/builder/matrix_builder.rs +++ b/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/builder/matrix_builder.rs @@ -12,7 +12,7 @@ pub type MatrixBuilderBuildResult = /// * RecoveryRoleBuilder /// * ConfirmationRoleBuilder /// -/// And `number_of_days_until_auto_confirm`. +/// And `number_of_days_until_timed_confirmation_is_callable`. pub type MatrixBuilder = AbstractMatrixBuilderOrBuilt< IS_MATRIX_BUILDER, IS_ROLE_BUILDER, @@ -28,8 +28,8 @@ impl MatrixBuilder { primary_role: PrimaryRoleBuilder::new(), recovery_role: RecoveryRoleBuilder::new(), confirmation_role: ConfirmationRoleBuilder::new(), - number_of_days_until_auto_confirm: - Self::DEFAULT_NUMBER_OF_DAYS_UNTIL_AUTO_CONFIRM, + number_of_days_until_timed_confirmation_is_callable: + Self::DEFAULT_NUMBER_OF_DAYS_UNTIL_TIMED_CONFIRMATION_IS_CALLABLE, } } @@ -37,7 +37,7 @@ impl MatrixBuilder { /// /// If valid it returns a "built" `MatrixOfFactorSourceIds`. pub fn build(&self) -> MatrixBuilderBuildResult { - self.validate_number_of_days_until_auto_confirm()?; + self.validate_number_of_days_until_timed_confirmation_is_callable()?; let primary = self .primary_role @@ -61,7 +61,7 @@ impl MatrixBuilder { primary, recovery, confirmation, - self.number_of_days_until_auto_confirm, + self.number_of_days_until_timed_confirmation_is_callable, ) }; Ok(built) @@ -379,17 +379,20 @@ impl MatrixBuilder { self.primary_role.get_threshold() } - pub fn set_number_of_days_until_auto_confirm( + pub fn set_number_of_days_until_timed_confirmation_is_callable( &mut self, number_of_days: u16, ) -> MatrixBuilderMutateResult { - self.number_of_days_until_auto_confirm = number_of_days; + self.number_of_days_until_timed_confirmation_is_callable = + number_of_days; - self.validate_number_of_days_until_auto_confirm() + self.validate_number_of_days_until_timed_confirmation_is_callable() } - pub fn get_number_of_days_until_auto_confirm(&self) -> u16 { - self.number_of_days_until_auto_confirm + pub fn get_number_of_days_until_timed_confirmation_is_callable( + &self, + ) -> u16 { + self.number_of_days_until_timed_confirmation_is_callable } fn remove_factor_from_role( @@ -533,13 +536,13 @@ impl MatrixBuilder { } } - fn validate_number_of_days_until_auto_confirm( + fn validate_number_of_days_until_timed_confirmation_is_callable( &self, ) -> MatrixBuilderMutateResult { - if self.number_of_days_until_auto_confirm == 0 { + if self.number_of_days_until_timed_confirmation_is_callable == 0 { return Err(MatrixBuilderValidation::CombinationViolation( MatrixRolesInCombinationViolation::Basic( - MatrixRolesInCombinationBasicViolation::NumberOfDaysUntilAutoConfirmMustBeGreaterThanZero, + MatrixRolesInCombinationBasicViolation::NumberOfDaysUntilTimeBasedConfirmationMustBeGreaterThanZero, ), )); } @@ -603,14 +606,14 @@ impl MatrixBuilder { /// 1. If only one factor is used for `Primary`, that factor may not be used for either `Recovery` or `Confirmation` /// 2. No factor may be used (override) in both `Recovery` and `Confirmation` /// 3. No factor may be used in both the `Primary` threshold and `Primary` override - /// 4. Number of days until auto confirm is greater than zero + /// 4. Number of days until timed confirm is callable is greater than zero fn validate_combination(&self) -> MatrixBuilderMutateResult { self.validate_if_primary_has_single_it_must_not_be_used_by_any_other_role()?; self.validate_primary_cannot_have_multiple_devices()?; self.validate_no_factor_may_be_used_in_both_primary_threshold_and_override()?; self.validate_no_factor_may_be_used_in_both_recovery_and_confirmation( )?; - self.validate_number_of_days_until_auto_confirm()?; + self.validate_number_of_days_until_timed_confirmation_is_callable()?; Ok(()) } } diff --git a/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/builder/matrix_builder_unit_tests.rs b/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/builder/matrix_builder_unit_tests.rs index c3515b99a..6be093792 100644 --- a/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/builder/matrix_builder_unit_tests.rs +++ b/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/builder/matrix_builder_unit_tests.rs @@ -86,11 +86,11 @@ fn set_number_of_days_cannot_be_zero() { ) .unwrap(); - sut.number_of_days_until_auto_confirm = 0; // bypass validation + sut.number_of_days_until_timed_confirmation_is_callable = 0; // bypass validation // Build let validation = MatrixBuilderValidation::CombinationViolation( - MatrixRolesInCombinationViolation::Basic(MatrixRolesInCombinationBasicViolation::NumberOfDaysUntilAutoConfirmMustBeGreaterThanZero) + MatrixRolesInCombinationViolation::Basic(MatrixRolesInCombinationBasicViolation::NumberOfDaysUntilTimeBasedConfirmationMustBeGreaterThanZero) ); assert_eq!(sut.validate(), Err(validation)); let res = sut.build(); @@ -117,7 +117,8 @@ fn set_number_of_days_42() { ) .unwrap(); - sut.set_number_of_days_until_auto_confirm(42).unwrap(); + sut.set_number_of_days_until_timed_confirmation_is_callable(42) + .unwrap(); // Build assert!(sut.validate().is_ok()); @@ -142,8 +143,11 @@ fn set_number_of_days_42() { } #[test] -fn auto_confirm_default() { - assert_eq!(SUT::DEFAULT_NUMBER_OF_DAYS_UNTIL_AUTO_CONFIRM, 14); +fn timed_confirm_default() { + assert_eq!( + SUT::DEFAULT_NUMBER_OF_DAYS_UNTIL_TIMED_CONFIRMATION_IS_CALLABLE, + 14 + ); } #[test] @@ -183,7 +187,7 @@ fn set_number_of_days_if_not_set_uses_default() { ConfirmationRoleWithFactorSourceIds::override_only([ FactorSourceID::sample_password() ],), - SUT::DEFAULT_NUMBER_OF_DAYS_UNTIL_AUTO_CONFIRM, + SUT::DEFAULT_NUMBER_OF_DAYS_UNTIL_TIMED_CONFIRMATION_IS_CALLABLE, ) ); } diff --git a/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/builder/matrix_template.rs b/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/builder/matrix_template.rs index 9e2af5daa..7c56f877b 100644 --- a/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/builder/matrix_template.rs +++ b/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/builder/matrix_template.rs @@ -82,8 +82,8 @@ impl MatrixTemplate { self, factor_source_ids: impl IntoIterator, ) -> Result { - let number_of_days_until_auto_confirm = - self.number_of_days_until_auto_confirm; + let number_of_days_until_timed_confirmation_is_callable = + self.number_of_days_until_timed_confirmation_is_callable; let mut assigner = FactorSourceIdAssigner::new(factor_source_ids); @@ -98,7 +98,7 @@ impl MatrixTemplate { primary_role, recovery_role, confirmation_role, - number_of_days_until_auto_confirm, + number_of_days_until_timed_confirmation_is_callable, ) }; @@ -113,7 +113,7 @@ impl MatrixTemplate { confirmation_role: ConfirmationRoleTemplate, ) -> Self { unsafe { - Self::unbuilt_with_roles_and_days(primary_role, recovery_role, confirmation_role, MatrixOfFactorSourceIds::DEFAULT_NUMBER_OF_DAYS_UNTIL_AUTO_CONFIRM) + Self::unbuilt_with_roles_and_days(primary_role, recovery_role, confirmation_role, MatrixOfFactorSourceIds::DEFAULT_NUMBER_OF_DAYS_UNTIL_TIMED_CONFIRMATION_IS_CALLABLE) } } diff --git a/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/matrix_of_factor_instances.rs b/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/matrix_of_factor_instances.rs index dc07b35b4..74ee05bc2 100644 --- a/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/matrix_of_factor_instances.rs +++ b/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/matrix_of_factor_instances.rs @@ -5,7 +5,7 @@ pub type MatrixOfFactorInstances = AbstractMatrixBuilt; impl MatrixOfFactorInstances { pub fn timed_recovery_delay_in_minutes(&self) -> u32 { let timed_recovery_in_days = - self.number_of_days_until_auto_confirm as u32; + self.number_of_days_until_timed_confirmation_is_callable as u32; MINUTES_PER_DAY * timed_recovery_in_days } } @@ -290,7 +290,8 @@ impl MatrixOfFactorInstances { primary_role, recovery_role, confirmation_role, - matrix_of_factor_sources.number_of_days_until_auto_confirm, + matrix_of_factor_sources + .number_of_days_until_timed_confirmation_is_callable, ) }; @@ -339,7 +340,10 @@ mod tests { let sut = SUT::sample(); assert_eq!( sut.timed_recovery_delay_in_minutes(), - SUT::DEFAULT_NUMBER_OF_DAYS_UNTIL_AUTO_CONFIRM as u32 * 24 * 60 + SUT::DEFAULT_NUMBER_OF_DAYS_UNTIL_TIMED_CONFIRMATION_IS_CALLABLE + as u32 + * 24 + * 60 ); } @@ -557,7 +561,7 @@ mod tests { } ] }, - "numberOfDaysUntilAutoConfirm": 14 + "numberOfDaysUntilTimedConfirmationIsCallable": 14 } "#, ); diff --git a/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/matrix_of_factor_source_ids.rs b/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/matrix_of_factor_source_ids.rs index aed8c4abb..21d3f74eb 100644 --- a/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/matrix_of_factor_source_ids.rs +++ b/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/matrix_of_factor_source_ids.rs @@ -13,7 +13,7 @@ impl MatrixOfFactorSourceIds { primary, recovery, confirmation, - Self::DEFAULT_NUMBER_OF_DAYS_UNTIL_AUTO_CONFIRM, + Self::DEFAULT_NUMBER_OF_DAYS_UNTIL_TIMED_CONFIRMATION_IS_CALLABLE, ) } } @@ -25,14 +25,14 @@ impl MatrixOfFactorSourceIds { primary: PrimaryRoleWithFactorSourceIds, recovery: RecoveryRoleWithFactorSourceIds, confirmation: ConfirmationRoleWithFactorSourceIds, - number_of_days_until_auto_confirm: u16, + number_of_days_until_timed_confirmation_is_callable: u16, ) -> Self { unsafe { Self::unbuilt_with_roles_and_days( primary, recovery, confirmation, - number_of_days_until_auto_confirm, + number_of_days_until_timed_confirmation_is_callable, ) } } @@ -46,7 +46,7 @@ impl MatrixOfFactorSourceIds { primary, recovery, confirmation, - Self::DEFAULT_NUMBER_OF_DAYS_UNTIL_AUTO_CONFIRM, + Self::DEFAULT_NUMBER_OF_DAYS_UNTIL_TIMED_CONFIRMATION_IS_CALLABLE, ) } } @@ -321,7 +321,7 @@ mod tests { } ] }, - "numberOfDaysUntilAutoConfirm": 14 + "numberOfDaysUntilTimedConfirmationIsCallable": 14 } "#, ); @@ -373,7 +373,7 @@ mod tests { } ] }, - "numberOfDaysUntilAutoConfirm": 14 + "numberOfDaysUntilTimedConfirmationIsCallable": 14 } "#, ); diff --git a/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/matrix_of_factor_sources.rs b/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/matrix_of_factor_sources.rs index eb9cbf67d..1402a78f2 100644 --- a/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/matrix_of_factor_sources.rs +++ b/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/matrix_of_factor_sources.rs @@ -30,7 +30,7 @@ impl MatrixOfFactorSources { primary_role, recovery_role, confirmation_role, - matrix.number_of_days_until_auto_confirm, + matrix.number_of_days_until_timed_confirmation_is_callable, ) }; diff --git a/crates/profile/models/security-structures/src/roles_matrices_structures/security_shield_builder.rs b/crates/profile/models/security-structures/src/roles_matrices_structures/security_shield_builder.rs index 42b5bc54c..f5707224d 100644 --- a/crates/profile/models/security-structures/src/roles_matrices_structures/security_shield_builder.rs +++ b/crates/profile/models/security-structures/src/roles_matrices_structures/security_shield_builder.rs @@ -275,10 +275,13 @@ impl SecurityShieldBuilder { }) } - pub fn get_time_period_until_auto_confirm(&self) -> TimePeriod { + pub fn get_time_period_until_timed_confirmation_is_callable( + &self, + ) -> TimePeriod { self.get(|builder| { TimePeriod::with_days( - builder.get_number_of_days_until_auto_confirm(), + builder + .get_number_of_days_until_timed_confirmation_is_callable(), ) }) } @@ -433,12 +436,14 @@ impl SecurityShieldBuilder { self.set(|builder| builder.set_threshold(threshold)) } - pub fn set_time_period_until_auto_confirm( + pub fn set_time_period_until_timed_confirmation_is_callable( &self, time_period: TimePeriod, ) -> &Self { self.set(|builder| { - builder.set_number_of_days_until_auto_confirm(time_period.days()) + builder.set_number_of_days_until_timed_confirmation_is_callable( + time_period.days(), + ) }) } @@ -999,15 +1004,17 @@ mod tests { } #[test] - fn test_get_time_period_until_auto_confirm() { + fn test_get_time_period_until_timed_confirmation_is_callable() { let sut = SUT::strict(); assert_eq!( - sut.get_time_period_until_auto_confirm(), + sut.get_time_period_until_timed_confirmation_is_callable(), TimePeriod::with_days(14) ); - sut.set_time_period_until_auto_confirm(TimePeriod::with_days(42)); + sut.set_time_period_until_timed_confirmation_is_callable( + TimePeriod::with_days(42), + ); assert_eq!( - sut.get_time_period_until_auto_confirm(), + sut.get_time_period_until_timed_confirmation_is_callable(), TimePeriod::with_days(42) ); } @@ -1041,7 +1048,9 @@ mod tests { FactorSourceID::sample_device(), )) // Primary - .set_time_period_until_auto_confirm(TimePeriod::with_days(42)) + .set_time_period_until_timed_confirmation_is_callable( + TimePeriod::with_days(42), + ) .add_factor_source_to_primary_threshold( FactorSourceID::sample_device(), ) @@ -1585,12 +1594,14 @@ mod test_invalid { } #[test] - fn number_of_auto_confirm_days_invalid() { + fn number_of_days_until_timed_confirmation_is_callable_invalid() { let sut = valid(); - sut.set_time_period_until_auto_confirm(TimePeriod::with_days(0)); + sut.set_time_period_until_timed_confirmation_is_callable( + TimePeriod::with_days(0), + ); assert_eq!( sut.validate().unwrap(), - SecurityShieldBuilderRuleViolation::NumberOfDaysUntilAutoConfirmMustBeGreaterThanZero + SecurityShieldBuilderRuleViolation::NumberOfDaysUntilTimeBasedConfirmationMustBeGreaterThanZero ); } diff --git a/crates/profile/models/security-structures/src/roles_matrices_structures/security_shield_builder_rule_violation.rs b/crates/profile/models/security-structures/src/roles_matrices_structures/security_shield_builder_rule_violation.rs index 863455d7a..aebf6733a 100644 --- a/crates/profile/models/security-structures/src/roles_matrices_structures/security_shield_builder_rule_violation.rs +++ b/crates/profile/models/security-structures/src/roles_matrices_structures/security_shield_builder_rule_violation.rs @@ -53,8 +53,8 @@ impl AsShieldBuilderViolation for MatrixRolesInCombinationBasicViolation { match self { FactorSourceNotFoundInAnyRole => unreachable!("Cannot happen since this error is not returned by 'validate'/'build'."), - NumberOfDaysUntilAutoConfirmMustBeGreaterThanZero => { - Some(SecurityShieldBuilderRuleViolation::NumberOfDaysUntilAutoConfirmMustBeGreaterThanZero) + NumberOfDaysUntilTimeBasedConfirmationMustBeGreaterThanZero => { + Some(SecurityShieldBuilderRuleViolation::NumberOfDaysUntilTimeBasedConfirmationMustBeGreaterThanZero) } } } @@ -188,8 +188,8 @@ pub enum SecurityShieldBuilderRuleViolation { #[error("Shield name is invalid")] ShieldNameInvalid, - #[error("The number of days until auto confirm must be greater than zero")] - NumberOfDaysUntilAutoConfirmMustBeGreaterThanZero, + #[error("The number of days until timed confirm is callable must be greater than zero")] + NumberOfDaysUntilTimeBasedConfirmationMustBeGreaterThanZero, #[error("Recovery and confirmation factors overlap. No factor may be used in both the recovery and confirmation roles")] RecoveryAndConfirmationFactorsOverlap, diff --git a/crates/profile/models/security-structures/src/roles_matrices_structures/security_structure_of_factors/security_structure_of_factor_instances.rs b/crates/profile/models/security-structures/src/roles_matrices_structures/security_structure_of_factors/security_structure_of_factor_instances.rs index 59e12180a..3865741be 100644 --- a/crates/profile/models/security-structures/src/roles_matrices_structures/security_structure_of_factors/security_structure_of_factor_instances.rs +++ b/crates/profile/models/security-structures/src/roles_matrices_structures/security_structure_of_factors/security_structure_of_factor_instances.rs @@ -287,7 +287,7 @@ mod tests { } ] }, - "numberOfDaysUntilAutoConfirm": 14 + "numberOfDaysUntilTimedConfirmationIsCallable": 14 }, "authenticationSigningFactorInstance": { "factorSourceID": { @@ -471,7 +471,7 @@ mod tests { } ] }, - "numberOfDaysUntilAutoConfirm": 14 + "numberOfDaysUntilTimedConfirmationIsCallable": 14 }, "authenticationSigningFactorInstance": { "factorSourceID": { diff --git a/crates/profile/models/security-structures/src/roles_matrices_structures/security_structure_of_factors/security_structure_of_factor_source_ids.rs b/crates/profile/models/security-structures/src/roles_matrices_structures/security_structure_of_factors/security_structure_of_factor_source_ids.rs index 382acb199..a90a40e59 100644 --- a/crates/profile/models/security-structures/src/roles_matrices_structures/security_structure_of_factors/security_structure_of_factor_source_ids.rs +++ b/crates/profile/models/security-structures/src/roles_matrices_structures/security_structure_of_factors/security_structure_of_factor_source_ids.rs @@ -117,7 +117,7 @@ mod tests { } ] }, - "numberOfDaysUntilAutoConfirm": 14 + "numberOfDaysUntilTimedConfirmationIsCallable": 14 } } "#, @@ -184,7 +184,7 @@ mod tests { } ] }, - "numberOfDaysUntilAutoConfirm": 14 + "numberOfDaysUntilTimedConfirmationIsCallable": 14 } } "#, diff --git a/crates/profile/models/security-structures/src/roles_matrices_structures/security_structure_of_factors/security_structure_of_factor_sources.rs b/crates/profile/models/security-structures/src/roles_matrices_structures/security_structure_of_factors/security_structure_of_factor_sources.rs index 8391fb4e7..241cf59b6 100644 --- a/crates/profile/models/security-structures/src/roles_matrices_structures/security_structure_of_factors/security_structure_of_factor_sources.rs +++ b/crates/profile/models/security-structures/src/roles_matrices_structures/security_structure_of_factors/security_structure_of_factor_sources.rs @@ -104,7 +104,7 @@ impl From for MatrixOfFactorSourceIDs { ConfirmationRoleWithFactorSourceIds::from( value.confirmation_role, ), - value.number_of_days_until_auto_confirm, + value.number_of_days_until_timed_confirmation_is_callable, ) } } diff --git a/crates/profile/models/security-structures/src/time_period.rs b/crates/profile/models/security-structures/src/time_period.rs index fc1e81b27..49a548ad6 100644 --- a/crates/profile/models/security-structures/src/time_period.rs +++ b/crates/profile/models/security-structures/src/time_period.rs @@ -2,7 +2,7 @@ use crate::prelude::*; /// Time period expressed by a number of `TimePeriodUnit`. /// -/// Used to represent in the hosts UI the time period until the recovery role is auto confirmed +/// Used to represent in the hosts UI the time period until recovery can be confirmed with timed based confirmation #[derive(PartialEq, Eq, Clone, Copy, Debug)] pub struct TimePeriod { pub value: u16, diff --git a/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_apply_security_shield_kind.rs b/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_apply_security_shield_kind.rs index 4fceeeb77..dff41ec6a 100644 --- a/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_apply_security_shield_kind.rs +++ b/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_apply_security_shield_kind.rs @@ -22,20 +22,65 @@ pub enum TransactionManifestApplySecurityShieldKind { /// (Primary Recovery Confirmation) PrimaryAndRecoveryWithExplicitConfirmation, - /// (Primary Recovery Time) - PrimaryAndRecoveryWithTimedAutoConfirm, + /// (Primary Recovery + Timed Confirm) + /// + /// Initiates recovery using `Recovery` role and confirms using time based + /// confirmation. + /// + /// Since this roles combination does not explicitly use the Confirmation + /// Role we will not include any confirm Instruction in the manifest + /// we build for this kind. Instead, if this is the TransactionManifest which + /// we will be submitting to the network, the host (user) will need to wait + /// until the transaction is confirmed and then update Profile to keep + /// track of the fact that the entity is in between states of recovery. + /// TODO: TBD probably a new variant of the `ProvisionalSecurifiedConfig` + /// `WaitingForTimedRecovery(SecurityStructureOfFactorInstances)` or similar. + /// + /// Host will also need to schedule a notification for user so that host + /// can call the `confirm_timed_recovery` method after the time has elapsed. + PrimaryAndRecoveryWithTimedConfirm, /// (Primary Confirmation) + /// + /// Initiates recovery using `Primary` role and quick confirms using + /// `Confirmation` role explicitly. PrimaryAndExplicitConfirmation, - /// (Primary Time) ‼️ REQUIRES "Dugong" ‼️ - PrimaryWithTimedAutoConfirm, + /// (Primary + Timed Confirm) ‼️ REQUIRES "Dugong" ‼️ + /// + /// Since this roles combination does not explicitly use the Confirmation + /// Role we will not include any confirm Instruction in the manifest + /// we build for this kind. Instead, if this is the TransactionManifest which + /// we will be submitting to the network, the host (user) will need to wait + /// until the transaction is confirmed and then update Profile to keep + /// track of the fact that the entity is in between states of recovery. + /// TODO: TBD probably a new variant of the `ProvisionalSecurifiedConfig` + /// `WaitingForTimedRecovery(SecurityStructureOfFactorInstances)` or similar. + /// + /// Host will also need to schedule a notification for user so that host + /// can call the `confirm_timed_recovery` method after the time has elapsed. + PrimaryWithTimedConfirm, - /// (Recovery Confirmation) + /// (Recovery + Confirmation) + /// + /// Initiates recovery using `Recovery` role and quick confirms using + /// `Confirmation` role explicitly. RecoveryAndExplicitConfirmation, - /// (Recovery Time) - RecoveryWithTimedAutoConfirm, + /// (Recovery + Timed Confirm) + /// + /// Since this roles combination does not explicitly use the Confirmation + /// Role we will not include any confirm Instruction in the manifest + /// we build for this kind. Instead, if this is the TransactionManifest which + /// we will be submitting to the network, the host (user) will need to wait + /// until the transaction is confirmed and then update Profile to keep + /// track of the fact that the entity is in between states of recovery. + /// TODO: TBD probably a new variant of the `ProvisionalSecurifiedConfig` + /// `WaitingForTimedRecovery(SecurityStructureOfFactorInstances)` or similar. + /// + /// Host will also need to schedule a notification for user so that host + /// can call the `confirm_timed_recovery` method after the time has elapsed. + RecoveryWithTimedConfirm, } use radix_common::prelude::ManifestEncode; @@ -54,11 +99,11 @@ impl TransactionManifestApplySecurityShieldKind { fn can_exercise_primary_role(&self) -> bool { match self { Self::PrimaryAndRecoveryWithExplicitConfirmation => true, - Self::PrimaryAndRecoveryWithTimedAutoConfirm => true, + Self::PrimaryAndRecoveryWithTimedConfirm => true, Self::PrimaryAndExplicitConfirmation => true, - Self::PrimaryWithTimedAutoConfirm => true, + Self::PrimaryWithTimedConfirm => true, Self::RecoveryAndExplicitConfirmation => false, - Self::RecoveryWithTimedAutoConfirm => false, + Self::RecoveryWithTimedConfirm => false, } } @@ -66,11 +111,11 @@ impl TransactionManifestApplySecurityShieldKind { fn can_exercise_recovery_role(&self) -> bool { match self { Self::PrimaryAndRecoveryWithExplicitConfirmation => true, - Self::PrimaryAndRecoveryWithTimedAutoConfirm => true, + Self::PrimaryAndRecoveryWithTimedConfirm => true, Self::PrimaryAndExplicitConfirmation => false, - Self::PrimaryWithTimedAutoConfirm => false, + Self::PrimaryWithTimedConfirm => false, Self::RecoveryAndExplicitConfirmation => true, - Self::RecoveryWithTimedAutoConfirm => true, + Self::RecoveryWithTimedConfirm => true, } } @@ -80,11 +125,11 @@ impl TransactionManifestApplySecurityShieldKind { fn can_exercise_confirmation_role_explicitly(&self) -> bool { match self { Self::PrimaryAndRecoveryWithExplicitConfirmation => true, - Self::PrimaryAndRecoveryWithTimedAutoConfirm => false, + Self::PrimaryAndRecoveryWithTimedConfirm => false, Self::PrimaryAndExplicitConfirmation => true, - Self::PrimaryWithTimedAutoConfirm => false, + Self::PrimaryWithTimedConfirm => false, Self::RecoveryAndExplicitConfirmation => true, - Self::RecoveryWithTimedAutoConfirm => false, + Self::RecoveryWithTimedConfirm => false, } } diff --git a/crates/uniffi/uniffi_SPLIT_ME/src/profile/mfa/security_structures/matrices/decl_matrix_macro.rs b/crates/uniffi/uniffi_SPLIT_ME/src/profile/mfa/security_structures/matrices/decl_matrix_macro.rs index 23fdb97b0..2a511668d 100644 --- a/crates/uniffi/uniffi_SPLIT_ME/src/profile/mfa/security_structures/matrices/decl_matrix_macro.rs +++ b/crates/uniffi/uniffi_SPLIT_ME/src/profile/mfa/security_structures/matrices/decl_matrix_macro.rs @@ -25,7 +25,7 @@ macro_rules! matrix_conversion { pub recovery_role: #recovery_role_type, pub confirmation_role: #confirmation_role_type, - pub number_of_days_until_auto_confirm: u16, + pub number_of_days_until_timed_confirmation_is_callable: u16, } delegate_debug_into!(#struct_name, #internal_struct_name); @@ -36,8 +36,8 @@ macro_rules! matrix_conversion { primary_role: value.primary().clone().into(), recovery_role: value.recovery().clone().into(), confirmation_role: value.confirmation().clone().into(), - number_of_days_until_auto_confirm: value - .number_of_days_until_auto_confirm, + number_of_days_until_timed_confirmation_is_callable: value + .number_of_days_until_timed_confirmation_is_callable, } } } @@ -49,7 +49,7 @@ macro_rules! matrix_conversion { self.primary_role.clone().into(), self.recovery_role.clone().into(), self.confirmation_role.clone().into(), - self.number_of_days_until_auto_confirm, + self.number_of_days_until_timed_confirmation_is_callable, ) } } diff --git a/crates/uniffi/uniffi_SPLIT_ME/src/profile/mfa/security_structures/security_shield_builder.rs b/crates/uniffi/uniffi_SPLIT_ME/src/profile/mfa/security_structures/security_shield_builder.rs index 8a1e0cc7b..9ffeb2c8f 100644 --- a/crates/uniffi/uniffi_SPLIT_ME/src/profile/mfa/security_structures/security_shield_builder.rs +++ b/crates/uniffi/uniffi_SPLIT_ME/src/profile/mfa/security_structures/security_shield_builder.rs @@ -102,9 +102,13 @@ impl SecurityShieldBuilder { .collect() } - pub fn get_time_period_until_auto_confirm(&self) -> TimePeriod { - self.get(|builder| builder.get_time_period_until_auto_confirm()) - .into() + pub fn get_time_period_until_timed_confirmation_is_callable( + &self, + ) -> TimePeriod { + self.get(|builder| { + builder.get_time_period_until_timed_confirmation_is_callable() + }) + .into() } pub fn get_name(&self) -> String { @@ -206,13 +210,14 @@ impl SecurityShieldBuilder { self.set(|builder| builder.set_threshold(threshold.into())) } - pub fn set_time_period_until_auto_confirm( + pub fn set_time_period_until_timed_confirmation_is_callable( self: Arc, time_period: TimePeriod, ) -> Arc { self.set(|builder| { - builder - .set_time_period_until_auto_confirm(time_period.clone().into()) + builder.set_time_period_until_timed_confirmation_is_callable( + time_period.clone().into(), + ) }) } @@ -637,16 +642,18 @@ mod tests { assert_eq!( time_period_to_days( - &sut.clone().get_time_period_until_auto_confirm() + &sut.clone() + .get_time_period_until_timed_confirmation_is_callable() ), 14 ); - sut = sut.set_time_period_until_auto_confirm( + sut = sut.set_time_period_until_timed_confirmation_is_callable( new_time_period_with_days(u16::MAX), ); assert_eq!( time_period_to_days( - &sut.clone().get_time_period_until_auto_confirm() + &sut.clone() + .get_time_period_until_timed_confirmation_is_callable() ), u16::MAX ); @@ -964,12 +971,12 @@ mod tests { FactorSource::sample_ledger_other(), ]; let name = "Auto Built"; - let days_to_auto_confirm = 237; + let days_until_timed_confirmation = 237; sut = sut .set_name(name.to_owned()) - .set_time_period_until_auto_confirm(new_time_period_with_days( - days_to_auto_confirm, - )) + .set_time_period_until_timed_confirmation_is_callable( + new_time_period_with_days(days_until_timed_confirmation), + ) .add_factor_source_to_primary_threshold( FactorSource::sample_device_babylon().id(), ) @@ -986,8 +993,8 @@ mod tests { assert_eq!(shield.metadata.display_name.value, name.to_owned()); let matrix = shield.matrix_of_factors; assert_eq!( - matrix.number_of_days_until_auto_confirm, - days_to_auto_confirm + matrix.number_of_days_until_timed_confirmation_is_callable, + days_until_timed_confirmation ); pretty_assertions::assert_eq!( diff --git a/crates/uniffi/uniffi_SPLIT_ME/src/profile/mfa/security_structures/security_shield_builder_rule_violation.rs b/crates/uniffi/uniffi_SPLIT_ME/src/profile/mfa/security_structures/security_shield_builder_rule_violation.rs index 6fddd6ad2..63b157791 100644 --- a/crates/uniffi/uniffi_SPLIT_ME/src/profile/mfa/security_structures/security_shield_builder_rule_violation.rs +++ b/crates/uniffi/uniffi_SPLIT_ME/src/profile/mfa/security_structures/security_shield_builder_rule_violation.rs @@ -14,8 +14,8 @@ pub enum SecurityShieldBuilderRuleViolation { #[error("Shield name is invalid")] ShieldNameInvalid, - #[error("The number of days until auto confirm must be greater than zero")] - NumberOfDaysUntilAutoConfirmMustBeGreaterThanZero, + #[error("The number of days until timed confirm is callable must be greater than zero")] + NumberOfDaysUntilTimeBasedConfirmationMustBeGreaterThanZero, #[error("Recovery and confirmation factors overlap. No factor may be used in both the recovery and confirmation roles")] RecoveryAndConfirmationFactorsOverlap, From 0ce2b35b2bc1184f5ba79d700cee14fe0c721a02 Mon Sep 17 00:00:00 2001 From: Alexander Cyon Date: Fri, 24 Jan 2025 14:59:25 +0100 Subject: [PATCH 12/25] fix typo --- .../lock_fee_against_xrd_vault_of_access_controller.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/transaction/manifests/src/manifests_security_shield/lock_fee_against_xrd_vault_of_access_controller.rs b/crates/transaction/manifests/src/manifests_security_shield/lock_fee_against_xrd_vault_of_access_controller.rs index 9e960af71..bc01c31fd 100644 --- a/crates/transaction/manifests/src/manifests_security_shield/lock_fee_against_xrd_vault_of_access_controller.rs +++ b/crates/transaction/manifests/src/manifests_security_shield/lock_fee_against_xrd_vault_of_access_controller.rs @@ -19,7 +19,7 @@ pub trait TransactionManifestLockFeeAgainstXrdVaultOfAccessController { /// In fact we will be locking fee for 6 flavours of transaction manifest /// which updates the security shield of an entity, as returned by /// `TransactionManifestApplySecurityShieldKind::all()`, and we could try to - /// be smart and run preview of each six to get a minimial fee per manifest, + /// be smart and run preview of each six to get a minimal fee per manifest, /// but we will avoid that complexity. /// /// Only relevant for securified entities - since it is only securified entities From 55297150ae98de0b8d1997b28a3f8b10187ea09c Mon Sep 17 00:00:00 2001 From: Alexander Cyon Date: Fri, 24 Jan 2025 19:21:00 +0100 Subject: [PATCH 13/25] review comments --- ...on_os_apply_security_shield_interaction.rs | 2 +- .../src/manifest_builder_from_manifest.rs | 36 ++++- ..._against_xrd_vault_of_access_controller.rs | 10 +- ...fests_securify_shield_securified_entity.rs | 9 +- ...sts_securify_shield_unsecurified_entity.rs | 2 +- .../src/manifests_security_shield/mod.rs | 8 +- ...le_in_transaction_manifest_combination.rs} | 126 +++++++++--------- ...nsaction_manifest_owner_badge_producing.rs | 68 ---------- ..._entity_owner_badge_into_bucket_putting.rs | 60 +++++++++ 9 files changed, 168 insertions(+), 153 deletions(-) rename crates/transaction/manifests/src/manifests_security_shield/{transaction_manifest_apply_security_shield_kind.rs => roles_exercisable_in_transaction_manifest_combination.rs} (67%) delete mode 100644 crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_owner_badge_producing.rs create mode 100644 crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_unsecurified_entity_owner_badge_into_bucket_putting.rs diff --git a/crates/system/os/factors/src/apply_security_shield/sargon_os_apply_security_shield_interaction.rs b/crates/system/os/factors/src/apply_security_shield/sargon_os_apply_security_shield_interaction.rs index 48704c7a1..83739916a 100644 --- a/crates/system/os/factors/src/apply_security_shield/sargon_os_apply_security_shield_interaction.rs +++ b/crates/system/os/factors/src/apply_security_shield/sargon_os_apply_security_shield_interaction.rs @@ -45,7 +45,7 @@ impl OsApplySecurityShieldInteraction for SargonOS { TransactionManifest::apply_security_shield_for_securified_entity( e, derived.clone(), - TransactionManifestApplySecurityShieldKind::PrimaryAndRecoveryWithExplicitConfirmation + RolesExercisableInTransactionManifestCombination::default() ) }).collect::>>()?; diff --git a/crates/transaction/manifests/src/manifest_builder_from_manifest.rs b/crates/transaction/manifests/src/manifest_builder_from_manifest.rs index 27c286068..ae933d6a3 100644 --- a/crates/transaction/manifests/src/manifest_builder_from_manifest.rs +++ b/crates/transaction/manifests/src/manifest_builder_from_manifest.rs @@ -2,7 +2,35 @@ use radix_transactions::prelude::ManifestBuilder; use crate::prelude::*; -pub trait BuilderFromManifest { +pub trait BuilderExtendWithInstructions: Sized { + fn extend_builder_with_instructions( + self, + instructions: impl IntoIterator, + ) -> ManifestBuilder; + + fn extend_builder_with_manifest( + self, + manifest: TransactionManifest, + ) -> ManifestBuilder { + Self::extend_builder_with_instructions( + self, + manifest.instructions().clone(), + ) + } +} + +impl BuilderExtendWithInstructions for ManifestBuilder { + fn extend_builder_with_instructions( + self, + instructions: impl IntoIterator, + ) -> ManifestBuilder { + instructions.into_iter().fold(self, |builder, instruction| { + builder.add_instruction_advanced(instruction).0 + }) + } +} + +pub trait BuilderFromManifest: BuilderExtendWithInstructions { fn with_instructions( instructions: impl IntoIterator, ) -> ManifestBuilder; @@ -16,11 +44,9 @@ impl BuilderFromManifest for ManifestBuilder { fn with_instructions( instructions: impl IntoIterator, ) -> ManifestBuilder { - instructions.into_iter().fold( + Self::extend_builder_with_instructions( ManifestBuilder::new(), - |builder, instruction| { - builder.add_instruction_advanced(instruction).0 - }, + instructions, ) } } diff --git a/crates/transaction/manifests/src/manifests_security_shield/lock_fee_against_xrd_vault_of_access_controller.rs b/crates/transaction/manifests/src/manifests_security_shield/lock_fee_against_xrd_vault_of_access_controller.rs index bc01c31fd..fde41e6fa 100644 --- a/crates/transaction/manifests/src/manifests_security_shield/lock_fee_against_xrd_vault_of_access_controller.rs +++ b/crates/transaction/manifests/src/manifests_security_shield/lock_fee_against_xrd_vault_of_access_controller.rs @@ -18,7 +18,7 @@ pub trait TransactionManifestLockFeeAgainstXrdVaultOfAccessController { /// /// In fact we will be locking fee for 6 flavours of transaction manifest /// which updates the security shield of an entity, as returned by - /// `TransactionManifestApplySecurityShieldKind::all()`, and we could try to + /// `RolesExercisableInTransactionManifestCombination::all()`, and we could try to /// be smart and run preview of each six to get a minimal fee per manifest, /// but we will avoid that complexity. /// @@ -30,11 +30,14 @@ pub trait TransactionManifestLockFeeAgainstXrdVaultOfAccessController { // TODO: remove `entity_applying_shield`, this should be read out from the manifest in a throwing function, `manifest.get_address_of_entity_applying_shield()` or similar which Omar need to provide us with, oh well we need the account here, so elsewhere, in SargonOS where we have access to Profile we would call `manifest.get_address_of_entity_applying_shield` and then lookup the entity. entity_applying_shield: AnySecurifiedEntity, ) -> TransactionManifest { - let mut builder = ManifestBuilder::with_manifest(manifest); + let mut builder = ManifestBuilder::new(); + let access_controller_address = entity_applying_shield .securified_entity_control .access_controller_address; + // Lock fee against XRD vault of the access controller + // put this instruction at index 0 builder = builder.call_method( access_controller_address.scrypto(), SCRYPTO_ACCESS_CONTROLLER_LOCK_RECOVERY_FEE_IDENT, @@ -43,6 +46,9 @@ pub trait TransactionManifestLockFeeAgainstXrdVaultOfAccessController { }, ); + // ... then append all instructions from the original manifest + builder = builder.extend_builder_with_manifest(manifest); + TransactionManifest::sargon_built( builder, entity_applying_shield.entity.network_id(), diff --git a/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs b/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs index 630e389df..af12cdfa7 100644 --- a/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs +++ b/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs @@ -11,7 +11,7 @@ pub trait TransactionManifestSecurifySecurifiedEntity: securified_entity: AnySecurifiedEntity, security_structure_of_factor_instances: SecurityStructureOfFactorInstances, - apply_shield_manifest_kind: TransactionManifestApplySecurityShieldKind, + apply_shield_manifest_kind: RolesExercisableInTransactionManifestCombination, ) -> Result; } @@ -33,16 +33,13 @@ impl TransactionManifestSecurifySecurifiedEntity for TransactionManifest { securified_entity: AnySecurifiedEntity, security_structure_of_factor_instances: SecurityStructureOfFactorInstances, - apply_shield_manifest_kind: TransactionManifestApplySecurityShieldKind, + apply_shield_manifest_kind: RolesExercisableInTransactionManifestCombination, ) -> Result { let kind = apply_shield_manifest_kind; let entity_address = securified_entity.entity.address(); // ACCESS_CONTROLLER_CREATE_PROOF_IDENT - let mut builder = TransactionManifest::produce_owner_badge( - ScryptoTransactionManifestBuilder::new(), - &securified_entity.entity, - ); + let mut builder = ScryptoTransactionManifestBuilder::new(); let access_controller_address = securified_entity .securified_entity_control diff --git a/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_unsecurified_entity.rs b/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_unsecurified_entity.rs index 93276e08b..aae4095c2 100644 --- a/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_unsecurified_entity.rs +++ b/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_unsecurified_entity.rs @@ -37,7 +37,7 @@ impl TransactionManifestSecurifyUnsecurifiedEntity for TransactionManifest { // Securify the entity which will return an entity owner badge onto the worktop. let (mut builder, owner_badge_bucket) = Self::put_owner_badge_in_bucket( ScryptoTransactionManifestBuilder::new(), - &unsecurified_entity.entity, + &unsecurified_entity, ); // Create an access controller for the entity. diff --git a/crates/transaction/manifests/src/manifests_security_shield/mod.rs b/crates/transaction/manifests/src/manifests_security_shield/mod.rs index 0098531ec..6ba5ebe5a 100644 --- a/crates/transaction/manifests/src/manifests_security_shield/mod.rs +++ b/crates/transaction/manifests/src/manifests_security_shield/mod.rs @@ -3,10 +3,10 @@ mod confirm_timed_recovery; mod lock_fee_against_xrd_vault_of_access_controller; mod manifests_securify_shield_securified_entity; mod manifests_securify_shield_unsecurified_entity; +mod roles_exercisable_in_transaction_manifest_combination; mod set_rola_key; mod top_up_access_controller_xrd_vault; -mod transaction_manifest_apply_security_shield_kind; -mod transaction_manifest_owner_badge_producing; +mod transaction_manifest_unsecurified_entity_owner_badge_into_bucket_putting; pub use access_controller_factors_and_time_input::*; pub use confirm_timed_recovery::*; @@ -15,5 +15,5 @@ pub use manifests_securify_shield_securified_entity::*; pub use manifests_securify_shield_unsecurified_entity::*; pub use set_rola_key::*; pub use top_up_access_controller_xrd_vault::*; -pub use transaction_manifest_apply_security_shield_kind::*; -pub use transaction_manifest_owner_badge_producing::*; +pub use roles_exercisable_in_transaction_manifest_combination::*; +pub use transaction_manifest_unsecurified_entity_owner_badge_into_bucket_putting::*; diff --git a/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_apply_security_shield_kind.rs b/crates/transaction/manifests/src/manifests_security_shield/roles_exercisable_in_transaction_manifest_combination.rs similarity index 67% rename from crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_apply_security_shield_kind.rs rename to crates/transaction/manifests/src/manifests_security_shield/roles_exercisable_in_transaction_manifest_combination.rs index dff41ec6a..ee81de140 100644 --- a/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_apply_security_shield_kind.rs +++ b/crates/transaction/manifests/src/manifests_security_shield/roles_exercisable_in_transaction_manifest_combination.rs @@ -1,5 +1,9 @@ use crate::prelude::*; +use radix_common::prelude::{ + ManifestEncode as ScryptoManifestEncode, + ManifestSborTuple as ScryptoManifestSborTuple, +}; use radix_engine_interface::blueprints::access_controller::{ AccessControllerInitiateRecoveryAsPrimaryInput as ScryptoAccessControllerInitiateRecoveryAsPrimaryInput, AccessControllerInitiateRecoveryAsRecoveryInput as ScryptoAccessControllerInitiateRecoveryAsRecoveryInput, @@ -18,35 +22,20 @@ use radix_engine_interface::blueprints::access_controller::{ /// Each combination of roles allows us to skip signing with certain factors /// and still be able to recover + confirm the AccessController update. #[derive(Clone, Debug, PartialEq, Eq, Hash, enum_iterator::Sequence)] -pub enum TransactionManifestApplySecurityShieldKind { - /// (Primary Recovery Confirmation) - PrimaryAndRecoveryWithExplicitConfirmation, - - /// (Primary Recovery + Timed Confirm) - /// - /// Initiates recovery using `Recovery` role and confirms using time based - /// confirmation. - /// - /// Since this roles combination does not explicitly use the Confirmation - /// Role we will not include any confirm Instruction in the manifest - /// we build for this kind. Instead, if this is the TransactionManifest which - /// we will be submitting to the network, the host (user) will need to wait - /// until the transaction is confirmed and then update Profile to keep - /// track of the fact that the entity is in between states of recovery. - /// TODO: TBD probably a new variant of the `ProvisionalSecurifiedConfig` - /// `WaitingForTimedRecovery(SecurityStructureOfFactorInstances)` or similar. - /// - /// Host will also need to schedule a notification for user so that host - /// can call the `confirm_timed_recovery` method after the time has elapsed. - PrimaryAndRecoveryWithTimedConfirm, +pub enum RolesExercisableInTransactionManifestCombination { + /// Initiates recovery using `Primary` role and quick confirms using + /// `Recovery` role explicitly. + InitiateWithPrimaryCompleteWithRecovery, - /// (Primary Confirmation) - /// /// Initiates recovery using `Primary` role and quick confirms using /// `Confirmation` role explicitly. - PrimaryAndExplicitConfirmation, + InitiateWithPrimaryCompleteWithConfirmation, - /// (Primary + Timed Confirm) ‼️ REQUIRES "Dugong" ‼️ + /// Initiates recovery using `Recovery` role and quick confirms using + /// `Confirmation` role explicitly. + InitiateWithRecoveryCompleteWithConfirmation, + + /// Initiate recovery with `Recovery` role and use timed confirmation. /// /// Since this roles combination does not explicitly use the Confirmation /// Role we will not include any confirm Instruction in the manifest @@ -59,15 +48,10 @@ pub enum TransactionManifestApplySecurityShieldKind { /// /// Host will also need to schedule a notification for user so that host /// can call the `confirm_timed_recovery` method after the time has elapsed. - PrimaryWithTimedConfirm, - - /// (Recovery + Confirmation) - /// - /// Initiates recovery using `Recovery` role and quick confirms using - /// `Confirmation` role explicitly. - RecoveryAndExplicitConfirmation, + InitiateWithRecoveryDelayedCompletion, - /// (Recovery + Timed Confirm) + /// ‼️ REQUIRES "Dugong" ‼️ + /// Initiate recovery with `Primary` role and use timed confirmation. /// /// Since this roles combination does not explicitly use the Confirmation /// Role we will not include any confirm Instruction in the manifest @@ -80,57 +64,67 @@ pub enum TransactionManifestApplySecurityShieldKind { /// /// Host will also need to schedule a notification for user so that host /// can call the `confirm_timed_recovery` method after the time has elapsed. - RecoveryWithTimedConfirm, + /// + /// ‼️ REQUIRES "Dugong" ‼️ + InitiateWithPrimaryDelayedCompletion, + // TODO: + // FUTURE IMPROVEMENTS, + // User can't initiate themselves and needs to send a request to an external source (e.g. a friend or custodian) + // ExternalInitiateWithPrimary + // ExternalInitiateWithRecovery } -use radix_common::prelude::ManifestEncode; -use radix_common::prelude::ManifestSborTuple; -// Trickery to allow `Box` - which is not allowed it seems, -// but this solves it, since in Scrypto they impl ResolvableArguments for ManifestEncode + ManifestSborTuple -pub trait CallMethodInput: ManifestEncode + ManifestSborTuple {} -impl CallMethodInput for T {} +impl Default for RolesExercisableInTransactionManifestCombination { + fn default() -> Self { + // we default to a combination containing Primary since it allows + // use to top up XRD vault of AccessController + Self::InitiateWithPrimaryCompleteWithRecovery + } +} + +pub trait CallMethodInput: + ScryptoManifestEncode + ScryptoManifestSborTuple +{ +} +impl CallMethodInput + for T +{ +} -impl TransactionManifestApplySecurityShieldKind { +impl RolesExercisableInTransactionManifestCombination { pub fn all() -> IndexSet { enum_iterator::all::().collect() } /// If this combination of roles references the `Primary` role or not. fn can_exercise_primary_role(&self) -> bool { - match self { - Self::PrimaryAndRecoveryWithExplicitConfirmation => true, - Self::PrimaryAndRecoveryWithTimedConfirm => true, - Self::PrimaryAndExplicitConfirmation => true, - Self::PrimaryWithTimedConfirm => true, - Self::RecoveryAndExplicitConfirmation => false, - Self::RecoveryWithTimedConfirm => false, - } + matches!( + self, + Self::InitiateWithPrimaryCompleteWithRecovery + | Self::InitiateWithPrimaryCompleteWithConfirmation + | Self::InitiateWithPrimaryDelayedCompletion + ) } /// If this combination of roles references the `Recovery` role or not. fn can_exercise_recovery_role(&self) -> bool { - match self { - Self::PrimaryAndRecoveryWithExplicitConfirmation => true, - Self::PrimaryAndRecoveryWithTimedConfirm => true, - Self::PrimaryAndExplicitConfirmation => false, - Self::PrimaryWithTimedConfirm => false, - Self::RecoveryAndExplicitConfirmation => true, - Self::RecoveryWithTimedConfirm => true, - } + matches!( + self, + Self::InitiateWithPrimaryCompleteWithRecovery + | Self::InitiateWithRecoveryCompleteWithConfirmation + | Self::InitiateWithRecoveryDelayedCompletion + ) } /// If this combination of roles references the `Confirmation` role or not. /// /// Explicitly means "not using time, but use quick confirmation" fn can_exercise_confirmation_role_explicitly(&self) -> bool { - match self { - Self::PrimaryAndRecoveryWithExplicitConfirmation => true, - Self::PrimaryAndRecoveryWithTimedConfirm => false, - Self::PrimaryAndExplicitConfirmation => true, - Self::PrimaryWithTimedConfirm => false, - Self::RecoveryAndExplicitConfirmation => true, - Self::RecoveryWithTimedConfirm => false, - } + matches!( + self, + Self::InitiateWithPrimaryCompleteWithConfirmation + | Self::InitiateWithRecoveryCompleteWithConfirmation + ) } /// If we can set the ROLA key for this combination of roles. @@ -164,7 +158,7 @@ impl TransactionManifestApplySecurityShieldKind { ) } else { unreachable!( - "No kind exists which disallows for both primary and recovery" + "No combination exists which disallows for both primary and recovery" ) } } diff --git a/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_owner_badge_producing.rs b/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_owner_badge_producing.rs deleted file mode 100644 index cde0b894d..000000000 --- a/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_owner_badge_producing.rs +++ /dev/null @@ -1,68 +0,0 @@ -use std::borrow::Borrow; - -use radix_engine_interface::blueprints::access_controller::ACCESS_CONTROLLER_CREATE_PROOF_IDENT; - -use crate::prelude::*; - -impl TransactionManifestOwnerBadgeProducing for TransactionManifest {} - -pub trait TransactionManifestOwnerBadgeProducing { - /// Produces and puts the owner badge in a Bucket and returns the bucket. - fn put_owner_badge_in_bucket( - builder: ScryptoTransactionManifestBuilder, - owner: impl Borrow, - ) -> (ScryptoTransactionManifestBuilder, ScryptoManifestBucket) { - let owner = owner.borrow(); - let is_account = owner.is_account_entity(); - let owner_badge_bucket_name = "owner_badge_bucket"; - let owner_badge = if is_account { - SCRYPTO_ACCOUNT_OWNER_BADGE - } else { - SCRYPTO_IDENTITY_OWNER_BADGE - }; - let mut builder = Self::produce_owner_badge(builder, owner); - // Create a bucket out of the entity owner badge. - builder = - builder.take_from_worktop(owner_badge, 1, owner_badge_bucket_name); - - let owner_badge_bucket = builder.bucket(owner_badge_bucket_name); - - (builder, owner_badge_bucket) - } - - /// Produce the owner badge - /// TODO: Ask Omar if this is correct for Securified entityes. - fn produce_owner_badge( - builder: ScryptoTransactionManifestBuilder, - owner: impl Borrow, - ) -> ScryptoTransactionManifestBuilder { - let mut builder = builder; - let owner = owner.borrow(); - - let is_account = owner.is_account_entity(); - - match owner.security_state() { - EntitySecurityState::Securified { value } => { - builder = builder.call_method( - value.access_controller_address.scrypto(), - ACCESS_CONTROLLER_CREATE_PROOF_IDENT, - (), - ); - } - EntitySecurityState::Unsecured { value: _ } => { - let securify_entity_identifier = if is_account { - SCRYPTO_ACCOUNT_SECURIFY_IDENT - } else { - SCRYPTO_IDENTITY_SECURIFY_IDENT - }; - builder = builder.call_method( - owner.address().scrypto(), - securify_entity_identifier, - (), - ); - } - } - - builder - } -} diff --git a/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_unsecurified_entity_owner_badge_into_bucket_putting.rs b/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_unsecurified_entity_owner_badge_into_bucket_putting.rs new file mode 100644 index 000000000..58b6eda31 --- /dev/null +++ b/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_unsecurified_entity_owner_badge_into_bucket_putting.rs @@ -0,0 +1,60 @@ +use profile_supporting_types::AnyUnsecurifiedEntity; + +use crate::prelude::*; + +impl TransactionManifestUnsecurifiedEntityOwnerBadgeIntoBucketPutting + for TransactionManifest +{ +} + +pub trait TransactionManifestUnsecurifiedEntityOwnerBadgeIntoBucketPutting { + /// Produces and puts the owner badge of an Unsecurified Entity by calling + /// "securify" and put said owner badge in a Bucket and returns the bucket. + fn put_owner_badge_in_bucket( + builder: ScryptoTransactionManifestBuilder, + unsecurified_entity: &AnyUnsecurifiedEntity, + ) -> (ScryptoTransactionManifestBuilder, ScryptoManifestBucket) { + let is_account = unsecurified_entity.entity.is_account_entity(); + let owner_badge_bucket_name = "owner_badge_bucket"; + let owner_badge = if is_account { + SCRYPTO_ACCOUNT_OWNER_BADGE + } else { + SCRYPTO_IDENTITY_OWNER_BADGE + }; + let mut builder = Self::call_securify_for_unsecurified_entity( + builder, + unsecurified_entity, + ); + // Create a bucket out of the entity owner badge. + builder = + builder.take_from_worktop(owner_badge, 1, owner_badge_bucket_name); + + let owner_badge_bucket = builder.bucket(owner_badge_bucket_name); + + (builder, owner_badge_bucket) + } + + /// Calls "secufiry" for an unsecurified entity which places the owner badge + /// on the worktop. + fn call_securify_for_unsecurified_entity( + builder: ScryptoTransactionManifestBuilder, + unsecurified_entity: &AnyUnsecurifiedEntity, + ) -> ScryptoTransactionManifestBuilder { + let mut builder = builder; + + let is_account = unsecurified_entity.entity.is_account_entity(); + + let securify_entity_identifier = if is_account { + SCRYPTO_ACCOUNT_SECURIFY_IDENT + } else { + SCRYPTO_IDENTITY_SECURIFY_IDENT + }; + builder = builder.call_method( + unsecurified_entity.address().scrypto(), + securify_entity_identifier, + (), + ); + + builder + } +} From 15e0558cdc2b87929934c0dfc4d115a8680c772f Mon Sep 17 00:00:00 2001 From: Alexander Cyon Date: Sat, 25 Jan 2025 15:32:05 +0100 Subject: [PATCH 14/25] refactor and assert manifests --- crates/app/radix-connect/src/lib.rs | 2 +- crates/app/signing-traits/src/lib.rs | 8 - crates/app/signing/src/lib.rs | 2 +- crates/core/prelude/src/lib.rs | 1 + crates/factors/keys-collector/src/lib.rs | 2 +- crates/profile/models/account/src/lib.rs | 8 - .../models/profile_SPLIT_ME/src/lib.rs | 3 - .../models/security-structures/src/lib.rs | 2 - .../src/any_securified_entity.rs | 66 ++++++ .../models/supporting-types/src/lib.rs | 1 + .../src/securified_account.rs | 6 + .../src/securified_persona.rs | 35 ++++ .../src/unsecurified_entity.rs | 8 +- .../src/sargon_os_derive_public_keys.rs | 5 +- crates/system/os/factors/src/lib.rs | 2 - crates/system/os/os/src/lib.rs | 2 - crates/transaction/manifests/src/lib.rs | 4 +- ..._against_xrd_vault_of_access_controller.rs | 9 +- ...fests_securify_shield_securified_entity.rs | 178 +++++++++++++++- ...sts_securify_shield_unsecurified_entity.rs | 78 +++++-- ...ble_in_transaction_manifest_combination.rs | 88 +++++--- .../top_up_access_controller_xrd_vault.rs | 76 ++++++- ...top_up_by_securified_account_amount_42.rtm | 120 +++++++++++ ...d_vault_top_up_by_unsecurified_account.rtm | 116 +++++++++++ ..._of_account_init_with_P_confirm_with_C.rtm | 171 +++++++++++++++ ..._where_payer_is_entity_applying_shield.rtm | 191 +++++++++++++++++ ...s_entity_applying_shield_with_xrd_lock.rtm | 196 ++++++++++++++++++ ..._of_persona_init_with_P_confirm_with_C.rtm | 159 ++++++++++++++ ..._of_persona_init_with_P_confirm_with_R.rtm | 159 ++++++++++++++ ..._of_persona_init_with_P_confirm_with_T.rtm | 85 ++++++++ ..._of_persona_init_with_R_confirm_with_C.rtm | 148 +++++++++++++ ..._of_persona_init_with_R_confirm_with_T.rtm | 74 +++++++ makefile | 4 + 33 files changed, 1905 insertions(+), 104 deletions(-) create mode 100644 fixtures/transaction/create_access_controller_for_persona_with_ac_xrd_vault_top_up_by_securified_account_amount_42.rtm create mode 100644 fixtures/transaction/create_access_controller_for_persona_with_ac_xrd_vault_top_up_by_unsecurified_account.rtm create mode 100644 fixtures/transaction/update_shield_of_account_init_with_P_confirm_with_C.rtm create mode 100644 fixtures/transaction/update_shield_of_account_init_with_P_confirm_with_C_with_top_up_where_payer_is_entity_applying_shield.rtm create mode 100644 fixtures/transaction/update_shield_of_account_init_with_P_confirm_with_C_with_top_up_where_payer_is_entity_applying_shield_with_xrd_lock.rtm create mode 100644 fixtures/transaction/update_shield_of_persona_init_with_P_confirm_with_C.rtm create mode 100644 fixtures/transaction/update_shield_of_persona_init_with_P_confirm_with_R.rtm create mode 100644 fixtures/transaction/update_shield_of_persona_init_with_P_confirm_with_T.rtm create mode 100644 fixtures/transaction/update_shield_of_persona_init_with_R_confirm_with_C.rtm create mode 100644 fixtures/transaction/update_shield_of_persona_init_with_R_confirm_with_T.rtm diff --git a/crates/app/radix-connect/src/lib.rs b/crates/app/radix-connect/src/lib.rs index b790456c2..fc98dd83f 100644 --- a/crates/app/radix-connect/src/lib.rs +++ b/crates/app/radix-connect/src/lib.rs @@ -49,7 +49,7 @@ pub mod prelude { mod testing { pub(crate) use drivers::prelude::MockNetworkingDriver; pub(crate) use serde_json::json; - pub(crate) use std::collections::{BTreeSet, HashSet}; + pub(crate) use std::collections::BTreeSet; } } diff --git a/crates/app/signing-traits/src/lib.rs b/crates/app/signing-traits/src/lib.rs index d778cc859..a5aa59af9 100644 --- a/crates/app/signing-traits/src/lib.rs +++ b/crates/app/signing-traits/src/lib.rs @@ -38,14 +38,6 @@ pub mod prelude { pub(crate) use indexmap::{IndexMap, IndexSet}; pub(crate) use std::fmt::Debug; - - #[cfg(test)] - pub(crate) use testing::*; - - #[cfg(test)] - mod testing { - pub(crate) use std::collections::HashSet; - } } pub use prelude::*; diff --git a/crates/app/signing/src/lib.rs b/crates/app/signing/src/lib.rs index 6059f35a9..0ff995c6e 100644 --- a/crates/app/signing/src/lib.rs +++ b/crates/app/signing/src/lib.rs @@ -31,7 +31,7 @@ pub mod prelude { pub(crate) use transaction_models::prelude::*; pub(crate) use log::*; - pub(crate) use std::collections::{HashMap, HashSet}; + pub(crate) use std::collections::HashMap; #[cfg(test)] pub(crate) use testing::*; diff --git a/crates/core/prelude/src/lib.rs b/crates/core/prelude/src/lib.rs index 9e572d391..f8c3ba15a 100644 --- a/crates/core/prelude/src/lib.rs +++ b/crates/core/prelude/src/lib.rs @@ -48,6 +48,7 @@ macro_rules! fixture_gw_model { } pub mod prelude { + pub use std::collections::HashSet; pub use std::str::FromStr; pub use std::sync::{Arc, RwLock}; } diff --git a/crates/factors/keys-collector/src/lib.rs b/crates/factors/keys-collector/src/lib.rs index 7bc15254c..91042b42b 100644 --- a/crates/factors/keys-collector/src/lib.rs +++ b/crates/factors/keys-collector/src/lib.rs @@ -21,7 +21,7 @@ pub mod prelude { pub(crate) use indexmap::{IndexMap, IndexSet}; pub(crate) use log::*; - pub(crate) use std::collections::{HashMap, HashSet}; + pub(crate) use std::collections::HashMap; #[cfg(test)] pub(crate) use testing::*; diff --git a/crates/profile/models/account/src/lib.rs b/crates/profile/models/account/src/lib.rs index 8dea804ea..d7d886e42 100644 --- a/crates/profile/models/account/src/lib.rs +++ b/crates/profile/models/account/src/lib.rs @@ -18,14 +18,6 @@ pub mod prelude { pub(crate) use transaction_models::prelude::*; pub(crate) use serde::{Deserialize, Serialize}; - - #[cfg(test)] - pub(crate) use testing::*; - - #[cfg(test)] - mod testing { - pub(crate) use std::collections::HashSet; - } } pub use prelude::*; diff --git a/crates/profile/models/profile_SPLIT_ME/src/lib.rs b/crates/profile/models/profile_SPLIT_ME/src/lib.rs index b1ba60f6f..cb8d32545 100644 --- a/crates/profile/models/profile_SPLIT_ME/src/lib.rs +++ b/crates/profile/models/profile_SPLIT_ME/src/lib.rs @@ -38,7 +38,4 @@ pub mod prelude { #[cfg(test)] pub(crate) use serde_json::json; - - #[cfg(test)] - pub(crate) use std::collections::HashSet; } diff --git a/crates/profile/models/security-structures/src/lib.rs b/crates/profile/models/security-structures/src/lib.rs index e18644041..e484892b5 100644 --- a/crates/profile/models/security-structures/src/lib.rs +++ b/crates/profile/models/security-structures/src/lib.rs @@ -43,6 +43,4 @@ pub mod prelude { pub(crate) use serde::{Deserialize, Serialize}; #[cfg(test)] pub(crate) use serde_json::json; - - pub(crate) use std::collections::HashSet; } diff --git a/crates/profile/models/supporting-types/src/any_securified_entity.rs b/crates/profile/models/supporting-types/src/any_securified_entity.rs index 9fceb98bd..41a7a18c3 100644 --- a/crates/profile/models/supporting-types/src/any_securified_entity.rs +++ b/crates/profile/models/supporting-types/src/any_securified_entity.rs @@ -9,3 +9,69 @@ impl TryFrom for AnySecurifiedEntity { Self::new(value) } } + +impl AnySecurifiedEntity { + pub fn sample_account() -> Self { + SecurifiedAccount::sample().into() + } + + pub fn sample_account_other() -> Self { + SecurifiedAccount::sample_other().into() + } + + pub fn sample_persona() -> Self { + SecurifiedPersona::sample().into() + } + + pub fn sample_persona_other() -> Self { + SecurifiedPersona::sample_other().into() + } +} + +impl HasSampleValues for AnySecurifiedEntity { + fn sample() -> Self { + Self::sample_account() + } + + fn sample_other() -> Self { + Self::sample_persona() + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[allow(clippy::upper_case_acronyms)] + type SUT = AnySecurifiedEntity; + + #[test] + fn equality() { + assert_eq!(SUT::sample(), SUT::sample()); + assert_eq!(SUT::sample_other(), SUT::sample_other()); + } + + #[test] + fn inequality() { + assert_ne!(SUT::sample(), SUT::sample_other()); + } + + #[test] + fn hash() { + assert_eq!( + HashSet::::from_iter([ + SUT::sample_account(), + SUT::sample_account_other(), + SUT::sample_persona(), + SUT::sample_persona_other(), + // Duplicates should be removed + SUT::sample_account(), + SUT::sample_account_other(), + SUT::sample_persona(), + SUT::sample_persona_other(), + ]) + .len(), + 4 + ); + } +} diff --git a/crates/profile/models/supporting-types/src/lib.rs b/crates/profile/models/supporting-types/src/lib.rs index d0bc7f961..e206c846f 100644 --- a/crates/profile/models/supporting-types/src/lib.rs +++ b/crates/profile/models/supporting-types/src/lib.rs @@ -22,6 +22,7 @@ pub mod prelude { pub use crate::veci::*; pub use hierarchical_deterministic::prelude::*; + pub use prelude::prelude::*; pub use profile::prelude::*; pub(crate) use enum_as_inner::EnumAsInner; diff --git a/crates/profile/models/supporting-types/src/securified_account.rs b/crates/profile/models/supporting-types/src/securified_account.rs index d9b52a752..596e050f5 100644 --- a/crates/profile/models/supporting-types/src/securified_account.rs +++ b/crates/profile/models/supporting-types/src/securified_account.rs @@ -15,6 +15,12 @@ impl From for AnySecurifiedEntity { } } +impl From for Account { + fn from(value: SecurifiedAccount) -> Self { + value.entity + } +} + impl HasEntityKind for SecurifiedAccount { fn entity_kind() -> CAP26EntityKind { CAP26EntityKind::Account diff --git a/crates/profile/models/supporting-types/src/securified_persona.rs b/crates/profile/models/supporting-types/src/securified_persona.rs index d9b482925..0bf75bf5f 100644 --- a/crates/profile/models/supporting-types/src/securified_persona.rs +++ b/crates/profile/models/supporting-types/src/securified_persona.rs @@ -15,6 +15,12 @@ impl From for AnySecurifiedEntity { } } +impl From for Persona { + fn from(value: SecurifiedPersona) -> Self { + value.entity + } +} + impl HasEntityKind for SecurifiedPersona { fn entity_kind() -> CAP26EntityKind { CAP26EntityKind::Identity @@ -43,3 +49,32 @@ impl TryFrom for SecurifiedPersona { } } } + +impl HasSampleValues for SecurifiedPersona { + fn sample() -> Self { + Self::new(Persona::sample_at(2)).unwrap() + } + + fn sample_other() -> Self { + Self::new(Persona::sample_at(3)).unwrap() + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[allow(clippy::upper_case_acronyms)] + type SUT = SecurifiedPersona; + + #[test] + fn equality() { + assert_eq!(SUT::sample(), SUT::sample()); + assert_eq!(SUT::sample_other(), SUT::sample_other()); + } + + #[test] + fn inequality() { + assert_ne!(SUT::sample(), SUT::sample_other()); + } +} diff --git a/crates/profile/models/supporting-types/src/unsecurified_entity.rs b/crates/profile/models/supporting-types/src/unsecurified_entity.rs index 5ba614284..8fea1be29 100644 --- a/crates/profile/models/supporting-types/src/unsecurified_entity.rs +++ b/crates/profile/models/supporting-types/src/unsecurified_entity.rs @@ -48,12 +48,12 @@ where /// # Throws /// Throws if the entity is securified - pub fn new(entity: E) -> Result { + pub fn new>(entity: T) -> Result { match entity.security_state() { EntitySecurityState::Unsecured { value: unsecured_entity_control, } => Ok(Self::with_unsecured_entity_control( - entity, + entity.into(), unsecured_entity_control, )), EntitySecurityState::Securified { .. } => { @@ -129,11 +129,11 @@ impl TryFrom for UnsecurifiedPersona { impl HasSampleValues for AnyUnsecurifiedEntity { fn sample() -> Self { - Self::new(Account::sample().into()).unwrap() + Self::new(Account::sample()).unwrap() } fn sample_other() -> Self { - Self::new(Account::sample_other().into()).unwrap() + Self::new(Account::sample_other()).unwrap() } } diff --git a/crates/system/os/derive-public-keys/src/sargon_os_derive_public_keys.rs b/crates/system/os/derive-public-keys/src/sargon_os_derive_public_keys.rs index a33b16b20..ca23a41dc 100644 --- a/crates/system/os/derive-public-keys/src/sargon_os_derive_public_keys.rs +++ b/crates/system/os/derive-public-keys/src/sargon_os_derive_public_keys.rs @@ -111,9 +111,8 @@ mod test { let factor_source_not_in_profile = FactorSourceIDFromHash::sample_password(); - let source = DerivePublicKeysSource::FactorSource( - factor_source_not_in_profile.clone(), - ); + let source = + DerivePublicKeysSource::FactorSource(factor_source_not_in_profile); let result = sut .derive_public_keys(sample_derivation_paths(), source) .await diff --git a/crates/system/os/factors/src/lib.rs b/crates/system/os/factors/src/lib.rs index 532283d93..d167bf328 100644 --- a/crates/system/os/factors/src/lib.rs +++ b/crates/system/os/factors/src/lib.rs @@ -18,8 +18,6 @@ pub mod prelude { pub use profile_logic::prelude::*; pub use sargon_os::prelude::*; - pub(crate) use std::collections::HashSet; - #[cfg(test)] pub(crate) use interactors::prelude::*; } diff --git a/crates/system/os/os/src/lib.rs b/crates/system/os/os/src/lib.rs index 7facec218..7b240450c 100644 --- a/crates/system/os/os/src/lib.rs +++ b/crates/system/os/os/src/lib.rs @@ -38,8 +38,6 @@ pub mod prelude { pub(crate) use signing_traits::prelude::*; pub(crate) use sub_systems::prelude::*; - pub(crate) use std::collections::HashSet; - #[cfg(test)] pub(crate) use testing::*; diff --git a/crates/transaction/manifests/src/lib.rs b/crates/transaction/manifests/src/lib.rs index 45ff0b5a8..cbddf100c 100644 --- a/crates/transaction/manifests/src/lib.rs +++ b/crates/transaction/manifests/src/lib.rs @@ -30,6 +30,7 @@ pub mod prelude { pub use gateway_models::prelude::*; pub use hierarchical_deterministic::prelude::*; pub use metadata::prelude::*; + pub use prelude::prelude::*; pub use profile::prelude::*; pub use std::str::FromStr; @@ -158,9 +159,6 @@ pub mod prelude { pub(crate) use serde::{Deserialize, Serialize}; pub(crate) use std::collections::BTreeMap; - - #[cfg(test)] - pub(crate) use std::collections::HashSet; } pub use prelude::*; diff --git a/crates/transaction/manifests/src/manifests_security_shield/lock_fee_against_xrd_vault_of_access_controller.rs b/crates/transaction/manifests/src/manifests_security_shield/lock_fee_against_xrd_vault_of_access_controller.rs index fde41e6fa..f9fd980a3 100644 --- a/crates/transaction/manifests/src/manifests_security_shield/lock_fee_against_xrd_vault_of_access_controller.rs +++ b/crates/transaction/manifests/src/manifests_security_shield/lock_fee_against_xrd_vault_of_access_controller.rs @@ -7,6 +7,11 @@ use radix_transactions::prelude::ManifestBuilder; use crate::prelude::*; +impl TransactionManifestLockFeeAgainstXrdVaultOfAccessController + for TransactionManifest +{ +} + pub trait TransactionManifestLockFeeAgainstXrdVaultOfAccessController { /// Locks transaction fee against the XRD vault of the access controller of /// `entity_applying_shield` - either AC of an Account or of a Persona. @@ -28,10 +33,10 @@ pub trait TransactionManifestLockFeeAgainstXrdVaultOfAccessController { manifest: TransactionManifest, fee: Decimal192, // TODO: remove `entity_applying_shield`, this should be read out from the manifest in a throwing function, `manifest.get_address_of_entity_applying_shield()` or similar which Omar need to provide us with, oh well we need the account here, so elsewhere, in SargonOS where we have access to Profile we would call `manifest.get_address_of_entity_applying_shield` and then lookup the entity. - entity_applying_shield: AnySecurifiedEntity, + entity_applying_shield: impl Into, ) -> TransactionManifest { let mut builder = ManifestBuilder::new(); - + let entity_applying_shield = entity_applying_shield.into(); let access_controller_address = entity_applying_shield .securified_entity_control .access_controller_address; diff --git a/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs b/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs index af12cdfa7..1ce3e0a53 100644 --- a/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs +++ b/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs @@ -8,10 +8,10 @@ pub trait TransactionManifestSecurifySecurifiedEntity: TransactionManifestSetRolaKey { fn apply_security_shield_for_securified_entity( - securified_entity: AnySecurifiedEntity, + securified_entity: impl Into, security_structure_of_factor_instances: SecurityStructureOfFactorInstances, - apply_shield_manifest_kind: RolesExercisableInTransactionManifestCombination, + roles_combination: RolesExercisableInTransactionManifestCombination, ) -> Result; } @@ -25,17 +25,18 @@ impl TransactionManifestSecurifySecurifiedEntity for TransactionManifest { /// /// And when we know the fee we can calculate how much to top up the XRD vault of the AccessController /// and call - /// * `modify_manifest_add_withdraw_of_xrd_for_access_controller_xrd_vault_top_up_paid_by_account` + /// * `modify_manifest_add_withdraw_of_xrd_for_access_controller_xrd_vault_top_up_of_securified_account_paid_by_account` /// /// For timed confirmation - much later (`timed_recovery_delay_in_minutes` later ) the /// host app will need to call `confirm_timed_recovery` fn apply_security_shield_for_securified_entity( - securified_entity: AnySecurifiedEntity, + securified_entity: impl Into, security_structure_of_factor_instances: SecurityStructureOfFactorInstances, - apply_shield_manifest_kind: RolesExercisableInTransactionManifestCombination, + roles_combination: RolesExercisableInTransactionManifestCombination, ) -> Result { - let kind = apply_shield_manifest_kind; + let securified_entity = securified_entity.into(); + let kind = roles_combination; let entity_address = securified_entity.entity.address(); // ACCESS_CONTROLLER_CREATE_PROOF_IDENT @@ -101,10 +102,169 @@ impl TransactionManifestSecurifySecurifiedEntity for TransactionManifest { // Furthermore: // We do NOT top of XRD vault of AccessController - yet! // Host will need to call the function: - // `modify_manifest_add_withdraw_of_xrd_for_access_controller_xrd_vault_top_up_paid_by_account` - // after user has selected account to pay in wallet GUI. - // (and as usual also call `modify_manifest_lock_fee`) + // `modify_manifest_add_withdraw_of_xrd_for_access_controller_xrd_vault_top_up_of_securified_account_paid_by_account` + // after user has selected account to pay in wallet GUI. And also call + // `modify_manifest_add_lock_fee_against_xrd_vault_of_access_controller` Ok(manifest) } } + +#[cfg(test)] +mod tests { + #![allow(non_snake_case)] + + use prelude::fixture_rtm; + use profile_supporting_types::{SecurifiedAccount, SecurifiedPersona}; + + use super::*; + + #[allow(clippy::upper_case_acronyms)] + type SUT = TransactionManifest; + + #[test] + fn classify() { + let test = + |combination: RolesExercisableInTransactionManifestCombination, + expected: bool| { + let entity_applying_shield = AnySecurifiedEntity::sample(); + let mut instances = + SecurityStructureOfFactorInstances::sample(); + + // skip set rola + instances.authentication_signing_factor_instance = + entity_applying_shield + .current_authentication_signing_factor_instance(); + let manifest = + SUT::apply_security_shield_for_securified_entity( + entity_applying_shield.clone(), + instances, + combination, + ) + .unwrap(); + let classified = manifest.explicitly_references_primary_role(); + assert_eq!(classified, expected); + }; + test(RolesExercisableInTransactionManifestCombination::InitiateWithPrimaryCompleteWithConfirmation, true); + test(RolesExercisableInTransactionManifestCombination::InitiateWithPrimaryCompleteWithRecovery, true); + test(RolesExercisableInTransactionManifestCombination::InitiateWithPrimaryDelayedCompletion, true); + + test(RolesExercisableInTransactionManifestCombination::InitiateWithRecoveryCompleteWithConfirmation, false); + test(RolesExercisableInTransactionManifestCombination::InitiateWithRecoveryDelayedCompletion, false); + } + + #[test] + fn update_shield_of_securified_account_with_top_up_where_payer_is_entity_applying_shield( + ) { + let entity_applying_shield = SecurifiedAccount::sample(); + assert_eq!(entity_applying_shield.securified_entity_control.access_controller_address.to_string(), "accesscontroller_rdx1cdgcq7yqee9uhyqrsp9kgud3a7h4dvz3dqmx26ws5dmjsu7g3zg23g"); + + let manifest = SUT::apply_security_shield_for_securified_entity( + entity_applying_shield.clone(), + SecurityStructureOfFactorInstances::sample(), + RolesExercisableInTransactionManifestCombination::InitiateWithPrimaryCompleteWithConfirmation, + ).unwrap(); + + let expected_manifest_str = + fixture_rtm!("update_shield_of_account_init_with_P_confirm_with_C"); + manifest_eq(manifest.clone(), expected_manifest_str); + assert!(expected_manifest_str.contains("accesscontroller_rdx1cdgcq7yqee9uhyqrsp9kgud3a7h4dvz3dqmx26ws5dmjsu7g3zg23g")); + + let manifest = SUT::modify_manifest_add_withdraw_of_xrd_for_access_controller_xrd_vault_top_up_of_securified_account_paid_by_account(entity_applying_shield.clone(), entity_applying_shield.clone(), manifest.clone(), Decimal192::ten()).unwrap(); + + let expected_manifest_str = + fixture_rtm!("update_shield_of_account_init_with_P_confirm_with_C_with_top_up_where_payer_is_entity_applying_shield"); + manifest_eq(manifest.clone(), expected_manifest_str); + + let manifest = SUT::modify_manifest_add_lock_fee_against_xrd_vault_of_access_controller(manifest, Decimal192::nine(), entity_applying_shield); + + let expected_manifest_str = + fixture_rtm!("update_shield_of_account_init_with_P_confirm_with_C_with_top_up_where_payer_is_entity_applying_shield_with_xrd_lock"); + manifest_eq(manifest, expected_manifest_str); + } + + fn test_update_shield_of_securified_persona_cond_set_rola<'a>( + roles: RolesExercisableInTransactionManifestCombination, + set_rola: bool, + rtm: impl Fn() -> &'a str, + ) { + let entity_applying_shield = SecurifiedPersona::sample(); + let mut instances = SecurityStructureOfFactorInstances::sample_other(); + if !set_rola { + instances.authentication_signing_factor_instance = + entity_applying_shield + .current_authentication_signing_factor_instance(); + } + let manifest = SUT::apply_security_shield_for_securified_entity( + entity_applying_shield.clone(), + instances, + roles, + ) + .unwrap(); + let expected_manifest_str = rtm(); + manifest_eq(manifest.clone(), expected_manifest_str); + } + + fn test_update_shield_of_securified_persona<'a>( + roles: RolesExercisableInTransactionManifestCombination, + rtm: impl Fn() -> &'a str, + ) { + test_update_shield_of_securified_persona_cond_set_rola(roles, true, rtm) + } + + #[test] + fn update_shield_of_securified_persona_init_with_P_confirm_with_R() { + test_update_shield_of_securified_persona( + RolesExercisableInTransactionManifestCombination::InitiateWithPrimaryCompleteWithRecovery, + || fixture_rtm!("update_shield_of_persona_init_with_P_confirm_with_R") + ) + } + + #[test] + fn update_shield_of_securified_persona_init_with_P_confirm_with_C() { + test_update_shield_of_securified_persona( + RolesExercisableInTransactionManifestCombination::InitiateWithPrimaryCompleteWithConfirmation, + || fixture_rtm!("update_shield_of_persona_init_with_P_confirm_with_C") + ) + } + + #[test] + fn update_shield_of_securified_persona_init_with_P_confirm_with_T() { + test_update_shield_of_securified_persona( + RolesExercisableInTransactionManifestCombination::InitiateWithPrimaryDelayedCompletion, + || fixture_rtm!("update_shield_of_persona_init_with_P_confirm_with_T") + ) + } + + #[test] + fn update_shield_of_securified_persona_init_with_R_confirm_with_C() { + test_update_shield_of_securified_persona_cond_set_rola( + RolesExercisableInTransactionManifestCombination::InitiateWithRecoveryCompleteWithConfirmation, + false, + || fixture_rtm!("update_shield_of_persona_init_with_R_confirm_with_C") + ) + } + + #[test] + fn update_shield_of_securified_persona_init_with_R_confirm_with_T() { + test_update_shield_of_securified_persona_cond_set_rola( + RolesExercisableInTransactionManifestCombination::InitiateWithRecoveryDelayedCompletion, + false, + || fixture_rtm!("update_shield_of_persona_init_with_R_confirm_with_T") + ) + } + + #[test] + fn update_shield_of_securified_persona_fails_when_setting_rola_and_without_primary( + ) { + let entity_applying_shield = SecurifiedPersona::sample(); + + let res = SUT::apply_security_shield_for_securified_entity( + entity_applying_shield.clone(), + SecurityStructureOfFactorInstances::sample_other(), + RolesExercisableInTransactionManifestCombination::InitiateWithRecoveryDelayedCompletion, + ); + + assert_eq!(res, Err(CommonError::Unknown)); + } +} diff --git a/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_unsecurified_entity.rs b/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_unsecurified_entity.rs index aae4095c2..a0ce8c950 100644 --- a/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_unsecurified_entity.rs +++ b/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_unsecurified_entity.rs @@ -21,7 +21,7 @@ pub trait TransactionManifestSecurifyUnsecurifiedEntity: impl TransactionManifestSecurifyUnsecurifiedEntity for TransactionManifest { /// We do NOT top of XRD vault of AccessController - yet! /// Host will need to call the function: - /// `modify_manifest_add_withdraw_of_xrd_for_access_controller_xrd_vault_top_up_paid_by_account` + /// `modify_manifest_add_withdraw_of_xrd_for_access_controller_xrd_vault_top_up_of_unsecurified_account_paid_by_account` /// after user has selected account to pay in wallet GUI. /// (and as usual also call `modify_manifest_lock_fee`) fn apply_security_shield_for_unsecurified_entity( @@ -98,7 +98,7 @@ impl TransactionManifestSecurifyUnsecurifiedEntity for TransactionManifest { // N.B. // We do NOT top of XRD vault of AccessController - yet! // Host will need to call the function: - // `modify_manifest_add_withdraw_of_xrd_for_access_controller_xrd_vault_top_up_paid_by_account` + // `modify_manifest_add_withdraw_of_xrd_for_access_controller_xrd_vault_top_up_of_unsecurified_account_paid_by_account` // after user has selected account to pay in wallet GUI. // (and as usual also call `modify_manifest_lock_fee`) @@ -117,13 +117,13 @@ mod tests { fn test_securify_unsecurified_account() { let expected_manifest_str = fixture_rtm!("create_access_controller_for_account"); - let entity = Account::sample(); + let account = Account::sample(); let security_structure_of_factor_instances = SecurityStructureOfFactorInstances::sample(); let manifest = TransactionManifest::apply_security_shield_for_unsecurified_entity( - AnyUnsecurifiedEntity::new(entity.clone().into()).unwrap(), + AnyUnsecurifiedEntity::new(account.clone()).unwrap(), security_structure_of_factor_instances.clone(), ) .unwrap(); @@ -144,13 +144,13 @@ mod tests { .contains(&PublicKeyHash::hash(fi.public_key()).to_string())); } - assert!(expected_manifest_str.contains(&entity.address.to_string())); + assert!(expected_manifest_str.contains(&account.address.to_string())); let bob = Account::sample_bob(); - let with_ac_xrd_vault_top_up_by_unsecurified_account = TransactionManifest::modify_manifest_add_withdraw_of_xrd_for_access_controller_xrd_vault_top_up_paid_by_account( + let with_ac_xrd_vault_top_up_by_unsecurified_account = TransactionManifest::modify_manifest_add_withdraw_of_xrd_for_access_controller_xrd_vault_top_up_of_unsecurified_account_paid_by_account( bob.clone(), - entity.clone(), + AnyUnsecurifiedEntity::new( account.clone()).unwrap(), manifest.clone(), None, ); @@ -176,9 +176,9 @@ mod tests { }, ); - let with_ac_xrd_vault_top_up_by_securified_account_amount_42 = TransactionManifest::modify_manifest_add_withdraw_of_xrd_for_access_controller_xrd_vault_top_up_paid_by_account( + let with_ac_xrd_vault_top_up_by_securified_account_amount_42 = TransactionManifest::modify_manifest_add_withdraw_of_xrd_for_access_controller_xrd_vault_top_up_of_unsecurified_account_paid_by_account( grace_secure.clone(), - entity.clone(), + AnyUnsecurifiedEntity::new(account.clone()).unwrap(), manifest.clone(), Decimal192::from(42), ); @@ -196,18 +196,17 @@ mod tests { fn test_securify_unsecurified_persona() { let expected_manifest_str = fixture_rtm!("create_access_controller_for_persona"); - let entity = Persona::sample_other(); + let persona = Persona::sample_other(); let security_structure_of_factor_instances = SecurityStructureOfFactorInstances::sample_other(); let manifest = TransactionManifest::apply_security_shield_for_unsecurified_entity( - AnyUnsecurifiedEntity::new(entity.clone().into()).unwrap(), + AnyUnsecurifiedEntity::new(persona.clone()).unwrap(), security_structure_of_factor_instances.clone(), ) .unwrap(); - manifest_eq(manifest, expected_manifest_str); - + manifest_eq(manifest.clone(), expected_manifest_str); assert!(expected_manifest_str.contains("securify")); assert!(expected_manifest_str.contains( &security_structure_of_factor_instances @@ -224,15 +223,59 @@ mod tests { .contains(&PublicKeyHash::hash(fi.public_key()).to_string())); } - assert!(expected_manifest_str.contains(&entity.address.to_string())); + assert!(expected_manifest_str.contains(&persona.address.to_string())); + + let bob = Account::sample_bob(); + + let with_ac_xrd_vault_top_up_by_unsecurified_account = TransactionManifest::modify_manifest_add_withdraw_of_xrd_for_access_controller_xrd_vault_top_up_of_unsecurified_account_paid_by_account( + bob.clone(), + AnyUnsecurifiedEntity::new(persona.clone()).unwrap(), + manifest.clone(), + None, + ); + + let expected_manifest_str = + fixture_rtm!("create_access_controller_for_persona_with_ac_xrd_vault_top_up_by_unsecurified_account"); + + manifest_eq( + with_ac_xrd_vault_top_up_by_unsecurified_account, + expected_manifest_str, + ); + + let grace_secure = Account::sample_securified_mainnet( + "Grace", + 6, + HierarchicalDeterministicFactorInstance::sample_mainnet_account_device_factor_fs_10_unsecurified_at_index(0), + || { + GeneralRoleWithHierarchicalDeterministicFactorInstances::r6( + HierarchicalDeterministicFactorInstance::sample_id_to_instance( + CAP26EntityKind::Account, + Hardened::from_local_key_space(6u32, IsSecurified(true)).unwrap(), + )) + }, + ); + + let with_ac_xrd_vault_top_up_by_securified_account_amount_42 = TransactionManifest::modify_manifest_add_withdraw_of_xrd_for_access_controller_xrd_vault_top_up_of_unsecurified_account_paid_by_account( + grace_secure.clone(), + AnyUnsecurifiedEntity::new( persona.clone()).unwrap(), + manifest.clone(), + Decimal192::from(42), + ); + + let expected_manifest_str = + fixture_rtm!("create_access_controller_for_persona_with_ac_xrd_vault_top_up_by_securified_account_amount_42"); + + manifest_eq( + with_ac_xrd_vault_top_up_by_securified_account_amount_42, + expected_manifest_str, + ); } #[test] fn test_mismatch_entity_kind_account_persona() { let manifest = TransactionManifest::apply_security_shield_for_unsecurified_entity( - AnyUnsecurifiedEntity::new(Account::sample_other().into()) - .unwrap(), + AnyUnsecurifiedEntity::new(Account::sample_other()).unwrap(), SecurityStructureOfFactorInstances::sample_other(), ); assert_eq!(manifest, Err(CommonError::SecurityStructureOfFactorInstancesEntityDiscrepancyInEntityKind { entity_kind_of_entity: CAP26EntityKind::Account.to_string(), entity_kind_of_factor_instances: CAP26EntityKind::Identity.to_string() })); @@ -242,8 +285,7 @@ mod tests { fn test_mismatch_entity_kind_persona_account() { let manifest = TransactionManifest::apply_security_shield_for_unsecurified_entity( - AnyUnsecurifiedEntity::new(Persona::sample_other().into()) - .unwrap(), + AnyUnsecurifiedEntity::new(Persona::sample_other()).unwrap(), SecurityStructureOfFactorInstances::sample(), ); assert_eq!(manifest, Err(CommonError::SecurityStructureOfFactorInstancesEntityDiscrepancyInEntityKind { entity_kind_of_entity: CAP26EntityKind::Identity.to_string(), entity_kind_of_factor_instances: CAP26EntityKind::Account.to_string() })); diff --git a/crates/transaction/manifests/src/manifests_security_shield/roles_exercisable_in_transaction_manifest_combination.rs b/crates/transaction/manifests/src/manifests_security_shield/roles_exercisable_in_transaction_manifest_combination.rs index ee81de140..83ee49cbe 100644 --- a/crates/transaction/manifests/src/manifests_security_shield/roles_exercisable_in_transaction_manifest_combination.rs +++ b/crates/transaction/manifests/src/manifests_security_shield/roles_exercisable_in_transaction_manifest_combination.rs @@ -21,7 +21,7 @@ use radix_engine_interface::blueprints::access_controller::{ /// /// Each combination of roles allows us to skip signing with certain factors /// and still be able to recover + confirm the AccessController update. -#[derive(Clone, Debug, PartialEq, Eq, Hash, enum_iterator::Sequence)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, enum_iterator::Sequence)] pub enum RolesExercisableInTransactionManifestCombination { /// Initiates recovery using `Primary` role and quick confirms using /// `Recovery` role explicitly. @@ -97,7 +97,7 @@ impl RolesExercisableInTransactionManifestCombination { } /// If this combination of roles references the `Primary` role or not. - fn can_exercise_primary_role(&self) -> bool { + pub fn can_exercise_primary_role(&self) -> bool { matches!( self, Self::InitiateWithPrimaryCompleteWithRecovery @@ -106,20 +106,32 @@ impl RolesExercisableInTransactionManifestCombination { ) } - /// If this combination of roles references the `Recovery` role or not. - fn can_exercise_recovery_role(&self) -> bool { + /// If we can set the ROLA key for this combination of roles. + pub fn can_set_rola_key(&self) -> bool { + self.can_exercise_primary_role() + } + + fn initiate_recovery_with_primary(&self) -> bool { matches!( self, Self::InitiateWithPrimaryCompleteWithRecovery - | Self::InitiateWithRecoveryCompleteWithConfirmation + | Self::InitiateWithPrimaryCompleteWithConfirmation + | Self::InitiateWithPrimaryDelayedCompletion + ) + } + fn initiate_recovery_with_recovery(&self) -> bool { + matches!( + self, + Self::InitiateWithRecoveryCompleteWithConfirmation | Self::InitiateWithRecoveryDelayedCompletion ) } - /// If this combination of roles references the `Confirmation` role or not. - /// - /// Explicitly means "not using time, but use quick confirmation" - fn can_exercise_confirmation_role_explicitly(&self) -> bool { + fn quick_confirm_with_recovery(&self) -> bool { + matches!(self, Self::InitiateWithPrimaryCompleteWithRecovery) + } + + fn quick_confirm_with_confirmation(&self) -> bool { matches!( self, Self::InitiateWithPrimaryCompleteWithConfirmation @@ -127,38 +139,33 @@ impl RolesExercisableInTransactionManifestCombination { ) } - /// If we can set the ROLA key for this combination of roles. - pub fn can_set_rola_key(&self) -> bool { - self.can_exercise_primary_role() - } - /// Returns method identifier and input for **initiating** recovery /// on an AccessController - depending on which roles we can exercise. pub fn input_for_initialization( &self, factors_and_time: &AccessControllerFactorsAndTimeInput, ) -> (&'static str, Box) { - if self.can_exercise_recovery_role() { + if self.initiate_recovery_with_primary() { ( - SCRYPTO_ACCESS_CONTROLLER_INITIATE_RECOVERY_AS_RECOVERY_IDENT, + SCRYPTO_ACCESS_CONTROLLER_INITIATE_RECOVERY_AS_PRIMARY_IDENT, Box::new( - ScryptoAccessControllerInitiateRecoveryAsRecoveryInput::from( + ScryptoAccessControllerInitiateRecoveryAsPrimaryInput::from( factors_and_time, ), ), ) - } else if self.can_exercise_primary_role() { + } else if self.initiate_recovery_with_recovery() { ( - SCRYPTO_ACCESS_CONTROLLER_INITIATE_RECOVERY_AS_PRIMARY_IDENT, + SCRYPTO_ACCESS_CONTROLLER_INITIATE_RECOVERY_AS_RECOVERY_IDENT, Box::new( - ScryptoAccessControllerInitiateRecoveryAsPrimaryInput::from( + ScryptoAccessControllerInitiateRecoveryAsRecoveryInput::from( factors_and_time, ), ), ) } else { unreachable!( - "No combination exists which disallows for both primary and recovery" + "unable to calculate input_for_initialization - this is a programmer error" ) } } @@ -171,12 +178,24 @@ impl RolesExercisableInTransactionManifestCombination { &self, factors_and_time: &AccessControllerFactorsAndTimeInput, ) -> Option<(&'static str, Box)> { - if self.can_exercise_confirmation_role_explicitly() { - Some(if self.can_exercise_recovery_role() { - (SCRYPTO_ACCESS_CONTROLLER_QUICK_CONFIRM_RECOVERY_ROLE_RECOVERY_PROPOSAL_IDENT, Box::new(ScryptoAccessControllerQuickConfirmRecoveryRoleRecoveryProposalInput::from(factors_and_time))) + if self.quick_confirm_with_confirmation() + || self.quick_confirm_with_recovery() + { + if self.initiate_recovery_with_primary() { + Some(( + SCRYPTO_ACCESS_CONTROLLER_QUICK_CONFIRM_PRIMARY_ROLE_RECOVERY_PROPOSAL_IDENT, + Box::new(ScryptoAccessControllerQuickConfirmPrimaryRoleRecoveryProposalInput::from(factors_and_time)) + )) + } else if self.initiate_recovery_with_recovery() { + Some(( + SCRYPTO_ACCESS_CONTROLLER_QUICK_CONFIRM_RECOVERY_ROLE_RECOVERY_PROPOSAL_IDENT, + Box::new(ScryptoAccessControllerQuickConfirmRecoveryRoleRecoveryProposalInput::from(factors_and_time)) + )) } else { - (SCRYPTO_ACCESS_CONTROLLER_QUICK_CONFIRM_PRIMARY_ROLE_RECOVERY_PROPOSAL_IDENT, Box::new(ScryptoAccessControllerQuickConfirmPrimaryRoleRecoveryProposalInput::from(factors_and_time))) - }) + unreachable!( + "unable to calculate input_for_quick_confirm - this is a programmer error" + ) + } } else { // Time based cannot happen yet - host (user) need to wait the specified // amount of time (factors_and_time.time) before calling this method. @@ -186,3 +205,20 @@ impl RolesExercisableInTransactionManifestCombination { } } } + +pub trait TransactionManifestExplicitlyReferencesPrimaryRole { + fn explicitly_references_primary_role(&self) -> bool; +} +impl TransactionManifestExplicitlyReferencesPrimaryRole + for TransactionManifest +{ + fn explicitly_references_primary_role(&self) -> bool { + let has = |identifier: &str| -> bool { + self.instructions() + .iter() + .any(|instruction| matches!(instruction, ScryptoInstruction::CallMethod(method) if method.method_name == identifier)) + }; + + has(SCRYPTO_ACCESS_CONTROLLER_INITIATE_RECOVERY_AS_PRIMARY_IDENT) + } +} diff --git a/crates/transaction/manifests/src/manifests_security_shield/top_up_access_controller_xrd_vault.rs b/crates/transaction/manifests/src/manifests_security_shield/top_up_access_controller_xrd_vault.rs index d9943dba4..260a9dc90 100644 --- a/crates/transaction/manifests/src/manifests_security_shield/top_up_access_controller_xrd_vault.rs +++ b/crates/transaction/manifests/src/manifests_security_shield/top_up_access_controller_xrd_vault.rs @@ -1,3 +1,4 @@ +use profile_supporting_types::{AnySecurifiedEntity, AnyUnsecurifiedEntity}; use radix_common::prelude::ManifestGlobalAddress; use radix_engine_interface::blueprints::access_controller::{ AccessControllerContributeRecoveryFeeManifestInput, @@ -20,14 +21,10 @@ pub trait TransactionManifestAccessControllerXrdVaultToppingUp { /// at the end of `manifest` for topping the XRD vault of the access controller /// with `top_up_amount` many XRD. /// - /// N.B. We will call this method for both when `entity_applying_shield` is - /// securified or unsecurified. In the case of unsecurified entity we will use - /// the address reservation of `apply_security_shield_for_unsecurified_entity` + /// We will use the address reservation of `apply_security_shield_for_unsecurified_entity` /// (`ACCESS_CONTROLLER_ADDRESS_RESERVATION_NAME`) which we cannot access by id /// since Radix Engine discard those ids and uses internal ones, instead we need /// to use `ManifestGlobalAddress::Named(ScryptoManifestNamedAddress(0))`. - /// If `entity_applying_shield` is securified we will use the address of the - /// already existing access controller. /// /// If `payer` is securified we will also add a `create_proof` instruction for /// authenticating the withdrawal of XRD from the payer. @@ -36,14 +33,69 @@ pub trait TransactionManifestAccessControllerXrdVaultToppingUp { /// We allow to pass amount so that we can top of with more or less based on /// token balance of `payer` and current balance of the access controller (when /// we use this method for securified entities.) - fn modify_manifest_add_withdraw_of_xrd_for_access_controller_xrd_vault_top_up_paid_by_account( - payer: Account, - // TODO: remove `entity_applying_shield`, this should be read out from the manifest in a throwing function, `manifest.get_address_of_entity_applying_shield()` or similar which Omar need to provide us with, oh well we need the account here, so elsewhere, in SargonOS where we have access to Profile we would call `manifest.get_address_of_entity_applying_shield` and then lookup the entity. - entity_applying_shield: Account, + fn modify_manifest_add_withdraw_of_xrd_for_access_controller_xrd_vault_top_up_of_unsecurified_account_paid_by_account( + payer: impl Into, + // TODO: remove `unsecurified_entity_applying_shield`, this should be read out from the manifest in a throwing function, `manifest.get_address_of_entity_applying_shield()` or similar which Omar need to provide us with, oh well we need the account here, so elsewhere, in SargonOS where we have access to Profile we would call `manifest.get_address_of_entity_applying_shield` and then lookup the entity. + unsecurified_entity_applying_shield: AnyUnsecurifiedEntity, manifest: TransactionManifest, top_up_amount: impl Into>, ) -> TransactionManifest { + assert!(!manifest.explicitly_references_primary_role(), "Unexpectedly classified manifest as updating of shield of securified entity, but it is not."); + Self::_modify_manifest_add_withdraw_of_xrd_for_access_controller_xrd_vault_top_up_paid_by_account( + payer, + unsecurified_entity_applying_shield.entity, + manifest, + top_up_amount, + ).expect("Should never fail") + } + + fn modify_manifest_add_withdraw_of_xrd_for_access_controller_xrd_vault_top_up_of_securified_account_paid_by_account( + payer: impl Into, + // TODO: remove `securified_entity_applying_shield`, this should be read out from the manifest in a throwing function, `manifest.get_address_of_entity_applying_shield()` or similar which Omar need to provide us with, oh well we need the account here, so elsewhere, in SargonOS where we have access to Profile we would call `manifest.get_address_of_entity_applying_shield` and then lookup the entity. + securified_entity_applying_shield: impl Into, + manifest: TransactionManifest, + top_up_amount: impl Into>, + ) -> Result { + Self::_modify_manifest_add_withdraw_of_xrd_for_access_controller_xrd_vault_top_up_paid_by_account( + payer, + securified_entity_applying_shield.into().entity, + manifest, + top_up_amount, + ) + } + + fn _modify_manifest_add_withdraw_of_xrd_for_access_controller_xrd_vault_top_up_paid_by_account( + payer: impl Into, + // TODO: remove `entity_applying_shield`, this should be read out from the manifest in a throwing function, `manifest.get_address_of_entity_applying_shield()` or similar which Omar need to provide us with, oh well we need the account here, so elsewhere, in SargonOS where we have access to Profile we would call `manifest.get_address_of_entity_applying_shield` and then lookup the entity. + entity_applying_shield: AccountOrPersona, + manifest: TransactionManifest, + top_up_amount: impl Into>, + ) -> Result { + let payer = payer.into(); let address_of_paying_account = payer.address(); + + { + // Try to eagerly identify invalid manifest. + // We dont _need_ this and might remove it. + // but I think this will work. + + let payer_is_entity_applying_shield = + entity_applying_shield.address() == payer.address().into(); + if payer_is_entity_applying_shield { + let cannot_exercise_primary_role = + !manifest.explicitly_references_primary_role(); + let is_unable_to_top_up_xrd_vault = + payer_is_entity_applying_shield + && cannot_exercise_primary_role; + if is_unable_to_top_up_xrd_vault { + // The payer is the entity applying the shield, but the manifest is not classified as + // to be able to exercise the primary role. Thus we will not be able to + // top up the XRD vault of the access controller. + return Err(CommonError::Unknown); // TODO: Add error + } + } + } + let mut builder = ManifestBuilder::with_manifest(manifest); let address_of_access_controller_to_top_up = @@ -120,10 +172,12 @@ pub trait TransactionManifestAccessControllerXrdVaultToppingUp { }, ); - TransactionManifest::sargon_built( + let manifest = TransactionManifest::sargon_built( builder, address_of_paying_account.network_id(), - ) + ); + + Ok(manifest) } } diff --git a/fixtures/transaction/create_access_controller_for_persona_with_ac_xrd_vault_top_up_by_securified_account_amount_42.rtm b/fixtures/transaction/create_access_controller_for_persona_with_ac_xrd_vault_top_up_by_securified_account_amount_42.rtm new file mode 100644 index 000000000..78b857b4a --- /dev/null +++ b/fixtures/transaction/create_access_controller_for_persona_with_ac_xrd_vault_top_up_by_securified_account_amount_42.rtm @@ -0,0 +1,120 @@ +CALL_METHOD + Address("identity_rdx12tw6rt9c4l56rz6p866e35tmzp556nymxmpj8hagfewq82kspctdyw") + "securify" +; +TAKE_FROM_WORKTOP + Address("resource_rdx1nfxxxxxxxxxxdntwnrxxxxxxxxx002876444928xxxxxxxxxdntwnr") + Decimal("1") + Bucket("bucket1") +; +ALLOCATE_GLOBAL_ADDRESS + Address("package_rdx1pkgxxxxxxxxxcntrlrxxxxxxxxx000648572295xxxxxxxxxcntrlr") + "AccessController" + AddressReservation("reservation1") + NamedAddress("address1") +; +CREATE_ACCESS_CONTROLLER + Bucket("bucket1") + Tuple( + Enum<2u8>( + Enum<1u8>( + Array( + Enum<0u8>( + Enum<2u8>( + 1u8, + Array( + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[99b417749d9022e73a6d2e025648a928ffbc499be8dc9e55eda900b11f]") + ) + ) + ) + ), + Enum<0u8>( + Enum<4u8>( + Array() + ) + ) + ) + ) + ), + Enum<2u8>( + Enum<1u8>( + Array( + Enum<0u8>( + Enum<2u8>( + 0u8, + Array() + ) + ), + Enum<0u8>( + Enum<4u8>( + Array( + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[97d5d7196e49781708520322aaf5872214d854122600dd0125c837aefe]") + ) + ) + ) + ) + ) + ) + ), + Enum<2u8>( + Enum<1u8>( + Array( + Enum<0u8>( + Enum<2u8>( + 0u8, + Array() + ) + ), + Enum<0u8>( + Enum<4u8>( + Array( + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[0b9bdb05d848b70041d7ed45c28dd9d6743a19eb129524d1c623b31784]") + ) + ) + ) + ) + ) + ) + ) + ) + Enum<1u8>( + 20160u32 + ) + Enum<1u8>( + AddressReservation("reservation1") + ) +; +SET_METADATA + Address("identity_rdx12tw6rt9c4l56rz6p866e35tmzp556nymxmpj8hagfewq82kspctdyw") + "owner_keys" + Enum<143u8>( + Array( + Enum<1u8>( + Bytes("675506ad8d7ce4c602cb06c593c0f10e1cc4dcdf2c4144360ef33ebeef") + ) + ) + ) +; +CALL_METHOD + Address("accesscontroller_rdx1cdgmx69r8532n7e0w6sgs8lrctmdzsmylak75a0khwmp55pau5p8pr") + "create_proof" +; +CALL_METHOD + Address("account_rdx12xek3geay25lktmk5zyplc7z7mg5xe8ldh48ta4mkcd9q0v0q6l8y6") + "withdraw" + Address("resource_rdx1tknxxxxxxxxxradxrdxxxxxxxxx009923554798xxxxxxxxxradxrd") + Decimal("42") +; +TAKE_FROM_WORKTOP + Address("resource_rdx1tknxxxxxxxxxradxrdxxxxxxxxx009923554798xxxxxxxxxradxrd") + Decimal("42") + Bucket("bucket2") +; +CALL_METHOD + NamedAddress("address1") + "contribute_recovery_fee" + Bucket("bucket2") +; \ No newline at end of file diff --git a/fixtures/transaction/create_access_controller_for_persona_with_ac_xrd_vault_top_up_by_unsecurified_account.rtm b/fixtures/transaction/create_access_controller_for_persona_with_ac_xrd_vault_top_up_by_unsecurified_account.rtm new file mode 100644 index 000000000..dd59018d6 --- /dev/null +++ b/fixtures/transaction/create_access_controller_for_persona_with_ac_xrd_vault_top_up_by_unsecurified_account.rtm @@ -0,0 +1,116 @@ +CALL_METHOD + Address("identity_rdx12tw6rt9c4l56rz6p866e35tmzp556nymxmpj8hagfewq82kspctdyw") + "securify" +; +TAKE_FROM_WORKTOP + Address("resource_rdx1nfxxxxxxxxxxdntwnrxxxxxxxxx002876444928xxxxxxxxxdntwnr") + Decimal("1") + Bucket("bucket1") +; +ALLOCATE_GLOBAL_ADDRESS + Address("package_rdx1pkgxxxxxxxxxcntrlrxxxxxxxxx000648572295xxxxxxxxxcntrlr") + "AccessController" + AddressReservation("reservation1") + NamedAddress("address1") +; +CREATE_ACCESS_CONTROLLER + Bucket("bucket1") + Tuple( + Enum<2u8>( + Enum<1u8>( + Array( + Enum<0u8>( + Enum<2u8>( + 1u8, + Array( + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[99b417749d9022e73a6d2e025648a928ffbc499be8dc9e55eda900b11f]") + ) + ) + ) + ), + Enum<0u8>( + Enum<4u8>( + Array() + ) + ) + ) + ) + ), + Enum<2u8>( + Enum<1u8>( + Array( + Enum<0u8>( + Enum<2u8>( + 0u8, + Array() + ) + ), + Enum<0u8>( + Enum<4u8>( + Array( + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[97d5d7196e49781708520322aaf5872214d854122600dd0125c837aefe]") + ) + ) + ) + ) + ) + ) + ), + Enum<2u8>( + Enum<1u8>( + Array( + Enum<0u8>( + Enum<2u8>( + 0u8, + Array() + ) + ), + Enum<0u8>( + Enum<4u8>( + Array( + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[0b9bdb05d848b70041d7ed45c28dd9d6743a19eb129524d1c623b31784]") + ) + ) + ) + ) + ) + ) + ) + ) + Enum<1u8>( + 20160u32 + ) + Enum<1u8>( + AddressReservation("reservation1") + ) +; +SET_METADATA + Address("identity_rdx12tw6rt9c4l56rz6p866e35tmzp556nymxmpj8hagfewq82kspctdyw") + "owner_keys" + Enum<143u8>( + Array( + Enum<1u8>( + Bytes("675506ad8d7ce4c602cb06c593c0f10e1cc4dcdf2c4144360ef33ebeef") + ) + ) + ) +; +CALL_METHOD + Address("account_rdx12y02nen8zjrq0k0nku98shjq7n05kvl3j9m5d3a6cpduqwzgmenjq7") + "withdraw" + Address("resource_rdx1tknxxxxxxxxxradxrdxxxxxxxxx009923554798xxxxxxxxxradxrd") + Decimal("100") +; +TAKE_FROM_WORKTOP + Address("resource_rdx1tknxxxxxxxxxradxrdxxxxxxxxx009923554798xxxxxxxxxradxrd") + Decimal("100") + Bucket("bucket2") +; +CALL_METHOD + NamedAddress("address1") + "contribute_recovery_fee" + Bucket("bucket2") +; \ No newline at end of file diff --git a/fixtures/transaction/update_shield_of_account_init_with_P_confirm_with_C.rtm b/fixtures/transaction/update_shield_of_account_init_with_P_confirm_with_C.rtm new file mode 100644 index 000000000..5d38fdbd7 --- /dev/null +++ b/fixtures/transaction/update_shield_of_account_init_with_P_confirm_with_C.rtm @@ -0,0 +1,171 @@ +CALL_METHOD + Address("accesscontroller_rdx1cdgcq7yqee9uhyqrsp9kgud3a7h4dvz3dqmx26ws5dmjsu7g3zg23g") + "initiate_recovery_as_primary" + Tuple( + Tuple( + Enum<2u8>( + Enum<1u8>( + Array( + Enum<0u8>( + Enum<2u8>( + 2u8, + Array( + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[2dabcc6872c45a625bccc21be9e666bfbc62b1f87a16f3848dd877ba22]") + ), + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[7225b29de13d7d06e0e9f406fe15165677573c9106ee036ad52bee2864]") + ) + ) + ) + ), + Enum<0u8>( + Enum<4u8>( + Array() + ) + ) + ) + ) + ), + Enum<2u8>( + Enum<1u8>( + Array( + Enum<0u8>( + Enum<2u8>( + 0u8, + Array() + ) + ), + Enum<0u8>( + Enum<4u8>( + Array( + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[2dabcc6872c45a625bccc21be9e666bfbc62b1f87a16f3848dd877ba22]") + ), + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[7225b29de13d7d06e0e9f406fe15165677573c9106ee036ad52bee2864]") + ) + ) + ) + ) + ) + ) + ), + Enum<2u8>( + Enum<1u8>( + Array( + Enum<0u8>( + Enum<2u8>( + 0u8, + Array() + ) + ), + Enum<0u8>( + Enum<4u8>( + Array( + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[31262cc8dc5e9a49d1fe0ea8e60a17ef36d1ea857db94cca3e1e2a52dd]") + ) + ) + ) + ) + ) + ) + ) + ), + Enum<1u8>( + 20160u32 + ) + ) +; +CALL_METHOD + Address("accesscontroller_rdx1cdgcq7yqee9uhyqrsp9kgud3a7h4dvz3dqmx26ws5dmjsu7g3zg23g") + "quick_confirm_primary_role_recovery_proposal" + Tuple( + Tuple( + Enum<2u8>( + Enum<1u8>( + Array( + Enum<0u8>( + Enum<2u8>( + 2u8, + Array( + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[2dabcc6872c45a625bccc21be9e666bfbc62b1f87a16f3848dd877ba22]") + ), + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[7225b29de13d7d06e0e9f406fe15165677573c9106ee036ad52bee2864]") + ) + ) + ) + ), + Enum<0u8>( + Enum<4u8>( + Array() + ) + ) + ) + ) + ), + Enum<2u8>( + Enum<1u8>( + Array( + Enum<0u8>( + Enum<2u8>( + 0u8, + Array() + ) + ), + Enum<0u8>( + Enum<4u8>( + Array( + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[2dabcc6872c45a625bccc21be9e666bfbc62b1f87a16f3848dd877ba22]") + ), + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[7225b29de13d7d06e0e9f406fe15165677573c9106ee036ad52bee2864]") + ) + ) + ) + ) + ) + ) + ), + Enum<2u8>( + Enum<1u8>( + Array( + Enum<0u8>( + Enum<2u8>( + 0u8, + Array() + ) + ), + Enum<0u8>( + Enum<4u8>( + Array( + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[31262cc8dc5e9a49d1fe0ea8e60a17ef36d1ea857db94cca3e1e2a52dd]") + ) + ) + ) + ) + ) + ) + ) + ), + Enum<1u8>( + 20160u32 + ) + ) +; +SET_METADATA + Address("account_rdx12xq83qxwf09eqquqfdj8rv004attq5tgxejkn59rwu588jprdy0xcg") + "owner_keys" + Enum<143u8>( + Array( + Enum<1u8>( + Bytes("cb3f6086cd08a1d0ab10139a9c6d191783edb534059f7b4716dc5d239e") + ) + ) + ) +; \ No newline at end of file diff --git a/fixtures/transaction/update_shield_of_account_init_with_P_confirm_with_C_with_top_up_where_payer_is_entity_applying_shield.rtm b/fixtures/transaction/update_shield_of_account_init_with_P_confirm_with_C_with_top_up_where_payer_is_entity_applying_shield.rtm new file mode 100644 index 000000000..058704ed9 --- /dev/null +++ b/fixtures/transaction/update_shield_of_account_init_with_P_confirm_with_C_with_top_up_where_payer_is_entity_applying_shield.rtm @@ -0,0 +1,191 @@ +CALL_METHOD + Address("accesscontroller_rdx1cdgcq7yqee9uhyqrsp9kgud3a7h4dvz3dqmx26ws5dmjsu7g3zg23g") + "initiate_recovery_as_primary" + Tuple( + Tuple( + Enum<2u8>( + Enum<1u8>( + Array( + Enum<0u8>( + Enum<2u8>( + 2u8, + Array( + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[2dabcc6872c45a625bccc21be9e666bfbc62b1f87a16f3848dd877ba22]") + ), + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[7225b29de13d7d06e0e9f406fe15165677573c9106ee036ad52bee2864]") + ) + ) + ) + ), + Enum<0u8>( + Enum<4u8>( + Array() + ) + ) + ) + ) + ), + Enum<2u8>( + Enum<1u8>( + Array( + Enum<0u8>( + Enum<2u8>( + 0u8, + Array() + ) + ), + Enum<0u8>( + Enum<4u8>( + Array( + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[2dabcc6872c45a625bccc21be9e666bfbc62b1f87a16f3848dd877ba22]") + ), + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[7225b29de13d7d06e0e9f406fe15165677573c9106ee036ad52bee2864]") + ) + ) + ) + ) + ) + ) + ), + Enum<2u8>( + Enum<1u8>( + Array( + Enum<0u8>( + Enum<2u8>( + 0u8, + Array() + ) + ), + Enum<0u8>( + Enum<4u8>( + Array( + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[31262cc8dc5e9a49d1fe0ea8e60a17ef36d1ea857db94cca3e1e2a52dd]") + ) + ) + ) + ) + ) + ) + ) + ), + Enum<1u8>( + 20160u32 + ) + ) +; +CALL_METHOD + Address("accesscontroller_rdx1cdgcq7yqee9uhyqrsp9kgud3a7h4dvz3dqmx26ws5dmjsu7g3zg23g") + "quick_confirm_primary_role_recovery_proposal" + Tuple( + Tuple( + Enum<2u8>( + Enum<1u8>( + Array( + Enum<0u8>( + Enum<2u8>( + 2u8, + Array( + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[2dabcc6872c45a625bccc21be9e666bfbc62b1f87a16f3848dd877ba22]") + ), + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[7225b29de13d7d06e0e9f406fe15165677573c9106ee036ad52bee2864]") + ) + ) + ) + ), + Enum<0u8>( + Enum<4u8>( + Array() + ) + ) + ) + ) + ), + Enum<2u8>( + Enum<1u8>( + Array( + Enum<0u8>( + Enum<2u8>( + 0u8, + Array() + ) + ), + Enum<0u8>( + Enum<4u8>( + Array( + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[2dabcc6872c45a625bccc21be9e666bfbc62b1f87a16f3848dd877ba22]") + ), + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[7225b29de13d7d06e0e9f406fe15165677573c9106ee036ad52bee2864]") + ) + ) + ) + ) + ) + ) + ), + Enum<2u8>( + Enum<1u8>( + Array( + Enum<0u8>( + Enum<2u8>( + 0u8, + Array() + ) + ), + Enum<0u8>( + Enum<4u8>( + Array( + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[31262cc8dc5e9a49d1fe0ea8e60a17ef36d1ea857db94cca3e1e2a52dd]") + ) + ) + ) + ) + ) + ) + ) + ), + Enum<1u8>( + 20160u32 + ) + ) +; +SET_METADATA + Address("account_rdx12xq83qxwf09eqquqfdj8rv004attq5tgxejkn59rwu588jprdy0xcg") + "owner_keys" + Enum<143u8>( + Array( + Enum<1u8>( + Bytes("cb3f6086cd08a1d0ab10139a9c6d191783edb534059f7b4716dc5d239e") + ) + ) + ) +; +CALL_METHOD + Address("accesscontroller_rdx1cdgcq7yqee9uhyqrsp9kgud3a7h4dvz3dqmx26ws5dmjsu7g3zg23g") + "create_proof" +; +CALL_METHOD + Address("account_rdx12xq83qxwf09eqquqfdj8rv004attq5tgxejkn59rwu588jprdy0xcg") + "withdraw" + Address("resource_rdx1tknxxxxxxxxxradxrdxxxxxxxxx009923554798xxxxxxxxxradxrd") + Decimal("10") +; +TAKE_FROM_WORKTOP + Address("resource_rdx1tknxxxxxxxxxradxrdxxxxxxxxx009923554798xxxxxxxxxradxrd") + Decimal("10") + Bucket("bucket1") +; +CALL_METHOD + Address("accesscontroller_rdx1cdgcq7yqee9uhyqrsp9kgud3a7h4dvz3dqmx26ws5dmjsu7g3zg23g") + "contribute_recovery_fee" + Bucket("bucket1") +; \ No newline at end of file diff --git a/fixtures/transaction/update_shield_of_account_init_with_P_confirm_with_C_with_top_up_where_payer_is_entity_applying_shield_with_xrd_lock.rtm b/fixtures/transaction/update_shield_of_account_init_with_P_confirm_with_C_with_top_up_where_payer_is_entity_applying_shield_with_xrd_lock.rtm new file mode 100644 index 000000000..91287777f --- /dev/null +++ b/fixtures/transaction/update_shield_of_account_init_with_P_confirm_with_C_with_top_up_where_payer_is_entity_applying_shield_with_xrd_lock.rtm @@ -0,0 +1,196 @@ +CALL_METHOD + Address("accesscontroller_rdx1cdgcq7yqee9uhyqrsp9kgud3a7h4dvz3dqmx26ws5dmjsu7g3zg23g") + "lock_recovery_fee" + Decimal("9") +; +CALL_METHOD + Address("accesscontroller_rdx1cdgcq7yqee9uhyqrsp9kgud3a7h4dvz3dqmx26ws5dmjsu7g3zg23g") + "initiate_recovery_as_primary" + Tuple( + Tuple( + Enum<2u8>( + Enum<1u8>( + Array( + Enum<0u8>( + Enum<2u8>( + 2u8, + Array( + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[2dabcc6872c45a625bccc21be9e666bfbc62b1f87a16f3848dd877ba22]") + ), + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[7225b29de13d7d06e0e9f406fe15165677573c9106ee036ad52bee2864]") + ) + ) + ) + ), + Enum<0u8>( + Enum<4u8>( + Array() + ) + ) + ) + ) + ), + Enum<2u8>( + Enum<1u8>( + Array( + Enum<0u8>( + Enum<2u8>( + 0u8, + Array() + ) + ), + Enum<0u8>( + Enum<4u8>( + Array( + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[2dabcc6872c45a625bccc21be9e666bfbc62b1f87a16f3848dd877ba22]") + ), + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[7225b29de13d7d06e0e9f406fe15165677573c9106ee036ad52bee2864]") + ) + ) + ) + ) + ) + ) + ), + Enum<2u8>( + Enum<1u8>( + Array( + Enum<0u8>( + Enum<2u8>( + 0u8, + Array() + ) + ), + Enum<0u8>( + Enum<4u8>( + Array( + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[31262cc8dc5e9a49d1fe0ea8e60a17ef36d1ea857db94cca3e1e2a52dd]") + ) + ) + ) + ) + ) + ) + ) + ), + Enum<1u8>( + 20160u32 + ) + ) +; +CALL_METHOD + Address("accesscontroller_rdx1cdgcq7yqee9uhyqrsp9kgud3a7h4dvz3dqmx26ws5dmjsu7g3zg23g") + "quick_confirm_primary_role_recovery_proposal" + Tuple( + Tuple( + Enum<2u8>( + Enum<1u8>( + Array( + Enum<0u8>( + Enum<2u8>( + 2u8, + Array( + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[2dabcc6872c45a625bccc21be9e666bfbc62b1f87a16f3848dd877ba22]") + ), + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[7225b29de13d7d06e0e9f406fe15165677573c9106ee036ad52bee2864]") + ) + ) + ) + ), + Enum<0u8>( + Enum<4u8>( + Array() + ) + ) + ) + ) + ), + Enum<2u8>( + Enum<1u8>( + Array( + Enum<0u8>( + Enum<2u8>( + 0u8, + Array() + ) + ), + Enum<0u8>( + Enum<4u8>( + Array( + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[2dabcc6872c45a625bccc21be9e666bfbc62b1f87a16f3848dd877ba22]") + ), + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[7225b29de13d7d06e0e9f406fe15165677573c9106ee036ad52bee2864]") + ) + ) + ) + ) + ) + ) + ), + Enum<2u8>( + Enum<1u8>( + Array( + Enum<0u8>( + Enum<2u8>( + 0u8, + Array() + ) + ), + Enum<0u8>( + Enum<4u8>( + Array( + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[31262cc8dc5e9a49d1fe0ea8e60a17ef36d1ea857db94cca3e1e2a52dd]") + ) + ) + ) + ) + ) + ) + ) + ), + Enum<1u8>( + 20160u32 + ) + ) +; +SET_METADATA + Address("account_rdx12xq83qxwf09eqquqfdj8rv004attq5tgxejkn59rwu588jprdy0xcg") + "owner_keys" + Enum<143u8>( + Array( + Enum<1u8>( + Bytes("cb3f6086cd08a1d0ab10139a9c6d191783edb534059f7b4716dc5d239e") + ) + ) + ) +; +CALL_METHOD + Address("accesscontroller_rdx1cdgcq7yqee9uhyqrsp9kgud3a7h4dvz3dqmx26ws5dmjsu7g3zg23g") + "create_proof" +; +CALL_METHOD + Address("account_rdx12xq83qxwf09eqquqfdj8rv004attq5tgxejkn59rwu588jprdy0xcg") + "withdraw" + Address("resource_rdx1tknxxxxxxxxxradxrdxxxxxxxxx009923554798xxxxxxxxxradxrd") + Decimal("10") +; +TAKE_FROM_WORKTOP + Address("resource_rdx1tknxxxxxxxxxradxrdxxxxxxxxx009923554798xxxxxxxxxradxrd") + Decimal("10") + Bucket("bucket1") +; +CALL_METHOD + Address("accesscontroller_rdx1cdgcq7yqee9uhyqrsp9kgud3a7h4dvz3dqmx26ws5dmjsu7g3zg23g") + "contribute_recovery_fee" + Bucket("bucket1") +; \ No newline at end of file diff --git a/fixtures/transaction/update_shield_of_persona_init_with_P_confirm_with_C.rtm b/fixtures/transaction/update_shield_of_persona_init_with_P_confirm_with_C.rtm new file mode 100644 index 000000000..61ec30484 --- /dev/null +++ b/fixtures/transaction/update_shield_of_persona_init_with_P_confirm_with_C.rtm @@ -0,0 +1,159 @@ +CALL_METHOD + Address("accesscontroller_rdx1cdf8qgfmz0fgxap9u5haf4ta2lstc04rcfrljgdnznrpugkqv2wudm") + "initiate_recovery_as_primary" + Tuple( + Tuple( + Enum<2u8>( + Enum<1u8>( + Array( + Enum<0u8>( + Enum<2u8>( + 1u8, + Array( + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[99b417749d9022e73a6d2e025648a928ffbc499be8dc9e55eda900b11f]") + ) + ) + ) + ), + Enum<0u8>( + Enum<4u8>( + Array() + ) + ) + ) + ) + ), + Enum<2u8>( + Enum<1u8>( + Array( + Enum<0u8>( + Enum<2u8>( + 0u8, + Array() + ) + ), + Enum<0u8>( + Enum<4u8>( + Array( + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[97d5d7196e49781708520322aaf5872214d854122600dd0125c837aefe]") + ) + ) + ) + ) + ) + ) + ), + Enum<2u8>( + Enum<1u8>( + Array( + Enum<0u8>( + Enum<2u8>( + 0u8, + Array() + ) + ), + Enum<0u8>( + Enum<4u8>( + Array( + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[0b9bdb05d848b70041d7ed45c28dd9d6743a19eb129524d1c623b31784]") + ) + ) + ) + ) + ) + ) + ) + ), + Enum<1u8>( + 20160u32 + ) + ) +; +CALL_METHOD + Address("accesscontroller_rdx1cdf8qgfmz0fgxap9u5haf4ta2lstc04rcfrljgdnznrpugkqv2wudm") + "quick_confirm_primary_role_recovery_proposal" + Tuple( + Tuple( + Enum<2u8>( + Enum<1u8>( + Array( + Enum<0u8>( + Enum<2u8>( + 1u8, + Array( + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[99b417749d9022e73a6d2e025648a928ffbc499be8dc9e55eda900b11f]") + ) + ) + ) + ), + Enum<0u8>( + Enum<4u8>( + Array() + ) + ) + ) + ) + ), + Enum<2u8>( + Enum<1u8>( + Array( + Enum<0u8>( + Enum<2u8>( + 0u8, + Array() + ) + ), + Enum<0u8>( + Enum<4u8>( + Array( + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[97d5d7196e49781708520322aaf5872214d854122600dd0125c837aefe]") + ) + ) + ) + ) + ) + ) + ), + Enum<2u8>( + Enum<1u8>( + Array( + Enum<0u8>( + Enum<2u8>( + 0u8, + Array() + ) + ), + Enum<0u8>( + Enum<4u8>( + Array( + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[0b9bdb05d848b70041d7ed45c28dd9d6743a19eb129524d1c623b31784]") + ) + ) + ) + ) + ) + ) + ) + ), + Enum<1u8>( + 20160u32 + ) + ) +; +SET_METADATA + Address("identity_rdx12fczzwcn62phgf099l2d2l2huz7rag7zglujrvc5cc0z9szs2dzevj") + "owner_keys" + Enum<143u8>( + Array( + Enum<1u8>( + Bytes("675506ad8d7ce4c602cb06c593c0f10e1cc4dcdf2c4144360ef33ebeef") + ) + ) + ) +; \ No newline at end of file diff --git a/fixtures/transaction/update_shield_of_persona_init_with_P_confirm_with_R.rtm b/fixtures/transaction/update_shield_of_persona_init_with_P_confirm_with_R.rtm new file mode 100644 index 000000000..61ec30484 --- /dev/null +++ b/fixtures/transaction/update_shield_of_persona_init_with_P_confirm_with_R.rtm @@ -0,0 +1,159 @@ +CALL_METHOD + Address("accesscontroller_rdx1cdf8qgfmz0fgxap9u5haf4ta2lstc04rcfrljgdnznrpugkqv2wudm") + "initiate_recovery_as_primary" + Tuple( + Tuple( + Enum<2u8>( + Enum<1u8>( + Array( + Enum<0u8>( + Enum<2u8>( + 1u8, + Array( + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[99b417749d9022e73a6d2e025648a928ffbc499be8dc9e55eda900b11f]") + ) + ) + ) + ), + Enum<0u8>( + Enum<4u8>( + Array() + ) + ) + ) + ) + ), + Enum<2u8>( + Enum<1u8>( + Array( + Enum<0u8>( + Enum<2u8>( + 0u8, + Array() + ) + ), + Enum<0u8>( + Enum<4u8>( + Array( + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[97d5d7196e49781708520322aaf5872214d854122600dd0125c837aefe]") + ) + ) + ) + ) + ) + ) + ), + Enum<2u8>( + Enum<1u8>( + Array( + Enum<0u8>( + Enum<2u8>( + 0u8, + Array() + ) + ), + Enum<0u8>( + Enum<4u8>( + Array( + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[0b9bdb05d848b70041d7ed45c28dd9d6743a19eb129524d1c623b31784]") + ) + ) + ) + ) + ) + ) + ) + ), + Enum<1u8>( + 20160u32 + ) + ) +; +CALL_METHOD + Address("accesscontroller_rdx1cdf8qgfmz0fgxap9u5haf4ta2lstc04rcfrljgdnznrpugkqv2wudm") + "quick_confirm_primary_role_recovery_proposal" + Tuple( + Tuple( + Enum<2u8>( + Enum<1u8>( + Array( + Enum<0u8>( + Enum<2u8>( + 1u8, + Array( + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[99b417749d9022e73a6d2e025648a928ffbc499be8dc9e55eda900b11f]") + ) + ) + ) + ), + Enum<0u8>( + Enum<4u8>( + Array() + ) + ) + ) + ) + ), + Enum<2u8>( + Enum<1u8>( + Array( + Enum<0u8>( + Enum<2u8>( + 0u8, + Array() + ) + ), + Enum<0u8>( + Enum<4u8>( + Array( + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[97d5d7196e49781708520322aaf5872214d854122600dd0125c837aefe]") + ) + ) + ) + ) + ) + ) + ), + Enum<2u8>( + Enum<1u8>( + Array( + Enum<0u8>( + Enum<2u8>( + 0u8, + Array() + ) + ), + Enum<0u8>( + Enum<4u8>( + Array( + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[0b9bdb05d848b70041d7ed45c28dd9d6743a19eb129524d1c623b31784]") + ) + ) + ) + ) + ) + ) + ) + ), + Enum<1u8>( + 20160u32 + ) + ) +; +SET_METADATA + Address("identity_rdx12fczzwcn62phgf099l2d2l2huz7rag7zglujrvc5cc0z9szs2dzevj") + "owner_keys" + Enum<143u8>( + Array( + Enum<1u8>( + Bytes("675506ad8d7ce4c602cb06c593c0f10e1cc4dcdf2c4144360ef33ebeef") + ) + ) + ) +; \ No newline at end of file diff --git a/fixtures/transaction/update_shield_of_persona_init_with_P_confirm_with_T.rtm b/fixtures/transaction/update_shield_of_persona_init_with_P_confirm_with_T.rtm new file mode 100644 index 000000000..1e033b62a --- /dev/null +++ b/fixtures/transaction/update_shield_of_persona_init_with_P_confirm_with_T.rtm @@ -0,0 +1,85 @@ +CALL_METHOD + Address("accesscontroller_rdx1cdf8qgfmz0fgxap9u5haf4ta2lstc04rcfrljgdnznrpugkqv2wudm") + "initiate_recovery_as_primary" + Tuple( + Tuple( + Enum<2u8>( + Enum<1u8>( + Array( + Enum<0u8>( + Enum<2u8>( + 1u8, + Array( + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[99b417749d9022e73a6d2e025648a928ffbc499be8dc9e55eda900b11f]") + ) + ) + ) + ), + Enum<0u8>( + Enum<4u8>( + Array() + ) + ) + ) + ) + ), + Enum<2u8>( + Enum<1u8>( + Array( + Enum<0u8>( + Enum<2u8>( + 0u8, + Array() + ) + ), + Enum<0u8>( + Enum<4u8>( + Array( + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[97d5d7196e49781708520322aaf5872214d854122600dd0125c837aefe]") + ) + ) + ) + ) + ) + ) + ), + Enum<2u8>( + Enum<1u8>( + Array( + Enum<0u8>( + Enum<2u8>( + 0u8, + Array() + ) + ), + Enum<0u8>( + Enum<4u8>( + Array( + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[0b9bdb05d848b70041d7ed45c28dd9d6743a19eb129524d1c623b31784]") + ) + ) + ) + ) + ) + ) + ) + ), + Enum<1u8>( + 20160u32 + ) + ) +; +SET_METADATA + Address("identity_rdx12fczzwcn62phgf099l2d2l2huz7rag7zglujrvc5cc0z9szs2dzevj") + "owner_keys" + Enum<143u8>( + Array( + Enum<1u8>( + Bytes("675506ad8d7ce4c602cb06c593c0f10e1cc4dcdf2c4144360ef33ebeef") + ) + ) + ) +; \ No newline at end of file diff --git a/fixtures/transaction/update_shield_of_persona_init_with_R_confirm_with_C.rtm b/fixtures/transaction/update_shield_of_persona_init_with_R_confirm_with_C.rtm new file mode 100644 index 000000000..6d7ec8173 --- /dev/null +++ b/fixtures/transaction/update_shield_of_persona_init_with_R_confirm_with_C.rtm @@ -0,0 +1,148 @@ +CALL_METHOD + Address("accesscontroller_rdx1cdf8qgfmz0fgxap9u5haf4ta2lstc04rcfrljgdnznrpugkqv2wudm") + "initiate_recovery_as_recovery" + Tuple( + Tuple( + Enum<2u8>( + Enum<1u8>( + Array( + Enum<0u8>( + Enum<2u8>( + 1u8, + Array( + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[99b417749d9022e73a6d2e025648a928ffbc499be8dc9e55eda900b11f]") + ) + ) + ) + ), + Enum<0u8>( + Enum<4u8>( + Array() + ) + ) + ) + ) + ), + Enum<2u8>( + Enum<1u8>( + Array( + Enum<0u8>( + Enum<2u8>( + 0u8, + Array() + ) + ), + Enum<0u8>( + Enum<4u8>( + Array( + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[97d5d7196e49781708520322aaf5872214d854122600dd0125c837aefe]") + ) + ) + ) + ) + ) + ) + ), + Enum<2u8>( + Enum<1u8>( + Array( + Enum<0u8>( + Enum<2u8>( + 0u8, + Array() + ) + ), + Enum<0u8>( + Enum<4u8>( + Array( + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[0b9bdb05d848b70041d7ed45c28dd9d6743a19eb129524d1c623b31784]") + ) + ) + ) + ) + ) + ) + ) + ), + Enum<1u8>( + 20160u32 + ) + ) +; +CALL_METHOD + Address("accesscontroller_rdx1cdf8qgfmz0fgxap9u5haf4ta2lstc04rcfrljgdnznrpugkqv2wudm") + "quick_confirm_recovery_role_recovery_proposal" + Tuple( + Tuple( + Enum<2u8>( + Enum<1u8>( + Array( + Enum<0u8>( + Enum<2u8>( + 1u8, + Array( + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[99b417749d9022e73a6d2e025648a928ffbc499be8dc9e55eda900b11f]") + ) + ) + ) + ), + Enum<0u8>( + Enum<4u8>( + Array() + ) + ) + ) + ) + ), + Enum<2u8>( + Enum<1u8>( + Array( + Enum<0u8>( + Enum<2u8>( + 0u8, + Array() + ) + ), + Enum<0u8>( + Enum<4u8>( + Array( + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[97d5d7196e49781708520322aaf5872214d854122600dd0125c837aefe]") + ) + ) + ) + ) + ) + ) + ), + Enum<2u8>( + Enum<1u8>( + Array( + Enum<0u8>( + Enum<2u8>( + 0u8, + Array() + ) + ), + Enum<0u8>( + Enum<4u8>( + Array( + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[0b9bdb05d848b70041d7ed45c28dd9d6743a19eb129524d1c623b31784]") + ) + ) + ) + ) + ) + ) + ) + ), + Enum<1u8>( + 20160u32 + ) + ) +; \ No newline at end of file diff --git a/fixtures/transaction/update_shield_of_persona_init_with_R_confirm_with_T.rtm b/fixtures/transaction/update_shield_of_persona_init_with_R_confirm_with_T.rtm new file mode 100644 index 000000000..64d011623 --- /dev/null +++ b/fixtures/transaction/update_shield_of_persona_init_with_R_confirm_with_T.rtm @@ -0,0 +1,74 @@ +CALL_METHOD + Address("accesscontroller_rdx1cdf8qgfmz0fgxap9u5haf4ta2lstc04rcfrljgdnznrpugkqv2wudm") + "initiate_recovery_as_recovery" + Tuple( + Tuple( + Enum<2u8>( + Enum<1u8>( + Array( + Enum<0u8>( + Enum<2u8>( + 1u8, + Array( + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[99b417749d9022e73a6d2e025648a928ffbc499be8dc9e55eda900b11f]") + ) + ) + ) + ), + Enum<0u8>( + Enum<4u8>( + Array() + ) + ) + ) + ) + ), + Enum<2u8>( + Enum<1u8>( + Array( + Enum<0u8>( + Enum<2u8>( + 0u8, + Array() + ) + ), + Enum<0u8>( + Enum<4u8>( + Array( + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[97d5d7196e49781708520322aaf5872214d854122600dd0125c837aefe]") + ) + ) + ) + ) + ) + ) + ), + Enum<2u8>( + Enum<1u8>( + Array( + Enum<0u8>( + Enum<2u8>( + 0u8, + Array() + ) + ), + Enum<0u8>( + Enum<4u8>( + Array( + Enum<0u8>( + NonFungibleGlobalId("resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[0b9bdb05d848b70041d7ed45c28dd9d6743a19eb129524d1c623b31784]") + ) + ) + ) + ) + ) + ) + ) + ), + Enum<1u8>( + 20160u32 + ) + ) +; \ No newline at end of file diff --git a/makefile b/makefile index 272d96e29..82c825099 100644 --- a/makefile +++ b/makefile @@ -15,3 +15,7 @@ test_mac: test_mac_build: ./scripts/ios/test.sh --build + +clean: + cargo clean + rm cobertura.xml 2> /dev/null || true From 252f2bde3203336cf5767fec0e0d0c619681127f Mon Sep 17 00:00:00 2001 From: Alexander Cyon Date: Sat, 25 Jan 2025 17:01:08 +0100 Subject: [PATCH 15/25] refactored fixtures moved incorrectly placed ones from vector folder. --- .cargo/config.toml | 3 ++ .../src/mobile/deep_link_parsing/parser.rs | 2 +- .../app/signing/src/tests/auth_intent_hash.rs | 4 +-- crates/core/prelude/src/lib.rs | 30 +++++++++++++++++++ .../security_questions_factor_source.rs | 10 ++++--- .../encrypted_profile_snapshot.rs | 6 ++-- .../profile_SPLIT_ME/src/v100/profile.rs | 4 +-- crates/sargon/tests/vectors/main.rs | 25 ++++++++-------- .../deep_link_request_params.json | 0 .../rola_challenge_payload_hash_vectors.json | 0 ...let_interaction_batch_of_transactions.json | 0 .../wallet_interactions_dapp_to_wallet.json | 0 .../wallet_interactions_wallet_to_dapp.json | 0 .../profile}/big_profile_100_accounts.json | 0 .../profile}/huge_profile_1000_accounts.json | 0 ...rsion_100_patch_after_app_version_120.json | 0 ...laintext_profile_snapshot_version_100.json | 0 .../profile_encrypted_by_password_empty.json | 0 ...file_encrypted_by_password_of_babylon.json | 0 ...curity_questions_factor_source_sample.json | 0 ..._questions_factor_source_sample_other.json | 0 21 files changed, 59 insertions(+), 25 deletions(-) rename fixtures/{vector => models/interaction}/deep_link_request_params.json (100%) rename fixtures/{vector => models/interaction}/rola_challenge_payload_hash_vectors.json (100%) create mode 100644 fixtures/models/interaction/wallet_interaction_batch_of_transactions.json rename fixtures/{vector => models/interaction}/wallet_interactions_dapp_to_wallet.json (100%) rename fixtures/{vector => models/interaction}/wallet_interactions_wallet_to_dapp.json (100%) rename fixtures/{vector => models/profile}/big_profile_100_accounts.json (100%) rename fixtures/{vector => models/profile}/huge_profile_1000_accounts.json (100%) rename fixtures/{vector => models/profile}/multi_profile_snapshots_test_version_100_patch_after_app_version_120.json (100%) rename fixtures/{vector => models/profile}/only_plaintext_profile_snapshot_version_100.json (100%) rename fixtures/{vector => models/profile}/profile_encrypted_by_password_empty.json (100%) rename fixtures/{vector => models/profile}/profile_encrypted_by_password_of_babylon.json (100%) rename fixtures/{vector => models/profile_submodels}/security_questions_factor_source_sample.json (100%) rename fixtures/{vector => models/profile_submodels}/security_questions_factor_source_sample_other.json (100%) diff --git a/.cargo/config.toml b/.cargo/config.toml index 2d4363c27..9a327149a 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -6,3 +6,6 @@ FIXTURES_TX = "fixtures/transaction" FIXTURES_VECTOR = "fixtures/vector" FIXTURES_MODELS = "fixtures/models" FIXTURES_MODELS_GW = "fixtures/models/gateway" +FIXTURES_MODELS_INTERACTION = "fixtures/models/interaction" +FIXTURES_MODELS_PROFILES = "fixtures/models/profile" +FIXTURES_MODELS_PROFILE = "fixtures/models/profile_submodels" diff --git a/crates/app/radix-connect/src/mobile/deep_link_parsing/parser.rs b/crates/app/radix-connect/src/mobile/deep_link_parsing/parser.rs index a36855b3d..4ad1c2b36 100644 --- a/crates/app/radix-connect/src/mobile/deep_link_parsing/parser.rs +++ b/crates/app/radix-connect/src/mobile/deep_link_parsing/parser.rs @@ -171,7 +171,7 @@ impl SampleRequestParams { } pub fn new_from_text_vector() -> Self { - fixture::(prelude::fixture_vector!( + fixture::(prelude::fixture_interaction!( "deep_link_request_params" )) .unwrap() diff --git a/crates/app/signing/src/tests/auth_intent_hash.rs b/crates/app/signing/src/tests/auth_intent_hash.rs index 23501bdfc..349d47e16 100644 --- a/crates/app/signing/src/tests/auth_intent_hash.rs +++ b/crates/app/signing/src/tests/auth_intent_hash.rs @@ -1,6 +1,6 @@ #[cfg(test)] mod tests { - use prelude::fixture_vector; + use prelude::fixture_interaction; use serde::{de, Deserializer}; use crate::prelude::*; @@ -52,7 +52,7 @@ mod tests { #[test] fn test_from_vectors() { - let json = fixture_vector!("rola_challenge_payload_hash_vectors"); + let json = fixture_interaction!("rola_challenge_payload_hash_vectors"); let vector = serde_json::from_str::>(json) .unwrap(); diff --git a/crates/core/prelude/src/lib.rs b/crates/core/prelude/src/lib.rs index f8c3ba15a..5f49dab9a 100644 --- a/crates/core/prelude/src/lib.rs +++ b/crates/core/prelude/src/lib.rs @@ -47,6 +47,36 @@ macro_rules! fixture_gw_model { }; } +#[macro_export] +macro_rules! fixture_profiles { + ($file: expr) => { + $crate::fixture_in!( + env!("FIXTURES_MODELS_PROFILES"), + concat!($file, ".json") + ) + }; +} + +#[macro_export] +macro_rules! fixture_profile_model { + ($file: expr) => { + $crate::fixture_in!( + env!("FIXTURES_MODELS_PROFILE"), + concat!($file, ".json") + ) + }; +} + +#[macro_export] +macro_rules! fixture_interaction { + ($file: expr) => { + $crate::fixture_in!( + env!("FIXTURES_MODELS_INTERACTION"), + concat!($file, ".json") + ) + }; +} + pub mod prelude { pub use std::collections::HashSet; pub use std::str::FromStr; diff --git a/crates/factors/factors/src/mfa_factor_sources/security_questions_factor_source/security_questions_factor_source.rs b/crates/factors/factors/src/mfa_factor_sources/security_questions_factor_source/security_questions_factor_source.rs index 18e9069c6..4e74b7580 100644 --- a/crates/factors/factors/src/mfa_factor_sources/security_questions_factor_source/security_questions_factor_source.rs +++ b/crates/factors/factors/src/mfa_factor_sources/security_questions_factor_source/security_questions_factor_source.rs @@ -1,5 +1,5 @@ use encryption::EncryptionScheme; -use prelude::fixture_vector; +use prelude::fixture_profile_model; use crate::prelude::*; @@ -195,7 +195,8 @@ impl SecurityQuestions_NOT_PRODUCTION_READY_FactorSource { impl HasSampleValues for SecurityQuestions_NOT_PRODUCTION_READY_FactorSource { fn sample() -> Self { - let json = fixture_vector!("security_questions_factor_source_sample"); + let json = + fixture_profile_model!("security_questions_factor_source_sample"); let sut = serde_json::from_str::(json).unwrap(); let decrypted = sut.decrypt( @@ -207,8 +208,9 @@ impl HasSampleValues for SecurityQuestions_NOT_PRODUCTION_READY_FactorSource { } fn sample_other() -> Self { - let json = - fixture_vector!("security_questions_factor_source_sample_other"); + let json = fixture_profile_model!( + "security_questions_factor_source_sample_other" + ); let sut = serde_json::from_str::(json).unwrap(); let decrypted = sut .decrypt( diff --git a/crates/profile/models/profile_SPLIT_ME/src/encrypted_profile/encrypted_profile_snapshot.rs b/crates/profile/models/profile_SPLIT_ME/src/encrypted_profile/encrypted_profile_snapshot.rs index b66fb2665..e37442d7f 100644 --- a/crates/profile/models/profile_SPLIT_ME/src/encrypted_profile/encrypted_profile_snapshot.rs +++ b/crates/profile/models/profile_SPLIT_ME/src/encrypted_profile/encrypted_profile_snapshot.rs @@ -2,7 +2,7 @@ use encryption::{ EncryptionKey, EncryptionScheme, PasswordBasedKeyDerivationScheme, VersionedEncryption, VersionedPasswordBasedKeyDerivation, }; -use prelude::fixture_vector; +use prelude::fixture_profiles; use crate::prelude::*; @@ -92,13 +92,13 @@ impl HasSampleValues for EncryptedProfileSnapshot { /// Password is: `"babylon"` - encryption of SAME profile as `Self::sample_other()` fn sample() -> Self { let json_str = - fixture_vector!("profile_encrypted_by_password_of_babylon"); + fixture_profiles!("profile_encrypted_by_password_of_babylon"); serde_json::from_str::(json_str).unwrap() } /// Password is: `""` (empty) - encryption of SAME profile as `Self::sample()` fn sample_other() -> Self { - let json_str = fixture_vector!("profile_encrypted_by_password_empty"); + let json_str = fixture_profiles!("profile_encrypted_by_password_empty"); serde_json::from_str::(json_str).unwrap() } } diff --git a/crates/profile/models/profile_SPLIT_ME/src/v100/profile.rs b/crates/profile/models/profile_SPLIT_ME/src/v100/profile.rs index b7b2bc919..7eba24736 100644 --- a/crates/profile/models/profile_SPLIT_ME/src/v100/profile.rs +++ b/crates/profile/models/profile_SPLIT_ME/src/v100/profile.rs @@ -399,7 +399,7 @@ impl HasSampleValues for Profile { #[cfg(test)] mod tests { - use prelude::fixture_vector; + use prelude::fixture_profiles; use super::*; @@ -638,7 +638,7 @@ mod tests { fn check_if_profile_json_contains_legacy_p2p_links_in_profile_snapshot_version_100( ) { let json = - fixture_vector!("only_plaintext_profile_snapshot_version_100"); + fixture_profiles!("only_plaintext_profile_snapshot_version_100"); assert!(SUT::check_if_profile_json_contains_legacy_p2p_links(json)); } diff --git a/crates/sargon/tests/vectors/main.rs b/crates/sargon/tests/vectors/main.rs index 8bf37bb63..d2a5f0280 100644 --- a/crates/sargon/tests/vectors/main.rs +++ b/crates/sargon/tests/vectors/main.rs @@ -1,12 +1,11 @@ -use sargon::prelude::*; - use core::fmt::Debug; +use sargon::prelude::*; use serde::Deserialize; use std::str::FromStr; #[cfg(test)] mod profile_snapshot_tests { - use prelude::fixture_vector; + use prelude::fixture_profiles; use super::*; @@ -17,7 +16,7 @@ mod profile_snapshot_tests { /// [doc]: https://radixdlt.atlassian.net/wiki/spaces/AT/pages/3251863610/CAP-36+WebRTC+Clients+Protocol #[test] fn v100_100() { - fixture_and_json::(fixture_vector!( + fixture_and_json::(fixture_profiles!( "only_plaintext_profile_snapshot_version_100" )) .expect("V100 Profile to deserialize"); @@ -592,7 +591,7 @@ mod slip10_tests { mod encrypted_profile_tests { use std::collections::HashSet; - use prelude::fixture_vector; + use prelude::fixture_profiles; use serde::Serialize; use super::*; @@ -744,7 +743,7 @@ mod encrypted_profile_tests { #[test] fn test_vectors() { - let fixture = fixture::(fixture_vector!( + let fixture = fixture::(fixture_profiles!( "multi_profile_snapshots_test_version_100_patch_after_app_version_120" )) .expect("Encrypted Profile tests"); @@ -756,13 +755,13 @@ mod encrypted_profile_tests { #[cfg(test)] mod dapp_to_wallet_interaction_tests { use super::*; - use prelude::fixture_vector; + use prelude::fixture_interaction; use serde_json::Value; #[test] fn test_vector() { let decoded_wallet_interactions = - fixture::>(fixture_vector!( + fixture::>(fixture_interaction!( "wallet_interactions_dapp_to_wallet" )) .expect("wallet_interactions_dapp_to_wallet fixture"); @@ -992,9 +991,9 @@ mod dapp_to_wallet_interaction_tests { pretty_assertions::assert_eq!(fixture, expected); } - let raw_wallet_interactions = fixture::>(fixture_vector!( - "wallet_interactions_dapp_to_wallet" - )) + let raw_wallet_interactions = fixture::>( + fixture_interaction!("wallet_interactions_dapp_to_wallet"), + ) .expect("wallet_interactions_dapp_to_wallet fixture"); let encoded_interactions = @@ -1014,7 +1013,7 @@ mod dapp_to_wallet_interaction_tests { mod wallet_to_dapp_interaction_tests { use super::*; - use prelude::fixture_vector; + use prelude::fixture_interaction; use serde_json::Value; #[test] @@ -1280,7 +1279,7 @@ mod wallet_to_dapp_interaction_tests { let encoded = serde_json::to_string(&responses).unwrap(); let serde_value: Vec = serde_json::from_str(&encoded).unwrap(); - let fixture = fixture::>(fixture_vector!( + let fixture = fixture::>(fixture_interaction!( "wallet_interactions_wallet_to_dapp" )) .expect("wallet_interactions_wallet_to_dapp fixture"); diff --git a/fixtures/vector/deep_link_request_params.json b/fixtures/models/interaction/deep_link_request_params.json similarity index 100% rename from fixtures/vector/deep_link_request_params.json rename to fixtures/models/interaction/deep_link_request_params.json diff --git a/fixtures/vector/rola_challenge_payload_hash_vectors.json b/fixtures/models/interaction/rola_challenge_payload_hash_vectors.json similarity index 100% rename from fixtures/vector/rola_challenge_payload_hash_vectors.json rename to fixtures/models/interaction/rola_challenge_payload_hash_vectors.json diff --git a/fixtures/models/interaction/wallet_interaction_batch_of_transactions.json b/fixtures/models/interaction/wallet_interaction_batch_of_transactions.json new file mode 100644 index 000000000..e69de29bb diff --git a/fixtures/vector/wallet_interactions_dapp_to_wallet.json b/fixtures/models/interaction/wallet_interactions_dapp_to_wallet.json similarity index 100% rename from fixtures/vector/wallet_interactions_dapp_to_wallet.json rename to fixtures/models/interaction/wallet_interactions_dapp_to_wallet.json diff --git a/fixtures/vector/wallet_interactions_wallet_to_dapp.json b/fixtures/models/interaction/wallet_interactions_wallet_to_dapp.json similarity index 100% rename from fixtures/vector/wallet_interactions_wallet_to_dapp.json rename to fixtures/models/interaction/wallet_interactions_wallet_to_dapp.json diff --git a/fixtures/vector/big_profile_100_accounts.json b/fixtures/models/profile/big_profile_100_accounts.json similarity index 100% rename from fixtures/vector/big_profile_100_accounts.json rename to fixtures/models/profile/big_profile_100_accounts.json diff --git a/fixtures/vector/huge_profile_1000_accounts.json b/fixtures/models/profile/huge_profile_1000_accounts.json similarity index 100% rename from fixtures/vector/huge_profile_1000_accounts.json rename to fixtures/models/profile/huge_profile_1000_accounts.json diff --git a/fixtures/vector/multi_profile_snapshots_test_version_100_patch_after_app_version_120.json b/fixtures/models/profile/multi_profile_snapshots_test_version_100_patch_after_app_version_120.json similarity index 100% rename from fixtures/vector/multi_profile_snapshots_test_version_100_patch_after_app_version_120.json rename to fixtures/models/profile/multi_profile_snapshots_test_version_100_patch_after_app_version_120.json diff --git a/fixtures/vector/only_plaintext_profile_snapshot_version_100.json b/fixtures/models/profile/only_plaintext_profile_snapshot_version_100.json similarity index 100% rename from fixtures/vector/only_plaintext_profile_snapshot_version_100.json rename to fixtures/models/profile/only_plaintext_profile_snapshot_version_100.json diff --git a/fixtures/vector/profile_encrypted_by_password_empty.json b/fixtures/models/profile/profile_encrypted_by_password_empty.json similarity index 100% rename from fixtures/vector/profile_encrypted_by_password_empty.json rename to fixtures/models/profile/profile_encrypted_by_password_empty.json diff --git a/fixtures/vector/profile_encrypted_by_password_of_babylon.json b/fixtures/models/profile/profile_encrypted_by_password_of_babylon.json similarity index 100% rename from fixtures/vector/profile_encrypted_by_password_of_babylon.json rename to fixtures/models/profile/profile_encrypted_by_password_of_babylon.json diff --git a/fixtures/vector/security_questions_factor_source_sample.json b/fixtures/models/profile_submodels/security_questions_factor_source_sample.json similarity index 100% rename from fixtures/vector/security_questions_factor_source_sample.json rename to fixtures/models/profile_submodels/security_questions_factor_source_sample.json diff --git a/fixtures/vector/security_questions_factor_source_sample_other.json b/fixtures/models/profile_submodels/security_questions_factor_source_sample_other.json similarity index 100% rename from fixtures/vector/security_questions_factor_source_sample_other.json rename to fixtures/models/profile_submodels/security_questions_factor_source_sample_other.json From 3489880f7025549b8a2214920dadedcba417331c Mon Sep 17 00:00:00 2001 From: Alexander Cyon Date: Sun, 26 Jan 2025 10:19:55 +0100 Subject: [PATCH 16/25] interaction --- Cargo.lock | 1 + crates/app/radix-connect/Cargo.toml | 1 + crates/app/radix-connect/src/lib.rs | 3 +- .../batch_of_transactions.rs | 12 +- ...f_transactions_applying_security_shield.rs | 110 ++++++++++++++++++ .../batch_of_transactions/mod.rs | 2 + ...on_os_apply_security_shield_interaction.rs | 36 ++++-- .../batch_of_transactions.rs | 2 +- ...f_transactions_applying_security_shield.rs | 18 +++ .../batch_of_transactions/mod.rs | 2 + 10 files changed, 168 insertions(+), 19 deletions(-) create mode 100644 crates/app/radix-connect/src/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/batch_of_transactions_applying_security_shield.rs create mode 100644 crates/uniffi/uniffi_SPLIT_ME/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/batch_of_transactions_applying_security_shield.rs diff --git a/Cargo.lock b/Cargo.lock index d12cd9632..aa3ee7125 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3305,6 +3305,7 @@ dependencies = [ "prelude", "pretty_assertions", "profile-persona-data", + "profile-security-structures", "radix-connect-models", "serde", "serde_json", diff --git a/crates/app/radix-connect/Cargo.toml b/crates/app/radix-connect/Cargo.toml index 1f4d87309..4a2afac60 100644 --- a/crates/app/radix-connect/Cargo.toml +++ b/crates/app/radix-connect/Cargo.toml @@ -25,6 +25,7 @@ entity-foundation = { workspace = true } short-string = { workspace = true } has-sample-values = { workspace = true } radix-connect-models = { workspace = true } +profile-security-structures = { workspace = true } # === RADIX DEPENDENCIES === # None diff --git a/crates/app/radix-connect/src/lib.rs b/crates/app/radix-connect/src/lib.rs index fc98dd83f..d87d53902 100644 --- a/crates/app/radix-connect/src/lib.rs +++ b/crates/app/radix-connect/src/lib.rs @@ -29,8 +29,9 @@ pub mod prelude { pub(crate) use identified_vec_of::prelude::*; pub(crate) use prelude::prelude::*; pub(crate) use profile_persona_data::prelude::*; + pub(crate) use profile_security_structures::prelude::*; pub(crate) use radix_connect_models::prelude::*; - pub(crate) use short_string::prelude::*; + pub(crate) use transaction_models::prelude::*; // EXTERNAL DEPENDENCIES diff --git a/crates/app/radix-connect/src/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/batch_of_transactions.rs b/crates/app/radix-connect/src/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/batch_of_transactions.rs index 7b69b36c8..27b1a4a3a 100644 --- a/crates/app/radix-connect/src/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/batch_of_transactions.rs +++ b/crates/app/radix-connect/src/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/batch_of_transactions.rs @@ -2,12 +2,14 @@ use crate::prelude::*; #[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] pub struct DappToWalletInteractionBatchOfTransactions { - pub transactions: Vec, + pub transactions: Vec, } impl DappToWalletInteractionBatchOfTransactions { pub fn new( - transactions: impl IntoIterator, + transactions: impl IntoIterator< + Item = BatchOfTransactionsApplyingSecurityShield, + >, ) -> Self { Self { transactions: transactions.into_iter().collect(), @@ -18,13 +20,13 @@ impl DappToWalletInteractionBatchOfTransactions { impl HasSampleValues for DappToWalletInteractionBatchOfTransactions { fn sample() -> Self { Self::new([ - UnvalidatedTransactionManifest::sample(), - UnvalidatedTransactionManifest::sample_other(), + BatchOfTransactionsApplyingSecurityShield::sample(), + BatchOfTransactionsApplyingSecurityShield::sample_other(), ]) } fn sample_other() -> Self { - Self::new([UnvalidatedTransactionManifest::sample_other()]) + Self::new([BatchOfTransactionsApplyingSecurityShield::sample_other()]) } } diff --git a/crates/app/radix-connect/src/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/batch_of_transactions_applying_security_shield.rs b/crates/app/radix-connect/src/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/batch_of_transactions_applying_security_shield.rs new file mode 100644 index 000000000..973923b32 --- /dev/null +++ b/crates/app/radix-connect/src/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/batch_of_transactions_applying_security_shield.rs @@ -0,0 +1,110 @@ +use prelude::fixture_rtm; + +use crate::prelude::*; + +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] +pub struct BatchOfTransactionsApplyingSecurityShield { + /// The ID of security shield being applied + pub shield_id: SecurityStructureID, + + /// The address of the entity for which we apply the security shield. + pub entity_address: AddressOfAccountOrPersona, + + /// This Vec will contain a single TransactionManifest if entity identified + /// by entity_address is unsecurified, but if it is securified it will contain + /// `RolesExercisableInTransactionManifestCombination::all().len()` many + /// TransactionManifests + pub transactions: Vec, +} + +impl BatchOfTransactionsApplyingSecurityShield { + pub fn new( + shield_id: SecurityStructureID, + entity_address: AddressOfAccountOrPersona, + transactions: impl IntoIterator, + ) -> Self { + Self { + shield_id, + entity_address, + transactions: transactions.into_iter().collect(), + } + } +} +impl HasSampleValues for BatchOfTransactionsApplyingSecurityShield { + fn sample() -> Self { + let init_p_conf_r = TransactionManifest::new( + fixture_rtm!("update_shield_of_persona_init_with_P_confirm_with_R"), + NetworkID::Mainnet, + Blobs::default(), + ) + .unwrap(); + let init_p_conf_c = TransactionManifest::new( + fixture_rtm!("update_shield_of_persona_init_with_P_confirm_with_C"), + NetworkID::Mainnet, + Blobs::default(), + ) + .unwrap(); + let init_p_conf_t = TransactionManifest::new( + fixture_rtm!("update_shield_of_persona_init_with_P_confirm_with_T"), + NetworkID::Mainnet, + Blobs::default(), + ) + .unwrap(); + + let init_r_conf_c = TransactionManifest::new( + fixture_rtm!("update_shield_of_persona_init_with_R_confirm_with_C"), + NetworkID::Mainnet, + Blobs::default(), + ) + .unwrap(); + let init_r_conf_t = TransactionManifest::new( + fixture_rtm!("update_shield_of_persona_init_with_R_confirm_with_T"), + NetworkID::Mainnet, + Blobs::default(), + ) + .unwrap(); + Self::new( + SecurityStructureID::sample(), + IdentityAddress::sample_mainnet().into(), + [ + init_p_conf_r, + init_p_conf_c, + init_p_conf_t, + init_r_conf_c, + init_r_conf_t, + ] + .into_iter() + .map(Into::into), + ) + } + + fn sample_other() -> Self { + let unsecurified = TransactionManifest::new( + fixture_rtm!("create_access_controller_for_account"), + NetworkID::Mainnet, + Blobs::default(), + ) + .unwrap(); + Self::new(SecurityStructureID::sample(), "account_rdx128dtethfy8ujrsfdztemyjk0kvhnah6dafr57frz85dcw2c8z0td87".parse().unwrap(), [ + unsecurified + ].into_iter().map(Into::into),) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[allow(clippy::upper_case_acronyms)] + type SUT = BatchOfTransactionsApplyingSecurityShield; + + #[test] + fn equality() { + assert_eq!(SUT::sample(), SUT::sample()); + } + + #[test] + fn inequality() { + assert_ne!(SUT::sample(), SUT::sample_other()); + } +} diff --git a/crates/app/radix-connect/src/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/mod.rs b/crates/app/radix-connect/src/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/mod.rs index ea996a5c3..8de5df34f 100644 --- a/crates/app/radix-connect/src/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/mod.rs +++ b/crates/app/radix-connect/src/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/mod.rs @@ -1,4 +1,6 @@ #[allow(clippy::module_inception)] mod batch_of_transactions; +mod batch_of_transactions_applying_security_shield; pub use batch_of_transactions::*; +pub use batch_of_transactions_applying_security_shield::*; diff --git a/crates/system/os/factors/src/apply_security_shield/sargon_os_apply_security_shield_interaction.rs b/crates/system/os/factors/src/apply_security_shield/sargon_os_apply_security_shield_interaction.rs index 83739916a..aa6efb60a 100644 --- a/crates/system/os/factors/src/apply_security_shield/sargon_os_apply_security_shield_interaction.rs +++ b/crates/system/os/factors/src/apply_security_shield/sargon_os_apply_security_shield_interaction.rs @@ -1,5 +1,8 @@ use crate::prelude::*; -use radix_connect::DappToWalletInteractionBatchOfTransactions; +use radix_connect::{ + BatchOfTransactionsApplyingSecurityShield, + DappToWalletInteractionBatchOfTransactions, +}; #[async_trait::async_trait] pub trait OsApplySecurityShieldInteraction { @@ -31,10 +34,12 @@ impl OsApplySecurityShieldInteraction for SargonOS { let provisional = e.entity.get_provisional().expect("Entity should have a provisional config set since we applied shield above"); let derived = provisional.as_factor_instances_derived().expect("Should have derived factors"); TransactionManifest::apply_security_shield_for_unsecurified_entity( - e, + e.clone(), derived.clone() - ) - }).collect::>>()?; + ).map(|manifest| { + BatchOfTransactionsApplyingSecurityShield::new(derived.security_structure_id, e.address(), [UnvalidatedTransactionManifest::from(manifest)]) + }) + }).collect::>>()?; let manifests_for_securified = entities_with_provisional .securified_erased() @@ -42,19 +47,26 @@ impl OsApplySecurityShieldInteraction for SargonOS { .map(|e| { let provisional = e.entity.get_provisional().expect("Entity should have a provisional config set since we applied shield above"); let derived = provisional.as_factor_instances_derived().expect("Should have derived factors"); - TransactionManifest::apply_security_shield_for_securified_entity( - e, - derived.clone(), - RolesExercisableInTransactionManifestCombination::default() - ) - }).collect::>>()?; + + let res = RolesExercisableInTransactionManifestCombination::all() + .into_iter() + .map(|combination| { + TransactionManifest::apply_security_shield_for_securified_entity( + e.clone(), + derived.clone(), + combination + ).map(UnvalidatedTransactionManifest::from) + }) + .collect::>>(); + + res.map(|manifests| BatchOfTransactionsApplyingSecurityShield::new(derived.security_structure_id, e.address(), manifests)) + }).collect::>>()?; Ok(DappToWalletInteractionBatchOfTransactions::new( manifests_for_unsecurified .iter() .chain(manifests_for_securified.iter()) - .cloned() - .map(UnvalidatedTransactionManifest::from), + .cloned(), )) } } diff --git a/crates/uniffi/uniffi_SPLIT_ME/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/batch_of_transactions.rs b/crates/uniffi/uniffi_SPLIT_ME/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/batch_of_transactions.rs index bc9eb7e24..12556650f 100644 --- a/crates/uniffi/uniffi_SPLIT_ME/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/batch_of_transactions.rs +++ b/crates/uniffi/uniffi_SPLIT_ME/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/batch_of_transactions.rs @@ -3,5 +3,5 @@ use sargon::DappToWalletInteractionBatchOfTransactions as InternalDappToWalletIn #[derive(Clone, PartialEq, InternalConversion, uniffi::Record)] pub struct DappToWalletInteractionBatchOfTransactions { - pub transactions: Vec, + pub transactions: Vec, } diff --git a/crates/uniffi/uniffi_SPLIT_ME/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/batch_of_transactions_applying_security_shield.rs b/crates/uniffi/uniffi_SPLIT_ME/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/batch_of_transactions_applying_security_shield.rs new file mode 100644 index 000000000..3f38195ac --- /dev/null +++ b/crates/uniffi/uniffi_SPLIT_ME/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/batch_of_transactions_applying_security_shield.rs @@ -0,0 +1,18 @@ +use crate::prelude::*; + +use sargon::BatchOfTransactionsApplyingSecurityShield as InternalBatchOfTransactionsApplyingSecurityShield; + +#[derive(Clone, PartialEq, InternalConversion, uniffi::Record)] +pub struct BatchOfTransactionsApplyingSecurityShield { + /// The ID of security shield being applied + pub shield_id: SecurityStructureID, + + /// The address of the entity for which we apply the security shield. + pub entity_address: AddressOfAccountOrPersona, + + /// This Vec will contain a single TransactionManifest if entity identified + /// by entity_address is unsecurified, but if it is securified it will contain + /// `RolesExercisableInTransactionManifestCombination::all().len()` many + /// TransactionManifests + pub transactions: Vec, +} diff --git a/crates/uniffi/uniffi_SPLIT_ME/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/mod.rs b/crates/uniffi/uniffi_SPLIT_ME/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/mod.rs index ea996a5c3..8de5df34f 100644 --- a/crates/uniffi/uniffi_SPLIT_ME/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/mod.rs +++ b/crates/uniffi/uniffi_SPLIT_ME/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/mod.rs @@ -1,4 +1,6 @@ #[allow(clippy::module_inception)] mod batch_of_transactions; +mod batch_of_transactions_applying_security_shield; pub use batch_of_transactions::*; +pub use batch_of_transactions_applying_security_shield::*; From 3ac37f3fea65453feadd8e622256f88127e484fb Mon Sep 17 00:00:00 2001 From: Alexander Cyon Date: Sun, 26 Jan 2025 15:30:18 +0100 Subject: [PATCH 17/25] add interaction model --- ...on_os_apply_security_shield_interaction.rs | 181 +++++++++++++++++- .../sargon_os_apply_shield.rs | 108 ++++++----- ...fests_securify_shield_securified_entity.rs | 13 +- ...let_interaction_batch_of_transactions.json | 68 +++++++ 4 files changed, 313 insertions(+), 57 deletions(-) diff --git a/crates/system/os/factors/src/apply_security_shield/sargon_os_apply_security_shield_interaction.rs b/crates/system/os/factors/src/apply_security_shield/sargon_os_apply_security_shield_interaction.rs index aa6efb60a..f83b8aad1 100644 --- a/crates/system/os/factors/src/apply_security_shield/sargon_os_apply_security_shield_interaction.rs +++ b/crates/system/os/factors/src/apply_security_shield/sargon_os_apply_security_shield_interaction.rs @@ -48,19 +48,20 @@ impl OsApplySecurityShieldInteraction for SargonOS { let provisional = e.entity.get_provisional().expect("Entity should have a provisional config set since we applied shield above"); let derived = provisional.as_factor_instances_derived().expect("Should have derived factors"); - let res = RolesExercisableInTransactionManifestCombination::all() + let manifests = RolesExercisableInTransactionManifestCombination::all() .into_iter() - .map(|combination| { + .filter_map(|combination| { TransactionManifest::apply_security_shield_for_securified_entity( e.clone(), derived.clone(), combination - ).map(UnvalidatedTransactionManifest::from) + ) }) - .collect::>>(); + .map(UnvalidatedTransactionManifest::from) + .collect::>(); - res.map(|manifests| BatchOfTransactionsApplyingSecurityShield::new(derived.security_structure_id, e.address(), manifests)) - }).collect::>>()?; + BatchOfTransactionsApplyingSecurityShield::new(derived.security_structure_id, e.address(), manifests) + }).collect::>(); Ok(DappToWalletInteractionBatchOfTransactions::new( manifests_for_unsecurified @@ -70,3 +71,171 @@ impl OsApplySecurityShieldInteraction for SargonOS { )) } } + +#[cfg(test)] +mod tests { + use prelude::fixture_interaction; + + use super::*; + + #[actix_rt::test] + async fn test_make_interaction_for_applying_security_shield() { + // ARRANGE + let (os, shield_id, addresses_of_mixed_entities_sec_unsec) = { + let os = SargonOS::fast_boot_bdfs_and_interactor( + MnemonicWithPassphrase::sample_device_other(), + None, + false, + ) + .await; + let shield = add_unsafe_shield_with_matrix_with_fixed_metadata( + &os, + SecurityStructureMetadata::sample(), + ) + .await + .unwrap(); + let shield_id = shield.id(); + let network = NetworkID::Mainnet; + let account = os + .create_and_save_new_account_with_main_bdfs( + network, + DisplayName::sample(), + ) + .await + .unwrap(); + let persona = os + .create_and_save_new_persona_with_main_bdfs( + network, + DisplayName::sample_other(), + None, + ) + .await + .unwrap(); + + os.apply_security_shield_with_id_to_entities( + shield_id, + IndexSet::from_iter([ + AddressOfAccountOrPersona::from(account.address()), + AddressOfAccountOrPersona::from(persona.address()), + ]), + ) + .await + .unwrap(); + + // Dummy impl of securifying entities + let (securified_account, securified_persona) = { + let mut account = + os.account_by_address(account.address()).unwrap(); + let mut persona = + os.persona_by_address(persona.address()).unwrap(); + + let mut account_security_structure_of_instances = account + .get_provisional() + .unwrap() + .as_factor_instances_derived() + .unwrap() + .clone(); + + // Here we ensure that we test that we reuse the existing ROLA key for the persona below, but not for this account, i.e. the existing ROLA key of this account will mismatch that of the shield. + account_security_structure_of_instances + .authentication_signing_factor_instance = + HierarchicalDeterministicFactorInstance::sample_auth_signing(); + assert_ne!( + FactorSourceID::from( + account_security_structure_of_instances + .authentication_signing_factor_instance + .factor_source_id + ), + shield.authentication_signing_factor + ); + + let account_secured_control = SecuredEntityControl::new( + account + .clone() + .security_state() + .as_unsecured() + .unwrap() + .transaction_signing + .clone(), + AccessControllerAddress::sample_mainnet(), + account_security_structure_of_instances, + ) + .unwrap(); + account + .set_security_state(EntitySecurityState::Securified { + value: account_secured_control, + }) + .unwrap(); + os.update_account(account.clone()).await.unwrap(); + + let persona_security_structure_of_instances = persona + .get_provisional() + .unwrap() + .as_factor_instances_derived() + .unwrap() + .clone(); + let persona_secured_control = SecuredEntityControl::new( + persona + .clone() + .security_state() + .as_unsecured() + .unwrap() + .transaction_signing + .clone(), + AccessControllerAddress::sample_mainnet_other(), + persona_security_structure_of_instances, + ) + .unwrap(); + persona + .set_security_state(EntitySecurityState::Securified { + value: persona_secured_control, + }) + .unwrap(); + os.update_persona(persona.clone()).await.unwrap(); + + (account, persona) + }; + + let account = os + .create_and_save_new_account_with_main_bdfs( + network, + DisplayName::sample(), + ) + .await + .unwrap(); + let persona = os + .create_and_save_new_persona_with_main_bdfs( + network, + DisplayName::sample_other(), + None, + ) + .await + .unwrap(); + + ( + os, + shield_id, + IndexSet::from_iter([ + AddressOfAccountOrPersona::from(account.address()), + persona.address().into(), + securified_account.address().into(), + securified_persona.address().into(), + ]), + ) + }; + + // ACT + let interaction = { + os.make_interaction_for_applying_security_shield( + shield_id, + addresses_of_mixed_entities_sec_unsec.clone(), + ) + .await + .unwrap() + }; + + let fixture_json = + fixture_interaction!("wallet_interaction_batch_of_transactions"); + assert_eq_after_json_roundtrip(&interaction, fixture_json); + } +} diff --git a/crates/system/os/factors/src/apply_security_shield/sargon_os_apply_shield.rs b/crates/system/os/factors/src/apply_security_shield/sargon_os_apply_shield.rs index 0eaf4a505..95482e7a1 100644 --- a/crates/system/os/factors/src/apply_security_shield/sargon_os_apply_shield.rs +++ b/crates/system/os/factors/src/apply_security_shield/sargon_os_apply_shield.rs @@ -367,56 +367,72 @@ impl OsShieldApplying for SargonOS { } #[cfg(test)] -mod tests { - - use super::*; - - fn unsafe_shield_with_bdfs( - bdfs: &FactorSource, - ) -> SecurityStructureOfFactorSourceIDs { - let id = bdfs.factor_source_id(); - - // This is an invalid shield, but it's just for testing - let matrix = unsafe { - MatrixOfFactorSourceIds::unbuilt_with_roles_and_days( - PrimaryRoleWithFactorSourceIDs::unbuilt_with_factors( - Threshold::zero(), - [], - [id], - ), - RecoveryRoleWithFactorSourceIDs::unbuilt_with_factors( - Threshold::zero(), - [], - [id], - ), - ConfirmationRoleWithFactorSourceIDs::unbuilt_with_factors( - Threshold::zero(), - [], - [id], - ), - 14, - ) - }; - SecurityStructureOfFactorSourceIds::new( - DisplayName::new("Invalid Shield").unwrap(), - matrix, - id, +pub(crate) fn unsafe_shield_with_bdfs( + bdfs: &FactorSource, +) -> SecurityStructureOfFactorSourceIDs { + let id = bdfs.factor_source_id(); + + // This is an invalid shield, but it's just for testing + let matrix = unsafe { + MatrixOfFactorSourceIds::unbuilt_with_roles_and_days( + PrimaryRoleWithFactorSourceIDs::unbuilt_with_factors( + Threshold::zero(), + [], + [id], + ), + RecoveryRoleWithFactorSourceIDs::unbuilt_with_factors( + Threshold::zero(), + [], + [id], + ), + ConfirmationRoleWithFactorSourceIDs::unbuilt_with_factors( + Threshold::zero(), + [], + [id], + ), + 14, ) - } + }; + SecurityStructureOfFactorSourceIds::new( + DisplayName::new("Invalid Shield").unwrap(), + matrix, + id, + ) +} - async fn add_unsafe_shield_with_matrix( - os: &SargonOS, - ) -> Result { - let bdsf = os.main_bdfs()?; - let shield_of_ids = unsafe_shield_with_bdfs(&bdsf.into()); - os.add_security_structure_of_factor_source_ids(&shield_of_ids) - .await?; - Ok(shield_of_ids) +#[cfg(test)] +pub(crate) async fn add_unsafe_shield_with_matrix_with_fixed_metadata( + os: &SargonOS, + fixed_metadata: impl Into>, +) -> Result { + let bdsf = os.main_bdfs()?; + let mut shield_of_ids = unsafe_shield_with_bdfs(&bdsf.into()); + if let Some(fixed_metadata) = fixed_metadata.into() { + shield_of_ids.metadata = fixed_metadata; } + os.add_security_structure_of_factor_source_ids(&shield_of_ids) + .await?; + Ok(shield_of_ids) +} - async fn add_unsafe_shield(os: &SargonOS) -> Result { - add_unsafe_shield_with_matrix(os).await.map(|s| s.id()) - } +#[cfg(test)] +pub(crate) async fn add_unsafe_shield_with_matrix( + os: &SargonOS, +) -> Result { + add_unsafe_shield_with_matrix_with_fixed_metadata(os, None).await +} + +#[cfg(test)] +pub(crate) async fn add_unsafe_shield( + os: &SargonOS, +) -> Result { + add_unsafe_shield_with_matrix(os).await.map(|s| s.id()) +} + +#[cfg(test)] +mod tests { + + use super::*; #[actix_rt::test] async fn test_apply_security_shield_with_id_to_unsecurified_entities_only() diff --git a/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs b/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs index 1ce3e0a53..d727ff4e6 100644 --- a/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs +++ b/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs @@ -12,7 +12,7 @@ pub trait TransactionManifestSecurifySecurifiedEntity: security_structure_of_factor_instances: SecurityStructureOfFactorInstances, roles_combination: RolesExercisableInTransactionManifestCombination, - ) -> Result; + ) -> Option; } impl TransactionManifestSecurifySecurifiedEntity for TransactionManifest { @@ -34,11 +34,14 @@ impl TransactionManifestSecurifySecurifiedEntity for TransactionManifest { security_structure_of_factor_instances: SecurityStructureOfFactorInstances, roles_combination: RolesExercisableInTransactionManifestCombination, - ) -> Result { + ) -> Option { let securified_entity = securified_entity.into(); let kind = roles_combination; let entity_address = securified_entity.entity.address(); + security_structure_of_factor_instances + .assert_has_entity_kind(entity_address.get_entity_kind()).expect("Shouldn't have used wrong FactorInstance for entity - apply_security_shield_with_id_to_entities has some bug."); + // ACCESS_CONTROLLER_CREATE_PROOF_IDENT let mut builder = ScryptoTransactionManifestBuilder::new(); @@ -85,7 +88,7 @@ impl TransactionManifestSecurifySecurifiedEntity for TransactionManifest { &entity_address, ); } else { - return Err(CommonError::Unknown); // TODO: new error variant + return None; // Nothing has "failed" really, but we cannot proceed with this combination. } } @@ -106,7 +109,7 @@ impl TransactionManifestSecurifySecurifiedEntity for TransactionManifest { // after user has selected account to pay in wallet GUI. And also call // `modify_manifest_add_lock_fee_against_xrd_vault_of_access_controller` - Ok(manifest) + Some(manifest) } } @@ -265,6 +268,6 @@ mod tests { RolesExercisableInTransactionManifestCombination::InitiateWithRecoveryDelayedCompletion, ); - assert_eq!(res, Err(CommonError::Unknown)); + assert_eq!(res, None); } } diff --git a/fixtures/models/interaction/wallet_interaction_batch_of_transactions.json b/fixtures/models/interaction/wallet_interaction_batch_of_transactions.json index e69de29bb..1e21762e0 100644 --- a/fixtures/models/interaction/wallet_interaction_batch_of_transactions.json +++ b/fixtures/models/interaction/wallet_interaction_batch_of_transactions.json @@ -0,0 +1,68 @@ +{ + "transactions": [ + { + "shield_id": "ffffffff-ffff-ffff-ffff-ffffffffffff", + "entity_address": "account_rdx128mh2ae9dsrwa0t8l37ayjrxxf0p84e6qm227ytxtcu447f5uw5m8w", + "transactions": [ + { + "transactionManifest": "CALL_METHOD\n Address(\"account_rdx128mh2ae9dsrwa0t8l37ayjrxxf0p84e6qm227ytxtcu447f5uw5m8w\")\n \"securify\"\n;\nTAKE_FROM_WORKTOP\n Address(\"resource_rdx1nfxxxxxxxxxxaccwnrxxxxxxxxx006664022062xxxxxxxxxaccwnr\")\n Decimal(\"1\")\n Bucket(\"bucket1\")\n;\nALLOCATE_GLOBAL_ADDRESS\n Address(\"package_rdx1pkgxxxxxxxxxcntrlrxxxxxxxxx000648572295xxxxxxxxxcntrlr\")\n \"AccessController\"\n AddressReservation(\"reservation1\")\n NamedAddress(\"address1\")\n;\nCREATE_ACCESS_CONTROLLER\n Bucket(\"bucket1\")\n Tuple(\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[0e8695a4117774464ca04bb6d10ce0b11aede12bd797dcdee811067094]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[0e8695a4117774464ca04bb6d10ce0b11aede12bd797dcdee811067094]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[0e8695a4117774464ca04bb6d10ce0b11aede12bd797dcdee811067094]\")\n )\n )\n )\n )\n )\n )\n )\n )\n Enum<1u8>(\n 20160u32\n )\n Enum<1u8>(\n AddressReservation(\"reservation1\")\n )\n;\nSET_METADATA\n Address(\"account_rdx128mh2ae9dsrwa0t8l37ayjrxxf0p84e6qm227ytxtcu447f5uw5m8w\")\n \"owner_keys\"\n Enum<143u8>(\n Array(\n Enum<1u8>(\n Bytes(\"8e7da995687de79d87a51e4acadccbeea15df2b165800247930298bc16\")\n )\n )\n )\n;\n", + "blobs": [] + } + ] + }, + { + "shield_id": "ffffffff-ffff-ffff-ffff-ffffffffffff", + "entity_address": "identity_rdx122kkqj7pc04gwsgcwsxmfmknlsg4qpz52rrs6vj72cujks4ukw993v", + "transactions": [ + { + "transactionManifest": "CALL_METHOD\n Address(\"identity_rdx122kkqj7pc04gwsgcwsxmfmknlsg4qpz52rrs6vj72cujks4ukw993v\")\n \"securify\"\n;\nTAKE_FROM_WORKTOP\n Address(\"resource_rdx1nfxxxxxxxxxxdntwnrxxxxxxxxx002876444928xxxxxxxxxdntwnr\")\n Decimal(\"1\")\n Bucket(\"bucket1\")\n;\nALLOCATE_GLOBAL_ADDRESS\n Address(\"package_rdx1pkgxxxxxxxxxcntrlrxxxxxxxxx000648572295xxxxxxxxxcntrlr\")\n \"AccessController\"\n AddressReservation(\"reservation1\")\n NamedAddress(\"address1\")\n;\nCREATE_ACCESS_CONTROLLER\n Bucket(\"bucket1\")\n Tuple(\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[0b5896b1b5a1de8573b3a90216e7b14b42aa11746ad2e0bcb0741c216d]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[0b5896b1b5a1de8573b3a90216e7b14b42aa11746ad2e0bcb0741c216d]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[0b5896b1b5a1de8573b3a90216e7b14b42aa11746ad2e0bcb0741c216d]\")\n )\n )\n )\n )\n )\n )\n )\n )\n Enum<1u8>(\n 20160u32\n )\n Enum<1u8>(\n AddressReservation(\"reservation1\")\n )\n;\nSET_METADATA\n Address(\"identity_rdx122kkqj7pc04gwsgcwsxmfmknlsg4qpz52rrs6vj72cujks4ukw993v\")\n \"owner_keys\"\n Enum<143u8>(\n Array(\n Enum<1u8>(\n Bytes(\"a9a3197f2553f4cfe4603e77fd1802f14490862e11a33d81c98c430e31\")\n )\n )\n )\n;\n", + "blobs": [] + } + ] + }, + { + "shield_id": "ffffffff-ffff-ffff-ffff-ffffffffffff", + "entity_address": "account_rdx12xek3geay25lktmk5zyplc7z7mg5xe8ldh48ta4mkcd9q0v0q6l8y6", + "transactions": [ + { + "transactionManifest": "CALL_METHOD\n Address(\"accesscontroller_rdx1c0duj4lq0dc3cpl8qd420fpn5eckh8ljeysvjm894lyl5ja5yq6y5a\")\n \"initiate_recovery_as_primary\"\n Tuple(\n Tuple(\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[bfcba3ae8b30485830dc1dc578b2f921b1b65cb2a391cb063c0f1b6106]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[bfcba3ae8b30485830dc1dc578b2f921b1b65cb2a391cb063c0f1b6106]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[bfcba3ae8b30485830dc1dc578b2f921b1b65cb2a391cb063c0f1b6106]\")\n )\n )\n )\n )\n )\n )\n )\n ),\n Enum<1u8>(\n 20160u32\n )\n )\n;\nCALL_METHOD\n Address(\"accesscontroller_rdx1c0duj4lq0dc3cpl8qd420fpn5eckh8ljeysvjm894lyl5ja5yq6y5a\")\n \"quick_confirm_primary_role_recovery_proposal\"\n Tuple(\n Tuple(\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[bfcba3ae8b30485830dc1dc578b2f921b1b65cb2a391cb063c0f1b6106]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[bfcba3ae8b30485830dc1dc578b2f921b1b65cb2a391cb063c0f1b6106]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[bfcba3ae8b30485830dc1dc578b2f921b1b65cb2a391cb063c0f1b6106]\")\n )\n )\n )\n )\n )\n )\n )\n ),\n Enum<1u8>(\n 20160u32\n )\n )\n;\nSET_METADATA\n Address(\"account_rdx12xek3geay25lktmk5zyplc7z7mg5xe8ldh48ta4mkcd9q0v0q6l8y6\")\n \"owner_keys\"\n Enum<143u8>(\n Array(\n Enum<1u8>(\n Bytes(\"e2e27b925c7d98ebe436172f00b024862127b26b40decd416ca41cdb48\")\n )\n )\n )\n;\n", + "blobs": [] + }, + { + "transactionManifest": "CALL_METHOD\n Address(\"accesscontroller_rdx1c0duj4lq0dc3cpl8qd420fpn5eckh8ljeysvjm894lyl5ja5yq6y5a\")\n \"initiate_recovery_as_primary\"\n Tuple(\n Tuple(\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[bfcba3ae8b30485830dc1dc578b2f921b1b65cb2a391cb063c0f1b6106]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[bfcba3ae8b30485830dc1dc578b2f921b1b65cb2a391cb063c0f1b6106]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[bfcba3ae8b30485830dc1dc578b2f921b1b65cb2a391cb063c0f1b6106]\")\n )\n )\n )\n )\n )\n )\n )\n ),\n Enum<1u8>(\n 20160u32\n )\n )\n;\nCALL_METHOD\n Address(\"accesscontroller_rdx1c0duj4lq0dc3cpl8qd420fpn5eckh8ljeysvjm894lyl5ja5yq6y5a\")\n \"quick_confirm_primary_role_recovery_proposal\"\n Tuple(\n Tuple(\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[bfcba3ae8b30485830dc1dc578b2f921b1b65cb2a391cb063c0f1b6106]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[bfcba3ae8b30485830dc1dc578b2f921b1b65cb2a391cb063c0f1b6106]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[bfcba3ae8b30485830dc1dc578b2f921b1b65cb2a391cb063c0f1b6106]\")\n )\n )\n )\n )\n )\n )\n )\n ),\n Enum<1u8>(\n 20160u32\n )\n )\n;\nSET_METADATA\n Address(\"account_rdx12xek3geay25lktmk5zyplc7z7mg5xe8ldh48ta4mkcd9q0v0q6l8y6\")\n \"owner_keys\"\n Enum<143u8>(\n Array(\n Enum<1u8>(\n Bytes(\"e2e27b925c7d98ebe436172f00b024862127b26b40decd416ca41cdb48\")\n )\n )\n )\n;\n", + "blobs": [] + }, + { + "transactionManifest": "CALL_METHOD\n Address(\"accesscontroller_rdx1c0duj4lq0dc3cpl8qd420fpn5eckh8ljeysvjm894lyl5ja5yq6y5a\")\n \"initiate_recovery_as_primary\"\n Tuple(\n Tuple(\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[bfcba3ae8b30485830dc1dc578b2f921b1b65cb2a391cb063c0f1b6106]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[bfcba3ae8b30485830dc1dc578b2f921b1b65cb2a391cb063c0f1b6106]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[bfcba3ae8b30485830dc1dc578b2f921b1b65cb2a391cb063c0f1b6106]\")\n )\n )\n )\n )\n )\n )\n )\n ),\n Enum<1u8>(\n 20160u32\n )\n )\n;\nSET_METADATA\n Address(\"account_rdx12xek3geay25lktmk5zyplc7z7mg5xe8ldh48ta4mkcd9q0v0q6l8y6\")\n \"owner_keys\"\n Enum<143u8>(\n Array(\n Enum<1u8>(\n Bytes(\"e2e27b925c7d98ebe436172f00b024862127b26b40decd416ca41cdb48\")\n )\n )\n )\n;\n", + "blobs": [] + } + ] + }, + { + "shield_id": "ffffffff-ffff-ffff-ffff-ffffffffffff", + "entity_address": "identity_rdx12fhyj4l6k63p3hhvgczhr8c6w697tv3eudn7ndsn2hphrkm7thupd4", + "transactions": [ + { + "transactionManifest": "CALL_METHOD\n Address(\"accesscontroller_rdx1cv93xuha64eay8ctkx9km0el2jgkuh6gqlwec7tzecccyu0rj37xak\")\n \"initiate_recovery_as_primary\"\n Tuple(\n Tuple(\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n )\n ),\n Enum<1u8>(\n 20160u32\n )\n )\n;\nCALL_METHOD\n Address(\"accesscontroller_rdx1cv93xuha64eay8ctkx9km0el2jgkuh6gqlwec7tzecccyu0rj37xak\")\n \"quick_confirm_primary_role_recovery_proposal\"\n Tuple(\n Tuple(\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n )\n ),\n Enum<1u8>(\n 20160u32\n )\n )\n;\n", + "blobs": [] + }, + { + "transactionManifest": "CALL_METHOD\n Address(\"accesscontroller_rdx1cv93xuha64eay8ctkx9km0el2jgkuh6gqlwec7tzecccyu0rj37xak\")\n \"initiate_recovery_as_primary\"\n Tuple(\n Tuple(\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n )\n ),\n Enum<1u8>(\n 20160u32\n )\n )\n;\nCALL_METHOD\n Address(\"accesscontroller_rdx1cv93xuha64eay8ctkx9km0el2jgkuh6gqlwec7tzecccyu0rj37xak\")\n \"quick_confirm_primary_role_recovery_proposal\"\n Tuple(\n Tuple(\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n )\n ),\n Enum<1u8>(\n 20160u32\n )\n )\n;\n", + "blobs": [] + }, + { + "transactionManifest": "CALL_METHOD\n Address(\"accesscontroller_rdx1cv93xuha64eay8ctkx9km0el2jgkuh6gqlwec7tzecccyu0rj37xak\")\n \"initiate_recovery_as_recovery\"\n Tuple(\n Tuple(\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n )\n ),\n Enum<1u8>(\n 20160u32\n )\n )\n;\nCALL_METHOD\n Address(\"accesscontroller_rdx1cv93xuha64eay8ctkx9km0el2jgkuh6gqlwec7tzecccyu0rj37xak\")\n \"quick_confirm_recovery_role_recovery_proposal\"\n Tuple(\n Tuple(\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n )\n ),\n Enum<1u8>(\n 20160u32\n )\n )\n;\n", + "blobs": [] + }, + { + "transactionManifest": "CALL_METHOD\n Address(\"accesscontroller_rdx1cv93xuha64eay8ctkx9km0el2jgkuh6gqlwec7tzecccyu0rj37xak\")\n \"initiate_recovery_as_recovery\"\n Tuple(\n Tuple(\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n )\n ),\n Enum<1u8>(\n 20160u32\n )\n )\n;\n", + "blobs": [] + }, + { + "transactionManifest": "CALL_METHOD\n Address(\"accesscontroller_rdx1cv93xuha64eay8ctkx9km0el2jgkuh6gqlwec7tzecccyu0rj37xak\")\n \"initiate_recovery_as_primary\"\n Tuple(\n Tuple(\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n )\n ),\n Enum<1u8>(\n 20160u32\n )\n )\n;\n", + "blobs": [] + } + ] + } + ] + } \ No newline at end of file From ebde221684822570c65f87913daaa14e7c66f065 Mon Sep 17 00:00:00 2001 From: Alexander Cyon Date: Sun, 26 Jan 2025 20:16:22 +0100 Subject: [PATCH 18/25] change 'number_of_days_until_timed_confirmation_is_callable' into 'time_until_delayed_confirmation_is_callable' and change type from u16 into TimePeriod --- ...entity_index_profile_analyzing_assigner.rs | 6 +- ...trix_of_factor_instances_index_agnostic.rs | 4 +- .../models/app-preferences/src/security.rs | 10 +++- .../entity_security_state.rs | 10 +++- .../secured_entity_control.rs | 10 +++- .../abstract_matrix_builder_or_built.rs | 10 ++-- .../matrices/builder/matrix_builder.rs | 30 +++++----- .../builder/matrix_builder_unit_tests.rs | 12 ++-- .../matrices/builder/matrix_template.rs | 8 +-- .../matrices/matrix_of_factor_instances.rs | 22 +++---- .../matrices/matrix_of_factor_source_ids.rs | 18 ++++-- .../matrices/matrix_of_factor_sources.rs | 2 +- .../security_shield_builder.rs | 9 +-- .../security_structure_of_factor_instances.rs | 10 +++- ...security_structure_of_factor_source_ids.rs | 10 +++- .../security_structure_of_factor_sources.rs | 2 +- .../security-structures/src/time_period.rs | 60 ++++++++++++++++++- .../src/time_period_unit.rs | 12 +++- .../sargon_os_apply_shield.rs | 2 +- .../os/factors/src/test_instances_provider.rs | 33 +++++----- .../matrices/decl_matrix_macro.rs | 8 +-- .../security_structures/models/time_period.rs | 4 +- .../security_shield_builder.rs | 11 ++-- 23 files changed, 200 insertions(+), 103 deletions(-) diff --git a/crates/factors/instances-provider/src/next_index_assigner/next_derivation_entity_index_profile_analyzing_assigner.rs b/crates/factors/instances-provider/src/next_index_assigner/next_derivation_entity_index_profile_analyzing_assigner.rs index 2335a1197..c7a6030e5 100644 --- a/crates/factors/instances-provider/src/next_index_assigner/next_derivation_entity_index_profile_analyzing_assigner.rs +++ b/crates/factors/instances-provider/src/next_index_assigner/next_derivation_entity_index_profile_analyzing_assigner.rs @@ -483,7 +483,7 @@ mod tests { ConfirmationRoleWithFactorInstances::override_only( [fi.clone()], ), - 10, + TimePeriod::with_days(10), ) }; @@ -539,7 +539,7 @@ mod tests { ConfirmationRoleWithFactorInstances::override_only( [fi.clone()], ), - 10, + TimePeriod::with_days(10), ) }; @@ -675,7 +675,7 @@ mod tests { ConfirmationRoleWithFactorInstances::override_only( factors.clone(), ), - 123, + TimePeriod::with_days(123), ) }; diff --git a/crates/profile/logic/logic_SPLIT_ME/src/tests/matrix_of_factor_instances_index_agnostic.rs b/crates/profile/logic/logic_SPLIT_ME/src/tests/matrix_of_factor_instances_index_agnostic.rs index 09e61ed59..314534641 100644 --- a/crates/profile/logic/logic_SPLIT_ME/src/tests/matrix_of_factor_instances_index_agnostic.rs +++ b/crates/profile/logic/logic_SPLIT_ME/src/tests/matrix_of_factor_instances_index_agnostic.rs @@ -27,7 +27,7 @@ fn wrong_entity_kind() { [], [], ), - 1, + TimePeriod::with_days(1), ) }; let res = invalid.index_agnostic_path_of_all_tx_signing_factor_instances(); @@ -62,7 +62,7 @@ fn wrong_key_kind() { [], [], ), - 1, + TimePeriod::with_days(1), ) }; let res = invalid.index_agnostic_path_of_all_tx_signing_factor_instances(); diff --git a/crates/profile/models/app-preferences/src/security.rs b/crates/profile/models/app-preferences/src/security.rs index 2d0162299..6f94e1114 100644 --- a/crates/profile/models/app-preferences/src/security.rs +++ b/crates/profile/models/app-preferences/src/security.rs @@ -247,7 +247,10 @@ mod tests { } ] }, - "numberOfDaysUntilTimedConfirmationIsCallable": 14 + "timeUntilDelayedConfirmationIsCallable": { + "value": 2, + "unit": "weeks" + } } }, { @@ -304,7 +307,10 @@ mod tests { } ] }, - "numberOfDaysUntilTimedConfirmationIsCallable": 14 + "timeUntilDelayedConfirmationIsCallable": { + "value": 2, + "unit": "weeks" + } } } ] diff --git a/crates/profile/models/base-entity/src/entity_security_state/entity_security_state.rs b/crates/profile/models/base-entity/src/entity_security_state/entity_security_state.rs index 6e72dc823..592e31bfc 100644 --- a/crates/profile/models/base-entity/src/entity_security_state/entity_security_state.rs +++ b/crates/profile/models/base-entity/src/entity_security_state/entity_security_state.rs @@ -382,7 +382,10 @@ mod tests { } ] }, - "numberOfDaysUntilTimedConfirmationIsCallable": 14 + "timeUntilDelayedConfirmationIsCallable": { + "value": 2, + "unit": "weeks" + } }, "authenticationSigningFactorInstance": { "factorSourceID": { @@ -508,7 +511,10 @@ mod tests { } ] }, - "numberOfDaysUntilTimedConfirmationIsCallable": 14 + "timeUntilDelayedConfirmationIsCallable": { + "value": 2, + "unit": "weeks" + } }, "authenticationSigningFactorInstance": { "factorSourceID": { diff --git a/crates/profile/models/base-entity/src/entity_security_state/secured_entity_control/secured_entity_control.rs b/crates/profile/models/base-entity/src/entity_security_state/secured_entity_control/secured_entity_control.rs index 336dcbbb7..07b48b397 100644 --- a/crates/profile/models/base-entity/src/entity_security_state/secured_entity_control/secured_entity_control.rs +++ b/crates/profile/models/base-entity/src/entity_security_state/secured_entity_control/secured_entity_control.rs @@ -349,7 +349,10 @@ mod tests { } ] }, - "numberOfDaysUntilTimedConfirmationIsCallable": 14 + "timeUntilDelayedConfirmationIsCallable": { + "value": 2, + "unit": "weeks" + } }, "authenticationSigningFactorInstance": { "factorSourceID": { @@ -475,7 +478,10 @@ mod tests { } ] }, - "numberOfDaysUntilTimedConfirmationIsCallable": 14 + "timeUntilDelayedConfirmationIsCallable": { + "value": 2, + "unit": "weeks" + } }, "authenticationSigningFactorInstance": { "factorSourceID": { diff --git a/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/abstract_matrix_builder_or_built.rs b/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/abstract_matrix_builder_or_built.rs index 49c2ac28f..a91fb832d 100644 --- a/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/abstract_matrix_builder_or_built.rs +++ b/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/abstract_matrix_builder_or_built.rs @@ -39,14 +39,14 @@ pub struct AbstractMatrixBuilderOrBuilt< pub(crate) confirmation_role: AbstractRoleBuilderOrBuilt<{ ROLE_CONFIRMATION }, MODE_OF_ROLE, FACTOR>, - pub number_of_days_until_timed_confirmation_is_callable: u16, + pub time_until_delayed_confirmation_is_callable: TimePeriod, } impl AbstractMatrixBuilderOrBuilt { - pub const DEFAULT_NUMBER_OF_DAYS_UNTIL_TIMED_CONFIRMATION_IS_CALLABLE: u16 = - 14; + pub const DEFAULT_TIME_UNTIL_DELAYE_CONFIRMATION_IS_CALLABLE: TimePeriod = + TimePeriod::with_days(14); /// # Safety /// Rust memory safe, but marked "unsafe" since it might allow for unsafe @@ -110,13 +110,13 @@ impl MODE_OF_ROLE, FACTOR, >, - number_of_days_until_timed_confirmation_is_callable: u16, + time_until_delayed_confirmation_is_callable: TimePeriod, ) -> Self { Self { primary_role, recovery_role, confirmation_role, - number_of_days_until_timed_confirmation_is_callable, + time_until_delayed_confirmation_is_callable, } } } diff --git a/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/builder/matrix_builder.rs b/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/builder/matrix_builder.rs index 3ffa06d3e..87c98461d 100644 --- a/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/builder/matrix_builder.rs +++ b/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/builder/matrix_builder.rs @@ -12,7 +12,7 @@ pub type MatrixBuilderBuildResult = /// * RecoveryRoleBuilder /// * ConfirmationRoleBuilder /// -/// And `number_of_days_until_timed_confirmation_is_callable`. +/// And `time_until_delayed_confirmation_is_callable`. pub type MatrixBuilder = AbstractMatrixBuilderOrBuilt< IS_MATRIX_BUILDER, IS_ROLE_BUILDER, @@ -28,8 +28,8 @@ impl MatrixBuilder { primary_role: PrimaryRoleBuilder::new(), recovery_role: RecoveryRoleBuilder::new(), confirmation_role: ConfirmationRoleBuilder::new(), - number_of_days_until_timed_confirmation_is_callable: - Self::DEFAULT_NUMBER_OF_DAYS_UNTIL_TIMED_CONFIRMATION_IS_CALLABLE, + time_until_delayed_confirmation_is_callable: + Self::DEFAULT_TIME_UNTIL_DELAYE_CONFIRMATION_IS_CALLABLE, } } @@ -37,7 +37,7 @@ impl MatrixBuilder { /// /// If valid it returns a "built" `MatrixOfFactorSourceIds`. pub fn build(&self) -> MatrixBuilderBuildResult { - self.validate_number_of_days_until_timed_confirmation_is_callable()?; + self.validate_time_until_delayed_confirmation_is_callable()?; let primary = self .primary_role @@ -61,7 +61,7 @@ impl MatrixBuilder { primary, recovery, confirmation, - self.number_of_days_until_timed_confirmation_is_callable, + self.time_until_delayed_confirmation_is_callable, ) }; Ok(built) @@ -379,20 +379,20 @@ impl MatrixBuilder { self.primary_role.get_threshold() } - pub fn set_number_of_days_until_timed_confirmation_is_callable( + pub fn set_time_until_delayed_confirmation_is_callable( &mut self, number_of_days: u16, ) -> MatrixBuilderMutateResult { - self.number_of_days_until_timed_confirmation_is_callable = - number_of_days; + self.time_until_delayed_confirmation_is_callable = + TimePeriod::with_days(number_of_days); - self.validate_number_of_days_until_timed_confirmation_is_callable() + self.validate_time_until_delayed_confirmation_is_callable() } - pub fn get_number_of_days_until_timed_confirmation_is_callable( + pub fn get_time_until_delayed_confirmation_is_callable( &self, - ) -> u16 { - self.number_of_days_until_timed_confirmation_is_callable + ) -> TimePeriod { + self.time_until_delayed_confirmation_is_callable } fn remove_factor_from_role( @@ -536,10 +536,10 @@ impl MatrixBuilder { } } - fn validate_number_of_days_until_timed_confirmation_is_callable( + fn validate_time_until_delayed_confirmation_is_callable( &self, ) -> MatrixBuilderMutateResult { - if self.number_of_days_until_timed_confirmation_is_callable == 0 { + if self.time_until_delayed_confirmation_is_callable.is_zero() { return Err(MatrixBuilderValidation::CombinationViolation( MatrixRolesInCombinationViolation::Basic( MatrixRolesInCombinationBasicViolation::NumberOfDaysUntilTimeBasedConfirmationMustBeGreaterThanZero, @@ -613,7 +613,7 @@ impl MatrixBuilder { self.validate_no_factor_may_be_used_in_both_primary_threshold_and_override()?; self.validate_no_factor_may_be_used_in_both_recovery_and_confirmation( )?; - self.validate_number_of_days_until_timed_confirmation_is_callable()?; + self.validate_time_until_delayed_confirmation_is_callable()?; Ok(()) } } diff --git a/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/builder/matrix_builder_unit_tests.rs b/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/builder/matrix_builder_unit_tests.rs index 6be093792..d4347c35d 100644 --- a/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/builder/matrix_builder_unit_tests.rs +++ b/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/builder/matrix_builder_unit_tests.rs @@ -86,7 +86,7 @@ fn set_number_of_days_cannot_be_zero() { ) .unwrap(); - sut.number_of_days_until_timed_confirmation_is_callable = 0; // bypass validation + sut.time_until_delayed_confirmation_is_callable = TimePeriod::with_days(0); // bypass validation // Build let validation = MatrixBuilderValidation::CombinationViolation( @@ -117,7 +117,7 @@ fn set_number_of_days_42() { ) .unwrap(); - sut.set_number_of_days_until_timed_confirmation_is_callable(42) + sut.set_time_until_delayed_confirmation_is_callable(42) .unwrap(); // Build @@ -137,7 +137,7 @@ fn set_number_of_days_42() { ConfirmationRoleWithFactorSourceIds::override_only([ FactorSourceID::sample_password() ],), - 42, + TimePeriod::with_days(42), ) ); } @@ -145,8 +145,8 @@ fn set_number_of_days_42() { #[test] fn timed_confirm_default() { assert_eq!( - SUT::DEFAULT_NUMBER_OF_DAYS_UNTIL_TIMED_CONFIRMATION_IS_CALLABLE, - 14 + SUT::DEFAULT_TIME_UNTIL_DELAYE_CONFIRMATION_IS_CALLABLE, + TimePeriod::with_days(14) ); } @@ -187,7 +187,7 @@ fn set_number_of_days_if_not_set_uses_default() { ConfirmationRoleWithFactorSourceIds::override_only([ FactorSourceID::sample_password() ],), - SUT::DEFAULT_NUMBER_OF_DAYS_UNTIL_TIMED_CONFIRMATION_IS_CALLABLE, + SUT::DEFAULT_TIME_UNTIL_DELAYE_CONFIRMATION_IS_CALLABLE, ) ); } diff --git a/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/builder/matrix_template.rs b/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/builder/matrix_template.rs index 7c56f877b..ce59b8e1b 100644 --- a/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/builder/matrix_template.rs +++ b/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/builder/matrix_template.rs @@ -82,8 +82,8 @@ impl MatrixTemplate { self, factor_source_ids: impl IntoIterator, ) -> Result { - let number_of_days_until_timed_confirmation_is_callable = - self.number_of_days_until_timed_confirmation_is_callable; + let time_until_delayed_confirmation_is_callable = + self.time_until_delayed_confirmation_is_callable; let mut assigner = FactorSourceIdAssigner::new(factor_source_ids); @@ -98,7 +98,7 @@ impl MatrixTemplate { primary_role, recovery_role, confirmation_role, - number_of_days_until_timed_confirmation_is_callable, + time_until_delayed_confirmation_is_callable, ) }; @@ -113,7 +113,7 @@ impl MatrixTemplate { confirmation_role: ConfirmationRoleTemplate, ) -> Self { unsafe { - Self::unbuilt_with_roles_and_days(primary_role, recovery_role, confirmation_role, MatrixOfFactorSourceIds::DEFAULT_NUMBER_OF_DAYS_UNTIL_TIMED_CONFIRMATION_IS_CALLABLE) + Self::unbuilt_with_roles_and_days(primary_role, recovery_role, confirmation_role, MatrixOfFactorSourceIds::DEFAULT_TIME_UNTIL_DELAYE_CONFIRMATION_IS_CALLABLE) } } diff --git a/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/matrix_of_factor_instances.rs b/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/matrix_of_factor_instances.rs index 74ee05bc2..eb4d0d35f 100644 --- a/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/matrix_of_factor_instances.rs +++ b/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/matrix_of_factor_instances.rs @@ -4,9 +4,8 @@ pub type MatrixOfFactorInstances = AbstractMatrixBuilt; impl MatrixOfFactorInstances { pub fn timed_recovery_delay_in_minutes(&self) -> u32 { - let timed_recovery_in_days = - self.number_of_days_until_timed_confirmation_is_callable as u32; - MINUTES_PER_DAY * timed_recovery_in_days + self.time_until_delayed_confirmation_is_callable + .in_minutes() } } @@ -291,7 +290,7 @@ impl MatrixOfFactorInstances { recovery_role, confirmation_role, matrix_of_factor_sources - .number_of_days_until_timed_confirmation_is_callable, + .time_until_delayed_confirmation_is_callable, ) }; @@ -338,13 +337,7 @@ mod tests { #[test] fn timed_recovery_delay_in_minutes() { let sut = SUT::sample(); - assert_eq!( - sut.timed_recovery_delay_in_minutes(), - SUT::DEFAULT_NUMBER_OF_DAYS_UNTIL_TIMED_CONFIRMATION_IS_CALLABLE - as u32 - * 24 - * 60 - ); + assert_eq!(sut.timed_recovery_delay_in_minutes(), 14_u32 * 24 * 60); } #[test] @@ -386,7 +379,7 @@ mod tests { [], [], ), - 1, + TimePeriod::with_days(1), ) }; let res = @@ -561,7 +554,10 @@ mod tests { } ] }, - "numberOfDaysUntilTimedConfirmationIsCallable": 14 + "timeUntilDelayedConfirmationIsCallable": { + "value": 2, + "unit": "weeks" + } } "#, ); diff --git a/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/matrix_of_factor_source_ids.rs b/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/matrix_of_factor_source_ids.rs index 21d3f74eb..5ff5210ee 100644 --- a/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/matrix_of_factor_source_ids.rs +++ b/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/matrix_of_factor_source_ids.rs @@ -13,7 +13,7 @@ impl MatrixOfFactorSourceIds { primary, recovery, confirmation, - Self::DEFAULT_NUMBER_OF_DAYS_UNTIL_TIMED_CONFIRMATION_IS_CALLABLE, + Self::DEFAULT_TIME_UNTIL_DELAYE_CONFIRMATION_IS_CALLABLE, ) } } @@ -25,14 +25,14 @@ impl MatrixOfFactorSourceIds { primary: PrimaryRoleWithFactorSourceIds, recovery: RecoveryRoleWithFactorSourceIds, confirmation: ConfirmationRoleWithFactorSourceIds, - number_of_days_until_timed_confirmation_is_callable: u16, + time_until_delayed_confirmation_is_callable: TimePeriod, ) -> Self { unsafe { Self::unbuilt_with_roles_and_days( primary, recovery, confirmation, - number_of_days_until_timed_confirmation_is_callable, + time_until_delayed_confirmation_is_callable, ) } } @@ -46,7 +46,7 @@ impl MatrixOfFactorSourceIds { primary, recovery, confirmation, - Self::DEFAULT_NUMBER_OF_DAYS_UNTIL_TIMED_CONFIRMATION_IS_CALLABLE, + Self::DEFAULT_TIME_UNTIL_DELAYE_CONFIRMATION_IS_CALLABLE, ) } } @@ -321,7 +321,10 @@ mod tests { } ] }, - "numberOfDaysUntilTimedConfirmationIsCallable": 14 + "timeUntilDelayedConfirmationIsCallable": { + "value": 2, + "unit": "weeks" + } } "#, ); @@ -373,7 +376,10 @@ mod tests { } ] }, - "numberOfDaysUntilTimedConfirmationIsCallable": 14 + "timeUntilDelayedConfirmationIsCallable": { + "value": 2, + "unit": "weeks" + } } "#, ); diff --git a/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/matrix_of_factor_sources.rs b/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/matrix_of_factor_sources.rs index 1402a78f2..d3d8a6801 100644 --- a/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/matrix_of_factor_sources.rs +++ b/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/matrix_of_factor_sources.rs @@ -30,7 +30,7 @@ impl MatrixOfFactorSources { primary_role, recovery_role, confirmation_role, - matrix.number_of_days_until_timed_confirmation_is_callable, + matrix.time_until_delayed_confirmation_is_callable, ) }; diff --git a/crates/profile/models/security-structures/src/roles_matrices_structures/security_shield_builder.rs b/crates/profile/models/security-structures/src/roles_matrices_structures/security_shield_builder.rs index f5707224d..9b72f4235 100644 --- a/crates/profile/models/security-structures/src/roles_matrices_structures/security_shield_builder.rs +++ b/crates/profile/models/security-structures/src/roles_matrices_structures/security_shield_builder.rs @@ -279,10 +279,7 @@ impl SecurityShieldBuilder { &self, ) -> TimePeriod { self.get(|builder| { - TimePeriod::with_days( - builder - .get_number_of_days_until_timed_confirmation_is_callable(), - ) + builder.get_time_until_delayed_confirmation_is_callable() }) } @@ -441,7 +438,7 @@ impl SecurityShieldBuilder { time_period: TimePeriod, ) -> &Self { self.set(|builder| { - builder.set_number_of_days_until_timed_confirmation_is_callable( + builder.set_time_until_delayed_confirmation_is_callable( time_period.days(), ) }) @@ -1594,7 +1591,7 @@ mod test_invalid { } #[test] - fn number_of_days_until_timed_confirmation_is_callable_invalid() { + fn time_until_delayed_confirmation_is_callable_invalid() { let sut = valid(); sut.set_time_period_until_timed_confirmation_is_callable( TimePeriod::with_days(0), diff --git a/crates/profile/models/security-structures/src/roles_matrices_structures/security_structure_of_factors/security_structure_of_factor_instances.rs b/crates/profile/models/security-structures/src/roles_matrices_structures/security_structure_of_factors/security_structure_of_factor_instances.rs index 3865741be..7d734a23a 100644 --- a/crates/profile/models/security-structures/src/roles_matrices_structures/security_structure_of_factors/security_structure_of_factor_instances.rs +++ b/crates/profile/models/security-structures/src/roles_matrices_structures/security_structure_of_factors/security_structure_of_factor_instances.rs @@ -287,7 +287,10 @@ mod tests { } ] }, - "numberOfDaysUntilTimedConfirmationIsCallable": 14 + "timeUntilDelayedConfirmationIsCallable": { + "value": 2, + "unit": "weeks" + } }, "authenticationSigningFactorInstance": { "factorSourceID": { @@ -471,7 +474,10 @@ mod tests { } ] }, - "numberOfDaysUntilTimedConfirmationIsCallable": 14 + "timeUntilDelayedConfirmationIsCallable": { + "value": 2, + "unit": "weeks" + } }, "authenticationSigningFactorInstance": { "factorSourceID": { diff --git a/crates/profile/models/security-structures/src/roles_matrices_structures/security_structure_of_factors/security_structure_of_factor_source_ids.rs b/crates/profile/models/security-structures/src/roles_matrices_structures/security_structure_of_factors/security_structure_of_factor_source_ids.rs index a90a40e59..cd4c0c826 100644 --- a/crates/profile/models/security-structures/src/roles_matrices_structures/security_structure_of_factors/security_structure_of_factor_source_ids.rs +++ b/crates/profile/models/security-structures/src/roles_matrices_structures/security_structure_of_factors/security_structure_of_factor_source_ids.rs @@ -117,7 +117,10 @@ mod tests { } ] }, - "numberOfDaysUntilTimedConfirmationIsCallable": 14 + "timeUntilDelayedConfirmationIsCallable": { + "value": 2, + "unit": "weeks" + } } } "#, @@ -184,7 +187,10 @@ mod tests { } ] }, - "numberOfDaysUntilTimedConfirmationIsCallable": 14 + "timeUntilDelayedConfirmationIsCallable": { + "value": 2, + "unit": "weeks" + } } } "#, diff --git a/crates/profile/models/security-structures/src/roles_matrices_structures/security_structure_of_factors/security_structure_of_factor_sources.rs b/crates/profile/models/security-structures/src/roles_matrices_structures/security_structure_of_factors/security_structure_of_factor_sources.rs index 241cf59b6..60283e99e 100644 --- a/crates/profile/models/security-structures/src/roles_matrices_structures/security_structure_of_factors/security_structure_of_factor_sources.rs +++ b/crates/profile/models/security-structures/src/roles_matrices_structures/security_structure_of_factors/security_structure_of_factor_sources.rs @@ -104,7 +104,7 @@ impl From for MatrixOfFactorSourceIDs { ConfirmationRoleWithFactorSourceIds::from( value.confirmation_role, ), - value.number_of_days_until_timed_confirmation_is_callable, + value.time_until_delayed_confirmation_is_callable, ) } } diff --git a/crates/profile/models/security-structures/src/time_period.rs b/crates/profile/models/security-structures/src/time_period.rs index 49a548ad6..fa9b729ff 100644 --- a/crates/profile/models/security-structures/src/time_period.rs +++ b/crates/profile/models/security-structures/src/time_period.rs @@ -3,14 +3,29 @@ use crate::prelude::*; /// Time period expressed by a number of `TimePeriodUnit`. /// /// Used to represent in the hosts UI the time period until recovery can be confirmed with timed based confirmation -#[derive(PartialEq, Eq, Clone, Copy, Debug)] +#[derive( + PartialEq, Eq, Clone, Copy, Debug, StdHash, Serialize, Deserialize, +)] pub struct TimePeriod { pub value: u16, pub unit: TimePeriodUnit, } impl TimePeriod { - pub fn with_days(value: u16) -> Self { + pub fn is_zero(&self) -> bool { + self.value == 0 + } + + pub fn in_minutes(&self) -> u32 { + match self.unit { + TimePeriodUnit::Days => self.value as u32 * MINUTES_PER_DAY, + TimePeriodUnit::Weeks => { + self.value as u32 * DAYS_PER_WEEK as u32 * MINUTES_PER_DAY + } + } + } + + pub const fn with_days(value: u16) -> Self { if (value % DAYS_PER_WEEK) == 0 { Self { value: value / DAYS_PER_WEEK, @@ -66,6 +81,21 @@ mod tests { assert_ne!(SUT::sample(), SUT::sample_other()); } + #[test] + fn is_zero() { + assert!(SUT::with_days(0).is_zero()); + } + + #[test] + fn day_in_minutes() { + assert_eq!(SUT::sample().in_minutes(), 1440); + } + + #[test] + fn week_in_minutes() { + assert_eq!(SUT::sample_other().in_minutes(), 10080); + } + #[test] fn days_conversion() { let mut sut = SUT::with_days(DAYS_PER_WEEK); @@ -82,4 +112,30 @@ mod tests { assert_eq!(sut.days(), 400); assert_eq!(sut.unit, TimePeriodUnit::Days); } + + #[test] + fn json_roundtrip_days() { + assert_eq_after_json_roundtrip( + &SUT::sample(), + r#" + { + "value": 1, + "unit": "days" + } + "#, + ); + } + + #[test] + fn json_roundtrip_weeks() { + assert_eq_after_json_roundtrip( + &SUT::sample_other(), + r#" + { + "value": 1, + "unit": "weeks" + } + "#, + ); + } } diff --git a/crates/profile/models/security-structures/src/time_period_unit.rs b/crates/profile/models/security-structures/src/time_period_unit.rs index 4232ed9a5..21b2f4ebd 100644 --- a/crates/profile/models/security-structures/src/time_period_unit.rs +++ b/crates/profile/models/security-structures/src/time_period_unit.rs @@ -3,9 +3,13 @@ use crate::prelude::*; /// Time period unit expressed in days, weeks, or years. /// /// Used to represent in the hosts UI the time period. -#[derive(PartialEq, Eq, Clone, Copy, Debug)] +#[derive( + PartialEq, Eq, Clone, Copy, Debug, StdHash, Serialize, Deserialize, +)] pub enum TimePeriodUnit { + #[serde(rename = "days")] Days, + #[serde(rename = "weeks")] Weeks, } @@ -36,4 +40,10 @@ mod tests { fn inequality() { assert_ne!(SUT::sample(), SUT::sample_other()); } + + #[test] + fn json_roundtrip() { + assert_json_value_eq_after_roundtrip(&SUT::Days, json!("days")); + assert_json_value_eq_after_roundtrip(&SUT::Weeks, json!("weeks")); + } } diff --git a/crates/system/os/factors/src/apply_security_shield/sargon_os_apply_shield.rs b/crates/system/os/factors/src/apply_security_shield/sargon_os_apply_shield.rs index 95482e7a1..54de073a6 100644 --- a/crates/system/os/factors/src/apply_security_shield/sargon_os_apply_shield.rs +++ b/crates/system/os/factors/src/apply_security_shield/sargon_os_apply_shield.rs @@ -390,7 +390,7 @@ pub(crate) fn unsafe_shield_with_bdfs( [], [id], ), - 14, + TimePeriod::with_days(14), ) }; SecurityStructureOfFactorSourceIds::new( diff --git a/crates/system/os/factors/src/test_instances_provider.rs b/crates/system/os/factors/src/test_instances_provider.rs index 2f4ac1675..7875050bf 100644 --- a/crates/system/os/factors/src/test_instances_provider.rs +++ b/crates/system/os/factors/src/test_instances_provider.rs @@ -404,7 +404,7 @@ async fn cache_is_unchanged_in_case_of_failure() { [], [bdfs.clone()], ), - 1, + TimePeriod::with_days(1), ) }; @@ -565,7 +565,7 @@ async fn test_assert_factor_instances_invalid() { [], [bdfs.clone()], ), - 1, + TimePeriod::with_days(1), ) }; @@ -916,7 +916,7 @@ async fn test_securified_accounts() { [], [bdfs.clone(), ledger.clone(), arculus.clone()], ), - 1, + TimePeriod::with_days(1), ) }; @@ -1066,7 +1066,7 @@ async fn test_securified_accounts() { [], [password.clone()], ), - 1, + TimePeriod::with_days(1), ) }; @@ -1210,7 +1210,7 @@ async fn securify_accounts_when_cache_is_half_full_single_factor_source() { [], [bdfs.clone()], ), - 1, + TimePeriod::with_days(1), ) }; @@ -1380,7 +1380,7 @@ async fn securify_accounts_when_cache_is_half_full_multiple_factor_sources() { [], [bdfs.clone(), ledger.clone(), arculus.clone()], ), - 1, + TimePeriod::with_days(1), ) }; @@ -1632,7 +1632,7 @@ async fn securify_personas_when_cache_is_half_full_single_factor_source() { [], [bdfs.clone()], ), - 1, + TimePeriod::with_days(1), ) }; @@ -1780,7 +1780,7 @@ async fn create_single_account() { [], [bdfs.clone()], ), - 1, + TimePeriod::with_days(1), ) }; @@ -1879,7 +1879,7 @@ async fn securified_personas() { [], [bdfs.clone(), ledger.clone(), arculus.clone()], ), - 1, + TimePeriod::with_days(1), ) }; @@ -2032,7 +2032,7 @@ async fn securified_personas() { [], [password.clone()], ), - 1, + TimePeriod::with_days(1), ) }; @@ -2208,7 +2208,7 @@ async fn securified_all_accounts_next_veci_does_not_start_at_zero() { [], [bdfs.clone()], ), - 1, + TimePeriod::with_days(1), ) }; @@ -2421,7 +2421,7 @@ async fn securified_accounts_and_personas_mixed_asymmetric_indices() { [], [bdfs.clone()], ), - 1, + TimePeriod::with_days(1), ) }; @@ -2455,8 +2455,6 @@ async fn securified_accounts_and_personas_mixed_asymmetric_indices() { .await .unwrap(); - println!("🔮🔮🔮🔮"); - for ui in updated_instances { println!( "{:?}", @@ -2478,7 +2476,6 @@ async fn securified_accounts_and_personas_mixed_asymmetric_indices() { .collect_vec() ); } - println!("🔮🔮🔮🔮"); assert!( !derivation_outcome.derived_any_new_instance_for_any_factor_source(), @@ -2577,7 +2574,7 @@ async fn securified_accounts_and_personas_mixed_asymmetric_indices() { [], [bdfs.clone(), arculus.clone()], ), - 1, + TimePeriod::with_days(1), ) }; @@ -2648,7 +2645,7 @@ async fn securified_accounts_and_personas_mixed_asymmetric_indices() { [], [bdfs.clone(), ledger.clone()], ), - 1, + TimePeriod::with_days(1), ) }; @@ -2762,7 +2759,7 @@ async fn securified_accounts_and_personas_mixed_asymmetric_indices() { [], [bdfs.clone(), ledger.clone(), arculus.clone()], ), - 1, + TimePeriod::with_days(1), ) }; diff --git a/crates/uniffi/uniffi_SPLIT_ME/src/profile/mfa/security_structures/matrices/decl_matrix_macro.rs b/crates/uniffi/uniffi_SPLIT_ME/src/profile/mfa/security_structures/matrices/decl_matrix_macro.rs index 2a511668d..643a58ced 100644 --- a/crates/uniffi/uniffi_SPLIT_ME/src/profile/mfa/security_structures/matrices/decl_matrix_macro.rs +++ b/crates/uniffi/uniffi_SPLIT_ME/src/profile/mfa/security_structures/matrices/decl_matrix_macro.rs @@ -25,7 +25,7 @@ macro_rules! matrix_conversion { pub recovery_role: #recovery_role_type, pub confirmation_role: #confirmation_role_type, - pub number_of_days_until_timed_confirmation_is_callable: u16, + pub time_until_delayed_confirmation_is_callable: TimePeriod, } delegate_debug_into!(#struct_name, #internal_struct_name); @@ -36,8 +36,8 @@ macro_rules! matrix_conversion { primary_role: value.primary().clone().into(), recovery_role: value.recovery().clone().into(), confirmation_role: value.confirmation().clone().into(), - number_of_days_until_timed_confirmation_is_callable: value - .number_of_days_until_timed_confirmation_is_callable, + time_until_delayed_confirmation_is_callable: value + .time_until_delayed_confirmation_is_callable.into(), } } } @@ -49,7 +49,7 @@ macro_rules! matrix_conversion { self.primary_role.clone().into(), self.recovery_role.clone().into(), self.confirmation_role.clone().into(), - self.number_of_days_until_timed_confirmation_is_callable, + self.time_until_delayed_confirmation_is_callable.into(), ) } } diff --git a/crates/uniffi/uniffi_SPLIT_ME/src/profile/mfa/security_structures/models/time_period.rs b/crates/uniffi/uniffi_SPLIT_ME/src/profile/mfa/security_structures/models/time_period.rs index 2a249fb4d..606b74e3f 100644 --- a/crates/uniffi/uniffi_SPLIT_ME/src/profile/mfa/security_structures/models/time_period.rs +++ b/crates/uniffi/uniffi_SPLIT_ME/src/profile/mfa/security_structures/models/time_period.rs @@ -4,7 +4,9 @@ use sargon::TimePeriod as InternalTimePeriod; /// Time period unit expressed in days, weeks, or years. /// /// Used to represent in the hosts UI the time period. -#[derive(Clone, PartialEq, Eq, Hash, InternalConversion, uniffi::Record)] +#[derive( + Clone, Debug, Copy, PartialEq, Eq, Hash, InternalConversion, uniffi::Record, +)] pub struct TimePeriod { /// The value of the time period. pub value: u16, diff --git a/crates/uniffi/uniffi_SPLIT_ME/src/profile/mfa/security_structures/security_shield_builder.rs b/crates/uniffi/uniffi_SPLIT_ME/src/profile/mfa/security_structures/security_shield_builder.rs index 9ffeb2c8f..ddb0d0e45 100644 --- a/crates/uniffi/uniffi_SPLIT_ME/src/profile/mfa/security_structures/security_shield_builder.rs +++ b/crates/uniffi/uniffi_SPLIT_ME/src/profile/mfa/security_structures/security_shield_builder.rs @@ -216,7 +216,7 @@ impl SecurityShieldBuilder { ) -> Arc { self.set(|builder| { builder.set_time_period_until_timed_confirmation_is_callable( - time_period.clone().into(), + time_period.into(), ) }) } @@ -971,11 +971,14 @@ mod tests { FactorSource::sample_ledger_other(), ]; let name = "Auto Built"; - let days_until_timed_confirmation = 237; + let days_until_timed_confirmation = TimePeriod { + value: 237, + unit: TimePeriodUnit::Days, + }; sut = sut .set_name(name.to_owned()) .set_time_period_until_timed_confirmation_is_callable( - new_time_period_with_days(days_until_timed_confirmation), + new_time_period_with_days(237), ) .add_factor_source_to_primary_threshold( FactorSource::sample_device_babylon().id(), @@ -993,7 +996,7 @@ mod tests { assert_eq!(shield.metadata.display_name.value, name.to_owned()); let matrix = shield.matrix_of_factors; assert_eq!( - matrix.number_of_days_until_timed_confirmation_is_callable, + matrix.time_until_delayed_confirmation_is_callable, days_until_timed_confirmation ); From be7fdcabebf51dcf9bcf8db4903ff8262fda7ce8 Mon Sep 17 00:00:00 2001 From: Alexander Cyon Date: Mon, 27 Jan 2025 08:47:15 +0100 Subject: [PATCH 19/25] simplify interaction to use Vec again --- .../batch_of_transactions.rs | 37 ++++-- ...f_transactions_applying_security_shield.rs | 110 ------------------ .../batch_of_transactions/mod.rs | 2 - ...on_os_apply_security_shield_interaction.rs | 33 ++---- .../batch_of_transactions.rs | 2 +- ...f_transactions_applying_security_shield.rs | 18 --- .../batch_of_transactions/mod.rs | 2 - ...let_interaction_batch_of_transactions.json | 86 +++----------- 8 files changed, 58 insertions(+), 232 deletions(-) delete mode 100644 crates/app/radix-connect/src/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/batch_of_transactions_applying_security_shield.rs delete mode 100644 crates/uniffi/uniffi_SPLIT_ME/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/batch_of_transactions_applying_security_shield.rs diff --git a/crates/app/radix-connect/src/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/batch_of_transactions.rs b/crates/app/radix-connect/src/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/batch_of_transactions.rs index 27b1a4a3a..b822d2f97 100644 --- a/crates/app/radix-connect/src/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/batch_of_transactions.rs +++ b/crates/app/radix-connect/src/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/batch_of_transactions.rs @@ -1,15 +1,15 @@ +use prelude::fixture_rtm; + use crate::prelude::*; #[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] pub struct DappToWalletInteractionBatchOfTransactions { - pub transactions: Vec, + pub transactions: Vec, } impl DappToWalletInteractionBatchOfTransactions { pub fn new( - transactions: impl IntoIterator< - Item = BatchOfTransactionsApplyingSecurityShield, - >, + transactions: impl IntoIterator, ) -> Self { Self { transactions: transactions.into_iter().collect(), @@ -19,14 +19,33 @@ impl DappToWalletInteractionBatchOfTransactions { impl HasSampleValues for DappToWalletInteractionBatchOfTransactions { fn sample() -> Self { - Self::new([ - BatchOfTransactionsApplyingSecurityShield::sample(), - BatchOfTransactionsApplyingSecurityShield::sample_other(), - ]) + let init_p_conf_r = TransactionManifest::new( + fixture_rtm!("update_shield_of_persona_init_with_P_confirm_with_R"), + NetworkID::Mainnet, + Blobs::default(), + ) + .unwrap(); + let unsecurified = TransactionManifest::new( + fixture_rtm!("create_access_controller_for_account"), + NetworkID::Mainnet, + Blobs::default(), + ) + .unwrap(); + Self::new( + [init_p_conf_r, unsecurified] + .map(UnvalidatedTransactionManifest::from), + ) } fn sample_other() -> Self { - Self::new([BatchOfTransactionsApplyingSecurityShield::sample_other()]) + let init_p_conf_c = TransactionManifest::new( + fixture_rtm!("update_shield_of_persona_init_with_P_confirm_with_R"), + NetworkID::Mainnet, + Blobs::default(), + ) + .unwrap(); + + Self::new([init_p_conf_c].map(UnvalidatedTransactionManifest::from)) } } diff --git a/crates/app/radix-connect/src/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/batch_of_transactions_applying_security_shield.rs b/crates/app/radix-connect/src/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/batch_of_transactions_applying_security_shield.rs deleted file mode 100644 index 973923b32..000000000 --- a/crates/app/radix-connect/src/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/batch_of_transactions_applying_security_shield.rs +++ /dev/null @@ -1,110 +0,0 @@ -use prelude::fixture_rtm; - -use crate::prelude::*; - -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] -pub struct BatchOfTransactionsApplyingSecurityShield { - /// The ID of security shield being applied - pub shield_id: SecurityStructureID, - - /// The address of the entity for which we apply the security shield. - pub entity_address: AddressOfAccountOrPersona, - - /// This Vec will contain a single TransactionManifest if entity identified - /// by entity_address is unsecurified, but if it is securified it will contain - /// `RolesExercisableInTransactionManifestCombination::all().len()` many - /// TransactionManifests - pub transactions: Vec, -} - -impl BatchOfTransactionsApplyingSecurityShield { - pub fn new( - shield_id: SecurityStructureID, - entity_address: AddressOfAccountOrPersona, - transactions: impl IntoIterator, - ) -> Self { - Self { - shield_id, - entity_address, - transactions: transactions.into_iter().collect(), - } - } -} -impl HasSampleValues for BatchOfTransactionsApplyingSecurityShield { - fn sample() -> Self { - let init_p_conf_r = TransactionManifest::new( - fixture_rtm!("update_shield_of_persona_init_with_P_confirm_with_R"), - NetworkID::Mainnet, - Blobs::default(), - ) - .unwrap(); - let init_p_conf_c = TransactionManifest::new( - fixture_rtm!("update_shield_of_persona_init_with_P_confirm_with_C"), - NetworkID::Mainnet, - Blobs::default(), - ) - .unwrap(); - let init_p_conf_t = TransactionManifest::new( - fixture_rtm!("update_shield_of_persona_init_with_P_confirm_with_T"), - NetworkID::Mainnet, - Blobs::default(), - ) - .unwrap(); - - let init_r_conf_c = TransactionManifest::new( - fixture_rtm!("update_shield_of_persona_init_with_R_confirm_with_C"), - NetworkID::Mainnet, - Blobs::default(), - ) - .unwrap(); - let init_r_conf_t = TransactionManifest::new( - fixture_rtm!("update_shield_of_persona_init_with_R_confirm_with_T"), - NetworkID::Mainnet, - Blobs::default(), - ) - .unwrap(); - Self::new( - SecurityStructureID::sample(), - IdentityAddress::sample_mainnet().into(), - [ - init_p_conf_r, - init_p_conf_c, - init_p_conf_t, - init_r_conf_c, - init_r_conf_t, - ] - .into_iter() - .map(Into::into), - ) - } - - fn sample_other() -> Self { - let unsecurified = TransactionManifest::new( - fixture_rtm!("create_access_controller_for_account"), - NetworkID::Mainnet, - Blobs::default(), - ) - .unwrap(); - Self::new(SecurityStructureID::sample(), "account_rdx128dtethfy8ujrsfdztemyjk0kvhnah6dafr57frz85dcw2c8z0td87".parse().unwrap(), [ - unsecurified - ].into_iter().map(Into::into),) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[allow(clippy::upper_case_acronyms)] - type SUT = BatchOfTransactionsApplyingSecurityShield; - - #[test] - fn equality() { - assert_eq!(SUT::sample(), SUT::sample()); - } - - #[test] - fn inequality() { - assert_ne!(SUT::sample(), SUT::sample_other()); - } -} diff --git a/crates/app/radix-connect/src/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/mod.rs b/crates/app/radix-connect/src/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/mod.rs index 8de5df34f..ea996a5c3 100644 --- a/crates/app/radix-connect/src/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/mod.rs +++ b/crates/app/radix-connect/src/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/mod.rs @@ -1,6 +1,4 @@ #[allow(clippy::module_inception)] mod batch_of_transactions; -mod batch_of_transactions_applying_security_shield; pub use batch_of_transactions::*; -pub use batch_of_transactions_applying_security_shield::*; diff --git a/crates/system/os/factors/src/apply_security_shield/sargon_os_apply_security_shield_interaction.rs b/crates/system/os/factors/src/apply_security_shield/sargon_os_apply_security_shield_interaction.rs index f83b8aad1..996687845 100644 --- a/crates/system/os/factors/src/apply_security_shield/sargon_os_apply_security_shield_interaction.rs +++ b/crates/system/os/factors/src/apply_security_shield/sargon_os_apply_security_shield_interaction.rs @@ -1,8 +1,5 @@ use crate::prelude::*; -use radix_connect::{ - BatchOfTransactionsApplyingSecurityShield, - DappToWalletInteractionBatchOfTransactions, -}; +use radix_connect::DappToWalletInteractionBatchOfTransactions; #[async_trait::async_trait] pub trait OsApplySecurityShieldInteraction { @@ -36,10 +33,8 @@ impl OsApplySecurityShieldInteraction for SargonOS { TransactionManifest::apply_security_shield_for_unsecurified_entity( e.clone(), derived.clone() - ).map(|manifest| { - BatchOfTransactionsApplyingSecurityShield::new(derived.security_structure_id, e.address(), [UnvalidatedTransactionManifest::from(manifest)]) - }) - }).collect::>>()?; + ).map(UnvalidatedTransactionManifest::from) + }).collect::>>()?; let manifests_for_securified = entities_with_provisional .securified_erased() @@ -47,21 +42,13 @@ impl OsApplySecurityShieldInteraction for SargonOS { .map(|e| { let provisional = e.entity.get_provisional().expect("Entity should have a provisional config set since we applied shield above"); let derived = provisional.as_factor_instances_derived().expect("Should have derived factors"); - - let manifests = RolesExercisableInTransactionManifestCombination::all() - .into_iter() - .filter_map(|combination| { - TransactionManifest::apply_security_shield_for_securified_entity( - e.clone(), - derived.clone(), - combination - ) - }) - .map(UnvalidatedTransactionManifest::from) - .collect::>(); - - BatchOfTransactionsApplyingSecurityShield::new(derived.security_structure_id, e.address(), manifests) - }).collect::>(); + TransactionManifest::apply_security_shield_for_securified_entity( + e.clone(), + derived.clone(), + RolesExercisableInTransactionManifestCombination::default() + ) + .map(UnvalidatedTransactionManifest::from).unwrap() + }).collect_vec(); Ok(DappToWalletInteractionBatchOfTransactions::new( manifests_for_unsecurified diff --git a/crates/uniffi/uniffi_SPLIT_ME/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/batch_of_transactions.rs b/crates/uniffi/uniffi_SPLIT_ME/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/batch_of_transactions.rs index 12556650f..bc9eb7e24 100644 --- a/crates/uniffi/uniffi_SPLIT_ME/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/batch_of_transactions.rs +++ b/crates/uniffi/uniffi_SPLIT_ME/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/batch_of_transactions.rs @@ -3,5 +3,5 @@ use sargon::DappToWalletInteractionBatchOfTransactions as InternalDappToWalletIn #[derive(Clone, PartialEq, InternalConversion, uniffi::Record)] pub struct DappToWalletInteractionBatchOfTransactions { - pub transactions: Vec, + pub transactions: Vec, } diff --git a/crates/uniffi/uniffi_SPLIT_ME/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/batch_of_transactions_applying_security_shield.rs b/crates/uniffi/uniffi_SPLIT_ME/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/batch_of_transactions_applying_security_shield.rs deleted file mode 100644 index 3f38195ac..000000000 --- a/crates/uniffi/uniffi_SPLIT_ME/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/batch_of_transactions_applying_security_shield.rs +++ /dev/null @@ -1,18 +0,0 @@ -use crate::prelude::*; - -use sargon::BatchOfTransactionsApplyingSecurityShield as InternalBatchOfTransactionsApplyingSecurityShield; - -#[derive(Clone, PartialEq, InternalConversion, uniffi::Record)] -pub struct BatchOfTransactionsApplyingSecurityShield { - /// The ID of security shield being applied - pub shield_id: SecurityStructureID, - - /// The address of the entity for which we apply the security shield. - pub entity_address: AddressOfAccountOrPersona, - - /// This Vec will contain a single TransactionManifest if entity identified - /// by entity_address is unsecurified, but if it is securified it will contain - /// `RolesExercisableInTransactionManifestCombination::all().len()` many - /// TransactionManifests - pub transactions: Vec, -} diff --git a/crates/uniffi/uniffi_SPLIT_ME/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/mod.rs b/crates/uniffi/uniffi_SPLIT_ME/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/mod.rs index 8de5df34f..ea996a5c3 100644 --- a/crates/uniffi/uniffi_SPLIT_ME/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/mod.rs +++ b/crates/uniffi/uniffi_SPLIT_ME/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/mod.rs @@ -1,6 +1,4 @@ #[allow(clippy::module_inception)] mod batch_of_transactions; -mod batch_of_transactions_applying_security_shield; pub use batch_of_transactions::*; -pub use batch_of_transactions_applying_security_shield::*; diff --git a/fixtures/models/interaction/wallet_interaction_batch_of_transactions.json b/fixtures/models/interaction/wallet_interaction_batch_of_transactions.json index 1e21762e0..ac75066cd 100644 --- a/fixtures/models/interaction/wallet_interaction_batch_of_transactions.json +++ b/fixtures/models/interaction/wallet_interaction_batch_of_transactions.json @@ -1,68 +1,20 @@ { - "transactions": [ - { - "shield_id": "ffffffff-ffff-ffff-ffff-ffffffffffff", - "entity_address": "account_rdx128mh2ae9dsrwa0t8l37ayjrxxf0p84e6qm227ytxtcu447f5uw5m8w", - "transactions": [ - { - "transactionManifest": "CALL_METHOD\n Address(\"account_rdx128mh2ae9dsrwa0t8l37ayjrxxf0p84e6qm227ytxtcu447f5uw5m8w\")\n \"securify\"\n;\nTAKE_FROM_WORKTOP\n Address(\"resource_rdx1nfxxxxxxxxxxaccwnrxxxxxxxxx006664022062xxxxxxxxxaccwnr\")\n Decimal(\"1\")\n Bucket(\"bucket1\")\n;\nALLOCATE_GLOBAL_ADDRESS\n Address(\"package_rdx1pkgxxxxxxxxxcntrlrxxxxxxxxx000648572295xxxxxxxxxcntrlr\")\n \"AccessController\"\n AddressReservation(\"reservation1\")\n NamedAddress(\"address1\")\n;\nCREATE_ACCESS_CONTROLLER\n Bucket(\"bucket1\")\n Tuple(\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[0e8695a4117774464ca04bb6d10ce0b11aede12bd797dcdee811067094]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[0e8695a4117774464ca04bb6d10ce0b11aede12bd797dcdee811067094]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[0e8695a4117774464ca04bb6d10ce0b11aede12bd797dcdee811067094]\")\n )\n )\n )\n )\n )\n )\n )\n )\n Enum<1u8>(\n 20160u32\n )\n Enum<1u8>(\n AddressReservation(\"reservation1\")\n )\n;\nSET_METADATA\n Address(\"account_rdx128mh2ae9dsrwa0t8l37ayjrxxf0p84e6qm227ytxtcu447f5uw5m8w\")\n \"owner_keys\"\n Enum<143u8>(\n Array(\n Enum<1u8>(\n Bytes(\"8e7da995687de79d87a51e4acadccbeea15df2b165800247930298bc16\")\n )\n )\n )\n;\n", - "blobs": [] - } - ] - }, - { - "shield_id": "ffffffff-ffff-ffff-ffff-ffffffffffff", - "entity_address": "identity_rdx122kkqj7pc04gwsgcwsxmfmknlsg4qpz52rrs6vj72cujks4ukw993v", - "transactions": [ - { - "transactionManifest": "CALL_METHOD\n Address(\"identity_rdx122kkqj7pc04gwsgcwsxmfmknlsg4qpz52rrs6vj72cujks4ukw993v\")\n \"securify\"\n;\nTAKE_FROM_WORKTOP\n Address(\"resource_rdx1nfxxxxxxxxxxdntwnrxxxxxxxxx002876444928xxxxxxxxxdntwnr\")\n Decimal(\"1\")\n Bucket(\"bucket1\")\n;\nALLOCATE_GLOBAL_ADDRESS\n Address(\"package_rdx1pkgxxxxxxxxxcntrlrxxxxxxxxx000648572295xxxxxxxxxcntrlr\")\n \"AccessController\"\n AddressReservation(\"reservation1\")\n NamedAddress(\"address1\")\n;\nCREATE_ACCESS_CONTROLLER\n Bucket(\"bucket1\")\n Tuple(\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[0b5896b1b5a1de8573b3a90216e7b14b42aa11746ad2e0bcb0741c216d]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[0b5896b1b5a1de8573b3a90216e7b14b42aa11746ad2e0bcb0741c216d]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[0b5896b1b5a1de8573b3a90216e7b14b42aa11746ad2e0bcb0741c216d]\")\n )\n )\n )\n )\n )\n )\n )\n )\n Enum<1u8>(\n 20160u32\n )\n Enum<1u8>(\n AddressReservation(\"reservation1\")\n )\n;\nSET_METADATA\n Address(\"identity_rdx122kkqj7pc04gwsgcwsxmfmknlsg4qpz52rrs6vj72cujks4ukw993v\")\n \"owner_keys\"\n Enum<143u8>(\n Array(\n Enum<1u8>(\n Bytes(\"a9a3197f2553f4cfe4603e77fd1802f14490862e11a33d81c98c430e31\")\n )\n )\n )\n;\n", - "blobs": [] - } - ] - }, - { - "shield_id": "ffffffff-ffff-ffff-ffff-ffffffffffff", - "entity_address": "account_rdx12xek3geay25lktmk5zyplc7z7mg5xe8ldh48ta4mkcd9q0v0q6l8y6", - "transactions": [ - { - "transactionManifest": "CALL_METHOD\n Address(\"accesscontroller_rdx1c0duj4lq0dc3cpl8qd420fpn5eckh8ljeysvjm894lyl5ja5yq6y5a\")\n \"initiate_recovery_as_primary\"\n Tuple(\n Tuple(\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[bfcba3ae8b30485830dc1dc578b2f921b1b65cb2a391cb063c0f1b6106]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[bfcba3ae8b30485830dc1dc578b2f921b1b65cb2a391cb063c0f1b6106]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[bfcba3ae8b30485830dc1dc578b2f921b1b65cb2a391cb063c0f1b6106]\")\n )\n )\n )\n )\n )\n )\n )\n ),\n Enum<1u8>(\n 20160u32\n )\n )\n;\nCALL_METHOD\n Address(\"accesscontroller_rdx1c0duj4lq0dc3cpl8qd420fpn5eckh8ljeysvjm894lyl5ja5yq6y5a\")\n \"quick_confirm_primary_role_recovery_proposal\"\n Tuple(\n Tuple(\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[bfcba3ae8b30485830dc1dc578b2f921b1b65cb2a391cb063c0f1b6106]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[bfcba3ae8b30485830dc1dc578b2f921b1b65cb2a391cb063c0f1b6106]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[bfcba3ae8b30485830dc1dc578b2f921b1b65cb2a391cb063c0f1b6106]\")\n )\n )\n )\n )\n )\n )\n )\n ),\n Enum<1u8>(\n 20160u32\n )\n )\n;\nSET_METADATA\n Address(\"account_rdx12xek3geay25lktmk5zyplc7z7mg5xe8ldh48ta4mkcd9q0v0q6l8y6\")\n \"owner_keys\"\n Enum<143u8>(\n Array(\n Enum<1u8>(\n Bytes(\"e2e27b925c7d98ebe436172f00b024862127b26b40decd416ca41cdb48\")\n )\n )\n )\n;\n", - "blobs": [] - }, - { - "transactionManifest": "CALL_METHOD\n Address(\"accesscontroller_rdx1c0duj4lq0dc3cpl8qd420fpn5eckh8ljeysvjm894lyl5ja5yq6y5a\")\n \"initiate_recovery_as_primary\"\n Tuple(\n Tuple(\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[bfcba3ae8b30485830dc1dc578b2f921b1b65cb2a391cb063c0f1b6106]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[bfcba3ae8b30485830dc1dc578b2f921b1b65cb2a391cb063c0f1b6106]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[bfcba3ae8b30485830dc1dc578b2f921b1b65cb2a391cb063c0f1b6106]\")\n )\n )\n )\n )\n )\n )\n )\n ),\n Enum<1u8>(\n 20160u32\n )\n )\n;\nCALL_METHOD\n Address(\"accesscontroller_rdx1c0duj4lq0dc3cpl8qd420fpn5eckh8ljeysvjm894lyl5ja5yq6y5a\")\n \"quick_confirm_primary_role_recovery_proposal\"\n Tuple(\n Tuple(\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[bfcba3ae8b30485830dc1dc578b2f921b1b65cb2a391cb063c0f1b6106]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[bfcba3ae8b30485830dc1dc578b2f921b1b65cb2a391cb063c0f1b6106]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[bfcba3ae8b30485830dc1dc578b2f921b1b65cb2a391cb063c0f1b6106]\")\n )\n )\n )\n )\n )\n )\n )\n ),\n Enum<1u8>(\n 20160u32\n )\n )\n;\nSET_METADATA\n Address(\"account_rdx12xek3geay25lktmk5zyplc7z7mg5xe8ldh48ta4mkcd9q0v0q6l8y6\")\n \"owner_keys\"\n Enum<143u8>(\n Array(\n Enum<1u8>(\n Bytes(\"e2e27b925c7d98ebe436172f00b024862127b26b40decd416ca41cdb48\")\n )\n )\n )\n;\n", - "blobs": [] - }, - { - "transactionManifest": "CALL_METHOD\n Address(\"accesscontroller_rdx1c0duj4lq0dc3cpl8qd420fpn5eckh8ljeysvjm894lyl5ja5yq6y5a\")\n \"initiate_recovery_as_primary\"\n Tuple(\n Tuple(\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[bfcba3ae8b30485830dc1dc578b2f921b1b65cb2a391cb063c0f1b6106]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[bfcba3ae8b30485830dc1dc578b2f921b1b65cb2a391cb063c0f1b6106]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[bfcba3ae8b30485830dc1dc578b2f921b1b65cb2a391cb063c0f1b6106]\")\n )\n )\n )\n )\n )\n )\n )\n ),\n Enum<1u8>(\n 20160u32\n )\n )\n;\nSET_METADATA\n Address(\"account_rdx12xek3geay25lktmk5zyplc7z7mg5xe8ldh48ta4mkcd9q0v0q6l8y6\")\n \"owner_keys\"\n Enum<143u8>(\n Array(\n Enum<1u8>(\n Bytes(\"e2e27b925c7d98ebe436172f00b024862127b26b40decd416ca41cdb48\")\n )\n )\n )\n;\n", - "blobs": [] - } - ] - }, - { - "shield_id": "ffffffff-ffff-ffff-ffff-ffffffffffff", - "entity_address": "identity_rdx12fhyj4l6k63p3hhvgczhr8c6w697tv3eudn7ndsn2hphrkm7thupd4", - "transactions": [ - { - "transactionManifest": "CALL_METHOD\n Address(\"accesscontroller_rdx1cv93xuha64eay8ctkx9km0el2jgkuh6gqlwec7tzecccyu0rj37xak\")\n \"initiate_recovery_as_primary\"\n Tuple(\n Tuple(\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n )\n ),\n Enum<1u8>(\n 20160u32\n )\n )\n;\nCALL_METHOD\n Address(\"accesscontroller_rdx1cv93xuha64eay8ctkx9km0el2jgkuh6gqlwec7tzecccyu0rj37xak\")\n \"quick_confirm_primary_role_recovery_proposal\"\n Tuple(\n Tuple(\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n )\n ),\n Enum<1u8>(\n 20160u32\n )\n )\n;\n", - "blobs": [] - }, - { - "transactionManifest": "CALL_METHOD\n Address(\"accesscontroller_rdx1cv93xuha64eay8ctkx9km0el2jgkuh6gqlwec7tzecccyu0rj37xak\")\n \"initiate_recovery_as_primary\"\n Tuple(\n Tuple(\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n )\n ),\n Enum<1u8>(\n 20160u32\n )\n )\n;\nCALL_METHOD\n Address(\"accesscontroller_rdx1cv93xuha64eay8ctkx9km0el2jgkuh6gqlwec7tzecccyu0rj37xak\")\n \"quick_confirm_primary_role_recovery_proposal\"\n Tuple(\n Tuple(\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n )\n ),\n Enum<1u8>(\n 20160u32\n )\n )\n;\n", - "blobs": [] - }, - { - "transactionManifest": "CALL_METHOD\n Address(\"accesscontroller_rdx1cv93xuha64eay8ctkx9km0el2jgkuh6gqlwec7tzecccyu0rj37xak\")\n \"initiate_recovery_as_recovery\"\n Tuple(\n Tuple(\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n )\n ),\n Enum<1u8>(\n 20160u32\n )\n )\n;\nCALL_METHOD\n Address(\"accesscontroller_rdx1cv93xuha64eay8ctkx9km0el2jgkuh6gqlwec7tzecccyu0rj37xak\")\n \"quick_confirm_recovery_role_recovery_proposal\"\n Tuple(\n Tuple(\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n )\n ),\n Enum<1u8>(\n 20160u32\n )\n )\n;\n", - "blobs": [] - }, - { - "transactionManifest": "CALL_METHOD\n Address(\"accesscontroller_rdx1cv93xuha64eay8ctkx9km0el2jgkuh6gqlwec7tzecccyu0rj37xak\")\n \"initiate_recovery_as_recovery\"\n Tuple(\n Tuple(\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n )\n ),\n Enum<1u8>(\n 20160u32\n )\n )\n;\n", - "blobs": [] - }, - { - "transactionManifest": "CALL_METHOD\n Address(\"accesscontroller_rdx1cv93xuha64eay8ctkx9km0el2jgkuh6gqlwec7tzecccyu0rj37xak\")\n \"initiate_recovery_as_primary\"\n Tuple(\n Tuple(\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n )\n ),\n Enum<1u8>(\n 20160u32\n )\n )\n;\n", - "blobs": [] - } - ] - } - ] - } \ No newline at end of file + "transactions": [ + { + "transactionManifest": "CALL_METHOD\n Address(\"account_rdx128mh2ae9dsrwa0t8l37ayjrxxf0p84e6qm227ytxtcu447f5uw5m8w\")\n \"securify\"\n;\nTAKE_FROM_WORKTOP\n Address(\"resource_rdx1nfxxxxxxxxxxaccwnrxxxxxxxxx006664022062xxxxxxxxxaccwnr\")\n Decimal(\"1\")\n Bucket(\"bucket1\")\n;\nALLOCATE_GLOBAL_ADDRESS\n Address(\"package_rdx1pkgxxxxxxxxxcntrlrxxxxxxxxx000648572295xxxxxxxxxcntrlr\")\n \"AccessController\"\n AddressReservation(\"reservation1\")\n NamedAddress(\"address1\")\n;\nCREATE_ACCESS_CONTROLLER\n Bucket(\"bucket1\")\n Tuple(\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[0e8695a4117774464ca04bb6d10ce0b11aede12bd797dcdee811067094]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[0e8695a4117774464ca04bb6d10ce0b11aede12bd797dcdee811067094]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[0e8695a4117774464ca04bb6d10ce0b11aede12bd797dcdee811067094]\")\n )\n )\n )\n )\n )\n )\n )\n )\n Enum<1u8>(\n 20160u32\n )\n Enum<1u8>(\n AddressReservation(\"reservation1\")\n )\n;\nSET_METADATA\n Address(\"account_rdx128mh2ae9dsrwa0t8l37ayjrxxf0p84e6qm227ytxtcu447f5uw5m8w\")\n \"owner_keys\"\n Enum<143u8>(\n Array(\n Enum<1u8>(\n Bytes(\"8e7da995687de79d87a51e4acadccbeea15df2b165800247930298bc16\")\n )\n )\n )\n;\n", + "blobs": [] + }, + { + "transactionManifest": "CALL_METHOD\n Address(\"identity_rdx122kkqj7pc04gwsgcwsxmfmknlsg4qpz52rrs6vj72cujks4ukw993v\")\n \"securify\"\n;\nTAKE_FROM_WORKTOP\n Address(\"resource_rdx1nfxxxxxxxxxxdntwnrxxxxxxxxx002876444928xxxxxxxxxdntwnr\")\n Decimal(\"1\")\n Bucket(\"bucket1\")\n;\nALLOCATE_GLOBAL_ADDRESS\n Address(\"package_rdx1pkgxxxxxxxxxcntrlrxxxxxxxxx000648572295xxxxxxxxxcntrlr\")\n \"AccessController\"\n AddressReservation(\"reservation1\")\n NamedAddress(\"address1\")\n;\nCREATE_ACCESS_CONTROLLER\n Bucket(\"bucket1\")\n Tuple(\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[0b5896b1b5a1de8573b3a90216e7b14b42aa11746ad2e0bcb0741c216d]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[0b5896b1b5a1de8573b3a90216e7b14b42aa11746ad2e0bcb0741c216d]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[0b5896b1b5a1de8573b3a90216e7b14b42aa11746ad2e0bcb0741c216d]\")\n )\n )\n )\n )\n )\n )\n )\n )\n Enum<1u8>(\n 20160u32\n )\n Enum<1u8>(\n AddressReservation(\"reservation1\")\n )\n;\nSET_METADATA\n Address(\"identity_rdx122kkqj7pc04gwsgcwsxmfmknlsg4qpz52rrs6vj72cujks4ukw993v\")\n \"owner_keys\"\n Enum<143u8>(\n Array(\n Enum<1u8>(\n Bytes(\"a9a3197f2553f4cfe4603e77fd1802f14490862e11a33d81c98c430e31\")\n )\n )\n )\n;\n", + "blobs": [] + }, + { + "transactionManifest": "CALL_METHOD\n Address(\"accesscontroller_rdx1c0duj4lq0dc3cpl8qd420fpn5eckh8ljeysvjm894lyl5ja5yq6y5a\")\n \"initiate_recovery_as_primary\"\n Tuple(\n Tuple(\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[bfcba3ae8b30485830dc1dc578b2f921b1b65cb2a391cb063c0f1b6106]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[bfcba3ae8b30485830dc1dc578b2f921b1b65cb2a391cb063c0f1b6106]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[bfcba3ae8b30485830dc1dc578b2f921b1b65cb2a391cb063c0f1b6106]\")\n )\n )\n )\n )\n )\n )\n )\n ),\n Enum<1u8>(\n 20160u32\n )\n )\n;\nCALL_METHOD\n Address(\"accesscontroller_rdx1c0duj4lq0dc3cpl8qd420fpn5eckh8ljeysvjm894lyl5ja5yq6y5a\")\n \"quick_confirm_primary_role_recovery_proposal\"\n Tuple(\n Tuple(\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[bfcba3ae8b30485830dc1dc578b2f921b1b65cb2a391cb063c0f1b6106]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[bfcba3ae8b30485830dc1dc578b2f921b1b65cb2a391cb063c0f1b6106]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[bfcba3ae8b30485830dc1dc578b2f921b1b65cb2a391cb063c0f1b6106]\")\n )\n )\n )\n )\n )\n )\n )\n ),\n Enum<1u8>(\n 20160u32\n )\n )\n;\nSET_METADATA\n Address(\"account_rdx12xek3geay25lktmk5zyplc7z7mg5xe8ldh48ta4mkcd9q0v0q6l8y6\")\n \"owner_keys\"\n Enum<143u8>(\n Array(\n Enum<1u8>(\n Bytes(\"e2e27b925c7d98ebe436172f00b024862127b26b40decd416ca41cdb48\")\n )\n )\n )\n;\n", + "blobs": [] + }, + { + "transactionManifest": "CALL_METHOD\n Address(\"accesscontroller_rdx1cv93xuha64eay8ctkx9km0el2jgkuh6gqlwec7tzecccyu0rj37xak\")\n \"initiate_recovery_as_primary\"\n Tuple(\n Tuple(\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n )\n ),\n Enum<1u8>(\n 20160u32\n )\n )\n;\nCALL_METHOD\n Address(\"accesscontroller_rdx1cv93xuha64eay8ctkx9km0el2jgkuh6gqlwec7tzecccyu0rj37xak\")\n \"quick_confirm_primary_role_recovery_proposal\"\n Tuple(\n Tuple(\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n )\n ),\n Enum<1u8>(\n 20160u32\n )\n )\n;\n", + "blobs": [] + } + ] +} \ No newline at end of file From f567ae30681d547c18e2f052b8334874dbaff695 Mon Sep 17 00:00:00 2001 From: Alexander Cyon Date: Mon, 27 Jan 2025 09:00:36 +0100 Subject: [PATCH 20/25] doc --- ...on_os_apply_security_shield_interaction.rs | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/crates/system/os/factors/src/apply_security_shield/sargon_os_apply_security_shield_interaction.rs b/crates/system/os/factors/src/apply_security_shield/sargon_os_apply_security_shield_interaction.rs index 996687845..16577a429 100644 --- a/crates/system/os/factors/src/apply_security_shield/sargon_os_apply_security_shield_interaction.rs +++ b/crates/system/os/factors/src/apply_security_shield/sargon_os_apply_security_shield_interaction.rs @@ -3,6 +3,35 @@ use radix_connect::DappToWalletInteractionBatchOfTransactions; #[async_trait::async_trait] pub trait OsApplySecurityShieldInteraction { + /// For every entity in the given set of addresses, we use FactorInstancesProvider + /// to create `SecurityStructureOfFactorInstances` based on the security shield + /// loaded by the given `security_shield_id`. We update Profile to set + /// a provisional security config with the derived factors. + /// + /// We then create one TransactionManifest for each entity, if the entity + /// is unsecurified it will be a Manifest which calls "securify" on the + /// component and creates an AccessController for it. If the entity is already + /// securified, we will create a Manifest which uses default `RolesExercisableInTransactionManifestCombination` + /// to update the security config. + /// + /// These manifests are not fully valid yet - we need to set a payer of XRD + /// vault top up and TX fee - which uses different logic depending on if + /// the entity applying the shield is securified or not. If it is securified + /// we will need to lock fee against the XRD vault of the AccessController - + /// if the entity is unsecurified we will need to lock fee against the account + /// address if it is an account - if it is a Persona another account - securified + /// or not - will need to be used to pay TX fee. + /// + /// Host should present these manifests to the user for approval, and then + /// display necessary input UI components for payer and fee locking - and then + /// host need to tell Sargon to create many more manifest for each securified + /// entity, `RolesExercisableInTransactionManifestCombination::all() - 1` more + /// manifests need to be created and set payer and fee locking for each of them. + /// + /// When user slides to sign - Sargon will try to batch sign each kind of manifest + /// based on `RolesExercisableInTransactionManifestCombination` for the securified + /// entities - and for the unsecurified entities the Primary role will always + /// be used. async fn make_interaction_for_applying_security_shield( &self, security_shield_id: SecurityStructureID, From 79ef5a7d234edbc20731cc45b5b3a49f17134d99 Mon Sep 17 00:00:00 2001 From: Alexander Cyon Date: Mon, 27 Jan 2025 12:09:10 +0100 Subject: [PATCH 21/25] try fix swift tests --- ...FileSystemDriver+Data+ContentsOf+URL.swift | 2 +- .../UnsafeStorageDriver+UserDefaults.swift | 2 +- .../MFA/SecurityShieldBuilder+Swifified.swift | 4 +- .../Sargon/Protocols/EntityProtocol.swift | 5 +- .../SargonOS/TestOSTests.swift | 1 + .../Profile/Collection/AccountsTests.swift | 3 ++ .../Collection/FactorSourcesTests.swift | 4 ++ .../Factor/DeviceFactorSourceTests.swift | 1 + .../MFA/SecurityShieldsBuilderTests.swift | 54 +++++++++++++------ .../TestCases/Profile/ProfileTests.swift | 10 ++-- ...WalletToDappInteractionResponseTests.swift | 7 ++- .../Utils/Extensions/UUID+Literals.swift | 6 ++- apple/Tests/Utils/Test.swift | 24 ++++++--- .../abstract_matrix_builder_or_built.rs | 2 +- .../matrices/builder/matrix_builder.rs | 2 +- .../builder/matrix_builder_unit_tests.rs | 4 +- .../matrices/builder/matrix_template.rs | 2 +- .../matrices/matrix_of_factor_source_ids.rs | 4 +- .../security_shield_builder.rs | 18 +++---- ...fests_securify_shield_securified_entity.rs | 16 +++--- ...ble_in_transaction_manifest_combination.rs | 42 +++++++-------- ..._entity_owner_badge_into_bucket_putting.rs | 2 +- .../security_shield_builder.rs | 20 +++---- 23 files changed, 136 insertions(+), 99 deletions(-) diff --git a/apple/Sources/Sargon/Drivers/FileSystem/FileSystemDriver+Data+ContentsOf+URL.swift b/apple/Sources/Sargon/Drivers/FileSystem/FileSystemDriver+Data+ContentsOf+URL.swift index c4dd11d74..ec2f4b9aa 100644 --- a/apple/Sources/Sargon/Drivers/FileSystem/FileSystemDriver+Data+ContentsOf+URL.swift +++ b/apple/Sources/Sargon/Drivers/FileSystem/FileSystemDriver+Data+ContentsOf+URL.swift @@ -2,7 +2,7 @@ import Foundation import SargonUniFFI // MARK: - FileManager + @unchecked Sendable -extension FileManager: @unchecked Sendable {} +extension FileManager: @unchecked @retroactive Sendable {} // Makes it possible to type `.shared` on an initalizer/func taking // `some FileSystemDriver` as parameter. diff --git a/apple/Sources/Sargon/Drivers/UnsafeStorage/UnsafeStorageDriver+UserDefaults.swift b/apple/Sources/Sargon/Drivers/UnsafeStorage/UnsafeStorageDriver+UserDefaults.swift index 497e6a90a..eabb4f0e3 100644 --- a/apple/Sources/Sargon/Drivers/UnsafeStorage/UnsafeStorageDriver+UserDefaults.swift +++ b/apple/Sources/Sargon/Drivers/UnsafeStorage/UnsafeStorageDriver+UserDefaults.swift @@ -2,7 +2,7 @@ import Foundation import SargonUniFFI // MARK: - UserDefaults + @unchecked Sendable -extension UserDefaults: @unchecked Sendable {} +extension UserDefaults: @unchecked @retroactive Sendable {} // Makes it possible to type `.shared` on an initalizer/func taking // `some UnsafeStorageDriver` as parameter. diff --git a/apple/Sources/Sargon/Extensions/Swiftified/Profile/MFA/SecurityShieldBuilder+Swifified.swift b/apple/Sources/Sargon/Extensions/Swiftified/Profile/MFA/SecurityShieldBuilder+Swifified.swift index a82b1d474..696d17aa5 100644 --- a/apple/Sources/Sargon/Extensions/Swiftified/Profile/MFA/SecurityShieldBuilder+Swifified.swift +++ b/apple/Sources/Sargon/Extensions/Swiftified/Profile/MFA/SecurityShieldBuilder+Swifified.swift @@ -4,8 +4,8 @@ extension SecurityShieldBuilder { public typealias Factor = FactorSourceID /// Confirmation Role - public var timePeriodUntilAutoConfirm: TimePeriod { - getTimePeriodUntilAutoConfirm() + public var timeUntilTimedConfirmationIsCallable: TimePeriod { + getTimeUntilTimedConfirmationIsCallable() } public var threshold: Threshold { diff --git a/apple/Sources/Sargon/Protocols/EntityProtocol.swift b/apple/Sources/Sargon/Protocols/EntityProtocol.swift index 8c151dda3..83e3ceb8a 100644 --- a/apple/Sources/Sargon/Protocols/EntityProtocol.swift +++ b/apple/Sources/Sargon/Protocols/EntityProtocol.swift @@ -43,7 +43,6 @@ extension EntityBaseProtocol { flags.contains(.hiddenByUser) } - // TODO: MOVE TO SARGON public var virtualHierarchicalDeterministicFactorInstances: Set { @@ -55,15 +54,13 @@ extension EntityBaseProtocol { } } - // TODO: MOVE TO SARGON public var hasAuthenticationSigningKey: Bool { switch securityState { - case let .unsecured(unsecuredEntityControl): + case .unsecured: false } } - // TODO: MOVE TO SARGON public var deviceFactorSourceID: FactorSourceIDFromHash? { switch self.securityState { case let .unsecured(control): diff --git a/apple/Tests/IntegrationTests/SargonOS/TestOSTests.swift b/apple/Tests/IntegrationTests/SargonOS/TestOSTests.swift index 7b28a3ac3..9613eef61 100644 --- a/apple/Tests/IntegrationTests/SargonOS/TestOSTests.swift +++ b/apple/Tests/IntegrationTests/SargonOS/TestOSTests.swift @@ -113,6 +113,7 @@ final class TestOSTests: OSTest { XCTAssertEqual(try sut.os.profile().header.creatingDevice, newCreatingDevice) // assert change worked } + @available(*, deprecated) func batch_create_many_accounts() async throws { let sut = await TestOS() try await sut.os.newWallet(shouldPreDeriveInstances: false) diff --git a/apple/Tests/TestCases/Profile/Collection/AccountsTests.swift b/apple/Tests/TestCases/Profile/Collection/AccountsTests.swift index fa3d706ec..c31a88b76 100644 --- a/apple/Tests/TestCases/Profile/Collection/AccountsTests.swift +++ b/apple/Tests/TestCases/Profile/Collection/AccountsTests.swift @@ -18,6 +18,7 @@ final class AccountsTests: CollectionTest { /// We can have this test implemented when swift-testing is stable to be used, /// and we will use "exit tests" to test it: /// https://forums.swift.org/t/exit-tests-death-tests-and-you/71186 + @available(*, deprecated) func omit_crash_if_duplicates() { // this test is relevant for Personas, AuthorizedDapps, ProfileNetworks etc etc... they all use the same rust type, which does not allow duplicates var profile = Profile.sample let a = Account.sample @@ -27,12 +28,14 @@ final class AccountsTests: CollectionTest { let _ = profile.jsonData() // should crash } + @available(*, deprecated) func test_json_decoding_of_profile_fails_if_accounts_contains_duplicates() throws { var json = JSON(Profile.sample) json["profileNetworks.accounts"] = [Account.sample, Account.sample] XCTAssertThrowsError(try Profile(jsonData: json.rawData())) } + @available(*, deprecated) func test_json_decoding_of_profile_fails_if_accounts_contains_duplicated_ids() throws { var json = JSON(Profile.sample) let a = Account.sample diff --git a/apple/Tests/TestCases/Profile/Collection/FactorSourcesTests.swift b/apple/Tests/TestCases/Profile/Collection/FactorSourcesTests.swift index ad95d5c41..1b2914fc8 100644 --- a/apple/Tests/TestCases/Profile/Collection/FactorSourcesTests.swift +++ b/apple/Tests/TestCases/Profile/Collection/FactorSourcesTests.swift @@ -18,24 +18,28 @@ final class FactorSourcesTests: CollectionTest { /// We can have this test implemented when swift-testing is stable to be used, /// and we will use "exit tests" to test it: /// https://forums.swift.org/t/exit-tests-death-tests-and-you/71186 + @available(*, deprecated) func omit_crash_if_empty() { var profile = Profile.sample profile.factorSources = [] // empty FactorSources is not allowed let _ = profile.jsonData() // should crash } + @available(*, deprecated) func test_json_decoding_of_profile_fails_if_factorSources_is_empty() throws { var json = JSON(Profile.sample) json["factorSources"] = [] XCTAssertThrowsError(try Profile(jsonData: json.rawData())) } + @available(*, deprecated) func test_json_decoding_of_profile_fails_if_factorSources_contains_duplicates() throws { var json = JSON(Profile.sample) json["factorSources"] = [FactorSource.sample, FactorSource.sample] XCTAssertThrowsError(try Profile(jsonData: json.rawData())) } + @available(*, deprecated) func test_json_decoding_of_profile_fails_if_factorSources_contains_duplicated_ids() throws { var json = JSON(Profile.sample) let a = FactorSource.sample diff --git a/apple/Tests/TestCases/Profile/Factor/DeviceFactorSourceTests.swift b/apple/Tests/TestCases/Profile/Factor/DeviceFactorSourceTests.swift index 9cd6e7447..7993c8e35 100644 --- a/apple/Tests/TestCases/Profile/Factor/DeviceFactorSourceTests.swift +++ b/apple/Tests/TestCases/Profile/Factor/DeviceFactorSourceTests.swift @@ -93,6 +93,7 @@ final class DeviceFactorSourceTests: SpecificFactorSourceTest { XCTAssertNoDifference(SUT.sample.id, SUT.sample.header.id) } + @available(*, deprecated) func test_encryption_roundtrip() throws { let password = "ultra secret" let sut = SUT.sample @@ -102,6 +103,7 @@ final class ProfileTests: Test { XCTAssertTrue(jsonString.contains("version")) } + @available(*, deprecated) func test_json_roundtrip() throws { func doTest(_ sut: SUT, _ json: String) throws { let encoded = sut.toJSONString(prettyPrinted: false) @@ -146,8 +148,9 @@ final class ProfileTests: Test { } } + @available(*, deprecated) func test_check_if_profile_json_contains_legacy_p2p_links_when_p2p_links_are_present() throws { - let json = try openFile(subPath: "vector", "only_plaintext_profile_snapshot_version_100", extension: "json") + let json = try jsonData(file: "only_plaintext_profile_snapshot_version_100") XCTAssert( SUT.checkIfProfileJsonContainsLegacyP2PLinks(contents: json) ) @@ -159,15 +162,16 @@ final class ProfileTests: Test { ) } + @available(*, deprecated) func test_check_if_encrypted_profile_json_contains_legacy_p2p_links_when_p2p_links_are_present() throws { - let json = try openFile(subPath: "vector", "profile_encrypted_by_password_of_babylon", extension: "json") + let json = try jsonData(file: "profile_encrypted_by_password_of_babylon") XCTAssert( SUT.checkIfEncryptedProfileJsonContainsLegacyP2PLinks(contents: json, password: "babylon") ) } func test_check_if_encrypted_profile_json_string_contains_legacy_p2p_links_when_p2p_links_are_present() throws { - let json = try openFile(subPath: "vector", "profile_encrypted_by_password_of_babylon", extension: "json") + let json = try jsonData(file: "profile_encrypted_by_password_of_babylon") let jsonString = try XCTUnwrap(String(data: json, encoding: .utf8)) XCTAssert( SUT.checkIfEncryptedProfileJsonStringContainsLegacyP2PLinks(jsonString: jsonString, password: "babylon") diff --git a/apple/Tests/TestCases/RadixConnect/WalletInteraction/WalletToDappInteractionResponseTests.swift b/apple/Tests/TestCases/RadixConnect/WalletInteraction/WalletToDappInteractionResponseTests.swift index 27a1b8d17..42cb97b15 100644 --- a/apple/Tests/TestCases/RadixConnect/WalletInteraction/WalletToDappInteractionResponseTests.swift +++ b/apple/Tests/TestCases/RadixConnect/WalletInteraction/WalletToDappInteractionResponseTests.swift @@ -6,10 +6,9 @@ import XCTest final class WalletToDappInteractionResponseTests: Test { func test_codable() throws { - let json = try openFile( - subPath: "vector", - "wallet_interactions_wallet_to_dapp", - extension: "json" + let json = try jsonData( + file: "wallet_interactions_wallet_to_dapp", + in: "models/interaction" ) let sut = try JSONDecoder().decode([SUT].self, from: json) let encoded = try JSONEncoder().encode(sut) diff --git a/apple/Tests/Utils/Extensions/UUID+Literals.swift b/apple/Tests/Utils/Extensions/UUID+Literals.swift index ee674bfd5..d5dc4734b 100644 --- a/apple/Tests/Utils/Extensions/UUID+Literals.swift +++ b/apple/Tests/Utils/Extensions/UUID+Literals.swift @@ -1,14 +1,16 @@ import Foundation // MARK: - UUID + ExpressibleByStringLiteral -extension UUID: ExpressibleByStringLiteral { +extension UUID: @retroactive ExpressibleByExtendedGraphemeClusterLiteral {} +extension UUID: @retroactive ExpressibleByUnicodeScalarLiteral {} +extension UUID: @retroactive ExpressibleByStringLiteral { public init(stringLiteral value: String) { self.init(uuidString: value)! } } // MARK: - UUID + ExpressibleByIntegerLiteral -extension UUID: ExpressibleByIntegerLiteral { +extension UUID: @retroactive ExpressibleByIntegerLiteral { public init(integerLiteral value: UInt8) { self.init(uuidString: "00000000-0000-0000-0000-0000000000" + String(format: "%02d", value))! } diff --git a/apple/Tests/Utils/Test.swift b/apple/Tests/Utils/Test.swift index d9390b2ab..9abf798eb 100644 --- a/apple/Tests/Utils/Test.swift +++ b/apple/Tests/Utils/Test.swift @@ -40,9 +40,10 @@ class TestCase: XCTestCase { func jsonFixture( as: T.Type = T.self, file fileName: String, + in subPath: String? = nil, decode: (Data) throws -> T = { try JSONDecoder().decode(T.self, from: $0) } ) throws -> (model: T, json: Data) { - let json = try openFile(subPath: "vector", fileName, extension: "json") + let json = try jsonData(file: fileName, in: subPath) let model: T = try decode(json) return (model, json) } @@ -50,23 +51,32 @@ class TestCase: XCTestCase { func jsonFixture( as: T.Type = T.self, file fileName: String, + in subPath: String? = nil, decode: (Data) throws -> T ) throws -> (model: T, json: Data) { - let json = try openFile(subPath: "vector", fileName, extension: "json") + let json = try jsonData(file: fileName, in: subPath) let model: T = try decode(json) return (model, json) } + func jsonData( + file fileName: String, + in subPath: String? = nil + ) throws -> Data { + try openFile( + subPath: subPath ?? "models/profile", + fileName, + extension: "json" + ) + } + func jsonString( as: T.Type = T.self, file fileName: String, + in subPath: String? = nil, decode: (String) throws -> T ) throws -> (model: T, jsonString: String) { - let jsonData = try openFile( - subPath: "vector", - fileName, - extension: "json" - ) + let jsonData = try jsonData(file: fileName, in: subPath) let jsonString = try XCTUnwrap(String(data: jsonData, encoding: .utf8)) let model: T = try decode(jsonString) return (model, jsonString) diff --git a/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/abstract_matrix_builder_or_built.rs b/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/abstract_matrix_builder_or_built.rs index a91fb832d..a5b5ec229 100644 --- a/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/abstract_matrix_builder_or_built.rs +++ b/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/abstract_matrix_builder_or_built.rs @@ -45,7 +45,7 @@ pub struct AbstractMatrixBuilderOrBuilt< impl AbstractMatrixBuilderOrBuilt { - pub const DEFAULT_TIME_UNTIL_DELAYE_CONFIRMATION_IS_CALLABLE: TimePeriod = + pub const DEFAULT_TIME_UNTIL_DELAYED_CONFIRMATION_IS_CALLABLE: TimePeriod = TimePeriod::with_days(14); /// # Safety diff --git a/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/builder/matrix_builder.rs b/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/builder/matrix_builder.rs index 87c98461d..60544c0f8 100644 --- a/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/builder/matrix_builder.rs +++ b/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/builder/matrix_builder.rs @@ -29,7 +29,7 @@ impl MatrixBuilder { recovery_role: RecoveryRoleBuilder::new(), confirmation_role: ConfirmationRoleBuilder::new(), time_until_delayed_confirmation_is_callable: - Self::DEFAULT_TIME_UNTIL_DELAYE_CONFIRMATION_IS_CALLABLE, + Self::DEFAULT_TIME_UNTIL_DELAYED_CONFIRMATION_IS_CALLABLE, } } diff --git a/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/builder/matrix_builder_unit_tests.rs b/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/builder/matrix_builder_unit_tests.rs index d4347c35d..f6f51190e 100644 --- a/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/builder/matrix_builder_unit_tests.rs +++ b/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/builder/matrix_builder_unit_tests.rs @@ -145,7 +145,7 @@ fn set_number_of_days_42() { #[test] fn timed_confirm_default() { assert_eq!( - SUT::DEFAULT_TIME_UNTIL_DELAYE_CONFIRMATION_IS_CALLABLE, + SUT::DEFAULT_TIME_UNTIL_DELAYED_CONFIRMATION_IS_CALLABLE, TimePeriod::with_days(14) ); } @@ -187,7 +187,7 @@ fn set_number_of_days_if_not_set_uses_default() { ConfirmationRoleWithFactorSourceIds::override_only([ FactorSourceID::sample_password() ],), - SUT::DEFAULT_TIME_UNTIL_DELAYE_CONFIRMATION_IS_CALLABLE, + SUT::DEFAULT_TIME_UNTIL_DELAYED_CONFIRMATION_IS_CALLABLE, ) ); } diff --git a/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/builder/matrix_template.rs b/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/builder/matrix_template.rs index ce59b8e1b..70df4ead8 100644 --- a/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/builder/matrix_template.rs +++ b/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/builder/matrix_template.rs @@ -113,7 +113,7 @@ impl MatrixTemplate { confirmation_role: ConfirmationRoleTemplate, ) -> Self { unsafe { - Self::unbuilt_with_roles_and_days(primary_role, recovery_role, confirmation_role, MatrixOfFactorSourceIds::DEFAULT_TIME_UNTIL_DELAYE_CONFIRMATION_IS_CALLABLE) + Self::unbuilt_with_roles_and_days(primary_role, recovery_role, confirmation_role, MatrixOfFactorSourceIds::DEFAULT_TIME_UNTIL_DELAYED_CONFIRMATION_IS_CALLABLE) } } diff --git a/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/matrix_of_factor_source_ids.rs b/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/matrix_of_factor_source_ids.rs index 5ff5210ee..c5383e032 100644 --- a/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/matrix_of_factor_source_ids.rs +++ b/crates/profile/models/security-structures/src/roles_matrices_structures/matrices/matrix_of_factor_source_ids.rs @@ -13,7 +13,7 @@ impl MatrixOfFactorSourceIds { primary, recovery, confirmation, - Self::DEFAULT_TIME_UNTIL_DELAYE_CONFIRMATION_IS_CALLABLE, + Self::DEFAULT_TIME_UNTIL_DELAYED_CONFIRMATION_IS_CALLABLE, ) } } @@ -46,7 +46,7 @@ impl MatrixOfFactorSourceIds { primary, recovery, confirmation, - Self::DEFAULT_TIME_UNTIL_DELAYE_CONFIRMATION_IS_CALLABLE, + Self::DEFAULT_TIME_UNTIL_DELAYED_CONFIRMATION_IS_CALLABLE, ) } } diff --git a/crates/profile/models/security-structures/src/roles_matrices_structures/security_shield_builder.rs b/crates/profile/models/security-structures/src/roles_matrices_structures/security_shield_builder.rs index 9b72f4235..aac3b182a 100644 --- a/crates/profile/models/security-structures/src/roles_matrices_structures/security_shield_builder.rs +++ b/crates/profile/models/security-structures/src/roles_matrices_structures/security_shield_builder.rs @@ -275,9 +275,7 @@ impl SecurityShieldBuilder { }) } - pub fn get_time_period_until_timed_confirmation_is_callable( - &self, - ) -> TimePeriod { + pub fn get_time_until_timed_confirmation_is_callable(&self) -> TimePeriod { self.get(|builder| { builder.get_time_until_delayed_confirmation_is_callable() }) @@ -433,7 +431,7 @@ impl SecurityShieldBuilder { self.set(|builder| builder.set_threshold(threshold)) } - pub fn set_time_period_until_timed_confirmation_is_callable( + pub fn set_time_until_delayed_confirmation_is_callable( &self, time_period: TimePeriod, ) -> &Self { @@ -1001,17 +999,17 @@ mod tests { } #[test] - fn test_get_time_period_until_timed_confirmation_is_callable() { + fn test_get_time_until_timed_confirmation_is_callable() { let sut = SUT::strict(); assert_eq!( - sut.get_time_period_until_timed_confirmation_is_callable(), + sut.get_time_until_timed_confirmation_is_callable(), TimePeriod::with_days(14) ); - sut.set_time_period_until_timed_confirmation_is_callable( + sut.set_time_until_delayed_confirmation_is_callable( TimePeriod::with_days(42), ); assert_eq!( - sut.get_time_period_until_timed_confirmation_is_callable(), + sut.get_time_until_timed_confirmation_is_callable(), TimePeriod::with_days(42) ); } @@ -1045,7 +1043,7 @@ mod tests { FactorSourceID::sample_device(), )) // Primary - .set_time_period_until_timed_confirmation_is_callable( + .set_time_until_delayed_confirmation_is_callable( TimePeriod::with_days(42), ) .add_factor_source_to_primary_threshold( @@ -1593,7 +1591,7 @@ mod test_invalid { #[test] fn time_until_delayed_confirmation_is_callable_invalid() { let sut = valid(); - sut.set_time_period_until_timed_confirmation_is_callable( + sut.set_time_until_delayed_confirmation_is_callable( TimePeriod::with_days(0), ); assert_eq!( diff --git a/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs b/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs index d727ff4e6..205614c81 100644 --- a/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs +++ b/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs @@ -150,7 +150,7 @@ mod tests { }; test(RolesExercisableInTransactionManifestCombination::InitiateWithPrimaryCompleteWithConfirmation, true); test(RolesExercisableInTransactionManifestCombination::InitiateWithPrimaryCompleteWithRecovery, true); - test(RolesExercisableInTransactionManifestCombination::InitiateWithPrimaryDelayedCompletion, true); + // test(RolesExercisableInTransactionManifestCombination::InitiateWithPrimaryDelayedCompletion, true); test(RolesExercisableInTransactionManifestCombination::InitiateWithRecoveryCompleteWithConfirmation, false); test(RolesExercisableInTransactionManifestCombination::InitiateWithRecoveryDelayedCompletion, false); @@ -231,13 +231,13 @@ mod tests { ) } - #[test] - fn update_shield_of_securified_persona_init_with_P_confirm_with_T() { - test_update_shield_of_securified_persona( - RolesExercisableInTransactionManifestCombination::InitiateWithPrimaryDelayedCompletion, - || fixture_rtm!("update_shield_of_persona_init_with_P_confirm_with_T") - ) - } + // #[test] // requires Dugong + // fn update_shield_of_securified_persona_init_with_P_confirm_with_T() { + // test_update_shield_of_securified_persona( + // RolesExercisableInTransactionManifestCombination::InitiateWithPrimaryDelayedCompletion, + // || fixture_rtm!("update_shield_of_persona_init_with_P_confirm_with_T") + // ) + // } #[test] fn update_shield_of_securified_persona_init_with_R_confirm_with_C() { diff --git a/crates/transaction/manifests/src/manifests_security_shield/roles_exercisable_in_transaction_manifest_combination.rs b/crates/transaction/manifests/src/manifests_security_shield/roles_exercisable_in_transaction_manifest_combination.rs index 83ee49cbe..90af46c9f 100644 --- a/crates/transaction/manifests/src/manifests_security_shield/roles_exercisable_in_transaction_manifest_combination.rs +++ b/crates/transaction/manifests/src/manifests_security_shield/roles_exercisable_in_transaction_manifest_combination.rs @@ -49,24 +49,22 @@ pub enum RolesExercisableInTransactionManifestCombination { /// Host will also need to schedule a notification for user so that host /// can call the `confirm_timed_recovery` method after the time has elapsed. InitiateWithRecoveryDelayedCompletion, + // Initiate recovery with `Primary` role and use timed confirmation. + // + // Since this roles combination does not explicitly use the Confirmation + // Role we will not include any confirm Instruction in the manifest + // we build for this kind. Instead, if this is the TransactionManifest which + // we will be submitting to the network, the host (user) will need to wait + // until the transaction is confirmed and then update Profile to keep + // track of the fact that the entity is in between states of recovery. + // TODO: TBD probably a new variant of the `ProvisionalSecurifiedConfig` + // `WaitingForTimedRecovery(SecurityStructureOfFactorInstances)` or similar. + // + // Host will also need to schedule a notification for user so that host + // can call the `confirm_timed_recovery` method after the time has elapsed. + // + // InitiateWithPrimaryDelayedCompletion, TODO: when Dugong is available => comment in this - /// ‼️ REQUIRES "Dugong" ‼️ - /// Initiate recovery with `Primary` role and use timed confirmation. - /// - /// Since this roles combination does not explicitly use the Confirmation - /// Role we will not include any confirm Instruction in the manifest - /// we build for this kind. Instead, if this is the TransactionManifest which - /// we will be submitting to the network, the host (user) will need to wait - /// until the transaction is confirmed and then update Profile to keep - /// track of the fact that the entity is in between states of recovery. - /// TODO: TBD probably a new variant of the `ProvisionalSecurifiedConfig` - /// `WaitingForTimedRecovery(SecurityStructureOfFactorInstances)` or similar. - /// - /// Host will also need to schedule a notification for user so that host - /// can call the `confirm_timed_recovery` method after the time has elapsed. - /// - /// ‼️ REQUIRES "Dugong" ‼️ - InitiateWithPrimaryDelayedCompletion, // TODO: // FUTURE IMPROVEMENTS, // User can't initiate themselves and needs to send a request to an external source (e.g. a friend or custodian) @@ -101,8 +99,7 @@ impl RolesExercisableInTransactionManifestCombination { matches!( self, Self::InitiateWithPrimaryCompleteWithRecovery - | Self::InitiateWithPrimaryCompleteWithConfirmation - | Self::InitiateWithPrimaryDelayedCompletion + | Self::InitiateWithPrimaryCompleteWithConfirmation // | Self::InitiateWithPrimaryDelayedCompletion ) } @@ -115,8 +112,7 @@ impl RolesExercisableInTransactionManifestCombination { matches!( self, Self::InitiateWithPrimaryCompleteWithRecovery - | Self::InitiateWithPrimaryCompleteWithConfirmation - | Self::InitiateWithPrimaryDelayedCompletion + | Self::InitiateWithPrimaryCompleteWithConfirmation // | Self::InitiateWithPrimaryDelayedCompletion ) } fn initiate_recovery_with_recovery(&self) -> bool { @@ -146,6 +142,8 @@ impl RolesExercisableInTransactionManifestCombination { factors_and_time: &AccessControllerFactorsAndTimeInput, ) -> (&'static str, Box) { if self.initiate_recovery_with_primary() { + // Recovery was initiated with `Primary` and needs to be confirmed with `Recovery` or with `Confirmation` + // as per specified by this RolesExercisableInTransactionManifestCombination ( SCRYPTO_ACCESS_CONTROLLER_INITIATE_RECOVERY_AS_PRIMARY_IDENT, Box::new( @@ -155,6 +153,8 @@ impl RolesExercisableInTransactionManifestCombination { ), ) } else if self.initiate_recovery_with_recovery() { + // Recovery was initiated with `Recovery` and needs to be confirmed with + // `Confirmation` role ( SCRYPTO_ACCESS_CONTROLLER_INITIATE_RECOVERY_AS_RECOVERY_IDENT, Box::new( diff --git a/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_unsecurified_entity_owner_badge_into_bucket_putting.rs b/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_unsecurified_entity_owner_badge_into_bucket_putting.rs index 58b6eda31..55d8975dd 100644 --- a/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_unsecurified_entity_owner_badge_into_bucket_putting.rs +++ b/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_unsecurified_entity_owner_badge_into_bucket_putting.rs @@ -34,7 +34,7 @@ pub trait TransactionManifestUnsecurifiedEntityOwnerBadgeIntoBucketPutting { (builder, owner_badge_bucket) } - /// Calls "secufiry" for an unsecurified entity which places the owner badge + /// Calls "securify" for an unsecurified entity which places the owner badge /// on the worktop. fn call_securify_for_unsecurified_entity( builder: ScryptoTransactionManifestBuilder, diff --git a/crates/uniffi/uniffi_SPLIT_ME/src/profile/mfa/security_structures/security_shield_builder.rs b/crates/uniffi/uniffi_SPLIT_ME/src/profile/mfa/security_structures/security_shield_builder.rs index ddb0d0e45..73726cbae 100644 --- a/crates/uniffi/uniffi_SPLIT_ME/src/profile/mfa/security_structures/security_shield_builder.rs +++ b/crates/uniffi/uniffi_SPLIT_ME/src/profile/mfa/security_structures/security_shield_builder.rs @@ -102,11 +102,9 @@ impl SecurityShieldBuilder { .collect() } - pub fn get_time_period_until_timed_confirmation_is_callable( - &self, - ) -> TimePeriod { + pub fn get_time_until_timed_confirmation_is_callable(&self) -> TimePeriod { self.get(|builder| { - builder.get_time_period_until_timed_confirmation_is_callable() + builder.get_time_until_timed_confirmation_is_callable() }) .into() } @@ -210,12 +208,12 @@ impl SecurityShieldBuilder { self.set(|builder| builder.set_threshold(threshold.into())) } - pub fn set_time_period_until_timed_confirmation_is_callable( + pub fn set_time_until_delayed_confirmation_is_callable( self: Arc, time_period: TimePeriod, ) -> Arc { self.set(|builder| { - builder.set_time_period_until_timed_confirmation_is_callable( + builder.set_time_until_delayed_confirmation_is_callable( time_period.into(), ) }) @@ -642,18 +640,16 @@ mod tests { assert_eq!( time_period_to_days( - &sut.clone() - .get_time_period_until_timed_confirmation_is_callable() + &sut.clone().get_time_until_timed_confirmation_is_callable() ), 14 ); - sut = sut.set_time_period_until_timed_confirmation_is_callable( + sut = sut.set_time_until_delayed_confirmation_is_callable( new_time_period_with_days(u16::MAX), ); assert_eq!( time_period_to_days( - &sut.clone() - .get_time_period_until_timed_confirmation_is_callable() + &sut.clone().get_time_until_timed_confirmation_is_callable() ), u16::MAX ); @@ -977,7 +973,7 @@ mod tests { }; sut = sut .set_name(name.to_owned()) - .set_time_period_until_timed_confirmation_is_callable( + .set_time_until_delayed_confirmation_is_callable( new_time_period_with_days(237), ) .add_factor_source_to_primary_threshold( From c36de912ebe763b4246aff65ce8cf7082e62b74e Mon Sep 17 00:00:00 2001 From: Alexander Cyon Date: Mon, 27 Jan 2025 12:45:02 +0100 Subject: [PATCH 22/25] try fix kotlin --- .../src/test/java/com/radixdlt/sargon/ProfileTest.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jvm/sargon-android/src/test/java/com/radixdlt/sargon/ProfileTest.kt b/jvm/sargon-android/src/test/java/com/radixdlt/sargon/ProfileTest.kt index 009443ab8..e6d718c2b 100644 --- a/jvm/sargon-android/src/test/java/com/radixdlt/sargon/ProfileTest.kt +++ b/jvm/sargon-android/src/test/java/com/radixdlt/sargon/ProfileTest.kt @@ -126,7 +126,7 @@ class ProfileTest : SampleTestable { @Test fun testCheckIfProfileJsonContainsLegacyP2PLinksWhenP2PLinksArePresent() { - val json = File("../../" + "fixtures/vector/only_plaintext_profile_snapshot_version_100.json").readText() + val json = File("../../" + "fixtures/models/profile/only_plaintext_profile_snapshot_version_100.json").readText() assertEquals( true, Profile.checkIfProfileJsonContainsLegacyP2PLinks(json) @@ -143,7 +143,7 @@ class ProfileTest : SampleTestable { @Test fun testCheckIfEncryptedProfileJsonContainsLegacyP2PLinksWhenP2PLinksArePresent() { - val json = File("../../" + "fixtures/vector/profile_encrypted_by_password_of_babylon.json").readText() + val json = File("../../" + "fixtures/models/profile/profile_encrypted_by_password_of_babylon.json").readText() assertEquals( true, Profile.checkIfEncryptedProfileJsonContainsLegacyP2PLinks(json, "babylon") From 30ebbdcc7ddf1aa90d2f8e650dc5ff8c11a87dd8 Mon Sep 17 00:00:00 2001 From: Alexander Cyon Date: Wed, 29 Jan 2025 10:53:22 +0100 Subject: [PATCH 23/25] polish --- ...on_os_apply_security_shield_interaction.rs | 3 +- ...fests_securify_shield_securified_entity.rs | 190 +++++++-------- ...ble_in_transaction_manifest_combination.rs | 216 ++++++++++-------- ..._entity_owner_badge_into_bucket_putting.rs | 8 +- ...let_interaction_batch_of_transactions.json | 36 +-- ..._of_persona_init_with_P_confirm_with_T.rtm | 22 +- ..._of_persona_init_with_R_confirm_with_C.rtm | 11 + 7 files changed, 266 insertions(+), 220 deletions(-) diff --git a/crates/system/os/factors/src/apply_security_shield/sargon_os_apply_security_shield_interaction.rs b/crates/system/os/factors/src/apply_security_shield/sargon_os_apply_security_shield_interaction.rs index 16577a429..3566aa566 100644 --- a/crates/system/os/factors/src/apply_security_shield/sargon_os_apply_security_shield_interaction.rs +++ b/crates/system/os/factors/src/apply_security_shield/sargon_os_apply_security_shield_interaction.rs @@ -74,7 +74,7 @@ impl OsApplySecurityShieldInteraction for SargonOS { TransactionManifest::apply_security_shield_for_securified_entity( e.clone(), derived.clone(), - RolesExercisableInTransactionManifestCombination::default() + RolesExercisableInTransactionManifestCombination::manifest_end_user_gets_to_preview() ) .map(UnvalidatedTransactionManifest::from).unwrap() }).collect_vec(); @@ -249,7 +249,6 @@ mod tests { .await .unwrap() }; - let fixture_json = fixture_interaction!("wallet_interaction_batch_of_transactions"); assert_eq_after_json_roundtrip(&interaction, fixture_json); diff --git a/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs b/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs index 205614c81..3a4c8ef78 100644 --- a/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs +++ b/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs @@ -42,9 +42,23 @@ impl TransactionManifestSecurifySecurifiedEntity for TransactionManifest { security_structure_of_factor_instances .assert_has_entity_kind(entity_address.get_entity_kind()).expect("Shouldn't have used wrong FactorInstance for entity - apply_security_shield_with_id_to_entities has some bug."); - // ACCESS_CONTROLLER_CREATE_PROOF_IDENT let mut builder = ScryptoTransactionManifestBuilder::new(); + let set_rola = |builder: ScryptoTransactionManifestBuilder| -> ScryptoTransactionManifestBuilder { + TransactionManifest::set_rola_key( + builder, + &security_structure_of_factor_instances + .authentication_signing_factor_instance, + &entity_address, + ) + }; + + let order_of_instruction_setting_rola = kind + .order_of_instruction_setting_rola( + &security_structure_of_factor_instances, + &securified_entity, + ); + let access_controller_address = securified_entity .securified_entity_control .access_controller_address; @@ -53,6 +67,15 @@ impl TransactionManifestSecurifySecurifiedEntity for TransactionManifest { &security_structure_of_factor_instances, ); + match order_of_instruction_setting_rola { + OrderOfInstructionSettingRolaKey::BeforeInitRecovery => { + builder = set_rola(builder); + } + OrderOfInstructionSettingRolaKey::AfterQuickConfirm | OrderOfInstructionSettingRolaKey::NotNeeded | OrderOfInstructionSettingRolaKey::MustSetInFutureTxForConfirmRecovery => { + // Do nothing for now + } + } + // INITIATE RECOVERY let (init_method, init_input) = kind.input_for_initialization(factors_and_time_input); @@ -73,22 +96,14 @@ impl TransactionManifestSecurifySecurifiedEntity for TransactionManifest { ); } - // Set Rola Key - let should_set_rola_key = security_structure_of_factor_instances - .authentication_signing_factor_instance - != securified_entity - .current_authentication_signing_factor_instance(); - - if should_set_rola_key { - if kind.can_set_rola_key() { - builder = TransactionManifest::set_rola_key( - builder, - &security_structure_of_factor_instances - .authentication_signing_factor_instance, - &entity_address, - ); - } else { - return None; // Nothing has "failed" really, but we cannot proceed with this combination. + match order_of_instruction_setting_rola { + OrderOfInstructionSettingRolaKey::AfterQuickConfirm => { + builder = set_rola(builder); + } + OrderOfInstructionSettingRolaKey::BeforeInitRecovery | OrderOfInstructionSettingRolaKey::NotNeeded => { + // nothing to do + } OrderOfInstructionSettingRolaKey::MustSetInFutureTxForConfirmRecovery => { + info!("Do not forget to set Rola key in future transaction for Confirm Recovery"); } } @@ -119,43 +134,16 @@ mod tests { use prelude::fixture_rtm; use profile_supporting_types::{SecurifiedAccount, SecurifiedPersona}; + use radix_transactions::manifest::{ + CallMetadataMethod, CallMethod, ManifestInstruction, + }; + use sbor::SborEnum; use super::*; #[allow(clippy::upper_case_acronyms)] type SUT = TransactionManifest; - #[test] - fn classify() { - let test = - |combination: RolesExercisableInTransactionManifestCombination, - expected: bool| { - let entity_applying_shield = AnySecurifiedEntity::sample(); - let mut instances = - SecurityStructureOfFactorInstances::sample(); - - // skip set rola - instances.authentication_signing_factor_instance = - entity_applying_shield - .current_authentication_signing_factor_instance(); - let manifest = - SUT::apply_security_shield_for_securified_entity( - entity_applying_shield.clone(), - instances, - combination, - ) - .unwrap(); - let classified = manifest.explicitly_references_primary_role(); - assert_eq!(classified, expected); - }; - test(RolesExercisableInTransactionManifestCombination::InitiateWithPrimaryCompleteWithConfirmation, true); - test(RolesExercisableInTransactionManifestCombination::InitiateWithPrimaryCompleteWithRecovery, true); - // test(RolesExercisableInTransactionManifestCombination::InitiateWithPrimaryDelayedCompletion, true); - - test(RolesExercisableInTransactionManifestCombination::InitiateWithRecoveryCompleteWithConfirmation, false); - test(RolesExercisableInTransactionManifestCombination::InitiateWithRecoveryDelayedCompletion, false); - } - #[test] fn update_shield_of_securified_account_with_top_up_where_payer_is_entity_applying_shield( ) { @@ -186,18 +174,13 @@ mod tests { manifest_eq(manifest, expected_manifest_str); } - fn test_update_shield_of_securified_persona_cond_set_rola<'a>( + fn test_update_shield_of_securified_persona<'a>( roles: RolesExercisableInTransactionManifestCombination, - set_rola: bool, rtm: impl Fn() -> &'a str, - ) { + ) -> Vec { let entity_applying_shield = SecurifiedPersona::sample(); - let mut instances = SecurityStructureOfFactorInstances::sample_other(); - if !set_rola { - instances.authentication_signing_factor_instance = - entity_applying_shield - .current_authentication_signing_factor_instance(); - } + let instances = SecurityStructureOfFactorInstances::sample_other(); + let manifest = SUT::apply_security_shield_for_securified_entity( entity_applying_shield.clone(), instances, @@ -206,68 +189,87 @@ mod tests { .unwrap(); let expected_manifest_str = rtm(); manifest_eq(manifest.clone(), expected_manifest_str); - } - - fn test_update_shield_of_securified_persona<'a>( - roles: RolesExercisableInTransactionManifestCombination, - rtm: impl Fn() -> &'a str, - ) { - test_update_shield_of_securified_persona_cond_set_rola(roles, true, rtm) + manifest + .instructions() + .iter() + .map(|i| i.get_discriminator()) + .collect_vec() } #[test] fn update_shield_of_securified_persona_init_with_P_confirm_with_R() { - test_update_shield_of_securified_persona( + let instruction_discriminants = test_update_shield_of_securified_persona( RolesExercisableInTransactionManifestCombination::InitiateWithPrimaryCompleteWithRecovery, || fixture_rtm!("update_shield_of_persona_init_with_P_confirm_with_R") - ) + ); + assert_eq!( + instruction_discriminants, + vec![ + CallMethod::ID, // init + CallMethod::ID, // quick confirm + CallMetadataMethod::ID, // set ROLA key + ] + ); } #[test] fn update_shield_of_securified_persona_init_with_P_confirm_with_C() { - test_update_shield_of_securified_persona( + let instruction_discriminants = test_update_shield_of_securified_persona( RolesExercisableInTransactionManifestCombination::InitiateWithPrimaryCompleteWithConfirmation, || fixture_rtm!("update_shield_of_persona_init_with_P_confirm_with_C") - ) + ); + assert_eq!( + instruction_discriminants, + vec![ + CallMethod::ID, // init + CallMethod::ID, // quick confirm + CallMetadataMethod::ID, // set ROLA key + ] + ); } - // #[test] // requires Dugong - // fn update_shield_of_securified_persona_init_with_P_confirm_with_T() { - // test_update_shield_of_securified_persona( - // RolesExercisableInTransactionManifestCombination::InitiateWithPrimaryDelayedCompletion, - // || fixture_rtm!("update_shield_of_persona_init_with_P_confirm_with_T") - // ) - // } + #[test] + fn update_shield_of_securified_persona_init_with_P_confirm_with_T() { + let instruction_discriminants = test_update_shield_of_securified_persona( + RolesExercisableInTransactionManifestCombination::InitiateWithPrimaryDelayedCompletion, + || fixture_rtm!("update_shield_of_persona_init_with_P_confirm_with_T") + ); + assert_eq!( + instruction_discriminants, + vec![ + CallMetadataMethod::ID, // set ROLA key + CallMethod::ID // init + ], + "Expected to FIRST set ROLA key and THEN init - since we can set it using existing factors." + ); + } #[test] fn update_shield_of_securified_persona_init_with_R_confirm_with_C() { - test_update_shield_of_securified_persona_cond_set_rola( + let instruction_discriminants = test_update_shield_of_securified_persona( RolesExercisableInTransactionManifestCombination::InitiateWithRecoveryCompleteWithConfirmation, - false, || fixture_rtm!("update_shield_of_persona_init_with_R_confirm_with_C") - ) + ); + assert_eq!( + instruction_discriminants, + vec![ + CallMethod::ID, // init + CallMethod::ID, // quick confirm + CallMetadataMethod::ID, // set ROLA key + ] + ); } #[test] fn update_shield_of_securified_persona_init_with_R_confirm_with_T() { - test_update_shield_of_securified_persona_cond_set_rola( + let instruction_discriminants = test_update_shield_of_securified_persona( RolesExercisableInTransactionManifestCombination::InitiateWithRecoveryDelayedCompletion, - false, || fixture_rtm!("update_shield_of_persona_init_with_R_confirm_with_T") - ) - } - - #[test] - fn update_shield_of_securified_persona_fails_when_setting_rola_and_without_primary( - ) { - let entity_applying_shield = SecurifiedPersona::sample(); - - let res = SUT::apply_security_shield_for_securified_entity( - entity_applying_shield.clone(), - SecurityStructureOfFactorInstances::sample_other(), - RolesExercisableInTransactionManifestCombination::InitiateWithRecoveryDelayedCompletion, ); - - assert_eq!(res, None); + assert_eq!( + instruction_discriminants, + vec![CallMethod::ID], + "init with R complete with T should not set rola key - since we cannot" + ); } } diff --git a/crates/transaction/manifests/src/manifests_security_shield/roles_exercisable_in_transaction_manifest_combination.rs b/crates/transaction/manifests/src/manifests_security_shield/roles_exercisable_in_transaction_manifest_combination.rs index 90af46c9f..18b8e5ac6 100644 --- a/crates/transaction/manifests/src/manifests_security_shield/roles_exercisable_in_transaction_manifest_combination.rs +++ b/crates/transaction/manifests/src/manifests_security_shield/roles_exercisable_in_transaction_manifest_combination.rs @@ -1,5 +1,7 @@ use crate::prelude::*; +use enum_as_inner::EnumAsInner; +use profile_supporting_types::AnySecurifiedEntity; use radix_common::prelude::{ ManifestEncode as ScryptoManifestEncode, ManifestSborTuple as ScryptoManifestSborTuple, @@ -49,22 +51,25 @@ pub enum RolesExercisableInTransactionManifestCombination { /// Host will also need to schedule a notification for user so that host /// can call the `confirm_timed_recovery` method after the time has elapsed. InitiateWithRecoveryDelayedCompletion, - // Initiate recovery with `Primary` role and use timed confirmation. - // - // Since this roles combination does not explicitly use the Confirmation - // Role we will not include any confirm Instruction in the manifest - // we build for this kind. Instead, if this is the TransactionManifest which - // we will be submitting to the network, the host (user) will need to wait - // until the transaction is confirmed and then update Profile to keep - // track of the fact that the entity is in between states of recovery. - // TODO: TBD probably a new variant of the `ProvisionalSecurifiedConfig` - // `WaitingForTimedRecovery(SecurityStructureOfFactorInstances)` or similar. - // - // Host will also need to schedule a notification for user so that host - // can call the `confirm_timed_recovery` method after the time has elapsed. - // - // InitiateWithPrimaryDelayedCompletion, TODO: when Dugong is available => comment in this + /// ‼️ Requires fuuture network upgrade "Dugong" + /// + /// Initiate recovery with `Primary` role and use timed confirmation. + /// + /// Since this roles combination does not explicitly use the Confirmation + /// Role we will not include any confirm Instruction in the manifest + /// we build for this kind. Instead, if this is the TransactionManifest which + /// we will be submitting to the network, the host (user) will need to wait + /// until the transaction is confirmed and then update Profile to keep + /// track of the fact that the entity is in between states of recovery. + /// TODO: TBD probably a new variant of the `ProvisionalSecurifiedConfig` + /// `WaitingForTimedRecovery(SecurityStructureOfFactorInstances)` or similar. + /// + /// Host will also need to schedule a notification for user so that host + /// can call the `confirm_timed_recovery` method after the time has elapsed. + /// + /// ‼️ Requires fuuture network upgrade "Dugong" + InitiateWithPrimaryDelayedCompletion, // TODO: // FUTURE IMPROVEMENTS, // User can't initiate themselves and needs to send a request to an external source (e.g. a friend or custodian) @@ -72,14 +77,6 @@ pub enum RolesExercisableInTransactionManifestCombination { // ExternalInitiateWithRecovery } -impl Default for RolesExercisableInTransactionManifestCombination { - fn default() -> Self { - // we default to a combination containing Primary since it allows - // use to top up XRD vault of AccessController - Self::InitiateWithPrimaryCompleteWithRecovery - } -} - pub trait CallMethodInput: ScryptoManifestEncode + ScryptoManifestSborTuple { @@ -89,50 +86,101 @@ impl CallMethodInput { } +/// Depending on the role used to initiate recovery, and if we are quick confirming +/// the recovery proposal we need to either place SET_METADATA instruction which +/// updates the ROLA key with the new factors before the recovery proposal - requiring +/// the OLD PrimaryRole factors to auth the transaction - or we can quick confirm +/// we will place the SET_METADATA instruction after we have (quick) confirmed the +/// recovery proposal. +#[derive(Clone, Debug, PartialEq, Eq, EnumAsInner)] +pub enum OrderOfInstructionSettingRolaKey { + /// Place SET_METADATA instruction before initiating recovery - so that + /// we can auth with the OLD factors of Primary role. + BeforeInitRecovery, + /// Place SET_METADATA instruction after quick confirming the recovery proposal + /// => requiring us to auth with the NEW factors of Primary role. + AfterQuickConfirm, + + /// No need to set ROLA key + NotNeeded, + + /// Cannot set ROLA key in this TX - must do it in a future TX when we confirm recovery + MustSetInFutureTxForConfirmRecovery, +} + +#[derive(Clone, Debug, PartialEq, Eq)] +enum RoleInitiatingRecovery { + Primary, + Recovery, +} + impl RolesExercisableInTransactionManifestCombination { + pub fn manifest_end_user_gets_to_preview() -> Self { + Self::InitiateWithRecoveryCompleteWithConfirmation + } + pub fn all() -> IndexSet { enum_iterator::all::().collect() } - /// If this combination of roles references the `Primary` role or not. - pub fn can_exercise_primary_role(&self) -> bool { - matches!( - self, - Self::InitiateWithPrimaryCompleteWithRecovery - | Self::InitiateWithPrimaryCompleteWithConfirmation // | Self::InitiateWithPrimaryDelayedCompletion - ) - } + pub fn order_of_instruction_setting_rola( + &self, + security_structure_of_factor_instances: &SecurityStructureOfFactorInstances, + entity: &AnySecurifiedEntity, + ) -> OrderOfInstructionSettingRolaKey { + if security_structure_of_factor_instances + .authentication_signing_factor_instance + == entity.current_authentication_signing_factor_instance() + { + // The factor of ROLA key is the same as the current factor of the entity + // => we can skip setting the ROLA key. + return OrderOfInstructionSettingRolaKey::NotNeeded; + } - /// If we can set the ROLA key for this combination of roles. - pub fn can_set_rola_key(&self) -> bool { - self.can_exercise_primary_role() + if self.can_quick_confirm() { + // we can quick confirm so we can always set the ROLA key using + // the NEW factors - disregarding of which role initiated recovery. + OrderOfInstructionSettingRolaKey::AfterQuickConfirm + } else { + match self.role_initiating_recovery() { + RoleInitiatingRecovery::Primary => { + // We cannot quick confirm and set ROLA key using new factors in + // the same TX, but fortunately we can set the ROLA key and auth with + // th old factors if we place the SET_METADATA instruction + // **before** initiating recovery instruction. + OrderOfInstructionSettingRolaKey::BeforeInitRecovery + } + RoleInitiatingRecovery::Recovery => { + // We cannot set ROLA key in this TX, because we are not using the + // quick confirm - so we must do it in a future TX. + OrderOfInstructionSettingRolaKey::MustSetInFutureTxForConfirmRecovery + } + } + } } - fn initiate_recovery_with_primary(&self) -> bool { - matches!( - self, + fn role_initiating_recovery(&self) -> RoleInitiatingRecovery { + match self { Self::InitiateWithPrimaryCompleteWithRecovery - | Self::InitiateWithPrimaryCompleteWithConfirmation // | Self::InitiateWithPrimaryDelayedCompletion - ) - } - fn initiate_recovery_with_recovery(&self) -> bool { - matches!( - self, + | Self::InitiateWithPrimaryCompleteWithConfirmation + | Self::InitiateWithPrimaryDelayedCompletion => { + RoleInitiatingRecovery::Primary + } Self::InitiateWithRecoveryCompleteWithConfirmation - | Self::InitiateWithRecoveryDelayedCompletion - ) - } - - fn quick_confirm_with_recovery(&self) -> bool { - matches!(self, Self::InitiateWithPrimaryCompleteWithRecovery) + | Self::InitiateWithRecoveryDelayedCompletion => { + RoleInitiatingRecovery::Recovery + } + } } - fn quick_confirm_with_confirmation(&self) -> bool { - matches!( - self, + fn can_quick_confirm(&self) -> bool { + match self { Self::InitiateWithPrimaryCompleteWithConfirmation - | Self::InitiateWithRecoveryCompleteWithConfirmation - ) + | Self::InitiateWithRecoveryCompleteWithConfirmation + | Self::InitiateWithPrimaryCompleteWithRecovery => true, + Self::InitiateWithRecoveryDelayedCompletion + | Self::InitiateWithPrimaryDelayedCompletion => false, + } } /// Returns method identifier and input for **initiating** recovery @@ -141,32 +189,27 @@ impl RolesExercisableInTransactionManifestCombination { &self, factors_and_time: &AccessControllerFactorsAndTimeInput, ) -> (&'static str, Box) { - if self.initiate_recovery_with_primary() { - // Recovery was initiated with `Primary` and needs to be confirmed with `Recovery` or with `Confirmation` - // as per specified by this RolesExercisableInTransactionManifestCombination - ( - SCRYPTO_ACCESS_CONTROLLER_INITIATE_RECOVERY_AS_PRIMARY_IDENT, - Box::new( - ScryptoAccessControllerInitiateRecoveryAsPrimaryInput::from( - factors_and_time, + match self.role_initiating_recovery() { + RoleInitiatingRecovery::Primary => { + ( + SCRYPTO_ACCESS_CONTROLLER_INITIATE_RECOVERY_AS_PRIMARY_IDENT, + Box::new( + ScryptoAccessControllerInitiateRecoveryAsPrimaryInput::from( + factors_and_time, + ), ), - ), - ) - } else if self.initiate_recovery_with_recovery() { - // Recovery was initiated with `Recovery` and needs to be confirmed with - // `Confirmation` role - ( - SCRYPTO_ACCESS_CONTROLLER_INITIATE_RECOVERY_AS_RECOVERY_IDENT, - Box::new( - ScryptoAccessControllerInitiateRecoveryAsRecoveryInput::from( - factors_and_time, + ) + } + RoleInitiatingRecovery::Recovery => { + ( + SCRYPTO_ACCESS_CONTROLLER_INITIATE_RECOVERY_AS_RECOVERY_IDENT, + Box::new( + ScryptoAccessControllerInitiateRecoveryAsRecoveryInput::from( + factors_and_time, + ), ), - ), - ) - } else { - unreachable!( - "unable to calculate input_for_initialization - this is a programmer error" - ) + ) + } } } @@ -178,23 +221,16 @@ impl RolesExercisableInTransactionManifestCombination { &self, factors_and_time: &AccessControllerFactorsAndTimeInput, ) -> Option<(&'static str, Box)> { - if self.quick_confirm_with_confirmation() - || self.quick_confirm_with_recovery() - { - if self.initiate_recovery_with_primary() { - Some(( + if self.can_quick_confirm() { + match self.role_initiating_recovery() { + RoleInitiatingRecovery::Primary => Some(( SCRYPTO_ACCESS_CONTROLLER_QUICK_CONFIRM_PRIMARY_ROLE_RECOVERY_PROPOSAL_IDENT, Box::new(ScryptoAccessControllerQuickConfirmPrimaryRoleRecoveryProposalInput::from(factors_and_time)) - )) - } else if self.initiate_recovery_with_recovery() { - Some(( + )), + RoleInitiatingRecovery::Recovery => Some(( SCRYPTO_ACCESS_CONTROLLER_QUICK_CONFIRM_RECOVERY_ROLE_RECOVERY_PROPOSAL_IDENT, Box::new(ScryptoAccessControllerQuickConfirmRecoveryRoleRecoveryProposalInput::from(factors_and_time)) )) - } else { - unreachable!( - "unable to calculate input_for_quick_confirm - this is a programmer error" - ) } } else { // Time based cannot happen yet - host (user) need to wait the specified diff --git a/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_unsecurified_entity_owner_badge_into_bucket_putting.rs b/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_unsecurified_entity_owner_badge_into_bucket_putting.rs index 55d8975dd..ec957bc2a 100644 --- a/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_unsecurified_entity_owner_badge_into_bucket_putting.rs +++ b/crates/transaction/manifests/src/manifests_security_shield/transaction_manifest_unsecurified_entity_owner_badge_into_bucket_putting.rs @@ -14,12 +14,10 @@ pub trait TransactionManifestUnsecurifiedEntityOwnerBadgeIntoBucketPutting { builder: ScryptoTransactionManifestBuilder, unsecurified_entity: &AnyUnsecurifiedEntity, ) -> (ScryptoTransactionManifestBuilder, ScryptoManifestBucket) { - let is_account = unsecurified_entity.entity.is_account_entity(); let owner_badge_bucket_name = "owner_badge_bucket"; - let owner_badge = if is_account { - SCRYPTO_ACCOUNT_OWNER_BADGE - } else { - SCRYPTO_IDENTITY_OWNER_BADGE + let owner_badge = match unsecurified_entity.entity.get_entity_kind() { + CAP26EntityKind::Account => SCRYPTO_ACCOUNT_OWNER_BADGE, + CAP26EntityKind::Identity => SCRYPTO_IDENTITY_OWNER_BADGE, }; let mut builder = Self::call_securify_for_unsecurified_entity( builder, diff --git a/fixtures/models/interaction/wallet_interaction_batch_of_transactions.json b/fixtures/models/interaction/wallet_interaction_batch_of_transactions.json index ac75066cd..83fa2ae9f 100644 --- a/fixtures/models/interaction/wallet_interaction_batch_of_transactions.json +++ b/fixtures/models/interaction/wallet_interaction_batch_of_transactions.json @@ -1,20 +1,20 @@ { - "transactions": [ - { - "transactionManifest": "CALL_METHOD\n Address(\"account_rdx128mh2ae9dsrwa0t8l37ayjrxxf0p84e6qm227ytxtcu447f5uw5m8w\")\n \"securify\"\n;\nTAKE_FROM_WORKTOP\n Address(\"resource_rdx1nfxxxxxxxxxxaccwnrxxxxxxxxx006664022062xxxxxxxxxaccwnr\")\n Decimal(\"1\")\n Bucket(\"bucket1\")\n;\nALLOCATE_GLOBAL_ADDRESS\n Address(\"package_rdx1pkgxxxxxxxxxcntrlrxxxxxxxxx000648572295xxxxxxxxxcntrlr\")\n \"AccessController\"\n AddressReservation(\"reservation1\")\n NamedAddress(\"address1\")\n;\nCREATE_ACCESS_CONTROLLER\n Bucket(\"bucket1\")\n Tuple(\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[0e8695a4117774464ca04bb6d10ce0b11aede12bd797dcdee811067094]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[0e8695a4117774464ca04bb6d10ce0b11aede12bd797dcdee811067094]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[0e8695a4117774464ca04bb6d10ce0b11aede12bd797dcdee811067094]\")\n )\n )\n )\n )\n )\n )\n )\n )\n Enum<1u8>(\n 20160u32\n )\n Enum<1u8>(\n AddressReservation(\"reservation1\")\n )\n;\nSET_METADATA\n Address(\"account_rdx128mh2ae9dsrwa0t8l37ayjrxxf0p84e6qm227ytxtcu447f5uw5m8w\")\n \"owner_keys\"\n Enum<143u8>(\n Array(\n Enum<1u8>(\n Bytes(\"8e7da995687de79d87a51e4acadccbeea15df2b165800247930298bc16\")\n )\n )\n )\n;\n", - "blobs": [] - }, - { - "transactionManifest": "CALL_METHOD\n Address(\"identity_rdx122kkqj7pc04gwsgcwsxmfmknlsg4qpz52rrs6vj72cujks4ukw993v\")\n \"securify\"\n;\nTAKE_FROM_WORKTOP\n Address(\"resource_rdx1nfxxxxxxxxxxdntwnrxxxxxxxxx002876444928xxxxxxxxxdntwnr\")\n Decimal(\"1\")\n Bucket(\"bucket1\")\n;\nALLOCATE_GLOBAL_ADDRESS\n Address(\"package_rdx1pkgxxxxxxxxxcntrlrxxxxxxxxx000648572295xxxxxxxxxcntrlr\")\n \"AccessController\"\n AddressReservation(\"reservation1\")\n NamedAddress(\"address1\")\n;\nCREATE_ACCESS_CONTROLLER\n Bucket(\"bucket1\")\n Tuple(\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[0b5896b1b5a1de8573b3a90216e7b14b42aa11746ad2e0bcb0741c216d]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[0b5896b1b5a1de8573b3a90216e7b14b42aa11746ad2e0bcb0741c216d]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[0b5896b1b5a1de8573b3a90216e7b14b42aa11746ad2e0bcb0741c216d]\")\n )\n )\n )\n )\n )\n )\n )\n )\n Enum<1u8>(\n 20160u32\n )\n Enum<1u8>(\n AddressReservation(\"reservation1\")\n )\n;\nSET_METADATA\n Address(\"identity_rdx122kkqj7pc04gwsgcwsxmfmknlsg4qpz52rrs6vj72cujks4ukw993v\")\n \"owner_keys\"\n Enum<143u8>(\n Array(\n Enum<1u8>(\n Bytes(\"a9a3197f2553f4cfe4603e77fd1802f14490862e11a33d81c98c430e31\")\n )\n )\n )\n;\n", - "blobs": [] - }, - { - "transactionManifest": "CALL_METHOD\n Address(\"accesscontroller_rdx1c0duj4lq0dc3cpl8qd420fpn5eckh8ljeysvjm894lyl5ja5yq6y5a\")\n \"initiate_recovery_as_primary\"\n Tuple(\n Tuple(\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[bfcba3ae8b30485830dc1dc578b2f921b1b65cb2a391cb063c0f1b6106]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[bfcba3ae8b30485830dc1dc578b2f921b1b65cb2a391cb063c0f1b6106]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[bfcba3ae8b30485830dc1dc578b2f921b1b65cb2a391cb063c0f1b6106]\")\n )\n )\n )\n )\n )\n )\n )\n ),\n Enum<1u8>(\n 20160u32\n )\n )\n;\nCALL_METHOD\n Address(\"accesscontroller_rdx1c0duj4lq0dc3cpl8qd420fpn5eckh8ljeysvjm894lyl5ja5yq6y5a\")\n \"quick_confirm_primary_role_recovery_proposal\"\n Tuple(\n Tuple(\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[bfcba3ae8b30485830dc1dc578b2f921b1b65cb2a391cb063c0f1b6106]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[bfcba3ae8b30485830dc1dc578b2f921b1b65cb2a391cb063c0f1b6106]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[bfcba3ae8b30485830dc1dc578b2f921b1b65cb2a391cb063c0f1b6106]\")\n )\n )\n )\n )\n )\n )\n )\n ),\n Enum<1u8>(\n 20160u32\n )\n )\n;\nSET_METADATA\n Address(\"account_rdx12xek3geay25lktmk5zyplc7z7mg5xe8ldh48ta4mkcd9q0v0q6l8y6\")\n \"owner_keys\"\n Enum<143u8>(\n Array(\n Enum<1u8>(\n Bytes(\"e2e27b925c7d98ebe436172f00b024862127b26b40decd416ca41cdb48\")\n )\n )\n )\n;\n", - "blobs": [] - }, - { - "transactionManifest": "CALL_METHOD\n Address(\"accesscontroller_rdx1cv93xuha64eay8ctkx9km0el2jgkuh6gqlwec7tzecccyu0rj37xak\")\n \"initiate_recovery_as_primary\"\n Tuple(\n Tuple(\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n )\n ),\n Enum<1u8>(\n 20160u32\n )\n )\n;\nCALL_METHOD\n Address(\"accesscontroller_rdx1cv93xuha64eay8ctkx9km0el2jgkuh6gqlwec7tzecccyu0rj37xak\")\n \"quick_confirm_primary_role_recovery_proposal\"\n Tuple(\n Tuple(\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n )\n ),\n Enum<1u8>(\n 20160u32\n )\n )\n;\n", - "blobs": [] - } - ] + "transactions": [ + { + "transactionManifest": "CALL_METHOD\n Address(\"account_rdx128mh2ae9dsrwa0t8l37ayjrxxf0p84e6qm227ytxtcu447f5uw5m8w\")\n \"securify\"\n;\nTAKE_FROM_WORKTOP\n Address(\"resource_rdx1nfxxxxxxxxxxaccwnrxxxxxxxxx006664022062xxxxxxxxxaccwnr\")\n Decimal(\"1\")\n Bucket(\"bucket1\")\n;\nALLOCATE_GLOBAL_ADDRESS\n Address(\"package_rdx1pkgxxxxxxxxxcntrlrxxxxxxxxx000648572295xxxxxxxxxcntrlr\")\n \"AccessController\"\n AddressReservation(\"reservation1\")\n NamedAddress(\"address1\")\n;\nCREATE_ACCESS_CONTROLLER\n Bucket(\"bucket1\")\n Tuple(\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[0e8695a4117774464ca04bb6d10ce0b11aede12bd797dcdee811067094]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[0e8695a4117774464ca04bb6d10ce0b11aede12bd797dcdee811067094]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[0e8695a4117774464ca04bb6d10ce0b11aede12bd797dcdee811067094]\")\n )\n )\n )\n )\n )\n )\n )\n )\n Enum<1u8>(\n 20160u32\n )\n Enum<1u8>(\n AddressReservation(\"reservation1\")\n )\n;\nSET_METADATA\n Address(\"account_rdx128mh2ae9dsrwa0t8l37ayjrxxf0p84e6qm227ytxtcu447f5uw5m8w\")\n \"owner_keys\"\n Enum<143u8>(\n Array(\n Enum<1u8>(\n Bytes(\"8e7da995687de79d87a51e4acadccbeea15df2b165800247930298bc16\")\n )\n )\n )\n;\n", + "blobs": [] + }, + { + "transactionManifest": "CALL_METHOD\n Address(\"identity_rdx122kkqj7pc04gwsgcwsxmfmknlsg4qpz52rrs6vj72cujks4ukw993v\")\n \"securify\"\n;\nTAKE_FROM_WORKTOP\n Address(\"resource_rdx1nfxxxxxxxxxxdntwnrxxxxxxxxx002876444928xxxxxxxxxdntwnr\")\n Decimal(\"1\")\n Bucket(\"bucket1\")\n;\nALLOCATE_GLOBAL_ADDRESS\n Address(\"package_rdx1pkgxxxxxxxxxcntrlrxxxxxxxxx000648572295xxxxxxxxxcntrlr\")\n \"AccessController\"\n AddressReservation(\"reservation1\")\n NamedAddress(\"address1\")\n;\nCREATE_ACCESS_CONTROLLER\n Bucket(\"bucket1\")\n Tuple(\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[0b5896b1b5a1de8573b3a90216e7b14b42aa11746ad2e0bcb0741c216d]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[0b5896b1b5a1de8573b3a90216e7b14b42aa11746ad2e0bcb0741c216d]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[0b5896b1b5a1de8573b3a90216e7b14b42aa11746ad2e0bcb0741c216d]\")\n )\n )\n )\n )\n )\n )\n )\n )\n Enum<1u8>(\n 20160u32\n )\n Enum<1u8>(\n AddressReservation(\"reservation1\")\n )\n;\nSET_METADATA\n Address(\"identity_rdx122kkqj7pc04gwsgcwsxmfmknlsg4qpz52rrs6vj72cujks4ukw993v\")\n \"owner_keys\"\n Enum<143u8>(\n Array(\n Enum<1u8>(\n Bytes(\"a9a3197f2553f4cfe4603e77fd1802f14490862e11a33d81c98c430e31\")\n )\n )\n )\n;\n", + "blobs": [] + }, + { + "transactionManifest": "CALL_METHOD\n Address(\"accesscontroller_rdx1c0duj4lq0dc3cpl8qd420fpn5eckh8ljeysvjm894lyl5ja5yq6y5a\")\n \"initiate_recovery_as_recovery\"\n Tuple(\n Tuple(\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[bfcba3ae8b30485830dc1dc578b2f921b1b65cb2a391cb063c0f1b6106]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[bfcba3ae8b30485830dc1dc578b2f921b1b65cb2a391cb063c0f1b6106]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[bfcba3ae8b30485830dc1dc578b2f921b1b65cb2a391cb063c0f1b6106]\")\n )\n )\n )\n )\n )\n )\n )\n ),\n Enum<1u8>(\n 20160u32\n )\n )\n;\nCALL_METHOD\n Address(\"accesscontroller_rdx1c0duj4lq0dc3cpl8qd420fpn5eckh8ljeysvjm894lyl5ja5yq6y5a\")\n \"quick_confirm_recovery_role_recovery_proposal\"\n Tuple(\n Tuple(\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[bfcba3ae8b30485830dc1dc578b2f921b1b65cb2a391cb063c0f1b6106]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[bfcba3ae8b30485830dc1dc578b2f921b1b65cb2a391cb063c0f1b6106]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[bfcba3ae8b30485830dc1dc578b2f921b1b65cb2a391cb063c0f1b6106]\")\n )\n )\n )\n )\n )\n )\n )\n ),\n Enum<1u8>(\n 20160u32\n )\n )\n;\nSET_METADATA\n Address(\"account_rdx12xek3geay25lktmk5zyplc7z7mg5xe8ldh48ta4mkcd9q0v0q6l8y6\")\n \"owner_keys\"\n Enum<143u8>(\n Array(\n Enum<1u8>(\n Bytes(\"e2e27b925c7d98ebe436172f00b024862127b26b40decd416ca41cdb48\")\n )\n )\n )\n;\n", + "blobs": [] + }, + { + "transactionManifest": "CALL_METHOD\n Address(\"accesscontroller_rdx1cv93xuha64eay8ctkx9km0el2jgkuh6gqlwec7tzecccyu0rj37xak\")\n \"initiate_recovery_as_recovery\"\n Tuple(\n Tuple(\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n )\n ),\n Enum<1u8>(\n 20160u32\n )\n )\n;\nCALL_METHOD\n Address(\"accesscontroller_rdx1cv93xuha64eay8ctkx9km0el2jgkuh6gqlwec7tzecccyu0rj37xak\")\n \"quick_confirm_recovery_role_recovery_proposal\"\n Tuple(\n Tuple(\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n ),\n Enum<2u8>(\n Enum<1u8>(\n Array(\n Enum<0u8>(\n Enum<2u8>(\n 0u8,\n Array()\n )\n ),\n Enum<0u8>(\n Enum<4u8>(\n Array(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_rdx1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxxed25sg:[388cd2d9ce11b878ba78fd193b5c5b34a8a497eb6cf9f0b4aac5a72a8a]\")\n )\n )\n )\n )\n )\n )\n )\n ),\n Enum<1u8>(\n 20160u32\n )\n )\n;\n", + "blobs": [] + } + ] } \ No newline at end of file diff --git a/fixtures/transaction/update_shield_of_persona_init_with_P_confirm_with_T.rtm b/fixtures/transaction/update_shield_of_persona_init_with_P_confirm_with_T.rtm index 1e033b62a..2343dee1b 100644 --- a/fixtures/transaction/update_shield_of_persona_init_with_P_confirm_with_T.rtm +++ b/fixtures/transaction/update_shield_of_persona_init_with_P_confirm_with_T.rtm @@ -1,3 +1,14 @@ +SET_METADATA + Address("identity_rdx12fczzwcn62phgf099l2d2l2huz7rag7zglujrvc5cc0z9szs2dzevj") + "owner_keys" + Enum<143u8>( + Array( + Enum<1u8>( + Bytes("675506ad8d7ce4c602cb06c593c0f10e1cc4dcdf2c4144360ef33ebeef") + ) + ) + ) +; CALL_METHOD Address("accesscontroller_rdx1cdf8qgfmz0fgxap9u5haf4ta2lstc04rcfrljgdnznrpugkqv2wudm") "initiate_recovery_as_primary" @@ -71,15 +82,4 @@ CALL_METHOD 20160u32 ) ) -; -SET_METADATA - Address("identity_rdx12fczzwcn62phgf099l2d2l2huz7rag7zglujrvc5cc0z9szs2dzevj") - "owner_keys" - Enum<143u8>( - Array( - Enum<1u8>( - Bytes("675506ad8d7ce4c602cb06c593c0f10e1cc4dcdf2c4144360ef33ebeef") - ) - ) - ) ; \ No newline at end of file diff --git a/fixtures/transaction/update_shield_of_persona_init_with_R_confirm_with_C.rtm b/fixtures/transaction/update_shield_of_persona_init_with_R_confirm_with_C.rtm index 6d7ec8173..05b014baa 100644 --- a/fixtures/transaction/update_shield_of_persona_init_with_R_confirm_with_C.rtm +++ b/fixtures/transaction/update_shield_of_persona_init_with_R_confirm_with_C.rtm @@ -145,4 +145,15 @@ CALL_METHOD 20160u32 ) ) +; +SET_METADATA + Address("identity_rdx12fczzwcn62phgf099l2d2l2huz7rag7zglujrvc5cc0z9szs2dzevj") + "owner_keys" + Enum<143u8>( + Array( + Enum<1u8>( + Bytes("675506ad8d7ce4c602cb06c593c0f10e1cc4dcdf2c4144360ef33ebeef") + ) + ) + ) ; \ No newline at end of file From f24f196dc4a65e4d2deb4154ea149f91166ff0df Mon Sep 17 00:00:00 2001 From: Alexander Cyon Date: Wed, 29 Jan 2025 13:52:50 +0100 Subject: [PATCH 24/25] dont set ROLA key when using timed completion of recovery. --- .../batch_of_transactions.rs | 4 +- ...fests_securify_shield_securified_entity.rs | 13 ++-- ...ble_in_transaction_manifest_combination.rs | 64 ++++++++++--------- ..._of_account_init_with_P_confirm_with_C.rtm | 22 +++---- ..._where_payer_is_entity_applying_shield.rtm | 22 +++---- ...s_entity_applying_shield_with_xrd_lock.rtm | 22 +++---- ..._of_persona_init_with_P_confirm_with_C.rtm | 22 +++---- ..._of_persona_init_with_P_confirm_with_T.rtm | 11 ---- ...of_persona_init_with_R_confirm_with_P.rtm} | 4 +- 9 files changed, 87 insertions(+), 97 deletions(-) rename fixtures/transaction/{update_shield_of_persona_init_with_P_confirm_with_R.rtm => update_shield_of_persona_init_with_R_confirm_with_P.rtm} (98%) diff --git a/crates/app/radix-connect/src/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/batch_of_transactions.rs b/crates/app/radix-connect/src/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/batch_of_transactions.rs index b822d2f97..a35045129 100644 --- a/crates/app/radix-connect/src/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/batch_of_transactions.rs +++ b/crates/app/radix-connect/src/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/batch_of_transactions.rs @@ -20,7 +20,7 @@ impl DappToWalletInteractionBatchOfTransactions { impl HasSampleValues for DappToWalletInteractionBatchOfTransactions { fn sample() -> Self { let init_p_conf_r = TransactionManifest::new( - fixture_rtm!("update_shield_of_persona_init_with_P_confirm_with_R"), + fixture_rtm!("update_shield_of_persona_init_with_R_confirm_with_P"), NetworkID::Mainnet, Blobs::default(), ) @@ -39,7 +39,7 @@ impl HasSampleValues for DappToWalletInteractionBatchOfTransactions { fn sample_other() -> Self { let init_p_conf_c = TransactionManifest::new( - fixture_rtm!("update_shield_of_persona_init_with_P_confirm_with_R"), + fixture_rtm!("update_shield_of_persona_init_with_R_confirm_with_P"), NetworkID::Mainnet, Blobs::default(), ) diff --git a/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs b/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs index 3a4c8ef78..ee302c7cf 100644 --- a/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs +++ b/crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs @@ -197,10 +197,10 @@ mod tests { } #[test] - fn update_shield_of_securified_persona_init_with_P_confirm_with_R() { + fn update_shield_of_securified_persona_init_with_R_confirm_with_P() { let instruction_discriminants = test_update_shield_of_securified_persona( - RolesExercisableInTransactionManifestCombination::InitiateWithPrimaryCompleteWithRecovery, - || fixture_rtm!("update_shield_of_persona_init_with_P_confirm_with_R") + RolesExercisableInTransactionManifestCombination::InitiateWithRecoveryCompleteWithPrimary, + || fixture_rtm!("update_shield_of_persona_init_with_R_confirm_with_P") ); assert_eq!( instruction_discriminants, @@ -221,10 +221,11 @@ mod tests { assert_eq!( instruction_discriminants, vec![ + CallMetadataMethod::ID, // set ROLA key CallMethod::ID, // init CallMethod::ID, // quick confirm - CallMetadataMethod::ID, // set ROLA key - ] + ], + "Expected to FIRST set ROLA key and THEN init - since we can set it using existing factors." ); } @@ -237,10 +238,8 @@ mod tests { assert_eq!( instruction_discriminants, vec![ - CallMetadataMethod::ID, // set ROLA key CallMethod::ID // init ], - "Expected to FIRST set ROLA key and THEN init - since we can set it using existing factors." ); } diff --git a/crates/transaction/manifests/src/manifests_security_shield/roles_exercisable_in_transaction_manifest_combination.rs b/crates/transaction/manifests/src/manifests_security_shield/roles_exercisable_in_transaction_manifest_combination.rs index 18b8e5ac6..b3d76c3f0 100644 --- a/crates/transaction/manifests/src/manifests_security_shield/roles_exercisable_in_transaction_manifest_combination.rs +++ b/crates/transaction/manifests/src/manifests_security_shield/roles_exercisable_in_transaction_manifest_combination.rs @@ -25,13 +25,9 @@ use radix_engine_interface::blueprints::access_controller::{ /// and still be able to recover + confirm the AccessController update. #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, enum_iterator::Sequence)] pub enum RolesExercisableInTransactionManifestCombination { - /// Initiates recovery using `Primary` role and quick confirms using - /// `Recovery` role explicitly. - InitiateWithPrimaryCompleteWithRecovery, - - /// Initiates recovery using `Primary` role and quick confirms using - /// `Confirmation` role explicitly. - InitiateWithPrimaryCompleteWithConfirmation, + /// Initiates recovery using `Recovery` role and quick confirms using + /// `Primary` role explicitly. + InitiateWithRecoveryCompleteWithPrimary, /// Initiates recovery using `Recovery` role and quick confirms using /// `Confirmation` role explicitly. @@ -52,7 +48,11 @@ pub enum RolesExercisableInTransactionManifestCombination { /// can call the `confirm_timed_recovery` method after the time has elapsed. InitiateWithRecoveryDelayedCompletion, - /// ‼️ Requires fuuture network upgrade "Dugong" + /// Initiates recovery using `Primary` role and quick confirms using + /// `Confirmation` role explicitly. + InitiateWithPrimaryCompleteWithConfirmation, + + /// ‼️ Requires future network upgrade "Dugong" /// /// Initiate recovery with `Primary` role and use timed confirmation. /// @@ -68,7 +68,7 @@ pub enum RolesExercisableInTransactionManifestCombination { /// Host will also need to schedule a notification for user so that host /// can call the `confirm_timed_recovery` method after the time has elapsed. /// - /// ‼️ Requires fuuture network upgrade "Dugong" + /// ‼️ Requires future network upgrade "Dugong" InitiateWithPrimaryDelayedCompletion, // TODO: // FUTURE IMPROVEMENTS, @@ -137,36 +137,38 @@ impl RolesExercisableInTransactionManifestCombination { return OrderOfInstructionSettingRolaKey::NotNeeded; } - if self.can_quick_confirm() { - // we can quick confirm so we can always set the ROLA key using - // the NEW factors - disregarding of which role initiated recovery. - OrderOfInstructionSettingRolaKey::AfterQuickConfirm - } else { - match self.role_initiating_recovery() { - RoleInitiatingRecovery::Primary => { - // We cannot quick confirm and set ROLA key using new factors in - // the same TX, but fortunately we can set the ROLA key and auth with - // th old factors if we place the SET_METADATA instruction - // **before** initiating recovery instruction. - OrderOfInstructionSettingRolaKey::BeforeInitRecovery - } - RoleInitiatingRecovery::Recovery => { - // We cannot set ROLA key in this TX, because we are not using the - // quick confirm - so we must do it in a future TX. - OrderOfInstructionSettingRolaKey::MustSetInFutureTxForConfirmRecovery - } + if !self.can_quick_confirm() { + // N.B. + // In case of role initiating the recovery being `Primary` we CAN in fact + // set the ROLA key in the same transaction as we initiate recovery, however, + // if we CANCEL the recovery proposal (instead of CONFIRM) in the future + // transaction we would be in a bad state (not using the old nor the new shield). + return OrderOfInstructionSettingRolaKey::MustSetInFutureTxForConfirmRecovery; + } + + match self.role_initiating_recovery() { + RoleInitiatingRecovery::Primary => { + // We can exercise the Primary Role => no need + // to set the ROLA key after recovery and use new factors, instead + // we can use existing factors + OrderOfInstructionSettingRolaKey::BeforeInitRecovery + } + RoleInitiatingRecovery::Recovery => { + // we can quick confirm so we can always set the ROLA key using + // the NEW factors - disregarding of which role initiated recovery. + OrderOfInstructionSettingRolaKey::AfterQuickConfirm } } } fn role_initiating_recovery(&self) -> RoleInitiatingRecovery { match self { - Self::InitiateWithPrimaryCompleteWithRecovery - | Self::InitiateWithPrimaryCompleteWithConfirmation + Self::InitiateWithPrimaryCompleteWithConfirmation | Self::InitiateWithPrimaryDelayedCompletion => { RoleInitiatingRecovery::Primary } - Self::InitiateWithRecoveryCompleteWithConfirmation + Self::InitiateWithRecoveryCompleteWithPrimary + | Self::InitiateWithRecoveryCompleteWithConfirmation | Self::InitiateWithRecoveryDelayedCompletion => { RoleInitiatingRecovery::Recovery } @@ -177,7 +179,7 @@ impl RolesExercisableInTransactionManifestCombination { match self { Self::InitiateWithPrimaryCompleteWithConfirmation | Self::InitiateWithRecoveryCompleteWithConfirmation - | Self::InitiateWithPrimaryCompleteWithRecovery => true, + | Self::InitiateWithRecoveryCompleteWithPrimary => true, Self::InitiateWithRecoveryDelayedCompletion | Self::InitiateWithPrimaryDelayedCompletion => false, } diff --git a/fixtures/transaction/update_shield_of_account_init_with_P_confirm_with_C.rtm b/fixtures/transaction/update_shield_of_account_init_with_P_confirm_with_C.rtm index 5d38fdbd7..acfff3388 100644 --- a/fixtures/transaction/update_shield_of_account_init_with_P_confirm_with_C.rtm +++ b/fixtures/transaction/update_shield_of_account_init_with_P_confirm_with_C.rtm @@ -1,3 +1,14 @@ +SET_METADATA + Address("account_rdx12xq83qxwf09eqquqfdj8rv004attq5tgxejkn59rwu588jprdy0xcg") + "owner_keys" + Enum<143u8>( + Array( + Enum<1u8>( + Bytes("cb3f6086cd08a1d0ab10139a9c6d191783edb534059f7b4716dc5d239e") + ) + ) + ) +; CALL_METHOD Address("accesscontroller_rdx1cdgcq7yqee9uhyqrsp9kgud3a7h4dvz3dqmx26ws5dmjsu7g3zg23g") "initiate_recovery_as_primary" @@ -157,15 +168,4 @@ CALL_METHOD 20160u32 ) ) -; -SET_METADATA - Address("account_rdx12xq83qxwf09eqquqfdj8rv004attq5tgxejkn59rwu588jprdy0xcg") - "owner_keys" - Enum<143u8>( - Array( - Enum<1u8>( - Bytes("cb3f6086cd08a1d0ab10139a9c6d191783edb534059f7b4716dc5d239e") - ) - ) - ) ; \ No newline at end of file diff --git a/fixtures/transaction/update_shield_of_account_init_with_P_confirm_with_C_with_top_up_where_payer_is_entity_applying_shield.rtm b/fixtures/transaction/update_shield_of_account_init_with_P_confirm_with_C_with_top_up_where_payer_is_entity_applying_shield.rtm index 058704ed9..ef7959202 100644 --- a/fixtures/transaction/update_shield_of_account_init_with_P_confirm_with_C_with_top_up_where_payer_is_entity_applying_shield.rtm +++ b/fixtures/transaction/update_shield_of_account_init_with_P_confirm_with_C_with_top_up_where_payer_is_entity_applying_shield.rtm @@ -1,3 +1,14 @@ +SET_METADATA + Address("account_rdx12xq83qxwf09eqquqfdj8rv004attq5tgxejkn59rwu588jprdy0xcg") + "owner_keys" + Enum<143u8>( + Array( + Enum<1u8>( + Bytes("cb3f6086cd08a1d0ab10139a9c6d191783edb534059f7b4716dc5d239e") + ) + ) + ) +; CALL_METHOD Address("accesscontroller_rdx1cdgcq7yqee9uhyqrsp9kgud3a7h4dvz3dqmx26ws5dmjsu7g3zg23g") "initiate_recovery_as_primary" @@ -158,17 +169,6 @@ CALL_METHOD ) ) ; -SET_METADATA - Address("account_rdx12xq83qxwf09eqquqfdj8rv004attq5tgxejkn59rwu588jprdy0xcg") - "owner_keys" - Enum<143u8>( - Array( - Enum<1u8>( - Bytes("cb3f6086cd08a1d0ab10139a9c6d191783edb534059f7b4716dc5d239e") - ) - ) - ) -; CALL_METHOD Address("accesscontroller_rdx1cdgcq7yqee9uhyqrsp9kgud3a7h4dvz3dqmx26ws5dmjsu7g3zg23g") "create_proof" diff --git a/fixtures/transaction/update_shield_of_account_init_with_P_confirm_with_C_with_top_up_where_payer_is_entity_applying_shield_with_xrd_lock.rtm b/fixtures/transaction/update_shield_of_account_init_with_P_confirm_with_C_with_top_up_where_payer_is_entity_applying_shield_with_xrd_lock.rtm index 91287777f..e0e42b7b0 100644 --- a/fixtures/transaction/update_shield_of_account_init_with_P_confirm_with_C_with_top_up_where_payer_is_entity_applying_shield_with_xrd_lock.rtm +++ b/fixtures/transaction/update_shield_of_account_init_with_P_confirm_with_C_with_top_up_where_payer_is_entity_applying_shield_with_xrd_lock.rtm @@ -3,6 +3,17 @@ CALL_METHOD "lock_recovery_fee" Decimal("9") ; +SET_METADATA + Address("account_rdx12xq83qxwf09eqquqfdj8rv004attq5tgxejkn59rwu588jprdy0xcg") + "owner_keys" + Enum<143u8>( + Array( + Enum<1u8>( + Bytes("cb3f6086cd08a1d0ab10139a9c6d191783edb534059f7b4716dc5d239e") + ) + ) + ) +; CALL_METHOD Address("accesscontroller_rdx1cdgcq7yqee9uhyqrsp9kgud3a7h4dvz3dqmx26ws5dmjsu7g3zg23g") "initiate_recovery_as_primary" @@ -163,17 +174,6 @@ CALL_METHOD ) ) ; -SET_METADATA - Address("account_rdx12xq83qxwf09eqquqfdj8rv004attq5tgxejkn59rwu588jprdy0xcg") - "owner_keys" - Enum<143u8>( - Array( - Enum<1u8>( - Bytes("cb3f6086cd08a1d0ab10139a9c6d191783edb534059f7b4716dc5d239e") - ) - ) - ) -; CALL_METHOD Address("accesscontroller_rdx1cdgcq7yqee9uhyqrsp9kgud3a7h4dvz3dqmx26ws5dmjsu7g3zg23g") "create_proof" diff --git a/fixtures/transaction/update_shield_of_persona_init_with_P_confirm_with_C.rtm b/fixtures/transaction/update_shield_of_persona_init_with_P_confirm_with_C.rtm index 61ec30484..607708056 100644 --- a/fixtures/transaction/update_shield_of_persona_init_with_P_confirm_with_C.rtm +++ b/fixtures/transaction/update_shield_of_persona_init_with_P_confirm_with_C.rtm @@ -1,3 +1,14 @@ +SET_METADATA + Address("identity_rdx12fczzwcn62phgf099l2d2l2huz7rag7zglujrvc5cc0z9szs2dzevj") + "owner_keys" + Enum<143u8>( + Array( + Enum<1u8>( + Bytes("675506ad8d7ce4c602cb06c593c0f10e1cc4dcdf2c4144360ef33ebeef") + ) + ) + ) +; CALL_METHOD Address("accesscontroller_rdx1cdf8qgfmz0fgxap9u5haf4ta2lstc04rcfrljgdnznrpugkqv2wudm") "initiate_recovery_as_primary" @@ -145,15 +156,4 @@ CALL_METHOD 20160u32 ) ) -; -SET_METADATA - Address("identity_rdx12fczzwcn62phgf099l2d2l2huz7rag7zglujrvc5cc0z9szs2dzevj") - "owner_keys" - Enum<143u8>( - Array( - Enum<1u8>( - Bytes("675506ad8d7ce4c602cb06c593c0f10e1cc4dcdf2c4144360ef33ebeef") - ) - ) - ) ; \ No newline at end of file diff --git a/fixtures/transaction/update_shield_of_persona_init_with_P_confirm_with_T.rtm b/fixtures/transaction/update_shield_of_persona_init_with_P_confirm_with_T.rtm index 2343dee1b..2f3b55cbe 100644 --- a/fixtures/transaction/update_shield_of_persona_init_with_P_confirm_with_T.rtm +++ b/fixtures/transaction/update_shield_of_persona_init_with_P_confirm_with_T.rtm @@ -1,14 +1,3 @@ -SET_METADATA - Address("identity_rdx12fczzwcn62phgf099l2d2l2huz7rag7zglujrvc5cc0z9szs2dzevj") - "owner_keys" - Enum<143u8>( - Array( - Enum<1u8>( - Bytes("675506ad8d7ce4c602cb06c593c0f10e1cc4dcdf2c4144360ef33ebeef") - ) - ) - ) -; CALL_METHOD Address("accesscontroller_rdx1cdf8qgfmz0fgxap9u5haf4ta2lstc04rcfrljgdnznrpugkqv2wudm") "initiate_recovery_as_primary" diff --git a/fixtures/transaction/update_shield_of_persona_init_with_P_confirm_with_R.rtm b/fixtures/transaction/update_shield_of_persona_init_with_R_confirm_with_P.rtm similarity index 98% rename from fixtures/transaction/update_shield_of_persona_init_with_P_confirm_with_R.rtm rename to fixtures/transaction/update_shield_of_persona_init_with_R_confirm_with_P.rtm index 61ec30484..05b014baa 100644 --- a/fixtures/transaction/update_shield_of_persona_init_with_P_confirm_with_R.rtm +++ b/fixtures/transaction/update_shield_of_persona_init_with_R_confirm_with_P.rtm @@ -1,6 +1,6 @@ CALL_METHOD Address("accesscontroller_rdx1cdf8qgfmz0fgxap9u5haf4ta2lstc04rcfrljgdnznrpugkqv2wudm") - "initiate_recovery_as_primary" + "initiate_recovery_as_recovery" Tuple( Tuple( Enum<2u8>( @@ -74,7 +74,7 @@ CALL_METHOD ; CALL_METHOD Address("accesscontroller_rdx1cdf8qgfmz0fgxap9u5haf4ta2lstc04rcfrljgdnznrpugkqv2wudm") - "quick_confirm_primary_role_recovery_proposal" + "quick_confirm_recovery_role_recovery_proposal" Tuple( Tuple( Enum<2u8>( From 0de346a9947f374a87349da19e7d63046b1bc57b Mon Sep 17 00:00:00 2001 From: Alexander Cyon Date: Wed, 29 Jan 2025 15:01:23 +0100 Subject: [PATCH 25/25] Release 1.1.123 account-for-display@1.1.123 addresses@1.1.123 assert-json@1.1.123 build-info@1.1.123 bytes@1.1.123 cap26-models@1.1.123 clients@1.1.123 core-collections@1.1.123 core-misc@1.1.123 core-utils@1.1.123 drivers@1.1.123 ecc@1.1.123 encryption@1.1.123 entity-by-address@1.1.123 entity-foundation@1.1.123 error@1.1.123 factor-instances-provider@1.1.123 factors@1.1.123 factors-supporting-types@1.1.123 gateway-client-and-api@1.1.123 gateway-models@1.1.123 has-sample-values@1.1.123 hash@1.1.123 hierarchical-deterministic@1.1.123 home-cards@1.1.123 host-info@1.1.123 http-client@1.1.123 identified-vec-of@1.1.123 interactors@1.1.123 key-derivation-traits@1.1.123 keys-collector@1.1.123 manifests@1.1.123 metadata@1.1.123 network@1.1.123 next-derivation-index-ephemeral@1.1.123 numeric@1.1.123 prelude@1.1.123 profile@1.1.123 profile-account@1.1.123 profile-account-or-persona@1.1.123 profile-app-preferences@1.1.123 profile-base-entity@1.1.123 profile-gateway@1.1.123 profile-logic@1.1.123 profile-persona@1.1.123 profile-persona-data@1.1.123 profile-security-structures@1.1.123 profile-state-holder@1.1.123 profile-supporting-types@1.1.123 radix-connect@1.1.123 radix-connect-models@1.1.123 sargon@1.1.123 sargon-os@1.1.123 sargon-os-accounts@1.1.123 sargon-os-derive-public-keys@1.1.123 sargon-os-factors@1.1.123 sargon-os-security-center@1.1.123 sargon-os-signing@1.1.123 sargon-os-transaction@1.1.123 sargon-uniffi@1.1.123 sargon-uniffi-conversion-macros@1.1.123 security-center@1.1.123 short-string@1.1.123 signatures-collector@1.1.123 signing-traits@1.1.123 sub-systems@1.1.123 time-utils@1.1.123 transaction-foundation@1.1.123 transaction-models@1.1.123 Generated by cargo-workspaces --- Cargo.lock | 168 +++++++++--------- crates/app/home-cards/Cargo.toml | 2 +- crates/app/key-derivation-traits/Cargo.toml | 2 +- crates/app/radix-connect-models/Cargo.toml | 2 +- crates/app/radix-connect/Cargo.toml | 2 +- crates/app/security-center/Cargo.toml | 2 +- crates/app/signing-traits/Cargo.toml | 2 +- crates/common/build-info/Cargo.toml | 2 +- crates/common/bytes/Cargo.toml | 2 +- crates/common/entity-foundation/Cargo.toml | 2 +- crates/common/host-info/Cargo.toml | 2 +- crates/common/identified-vec-of/Cargo.toml | 2 +- crates/common/metadata/Cargo.toml | 2 +- crates/common/network/Cargo.toml | 2 +- crates/common/numeric/Cargo.toml | 2 +- crates/common/short-string/Cargo.toml | 2 +- crates/core/assert-json/Cargo.toml | 2 +- crates/core/collections/Cargo.toml | 2 +- crates/core/error/Cargo.toml | 2 +- crates/core/has-sample-values/Cargo.toml | 2 +- crates/core/misc/Cargo.toml | 2 +- crates/core/prelude/Cargo.toml | 2 +- crates/core/time-utils/Cargo.toml | 2 +- crates/core/utils/Cargo.toml | 2 +- crates/crypto/addresses/Cargo.toml | 2 +- crates/crypto/cap26-models/Cargo.toml | 2 +- crates/crypto/ecc/Cargo.toml | 2 +- crates/crypto/encryption/Cargo.toml | 2 +- crates/crypto/hash/Cargo.toml | 2 +- crates/crypto/hd/Cargo.toml | 2 +- crates/factors/factors/Cargo.toml | 2 +- crates/factors/instances-provider/Cargo.toml | 2 +- crates/factors/keys-collector/Cargo.toml | 2 +- .../Cargo.toml | 2 +- .../factors/signatures-collector/Cargo.toml | 2 +- crates/factors/supporting-types/Cargo.toml | 2 +- crates/gateway/client-and-api/Cargo.toml | 2 +- crates/gateway/models/Cargo.toml | 2 +- .../profile/logic/logic_SPLIT_ME/Cargo.toml | 2 +- .../models/account-for-display/Cargo.toml | 2 +- .../models/account-or-persona/Cargo.toml | 2 +- crates/profile/models/account/Cargo.toml | 2 +- .../profile/models/app-preferences/Cargo.toml | 2 +- crates/profile/models/base-entity/Cargo.toml | 2 +- crates/profile/models/gateway/Cargo.toml | 2 +- crates/profile/models/persona-data/Cargo.toml | 2 +- crates/profile/models/persona/Cargo.toml | 2 +- .../models/profile_SPLIT_ME/Cargo.toml | 2 +- .../models/security-structures/Cargo.toml | 2 +- .../models/supporting-types/Cargo.toml | 2 +- .../traits/entity-by-address/Cargo.toml | 2 +- crates/sargon/Cargo.toml | 2 +- crates/system/clients/clients/Cargo.toml | 2 +- crates/system/clients/http/Cargo.toml | 2 +- crates/system/drivers/Cargo.toml | 2 +- crates/system/interactors/Cargo.toml | 2 +- crates/system/os/accounts/Cargo.toml | 2 +- .../system/os/derive-public-keys/Cargo.toml | 2 +- crates/system/os/factors/Cargo.toml | 2 +- crates/system/os/os/Cargo.toml | 2 +- crates/system/os/security-center/Cargo.toml | 2 +- crates/system/os/signing/Cargo.toml | 2 +- crates/system/os/transaction/Cargo.toml | 2 +- crates/system/profile-state-holder/Cargo.toml | 2 +- crates/system/sub-systems/Cargo.toml | 2 +- crates/transaction/foundation/Cargo.toml | 2 +- crates/transaction/manifests/Cargo.toml | 2 +- crates/transaction/models/Cargo.toml | 2 +- crates/uniffi/conversion-macros/Cargo.toml | 2 +- crates/uniffi/uniffi_SPLIT_ME/Cargo.toml | 2 +- 70 files changed, 153 insertions(+), 153 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1b4573154..d68c5eb31 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,7 +4,7 @@ version = 4 [[package]] name = "account-for-display" -version = "1.1.122" +version = "1.1.123" dependencies = [ "addresses", "derive_more", @@ -49,10 +49,10 @@ dependencies = [ [[package]] name = "addresses" -version = "1.1.122" +version = "1.1.123" dependencies = [ "assert-json", - "bytes 1.1.122", + "bytes 1.1.123", "cap26-models", "core-utils", "derive_more", @@ -246,7 +246,7 @@ checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "assert-json" -version = "1.1.122" +version = "1.1.123" dependencies = [ "assert-json-diff", "error", @@ -546,7 +546,7 @@ dependencies = [ [[package]] name = "build-info" -version = "1.1.122" +version = "1.1.123" dependencies = [ "assert-json", "cargo_toml", @@ -573,7 +573,7 @@ checksum = "5ce89b21cab1437276d2650d57e971f9d548a2d9037cc231abdc0562b97498ce" [[package]] name = "bytes" -version = "1.1.122" +version = "1.1.123" dependencies = [ "assert-json", "delegate", @@ -607,7 +607,7 @@ dependencies = [ [[package]] name = "cap26-models" -version = "1.1.122" +version = "1.1.123" dependencies = [ "assert-json", "derive_more", @@ -748,7 +748,7 @@ checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" [[package]] name = "clients" -version = "1.1.122" +version = "1.1.123" dependencies = [ "actix-rt", "async-trait", @@ -808,7 +808,7 @@ checksum = "0d8a42181e0652c2997ae4d217f25b63c5337a52fd2279736e97b832fa0a3cff" [[package]] name = "core-collections" -version = "1.1.122" +version = "1.1.123" dependencies = [ "has-sample-values", "indexmap 2.7.0", @@ -835,7 +835,7 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "core-misc" -version = "1.1.122" +version = "1.1.123" dependencies = [ "assert-json", "core-utils", @@ -855,7 +855,7 @@ dependencies = [ [[package]] name = "core-utils" -version = "1.1.122" +version = "1.1.123" dependencies = [ "error", "iso8601-timestamp", @@ -1084,7 +1084,7 @@ checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" [[package]] name = "drivers" -version = "1.1.122" +version = "1.1.123" dependencies = [ "actix-rt", "addresses", @@ -1108,10 +1108,10 @@ dependencies = [ [[package]] name = "ecc" -version = "1.1.122" +version = "1.1.123" dependencies = [ "assert-json", - "bytes 1.1.122", + "bytes 1.1.123", "derive_more", "enum-as-inner", "error", @@ -1210,11 +1210,11 @@ dependencies = [ [[package]] name = "encryption" -version = "1.1.122" +version = "1.1.123" dependencies = [ "aes-gcm", "assert-json", - "bytes 1.1.122", + "bytes 1.1.123", "derive_more", "error", "has-sample-values", @@ -1231,7 +1231,7 @@ dependencies = [ [[package]] name = "entity-by-address" -version = "1.1.122" +version = "1.1.123" dependencies = [ "addresses", "error", @@ -1243,7 +1243,7 @@ dependencies = [ [[package]] name = "entity-foundation" -version = "1.1.122" +version = "1.1.123" dependencies = [ "assert-json", "derive_more", @@ -1318,7 +1318,7 @@ dependencies = [ [[package]] name = "error" -version = "1.1.122" +version = "1.1.123" dependencies = [ "derive_more", "log", @@ -1377,7 +1377,7 @@ dependencies = [ [[package]] name = "factor-instances-provider" -version = "1.1.122" +version = "1.1.123" dependencies = [ "actix-rt", "addresses", @@ -1403,9 +1403,9 @@ dependencies = [ [[package]] name = "factors" -version = "1.1.122" +version = "1.1.123" dependencies = [ - "bytes 1.1.122", + "bytes 1.1.123", "cap26-models", "core-collections", "core-misc", @@ -1440,7 +1440,7 @@ dependencies = [ [[package]] name = "factors-supporting-types" -version = "1.1.122" +version = "1.1.123" dependencies = [ "async-trait", "error", @@ -1593,7 +1593,7 @@ dependencies = [ [[package]] name = "gateway-client-and-api" -version = "1.1.122" +version = "1.1.123" dependencies = [ "actix-rt", "addresses", @@ -1613,7 +1613,7 @@ dependencies = [ [[package]] name = "gateway-models" -version = "1.1.122" +version = "1.1.123" dependencies = [ "addresses", "assert-json", @@ -1718,7 +1718,7 @@ dependencies = [ [[package]] name = "has-sample-values" -version = "1.1.122" +version = "1.1.123" dependencies = [ "error", "indexmap 2.7.0", @@ -1729,9 +1729,9 @@ dependencies = [ [[package]] name = "hash" -version = "1.1.122" +version = "1.1.123" dependencies = [ - "bytes 1.1.122", + "bytes 1.1.123", "derive_more", "prelude", "radix-common", @@ -1795,11 +1795,11 @@ dependencies = [ [[package]] name = "hierarchical-deterministic" -version = "1.1.122" +version = "1.1.123" dependencies = [ "assert-json", "bip39", - "bytes 1.1.122", + "bytes 1.1.123", "cap26-models", "derive_more", "ecc", @@ -1842,13 +1842,13 @@ dependencies = [ [[package]] name = "home-cards" -version = "1.1.122" +version = "1.1.123" dependencies = [ "actix-rt", "addresses", "async-trait", "base64", - "bytes 1.1.122", + "bytes 1.1.123", "core-utils", "derive_more", "drivers", @@ -1868,7 +1868,7 @@ dependencies = [ [[package]] name = "host-info" -version = "1.1.122" +version = "1.1.123" dependencies = [ "assert-json", "derive_more", @@ -1915,10 +1915,10 @@ dependencies = [ [[package]] name = "http-client" -version = "1.1.122" +version = "1.1.123" dependencies = [ "actix-rt", - "bytes 1.1.122", + "bytes 1.1.123", "core-utils", "drivers", "error", @@ -2143,7 +2143,7 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "identified-vec-of" -version = "1.1.122" +version = "1.1.123" dependencies = [ "assert-json", "derive_more", @@ -2216,7 +2216,7 @@ dependencies = [ [[package]] name = "interactors" -version = "1.1.122" +version = "1.1.123" dependencies = [ "async-trait", "derive_more", @@ -2336,7 +2336,7 @@ dependencies = [ [[package]] name = "key-derivation-traits" -version = "1.1.122" +version = "1.1.123" dependencies = [ "addresses", "async-trait", @@ -2354,7 +2354,7 @@ dependencies = [ [[package]] name = "keys-collector" -version = "1.1.122" +version = "1.1.123" dependencies = [ "actix-rt", "addresses", @@ -2443,7 +2443,7 @@ dependencies = [ [[package]] name = "manifests" -version = "1.1.122" +version = "1.1.123" dependencies = [ "account-for-display", "addresses", @@ -2485,7 +2485,7 @@ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "metadata" -version = "1.1.122" +version = "1.1.123" dependencies = [ "derive_more", "has-sample-values", @@ -2585,7 +2585,7 @@ dependencies = [ [[package]] name = "network" -version = "1.1.122" +version = "1.1.123" dependencies = [ "assert-json", "enum-iterator", @@ -2601,7 +2601,7 @@ dependencies = [ [[package]] name = "next-derivation-index-ephemeral" -version = "1.1.122" +version = "1.1.123" dependencies = [ "addresses", "assert-json", @@ -2677,9 +2677,9 @@ dependencies = [ [[package]] name = "numeric" -version = "1.1.122" +version = "1.1.123" dependencies = [ - "bytes 1.1.122", + "bytes 1.1.123", "delegate", "derive_more", "enum-iterator", @@ -2899,7 +2899,7 @@ dependencies = [ [[package]] name = "prelude" -version = "1.1.122" +version = "1.1.123" dependencies = [ "radix-engine", "radix-engine-toolkit", @@ -2936,7 +2936,7 @@ dependencies = [ [[package]] name = "profile" -version = "1.1.122" +version = "1.1.123" dependencies = [ "account-for-display", "addresses", @@ -2980,7 +2980,7 @@ dependencies = [ [[package]] name = "profile-account" -version = "1.1.122" +version = "1.1.123" dependencies = [ "account-for-display", "addresses", @@ -3000,7 +3000,7 @@ dependencies = [ [[package]] name = "profile-account-or-persona" -version = "1.1.122" +version = "1.1.123" dependencies = [ "cap26-models", "derive_more", @@ -3017,7 +3017,7 @@ dependencies = [ [[package]] name = "profile-app-preferences" -version = "1.1.122" +version = "1.1.123" dependencies = [ "addresses", "core-misc", @@ -3040,7 +3040,7 @@ dependencies = [ [[package]] name = "profile-base-entity" -version = "1.1.122" +version = "1.1.123" dependencies = [ "addresses", "derive_more", @@ -3063,7 +3063,7 @@ dependencies = [ [[package]] name = "profile-gateway" -version = "1.1.122" +version = "1.1.123" dependencies = [ "addresses", "assert-json", @@ -3087,7 +3087,7 @@ dependencies = [ [[package]] name = "profile-logic" -version = "1.1.122" +version = "1.1.123" dependencies = [ "addresses", "derive_more", @@ -3109,7 +3109,7 @@ dependencies = [ [[package]] name = "profile-persona" -version = "1.1.122" +version = "1.1.123" dependencies = [ "addresses", "cap26-models", @@ -3130,7 +3130,7 @@ dependencies = [ [[package]] name = "profile-persona-data" -version = "1.1.122" +version = "1.1.123" dependencies = [ "addresses", "assert-json", @@ -3149,7 +3149,7 @@ dependencies = [ [[package]] name = "profile-security-structures" -version = "1.1.122" +version = "1.1.123" dependencies = [ "addresses", "cap26-models", @@ -3177,7 +3177,7 @@ dependencies = [ [[package]] name = "profile-state-holder" -version = "1.1.122" +version = "1.1.123" dependencies = [ "derive_more", "error", @@ -3192,7 +3192,7 @@ dependencies = [ [[package]] name = "profile-supporting-types" -version = "1.1.122" +version = "1.1.123" dependencies = [ "addresses", "derive_more", @@ -3281,14 +3281,14 @@ dependencies = [ [[package]] name = "radix-connect" -version = "1.1.122" +version = "1.1.123" dependencies = [ "actix-rt", "addresses", "assert-json", "async-trait", "base64", - "bytes 1.1.122", + "bytes 1.1.123", "core-misc", "core-utils", "derive_more", @@ -3317,10 +3317,10 @@ dependencies = [ [[package]] name = "radix-connect-models" -version = "1.1.122" +version = "1.1.123" dependencies = [ "addresses", - "bytes 1.1.122", + "bytes 1.1.123", "core-misc", "derive_more", "error", @@ -3762,7 +3762,7 @@ dependencies = [ [[package]] name = "sargon" -version = "1.1.122" +version = "1.1.123" dependencies = [ "actix-rt", "addresses", @@ -3827,7 +3827,7 @@ dependencies = [ [[package]] name = "sargon-os" -version = "1.1.122" +version = "1.1.123" dependencies = [ "actix-rt", "async-trait", @@ -3854,7 +3854,7 @@ dependencies = [ [[package]] name = "sargon-os-accounts" -version = "1.1.122" +version = "1.1.123" dependencies = [ "actix-rt", "addresses", @@ -3877,7 +3877,7 @@ dependencies = [ [[package]] name = "sargon-os-derive-public-keys" -version = "1.1.122" +version = "1.1.123" dependencies = [ "actix-rt", "async-trait", @@ -3896,7 +3896,7 @@ dependencies = [ [[package]] name = "sargon-os-factors" -version = "1.1.122" +version = "1.1.123" dependencies = [ "actix-rt", "async-trait", @@ -3924,7 +3924,7 @@ dependencies = [ [[package]] name = "sargon-os-security-center" -version = "1.1.122" +version = "1.1.123" dependencies = [ "actix-rt", "derive_more", @@ -3940,7 +3940,7 @@ dependencies = [ [[package]] name = "sargon-os-signing" -version = "1.1.122" +version = "1.1.123" dependencies = [ "actix-rt", "async-trait", @@ -3966,7 +3966,7 @@ dependencies = [ [[package]] name = "sargon-os-transaction" -version = "1.1.122" +version = "1.1.123" dependencies = [ "actix-rt", "async-std", @@ -3995,7 +3995,7 @@ dependencies = [ [[package]] name = "sargon-uniffi" -version = "1.1.122" +version = "1.1.123" dependencies = [ "actix-rt", "addresses", @@ -4052,7 +4052,7 @@ dependencies = [ [[package]] name = "sargon-uniffi-conversion-macros" -version = "1.1.122" +version = "1.1.123" dependencies = [ "proc-macro2", "quote", @@ -4225,7 +4225,7 @@ dependencies = [ [[package]] name = "security-center" -version = "1.1.122" +version = "1.1.123" dependencies = [ "addresses", "assert-json", @@ -4393,7 +4393,7 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "short-string" -version = "1.1.122" +version = "1.1.123" dependencies = [ "arraystring", "assert-json", @@ -4428,13 +4428,13 @@ dependencies = [ [[package]] name = "signatures-collector" -version = "1.1.122" +version = "1.1.123" dependencies = [ "actix-rt", "addresses", "assert-json", "async-trait", - "bytes 1.1.122", + "bytes 1.1.123", "cap26-models", "core-collections", "core-misc", @@ -4466,10 +4466,10 @@ dependencies = [ [[package]] name = "signing-traits" -version = "1.1.122" +version = "1.1.123" dependencies = [ "async-trait", - "bytes 1.1.122", + "bytes 1.1.123", "core-collections", "derive_more", "ecc", @@ -4634,7 +4634,7 @@ dependencies = [ [[package]] name = "sub-systems" -version = "1.1.122" +version = "1.1.123" dependencies = [ "derive_more", "drivers", @@ -4793,7 +4793,7 @@ dependencies = [ [[package]] name = "time-utils" -version = "1.1.122" +version = "1.1.123" dependencies = [ "iso8601-timestamp", "prelude", @@ -4943,10 +4943,10 @@ dependencies = [ [[package]] name = "transaction-foundation" -version = "1.1.122" +version = "1.1.123" dependencies = [ "assert-json", - "bytes 1.1.122", + "bytes 1.1.123", "derive_more", "has-sample-values", "paste", @@ -4958,10 +4958,10 @@ dependencies = [ [[package]] name = "transaction-models" -version = "1.1.122" +version = "1.1.123" dependencies = [ "addresses", - "bytes 1.1.122", + "bytes 1.1.123", "cargo_toml", "core-collections", "core-misc", diff --git a/crates/app/home-cards/Cargo.toml b/crates/app/home-cards/Cargo.toml index 59518c3af..14f75e7ac 100644 --- a/crates/app/home-cards/Cargo.toml +++ b/crates/app/home-cards/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "home-cards" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/app/key-derivation-traits/Cargo.toml b/crates/app/key-derivation-traits/Cargo.toml index 6b329e0c0..7a8e915c5 100644 --- a/crates/app/key-derivation-traits/Cargo.toml +++ b/crates/app/key-derivation-traits/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "key-derivation-traits" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/app/radix-connect-models/Cargo.toml b/crates/app/radix-connect-models/Cargo.toml index e07d05d96..b9acdcf43 100644 --- a/crates/app/radix-connect-models/Cargo.toml +++ b/crates/app/radix-connect-models/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "radix-connect-models" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/app/radix-connect/Cargo.toml b/crates/app/radix-connect/Cargo.toml index 73cf77824..ae0761d1f 100644 --- a/crates/app/radix-connect/Cargo.toml +++ b/crates/app/radix-connect/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "radix-connect" -version = "1.1.122" +version = "1.1.123" edition = "2021" diff --git a/crates/app/security-center/Cargo.toml b/crates/app/security-center/Cargo.toml index f9afcb614..6a7876f8f 100644 --- a/crates/app/security-center/Cargo.toml +++ b/crates/app/security-center/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "security-center" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/app/signing-traits/Cargo.toml b/crates/app/signing-traits/Cargo.toml index 8c917adfb..dca48b74f 100644 --- a/crates/app/signing-traits/Cargo.toml +++ b/crates/app/signing-traits/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "signing-traits" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/common/build-info/Cargo.toml b/crates/common/build-info/Cargo.toml index b3a2e82a0..abd960c36 100644 --- a/crates/common/build-info/Cargo.toml +++ b/crates/common/build-info/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "build-info" -version = "1.1.122" +version = "1.1.123" edition = "2021" build = "build.rs" diff --git a/crates/common/bytes/Cargo.toml b/crates/common/bytes/Cargo.toml index 10c593140..d939f537c 100644 --- a/crates/common/bytes/Cargo.toml +++ b/crates/common/bytes/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bytes" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/common/entity-foundation/Cargo.toml b/crates/common/entity-foundation/Cargo.toml index 320ac6313..ac6145815 100644 --- a/crates/common/entity-foundation/Cargo.toml +++ b/crates/common/entity-foundation/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "entity-foundation" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/common/host-info/Cargo.toml b/crates/common/host-info/Cargo.toml index 3fdefcbfd..eddfd2473 100644 --- a/crates/common/host-info/Cargo.toml +++ b/crates/common/host-info/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "host-info" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/common/identified-vec-of/Cargo.toml b/crates/common/identified-vec-of/Cargo.toml index 523c65daf..c06dde9bc 100644 --- a/crates/common/identified-vec-of/Cargo.toml +++ b/crates/common/identified-vec-of/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "identified-vec-of" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/common/metadata/Cargo.toml b/crates/common/metadata/Cargo.toml index 657ff501c..3b24f6463 100644 --- a/crates/common/metadata/Cargo.toml +++ b/crates/common/metadata/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "metadata" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/common/network/Cargo.toml b/crates/common/network/Cargo.toml index d45faf872..5d511fe71 100644 --- a/crates/common/network/Cargo.toml +++ b/crates/common/network/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "network" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/common/numeric/Cargo.toml b/crates/common/numeric/Cargo.toml index ddba92c78..b16e225ea 100644 --- a/crates/common/numeric/Cargo.toml +++ b/crates/common/numeric/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "numeric" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/common/short-string/Cargo.toml b/crates/common/short-string/Cargo.toml index 78753bf4d..79a88098e 100644 --- a/crates/common/short-string/Cargo.toml +++ b/crates/common/short-string/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "short-string" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/core/assert-json/Cargo.toml b/crates/core/assert-json/Cargo.toml index 7019c6dab..5a95ce8f1 100644 --- a/crates/core/assert-json/Cargo.toml +++ b/crates/core/assert-json/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "assert-json" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/core/collections/Cargo.toml b/crates/core/collections/Cargo.toml index 677337f3f..0c4fcb4c1 100644 --- a/crates/core/collections/Cargo.toml +++ b/crates/core/collections/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "core-collections" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/core/error/Cargo.toml b/crates/core/error/Cargo.toml index 7970518d0..dc29f5b1a 100644 --- a/crates/core/error/Cargo.toml +++ b/crates/core/error/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "error" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/core/has-sample-values/Cargo.toml b/crates/core/has-sample-values/Cargo.toml index b41303dff..795e59c87 100644 --- a/crates/core/has-sample-values/Cargo.toml +++ b/crates/core/has-sample-values/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "has-sample-values" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/core/misc/Cargo.toml b/crates/core/misc/Cargo.toml index 509c05bca..3765026d0 100644 --- a/crates/core/misc/Cargo.toml +++ b/crates/core/misc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "core-misc" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/core/prelude/Cargo.toml b/crates/core/prelude/Cargo.toml index f3437d964..5ad0b247d 100644 --- a/crates/core/prelude/Cargo.toml +++ b/crates/core/prelude/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "prelude" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/core/time-utils/Cargo.toml b/crates/core/time-utils/Cargo.toml index c0e4658c0..133741a04 100644 --- a/crates/core/time-utils/Cargo.toml +++ b/crates/core/time-utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "time-utils" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/core/utils/Cargo.toml b/crates/core/utils/Cargo.toml index a071a11c3..7793188f9 100644 --- a/crates/core/utils/Cargo.toml +++ b/crates/core/utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "core-utils" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/crypto/addresses/Cargo.toml b/crates/crypto/addresses/Cargo.toml index 194655bd0..541a3f906 100644 --- a/crates/crypto/addresses/Cargo.toml +++ b/crates/crypto/addresses/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "addresses" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/crypto/cap26-models/Cargo.toml b/crates/crypto/cap26-models/Cargo.toml index 22dcb27bd..933111226 100644 --- a/crates/crypto/cap26-models/Cargo.toml +++ b/crates/crypto/cap26-models/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cap26-models" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/crypto/ecc/Cargo.toml b/crates/crypto/ecc/Cargo.toml index f2643de4c..08dd43cc9 100644 --- a/crates/crypto/ecc/Cargo.toml +++ b/crates/crypto/ecc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ecc" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/crypto/encryption/Cargo.toml b/crates/crypto/encryption/Cargo.toml index 362eb4f79..d278a2ed5 100644 --- a/crates/crypto/encryption/Cargo.toml +++ b/crates/crypto/encryption/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "encryption" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/crypto/hash/Cargo.toml b/crates/crypto/hash/Cargo.toml index 5ba311328..734d6775e 100644 --- a/crates/crypto/hash/Cargo.toml +++ b/crates/crypto/hash/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hash" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/crypto/hd/Cargo.toml b/crates/crypto/hd/Cargo.toml index 86e48fc84..f8afd2ec3 100644 --- a/crates/crypto/hd/Cargo.toml +++ b/crates/crypto/hd/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hierarchical-deterministic" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/factors/factors/Cargo.toml b/crates/factors/factors/Cargo.toml index ebdf6df63..20c186115 100644 --- a/crates/factors/factors/Cargo.toml +++ b/crates/factors/factors/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "factors" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/factors/instances-provider/Cargo.toml b/crates/factors/instances-provider/Cargo.toml index e35baf445..d232bb927 100644 --- a/crates/factors/instances-provider/Cargo.toml +++ b/crates/factors/instances-provider/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "factor-instances-provider" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/factors/keys-collector/Cargo.toml b/crates/factors/keys-collector/Cargo.toml index cdbbde1c0..5d034119d 100644 --- a/crates/factors/keys-collector/Cargo.toml +++ b/crates/factors/keys-collector/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "keys-collector" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/factors/next-derivation-index-ephemeral/Cargo.toml b/crates/factors/next-derivation-index-ephemeral/Cargo.toml index b79188df8..cfa4f79ec 100644 --- a/crates/factors/next-derivation-index-ephemeral/Cargo.toml +++ b/crates/factors/next-derivation-index-ephemeral/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "next-derivation-index-ephemeral" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/factors/signatures-collector/Cargo.toml b/crates/factors/signatures-collector/Cargo.toml index b55baba99..a916062d0 100644 --- a/crates/factors/signatures-collector/Cargo.toml +++ b/crates/factors/signatures-collector/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "signatures-collector" -version = "1.1.122" +version = "1.1.123" edition = "2021" diff --git a/crates/factors/supporting-types/Cargo.toml b/crates/factors/supporting-types/Cargo.toml index f7ce891ba..329da23bd 100644 --- a/crates/factors/supporting-types/Cargo.toml +++ b/crates/factors/supporting-types/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "factors-supporting-types" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/gateway/client-and-api/Cargo.toml b/crates/gateway/client-and-api/Cargo.toml index f669ce29b..17b64fb48 100644 --- a/crates/gateway/client-and-api/Cargo.toml +++ b/crates/gateway/client-and-api/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "gateway-client-and-api" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/gateway/models/Cargo.toml b/crates/gateway/models/Cargo.toml index 694c35229..d691d8275 100644 --- a/crates/gateway/models/Cargo.toml +++ b/crates/gateway/models/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "gateway-models" -version = "1.1.122" +version = "1.1.123" edition = "2021" diff --git a/crates/profile/logic/logic_SPLIT_ME/Cargo.toml b/crates/profile/logic/logic_SPLIT_ME/Cargo.toml index 0c8aa450f..64904af2d 100644 --- a/crates/profile/logic/logic_SPLIT_ME/Cargo.toml +++ b/crates/profile/logic/logic_SPLIT_ME/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "profile-logic" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/profile/models/account-for-display/Cargo.toml b/crates/profile/models/account-for-display/Cargo.toml index a95d1bb75..b3b34bc3e 100644 --- a/crates/profile/models/account-for-display/Cargo.toml +++ b/crates/profile/models/account-for-display/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "account-for-display" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/profile/models/account-or-persona/Cargo.toml b/crates/profile/models/account-or-persona/Cargo.toml index 4234de7f1..a6dac7d82 100644 --- a/crates/profile/models/account-or-persona/Cargo.toml +++ b/crates/profile/models/account-or-persona/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "profile-account-or-persona" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/profile/models/account/Cargo.toml b/crates/profile/models/account/Cargo.toml index 299355d40..329947f2f 100644 --- a/crates/profile/models/account/Cargo.toml +++ b/crates/profile/models/account/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "profile-account" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/profile/models/app-preferences/Cargo.toml b/crates/profile/models/app-preferences/Cargo.toml index 2546a9574..1d9eca101 100644 --- a/crates/profile/models/app-preferences/Cargo.toml +++ b/crates/profile/models/app-preferences/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "profile-app-preferences" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/profile/models/base-entity/Cargo.toml b/crates/profile/models/base-entity/Cargo.toml index 02676c365..47c33fdbb 100644 --- a/crates/profile/models/base-entity/Cargo.toml +++ b/crates/profile/models/base-entity/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "profile-base-entity" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/profile/models/gateway/Cargo.toml b/crates/profile/models/gateway/Cargo.toml index 05b5aaed6..261433daf 100644 --- a/crates/profile/models/gateway/Cargo.toml +++ b/crates/profile/models/gateway/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "profile-gateway" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/profile/models/persona-data/Cargo.toml b/crates/profile/models/persona-data/Cargo.toml index 733a81327..75ce4dba5 100644 --- a/crates/profile/models/persona-data/Cargo.toml +++ b/crates/profile/models/persona-data/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "profile-persona-data" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/profile/models/persona/Cargo.toml b/crates/profile/models/persona/Cargo.toml index 5b27913c7..d03822aa0 100644 --- a/crates/profile/models/persona/Cargo.toml +++ b/crates/profile/models/persona/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "profile-persona" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/profile/models/profile_SPLIT_ME/Cargo.toml b/crates/profile/models/profile_SPLIT_ME/Cargo.toml index 5974aaa35..67d457720 100644 --- a/crates/profile/models/profile_SPLIT_ME/Cargo.toml +++ b/crates/profile/models/profile_SPLIT_ME/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "profile" -version = "1.1.122" +version = "1.1.123" edition = "2021" diff --git a/crates/profile/models/security-structures/Cargo.toml b/crates/profile/models/security-structures/Cargo.toml index 4741e5a75..1d099f9b8 100644 --- a/crates/profile/models/security-structures/Cargo.toml +++ b/crates/profile/models/security-structures/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "profile-security-structures" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/profile/models/supporting-types/Cargo.toml b/crates/profile/models/supporting-types/Cargo.toml index fea21d923..d8f0e6f59 100644 --- a/crates/profile/models/supporting-types/Cargo.toml +++ b/crates/profile/models/supporting-types/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "profile-supporting-types" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/profile/traits/entity-by-address/Cargo.toml b/crates/profile/traits/entity-by-address/Cargo.toml index 15edb1274..70afdf160 100644 --- a/crates/profile/traits/entity-by-address/Cargo.toml +++ b/crates/profile/traits/entity-by-address/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "entity-by-address" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/sargon/Cargo.toml b/crates/sargon/Cargo.toml index 1903fcdfb..6cd964a7d 100644 --- a/crates/sargon/Cargo.toml +++ b/crates/sargon/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sargon" -version = "1.1.122" +version = "1.1.123" edition = "2021" resolver = "2" # features enabled in integration test diff --git a/crates/system/clients/clients/Cargo.toml b/crates/system/clients/clients/Cargo.toml index cbe2b91eb..29d024870 100644 --- a/crates/system/clients/clients/Cargo.toml +++ b/crates/system/clients/clients/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clients" -version = "1.1.122" +version = "1.1.123" edition = "2021" diff --git a/crates/system/clients/http/Cargo.toml b/crates/system/clients/http/Cargo.toml index c6020d752..f6296b0df 100644 --- a/crates/system/clients/http/Cargo.toml +++ b/crates/system/clients/http/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "http-client" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/system/drivers/Cargo.toml b/crates/system/drivers/Cargo.toml index d094c1848..4dabb41b3 100644 --- a/crates/system/drivers/Cargo.toml +++ b/crates/system/drivers/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "drivers" -version = "1.1.122" +version = "1.1.123" edition = "2021" diff --git a/crates/system/interactors/Cargo.toml b/crates/system/interactors/Cargo.toml index f48ccc6e6..b0ad71d37 100644 --- a/crates/system/interactors/Cargo.toml +++ b/crates/system/interactors/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "interactors" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/system/os/accounts/Cargo.toml b/crates/system/os/accounts/Cargo.toml index a7e22cb60..b2f988316 100644 --- a/crates/system/os/accounts/Cargo.toml +++ b/crates/system/os/accounts/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sargon-os-accounts" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/system/os/derive-public-keys/Cargo.toml b/crates/system/os/derive-public-keys/Cargo.toml index d0db32f8c..48e91b633 100644 --- a/crates/system/os/derive-public-keys/Cargo.toml +++ b/crates/system/os/derive-public-keys/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sargon-os-derive-public-keys" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/system/os/factors/Cargo.toml b/crates/system/os/factors/Cargo.toml index 65cdf4420..670abb019 100644 --- a/crates/system/os/factors/Cargo.toml +++ b/crates/system/os/factors/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sargon-os-factors" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/system/os/os/Cargo.toml b/crates/system/os/os/Cargo.toml index 95c4bb854..d7aaf100b 100644 --- a/crates/system/os/os/Cargo.toml +++ b/crates/system/os/os/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sargon-os" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/system/os/security-center/Cargo.toml b/crates/system/os/security-center/Cargo.toml index e52c2a162..c440199ed 100644 --- a/crates/system/os/security-center/Cargo.toml +++ b/crates/system/os/security-center/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sargon-os-security-center" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/system/os/signing/Cargo.toml b/crates/system/os/signing/Cargo.toml index 7cd91c5cf..4654a9059 100644 --- a/crates/system/os/signing/Cargo.toml +++ b/crates/system/os/signing/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sargon-os-signing" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/system/os/transaction/Cargo.toml b/crates/system/os/transaction/Cargo.toml index 571d68b78..9219db8d6 100644 --- a/crates/system/os/transaction/Cargo.toml +++ b/crates/system/os/transaction/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sargon-os-transaction" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/system/profile-state-holder/Cargo.toml b/crates/system/profile-state-holder/Cargo.toml index a6f55a501..2d342ed7d 100644 --- a/crates/system/profile-state-holder/Cargo.toml +++ b/crates/system/profile-state-holder/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "profile-state-holder" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/system/sub-systems/Cargo.toml b/crates/system/sub-systems/Cargo.toml index 936871f29..4d324c292 100644 --- a/crates/system/sub-systems/Cargo.toml +++ b/crates/system/sub-systems/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sub-systems" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/transaction/foundation/Cargo.toml b/crates/transaction/foundation/Cargo.toml index 3188743e0..ccc034fe7 100644 --- a/crates/transaction/foundation/Cargo.toml +++ b/crates/transaction/foundation/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "transaction-foundation" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/transaction/manifests/Cargo.toml b/crates/transaction/manifests/Cargo.toml index 881d3414f..1ab330a60 100644 --- a/crates/transaction/manifests/Cargo.toml +++ b/crates/transaction/manifests/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "manifests" -version = "1.1.122" +version = "1.1.123" edition = "2021" diff --git a/crates/transaction/models/Cargo.toml b/crates/transaction/models/Cargo.toml index d751180e3..a843a6b66 100644 --- a/crates/transaction/models/Cargo.toml +++ b/crates/transaction/models/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "transaction-models" -version = "1.1.122" +version = "1.1.123" edition = "2021" diff --git a/crates/uniffi/conversion-macros/Cargo.toml b/crates/uniffi/conversion-macros/Cargo.toml index 05c145ef3..51b154d62 100644 --- a/crates/uniffi/conversion-macros/Cargo.toml +++ b/crates/uniffi/conversion-macros/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "sargon-uniffi-conversion-macros" -version = "1.1.122" +version = "1.1.123" edition = "2021" [dependencies] diff --git a/crates/uniffi/uniffi_SPLIT_ME/Cargo.toml b/crates/uniffi/uniffi_SPLIT_ME/Cargo.toml index cd85e7385..a3831250c 100644 --- a/crates/uniffi/uniffi_SPLIT_ME/Cargo.toml +++ b/crates/uniffi/uniffi_SPLIT_ME/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sargon-uniffi" -version = "1.1.122" +version = "1.1.123" edition = "2021" build = "build.rs"