Skip to main content

dpp/data_contract/conversion/json/
mod.rs

1mod v0;
2pub use v0::*;
3
4use crate::data_contract::v0::DataContractV0;
5use crate::data_contract::{DataContract, DataContractV1};
6use crate::version::PlatformVersion;
7use crate::ProtocolError;
8use serde_json::Value as JsonValue;
9
10impl DataContractJsonConversionMethodsV0 for DataContract {
11    fn from_json(
12        json_value: JsonValue,
13        full_validation: bool,
14        platform_version: &PlatformVersion,
15    ) -> Result<Self, ProtocolError>
16    where
17        Self: Sized,
18    {
19        match platform_version
20            .dpp
21            .contract_versions
22            .contract_structure_version
23        {
24            0 => Ok(
25                DataContractV0::from_json(json_value, full_validation, platform_version)?.into(),
26            ),
27            1 => Ok(
28                DataContractV1::from_json(json_value, full_validation, platform_version)?.into(),
29            ),
30            version => Err(ProtocolError::UnknownVersionMismatch {
31                method: "DataContract::from_json".to_string(),
32                known_versions: vec![0, 1],
33                received: version,
34            }),
35        }
36    }
37}
38
39#[cfg(test)]
40mod tests {
41    use crate::data_contract::conversion::json::DataContractJsonConversionMethodsV0;
42    use crate::prelude::DataContract;
43    use crate::version::PlatformVersion;
44    use serde_json::json;
45
46    #[test]
47    fn from_json_accepts_stepwise_with_string_keys() {
48        let platform_version = PlatformVersion::latest();
49
50        let owner = "HtQNfXBZJu3WnvjvCFJKgbvfgWYJxWxaFWy23TKoFjg9";
51        let id = "BmKTJeLL3GfH8FxEx7SUbTog4eAKj8vJRDi97gYkxB9p";
52
53        let contract = json!({
54            "$formatVersion": "1",
55            "id": id,
56            "ownerId": owner,
57            "version": 1,
58            "config": {
59                "$formatVersion": "0",
60                "canBeDeleted": false,
61                "readonly": false,
62                "keepsHistory": false,
63                "documentsKeepHistoryContractDefault": false,
64                "documentsMutableContractDefault": true,
65                "documentsCanBeDeletedContractDefault": false,
66                "requiresIdentityEncryptionBoundedKey": null,
67                "requiresIdentityDecryptionBoundedKey": null
68            },
69            "documentSchemas": {},
70            "tokens": {
71                "0": {
72                    "$formatVersion": "0",
73                    "conventions": { "$formatVersion": "0", "decimals": 2, "localizations": {} },
74                    "distributionRules": {
75                        "$formatVersion": "0",
76                        "perpetualDistribution": {
77                            "$formatVersion": "0",
78                            "distributionType": {
79                                "$type": "blockBasedDistribution",
80                                "interval": 10,
81                                "function": { "$type": "stepwise", "0": 100, "10": 50 }
82                            },
83                            "distributionRecipient": {"$type": "contractOwner"}
84                        },
85                        "perpetualDistributionRules": {
86                            "$formatVersion": "0",
87                            "authorizedToMakeChange": {"$type": "contractOwner"},
88                            "adminActionTakers": {"$type": "contractOwner"},
89                            "changingAuthorizedActionTakersToNoOneAllowed": false,
90                            "changingAdminActionTakersToNoOneAllowed": false,
91                            "selfChangingAdminActionTakersAllowed": false
92                        },
93                        "preProgrammedDistribution": null,
94                        "preProgrammedDistributionRules": {
95                            "$formatVersion": "0",
96                            "authorizedToMakeChange": {"$type": "noOne"},
97                            "adminActionTakers": {"$type": "noOne"},
98                            "changingAuthorizedActionTakersToNoOneAllowed": false,
99                            "changingAdminActionTakersToNoOneAllowed": false,
100                            "selfChangingAdminActionTakersAllowed": false
101                        },
102                        "newTokensDestinationIdentity": null,
103                        "newTokensDestinationIdentityRules": {
104                            "$formatVersion": "0",
105                            "authorizedToMakeChange": {"$type": "contractOwner"},
106                            "adminActionTakers": {"$type": "contractOwner"},
107                            "changingAuthorizedActionTakersToNoOneAllowed": false,
108                            "changingAdminActionTakersToNoOneAllowed": false,
109                            "selfChangingAdminActionTakersAllowed": false
110                        },
111                        "mintingAllowChoosingDestination": false,
112                        "mintingAllowChoosingDestinationRules": {
113                            "$formatVersion": "0",
114                            "authorizedToMakeChange": {"$type": "contractOwner"},
115                            "adminActionTakers": {"$type": "contractOwner"},
116                            "changingAuthorizedActionTakersToNoOneAllowed": false,
117                            "changingAdminActionTakersToNoOneAllowed": false,
118                            "selfChangingAdminActionTakersAllowed": false
119                        },
120                        "changeDirectPurchasePricingRules": {
121                            "$formatVersion": "0",
122                            "authorizedToMakeChange": {"$type": "noOne"},
123                            "adminActionTakers": {"$type": "noOne"},
124                            "changingAuthorizedActionTakersToNoOneAllowed": false,
125                            "changingAdminActionTakersToNoOneAllowed": false,
126                            "selfChangingAdminActionTakersAllowed": false
127                        }
128                    },
129                    "marketplaceRules": {"$formatVersion": "0", "tradeMode": "NotTradeable"},
130                    "manualMintingRules": {
131                        "$formatVersion": "0",
132                        "authorizedToMakeChange": {"$type": "contractOwner"},
133                        "adminActionTakers": {"$type": "contractOwner"},
134                        "changingAuthorizedActionTakersToNoOneAllowed": false,
135                        "changingAdminActionTakersToNoOneAllowed": false,
136                        "selfChangingAdminActionTakersAllowed": false
137                    },
138                    "manualBurningRules": {
139                        "$formatVersion": "0",
140                        "authorizedToMakeChange": {"$type": "contractOwner"},
141                        "adminActionTakers": {"$type": "contractOwner"},
142                        "changingAuthorizedActionTakersToNoOneAllowed": false,
143                        "changingAdminActionTakersToNoOneAllowed": false,
144                        "selfChangingAdminActionTakersAllowed": false
145                    },
146                    "freezeRules": {
147                        "$formatVersion": "0",
148                        "authorizedToMakeChange": {"$type": "contractOwner"},
149                        "adminActionTakers": {"$type": "contractOwner"},
150                        "changingAuthorizedActionTakersToNoOneAllowed": false,
151                        "changingAdminActionTakersToNoOneAllowed": false,
152                        "selfChangingAdminActionTakersAllowed": false
153                    },
154                    "unfreezeRules": {
155                        "$formatVersion": "0",
156                        "authorizedToMakeChange": {"$type": "contractOwner"},
157                        "adminActionTakers": {"$type": "contractOwner"},
158                        "changingAuthorizedActionTakersToNoOneAllowed": false,
159                        "changingAdminActionTakersToNoOneAllowed": false,
160                        "selfChangingAdminActionTakersAllowed": false
161                    },
162                    "destroyFrozenFundsRules": {
163                        "$formatVersion": "0",
164                        "authorizedToMakeChange": {"$type": "contractOwner"},
165                        "adminActionTakers": {"$type": "contractOwner"},
166                        "changingAuthorizedActionTakersToNoOneAllowed": false,
167                        "changingAdminActionTakersToNoOneAllowed": false,
168                        "selfChangingAdminActionTakersAllowed": false
169                    },
170                    "emergencyActionRules": {
171                        "$formatVersion": "0",
172                        "authorizedToMakeChange": {"$type": "contractOwner"},
173                        "adminActionTakers": {"$type": "contractOwner"},
174                        "changingAuthorizedActionTakersToNoOneAllowed": false,
175                        "changingAdminActionTakersToNoOneAllowed": false,
176                        "selfChangingAdminActionTakersAllowed": false
177                    },
178                    "mainControlGroup": null,
179                    "mainControlGroupCanBeModified": {"$type": "noOne"}
180                }
181            }
182        });
183
184        let result = DataContract::from_json(contract, true, platform_version);
185        assert!(
186            result.is_ok(),
187            "Stepwise with string keys should be accepted by from_json"
188        );
189    }
190
191    #[test]
192    fn from_json_accepts_preprogrammed_with_string_timestamp_keys() {
193        let platform_version = PlatformVersion::latest();
194
195        let owner = "HtQNfXBZJu3WnvjvCFJKgbvfgWYJxWxaFWy23TKoFjg9";
196        let id = "BmKTJeLL3GfH8FxEx7SUbTog4eAKj8vJRDi97gYkxB9p";
197
198        let contract = json!({
199            "$formatVersion": "1",
200            "id": id,
201            "ownerId": owner,
202            "version": 1,
203            "config": {
204                "$formatVersion": "0",
205                "canBeDeleted": false,
206                "readonly": false,
207                "keepsHistory": false,
208                "documentsKeepHistoryContractDefault": false,
209                "documentsMutableContractDefault": true,
210                "documentsCanBeDeletedContractDefault": false,
211                "requiresIdentityEncryptionBoundedKey": null,
212                "requiresIdentityDecryptionBoundedKey": null
213            },
214            "documentSchemas": {},
215            "tokens": {
216                "0": {
217                    "$formatVersion": "0",
218                    "conventions": { "$formatVersion": "0", "decimals": 2, "localizations": {} },
219                    "distributionRules": {
220                        "$formatVersion": "0",
221                        "perpetualDistribution": null,
222                        "perpetualDistributionRules": {
223                            "$formatVersion": "0",
224                            "authorizedToMakeChange": {"$type": "noOne"},
225                            "adminActionTakers": {"$type": "noOne"},
226                            "changingAuthorizedActionTakersToNoOneAllowed": false,
227                            "changingAdminActionTakersToNoOneAllowed": false,
228                            "selfChangingAdminActionTakersAllowed": false
229                        },
230                        "preProgrammedDistribution": {
231                            "$formatVersion": "0",
232                            "distributions": {
233                                "1735689600000": {
234                                    "HtQNfXBZJu3WnvjvCFJKgbvfgWYJxWxaFWy23TKoFjg9": 1000
235                                }
236                            }
237                        },
238                        "preProgrammedDistributionRules": {
239                            "$formatVersion": "0",
240                            "authorizedToMakeChange": {"$type": "contractOwner"},
241                            "adminActionTakers": {"$type": "contractOwner"},
242                            "changingAuthorizedActionTakersToNoOneAllowed": false,
243                            "changingAdminActionTakersToNoOneAllowed": false,
244                            "selfChangingAdminActionTakersAllowed": false
245                        },
246                        "newTokensDestinationIdentity": null,
247                        "newTokensDestinationIdentityRules": {
248                            "$formatVersion": "0",
249                            "authorizedToMakeChange": {"$type": "contractOwner"},
250                            "adminActionTakers": {"$type": "contractOwner"},
251                            "changingAuthorizedActionTakersToNoOneAllowed": false,
252                            "changingAdminActionTakersToNoOneAllowed": false,
253                            "selfChangingAdminActionTakersAllowed": false
254                        },
255                        "mintingAllowChoosingDestination": false,
256                        "mintingAllowChoosingDestinationRules": {
257                            "$formatVersion": "0",
258                            "authorizedToMakeChange": {"$type": "contractOwner"},
259                            "adminActionTakers": {"$type": "contractOwner"},
260                            "changingAuthorizedActionTakersToNoOneAllowed": false,
261                            "changingAdminActionTakersToNoOneAllowed": false,
262                            "selfChangingAdminActionTakersAllowed": false
263                        },
264                        "changeDirectPurchasePricingRules": {
265                            "$formatVersion": "0",
266                            "authorizedToMakeChange": {"$type": "noOne"},
267                            "adminActionTakers": {"$type": "noOne"},
268                            "changingAuthorizedActionTakersToNoOneAllowed": false,
269                            "changingAdminActionTakersToNoOneAllowed": false,
270                            "selfChangingAdminActionTakersAllowed": false
271                        }
272                    },
273                    "marketplaceRules": {"$formatVersion": "0", "tradeMode": "NotTradeable"},
274                    "manualMintingRules": {
275                        "$formatVersion": "0",
276                        "authorizedToMakeChange": {"$type": "contractOwner"},
277                        "adminActionTakers": {"$type": "contractOwner"},
278                        "changingAuthorizedActionTakersToNoOneAllowed": false,
279                        "changingAdminActionTakersToNoOneAllowed": false,
280                        "selfChangingAdminActionTakersAllowed": false
281                    },
282                    "manualBurningRules": {
283                        "$formatVersion": "0",
284                        "authorizedToMakeChange": {"$type": "contractOwner"},
285                        "adminActionTakers": {"$type": "contractOwner"},
286                        "changingAuthorizedActionTakersToNoOneAllowed": false,
287                        "changingAdminActionTakersToNoOneAllowed": false,
288                        "selfChangingAdminActionTakersAllowed": false
289                    },
290                    "freezeRules": {
291                        "$formatVersion": "0",
292                        "authorizedToMakeChange": {"$type": "contractOwner"},
293                        "adminActionTakers": {"$type": "contractOwner"},
294                        "changingAuthorizedActionTakersToNoOneAllowed": false,
295                        "changingAdminActionTakersToNoOneAllowed": false,
296                        "selfChangingAdminActionTakersAllowed": false
297                    },
298                    "unfreezeRules": {
299                        "$formatVersion": "0",
300                        "authorizedToMakeChange": {"$type": "contractOwner"},
301                        "adminActionTakers": {"$type": "contractOwner"},
302                        "changingAuthorizedActionTakersToNoOneAllowed": false,
303                        "changingAdminActionTakersToNoOneAllowed": false,
304                        "selfChangingAdminActionTakersAllowed": false
305                    },
306                    "destroyFrozenFundsRules": {
307                        "$formatVersion": "0",
308                        "authorizedToMakeChange": {"$type": "contractOwner"},
309                        "adminActionTakers": {"$type": "contractOwner"},
310                        "changingAuthorizedActionTakersToNoOneAllowed": false,
311                        "changingAdminActionTakersToNoOneAllowed": false,
312                        "selfChangingAdminActionTakersAllowed": false
313                    },
314                    "emergencyActionRules": {
315                        "$formatVersion": "0",
316                        "authorizedToMakeChange": {"$type": "contractOwner"},
317                        "adminActionTakers": {"$type": "contractOwner"},
318                        "changingAuthorizedActionTakersToNoOneAllowed": false,
319                        "changingAdminActionTakersToNoOneAllowed": false,
320                        "selfChangingAdminActionTakersAllowed": false
321                    },
322                    "mainControlGroup": null,
323                    "mainControlGroupCanBeModified": {"$type": "noOne"}
324                }
325            }
326        });
327
328        let result = DataContract::from_json(contract, true, platform_version);
329        assert!(
330            result.is_ok(),
331            "PreProgrammed with string timestamp keys should be accepted by from_json"
332        );
333    }
334}