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