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}