Skip to main content

dash_sdk/platform/tokens/transitions/
transfer.rs

1//! Token transfer operations for the Dash Platform SDK.
2//!
3//! This module provides functionality to transfer tokens between identities
4//! on the Dash Platform.
5
6use crate::platform::tokens::builders::transfer::TokenTransferTransitionBuilder;
7use crate::platform::transition::broadcast::BroadcastStateTransition;
8use crate::{Error, Sdk};
9use dpp::balances::credits::TokenAmount;
10use dpp::data_contract::group::GroupSumPower;
11use dpp::document::Document;
12use dpp::identity::signer::Signer;
13use dpp::identity::IdentityPublicKey;
14use dpp::platform_value::Identifier;
15use dpp::state_transition::proof_result::StateTransitionProofResult;
16use std::collections::BTreeMap;
17
18/// Result types returned from token transfer operations.
19///
20/// This enum represents the different possible outcomes when transferring tokens,
21/// depending on the token configuration and whether it's a group action.
22pub enum TransferResult {
23    /// Standard transfer result containing updated balances for affected identities.
24    IdentitiesBalances(BTreeMap<Identifier, TokenAmount>),
25    /// Transfer result with historical tracking via document storage.
26    HistoricalDocument(Document),
27    /// Group-based transfer action with optional document for history.
28    GroupActionWithDocument(GroupSumPower, Option<Document>),
29}
30
31impl Sdk {
32    /// Transfers tokens from one identity to another.
33    ///
34    /// This method broadcasts a transfer transition to move tokens between identities.
35    /// The result varies based on token configuration:
36    /// - Standard tokens return updated balances for the affected identities
37    /// - Tokens with history tracking return documents
38    /// - Group-managed tokens include group power information
39    ///
40    /// # Arguments
41    ///
42    /// * `transfer_tokens_transition_builder` - Builder containing transfer parameters including recipient and amount
43    /// * `signing_key` - The identity public key for signing the transition
44    /// * `signer` - Implementation of the Signer trait for cryptographic signing
45    ///
46    /// # Returns
47    ///
48    /// Returns a `Result` containing a `TransferResult` on success, or an `Error` on failure.
49    ///
50    /// # Errors
51    ///
52    /// This function will return an error if:
53    /// - The transition signing fails
54    /// - Broadcasting the transition fails
55    /// - The proof verification returns an unexpected result type
56    pub async fn token_transfer<S: Signer<IdentityPublicKey>>(
57        &self,
58        transfer_tokens_transition_builder: TokenTransferTransitionBuilder,
59        signing_key: &IdentityPublicKey,
60        signer: &S,
61    ) -> Result<TransferResult, Error> {
62        let platform_version = self.version();
63
64        let put_settings = transfer_tokens_transition_builder.settings;
65
66        let state_transition = transfer_tokens_transition_builder
67            .sign(self, signing_key, signer, platform_version)
68            .await?;
69
70        let proof_result = state_transition
71            // Whether this operation's proof binds execution depends on the token's
72            // keeps-history configuration (and group usage), which the SDK cannot
73            // know statically: accept the affected-state tag and treat no-history
74            // results as height-pinned snapshots, not execution evidence.
75            .broadcast_and_wait_for_affected_state::<StateTransitionProofResult>(self, put_settings)
76            .await?;
77
78        match proof_result {
79            StateTransitionProofResult::VerifiedTokenIdentitiesBalances(balances) => {
80                Ok(TransferResult::IdentitiesBalances(balances))
81            }
82            StateTransitionProofResult::VerifiedTokenActionWithDocument(doc) => {
83                Ok(TransferResult::HistoricalDocument(doc))
84            }
85            StateTransitionProofResult::VerifiedTokenGroupActionWithDocument(power, doc) => {
86                Ok(TransferResult::GroupActionWithDocument(power, doc))
87            }
88            _ => Err(Error::DriveProofError(
89                drive::error::proof::ProofError::UnexpectedResultProof(
90                    "Expected VerifiedTokenIdentitiesBalances, VerifiedTokenActionWithDocument, or VerifiedTokenGroupActionWithDocument for transfer transition".to_string(),
91                ),
92                vec![],
93                Default::default(),
94            )),
95        }
96    }
97}