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 .broadcast_and_wait::<StateTransitionProofResult>(self, put_settings)
74 .await?;
75
76 match proof_result {
77 StateTransitionProofResult::VerifiedTokenBalance(owner_id, balance) => {
78 Ok(DirectPurchaseResult::TokenBalance(owner_id, balance))
79 }
80 StateTransitionProofResult::VerifiedTokenActionWithDocument(doc) => {
81 Ok(DirectPurchaseResult::HistoricalDocument(doc))
82 }
83 StateTransitionProofResult::VerifiedTokenGroupActionWithDocument(power, doc) => {
84 Ok(DirectPurchaseResult::GroupActionWithDocument(power, doc))
85 }
86 _ => Err(Error::DriveProofError(
87 drive::error::proof::ProofError::UnexpectedResultProof(
88 "Expected VerifiedTokenBalance, VerifiedTokenActionWithDocument, or VerifiedTokenGroupActionWithDocument for direct purchase transition".to_string(),
89 ),
90 vec![],
91 Default::default(),
92 )),
93 }
94 }
95}