dpp/tokens/token_payment_info/v0/
mod.rs

1pub mod v0_accessors;
2
3use crate::balances::credits::TokenAmount;
4use crate::data_contract::TokenContractPosition;
5use crate::tokens::gas_fees_paid_by::GasFeesPaidBy;
6use crate::tokens::token_payment_info::v0::v0_accessors::TokenPaymentInfoAccessorsV0;
7use crate::ProtocolError;
8use bincode::{Decode, Encode};
9use derive_more::Display;
10use platform_value::btreemap_extensions::BTreeValueRemoveFromMapHelper;
11use platform_value::{Identifier, Value};
12#[cfg(any(
13    feature = "serde-conversion",
14    all(feature = "serde-conversion", feature = "serde-conversion"),
15))]
16use serde::{Deserialize, Serialize};
17use std::collections::BTreeMap;
18
19#[derive(Debug, Clone, Copy, Encode, Decode, Default, PartialEq, Display)]
20#[cfg_attr(
21    any(
22        feature = "serde-conversion",
23        all(feature = "serde-conversion", feature = "serde-conversion"),
24    ),
25    derive(Serialize, Deserialize),
26    serde(rename_all = "camelCase")
27)]
28#[display(
29    "Contract ID: {:?}, Token Position: {:?}, Min Cost: {:?}, Max Cost: {:?}, Gas Fees Paid By: {}",
30    payment_token_contract_id,
31    token_contract_position,
32    minimum_token_cost,
33    maximum_token_cost,
34    gas_fees_paid_by
35)]
36pub struct TokenPaymentInfoV0 {
37    /// By default, we use a token in the same contract, this field must be set if the document
38    /// requires payment using another contracts token.
39    pub payment_token_contract_id: Option<Identifier>,
40    /// If we are expecting to pay with a token in a contract, which token are we expecting
41    /// to pay with?
42    /// We have this set so contract owners can't switch out to more valuable token.
43    /// For example if my Data contract
44    pub token_contract_position: TokenContractPosition,
45    /// Minimum token cost, this most often should not be set
46    pub minimum_token_cost: Option<TokenAmount>,
47    /// Maximum token cost, this most often should be set
48    /// If:
49    /// - a client does not have this set
50    /// - and the data contract allows the price of NFTs to be changed by the data contract's owner or allowed party.
51    ///   Then:
52    /// - The user could see the cost changed on them
53    pub maximum_token_cost: Option<TokenAmount>,
54    /// Who pays the gas fees, this needs to match what the contract allows
55    pub gas_fees_paid_by: GasFeesPaidBy,
56}
57
58impl TokenPaymentInfoAccessorsV0 for TokenPaymentInfoV0 {
59    // Getters
60    fn payment_token_contract_id(&self) -> Option<Identifier> {
61        self.payment_token_contract_id
62    }
63
64    fn payment_token_contract_id_ref(&self) -> &Option<Identifier> {
65        &self.payment_token_contract_id
66    }
67
68    fn token_contract_position(&self) -> TokenContractPosition {
69        self.token_contract_position
70    }
71
72    fn minimum_token_cost(&self) -> Option<TokenAmount> {
73        self.minimum_token_cost
74    }
75
76    fn maximum_token_cost(&self) -> Option<TokenAmount> {
77        self.maximum_token_cost
78    }
79
80    // Setters
81    fn set_payment_token_contract_id(&mut self, id: Option<Identifier>) {
82        self.payment_token_contract_id = id;
83    }
84
85    fn set_token_contract_position(&mut self, position: TokenContractPosition) {
86        self.token_contract_position = position;
87    }
88
89    fn set_minimum_token_cost(&mut self, cost: Option<TokenAmount>) {
90        self.minimum_token_cost = cost;
91    }
92
93    fn set_maximum_token_cost(&mut self, cost: Option<TokenAmount>) {
94        self.maximum_token_cost = cost;
95    }
96
97    fn gas_fees_paid_by(&self) -> GasFeesPaidBy {
98        self.gas_fees_paid_by
99    }
100
101    fn set_gas_fees_paid_by(&mut self, payer: GasFeesPaidBy) {
102        self.gas_fees_paid_by = payer;
103    }
104}
105
106impl TryFrom<BTreeMap<String, Value>> for TokenPaymentInfoV0 {
107    type Error = ProtocolError;
108
109    fn try_from(mut map: BTreeMap<String, Value>) -> Result<Self, Self::Error> {
110        Ok(TokenPaymentInfoV0 {
111            payment_token_contract_id: map.remove_optional_identifier("paymentTokenContractId")?,
112
113            token_contract_position: map
114                .remove_optional_integer("tokenContractPosition")?
115                .unwrap_or_default(),
116
117            minimum_token_cost: map.remove_optional_integer("minimumTokenCost")?,
118
119            maximum_token_cost: map.remove_optional_integer("maximumTokenCost")?,
120
121            gas_fees_paid_by: map
122                .remove_optional_string("gasFeesPaidBy")?
123                .map(|v| match v.as_str() {
124                    "DocumentOwner" => GasFeesPaidBy::DocumentOwner,
125                    "ContractOwner" => GasFeesPaidBy::ContractOwner,
126                    "PreferContractOwner" => GasFeesPaidBy::PreferContractOwner,
127                    _ => GasFeesPaidBy::default(),
128                })
129                .unwrap_or_default(),
130        })
131    }
132}