dash_sdk/platform/transition/
purchase_document.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
use super::broadcast::BroadcastStateTransition;
use super::waitable::Waitable;
use crate::platform::transition::put_settings::PutSettings;
use crate::{Error, Sdk};
use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters;
use dpp::data_contract::document_type::DocumentType;
use dpp::document::Document;
use dpp::fee::Credits;
use dpp::identity::signer::Signer;
use dpp::identity::IdentityPublicKey;
use dpp::prelude::Identifier;
use dpp::state_transition::documents_batch_transition::methods::v0::DocumentsBatchTransitionMethodsV0;
use dpp::state_transition::documents_batch_transition::DocumentsBatchTransition;
use dpp::state_transition::StateTransition;

#[async_trait::async_trait]
/// A trait for purchasing a document on Platform
pub trait PurchaseDocument<S: Signer>: Waitable {
    /// Tries to purchase a document on platform
    /// Setting settings to `None` sets default connection behavior
    async fn purchase_document(
        &self,
        price: Credits,
        sdk: &Sdk,
        document_type: DocumentType,
        purchaser_id: Identifier,
        identity_public_key: IdentityPublicKey,
        signer: &S,
        settings: Option<PutSettings>,
    ) -> Result<StateTransition, Error>;

    /// Tries to purchase a document on platform and waits for the response
    async fn purchase_document_and_wait_for_response(
        &self,
        price: Credits,
        sdk: &Sdk,
        document_type: DocumentType,
        purchaser_id: Identifier,
        identity_public_key: IdentityPublicKey,
        signer: &S,
        settings: Option<PutSettings>,
    ) -> Result<Document, Error>;
}

#[async_trait::async_trait]
impl<S: Signer> PurchaseDocument<S> for Document {
    async fn purchase_document(
        &self,
        price: Credits,
        sdk: &Sdk,
        document_type: DocumentType,
        purchaser_id: Identifier,
        identity_public_key: IdentityPublicKey,
        signer: &S,
        settings: Option<PutSettings>,
    ) -> Result<StateTransition, Error> {
        let new_identity_contract_nonce = sdk
            .get_identity_contract_nonce(
                purchaser_id,
                document_type.data_contract_id(),
                true,
                settings,
            )
            .await?;

        let settings = settings.unwrap_or_default();

        let transition = DocumentsBatchTransition::new_document_purchase_transition_from_document(
            self.clone(),
            document_type.as_ref(),
            purchaser_id,
            price,
            &identity_public_key,
            new_identity_contract_nonce,
            settings.user_fee_increase.unwrap_or_default(),
            signer,
            sdk.version(),
            None,
            None,
            None,
        )?;

        transition.broadcast(sdk, Some(settings)).await?;
        // response is empty for a broadcast, result comes from the stream wait for state transition result
        Ok(transition)
    }

    async fn purchase_document_and_wait_for_response(
        &self,
        price: Credits,
        sdk: &Sdk,
        document_type: DocumentType,
        purchaser_id: Identifier,
        identity_public_key: IdentityPublicKey,
        signer: &S,
        settings: Option<PutSettings>,
    ) -> Result<Document, Error> {
        let state_transition = self
            .purchase_document(
                price,
                sdk,
                document_type,
                purchaser_id,
                identity_public_key,
                signer,
                settings,
            )
            .await?;

        Self::wait_for_response(sdk, state_transition, settings).await
    }
}