diff --git a/crates/sargon/fixtures/vector/wallet_interactions_dapp_to_wallet.json b/crates/sargon/fixtures/vector/wallet_interactions_dapp_to_wallet.json index c2c8d2407..56aeff516 100644 --- a/crates/sargon/fixtures/vector/wallet_interactions_dapp_to_wallet.json +++ b/crates/sargon/fixtures/vector/wallet_interactions_dapp_to_wallet.json @@ -191,5 +191,27 @@ "networkId": 2, "origin": "https://dev-sandbox.rdx-works-main.extratools.works/" } + }, + { + "interactionId": "17d530f6-0cb6-4122-8540-64e46a2e0f84", + "items": { + "discriminator": "preAuthorizationRequest", + "request": { + "version": 1, + "transactionManifest": "CALL_METHOD\n Address(\"account_rdx128y6j78mt0aqv6372evz28hrxp8mn06ccddkr7xppc88hyvynvjdwr\")\n \"lock_fee\"\n Decimal(\"0.61\")\n;\nCALL_METHOD\n Address(\"account_rdx128y6j78mt0aqv6372evz28hrxp8mn06ccddkr7xppc88hyvynvjdwr\")\n \"withdraw\"\n Address(\"resource_rdx1tknxxxxxxxxxradxrdxxxxxxxxx009923554798xxxxxxxxxradxrd\")\n Decimal(\"1337\")\n;\nTAKE_FROM_WORKTOP\n Address(\"resource_rdx1tknxxxxxxxxxradxrdxxxxxxxxx009923554798xxxxxxxxxradxrd\")\n Decimal(\"1337\")\n Bucket(\"bucket1\")\n;\nCALL_METHOD\n Address(\"account_rdx12xkzynhzgtpnnd02tudw2els2g9xl73yk54ppw8xekt2sdrlaer264\")\n \"try_deposit_or_abort\"\n Bucket(\"bucket1\")\n Enum<0u8>()\n;\n", + "blobs": [], + "message": "message", + "expiration": { + "discriminator": "expireAtTime", + "unixTimestampSeconds": "2023-09-11T16:05:56.000Z" + } + } + }, + "metadata": { + "version": 2, + "dAppDefinitionAddress": "account_tdx_2_12xd46c22d6m696lv565t9afn088htudtq275px3qs925ywwty8axze", + "networkId": 2, + "origin": "https://dev-sandbox.rdx-works-main.extratools.works/" + } } ] diff --git a/crates/sargon/fixtures/vector/wallet_interactions_wallet_to_dapp.json b/crates/sargon/fixtures/vector/wallet_interactions_wallet_to_dapp.json index a7a994888..5a0db9fba 100644 --- a/crates/sargon/fixtures/vector/wallet_interactions_wallet_to_dapp.json +++ b/crates/sargon/fixtures/vector/wallet_interactions_wallet_to_dapp.json @@ -159,5 +159,13 @@ ] } } + }, + { + "discriminator": "success", + "interactionId": "17d530f6-0cb6-4122-8540-64e46a2e0f84", + "items": { + "discriminator": "preAuthorizationResponse", + "signedPartialTransaction": "replace_actual_encoded_string_here" + } } ] \ No newline at end of file diff --git a/crates/sargon/src/core/error/common_error.rs b/crates/sargon/src/core/error/common_error.rs index de0ef95d2..487b0b31f 100644 --- a/crates/sargon/src/core/error/common_error.rs +++ b/crates/sargon/src/core/error/common_error.rs @@ -697,8 +697,12 @@ pub enum CommonError { #[error("Invalid SignedPartialTransaction, failed to decompile")] InvalidSignedPartialTransactionFailedToDecompile = 10195, + #[error("Invalid Signed Partial Transaction, failed to encode, reason: '{underlying}'")] + InvalidSignedPartialTransactionFailedToEncode { underlying: String } = + 10196, + #[error("Failed to generate manifest summary")] - FailedToGenerateManifestSummary = 10196, + FailedToGenerateManifestSummary = 10197, } #[uniffi::export] diff --git a/crates/sargon/src/core/types/mod.rs b/crates/sargon/src/core/types/mod.rs index 133ec9d9a..33b17da62 100644 --- a/crates/sargon/src/core/types/mod.rs +++ b/crates/sargon/src/core/types/mod.rs @@ -25,6 +25,7 @@ mod rounding_mode; mod safe_to_log; mod secret_bytes; mod signatures; +mod version_type; pub use appearance_id::*; pub use appearance_id_uniffi_fn::*; @@ -53,3 +54,4 @@ pub use rounding_mode::*; pub use safe_to_log::*; pub use secret_bytes::*; pub use signatures::*; +pub use version_type::*; diff --git a/crates/sargon/src/core/types/version_type.rs b/crates/sargon/src/core/types/version_type.rs new file mode 100644 index 000000000..7bb9570e7 --- /dev/null +++ b/crates/sargon/src/core/types/version_type.rs @@ -0,0 +1,96 @@ +use crate::prelude::*; +use paste::paste; + +/// A macro that generates a XYZVersion type, which is a typed version of `u64`. +macro_rules! decl_version_type { + ($name:ident) => { + paste! { + #[derive(Debug, Clone, Deserialize, Serialize, PartialEq)] + #[serde(transparent)] + pub struct [<$name Version>](u64); + + impl HasSampleValues for [<$name Version>] { + fn sample() -> Self { + Self(1) + } + + fn sample_other() -> Self { + Self(2) + } + } + + impl From for [<$name Version>] { + fn from(value: u64) -> Self { + Self(value) + } + } + + impl Deref for [<$name Version>] { + type Target = u64; + + fn deref(&self) -> &Self::Target { + &self.0 + } + } + + uniffi::custom_newtype!([<$name Version>], u64); + } + }; +} + +pub(crate) use decl_version_type; + +#[cfg(test)] +mod tests { + decl_version_type!(Example); + + use crate::prelude::*; + + #[test] + fn equality() { + assert_eq!(ExampleVersion::sample(), ExampleVersion::sample()); + assert_eq!( + ExampleVersion::sample_other(), + ExampleVersion::sample_other() + ); + } + + #[test] + fn inequality() { + assert_ne!(ExampleVersion::sample(), ExampleVersion::sample_other()); + } + + #[test] + fn modification() { + let mut sut: ExampleVersion = 5.into(); + assert_eq!(*sut, 5); + assert_eq!(sut.0, 5); + + sut.0 = 10; + assert_eq!(*sut, 10); + assert_eq!(sut.0, 10); + } + + #[test] + fn json_transparent() { + #[derive(Deserialize, Serialize, PartialEq, Debug)] + struct Test { + name: String, + version: ExampleVersion, + } + + let sut = Test { + name: "test".to_string(), + version: ExampleVersion(25), + }; + assert_eq_after_json_roundtrip( + &sut, + r#" + { + "name": "test", + "version": 25 + } + "#, + ); + } +} diff --git a/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/items.rs b/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/items.rs index f4cc15749..7be21e4b0 100644 --- a/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/items.rs +++ b/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/items.rs @@ -11,6 +11,9 @@ pub enum DappToWalletInteractionItems { #[serde(rename = "transaction")] Transaction(DappToWalletInteractionTransactionItems), + + #[serde(rename = "preAuthorizationRequest")] + PreAuthorization(DappToWalletInteractionPreAuthorizationItems), } impl HasSampleValues for DappToWalletInteractionItems { diff --git a/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/mod.rs b/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/mod.rs index 5f2ff6ad8..d48c80fee 100644 --- a/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/mod.rs +++ b/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/mod.rs @@ -1,7 +1,9 @@ mod items; +mod pre_authorization; mod request; mod transaction; pub use items::*; +pub use pre_authorization::*; pub use request::*; pub use transaction::*; diff --git a/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/pre_authorization/expiration/after_delay.rs b/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/pre_authorization/expiration/after_delay.rs new file mode 100644 index 000000000..80fb4b864 --- /dev/null +++ b/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/pre_authorization/expiration/after_delay.rs @@ -0,0 +1,56 @@ +use crate::prelude::*; + +/// Suggests that the subintent's expiry timestamp is set to `current_time + expire_after_seconds` +/// at the last moment, right before the intent is fixed for signing. +#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, uniffi::Record)] +#[serde(rename_all = "camelCase")] +pub struct DappToWalletInteractionSubintentExpireAfterDelay { + /// The time (in seconds) after the subintent is signed that it will expire. + pub expire_after_seconds: u64, +} + +impl From for DappToWalletInteractionSubintentExpireAfterDelay { + fn from(expire_after_seconds: u64) -> Self { + Self { + expire_after_seconds, + } + } +} + +impl HasSampleValues for DappToWalletInteractionSubintentExpireAfterDelay { + fn sample() -> Self { + Self { + expire_after_seconds: 10, + } + } + + fn sample_other() -> Self { + Self { + expire_after_seconds: 20, + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[allow(clippy::upper_case_acronyms)] + type SUT = DappToWalletInteractionSubintentExpireAfterDelay; + + #[test] + fn equality() { + assert_eq!(SUT::sample(), SUT::sample()); + assert_eq!(SUT::sample_other(), SUT::sample_other()); + } + + #[test] + fn inequality() { + assert_ne!(SUT::sample(), SUT::sample_other()); + } + + #[test] + fn from() { + assert_eq!(SUT::from(10), SUT::sample()); + } +} diff --git a/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/pre_authorization/expiration/at_time.rs b/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/pre_authorization/expiration/at_time.rs new file mode 100644 index 000000000..3518d1de5 --- /dev/null +++ b/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/pre_authorization/expiration/at_time.rs @@ -0,0 +1,55 @@ +use crate::prelude::*; + +/// The subintent expires at a specific fixed timestamp +#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, uniffi::Record)] +#[serde(rename_all = "camelCase")] +pub struct DappToWalletInteractionSubintentExpireAtTime { + /// The unix timestamp in seconds when the subintent expires. + pub unix_timestamp_seconds: Timestamp, +} + +impl From for DappToWalletInteractionSubintentExpireAtTime { + fn from(unix_timestamp_seconds: Timestamp) -> Self { + Self { + unix_timestamp_seconds, + } + } +} + +impl HasSampleValues for DappToWalletInteractionSubintentExpireAtTime { + fn sample() -> Self { + Self { + unix_timestamp_seconds: Timestamp::sample(), + } + } + + fn sample_other() -> Self { + Self { + unix_timestamp_seconds: Timestamp::sample_other(), + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[allow(clippy::upper_case_acronyms)] + type SUT = DappToWalletInteractionSubintentExpireAtTime; + + #[test] + fn equality() { + assert_eq!(SUT::sample(), SUT::sample()); + assert_eq!(SUT::sample_other(), SUT::sample_other()); + } + + #[test] + fn inequality() { + assert_ne!(SUT::sample(), SUT::sample_other()); + } + + #[test] + fn from() { + assert_eq!(SUT::from(Timestamp::sample()), SUT::sample()); + } +} diff --git a/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/pre_authorization/expiration/expiration.rs b/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/pre_authorization/expiration/expiration.rs new file mode 100644 index 000000000..d702cb043 --- /dev/null +++ b/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/pre_authorization/expiration/expiration.rs @@ -0,0 +1,80 @@ +use crate::prelude::*; + +/// An enum that represents the different ways a subintent can expire. +#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, uniffi::Enum)] +#[serde(tag = "discriminator", rename_all = "camelCase")] +pub enum DappToWalletInteractionSubintentExpiration { + /// The subintent expires at a specific fixed timestamp. + /// + /// For example, a dApp sends a subintent for `User A` to approve sending 100 XRD before 5:00 PM, + /// and a subintent for `User B` to approve sending 2 USDT with same expiration. + /// + /// If both users sign their subintents before 5:00 PM, the transaction to exchange + /// 100 XRD over 2 USDT will succeed. Otherwise, it would fail. + #[serde(rename = "expireAtTime")] + AtTime(DappToWalletInteractionSubintentExpireAtTime), + + /// The subintent expires X seconds after its signature. + /// + /// For example, a dApp sends a subintent for `User A` to approve sending 100 XRD with 1 hour expiration, + /// and a subintent for `User B` to approve sending 2 USDT with same expiration. + /// + /// If both users sign their subintents within one hour from each other, the transaction to exchange + /// 100 XRD over 2 USDT will succeed. Otherwise, it would fail. + #[serde(rename = "expireAfterDelay")] + AfterDelay(DappToWalletInteractionSubintentExpireAfterDelay), +} + +impl HasSampleValues for DappToWalletInteractionSubintentExpiration { + fn sample() -> Self { + Self::AtTime(DappToWalletInteractionSubintentExpireAtTime::sample()) + } + + fn sample_other() -> Self { + Self::AfterDelay( + DappToWalletInteractionSubintentExpireAfterDelay::sample(), + ) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[allow(clippy::upper_case_acronyms)] + type SUT = DappToWalletInteractionSubintentExpiration; + + #[test] + fn equality() { + assert_eq!(SUT::sample(), SUT::sample()); + assert_eq!(SUT::sample_other(), SUT::sample_other()); + } + + #[test] + fn inequality() { + assert_ne!(SUT::sample(), SUT::sample_other()); + } + + #[test] + fn json_roundtrip() { + assert_eq_after_json_roundtrip( + &SUT::sample(), + r#" + { + "discriminator": "expireAtTime", + "unixTimestampSeconds": "2023-09-11T16:05:56.000Z" + } + "#, + ); + + assert_eq_after_json_roundtrip( + &SUT::sample_other(), + r#" + { + "discriminator": "expireAfterDelay", + "expireAfterSeconds": 10 + } + "#, + ); + } +} diff --git a/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/pre_authorization/expiration/mod.rs b/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/pre_authorization/expiration/mod.rs new file mode 100644 index 000000000..8ba8d42f7 --- /dev/null +++ b/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/pre_authorization/expiration/mod.rs @@ -0,0 +1,7 @@ +mod after_delay; +mod at_time; +mod expiration; + +pub use after_delay::*; +pub use at_time::*; +pub use expiration::*; diff --git a/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/pre_authorization/mod.rs b/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/pre_authorization/mod.rs new file mode 100644 index 000000000..d74a7467c --- /dev/null +++ b/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/pre_authorization/mod.rs @@ -0,0 +1,7 @@ +mod expiration; +mod pre_authorization; +mod subintent; + +pub use expiration::*; +pub use pre_authorization::*; +pub use subintent::*; diff --git a/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/pre_authorization/pre_authorization.rs b/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/pre_authorization/pre_authorization.rs new file mode 100644 index 000000000..439118617 --- /dev/null +++ b/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/pre_authorization/pre_authorization.rs @@ -0,0 +1,40 @@ +use crate::prelude::*; + +#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, uniffi::Record)] +pub struct DappToWalletInteractionPreAuthorizationItems { + pub request: DappToWalletInteractionSubintentRequestItem, +} + +impl DappToWalletInteractionPreAuthorizationItems { + pub fn new(request: DappToWalletInteractionSubintentRequestItem) -> Self { + Self { request } + } +} + +impl HasSampleValues for DappToWalletInteractionPreAuthorizationItems { + fn sample() -> Self { + Self::new(DappToWalletInteractionSubintentRequestItem::sample()) + } + + fn sample_other() -> Self { + Self::new(DappToWalletInteractionSubintentRequestItem::sample_other()) + } +} +#[cfg(test)] +mod tests { + use super::*; + + #[allow(clippy::upper_case_acronyms)] + type SUT = DappToWalletInteractionPreAuthorizationItems; + + #[test] + fn equality() { + assert_eq!(SUT::sample(), SUT::sample()); + assert_eq!(SUT::sample_other(), SUT::sample_other()); + } + + #[test] + fn inequality() { + assert_ne!(SUT::sample(), SUT::sample_other()); + } +} diff --git a/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/pre_authorization/subintent.rs b/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/pre_authorization/subintent.rs new file mode 100644 index 000000000..147de607b --- /dev/null +++ b/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/pre_authorization/subintent.rs @@ -0,0 +1,92 @@ +use crate::prelude::*; + +decl_version_type!(Subintent); + +#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, uniffi::Record)] +#[serde(rename_all = "camelCase")] +pub struct DappToWalletInteractionSubintentRequestItem { + pub version: SubintentVersion, + + #[serde(flatten, with = "UnvalidatedTransactionManifest")] + pub unvalidated_manifest: UnvalidatedTransactionManifest, + + #[serde(skip_serializing_if = "Option::is_none")] + pub message: Option, + + #[serde(skip_serializing_if = "Option::is_none")] + pub expiration: Option, +} + +impl DappToWalletInteractionSubintentRequestItem { + pub fn new( + version: impl Into, + unvalidated_manifest: impl Into, + message: impl Into>, + expiration: impl Into>, + ) -> Self { + Self { + version: version.into(), + unvalidated_manifest: unvalidated_manifest.into(), + message: message.into(), + expiration: expiration.into(), + } + } +} + +impl HasSampleValues for DappToWalletInteractionSubintentRequestItem { + fn sample() -> Self { + Self::new( + SubintentVersion::sample(), + UnvalidatedTransactionManifest::sample(), + "message".to_owned(), + DappToWalletInteractionSubintentExpiration::sample(), + ) + } + + fn sample_other() -> Self { + Self::new( + SubintentVersion::sample_other(), + UnvalidatedTransactionManifest::sample_other(), + "message_other".to_owned(), + DappToWalletInteractionSubintentExpiration::sample_other(), + ) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[allow(clippy::upper_case_acronyms)] + type SUT = DappToWalletInteractionSubintentRequestItem; + + #[test] + fn equality() { + assert_eq!(SUT::sample(), SUT::sample()); + assert_eq!(SUT::sample_other(), SUT::sample_other()); + } + + #[test] + fn inequality() { + assert_ne!(SUT::sample(), SUT::sample_other()); + } + + #[test] + fn json_roundtrip() { + assert_eq_after_json_roundtrip( + &SUT::sample(), + r#" + { + "version" : 1, + "transactionManifest" : "CALL_METHOD\n Address(\"account_rdx128y6j78mt0aqv6372evz28hrxp8mn06ccddkr7xppc88hyvynvjdwr\")\n \"lock_fee\"\n Decimal(\"0.61\")\n;\nCALL_METHOD\n Address(\"account_rdx128y6j78mt0aqv6372evz28hrxp8mn06ccddkr7xppc88hyvynvjdwr\")\n \"withdraw\"\n Address(\"resource_rdx1tknxxxxxxxxxradxrdxxxxxxxxx009923554798xxxxxxxxxradxrd\")\n Decimal(\"1337\")\n;\nTAKE_FROM_WORKTOP\n Address(\"resource_rdx1tknxxxxxxxxxradxrdxxxxxxxxx009923554798xxxxxxxxxradxrd\")\n Decimal(\"1337\")\n Bucket(\"bucket1\")\n;\nCALL_METHOD\n Address(\"account_rdx12xkzynhzgtpnnd02tudw2els2g9xl73yk54ppw8xekt2sdrlaer264\")\n \"try_deposit_or_abort\"\n Bucket(\"bucket1\")\n Enum<0u8>()\n;\n", + "blobs" : [], + "message" : "message", + "expiration": { + "discriminator": "expireAtTime", + "unixTimestampSeconds": "2023-09-11T16:05:56.000Z" + } + } + "#, + ); + } +} diff --git a/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/transaction/mod.rs b/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/transaction/mod.rs index b158ad959..37cec1e43 100644 --- a/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/transaction/mod.rs +++ b/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/transaction/mod.rs @@ -1,9 +1,7 @@ mod transaction; -mod transaction_version; mod unvalidated_transaction_manifest; mod unvalidated_transaction_manifest_uniffi_fn; pub use transaction::*; -pub use transaction_version::*; pub use unvalidated_transaction_manifest::*; pub use unvalidated_transaction_manifest_uniffi_fn::*; diff --git a/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/transaction/transaction.rs b/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/transaction/transaction.rs index 5fa8d37d9..ab866b1b8 100644 --- a/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/transaction/transaction.rs +++ b/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/transaction/transaction.rs @@ -11,6 +11,8 @@ impl DappToWalletInteractionTransactionItems { } } +decl_version_type!(TX); + #[derive(Debug, Clone, Deserialize, Serialize, PartialEq, uniffi::Record)] #[serde(rename_all = "camelCase")] pub struct DappToWalletInteractionSendTransactionItem { diff --git a/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/transaction/transaction_version.rs b/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/transaction/transaction_version.rs deleted file mode 100644 index 4c4bab907..000000000 --- a/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/dapp_to_wallet/interaction_items/transaction/transaction_version.rs +++ /dev/null @@ -1,21 +0,0 @@ -use crate::prelude::*; - -uniffi::custom_newtype!(TXVersion, u64); -#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)] -pub struct TXVersion(u64); - -impl From for TXVersion { - fn from(value: u64) -> Self { - Self(value) - } -} - -impl HasSampleValues for TXVersion { - fn sample() -> Self { - Self(1) - } - - fn sample_other() -> Self { - Self(2) - } -} diff --git a/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/wallet_to_dapp/success_response/items.rs b/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/wallet_to_dapp/success_response/items.rs index 3e097c63c..8d59809f1 100644 --- a/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/wallet_to_dapp/success_response/items.rs +++ b/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/wallet_to_dapp/success_response/items.rs @@ -14,6 +14,9 @@ pub enum WalletToDappInteractionResponseItems { #[serde(rename = "transaction")] Transaction(WalletToDappInteractionTransactionResponseItems), + + #[serde(rename = "preAuthorizationResponse")] + PreAuthorization(WalletToDappInteractionPreAuthorizationResponseItems), } impl HasSampleValues for WalletToDappInteractionResponseItems { diff --git a/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/wallet_to_dapp/success_response/mod.rs b/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/wallet_to_dapp/success_response/mod.rs index 698f2d468..3a8f5bbf9 100644 --- a/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/wallet_to_dapp/success_response/mod.rs +++ b/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/wallet_to_dapp/success_response/mod.rs @@ -4,6 +4,7 @@ mod authorized_request; mod items; mod persona; mod persona_data; +mod pre_authorization; mod proof_of_ownership; mod success; mod transaction; @@ -15,6 +16,7 @@ pub use authorized_request::*; pub use items::*; pub use persona::*; pub use persona_data::*; +pub use pre_authorization::*; pub use proof_of_ownership::*; pub use success::*; pub use transaction::*; diff --git a/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/wallet_to_dapp/success_response/pre_authorization/mod.rs b/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/wallet_to_dapp/success_response/pre_authorization/mod.rs new file mode 100644 index 000000000..fc42fbd25 --- /dev/null +++ b/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/wallet_to_dapp/success_response/pre_authorization/mod.rs @@ -0,0 +1,3 @@ +mod pre_authorization; + +pub use pre_authorization::*; diff --git a/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/wallet_to_dapp/success_response/pre_authorization/pre_authorization.rs b/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/wallet_to_dapp/success_response/pre_authorization/pre_authorization.rs new file mode 100644 index 000000000..08ebeb2b3 --- /dev/null +++ b/crates/sargon/src/radix_connect/wallet_interaction/dapp_wallet_interaction/wallet_to_dapp/success_response/pre_authorization/pre_authorization.rs @@ -0,0 +1,70 @@ +use crate::prelude::*; +use radix_transactions::model::TransactionPayload; + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, uniffi::Record)] +pub struct WalletToDappInteractionPreAuthorizationResponseItems { + /// A hex encoded signed partial transaction. + #[serde(rename = "signedPartialTransaction")] + pub encoded_signed_partial_transaction: String, +} + +impl WalletToDappInteractionPreAuthorizationResponseItems { + pub fn new( + signed_partial_transaction: ScryptoSignedPartialTransaction, + ) -> Result { + let bytes = signed_partial_transaction + .to_raw() + .map_err(|e| match e { + sbor::EncodeError::MaxDepthExceeded(max) => { + CommonError::InvalidTransactionMaxSBORDepthExceeded { + max: max as u16, + } + } + _ => { + CommonError::InvalidSignedPartialTransactionFailedToEncode { + underlying: format!("{:?}", e), + } + } + })? + .to_vec(); + let encoded_signed_partial_transaction = hex_encode(&bytes); + Ok(Self { + encoded_signed_partial_transaction, + }) + } +} + +impl HasSampleValues for WalletToDappInteractionPreAuthorizationResponseItems { + fn sample() -> Self { + Self { + encoded_signed_partial_transaction: + "replace_actual_encoded_string_here".to_owned(), + } + } + + fn sample_other() -> Self { + Self { + encoded_signed_partial_transaction: + "replace_other_encoded_string_here".to_owned(), + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[allow(clippy::upper_case_acronyms)] + type SUT = WalletToDappInteractionPreAuthorizationResponseItems; + + #[test] + fn equality() { + assert_eq!(SUT::sample(), SUT::sample()); + assert_eq!(SUT::sample_other(), SUT::sample_other()); + } + + #[test] + fn inequality() { + assert_ne!(SUT::sample(), SUT::sample_other()); + } +} diff --git a/crates/sargon/src/signing/petition_types/petition_for_factors_types/petition_for_factors/petition_for_factors_state.rs b/crates/sargon/src/signing/petition_types/petition_for_factors_types/petition_for_factors/petition_for_factors_state.rs index 13aee7cce..ee43bec93 100644 --- a/crates/sargon/src/signing/petition_types/petition_for_factors_types/petition_for_factors/petition_for_factors_state.rs +++ b/crates/sargon/src/signing/petition_types/petition_for_factors_types/petition_for_factors/petition_for_factors_state.rs @@ -103,6 +103,7 @@ impl PetitionForFactorsState { #[cfg(test)] mod tests { use super::*; + use crate::DependencyInformation::Tag; type Sut = PetitionForFactorsState;