drive_proof_verifier/proof/
token_perpetual_distribution_last_claim.rs1use dapi_grpc::platform::v0::{
2 get_token_perpetual_distribution_last_claim_request::Version as RequestVersion,
3 get_token_perpetual_distribution_last_claim_response::{
4 get_token_perpetual_distribution_last_claim_response_v0, Version as ResponseVersion,
5 },
6 GetTokenPerpetualDistributionLastClaimResponse, Proof, ResponseMetadata,
7};
8use dpp::{
9 dashcore::Network,
10 data_contract::associated_token::{
11 token_configuration::accessors::v0::TokenConfigurationV0Getters,
12 token_distribution_rules::accessors::v0::TokenDistributionRulesV0Getters,
13 token_perpetual_distribution::{
14 methods::v0::TokenPerpetualDistributionV0Accessors,
15 reward_distribution_moment::RewardDistributionMoment,
16 },
17 },
18 prelude::Identifier,
19 version::PlatformVersion,
20};
21use drive::drive::Drive;
22use get_token_perpetual_distribution_last_claim_response_v0::Result as RespResult;
23
24use crate::{verify::verify_tenderdash_proof, ContextProvider, Error};
25
26use super::FromProof;
27use dapi_grpc::platform::v0::GetTokenPerpetualDistributionLastClaimRequest;
28
29impl FromProof<GetTokenPerpetualDistributionLastClaimRequest> for RewardDistributionMoment {
30 type Request = GetTokenPerpetualDistributionLastClaimRequest;
31 type Response = GetTokenPerpetualDistributionLastClaimResponse;
32
33 fn maybe_from_proof_with_metadata<'a, I: Into<Self::Request>, O: Into<Self::Response>>(
35 request: I,
36 response: O,
37 _network: Network,
38 platform_version: &PlatformVersion,
39 provider: &'a dyn ContextProvider,
40 ) -> Result<(Option<Self>, ResponseMetadata, Proof), Error>
41 where
42 Self: Sized + 'a,
43 {
44 let request = request.into();
45 let response = response.into();
46
47 let RequestVersion::V0(req_v0) = request.version.ok_or(Error::EmptyVersion)?;
48
49 let token_id: [u8; 32] =
50 req_v0
51 .token_id
52 .as_slice()
53 .try_into()
54 .map_err(|_| Error::RequestError {
55 error: "token_id must be 32 bytes".into(),
56 })?;
57
58 let identity_id: [u8; 32] =
59 req_v0
60 .identity_id
61 .as_slice()
62 .try_into()
63 .map_err(|_| Error::RequestError {
64 error: "identity_id must be 32 bytes".into(),
65 })?;
66
67 let ResponseVersion::V0(resp_v0) = response.version.ok_or(Error::EmptyVersion)?;
68
69 let metadata = resp_v0
70 .metadata
71 .clone()
72 .ok_or(Error::EmptyResponseMetadata)?;
73
74 let result = resp_v0.result.clone().ok_or(Error::NoProofInResult)?;
75
76 match result {
77 RespResult::Proof(proof_msg) => {
78 let maybe_distribution_type = {
79 let token_id_identifier = Identifier::from_vec(req_v0.token_id.clone())
80 .map_err(|_| Error::RequestError {
81 error: "token_id must be 32 bytes".into(),
82 })?;
83
84 let maybe_token_config =
85 provider.get_token_configuration(&token_id_identifier)?;
86 let maybe_dist_type = maybe_token_config
87 .as_ref()
88 .and_then(|cfg| cfg.distribution_rules().perpetual_distribution())
89 .map(|perp| perp.distribution_type().clone());
90
91 maybe_dist_type
92 };
93
94 match maybe_distribution_type {
95 Some(distribution_type) => {
96 let (root_hash, moment_opt) =
97 Drive::verify_token_perpetual_distribution_last_paid_time(
98 &proof_msg.grovedb_proof,
99 token_id,
100 identity_id,
101 &distribution_type,
102 false,
103 platform_version,
104 )?;
105
106 verify_tenderdash_proof(&proof_msg, &metadata, &root_hash, provider)?;
107
108 Ok((moment_opt, metadata, proof_msg))
110 }
111 None => Err(Error::RequestError {
112 error: "Token distribution type not found with get_token_distribution()"
113 .into(),
114 }),
115 }
116 }
117
118 RespResult::LastClaim(_) => Err(Error::RequestError {
119 error: "Non-proof LastClaim response is not supported in rs-sdk".into(),
120 }),
121 }
122 }
123}