diff --git a/Cargo.lock b/Cargo.lock index ff87758ad..7046bd31c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,7 +4,7 @@ version = 4 [[package]] name = "account-for-display" -version = "1.1.115" +version = "1.1.116" dependencies = [ "addresses", "derive_more", @@ -49,10 +49,10 @@ dependencies = [ [[package]] name = "addresses" -version = "1.1.115" +version = "1.1.116" dependencies = [ "assert-json", - "bytes 1.1.115", + "bytes 1.1.116", "cap26-models", "core-utils", "derive_more", @@ -246,7 +246,7 @@ checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "assert-json" -version = "1.1.115" +version = "1.1.116" dependencies = [ "assert-json-diff", "error", @@ -546,7 +546,7 @@ dependencies = [ [[package]] name = "build-info" -version = "1.1.115" +version = "1.1.116" dependencies = [ "assert-json", "cargo_toml", @@ -573,7 +573,7 @@ checksum = "5ce89b21cab1437276d2650d57e971f9d548a2d9037cc231abdc0562b97498ce" [[package]] name = "bytes" -version = "1.1.115" +version = "1.1.116" dependencies = [ "assert-json", "delegate", @@ -607,7 +607,7 @@ dependencies = [ [[package]] name = "cap26-models" -version = "1.1.115" +version = "1.1.116" dependencies = [ "assert-json", "derive_more", @@ -748,7 +748,7 @@ checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" [[package]] name = "clients" -version = "1.1.115" +version = "1.1.116" dependencies = [ "actix-rt", "async-trait", @@ -808,7 +808,7 @@ checksum = "0d8a42181e0652c2997ae4d217f25b63c5337a52fd2279736e97b832fa0a3cff" [[package]] name = "core-collections" -version = "1.1.115" +version = "1.1.116" dependencies = [ "has-sample-values", "indexmap 2.7.0", @@ -835,7 +835,7 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "core-misc" -version = "1.1.115" +version = "1.1.116" dependencies = [ "assert-json", "core-utils", @@ -855,7 +855,7 @@ dependencies = [ [[package]] name = "core-utils" -version = "1.1.115" +version = "1.1.116" dependencies = [ "error", "iso8601-timestamp", @@ -1084,7 +1084,7 @@ checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" [[package]] name = "drivers" -version = "1.1.115" +version = "1.1.116" dependencies = [ "actix-rt", "addresses", @@ -1108,10 +1108,10 @@ dependencies = [ [[package]] name = "ecc" -version = "1.1.115" +version = "1.1.116" dependencies = [ "assert-json", - "bytes 1.1.115", + "bytes 1.1.116", "derive_more", "enum-as-inner", "error", @@ -1210,11 +1210,11 @@ dependencies = [ [[package]] name = "encryption" -version = "1.1.115" +version = "1.1.116" dependencies = [ "aes-gcm", "assert-json", - "bytes 1.1.115", + "bytes 1.1.116", "derive_more", "error", "has-sample-values", @@ -1231,7 +1231,7 @@ dependencies = [ [[package]] name = "entity-by-address" -version = "1.1.115" +version = "1.1.116" dependencies = [ "addresses", "error", @@ -1243,7 +1243,7 @@ dependencies = [ [[package]] name = "entity-foundation" -version = "1.1.115" +version = "1.1.116" dependencies = [ "assert-json", "derive_more", @@ -1318,7 +1318,7 @@ dependencies = [ [[package]] name = "error" -version = "1.1.115" +version = "1.1.116" dependencies = [ "derive_more", "log", @@ -1377,7 +1377,7 @@ dependencies = [ [[package]] name = "factor-instances-provider" -version = "1.1.115" +version = "1.1.116" dependencies = [ "actix-rt", "addresses", @@ -1403,9 +1403,9 @@ dependencies = [ [[package]] name = "factors" -version = "1.1.115" +version = "1.1.116" dependencies = [ - "bytes 1.1.115", + "bytes 1.1.116", "cap26-models", "core-collections", "core-misc", @@ -1440,7 +1440,7 @@ dependencies = [ [[package]] name = "factors-supporting-types" -version = "1.1.115" +version = "1.1.116" dependencies = [ "async-trait", "error", @@ -1593,7 +1593,7 @@ dependencies = [ [[package]] name = "gateway-client-and-api" -version = "1.1.115" +version = "1.1.116" dependencies = [ "actix-rt", "addresses", @@ -1613,7 +1613,7 @@ dependencies = [ [[package]] name = "gateway-models" -version = "1.1.115" +version = "1.1.116" dependencies = [ "addresses", "assert-json", @@ -1718,7 +1718,7 @@ dependencies = [ [[package]] name = "has-sample-values" -version = "1.1.115" +version = "1.1.116" dependencies = [ "error", "indexmap 2.7.0", @@ -1729,9 +1729,9 @@ dependencies = [ [[package]] name = "hash" -version = "1.1.115" +version = "1.1.116" dependencies = [ - "bytes 1.1.115", + "bytes 1.1.116", "derive_more", "prelude", "radix-common", @@ -1795,11 +1795,11 @@ dependencies = [ [[package]] name = "hierarchical-deterministic" -version = "1.1.115" +version = "1.1.116" dependencies = [ "assert-json", "bip39", - "bytes 1.1.115", + "bytes 1.1.116", "cap26-models", "derive_more", "ecc", @@ -1842,13 +1842,13 @@ dependencies = [ [[package]] name = "home-cards" -version = "1.1.115" +version = "1.1.116" dependencies = [ "actix-rt", "addresses", "async-trait", "base64", - "bytes 1.1.115", + "bytes 1.1.116", "core-utils", "derive_more", "drivers", @@ -1868,7 +1868,7 @@ dependencies = [ [[package]] name = "host-info" -version = "1.1.115" +version = "1.1.116" dependencies = [ "assert-json", "derive_more", @@ -1915,10 +1915,10 @@ dependencies = [ [[package]] name = "http-client" -version = "1.1.115" +version = "1.1.116" dependencies = [ "actix-rt", - "bytes 1.1.115", + "bytes 1.1.116", "core-utils", "drivers", "error", @@ -2143,7 +2143,7 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "identified-vec-of" -version = "1.1.115" +version = "1.1.116" dependencies = [ "assert-json", "derive_more", @@ -2216,7 +2216,7 @@ dependencies = [ [[package]] name = "interactors" -version = "1.1.115" +version = "1.1.116" dependencies = [ "async-trait", "derive_more", @@ -2336,7 +2336,7 @@ dependencies = [ [[package]] name = "key-derivation-traits" -version = "1.1.115" +version = "1.1.116" dependencies = [ "addresses", "async-trait", @@ -2354,7 +2354,7 @@ dependencies = [ [[package]] name = "keys-collector" -version = "1.1.115" +version = "1.1.116" dependencies = [ "actix-rt", "addresses", @@ -2443,7 +2443,7 @@ dependencies = [ [[package]] name = "manifests" -version = "1.1.115" +version = "1.1.116" dependencies = [ "account-for-display", "addresses", @@ -2463,6 +2463,7 @@ dependencies = [ "profile", "profile-account-or-persona", "profile-base-entity", + "profile-supporting-types", "radix-common", "radix-engine", "radix-engine-interface", @@ -2483,7 +2484,7 @@ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "metadata" -version = "1.1.115" +version = "1.1.116" dependencies = [ "derive_more", "has-sample-values", @@ -2583,7 +2584,7 @@ dependencies = [ [[package]] name = "network" -version = "1.1.115" +version = "1.1.116" dependencies = [ "assert-json", "enum-iterator", @@ -2599,7 +2600,7 @@ dependencies = [ [[package]] name = "next-derivation-index-ephemeral" -version = "1.1.115" +version = "1.1.116" dependencies = [ "addresses", "assert-json", @@ -2675,9 +2676,9 @@ dependencies = [ [[package]] name = "numeric" -version = "1.1.115" +version = "1.1.116" dependencies = [ - "bytes 1.1.115", + "bytes 1.1.116", "delegate", "derive_more", "enum-iterator", @@ -2897,7 +2898,7 @@ dependencies = [ [[package]] name = "prelude" -version = "1.1.115" +version = "1.1.116" dependencies = [ "radix-engine", "radix-engine-toolkit", @@ -2934,7 +2935,7 @@ dependencies = [ [[package]] name = "profile" -version = "1.1.115" +version = "1.1.116" dependencies = [ "account-for-display", "addresses", @@ -2978,7 +2979,7 @@ dependencies = [ [[package]] name = "profile-account" -version = "1.1.115" +version = "1.1.116" dependencies = [ "account-for-display", "addresses", @@ -2998,7 +2999,7 @@ dependencies = [ [[package]] name = "profile-account-or-persona" -version = "1.1.115" +version = "1.1.116" dependencies = [ "cap26-models", "derive_more", @@ -3015,7 +3016,7 @@ dependencies = [ [[package]] name = "profile-app-preferences" -version = "1.1.115" +version = "1.1.116" dependencies = [ "addresses", "core-misc", @@ -3038,7 +3039,7 @@ dependencies = [ [[package]] name = "profile-base-entity" -version = "1.1.115" +version = "1.1.116" dependencies = [ "addresses", "derive_more", @@ -3061,7 +3062,7 @@ dependencies = [ [[package]] name = "profile-gateway" -version = "1.1.115" +version = "1.1.116" dependencies = [ "addresses", "assert-json", @@ -3085,7 +3086,7 @@ dependencies = [ [[package]] name = "profile-logic" -version = "1.1.115" +version = "1.1.116" dependencies = [ "addresses", "derive_more", @@ -3107,7 +3108,7 @@ dependencies = [ [[package]] name = "profile-persona" -version = "1.1.115" +version = "1.1.116" dependencies = [ "addresses", "cap26-models", @@ -3128,7 +3129,7 @@ dependencies = [ [[package]] name = "profile-persona-data" -version = "1.1.115" +version = "1.1.116" dependencies = [ "addresses", "assert-json", @@ -3147,7 +3148,7 @@ dependencies = [ [[package]] name = "profile-security-structures" -version = "1.1.115" +version = "1.1.116" dependencies = [ "addresses", "cap26-models", @@ -3175,7 +3176,7 @@ dependencies = [ [[package]] name = "profile-state-holder" -version = "1.1.115" +version = "1.1.116" dependencies = [ "derive_more", "error", @@ -3190,7 +3191,7 @@ dependencies = [ [[package]] name = "profile-supporting-types" -version = "1.1.115" +version = "1.1.116" dependencies = [ "addresses", "derive_more", @@ -3279,14 +3280,14 @@ dependencies = [ [[package]] name = "radix-connect" -version = "1.1.115" +version = "1.1.116" dependencies = [ "actix-rt", "addresses", "assert-json", "async-trait", "base64", - "bytes 1.1.115", + "bytes 1.1.116", "core-misc", "core-utils", "derive_more", @@ -3314,10 +3315,10 @@ dependencies = [ [[package]] name = "radix-connect-models" -version = "1.1.115" +version = "1.1.116" dependencies = [ "addresses", - "bytes 1.1.115", + "bytes 1.1.116", "core-misc", "derive_more", "error", @@ -3759,7 +3760,7 @@ dependencies = [ [[package]] name = "sargon" -version = "1.1.115" +version = "1.1.116" dependencies = [ "actix-rt", "addresses", @@ -3823,7 +3824,7 @@ dependencies = [ [[package]] name = "sargon-os" -version = "1.1.115" +version = "1.1.116" dependencies = [ "actix-rt", "async-trait", @@ -3850,7 +3851,7 @@ dependencies = [ [[package]] name = "sargon-os-accounts" -version = "1.1.115" +version = "1.1.116" dependencies = [ "actix-rt", "addresses", @@ -3873,30 +3874,35 @@ dependencies = [ [[package]] name = "sargon-os-factors" -version = "1.1.115" +version = "1.1.116" dependencies = [ "actix-rt", "async-trait", "clients", "derive_more", "drivers", + "enum-as-inner", "error", "factor-instances-provider", "interactors", "key-derivation-traits", "log", + "manifests", + "preinterpret", "prelude", "pretty_assertions", "profile", "profile-logic", + "radix-connect", "sargon-os", "serde", "serde_json", + "transaction-models", ] [[package]] name = "sargon-os-security-center" -version = "1.1.115" +version = "1.1.116" dependencies = [ "actix-rt", "derive_more", @@ -3912,7 +3918,7 @@ dependencies = [ [[package]] name = "sargon-os-signing" -version = "1.1.115" +version = "1.1.116" dependencies = [ "actix-rt", "async-trait", @@ -3938,7 +3944,7 @@ dependencies = [ [[package]] name = "sargon-os-transaction" -version = "1.1.115" +version = "1.1.116" dependencies = [ "actix-rt", "async-std", @@ -3967,7 +3973,7 @@ dependencies = [ [[package]] name = "sargon-uniffi" -version = "1.1.115" +version = "1.1.116" dependencies = [ "actix-rt", "addresses", @@ -4024,7 +4030,7 @@ dependencies = [ [[package]] name = "sargon-uniffi-conversion-macros" -version = "1.1.115" +version = "1.1.116" dependencies = [ "proc-macro2", "quote", @@ -4197,7 +4203,7 @@ dependencies = [ [[package]] name = "security-center" -version = "1.1.115" +version = "1.1.116" dependencies = [ "addresses", "assert-json", @@ -4365,7 +4371,7 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "short-string" -version = "1.1.115" +version = "1.1.116" dependencies = [ "arraystring", "assert-json", @@ -4400,13 +4406,13 @@ dependencies = [ [[package]] name = "signing" -version = "1.1.115" +version = "1.1.116" dependencies = [ "actix-rt", "addresses", "assert-json", "async-trait", - "bytes 1.1.115", + "bytes 1.1.116", "cap26-models", "core-collections", "core-misc", @@ -4438,10 +4444,10 @@ dependencies = [ [[package]] name = "signing-traits" -version = "1.1.115" +version = "1.1.116" dependencies = [ "async-trait", - "bytes 1.1.115", + "bytes 1.1.116", "core-collections", "derive_more", "ecc", @@ -4606,7 +4612,7 @@ dependencies = [ [[package]] name = "sub-systems" -version = "1.1.115" +version = "1.1.116" dependencies = [ "derive_more", "drivers", @@ -4765,7 +4771,7 @@ dependencies = [ [[package]] name = "time-utils" -version = "1.1.115" +version = "1.1.116" dependencies = [ "iso8601-timestamp", "prelude", @@ -4915,10 +4921,10 @@ dependencies = [ [[package]] name = "transaction-foundation" -version = "1.1.115" +version = "1.1.116" dependencies = [ "assert-json", - "bytes 1.1.115", + "bytes 1.1.116", "derive_more", "has-sample-values", "paste", @@ -4930,10 +4936,10 @@ dependencies = [ [[package]] name = "transaction-models" -version = "1.1.115" +version = "1.1.116" dependencies = [ "addresses", - "bytes 1.1.115", + "bytes 1.1.116", "cargo_toml", "core-collections", "core-misc", diff --git a/crates/app/home-cards/Cargo.toml b/crates/app/home-cards/Cargo.toml index 63bca5c27..afbc10efb 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.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/app/key-derivation-traits/Cargo.toml b/crates/app/key-derivation-traits/Cargo.toml index 988c01496..115fab3f3 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.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/app/radix-connect-models/Cargo.toml b/crates/app/radix-connect-models/Cargo.toml index a86acdaf9..1dc5fa078 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.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/app/radix-connect/Cargo.toml b/crates/app/radix-connect/Cargo.toml index 32076ddbd..db1ad778a 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.115" +version = "1.1.116" edition = "2021" 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 new file mode 100644 index 000000000..7b69b36c8 --- /dev/null +++ b/crates/app/radix-connect/src/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/batch_of_transactions.rs @@ -0,0 +1,47 @@ +use crate::prelude::*; + +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] +pub struct DappToWalletInteractionBatchOfTransactions { + pub transactions: Vec, +} + +impl DappToWalletInteractionBatchOfTransactions { + pub fn new( + transactions: impl IntoIterator, + ) -> Self { + Self { + transactions: transactions.into_iter().collect(), + } + } +} + +impl HasSampleValues for DappToWalletInteractionBatchOfTransactions { + fn sample() -> Self { + Self::new([ + UnvalidatedTransactionManifest::sample(), + UnvalidatedTransactionManifest::sample_other(), + ]) + } + + fn sample_other() -> Self { + Self::new([UnvalidatedTransactionManifest::sample_other()]) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[allow(clippy::upper_case_acronyms)] + type SUT = DappToWalletInteractionBatchOfTransactions; + + #[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 new file mode 100644 index 000000000..ea996a5c3 --- /dev/null +++ b/crates/app/radix-connect/src/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/mod.rs @@ -0,0 +1,4 @@ +#[allow(clippy::module_inception)] +mod batch_of_transactions; + +pub use batch_of_transactions::*; diff --git a/crates/app/radix-connect/src/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/items.rs b/crates/app/radix-connect/src/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/items.rs index 3086cbf35..d6bda114b 100644 --- a/crates/app/radix-connect/src/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/items.rs +++ b/crates/app/radix-connect/src/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/items.rs @@ -12,6 +12,9 @@ pub enum DappToWalletInteractionItems { #[serde(rename = "transaction")] Transaction(DappToWalletInteractionTransactionItems), + #[serde(rename = "batchOfTransactions")] + BatchOfTransactions(DappToWalletInteractionBatchOfTransactions), + #[serde(rename = "preAuthorizationRequest")] PreAuthorization(DappToWalletInteractionPreAuthorizationItems), } diff --git a/crates/app/radix-connect/src/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/mod.rs b/crates/app/radix-connect/src/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/mod.rs index d48c80fee..f19d3ce9f 100644 --- a/crates/app/radix-connect/src/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/mod.rs +++ b/crates/app/radix-connect/src/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/mod.rs @@ -1,8 +1,10 @@ +mod batch_of_transactions; mod items; mod pre_authorization; mod request; mod transaction; +pub use batch_of_transactions::*; pub use items::*; pub use pre_authorization::*; pub use request::*; diff --git a/crates/app/security-center/Cargo.toml b/crates/app/security-center/Cargo.toml index 6a69dfb9a..0b9264976 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.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/app/signing-traits/Cargo.toml b/crates/app/signing-traits/Cargo.toml index 23254d4c7..0010c2985 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.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/app/signing/Cargo.toml b/crates/app/signing/Cargo.toml index 0d0e9be19..230b25d22 100644 --- a/crates/app/signing/Cargo.toml +++ b/crates/app/signing/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "signing" -version = "1.1.115" +version = "1.1.116" edition = "2021" diff --git a/crates/common/build-info/Cargo.toml b/crates/common/build-info/Cargo.toml index 910f50a03..ab5710456 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.115" +version = "1.1.116" edition = "2021" build = "build.rs" diff --git a/crates/common/bytes/Cargo.toml b/crates/common/bytes/Cargo.toml index 5ce753a78..e4ad92534 100644 --- a/crates/common/bytes/Cargo.toml +++ b/crates/common/bytes/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bytes" -version = "1.1.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/common/entity-foundation/Cargo.toml b/crates/common/entity-foundation/Cargo.toml index f27bd4dda..cc1e7f772 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.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/common/host-info/Cargo.toml b/crates/common/host-info/Cargo.toml index 84ca8db0c..846737c13 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.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/common/identified-vec-of/Cargo.toml b/crates/common/identified-vec-of/Cargo.toml index a1dc973f9..4c19834fe 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.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/common/metadata/Cargo.toml b/crates/common/metadata/Cargo.toml index b01f962f2..b39a230d4 100644 --- a/crates/common/metadata/Cargo.toml +++ b/crates/common/metadata/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "metadata" -version = "1.1.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/common/network/Cargo.toml b/crates/common/network/Cargo.toml index 14964604e..e5efbe7e7 100644 --- a/crates/common/network/Cargo.toml +++ b/crates/common/network/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "network" -version = "1.1.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/common/numeric/Cargo.toml b/crates/common/numeric/Cargo.toml index 01cf958af..5e2ee43f3 100644 --- a/crates/common/numeric/Cargo.toml +++ b/crates/common/numeric/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "numeric" -version = "1.1.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/common/short-string/Cargo.toml b/crates/common/short-string/Cargo.toml index d9cf0435f..2dc64c7f6 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.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/core/assert-json/Cargo.toml b/crates/core/assert-json/Cargo.toml index 2eb8495d4..c749a3032 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.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/core/collections/Cargo.toml b/crates/core/collections/Cargo.toml index 22722d0a8..0048c668b 100644 --- a/crates/core/collections/Cargo.toml +++ b/crates/core/collections/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "core-collections" -version = "1.1.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/core/error/Cargo.toml b/crates/core/error/Cargo.toml index 00664e24c..5f7c6a0a1 100644 --- a/crates/core/error/Cargo.toml +++ b/crates/core/error/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "error" -version = "1.1.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/core/has-sample-values/Cargo.toml b/crates/core/has-sample-values/Cargo.toml index c61353234..1dfaad7d3 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.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/core/misc/Cargo.toml b/crates/core/misc/Cargo.toml index bf7dd1b93..534090fed 100644 --- a/crates/core/misc/Cargo.toml +++ b/crates/core/misc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "core-misc" -version = "1.1.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/core/prelude/Cargo.toml b/crates/core/prelude/Cargo.toml index c4aeb671e..c2c155cf4 100644 --- a/crates/core/prelude/Cargo.toml +++ b/crates/core/prelude/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "prelude" -version = "1.1.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/core/time-utils/Cargo.toml b/crates/core/time-utils/Cargo.toml index 11696315b..4437eb6ad 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.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/core/utils/Cargo.toml b/crates/core/utils/Cargo.toml index 60a2c1488..0ddca0ac0 100644 --- a/crates/core/utils/Cargo.toml +++ b/crates/core/utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "core-utils" -version = "1.1.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/crypto/addresses/Cargo.toml b/crates/crypto/addresses/Cargo.toml index cbc70eb91..686b17c20 100644 --- a/crates/crypto/addresses/Cargo.toml +++ b/crates/crypto/addresses/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "addresses" -version = "1.1.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/crypto/cap26-models/Cargo.toml b/crates/crypto/cap26-models/Cargo.toml index 67c887fa0..24e0c5e9a 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.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/crypto/ecc/Cargo.toml b/crates/crypto/ecc/Cargo.toml index 332696b8d..a46851e3c 100644 --- a/crates/crypto/ecc/Cargo.toml +++ b/crates/crypto/ecc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ecc" -version = "1.1.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/crypto/encryption/Cargo.toml b/crates/crypto/encryption/Cargo.toml index f20678840..3f44570ce 100644 --- a/crates/crypto/encryption/Cargo.toml +++ b/crates/crypto/encryption/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "encryption" -version = "1.1.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/crypto/hash/Cargo.toml b/crates/crypto/hash/Cargo.toml index f765aeb96..fdf486c86 100644 --- a/crates/crypto/hash/Cargo.toml +++ b/crates/crypto/hash/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hash" -version = "1.1.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/crypto/hd/Cargo.toml b/crates/crypto/hd/Cargo.toml index a434f5a0f..2f388dcf6 100644 --- a/crates/crypto/hd/Cargo.toml +++ b/crates/crypto/hd/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hierarchical-deterministic" -version = "1.1.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/factors/factors/Cargo.toml b/crates/factors/factors/Cargo.toml index 50ea3a3a3..91d793bbd 100644 --- a/crates/factors/factors/Cargo.toml +++ b/crates/factors/factors/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "factors" -version = "1.1.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/factors/instances-provider/Cargo.toml b/crates/factors/instances-provider/Cargo.toml index 062b4b693..5797600a6 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.115" +version = "1.1.116" edition = "2021" [dependencies] 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 91f50dec3..2335a1197 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 @@ -3,20 +3,9 @@ use crate::prelude::*; /// An analyzer of a `Profile` for some `network_id` (i.e. analyzer of `ProfileNetwork`), /// reading out the max derivation entity index for Unsecurified/Securified Accounts/Personas /// for some factor source id. +#[derive(derive_more::Deref)] pub struct NextDerivationEntityIndexProfileAnalyzingAssigner { - network_id: NetworkID, - - /// might be empty - unsecurified_accounts_on_network: IndexSet, - - /// might be empty - securified_accounts_on_network: IndexSet, - - /// might be empty - unsecurified_personas_on_network: IndexSet, - - /// might be empty - securified_personas_on_network: IndexSet, + entities_on_network: EntitiesOnNetwork, } impl NextDerivationEntityIndexProfileAnalyzingAssigner { @@ -48,19 +37,24 @@ impl NextDerivationEntityIndexProfileAnalyzingAssigner { .map(|p| p.securified_personas_on_network(network_id)) .unwrap_or_default(); - Self { + let entities_on_network = EntitiesOnNetwork::with_split( network_id, unsecurified_accounts_on_network, securified_accounts_on_network, unsecurified_personas_on_network, securified_personas_on_network, + ) + .expect("Should have only queried entities on the correct network"); + + Self { + entities_on_network, } } fn max_entity_veci( &self, factor_source_id: FactorSourceIDFromHash, - entities: impl IntoIterator, + entities: impl IntoIterator, securified_entities: impl IntoIterator, entity_kind: CAP26EntityKind, key_space: KeySpace, @@ -108,7 +102,11 @@ impl NextDerivationEntityIndexProfileAnalyzingAssigner { ) -> Option { self.max_entity_veci( factor_source_id, - self.unsecurified_accounts_on_network.clone(), + self.unsecurified_accounts_on_network + .clone() + .iter() + .map(Into::::into) + .collect::>(), self.securified_accounts_on_network .clone() .into_iter() @@ -127,7 +125,11 @@ impl NextDerivationEntityIndexProfileAnalyzingAssigner { ) -> Option { self.max_entity_veci( factor_source_id, - self.unsecurified_personas_on_network.clone(), + self.unsecurified_personas_on_network + .clone() + .iter() + .map(Into::::into) + .collect::>(), self.securified_personas_on_network .clone() .into_iter() @@ -142,11 +144,18 @@ impl NextDerivationEntityIndexProfileAnalyzingAssigner { /// factor source id found. /// By "controlled by" we mean having a MatrixOfFactorInstances which has that /// factor in **any role** in its MatrixOfFactorInstances. - fn max_entity_mfa( + fn max_entity_mfa< + E: IsBaseEntity + + std::hash::Hash + + Eq + + Clone + + std::fmt::Debug + + Identifiable, + >( &self, factor_source_id: FactorSourceIDFromHash, - unsecurified_entities: &IndexSet, - securified_entities: &IndexSet>, + unsecurified_entities: &IdentifiedVecOf>, + securified_entities: &IdentifiedVecOf>, entity_kind: CAP26EntityKind, ) -> Option { let predicate = AssertMatches { @@ -164,7 +173,7 @@ impl NextDerivationEntityIndexProfileAnalyzingAssigner { let max_provisional_unsecurified = unsecurified_entities .iter() - .filter_map(|e| e.provisional_securified_config.as_ref()) + .filter_map(|e| e.provisional_securified_config.clone()) .flat_map(|x| { x.highest_derivation_path_index(factor_source_id, predicate) }) @@ -207,11 +216,18 @@ impl NextDerivationEntityIndexProfileAnalyzingAssigner { ) } - fn max_entity_rola( + fn max_entity_rola< + E: IsBaseEntity + + std::hash::Hash + + Eq + + Clone + + std::fmt::Debug + + Identifiable, + >( &self, factor_source_id: FactorSourceIDFromHash, - unsecurified_entities: &IndexSet, - securified_entities: &IndexSet>, + unsecurified_entities: &IdentifiedVecOf>, + securified_entities: &IdentifiedVecOf>, entity_kind: CAP26EntityKind, ) -> Option { let predicate = AssertMatches { diff --git a/crates/factors/keys-collector/Cargo.toml b/crates/factors/keys-collector/Cargo.toml index 5447043f8..e25677e12 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.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/factors/next-derivation-index-ephemeral/Cargo.toml b/crates/factors/next-derivation-index-ephemeral/Cargo.toml index ebf341767..538fc66b7 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.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/factors/supporting-types/Cargo.toml b/crates/factors/supporting-types/Cargo.toml index 28b67e8a2..1ede7f5c6 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.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/gateway/client-and-api/Cargo.toml b/crates/gateway/client-and-api/Cargo.toml index 734f3b873..39c8c2557 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.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/gateway/models/Cargo.toml b/crates/gateway/models/Cargo.toml index 6fab0370f..34ce62bc2 100644 --- a/crates/gateway/models/Cargo.toml +++ b/crates/gateway/models/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "gateway-models" -version = "1.1.115" +version = "1.1.116" edition = "2021" diff --git a/crates/profile/logic/logic_SPLIT_ME/Cargo.toml b/crates/profile/logic/logic_SPLIT_ME/Cargo.toml index 07efec42c..4c3a2aa6a 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.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/profile/logic/logic_SPLIT_ME/src/logic/account/query_accounts.rs b/crates/profile/logic/logic_SPLIT_ME/src/logic/account/query_accounts.rs index f1ebbcba7..cce9fc448 100644 --- a/crates/profile/logic/logic_SPLIT_ME/src/logic/account/query_accounts.rs +++ b/crates/profile/logic/logic_SPLIT_ME/src/logic/account/query_accounts.rs @@ -20,13 +20,13 @@ pub trait ProfileEntitiesOfKindOnNetworkInKeySpace { entity_kind: CAP26EntityKind, network_id: NetworkID, key_space: KeySpace, - ) -> IndexSet; + ) -> IdentifiedVecOf; fn get_unsecurified_entities_of_kind_on_network( &self, entity_kind: CAP26EntityKind, network_id: NetworkID, - ) -> IndexSet { + ) -> IdentifiedVecOf { self.get_entities_of_kind_on_network_in_key_space( entity_kind, network_id, @@ -35,40 +35,33 @@ pub trait ProfileEntitiesOfKindOnNetworkInKeySpace { KeySpace::Unsecurified { is_hardened: true }, ) .into_iter() - .map(|e: AccountOrPersona| { - let factor_instance = match e.security_state() { - EntitySecurityState::Unsecured { value: uec } => { - uec.transaction_signing.clone() - } - _ => unreachable!( - "Should already have filtered out securified entities" - ), - }; - UnsecurifiedEntity::new( - e.address(), - factor_instance, - e.get_provisional(), - ) - }) + .filter_map(|e: AccountOrPersona| AnyUnsecurifiedEntity::new(e).ok()) .collect() } fn unsecurified_accounts_on_network( &self, network_id: NetworkID, - ) -> IndexSet { + ) -> IdentifiedVecOf { self.get_unsecurified_entities_of_kind_on_network( CAP26EntityKind::Account, network_id, ) + .into_iter() + .map(|x| UnsecurifiedAccount::try_from(x).unwrap()) + .collect() } fn get_securified_entities_of_kind_on_network< - E: IsSecurifiedEntity + HasEntityKind + TryFrom, + E: IsSecurifiedEntity + + HasEntityKind + + TryFrom + + Identifiable + + std::fmt::Debug, >( &self, network_id: NetworkID, - ) -> IndexSet { + ) -> IdentifiedVecOf { self.get_entities_of_kind_on_network_in_key_space( E::entity_kind(), network_id, @@ -82,24 +75,27 @@ pub trait ProfileEntitiesOfKindOnNetworkInKeySpace { fn securified_accounts_on_network( &self, network_id: NetworkID, - ) -> IndexSet { + ) -> IdentifiedVecOf { self.get_securified_entities_of_kind_on_network(network_id) } fn unsecurified_personas_on_network( &self, network_id: NetworkID, - ) -> IndexSet { + ) -> IdentifiedVecOf { self.get_unsecurified_entities_of_kind_on_network( CAP26EntityKind::Identity, network_id, ) + .into_iter() + .map(|x| UnsecurifiedPersona::try_from(x).unwrap()) + .collect() } fn securified_personas_on_network( &self, network_id: NetworkID, - ) -> IndexSet { + ) -> IdentifiedVecOf { self.get_securified_entities_of_kind_on_network(network_id) } @@ -141,7 +137,7 @@ impl ProfileEntitiesOfKindOnNetworkInKeySpace for Profile { entity_kind: CAP26EntityKind, network_id: NetworkID, key_space: KeySpace, - ) -> IndexSet { + ) -> IdentifiedVecOf { self.networks .get_id(network_id) .map(|n| { diff --git a/crates/profile/models/account-for-display/Cargo.toml b/crates/profile/models/account-for-display/Cargo.toml index aeec84fcb..7e7fa75bd 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.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/profile/models/account-or-persona/Cargo.toml b/crates/profile/models/account-or-persona/Cargo.toml index a3c7af0fc..b934cf02d 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.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/profile/models/account/Cargo.toml b/crates/profile/models/account/Cargo.toml index 22988083a..643509b40 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.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/profile/models/app-preferences/Cargo.toml b/crates/profile/models/app-preferences/Cargo.toml index 7a3f198d1..617936e0a 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.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/profile/models/base-entity/Cargo.toml b/crates/profile/models/base-entity/Cargo.toml index c16bbfe10..9f552038e 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.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/profile/models/gateway/Cargo.toml b/crates/profile/models/gateway/Cargo.toml index 65edcfcae..a8c487b22 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.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/profile/models/persona-data/Cargo.toml b/crates/profile/models/persona-data/Cargo.toml index 93798578f..ca5ea7430 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.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/profile/models/persona/Cargo.toml b/crates/profile/models/persona/Cargo.toml index 02c4a04f8..74672bf4d 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.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/profile/models/profile_SPLIT_ME/Cargo.toml b/crates/profile/models/profile_SPLIT_ME/Cargo.toml index c2bfe95ef..06dca8eac 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.115" +version = "1.1.116" edition = "2021" diff --git a/crates/profile/models/profile_SPLIT_ME/src/v100/profile_network_get_entities.rs b/crates/profile/models/profile_SPLIT_ME/src/v100/profile_network_get_entities.rs index 4989479d6..93bb8c12c 100644 --- a/crates/profile/models/profile_SPLIT_ME/src/v100/profile_network_get_entities.rs +++ b/crates/profile/models/profile_SPLIT_ME/src/v100/profile_network_get_entities.rs @@ -47,13 +47,13 @@ pub trait ProfileNetworkEntitiesQuerying { fn get_entities_erased( &self, entity_kind: CAP26EntityKind, - ) -> IndexSet; + ) -> IdentifiedVecOf; fn get_entities_of_kind_in_key_space( &self, entity_kind: CAP26EntityKind, key_space: KeySpace, - ) -> IndexSet { + ) -> IdentifiedVecOf { self.get_entities_erased(entity_kind) .into_iter() .filter(|e| e.matches_key_space(key_space)) @@ -101,20 +101,20 @@ impl ProfileNetworkEntitiesQuerying for ProfileNetwork { fn get_entities_erased( &self, entity_kind: CAP26EntityKind, - ) -> IndexSet { + ) -> IdentifiedVecOf { match entity_kind { CAP26EntityKind::Account => self .accounts .items() .into_iter() .map(AccountOrPersona::from) - .collect::>(), + .collect::>(), CAP26EntityKind::Identity => self .personas .items() .into_iter() .map(AccountOrPersona::from) - .collect::>(), + .collect::>(), } } } diff --git a/crates/profile/models/security-structures/Cargo.toml b/crates/profile/models/security-structures/Cargo.toml index 425e5f4c9..fd24c03f5 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.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/profile/models/supporting-types/Cargo.toml b/crates/profile/models/supporting-types/Cargo.toml index ea69d0d69..1f27f36ad 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.115" +version = "1.1.116" edition = "2021" [dependencies] 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 6f7084067..b99ca27e0 100644 --- a/crates/profile/models/supporting-types/src/abstract_securified_entity.rs +++ b/crates/profile/models/supporting-types/src/abstract_securified_entity.rs @@ -12,6 +12,15 @@ pub struct AbstractSecurifiedEntity< pub securified_entity_control: SecuredEntityControl, } +impl Identifiable + for AbstractSecurifiedEntity +{ + type ID = AddressOfAccountOrPersona; + fn id(&self) -> Self::ID { + self.entity.address().into() + } +} + impl IsNetworkAware for AbstractSecurifiedEntity { @@ -32,14 +41,21 @@ impl IsSecurifiedEntity impl AbstractSecurifiedEntity { + pub fn with_securified_entity_control( + entity: E, + securified_entity_control: SecuredEntityControl, + ) -> Self { + Self { + __hidden: HiddenConstructor, + entity, + securified_entity_control, + } + } + pub fn new(entity: E) -> Result { entity .try_get_secured_control() - .map(|securified_entity_control| Self { - __hidden: HiddenConstructor, - entity, - securified_entity_control, - }) + .map(|sec| Self::with_securified_entity_control(entity, sec)) } pub fn address(&self) -> AddressOfAccountOrPersona { diff --git a/crates/profile/models/supporting-types/src/entities_on_network.rs b/crates/profile/models/supporting-types/src/entities_on_network.rs new file mode 100644 index 000000000..a882504ec --- /dev/null +++ b/crates/profile/models/supporting-types/src/entities_on_network.rs @@ -0,0 +1,154 @@ +use crate::prelude::*; + +#[derive(Debug, Clone, PartialEq)] +pub struct EntitiesOnNetwork { + pub network_id: NetworkID, + + /// might be empty + pub unsecurified_accounts_on_network: IdentifiedVecOf, + + /// might be empty + pub securified_accounts_on_network: IdentifiedVecOf, + + /// might be empty + pub unsecurified_personas_on_network: IdentifiedVecOf, + + /// might be empty + pub securified_personas_on_network: IdentifiedVecOf, +} + +impl EntitiesOnNetwork { + /// # Throws + /// Throws if any entity in `splitting` is not on the network `network_id` + pub fn with_split( + network_id: NetworkID, + unsecurified_accounts_on_network: IdentifiedVecOf, + securified_accounts_on_network: IdentifiedVecOf, + unsecurified_personas_on_network: IdentifiedVecOf, + securified_personas_on_network: IdentifiedVecOf, + ) -> Result { + if let Some(entity_wrong_network) = unsecurified_accounts_on_network + .iter() + .find(|e| e.network_id() != network_id) + .map(|e| e.network_id()) + .or(securified_accounts_on_network + .iter() + .find(|e| e.network_id() != network_id) + .map(|e| e.network_id())) + .or(unsecurified_personas_on_network + .iter() + .find(|e| e.network_id() != network_id) + .map(|e| e.network_id())) + .or(securified_personas_on_network + .iter() + .find(|e| e.network_id() != network_id) + .map(|e| e.network_id())) + { + return Err(CommonError::NetworkDiscrepancy { + expected: network_id.to_string(), + actual: entity_wrong_network.to_string(), + }); + } + Ok(Self { + network_id, + unsecurified_accounts_on_network, + securified_accounts_on_network, + unsecurified_personas_on_network, + securified_personas_on_network, + }) + } + + /// # Throws + /// Throws if any entity in `splitting` is not on the network `network_id` + pub fn new( + network_id: NetworkID, + splitting: impl IntoIterator, + ) -> Result { + let splitting = splitting.into_iter().collect::>(); + let len = splitting.len(); + let unsecurified = splitting + .iter() + .filter_map(|e| AnyUnsecurifiedEntity::new(e).ok()) + .collect::>(); + + let securified = splitting + .iter() + .filter_map(|e| AnySecurifiedEntity::new(e).ok()) + .collect::>(); + + let _self = Self::with_split( + network_id, + unsecurified + .iter() + .filter_map(|e| UnsecurifiedAccount::try_from(e).ok()) + .collect(), + securified + .iter() + .filter_map(|e| SecurifiedAccount::try_from(e).ok()) + .collect(), + unsecurified + .iter() + .filter_map(|e| UnsecurifiedPersona::try_from(e).ok()) + .collect(), + securified + .iter() + .filter_map(|e| SecurifiedPersona::try_from(e).ok()) + .collect(), + )?; + + assert_eq!( + len, + _self.securified_accounts_on_network.len() + + _self.unsecurified_accounts_on_network.len() + + _self.securified_personas_on_network.len() + + _self.unsecurified_personas_on_network.len(), + "Internal error, incorrect implementation of SecurifiedEntity or UnsecurifiedEntity" + ); + + Ok(_self) + } + + pub fn unsecurified_erased( + &self, + ) -> IdentifiedVecOf { + let mut entities = IdentifiedVecOf::new(); + entities.extend( + self.unsecurified_accounts_on_network + .iter() + .map(|e| e.into()), + ); + + entities.extend( + self.unsecurified_personas_on_network + .iter() + .map(|e| e.into()), + ); + + entities + } + + pub fn securified_erased(&self) -> IdentifiedVecOf { + let mut entities = IdentifiedVecOf::new(); + entities.extend( + self.securified_accounts_on_network.iter().map(|e| e.into()), + ); + + entities.extend( + self.securified_personas_on_network.iter().map(|e| e.into()), + ); + + entities + } + + fn to_entities(&self) -> IdentifiedVecOf { + let mut entities = IdentifiedVecOf::new(); + entities.extend(self.unsecurified_erased().iter().map(|e| e.entity)); + entities.extend(self.securified_erased().iter().map(|e| e.entity)); + + entities + } + + pub fn all(&self, predicate: impl Fn(AccountOrPersona) -> bool) -> bool { + self.to_entities().iter().all(predicate) + } +} diff --git a/crates/profile/models/supporting-types/src/lib.rs b/crates/profile/models/supporting-types/src/lib.rs index c8fbc7f80..d0bc7f961 100644 --- a/crates/profile/models/supporting-types/src/lib.rs +++ b/crates/profile/models/supporting-types/src/lib.rs @@ -1,6 +1,7 @@ mod abstract_securified_entity; mod any_securified_entity; mod assert_derivation_path; +mod entities_on_network; mod is_securified_entity; mod profile_state; mod securified_account; @@ -12,6 +13,7 @@ pub mod prelude { pub use crate::abstract_securified_entity::*; pub use crate::any_securified_entity::*; pub use crate::assert_derivation_path::*; + pub use crate::entities_on_network::*; pub use crate::is_securified_entity::*; pub use crate::profile_state::*; pub use crate::securified_account::*; diff --git a/crates/profile/models/supporting-types/src/securified_account.rs b/crates/profile/models/supporting-types/src/securified_account.rs index 409eaae18..d9b52a752 100644 --- a/crates/profile/models/supporting-types/src/securified_account.rs +++ b/crates/profile/models/supporting-types/src/securified_account.rs @@ -9,6 +9,12 @@ impl SecurifiedAccount { } } +impl From for AnySecurifiedEntity { + fn from(value: SecurifiedAccount) -> Self { + value.erase_to_any() + } +} + impl HasEntityKind for SecurifiedAccount { fn entity_kind() -> CAP26EntityKind { CAP26EntityKind::Account @@ -23,6 +29,21 @@ impl TryFrom for SecurifiedAccount { } } +impl TryFrom for SecurifiedAccount { + type Error = CommonError; + + fn try_from(value: AnySecurifiedEntity) -> Result { + match value.entity { + AccountOrPersona::AccountEntity(account) => Self::new(account), + AccountOrPersona::PersonaEntity(_) => { + Err(CommonError::ExpectedAccountButGotPersona { + address: value.entity.address().to_string(), + }) + } + } + } +} + impl HasSampleValues for SecurifiedAccount { fn sample() -> Self { Self::new(Account::sample_at(2)).unwrap() diff --git a/crates/profile/models/supporting-types/src/securified_persona.rs b/crates/profile/models/supporting-types/src/securified_persona.rs index 2cc7f600d..d9b482925 100644 --- a/crates/profile/models/supporting-types/src/securified_persona.rs +++ b/crates/profile/models/supporting-types/src/securified_persona.rs @@ -9,6 +9,12 @@ impl SecurifiedPersona { } } +impl From for AnySecurifiedEntity { + fn from(value: SecurifiedPersona) -> Self { + value.erase_to_any() + } +} + impl HasEntityKind for SecurifiedPersona { fn entity_kind() -> CAP26EntityKind { CAP26EntityKind::Identity @@ -22,3 +28,18 @@ impl TryFrom for SecurifiedPersona { Persona::try_from(value).and_then(Self::new) } } + +impl TryFrom for SecurifiedPersona { + type Error = CommonError; + + fn try_from(value: AnySecurifiedEntity) -> Result { + match value.entity { + AccountOrPersona::PersonaEntity(persona) => Self::new(persona), + AccountOrPersona::AccountEntity(_) => { + Err(CommonError::ExpectedPersonaButGotAccount { + address: value.entity.address().to_string(), + }) + } + } + } +} diff --git a/crates/profile/models/supporting-types/src/unsecurified_entity.rs b/crates/profile/models/supporting-types/src/unsecurified_entity.rs index d9274111d..5ba614284 100644 --- a/crates/profile/models/supporting-types/src/unsecurified_entity.rs +++ b/crates/profile/models/supporting-types/src/unsecurified_entity.rs @@ -1,37 +1,65 @@ use crate::prelude::*; -/// The HierarchicalDeterministicFactorInstance and address of some -/// unsecurified entity. -#[derive(Clone, Debug, PartialEq, Eq, Hash)] -pub struct UnsecurifiedEntity { +/// An unsecurified entity + +#[derive(Clone, PartialEq, Eq, Hash, derive_more::Debug)] +pub struct AbstractUnsecurifiedEntity< + E: IsBaseEntity + std::hash::Hash + Eq + Clone, +> where + E::Address: Into, +{ + pub entity: E, + unsecured_entity_control: UnsecuredEntityControl, veci: VirtualEntityCreatingInstance, pub provisional_securified_config: Option, } -impl UnsecurifiedEntity { - pub fn with_veci( - veci: VirtualEntityCreatingInstance, - provisional_securified_config: impl Into< - Option, - >, +impl Identifiable + for AbstractUnsecurifiedEntity +where + E::Address: Into, +{ + type ID = AddressOfAccountOrPersona; + fn id(&self) -> Self::ID { + self.entity.address().into() + } +} + +impl + AbstractUnsecurifiedEntity +where + E::Address: Into, +{ + pub fn with_unsecured_entity_control( + entity: E, + unsecured_entity_control: UnsecuredEntityControl, ) -> Self { Self { - veci, - provisional_securified_config: provisional_securified_config.into(), + entity: entity.clone(), + unsecured_entity_control: unsecured_entity_control.clone(), + veci: VirtualEntityCreatingInstance::new( + unsecured_entity_control.transaction_signing, + Into::::into(entity.address()), + ), + provisional_securified_config: unsecured_entity_control + .provisional_securified_config, } } - /// # Panics - /// Panics if address does not match `factor_instance` - pub fn new( - address: AddressOfAccountOrPersona, - factor_instance: HierarchicalDeterministicFactorInstance, - provisional_securified_config: impl Into< - Option, - >, - ) -> Self { - let veci = VirtualEntityCreatingInstance::new(factor_instance, address); - Self::with_veci(veci, provisional_securified_config) + /// # Throws + /// Throws if the entity is securified + pub fn new(entity: E) -> Result { + match entity.security_state() { + EntitySecurityState::Unsecured { + value: unsecured_entity_control, + } => Ok(Self::with_unsecured_entity_control( + entity, + unsecured_entity_control, + )), + EntitySecurityState::Securified { .. } => { + Err(CommonError::SecurityStateSecurifiedButExpectedUnsecurified) + } + } } pub fn network_id(&self) -> NetworkID { @@ -47,13 +75,65 @@ impl UnsecurifiedEntity { } } -impl HasSampleValues for UnsecurifiedEntity { +pub type AnyUnsecurifiedEntity = AbstractUnsecurifiedEntity; + +pub type UnsecurifiedAccount = AbstractUnsecurifiedEntity; +pub type UnsecurifiedPersona = AbstractUnsecurifiedEntity; + +impl TryFrom for UnsecurifiedAccount { + type Error = CommonError; + + fn try_from(value: AnyUnsecurifiedEntity) -> Result { + match value.entity { + AccountOrPersona::AccountEntity(account) => Self::new(account), + AccountOrPersona::PersonaEntity(_) => { + Err(CommonError::ExpectedAccountButGotPersona { + address: value.entity.address().to_string(), + }) + } + } + } +} +impl From for AnyUnsecurifiedEntity { + fn from(value: UnsecurifiedAccount) -> Self { + Self::with_unsecured_entity_control( + value.entity.into(), + value.unsecured_entity_control, + ) + } +} + +impl From for AnyUnsecurifiedEntity { + fn from(value: UnsecurifiedPersona) -> Self { + Self::with_unsecured_entity_control( + value.entity.into(), + value.unsecured_entity_control, + ) + } +} + +impl TryFrom for UnsecurifiedPersona { + type Error = CommonError; + + fn try_from(value: AnyUnsecurifiedEntity) -> Result { + match value.entity { + AccountOrPersona::PersonaEntity(persona) => Self::new(persona), + AccountOrPersona::AccountEntity(_) => { + Err(CommonError::ExpectedPersonaButGotAccount { + address: value.entity.address().to_string(), + }) + } + } + } +} + +impl HasSampleValues for AnyUnsecurifiedEntity { fn sample() -> Self { - Self::with_veci(VirtualEntityCreatingInstance::sample(), None) + Self::new(Account::sample().into()).unwrap() } fn sample_other() -> Self { - Self::with_veci(VirtualEntityCreatingInstance::sample_other(), None) + Self::new(Account::sample_other().into()).unwrap() } } @@ -62,7 +142,7 @@ mod tests { use super::*; #[allow(clippy::upper_case_acronyms)] - type SUT = UnsecurifiedEntity; + type SUT = AnyUnsecurifiedEntity; #[test] fn equality() { @@ -77,6 +157,6 @@ mod tests { #[test] fn network_id() { - assert_eq!(SUT::sample_other().network_id(), NetworkID::Stokenet); + assert_eq!(SUT::sample_other().network_id(), NetworkID::Mainnet); } } diff --git a/crates/profile/traits/entity-by-address/Cargo.toml b/crates/profile/traits/entity-by-address/Cargo.toml index 826d8cbef..ffa16ed5d 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.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/sargon/Cargo.toml b/crates/sargon/Cargo.toml index 12a89c454..e592d9866 100644 --- a/crates/sargon/Cargo.toml +++ b/crates/sargon/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sargon" -version = "1.1.115" +version = "1.1.116" 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 9c3bfb1e4..c1af5ed37 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.115" +version = "1.1.116" edition = "2021" diff --git a/crates/system/clients/http/Cargo.toml b/crates/system/clients/http/Cargo.toml index 1d2c1810b..fc3c192b0 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.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/system/drivers/Cargo.toml b/crates/system/drivers/Cargo.toml index e80dc62e9..25419de47 100644 --- a/crates/system/drivers/Cargo.toml +++ b/crates/system/drivers/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "drivers" -version = "1.1.115" +version = "1.1.116" edition = "2021" diff --git a/crates/system/interactors/Cargo.toml b/crates/system/interactors/Cargo.toml index e9ee50537..d26a9a205 100644 --- a/crates/system/interactors/Cargo.toml +++ b/crates/system/interactors/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "interactors" -version = "1.1.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/system/os/accounts/Cargo.toml b/crates/system/os/accounts/Cargo.toml index 3dbce21af..7c2aad850 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.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/system/os/factors/Cargo.toml b/crates/system/os/factors/Cargo.toml index dcb7822fd..2a215a32a 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.115" +version = "1.1.116" edition = "2021" [dependencies] @@ -15,6 +15,9 @@ clients = { workspace = true } profile-logic = { workspace = true } factor-instances-provider = { workspace = true } key-derivation-traits = { workspace = true } +radix-connect = { workspace = true } +transaction-models = { workspace = true } +manifests = { workspace = true } # ==== RADIX DEPENDENCIES ==== # None @@ -23,7 +26,9 @@ key-derivation-traits = { workspace = true } actix-rt = { workspace = true } async-trait = { workspace = true } derive_more = { workspace = true } +enum-as-inner = { workspace = true } log = { workspace = true } +preinterpret = { workspace = true } pretty_assertions = { workspace = true } serde = { workspace = true } serde_json = { workspace = true } diff --git a/crates/system/os/factors/src/apply_security_shield/mod.rs b/crates/system/os/factors/src/apply_security_shield/mod.rs new file mode 100644 index 000000000..94e4a3f41 --- /dev/null +++ b/crates/system/os/factors/src/apply_security_shield/mod.rs @@ -0,0 +1,5 @@ +mod sargon_os_apply_security_shield_interaction; +mod sargon_os_apply_shield; + +pub use sargon_os_apply_security_shield_interaction::*; +pub use sargon_os_apply_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 new file mode 100644 index 000000000..30e6d19e2 --- /dev/null +++ b/crates/system/os/factors/src/apply_security_shield/sargon_os_apply_security_shield_interaction.rs @@ -0,0 +1,57 @@ +use crate::prelude::*; +use radix_connect::DappToWalletInteractionBatchOfTransactions; + +#[async_trait::async_trait] +pub trait OsApplySecurityShieldInteraction { + async fn make_interaction_for_applying_security_shield( + &self, + security_shield_id: SecurityStructureID, + addresses: IndexSet, + ) -> Result; +} + +#[async_trait::async_trait] +impl OsApplySecurityShieldInteraction for SargonOS { + async fn make_interaction_for_applying_security_shield( + &self, + security_shield_id: SecurityStructureID, + addresses: IndexSet, + ) -> Result { + let entities_with_provisional = self + .apply_security_shield_with_id_to_entities( + security_shield_id, + addresses, + ) + .await?; + + let manifests_for_unsecurified = entities_with_provisional + .unsecurified_erased() + .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"); + let input = TransactionManifestApplySecurityShieldUnsecurifiedInput::new(derived.clone()); + TransactionManifest::apply_security_shield_for_unsecurified_entity( + e, + input, + ) + }).collect::>>()?; + + let manifests_for_securified = entities_with_provisional + .securified_erased() + .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") + }).collect::>>()?; + + Ok(DappToWalletInteractionBatchOfTransactions::new( + manifests_for_unsecurified + .iter() + .chain(manifests_for_securified.iter()) + .cloned() + .map(UnvalidatedTransactionManifest::from), + )) + } +} diff --git a/crates/system/os/factors/src/sargon_os_apply_shield.rs b/crates/system/os/factors/src/apply_security_shield/sargon_os_apply_shield.rs similarity index 98% rename from crates/system/os/factors/src/sargon_os_apply_shield.rs rename to crates/system/os/factors/src/apply_security_shield/sargon_os_apply_shield.rs index 9b68ee682..e97082052 100644 --- a/crates/system/os/factors/src/sargon_os_apply_shield.rs +++ b/crates/system/os/factors/src/apply_security_shield/sargon_os_apply_shield.rs @@ -6,7 +6,7 @@ pub trait OsShieldApplying { &self, security_shield_id: SecurityStructureID, addresses: IndexSet, - ) -> Result<()>; + ) -> Result; async fn _apply_security_structure_of_factor_sources_to_entities_with_diagnostics( &self, @@ -21,14 +21,7 @@ pub trait OsShieldApplying { &self, shield: &SecurityStructureOfFactorSources, entity_addresses: IndexSet, - ) -> Result<()> { - self._apply_security_structure_of_factor_sources_to_entities_with_diagnostics( - shield, - entity_addresses, - ) - .await - .map(|_| ()) - } + ) -> Result; async fn _provide_instances_using_shield_for_entities_by_address_without_consuming_cache( &self, @@ -58,7 +51,7 @@ impl OsShieldApplying for SargonOS { &self, security_shield_id: SecurityStructureID, addresses: IndexSet, - ) -> Result<()> { + ) -> Result { let shield = self .security_structure_of_factor_sources_from_security_structure_id( security_shield_id, @@ -69,6 +62,20 @@ impl OsShieldApplying for SargonOS { .await } + async fn apply_security_structure_of_factor_sources_to_entities( + &self, + shield: &SecurityStructureOfFactorSources, + entity_addresses: IndexSet, + ) -> Result { + let network = self.current_network_id()?; + self._apply_security_structure_of_factor_sources_to_entities_with_diagnostics( + shield, + entity_addresses, + ) + .await + .and_then(|(entities, _)| EntitiesOnNetwork::new(network, entities)) + } + async fn _apply_security_structure_of_factor_sources_to_entities_with_diagnostics( &self, shield: &SecurityStructureOfFactorSources, diff --git a/crates/system/os/factors/src/lib.rs b/crates/system/os/factors/src/lib.rs index d2eac240f..532283d93 100644 --- a/crates/system/os/factors/src/lib.rs +++ b/crates/system/os/factors/src/lib.rs @@ -1,4 +1,4 @@ -mod sargon_os_apply_shield; +mod apply_security_shield; mod sargon_os_entities_linked_to_factor_source; mod sargon_os_security_structures; @@ -6,13 +6,15 @@ mod sargon_os_security_structures; mod test_instances_provider; pub mod prelude { - pub use crate::sargon_os_apply_shield::*; + pub use crate::apply_security_shield::*; + pub use crate::sargon_os_entities_linked_to_factor_source::*; pub use crate::sargon_os_security_structures::*; pub use clients::prelude::*; pub use factor_instances_provider::prelude::*; pub use key_derivation_traits::prelude::*; + pub use manifests::prelude::*; pub use profile_logic::prelude::*; pub use sargon_os::prelude::*; diff --git a/crates/system/os/factors/src/sargon_os_security_structures.rs b/crates/system/os/factors/src/sargon_os_security_structures.rs index 5117eaf6e..818b13c25 100644 --- a/crates/system/os/factors/src/sargon_os_security_structures.rs +++ b/crates/system/os/factors/src/sargon_os_security_structures.rs @@ -221,14 +221,13 @@ mod tests { // ACT let structure_factor_id_level = SecurityStructureOfFactorSourceIDs::sample(); - let _ = os - .with_timeout(|x| { - x.add_security_structure_of_factor_source_ids( - &structure_factor_id_level, - ) - }) - .await - .unwrap(); + os.with_timeout(|x| { + x.add_security_structure_of_factor_source_ids( + &structure_factor_id_level, + ) + }) + .await + .unwrap(); // ASSERT assert!(os @@ -322,12 +321,11 @@ mod tests { // ACT let structure_ids = SecurityStructureOfFactorSourceIDs::sample(); let id = structure_ids.metadata.id; - let _ = os - .with_timeout(|x| { - x.add_security_structure_of_factor_source_ids(&structure_ids) - }) - .await - .unwrap(); + os.with_timeout(|x| { + x.add_security_structure_of_factor_source_ids(&structure_ids) + }) + .await + .unwrap(); // ASSERT assert!(event_bus_driver.recorded().iter().any(|e| e.event @@ -350,14 +348,13 @@ mod tests { SecurityStructureOfFactorSourceIDs::sample(); let structure_source_ids_sample_other = SecurityStructureOfFactorSourceIDs::sample_other(); - let _ = os - .with_timeout(|x| { - x.add_security_structure_of_factor_source_ids( - &structure_source_ids_sample, - ) - }) - .await - .unwrap(); + os.with_timeout(|x| { + x.add_security_structure_of_factor_source_ids( + &structure_source_ids_sample, + ) + }) + .await + .unwrap(); let result = os .with_timeout(|x| { @@ -373,14 +370,13 @@ mod tests { }) ); - let _ = os - .with_timeout(|x| { - x.add_security_structure_of_factor_source_ids( - &structure_source_ids_sample_other, - ) - }) - .await - .unwrap(); + os.with_timeout(|x| { + x.add_security_structure_of_factor_source_ids( + &structure_source_ids_sample_other, + ) + }) + .await + .unwrap(); let structure_id_sample = SecurityStructureOfFactorSourceIDs::from( structure_source_ids_sample.clone(), diff --git a/crates/system/os/os/Cargo.toml b/crates/system/os/os/Cargo.toml index 409580eac..4132fd954 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.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/system/os/security-center/Cargo.toml b/crates/system/os/security-center/Cargo.toml index f3d1ae63b..17c5b852d 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.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/system/os/signing/Cargo.toml b/crates/system/os/signing/Cargo.toml index ea9c1d884..6234f57d9 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.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/system/os/signing/src/sargon_os_signing.rs b/crates/system/os/signing/src/sargon_os_signing.rs index c30741972..f4dbcf743 100644 --- a/crates/system/os/signing/src/sargon_os_signing.rs +++ b/crates/system/os/signing/src/sargon_os_signing.rs @@ -340,9 +340,9 @@ mod test { let signable = TransactionIntent::sample_entity_addresses_requiring_auth( [ - account_device.address.clone(), - account_ledger1.address.clone(), - account_ledger2.address.clone(), + account_device.address, + account_ledger1.address, + account_ledger2.address, ], [], ); diff --git a/crates/system/os/transaction/Cargo.toml b/crates/system/os/transaction/Cargo.toml index 10ed7a5b9..c51709ab5 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.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/system/profile-state-holder/Cargo.toml b/crates/system/profile-state-holder/Cargo.toml index deed76db4..0cbf800ca 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.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/system/sub-systems/Cargo.toml b/crates/system/sub-systems/Cargo.toml index d5802903f..1b47e8356 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.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/transaction/foundation/Cargo.toml b/crates/transaction/foundation/Cargo.toml index c603f4577..744c758c5 100644 --- a/crates/transaction/foundation/Cargo.toml +++ b/crates/transaction/foundation/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "transaction-foundation" -version = "1.1.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/transaction/manifests/Cargo.toml b/crates/transaction/manifests/Cargo.toml index 51b125320..c0f7122c3 100644 --- a/crates/transaction/manifests/Cargo.toml +++ b/crates/transaction/manifests/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "manifests" -version = "1.1.115" +version = "1.1.116" edition = "2021" @@ -17,6 +17,7 @@ transaction-models = { workspace = true } gateway-models = { workspace = true } profile = { workspace = true } profile-account-or-persona = { workspace = true } +profile-supporting-types = { workspace = true } profile-base-entity = { workspace = true } account-for-display = { workspace = true } diff --git a/crates/transaction/manifests/src/lib.rs b/crates/transaction/manifests/src/lib.rs index 5aecc5fb4..45ff0b5a8 100644 --- a/crates/transaction/manifests/src/lib.rs +++ b/crates/transaction/manifests/src/lib.rs @@ -4,9 +4,10 @@ mod delete_account; mod high_level; mod manifest_account_locker; mod manifest_assets_transfers; +mod manifest_builder_from_manifest; mod manifests; -mod manifests_access_controller; mod manifests_create_tokens; +mod manifests_security_shield; mod modify_manifest; mod third_party_deposit_update; @@ -18,9 +19,10 @@ pub mod prelude { pub use crate::high_level::*; pub use crate::manifest_account_locker::*; pub use crate::manifest_assets_transfers::*; + pub use crate::manifest_builder_from_manifest::*; pub use crate::manifests::*; - pub use crate::manifests_access_controller::*; pub use crate::manifests_create_tokens::*; + pub use crate::manifests_security_shield::*; pub use crate::modify_manifest::*; pub use crate::third_party_deposit_update::*; diff --git a/crates/transaction/manifests/src/manifest_builder_from_manifest.rs b/crates/transaction/manifests/src/manifest_builder_from_manifest.rs new file mode 100644 index 000000000..27c286068 --- /dev/null +++ b/crates/transaction/manifests/src/manifest_builder_from_manifest.rs @@ -0,0 +1,26 @@ +use radix_transactions::prelude::ManifestBuilder; + +use crate::prelude::*; + +pub trait BuilderFromManifest { + fn with_instructions( + instructions: impl IntoIterator, + ) -> ManifestBuilder; + + fn with_manifest(manifest: TransactionManifest) -> ManifestBuilder { + Self::with_instructions(manifest.instructions().clone()) + } +} + +impl BuilderFromManifest for ManifestBuilder { + fn with_instructions( + instructions: impl IntoIterator, + ) -> ManifestBuilder { + instructions.into_iter().fold( + ManifestBuilder::new(), + |builder, instruction| { + builder.add_instruction_advanced(instruction).0 + }, + ) + } +} diff --git a/crates/transaction/manifests/src/manifests_access_controller.rs b/crates/transaction/manifests/src/manifests_access_controller.rs deleted file mode 100644 index 1279ff504..000000000 --- a/crates/transaction/manifests/src/manifests_access_controller.rs +++ /dev/null @@ -1,229 +0,0 @@ -use bucket_factory::BucketFactory; - -use crate::prelude::*; - -pub trait TransactionManifestSecurifyEntity: Sized { - fn _securify_unsecurified_entity( - entity_address: AddressOfAccountOrPersona, - security_structure_of_factor_instances: SecurityStructureOfFactorInstances, - ) -> Result; - - fn securify_unsecurified_entity( - entity: E, - security_structure_of_factor_instances: SecurityStructureOfFactorInstances, - ) -> Result { - let Ok(unsecurified) = entity.security_state().into_unsecured() else { - return Err(CommonError::CannotSecurifyEntityItIsAlreadySecurifiedAccordingToProfile); - }; - - if unsecurified.provisional_securified_config.is_some() { - return Err( - CommonError::CannotSecurifyEntityHasProvisionalSecurityConfig, - ); - }; - - Self::_securify_unsecurified_entity( - Into::::into(entity.address()), - security_structure_of_factor_instances, - ) - } -} - -impl TransactionManifestSecurifyEntity for TransactionManifest { - fn _securify_unsecurified_entity( - entity_address: AddressOfAccountOrPersona, - security_structure_of_factor_instances: SecurityStructureOfFactorInstances, - ) -> Result { - 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(); - let bucket_factory = BucketFactory::default(); - - // Securify the entity which will return an entity owner badge onto the worktop. - let owner_badge_bucket = &{ - builder = builder.call_method( - &entity_address, - security_entity_identifier, - (), - ); - - // Create a bucket out of the entity owner badge. - let owner_badge_bucket = bucket_factory.next(); - builder = - builder.take_from_worktop(owner_badge, 1, &owner_badge_bucket); - owner_badge_bucket - }; - - // Create an access controller for the entity. - { - let timed_recovery_delay_in_minutes = - security_structure_of_factor_instances - .timed_recovery_delay_in_minutes(); - let rule_set = ScryptoRuleSet::from( - security_structure_of_factor_instances.matrix_of_factors, - ); - - builder = builder.create_access_controller( - owner_badge_bucket, - rule_set.primary_role, - rule_set.recovery_role, - rule_set.confirmation_role, - Some(timed_recovery_delay_in_minutes), - ); - } - - // Set Rola Key - { - let rola_key_hash = PublicKeyHash::hash( - security_structure_of_factor_instances - .authentication_signing_factor_instance - .public_key(), - ); - let owner_key_hashes = vec![rola_key_hash]; - builder = Self::set_owner_keys_hashes_on_builder( - &entity_address, - owner_key_hashes, - builder, - ); - } - - let manifest = TransactionManifest::sargon_built( - builder, - entity_address.network_id(), - ); - - Ok(manifest) - } -} - -#[cfg(test)] -mod tests { - - use prelude::fixture_rtm; - - use super::*; - - #[test] - fn cannot_securify_entity_it_is_already_securified_according_to_profile() { - let account = Account::sample_at(2); - assert!(account.is_securified()); - let res = TransactionManifest::securify_unsecurified_entity( - account, - SecurityStructureOfFactorInstances::sample(), - ); - assert_eq!(res, Err(CommonError::CannotSecurifyEntityItIsAlreadySecurifiedAccordingToProfile)); - } - - #[test] - fn cannot_securify_entity_with_provisional() { - let mut account = Account::sample_alice(); - assert!(!account.is_securified()); - account.security_state.set_provisional( - ProvisionalSecurifiedConfig::FactorInstancesDerived { - value: SecurityStructureOfFactorInstances::sample(), - }, - ); - let res = TransactionManifest::securify_unsecurified_entity( - account, - SecurityStructureOfFactorInstances::sample(), - ); - assert_eq!( - res, - Err(CommonError::CannotSecurifyEntityHasProvisionalSecurityConfig) - ); - } - - #[test] - fn test_securify_unsecurified_account() { - let expected_manifest_str = - fixture_rtm!("create_access_controller_for_account"); - let entity = Account::sample(); - let security_structure_of_factor_instances = - SecurityStructureOfFactorInstances::sample(); - let manifest = TransactionManifest::securify_unsecurified_entity( - entity.clone(), - security_structure_of_factor_instances.clone(), - ) - .unwrap(); - manifest_eq(manifest, expected_manifest_str); - assert!(expected_manifest_str.contains("securify")); - assert!(expected_manifest_str.contains( - &security_structure_of_factor_instances - .timed_recovery_delay_in_minutes() - .to_string() - )); - - for fi in security_structure_of_factor_instances - .unique_all_factor_instances() - .into_iter() - .filter_map(|f| f.try_as_hd_factor_instances().ok()) - { - assert!(expected_manifest_str - .contains(&PublicKeyHash::hash(fi.public_key()).to_string())); - } - - assert!(expected_manifest_str.contains(&entity.address.to_string())); - } - - #[test] - fn test_securify_unsecurified_persona() { - let expected_manifest_str = - fixture_rtm!("create_access_controller_for_persona"); - let entity = Persona::sample_other(); - let security_structure_of_factor_instances = - SecurityStructureOfFactorInstances::sample_other(); - let manifest = TransactionManifest::securify_unsecurified_entity( - entity.clone(), - security_structure_of_factor_instances.clone(), - ) - .unwrap(); - manifest_eq(manifest, expected_manifest_str); - - assert!(expected_manifest_str.contains("securify")); - assert!(expected_manifest_str.contains( - &security_structure_of_factor_instances - .timed_recovery_delay_in_minutes() - .to_string() - )); - - for fi in security_structure_of_factor_instances - .unique_all_factor_instances() - .into_iter() - .filter_map(|f| f.try_as_hd_factor_instances().ok()) - { - assert!(expected_manifest_str - .contains(&PublicKeyHash::hash(fi.public_key()).to_string())); - } - - assert!(expected_manifest_str.contains(&entity.address.to_string())); - } - - #[test] - fn test_mismatch_entity_kind_account_persona() { - let manifest = TransactionManifest::securify_unsecurified_entity( - Account::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() })); - } - - #[test] - fn test_mismatch_entity_kind_persona_account() { - let manifest = TransactionManifest::securify_unsecurified_entity( - Persona::sample_other(), - 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/manifests_security_shield.rs b/crates/transaction/manifests/src/manifests_security_shield/manifests_security_shield.rs new file mode 100644 index 000000000..43d797ccf --- /dev/null +++ b/crates/transaction/manifests/src/manifests_security_shield/manifests_security_shield.rs @@ -0,0 +1,327 @@ +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_transactions::prelude::ManifestBuilder; + +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 TransactionManifestSecurifyEntity: Sized { + 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, + ) + } + + /// 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`) + fn apply_security_shield_for_unsecurified_entity( + unsecurified_entity: AnyUnsecurifiedEntity, + input: TransactionManifestApplySecurityShieldUnsecurifiedInput, + ) -> 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())?; + + 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, + ); + }; + + // Create an access controller for the entity. + builder = { + let access_controller_reservation_identifier = + "access_controller_reservation"; + + builder = builder.allocate_global_address( + SCRYPTO_ACCESS_CONTROLLER_PACKAGE, + SCRYPTO_ACCESS_CONTROLLER_BLUEPRINT, + access_controller_reservation_identifier, + "access_controller_named_address", + ); + + let access_controller_address_reservation = builder + .address_reservation(access_controller_reservation_identifier); + + let timed_recovery_delay_in_minutes = + &security_structure_of_factor_instances + .timed_recovery_delay_in_minutes(); + + let rule_set = ScryptoRuleSet::from( + security_structure_of_factor_instances + .matrix_of_factors + .clone(), + ); + + let owner_badge_bucket = builder.bucket(owner_badge_bucket_name); + + builder.call_function( + SCRYPTO_ACCESS_CONTROLLER_PACKAGE, + SCRYPTO_ACCESS_CONTROLLER_BLUEPRINT, + SCRYPTO_ACCESS_CONTROLLER_CREATE_IDENT, + ScryptoAccessControllerCreateManifestInput { + controlled_asset: owner_badge_bucket, + rule_set, + timed_recovery_delay_in_minutes: Some( + *timed_recovery_delay_in_minutes, + ), + address_reservation: Some( + access_controller_address_reservation, + ), + }, + ) + }; + + // Set Rola Key + builder = TransactionManifest::set_rola_key( + builder, + &security_structure_of_factor_instances + .authentication_signing_factor_instance, + &entity_address, + ); + + let manifest = TransactionManifest::sargon_built( + builder, + entity_address.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) + } +} + +#[cfg(test)] +mod tests { + + use prelude::fixture_rtm; + + use super::*; + + #[test] + fn test_securify_unsecurified_account() { + let expected_manifest_str = + fixture_rtm!("create_access_controller_for_account"); + let entity = 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(), + TransactionManifestApplySecurityShieldUnsecurifiedInput::new( + security_structure_of_factor_instances.clone(), + ), + ) + .unwrap(); + manifest_eq(manifest.clone(), expected_manifest_str); + assert!(expected_manifest_str.contains("securify")); + assert!(expected_manifest_str.contains( + &security_structure_of_factor_instances + .timed_recovery_delay_in_minutes() + .to_string() + )); + + for fi in security_structure_of_factor_instances + .unique_all_factor_instances() + .into_iter() + .filter_map(|f| f.try_as_hd_factor_instances().ok()) + { + assert!(expected_manifest_str + .contains(&PublicKeyHash::hash(fi.public_key()).to_string())); + } + + assert!(expected_manifest_str.contains(&entity.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( + bob.clone(), + entity.clone(), + manifest.clone(), + None, + ); + + let expected_manifest_str = + fixture_rtm!("create_access_controller_for_account_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_paid_by_account( + grace_secure.clone(), + entity.clone(), + manifest.clone(), + Decimal192::from(42), + ); + + let expected_manifest_str = + fixture_rtm!("create_access_controller_for_account_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_securify_unsecurified_persona() { + let expected_manifest_str = + fixture_rtm!("create_access_controller_for_persona"); + let entity = 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(), + TransactionManifestApplySecurityShieldUnsecurifiedInput::new( + security_structure_of_factor_instances.clone(), + ), + ) + .unwrap(); + manifest_eq(manifest, expected_manifest_str); + + assert!(expected_manifest_str.contains("securify")); + assert!(expected_manifest_str.contains( + &security_structure_of_factor_instances + .timed_recovery_delay_in_minutes() + .to_string() + )); + + for fi in security_structure_of_factor_instances + .unique_all_factor_instances() + .into_iter() + .filter_map(|f| f.try_as_hd_factor_instances().ok()) + { + assert!(expected_manifest_str + .contains(&PublicKeyHash::hash(fi.public_key()).to_string())); + } + + assert!(expected_manifest_str.contains(&entity.address.to_string())); + } + + #[test] + fn test_mismatch_entity_kind_account_persona() { + let manifest = + TransactionManifest::apply_security_shield_for_unsecurified_entity( + AnyUnsecurifiedEntity::new(Account::sample_other().into()) + .unwrap(), + TransactionManifestApplySecurityShieldUnsecurifiedInput::new( + 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() })); + } + + #[test] + fn test_mismatch_entity_kind_persona_account() { + let manifest = + TransactionManifest::apply_security_shield_for_unsecurified_entity( + AnyUnsecurifiedEntity::new(Persona::sample_other().into()) + .unwrap(), + TransactionManifestApplySecurityShieldUnsecurifiedInput::new( + 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 new file mode 100644 index 000000000..8e47aa265 --- /dev/null +++ b/crates/transaction/manifests/src/manifests_security_shield/mod.rs @@ -0,0 +1,6 @@ +#[allow(clippy::module_inception)] +mod manifests_security_shield; +mod top_up_access_controller_xrd_vault; + +pub use manifests_security_shield::*; +pub use top_up_access_controller_xrd_vault::*; 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 new file mode 100644 index 000000000..d9943dba4 --- /dev/null +++ b/crates/transaction/manifests/src/manifests_security_shield/top_up_access_controller_xrd_vault.rs @@ -0,0 +1,133 @@ +use radix_common::prelude::ManifestGlobalAddress; +use radix_engine_interface::blueprints::access_controller::{ + AccessControllerContributeRecoveryFeeManifestInput, + ACCESS_CONTROLLER_CONTRIBUTE_RECOVERY_FEE_IDENT as SCRYPTO_ACCESS_CONTROLLER_CONTRIBUTE_RECOVERY_FEE_IDENT, + ACCESS_CONTROLLER_CREATE_PROOF_IDENT as SCRYPTO_ACCESS_CONTROLLER_CREATE_PROOF_IDENT, +}; +use radix_transactions::prelude::ManifestBuilder; + +use crate::prelude::*; + +const XRD_TO_AC_VAULT_FIRST_TOP_UP: ScryptoDecimal192 = + ScryptoDecimal192::ONE_HUNDRED; + +pub trait TransactionManifestAccessControllerXrdVaultToppingUp { + /// A method modifying manifests which applies security shield. We + /// The `manifest` which applies the security shield could not include + /// the instructions which we append in this method since the host did + /// not know the `payer` at the time of creating that manifest. The host + /// will call this method when the `payer` is known, which appends instructions + /// 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` + /// (`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. + /// + /// If `top_up_amount` is `None` the `XRD_TO_AC_VAULT_FIRST_TOP_UP` will be used. + /// 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, + manifest: TransactionManifest, + top_up_amount: impl Into>, + ) -> TransactionManifest { + let address_of_paying_account = payer.address(); + let mut builder = ManifestBuilder::with_manifest(manifest); + + let address_of_access_controller_to_top_up = + match entity_applying_shield.security_state() { + EntitySecurityState::Securified { value: sec } => { + ManifestGlobalAddress::Static( + sec.access_controller_address.scrypto(), + ) + } + EntitySecurityState::Unsecured { .. } => { + // We are securifying an unsecurified account => use the + // address reservation at index 0, + // which `apply_security_shield_for_unsecurified_entity` + // is using to create the access controller address + ManifestGlobalAddress::Named(ScryptoManifestNamedAddress(0)) + } + }; + + let address_of_access_controller_of_payer = { + match payer.security_state() { + EntitySecurityState::Securified { value: sec } => { + Some(ManifestGlobalAddress::Static( + sec.access_controller_address.scrypto(), + )) + } + EntitySecurityState::Unsecured { .. } => { + // No access controller to create proof for + None + } + } + }; + + // Add `create_proof` instruction for the access controller + if let Some(address_of_access_controller_of_payer) = + address_of_access_controller_of_payer + { + builder = builder.call_method( + address_of_access_controller_of_payer, + SCRYPTO_ACCESS_CONTROLLER_CREATE_PROOF_IDENT, + (), + ); + } + + let top_up_amount = top_up_amount + .into() + .map(ScryptoDecimal192::from) + .unwrap_or(XRD_TO_AC_VAULT_FIRST_TOP_UP); + + // Add withdraw XRD instruction + builder = builder.withdraw_from_account( + address_of_paying_account.scrypto(), + XRD, + top_up_amount, + ); + + // Deposit XRD into the access controllers XRD vault + // ... by first taking the XRD from the work top + let xrd_to_top_up_ac_vault_bucket_name = + "xrd_to_top_up_ac_vault_bucket"; + builder = builder.take_from_worktop( + XRD, + top_up_amount, + xrd_to_top_up_ac_vault_bucket_name, + ); + let xrd_to_top_up_ac_vault_bucket = + builder.bucket(xrd_to_top_up_ac_vault_bucket_name); + + // ... then deposit to XRD vault of access controller + builder = builder.call_method( + address_of_access_controller_to_top_up, + SCRYPTO_ACCESS_CONTROLLER_CONTRIBUTE_RECOVERY_FEE_IDENT, + AccessControllerContributeRecoveryFeeManifestInput { + bucket: xrd_to_top_up_ac_vault_bucket, + }, + ); + + TransactionManifest::sargon_built( + builder, + address_of_paying_account.network_id(), + ) + } +} + +impl TransactionManifestAccessControllerXrdVaultToppingUp + for TransactionManifest +{ +} diff --git a/crates/transaction/models/Cargo.toml b/crates/transaction/models/Cargo.toml index 9e08ab5d9..2cfc721f0 100644 --- a/crates/transaction/models/Cargo.toml +++ b/crates/transaction/models/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "transaction-models" -version = "1.1.115" +version = "1.1.116" edition = "2021" diff --git a/crates/uniffi/conversion-macros/Cargo.toml b/crates/uniffi/conversion-macros/Cargo.toml index 642bc8372..62529b728 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.115" +version = "1.1.116" edition = "2021" [dependencies] diff --git a/crates/uniffi/uniffi_SPLIT_ME/Cargo.toml b/crates/uniffi/uniffi_SPLIT_ME/Cargo.toml index 08d02e146..e360be891 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.115" +version = "1.1.116" edition = "2021" build = "build.rs" 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 new file mode 100644 index 000000000..bc9eb7e24 --- /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.rs @@ -0,0 +1,7 @@ +use crate::prelude::*; +use sargon::DappToWalletInteractionBatchOfTransactions as InternalDappToWalletInteractionBatchOfTransactions; + +#[derive(Clone, PartialEq, InternalConversion, uniffi::Record)] +pub struct DappToWalletInteractionBatchOfTransactions { + 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 new file mode 100644 index 000000000..ea996a5c3 --- /dev/null +++ b/crates/uniffi/uniffi_SPLIT_ME/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/batch_of_transactions/mod.rs @@ -0,0 +1,4 @@ +#[allow(clippy::module_inception)] +mod batch_of_transactions; + +pub use batch_of_transactions::*; diff --git a/crates/uniffi/uniffi_SPLIT_ME/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/items.rs b/crates/uniffi/uniffi_SPLIT_ME/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/items.rs index 861f53798..96c74671f 100644 --- a/crates/uniffi/uniffi_SPLIT_ME/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/items.rs +++ b/crates/uniffi/uniffi_SPLIT_ME/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/items.rs @@ -4,7 +4,12 @@ use sargon::DappToWalletInteractionItems as InternalDappToWalletInteractionItems #[derive(Clone, PartialEq, InternalConversion, uniffi::Enum)] pub enum DappToWalletInteractionItems { UnauthorizedRequest(DappToWalletInteractionUnauthorizedRequestItems), + AuthorizedRequest(DappToWalletInteractionAuthorizedRequestItems), + Transaction(DappToWalletInteractionTransactionItems), + + BatchOfTransactions(DappToWalletInteractionBatchOfTransactions), + PreAuthorization(DappToWalletInteractionPreAuthorizationItems), } diff --git a/crates/uniffi/uniffi_SPLIT_ME/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/mod.rs b/crates/uniffi/uniffi_SPLIT_ME/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/mod.rs index d48c80fee..f19d3ce9f 100644 --- a/crates/uniffi/uniffi_SPLIT_ME/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/mod.rs +++ b/crates/uniffi/uniffi_SPLIT_ME/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/mod.rs @@ -1,8 +1,10 @@ +mod batch_of_transactions; mod items; mod pre_authorization; mod request; mod transaction; +pub use batch_of_transactions::*; pub use items::*; pub use pre_authorization::*; pub use request::*; diff --git a/crates/uniffi/uniffi_SPLIT_ME/src/system/sargon_os/entities/apply_shield/sargon_os_apply_shield.rs b/crates/uniffi/uniffi_SPLIT_ME/src/system/sargon_os/entities/apply_shield/sargon_os_apply_shield.rs index 05c6eb1f9..413240f9f 100644 --- a/crates/uniffi/uniffi_SPLIT_ME/src/system/sargon_os/entities/apply_shield/sargon_os_apply_shield.rs +++ b/crates/uniffi/uniffi_SPLIT_ME/src/system/sargon_os/entities/apply_shield/sargon_os_apply_shield.rs @@ -18,6 +18,7 @@ impl SargonOS { addresses.into_internal(), ) .await + .map(|_| ()) .into_result() } } diff --git a/fixtures/transaction/create_access_controller_for_account.rtm b/fixtures/transaction/create_access_controller_for_account.rtm index feecabe59..5d5b5a18c 100644 --- a/fixtures/transaction/create_access_controller_for_account.rtm +++ b/fixtures/transaction/create_access_controller_for_account.rtm @@ -7,6 +7,12 @@ TAKE_FROM_WORKTOP Decimal("1") Bucket("bucket1") ; +ALLOCATE_GLOBAL_ADDRESS + Address("package_rdx1pkgxxxxxxxxxcntrlrxxxxxxxxx000648572295xxxxxxxxxcntrlr") + "AccessController" + AddressReservation("reservation1") + NamedAddress("address1") +; CREATE_ACCESS_CONTROLLER Bucket("bucket1") Tuple( @@ -83,7 +89,9 @@ CREATE_ACCESS_CONTROLLER Enum<1u8>( 20160u32 ) - Enum<0u8>() + Enum<1u8>( + AddressReservation("reservation1") + ) ; SET_METADATA Address("account_rdx128dtethfy8ujrsfdztemyjk0kvhnah6dafr57frz85dcw2c8z0td87") diff --git a/fixtures/transaction/create_access_controller_for_account_with_ac_xrd_vault_top_up_by_securified_account_amount_42.rtm b/fixtures/transaction/create_access_controller_for_account_with_ac_xrd_vault_top_up_by_securified_account_amount_42.rtm new file mode 100644 index 000000000..801d308e1 --- /dev/null +++ b/fixtures/transaction/create_access_controller_for_account_with_ac_xrd_vault_top_up_by_securified_account_amount_42.rtm @@ -0,0 +1,126 @@ +CALL_METHOD + Address("account_rdx128dtethfy8ujrsfdztemyjk0kvhnah6dafr57frz85dcw2c8z0td87") + "securify" +; +TAKE_FROM_WORKTOP + Address("resource_rdx1nfxxxxxxxxxxaccwnrxxxxxxxxx006664022062xxxxxxxxxaccwnr") + 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>( + 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 + ) + Enum<1u8>( + AddressReservation("reservation1") + ) +; +SET_METADATA + Address("account_rdx128dtethfy8ujrsfdztemyjk0kvhnah6dafr57frz85dcw2c8z0td87") + "owner_keys" + Enum<143u8>( + Array( + Enum<1u8>( + Bytes("cb3f6086cd08a1d0ab10139a9c6d191783edb534059f7b4716dc5d239e") + ) + ) + ) +; +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_account_with_ac_xrd_vault_top_up_by_unsecurified_account.rtm b/fixtures/transaction/create_access_controller_for_account_with_ac_xrd_vault_top_up_by_unsecurified_account.rtm new file mode 100644 index 000000000..acdfbd778 --- /dev/null +++ b/fixtures/transaction/create_access_controller_for_account_with_ac_xrd_vault_top_up_by_unsecurified_account.rtm @@ -0,0 +1,122 @@ +CALL_METHOD + Address("account_rdx128dtethfy8ujrsfdztemyjk0kvhnah6dafr57frz85dcw2c8z0td87") + "securify" +; +TAKE_FROM_WORKTOP + Address("resource_rdx1nfxxxxxxxxxxaccwnrxxxxxxxxx006664022062xxxxxxxxxaccwnr") + 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>( + 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 + ) + Enum<1u8>( + AddressReservation("reservation1") + ) +; +SET_METADATA + Address("account_rdx128dtethfy8ujrsfdztemyjk0kvhnah6dafr57frz85dcw2c8z0td87") + "owner_keys" + Enum<143u8>( + Array( + Enum<1u8>( + Bytes("cb3f6086cd08a1d0ab10139a9c6d191783edb534059f7b4716dc5d239e") + ) + ) + ) +; +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/create_access_controller_for_persona.rtm b/fixtures/transaction/create_access_controller_for_persona.rtm index c4809655d..65b8b7dc9 100644 --- a/fixtures/transaction/create_access_controller_for_persona.rtm +++ b/fixtures/transaction/create_access_controller_for_persona.rtm @@ -7,6 +7,12 @@ TAKE_FROM_WORKTOP Decimal("1") Bucket("bucket1") ; +ALLOCATE_GLOBAL_ADDRESS + Address("package_rdx1pkgxxxxxxxxxcntrlrxxxxxxxxx000648572295xxxxxxxxxcntrlr") + "AccessController" + AddressReservation("reservation1") + NamedAddress("address1") +; CREATE_ACCESS_CONTROLLER Bucket("bucket1") Tuple( @@ -77,7 +83,9 @@ CREATE_ACCESS_CONTROLLER Enum<1u8>( 20160u32 ) - Enum<0u8>() + Enum<1u8>( + AddressReservation("reservation1") + ) ; SET_METADATA Address("identity_rdx12tw6rt9c4l56rz6p866e35tmzp556nymxmpj8hagfewq82kspctdyw")