From 3bb6712d94310479269808af125dbc2d60f01dd6 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 29 Oct 2024 18:01:23 +0700 Subject: [PATCH 1/2] added transfer to sdk --- .../methods/mod.rs | 54 ++++++++++++- .../methods/v0/mod.rs | 24 ++++++ .../v0/v0_methods.rs | 79 ++++++++++++++++++- .../mod.rs | 1 + .../v1.rs | 1 + .../v2.rs | 1 + packages/rs-sdk/src/platform/transition.rs | 1 + .../src/platform/transition/transfer.rs | 67 ++++++++++++++++ 8 files changed, 225 insertions(+), 3 deletions(-) create mode 100644 packages/rs-sdk/src/platform/transition/transfer.rs diff --git a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/methods/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/methods/mod.rs index 2bea2328d79..43790f371db 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/methods/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/methods/mod.rs @@ -1,7 +1,57 @@ mod v0; - pub use v0::*; use crate::state_transition::identity_credit_transfer_transition::IdentityCreditTransferTransition; +#[cfg(feature = "state-transition-signing")] +use crate::{ + identity::{signer::Signer, Identity, IdentityPublicKey}, + prelude::{IdentityNonce, UserFeeIncrease}, + state_transition::{ + identity_credit_transfer_transition::v0::IdentityCreditTransferTransitionV0, + StateTransition, + }, + ProtocolError, +}; +#[cfg(feature = "state-transition-signing")] +use platform_value::Identifier; +#[cfg(feature = "state-transition-signing")] +use platform_version::version::{FeatureVersion, PlatformVersion}; -impl IdentityCreditTransferTransitionMethodsV0 for IdentityCreditTransferTransition {} +impl IdentityCreditTransferTransitionMethodsV0 for IdentityCreditTransferTransition { + #[cfg(feature = "state-transition-signing")] + fn try_from_identity( + identity: &Identity, + to_identity_with_identifier: Identifier, + amount: u64, + user_fee_increase: UserFeeIncrease, + signer: S, + signing_withdrawal_key_to_use: Option<&IdentityPublicKey>, + nonce: IdentityNonce, + platform_version: &PlatformVersion, + version: Option, + ) -> Result { + match version.unwrap_or( + platform_version + .dpp + .state_transition_conversion_versions + .identity_to_identity_transfer_transition, + ) { + 0 => Ok(IdentityCreditTransferTransitionV0::try_from_identity( + identity, + to_identity_with_identifier, + amount, + user_fee_increase, + signer, + signing_withdrawal_key_to_use, + nonce, + platform_version, + version, + )?), + version => Err(ProtocolError::UnknownVersionMismatch { + method: "IdentityCreditTransferTransition::try_from_identity".to_string(), + known_versions: vec![0], + received: version, + }), + } + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/methods/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/methods/v0/mod.rs index caa6ad6560e..eeb7104420b 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/methods/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/methods/v0/mod.rs @@ -1,6 +1,30 @@ +#[cfg(feature = "state-transition-signing")] +use crate::{ + identity::{signer::Signer, Identity, IdentityPublicKey}, + prelude::{IdentityNonce, UserFeeIncrease}, + state_transition::StateTransition, + ProtocolError, +}; +use platform_value::Identifier; +#[cfg(feature = "state-transition-signing")] +use platform_version::version::{FeatureVersion, PlatformVersion}; + use crate::state_transition::StateTransitionType; pub trait IdentityCreditTransferTransitionMethodsV0 { + #[cfg(feature = "state-transition-signing")] + fn try_from_identity( + identity: &Identity, + to_identity_with_identifier: Identifier, + amount: u64, + user_fee_increase: UserFeeIncrease, + signer: S, + signing_withdrawal_key_to_use: Option<&IdentityPublicKey>, + nonce: IdentityNonce, + platform_version: &PlatformVersion, + version: Option, + ) -> Result; + /// Get State Transition Type fn get_type() -> StateTransitionType { StateTransitionType::IdentityCreditTransfer diff --git a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/v0/v0_methods.rs index 0060a25a2ce..965e29613da 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/v0/v0_methods.rs @@ -1,4 +1,81 @@ +#[cfg(feature = "state-transition-signing")] +use crate::{ + identity::{ + accessors::IdentityGettersV0, signer::Signer, Identity, IdentityPublicKey, KeyType, + Purpose, SecurityLevel, + }, + prelude::{IdentityNonce, UserFeeIncrease}, + state_transition::StateTransition, + ProtocolError, +}; +use platform_value::Identifier; + use crate::state_transition::identity_credit_transfer_transition::methods::IdentityCreditTransferTransitionMethodsV0; use crate::state_transition::identity_credit_transfer_transition::v0::IdentityCreditTransferTransitionV0; +use crate::state_transition::GetDataContractSecurityLevelRequirementFn; +#[cfg(feature = "state-transition-signing")] +use platform_version::version::{FeatureVersion, PlatformVersion}; + +impl IdentityCreditTransferTransitionMethodsV0 for IdentityCreditTransferTransitionV0 { + #[cfg(feature = "state-transition-signing")] + fn try_from_identity( + identity: &Identity, + to_identity_with_identifier: Identifier, + amount: u64, + user_fee_increase: UserFeeIncrease, + signer: S, + signing_withdrawal_key_to_use: Option<&IdentityPublicKey>, + nonce: IdentityNonce, + _platform_version: &PlatformVersion, + _version: Option, + ) -> Result { + let mut transition: StateTransition = IdentityCreditTransferTransitionV0 { + identity_id: identity.id(), + recipient_id: to_identity_with_identifier, + amount, + nonce, + user_fee_increase, + signature_public_key_id: 0, + signature: Default::default(), + } + .into(); + + let identity_public_key = match signing_withdrawal_key_to_use { + Some(key) => { + if signer.can_sign_with(key) { + key + } else { + return Err( + ProtocolError::DesiredKeyWithTypePurposeSecurityLevelMissing( + "specified withdrawal public key cannot be used for signing" + .to_string(), + ), + ); + } + } + None => { + let key = identity + .get_first_public_key_matching( + Purpose::TRANSFER, + SecurityLevel::full_range().into(), + KeyType::all_key_types().into(), + true, + ) + .ok_or_else(|| { + ProtocolError::DesiredKeyWithTypePurposeSecurityLevelMissing( + "no transfer public key".to_string(), + ) + })?; + key + } + }; + + transition.sign_external( + identity_public_key, + &signer, + None::, + )?; -impl IdentityCreditTransferTransitionMethodsV0 for IdentityCreditTransferTransitionV0 {} + Ok(transition) + } +} diff --git a/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_conversion_versions/mod.rs b/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_conversion_versions/mod.rs index 4c2e0a22a3e..74d2b396618 100644 --- a/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_conversion_versions/mod.rs +++ b/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_conversion_versions/mod.rs @@ -7,6 +7,7 @@ pub mod v2; pub struct DPPStateTransitionConversionVersions { pub identity_to_identity_create_transition: FeatureVersion, pub identity_to_identity_top_up_transition: FeatureVersion, + pub identity_to_identity_transfer_transition: FeatureVersion, pub identity_to_identity_withdrawal_transition: FeatureVersion, pub identity_to_identity_create_transition_with_signer: FeatureVersion, } diff --git a/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_conversion_versions/v1.rs b/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_conversion_versions/v1.rs index d4653742503..a6ce0943468 100644 --- a/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_conversion_versions/v1.rs +++ b/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_conversion_versions/v1.rs @@ -4,6 +4,7 @@ pub const STATE_TRANSITION_CONVERSION_VERSIONS_V1: DPPStateTransitionConversionV DPPStateTransitionConversionVersions { identity_to_identity_create_transition: 0, identity_to_identity_top_up_transition: 0, + identity_to_identity_transfer_transition: 0, identity_to_identity_withdrawal_transition: 0, identity_to_identity_create_transition_with_signer: 0, }; diff --git a/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_conversion_versions/v2.rs b/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_conversion_versions/v2.rs index 17fd17bd949..fb38e3ebd75 100644 --- a/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_conversion_versions/v2.rs +++ b/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_conversion_versions/v2.rs @@ -4,6 +4,7 @@ pub const STATE_TRANSITION_CONVERSION_VERSIONS_V2: DPPStateTransitionConversionV DPPStateTransitionConversionVersions { identity_to_identity_create_transition: 0, identity_to_identity_top_up_transition: 0, + identity_to_identity_transfer_transition: 0, identity_to_identity_withdrawal_transition: 1, identity_to_identity_create_transition_with_signer: 0, }; diff --git a/packages/rs-sdk/src/platform/transition.rs b/packages/rs-sdk/src/platform/transition.rs index 490bc40090d..7c987785a3c 100644 --- a/packages/rs-sdk/src/platform/transition.rs +++ b/packages/rs-sdk/src/platform/transition.rs @@ -9,6 +9,7 @@ pub mod put_document; pub mod put_identity; pub mod put_settings; pub mod top_up_identity; +mod transfer; pub mod transfer_document; mod txid; pub mod update_price_of_document; diff --git a/packages/rs-sdk/src/platform/transition/transfer.rs b/packages/rs-sdk/src/platform/transition/transfer.rs new file mode 100644 index 00000000000..c0aafd00d56 --- /dev/null +++ b/packages/rs-sdk/src/platform/transition/transfer.rs @@ -0,0 +1,67 @@ +use dpp::identifier::Identifier; +use dpp::identity::accessors::IdentityGettersV0; + +use crate::platform::transition::broadcast::BroadcastStateTransition; +use crate::platform::transition::put_settings::PutSettings; +use crate::{Error, Sdk}; +use dpp::identity::signer::Signer; +use dpp::identity::{Identity, IdentityPublicKey}; +use dpp::state_transition::identity_credit_transfer_transition::methods::IdentityCreditTransferTransitionMethodsV0; +use dpp::state_transition::identity_credit_transfer_transition::IdentityCreditTransferTransition; +use dpp::state_transition::proof_result::StateTransitionProofResult; + +#[async_trait::async_trait] +pub trait TransferToIdentity { + /// Function to transfer credits from an identity to another identity. Returns the final + /// identity balance. + /// + /// If signing_withdrawal_key_to_use is not set, we will try to use one in the signer that is + /// available for the transfer + async fn transfer_credits( + &self, + sdk: &Sdk, + to_identity_id: Identifier, + amount: u64, + signing_transfer_key_to_use: Option<&IdentityPublicKey>, + signer: S, + settings: Option, + ) -> Result; +} + +#[async_trait::async_trait] +impl TransferToIdentity for Identity { + async fn transfer_credits( + &self, + sdk: &Sdk, + to_identity_id: Identifier, + amount: u64, + signing_transfer_key_to_use: Option<&IdentityPublicKey>, + signer: S, + settings: Option, + ) -> Result { + let new_identity_nonce = sdk.get_identity_nonce(self.id(), true, settings).await?; + let user_fee_increase = settings.and_then(|settings| settings.user_fee_increase); + let state_transition = IdentityCreditTransferTransition::try_from_identity( + self, + to_identity_id, + amount, + user_fee_increase.unwrap_or_default(), + signer, + signing_transfer_key_to_use, + new_identity_nonce, + sdk.version(), + None, + )?; + + let result = state_transition.broadcast_and_wait(sdk, None).await?; + + match result { + StateTransitionProofResult::VerifiedPartialIdentity(identity) => { + identity.balance.ok_or(Error::DapiClientError( + "expected an identity balance after transfer".to_string(), + )) + } + _ => Err(Error::DapiClientError("proved a non identity".to_string())), + } + } +} From 656e39c748713d0826d581cdeb14fd9b22815815 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 29 Oct 2024 18:21:21 +0700 Subject: [PATCH 2/2] small suggestion fixes --- .../identity_credit_transfer_transition/v0/v0_methods.rs | 3 +-- packages/rs-sdk/src/platform/transition.rs | 2 +- packages/rs-sdk/src/platform/transition/transfer.rs | 4 ++-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/v0/v0_methods.rs index 965e29613da..e04e061f677 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/v0/v0_methods.rs @@ -47,8 +47,7 @@ impl IdentityCreditTransferTransitionMethodsV0 for IdentityCreditTransferTransit } else { return Err( ProtocolError::DesiredKeyWithTypePurposeSecurityLevelMissing( - "specified withdrawal public key cannot be used for signing" - .to_string(), + "specified transfer public key cannot be used for signing".to_string(), ), ); } diff --git a/packages/rs-sdk/src/platform/transition.rs b/packages/rs-sdk/src/platform/transition.rs index 7c987785a3c..6bd51a3b2e3 100644 --- a/packages/rs-sdk/src/platform/transition.rs +++ b/packages/rs-sdk/src/platform/transition.rs @@ -9,7 +9,7 @@ pub mod put_document; pub mod put_identity; pub mod put_settings; pub mod top_up_identity; -mod transfer; +pub mod transfer; pub mod transfer_document; mod txid; pub mod update_price_of_document; diff --git a/packages/rs-sdk/src/platform/transition/transfer.rs b/packages/rs-sdk/src/platform/transition/transfer.rs index c0aafd00d56..bf330a1024d 100644 --- a/packages/rs-sdk/src/platform/transition/transfer.rs +++ b/packages/rs-sdk/src/platform/transition/transfer.rs @@ -15,8 +15,8 @@ pub trait TransferToIdentity { /// Function to transfer credits from an identity to another identity. Returns the final /// identity balance. /// - /// If signing_withdrawal_key_to_use is not set, we will try to use one in the signer that is - /// available for the transfer + /// If signing_transfer_key_to_use is not set, we will try to use one in the signer that is + /// available for the transfer. async fn transfer_credits( &self, sdk: &Sdk,