@dashevo/wasm-dpp 4.0.0 → 4.1.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dashevo/wasm-dpp",
3
- "version": "4.0.0",
3
+ "version": "4.1.0-beta.2",
4
4
  "description": "The JavaScript implementation of the Dash Platform Protocol",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -44,7 +44,7 @@
44
44
  "@babel/core": "^7.26.10",
45
45
  "@babel/preset-env": "^7.26.9",
46
46
  "@dashevo/dashcore-lib": "~0.22.0",
47
- "@dashevo/dpns-contract": "4.0.0",
47
+ "@dashevo/dpns-contract": "4.1.0-beta.2",
48
48
  "@types/bs58": "^4.0.1",
49
49
  "@types/node": "^20.10.0",
50
50
  "@yarnpkg/pnpify": "^4.0.0-rc.42",
@@ -13,7 +13,6 @@ use dpp::platform_value::{platform_value, Value};
13
13
  use dpp::data_contract::accessors::v0::{DataContractV0Getters, DataContractV0Setters};
14
14
  use dpp::data_contract::accessors::v1::DataContractV1Getters;
15
15
  use dpp::data_contract::config::DataContractConfig;
16
- use dpp::data_contract::conversion::json::DataContractJsonConversionMethodsV0;
17
16
  use dpp::data_contract::conversion::value::v0::DataContractValueConversionMethodsV0;
18
17
  use dpp::data_contract::created_data_contract::CreatedDataContract;
19
18
  use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters;
@@ -102,13 +101,11 @@ impl DataContractWasm {
102
101
 
103
102
  let platform_version = PlatformVersion::first();
104
103
 
105
- DataContract::from_value(
106
- raw_parameters.with_serde_to_platform_value()?,
107
- !skip_validation,
108
- platform_version,
109
- )
110
- .with_js_error()
111
- .map(Into::into)
104
+ let value = raw_parameters.with_serde_to_platform_value()?;
105
+ let full_validation = !skip_validation;
106
+ DataContract::from_value(value, full_validation, platform_version)
107
+ .with_js_error()
108
+ .map(Into::into)
112
109
  }
113
110
 
114
111
  #[wasm_bindgen(js_name=getId)]
@@ -326,9 +323,9 @@ impl DataContractWasm {
326
323
 
327
324
  #[wasm_bindgen(js_name=toObject)]
328
325
  pub fn to_object(&self) -> Result<JsValue, JsValue> {
329
- let platform_version = PlatformVersion::first();
330
-
331
- let value = self.inner.to_value(platform_version).with_js_error()?;
326
+ let value = dpp::platform_value::to_value(&self.inner)
327
+ .map_err(ProtocolError::ValueError)
328
+ .with_js_error()?;
332
329
 
333
330
  let serializer = serde_wasm_bindgen::Serializer::json_compatible();
334
331
 
@@ -370,9 +367,9 @@ impl DataContractWasm {
370
367
 
371
368
  #[wasm_bindgen(js_name=toJSON)]
372
369
  pub fn to_json(&self) -> Result<JsValue, JsValue> {
373
- let platform_version = PlatformVersion::first();
374
-
375
- let json = self.inner.to_json(platform_version).with_js_error()?;
370
+ let json = serde_json::to_value(&self.inner)
371
+ .map_err(|e| ProtocolError::EncodingError(e.to_string()))
372
+ .with_js_error()?;
376
373
  let serializer = serde_wasm_bindgen::Serializer::json_compatible();
377
374
  with_js_error!(json.serialize(&serializer))
378
375
  }
@@ -15,7 +15,9 @@ use dpp::state_transition::{
15
15
  StateTransitionIdentitySigned, StateTransitionOwned, StateTransitionSingleSigned,
16
16
  };
17
17
 
18
- use dpp::state_transition::{StateTransition, StateTransitionValueConvert};
18
+ use dpp::serialization::ValueConvertible;
19
+ use dpp::state_transition::StateTransition;
20
+ use dpp::state_transition::StateTransitionFieldTypes;
19
21
  use dpp::version::PlatformVersion;
20
22
  use dpp::{state_transition::StateTransitionLike, ProtocolError};
21
23
  use serde::Serialize;
@@ -47,14 +49,32 @@ impl From<DataContractCreateTransitionWasm> for DataContractCreateTransition {
47
49
  impl DataContractCreateTransitionWasm {
48
50
  #[wasm_bindgen(constructor)]
49
51
  pub fn new(value: JsValue) -> Result<DataContractCreateTransitionWasm, JsValue> {
50
- let platform_value = PlatformVersion::first();
51
-
52
- DataContractCreateTransition::from_object(
53
- value.with_serde_to_platform_value()?,
54
- platform_value,
55
- )
56
- .map(Into::into)
57
- .with_js_error()
52
+ use dpp::platform_value::Value;
53
+ let mut raw = value.with_serde_to_platform_value()?;
54
+ // Canonical `ValueConvertible::from_object` is a strict serde
55
+ // deserialization: it dispatches on the enum's `$formatVersion` tag and
56
+ // requires every field. Legacy JS clients construct a transition from
57
+ // its essential inputs (data contract + identity nonce) and sign it
58
+ // afterwards, so default the format tag plus the protocol-managed and
59
+ // signature fields they omit — preserving the lenient construction the
60
+ // pre-canonical path provided.
61
+ if let Value::Map(ref mut entries) = raw {
62
+ let mut ensure = |key: &str, default: Value| {
63
+ if !entries
64
+ .iter()
65
+ .any(|(k, _)| matches!(k, Value::Text(s) if s == key))
66
+ {
67
+ entries.push((Value::Text(key.to_string()), default));
68
+ }
69
+ };
70
+ ensure("$formatVersion", Value::Text("0".to_string()));
71
+ ensure("userFeeIncrease", Value::U16(0));
72
+ ensure("signaturePublicKeyId", Value::U32(0));
73
+ ensure("signature", Value::Bytes(vec![]));
74
+ }
75
+ DataContractCreateTransition::from_object(raw)
76
+ .map(Into::into)
77
+ .with_js_error()
58
78
  }
59
79
 
60
80
  #[wasm_bindgen(js_name=getDataContract)]
@@ -187,10 +207,17 @@ impl DataContractCreateTransitionWasm {
187
207
 
188
208
  #[wasm_bindgen(js_name=toObject)]
189
209
  pub fn to_object(&self, skip_signature: Option<bool>) -> Result<JsValue, JsValue> {
190
- let serde_object = self
191
- .0
192
- .to_cleaned_object(skip_signature.unwrap_or(false))
193
- .map_err(from_protocol_error)?;
210
+ let mut serde_object = self.0.to_object().map_err(from_protocol_error)?;
211
+
212
+ if skip_signature.unwrap_or(false) {
213
+ for path in
214
+ <DataContractCreateTransition as StateTransitionFieldTypes>::signature_property_paths()
215
+ {
216
+ serde_object
217
+ .remove_values_matching_path(path)
218
+ .map_err(|e| from_protocol_error(dpp::ProtocolError::ValueError(e)))?;
219
+ }
220
+ }
194
221
 
195
222
  let serializer = serde_wasm_bindgen::Serializer::json_compatible();
196
223
 
@@ -3,11 +3,13 @@
3
3
  // pub use validation::*;
4
4
 
5
5
  use dpp::consensus::ConsensusError;
6
+ use dpp::serialization::ValueConvertible;
6
7
  use dpp::serialization::{PlatformDeserializable, PlatformSerializable};
7
8
  use dpp::state_transition::data_contract_update_transition::accessors::DataContractUpdateTransitionAccessorsV0;
8
9
  use dpp::state_transition::data_contract_update_transition::DataContractUpdateTransition;
10
+ use dpp::state_transition::StateTransition;
11
+ use dpp::state_transition::StateTransitionFieldTypes;
9
12
  use dpp::state_transition::StateTransitionHasUserFeeIncrease;
10
- use dpp::state_transition::{StateTransition, StateTransitionValueConvert};
11
13
  use dpp::state_transition::{
12
14
  StateTransitionIdentitySigned, StateTransitionOwned, StateTransitionSingleSigned,
13
15
  };
@@ -48,14 +50,32 @@ impl From<DataContractUpdateTransitionWasm> for DataContractUpdateTransition {
48
50
  impl DataContractUpdateTransitionWasm {
49
51
  #[wasm_bindgen(constructor)]
50
52
  pub fn new(raw_parameters: JsValue) -> Result<DataContractUpdateTransitionWasm, JsValue> {
51
- let platform_version = PlatformVersion::first();
52
-
53
- DataContractUpdateTransition::from_object(
54
- raw_parameters.with_serde_to_platform_value()?,
55
- platform_version,
56
- )
57
- .map(Into::into)
58
- .with_js_error()
53
+ use dpp::platform_value::Value;
54
+ let mut raw = raw_parameters.with_serde_to_platform_value()?;
55
+ // Canonical `ValueConvertible::from_object` is a strict serde
56
+ // deserialization: it dispatches on the enum's `$formatVersion` tag and
57
+ // requires every field. Legacy JS clients construct a transition from
58
+ // its essential inputs (data contract + identity contract nonce) and
59
+ // sign it afterwards, so default the format tag plus the
60
+ // protocol-managed and signature fields they omit — preserving the
61
+ // lenient construction the pre-canonical path provided.
62
+ if let Value::Map(ref mut entries) = raw {
63
+ let mut ensure = |key: &str, default: Value| {
64
+ if !entries
65
+ .iter()
66
+ .any(|(k, _)| matches!(k, Value::Text(s) if s == key))
67
+ {
68
+ entries.push((Value::Text(key.to_string()), default));
69
+ }
70
+ };
71
+ ensure("$formatVersion", Value::Text("0".to_string()));
72
+ ensure("userFeeIncrease", Value::U16(0));
73
+ ensure("signaturePublicKeyId", Value::U32(0));
74
+ ensure("signature", Value::Bytes(vec![]));
75
+ }
76
+ DataContractUpdateTransition::from_object(raw)
77
+ .map(Into::into)
78
+ .with_js_error()
59
79
  }
60
80
 
61
81
  #[wasm_bindgen(js_name=getDataContract)]
@@ -191,10 +211,17 @@ impl DataContractUpdateTransitionWasm {
191
211
 
192
212
  #[wasm_bindgen(js_name=toObject)]
193
213
  pub fn to_object(&self, skip_signature: Option<bool>) -> Result<JsValue, JsValue> {
194
- let serde_object = self
195
- .0
196
- .to_cleaned_object(skip_signature.unwrap_or(false))
197
- .map_err(from_protocol_error)?;
214
+ let mut serde_object = self.0.to_object().map_err(from_protocol_error)?;
215
+
216
+ if skip_signature.unwrap_or(false) {
217
+ for path in
218
+ <DataContractUpdateTransition as StateTransitionFieldTypes>::signature_property_paths()
219
+ {
220
+ serde_object
221
+ .remove_values_matching_path(path)
222
+ .map_err(|e| from_protocol_error(ProtocolError::ValueError(e)))?;
223
+ }
224
+ }
198
225
 
199
226
  serde_object
200
227
  .serialize(&serde_wasm_bindgen::Serializer::json_compatible())
@@ -1,13 +1,9 @@
1
- use dpp::document::{
2
- DocumentV0Getters, DocumentV0Setters, ExtendedDocument, EXTENDED_DOCUMENT_IDENTIFIER_FIELDS,
3
- };
1
+ use dpp::document::{DocumentV0Getters, DocumentV0Setters, ExtendedDocument};
4
2
  use serde_json::Value as JsonValue;
5
3
 
6
4
  use dpp::platform_value::{Bytes32, Value};
7
5
  use dpp::prelude::{Identifier, Revision, TimestampMillis};
8
6
 
9
- use dpp::util::json_value::JsonValueExt;
10
-
11
7
  use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters;
12
8
  use dpp::document::serialization_traits::ExtendedDocumentPlatformConversionMethodsV0;
13
9
  use dpp::platform_value::converter::serde_json::BTreeValueJsonConverter;
@@ -21,14 +17,12 @@ use crate::buffer::Buffer;
21
17
  use crate::data_contract::DataContractWasm;
22
18
  #[allow(deprecated)] // BinaryType is unused in unused code below
23
19
  use crate::document::BinaryType;
24
- use crate::document::{ConversionOptions, DocumentWasm};
20
+ use crate::document::DocumentWasm;
25
21
  use crate::errors::RustConversionError;
26
22
  use crate::identifier::{identifier_from_js_value, IdentifierWrapper};
27
- use crate::lodash::lodash_set;
28
23
  use crate::metadata::MetadataWasm;
29
24
  use crate::utils::{with_serde_to_platform_value, IntoWasm, ToSerdeJSONExt, WithJsError};
30
25
  use crate::validation::ValidationResultWasm;
31
- use crate::with_js_error;
32
26
 
33
27
  #[wasm_bindgen(js_name=ExtendedDocument)]
34
28
  #[derive(Debug, Clone, Serialize, Deserialize)]
@@ -187,6 +181,21 @@ impl ExtendedDocumentWasm {
187
181
  Ok(js_value)
188
182
  }
189
183
 
184
+ #[wasm_bindgen(js_name=toObject)]
185
+ pub fn to_object(&self) -> Result<JsValue, JsValue> {
186
+ // Canonical object shape: every `$`-prefixed system field (id, ownerId,
187
+ // type, dataContractId, revision, timestamps/block-heights, creatorId)
188
+ // plus the flattened document properties, with identifiers and binary
189
+ // data rendered as `Uint8Array`. Serializing the non-human-readable
190
+ // `to_map_value()` turns every identifier/bytes node — including nested
191
+ // document properties — into a `Uint8Array` in one pass, so there is no
192
+ // need to walk the document type's identifier/binary paths.
193
+ let map = self.0.to_map_value().with_js_error()?;
194
+ let serializer =
195
+ serde_wasm_bindgen::Serializer::json_compatible().serialize_bytes_as_arrays(false);
196
+ Ok(map.serialize(&serializer)?)
197
+ }
198
+
190
199
  #[wasm_bindgen(js_name=set)]
191
200
  pub fn set(&mut self, path: String, js_value_to_set: JsValue) -> Result<(), JsValue> {
192
201
  let value: Value = js_value_to_set.with_serde_to_platform_value()?;
@@ -273,58 +282,6 @@ impl ExtendedDocumentWasm {
273
282
  Ok(())
274
283
  }
275
284
 
276
- #[wasm_bindgen(js_name=toObject)]
277
- pub fn to_object(&self, options: &JsValue) -> Result<JsValue, JsValue> {
278
- let options: ConversionOptions = if !options.is_undefined() && options.is_object() {
279
- let raw_options = options.with_serde_to_json_value()?;
280
- serde_json::from_value(raw_options).with_js_error()?
281
- } else {
282
- Default::default()
283
- };
284
- let mut value = self.0.to_json_object_for_validation().with_js_error()?;
285
-
286
- let document_type = self.0.document_type().with_js_error()?;
287
-
288
- let identifier_paths = document_type.identifier_paths();
289
- let binary_paths = document_type.binary_paths();
290
-
291
- let serializer = serde_wasm_bindgen::Serializer::json_compatible();
292
- let js_value = value.serialize(&serializer)?;
293
-
294
- for path in identifier_paths
295
- .iter()
296
- .map(|s| s.as_str())
297
- .chain(EXTENDED_DOCUMENT_IDENTIFIER_FIELDS)
298
- {
299
- if let Ok(bytes) = value.remove_value_at_path_into::<Vec<u8>>(path) {
300
- let buffer = Buffer::from_bytes_owned(bytes);
301
- if !options.skip_identifiers_conversion {
302
- lodash_set(&js_value, path, buffer.into());
303
- } else {
304
- let id = IdentifierWrapper::new(buffer.into());
305
- lodash_set(&js_value, path, id.into());
306
- }
307
- }
308
- }
309
-
310
- for path in binary_paths {
311
- if let Ok(bytes) = value.remove_value_at_path_into::<Vec<u8>>(path) {
312
- let buffer = Buffer::from_bytes(&bytes);
313
- lodash_set(&js_value, path, buffer.into());
314
- }
315
- }
316
-
317
- Ok(js_value)
318
- }
319
-
320
- #[wasm_bindgen(js_name=toJSON)]
321
- pub fn to_json(&self) -> Result<JsValue, JsValue> {
322
- let value = self.0.to_json(PlatformVersion::first()).with_js_error()?;
323
- let serializer = serde_wasm_bindgen::Serializer::json_compatible();
324
-
325
- with_js_error!(value.serialize(&serializer))
326
- }
327
-
328
285
  #[wasm_bindgen(js_name=toBuffer)]
329
286
  pub fn to_buffer(&self) -> Result<Buffer, JsValue> {
330
287
  let bytes: Vec<u8> = self
@@ -11,7 +11,9 @@ use crate::data_contract::DataContractWasm;
11
11
  use crate::identifier::IdentifierWrapper;
12
12
 
13
13
  use crate::utils::WithJsError;
14
- use crate::utils::{with_serde_to_json_value, ToSerdeJSONExt};
14
+ use crate::utils::{
15
+ json_value_to_platform_value_lenient, with_serde_to_json_value, ToSerdeJSONExt,
16
+ };
15
17
 
16
18
  use dpp::document::document_methods::DocumentMethodsV0;
17
19
  use dpp::document::DocumentV0Getters;
@@ -39,7 +41,6 @@ use dpp::{platform_value, ProtocolError};
39
41
 
40
42
  use dpp::data_contract::accessors::v0::DataContractV0Getters;
41
43
  use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters;
42
- use dpp::document::serialization_traits::DocumentPlatformValueMethodsV0;
43
44
  use dpp::version::PlatformVersion;
44
45
  use serde_json::Value as JsonValue;
45
46
 
@@ -71,7 +72,8 @@ impl DocumentWasm {
71
72
  js_data_contract: &DataContractWasm,
72
73
  js_document_type_name: JsValue,
73
74
  ) -> Result<DocumentWasm, JsValue> {
74
- let mut raw_document: Value = with_serde_to_json_value(&js_raw_document)?.into();
75
+ let mut raw_document: Value =
76
+ json_value_to_platform_value_lenient(with_serde_to_json_value(&js_raw_document)?);
75
77
 
76
78
  let document_type_name = js_document_type_name
77
79
  .as_string()
@@ -99,8 +101,23 @@ impl DocumentWasm {
99
101
  .with_js_error()?;
100
102
  // The binary paths are not being converted, because they always should be a `Buffer`. `Buffer` is always an Array
101
103
 
102
- let document = Document::from_platform_value(raw_document, PlatformVersion::first())
103
- .with_js_error()?;
104
+ // Phase D step 8 slice B replaced legacy `Document::from_platform_value`
105
+ // with canonical `ValueConvertible::from_object`, which requires a
106
+ // `$formatVersion` tag. Insert it for un-tagged JS-supplied input
107
+ // before delegating.
108
+ if let Value::Map(ref mut entries) = raw_document {
109
+ let has_tag = entries
110
+ .iter()
111
+ .any(|(k, _)| matches!(k, Value::Text(s) if s == "$formatVersion"));
112
+ if !has_tag {
113
+ entries.push((
114
+ Value::Text("$formatVersion".to_string()),
115
+ Value::Text("0".to_string()),
116
+ ));
117
+ }
118
+ }
119
+ use dpp::serialization::ValueConvertible;
120
+ let document = Document::from_object(raw_document).with_js_error()?;
104
121
 
105
122
  Ok(document.into())
106
123
  }
@@ -1,6 +1,7 @@
1
1
  use dpp::dashcore::consensus::Encodable;
2
2
  use dpp::dashcore::OutPoint;
3
3
  use dpp::identity::state_transition::asset_lock_proof::AssetLockProofType;
4
+ use dpp::serialization::ValueConvertible;
4
5
  use serde::{Deserialize, Serialize};
5
6
  use std::convert::TryInto;
6
7
  use wasm_bindgen::prelude::*;
@@ -117,7 +118,9 @@ impl ChainAssetLockProofWasm {
117
118
 
118
119
  #[wasm_bindgen(js_name=toObject)]
119
120
  pub fn to_object(&self) -> Result<JsValue, JsValue> {
120
- let asset_lock_value = self.0.to_cleaned_object().with_js_error()?;
121
+ // `to_cleaned_object` was a pure delegation to `to_object` in rs-dpp;
122
+ // the canonical `ValueConvertible::to_object` produces the same Value.
123
+ let asset_lock_value = self.0.to_object().with_js_error()?;
121
124
 
122
125
  let serializer = serde_wasm_bindgen::Serializer::json_compatible();
123
126
  let js_object = with_js_error!(asset_lock_value.serialize(&serializer))?;
@@ -5,6 +5,7 @@ use dpp::dashcore::{
5
5
 
6
6
  use dpp::dashcore::consensus::Encodable;
7
7
  use dpp::identity::state_transition::asset_lock_proof::AssetLockProofType;
8
+ use dpp::serialization::ValueConvertible;
8
9
  use serde::{Deserialize, Serialize};
9
10
  use std::convert::TryInto;
10
11
  use wasm_bindgen::prelude::*;
@@ -117,7 +118,10 @@ impl InstantAssetLockProofWasm {
117
118
 
118
119
  #[wasm_bindgen(js_name=toObject)]
119
120
  pub fn to_object(&self) -> Result<JsValue, JsValue> {
120
- let asset_lock_value = self.0.to_cleaned_object().with_js_error()?;
121
+ // `to_cleaned_object` was a pure delegation to `to_object` in
122
+ // rs-dpp; the canonical `ValueConvertible::to_object` produces the
123
+ // same Value (no `disabledAt` field on InstantAssetLockProof to clean).
124
+ let asset_lock_value = self.0.to_object().with_js_error()?;
121
125
 
122
126
  let serializer = serde_wasm_bindgen::Serializer::json_compatible();
123
127
  let js_object = with_js_error!(asset_lock_value.serialize(&serializer))?;
package/src/utils.rs CHANGED
@@ -105,7 +105,57 @@ pub fn with_serde_to_json_value(data: &JsValue) -> Result<JsonValue, JsValue> {
105
105
  }
106
106
 
107
107
  pub fn with_serde_to_platform_value(data: &JsValue) -> Result<Value, JsValue> {
108
- Ok(with_serde_to_json_value(data)?.into())
108
+ Ok(json_value_to_platform_value_lenient(
109
+ with_serde_to_json_value(data)?,
110
+ ))
111
+ }
112
+
113
+ /// Converts a `serde_json::Value` into a `platform_value::Value`, restoring the
114
+ /// legacy "array of u8 → `Value::Bytes`" coercion that `From<JsonValue> for Value`
115
+ /// used to perform before the Critical-2 faithful-conversion change in
116
+ /// rs-platform-value.
117
+ ///
118
+ /// The JS boundary of this (deprecated) crate stringifies JS `Buffer`s into plain
119
+ /// number arrays via [`stringify`], then relied on that coercion to reconstruct
120
+ /// binary document fields (`byteArrayField`, identifiers, …) as `Value::Bytes`.
121
+ /// rs-platform-value is now intentionally faithful (array → `Value::Array`), so we
122
+ /// re-apply the heuristic here — scoped to the legacy crate's JS input only —
123
+ /// rather than reintroduce the footgun globally.
124
+ pub(crate) fn json_value_to_platform_value_lenient(value: JsonValue) -> Value {
125
+ match value {
126
+ JsonValue::Array(array) => {
127
+ let u8_max = u8::MAX as u64;
128
+ // Matches the pre-Critical-2 heuristic exactly: length >= 10 and every
129
+ // element a u64 that fits in a byte ⇒ treat as a byte array.
130
+ if array.len() >= 10
131
+ && array
132
+ .iter()
133
+ .all(|v| v.as_u64().map(|int| int <= u8_max).unwrap_or(false))
134
+ {
135
+ Value::Bytes(
136
+ array
137
+ .into_iter()
138
+ .map(|v| v.as_u64().expect("checked above") as u8)
139
+ .collect(),
140
+ )
141
+ } else {
142
+ Value::Array(
143
+ array
144
+ .into_iter()
145
+ .map(json_value_to_platform_value_lenient)
146
+ .collect(),
147
+ )
148
+ }
149
+ }
150
+ JsonValue::Object(map) => Value::Map(
151
+ map.into_iter()
152
+ .map(|(k, v)| (k.into(), json_value_to_platform_value_lenient(v)))
153
+ .collect(),
154
+ ),
155
+ // Null / Bool / Number / String are unaffected by the heuristic and convert
156
+ // identically through the canonical impl.
157
+ other => other.into(),
158
+ }
109
159
  }
110
160
 
111
161
  pub fn with_serde_into<D>(data: &JsValue) -> Result<D, JsValue>
@@ -32,66 +32,6 @@ describe('ExtendedDocument', () => {
32
32
  document.setMetadata(metadataFixture);
33
33
  });
34
34
 
35
- describe.skip('#toJSON', () => {
36
- it('should return json document - Rust', () => {
37
- const result = document.toJSON();
38
-
39
- expect(result).to.deep.equal({
40
- $protocolVersion: document.getProtocolVersion(),
41
- $dataContractId: dataContract.getId().toString(),
42
- $id: document.getId().toString(),
43
- $ownerId: document.getOwnerId().toString(),
44
- $revision: 1,
45
- $type: 'withByteArrays',
46
- byteArrayField: document.get('byteArrayField').toString('base64'),
47
- identifierField: document.get('identifierField').toString(),
48
- });
49
- });
50
- });
51
-
52
- describe('#toObject', () => {
53
- it('should return raw document - Rust', () => {
54
- const result = document.toObject();
55
-
56
- expect(result).to.deep.equal({
57
- $createdAt: null, // TODO: it should be omitted
58
- $createdAtBlockHeight: null,
59
- $createdAtCoreBlockHeight: null,
60
- $creatorId: null,
61
- $updatedAt: null,
62
- $updatedAtBlockHeight: null,
63
- $updatedAtCoreBlockHeight: null,
64
- $transferredAt: null,
65
- $transferredAtBlockHeight: null,
66
- $transferredAtCoreBlockHeight: null,
67
- $dataContractId: dataContract.getId().toBuffer(),
68
- $id: document.getId().toBuffer(),
69
- $ownerId: document.getOwnerId().toBuffer(),
70
- $revision: 1,
71
- $type: 'withByteArrays',
72
- byteArrayField: document.get('byteArrayField'),
73
- identifierField: document.get('identifierField').toBuffer(),
74
- });
75
- });
76
-
77
- it('should return raw document with Identifiers - Rust', () => {
78
- const result = document.toObject({ skipIdentifiersConversion: true });
79
-
80
- expect(result.$dataContractId).to.be.an.instanceOf(Identifier);
81
- expect(result.$id).to.be.an.instanceOf(Identifier);
82
- expect(result.$ownerId).to.be.an.instanceOf(Identifier);
83
- expect(result.identifierField).to.be.an.instanceOf(Identifier);
84
-
85
- expect(result.$dataContractId.toBuffer()).to.deep.equal(dataContract.getId().toBuffer());
86
- expect(result.$id.toBuffer()).to.deep.equal(document.getId().toBuffer());
87
- expect(result.$ownerId.toBuffer()).to.deep.equal(document.getOwnerId().toBuffer());
88
- expect(result.identifierField.toBuffer()).to.deep.equal(document.get('identifierField').toBuffer());
89
- expect(BigInt(result.$revision)).to.deep.equal(document.getRevision());
90
- expect(result.$type).to.deep.equal(document.getType());
91
- expect(result.byteArrayField).to.deep.equal(document.get('byteArrayField'));
92
- });
93
- });
94
-
95
35
  describe('#setMetadata', () => {
96
36
  it('should set metadata - Rust', () => {
97
37
  const otherMetadata = new Metadata(BigInt(43), 1, BigInt(100), 2);
@@ -218,7 +218,7 @@ describe('DataContract', () => {
218
218
  const result = dataContract.toJSON();
219
219
 
220
220
  expect(result).to.deep.equal({
221
- $formatVersion: '0',
221
+ $formatVersion: '1',
222
222
  config: {
223
223
  $formatVersion: '0',
224
224
  canBeDeleted: false,
@@ -235,6 +235,16 @@ describe('DataContract', () => {
235
235
  ownerId: bs58.encode(ownerId),
236
236
  schemaDefs: null,
237
237
  documentSchemas,
238
+ createdAt: null,
239
+ updatedAt: null,
240
+ createdAtBlockHeight: null,
241
+ updatedAtBlockHeight: null,
242
+ createdAtEpoch: null,
243
+ updatedAtEpoch: null,
244
+ description: null,
245
+ keywords: [],
246
+ groups: {},
247
+ tokens: {},
238
248
  });
239
249
  });
240
250
 
@@ -248,7 +258,7 @@ describe('DataContract', () => {
248
258
  const result = dataContract.toJSON();
249
259
 
250
260
  expect(result).to.deep.equal({
251
- $formatVersion: '0',
261
+ $formatVersion: '1',
252
262
  config: {
253
263
  $formatVersion: '0',
254
264
  canBeDeleted: false,
@@ -265,6 +275,16 @@ describe('DataContract', () => {
265
275
  ownerId: bs58.encode(ownerId),
266
276
  documentSchemas,
267
277
  schemaDefs: $defs,
278
+ createdAt: null,
279
+ updatedAt: null,
280
+ createdAtBlockHeight: null,
281
+ updatedAtBlockHeight: null,
282
+ createdAtEpoch: null,
283
+ updatedAtEpoch: null,
284
+ description: null,
285
+ keywords: [],
286
+ groups: {},
287
+ tokens: {},
268
288
  });
269
289
  });
270
290
  });
@@ -72,7 +72,7 @@ describe('DataContractCreateTransition', () => {
72
72
  it('should return serialized State Transition', () => {
73
73
  const result = stateTransition.toBuffer();
74
74
  expect(result).to.be.instanceOf(Buffer);
75
- expect(result).to.have.lengthOf(2359);
75
+ expect(result).to.have.lengthOf(2370);
76
76
  });
77
77
 
78
78
  it('should be able to restore contract config from bytes', () => {
@@ -20,7 +20,8 @@ describe('DataContractUpdateTransition', () => {
20
20
  stateTransition = new DataContractUpdateTransition({
21
21
  protocolVersion: 1,
22
22
  dataContract: dataContract.toObject(),
23
- identityContractNonce: 1,
23
+ // Canonical serde wire name for the identity-contract-nonce field.
24
+ '$identity-contract-nonce': 1,
24
25
  });
25
26
  });
26
27
 
@@ -65,7 +66,7 @@ describe('DataContractUpdateTransition', () => {
65
66
  it('should return serialized State Transition', () => {
66
67
  const result = stateTransition.toBuffer();
67
68
  expect(result).to.be.instanceOf(Buffer);
68
- expect(result).to.have.lengthOf(2359);
69
+ expect(result).to.have.lengthOf(2370);
69
70
  });
70
71
 
71
72
  it('should be able to restore contract config from bytes', () => {
@@ -397,28 +397,6 @@ describe('Document', () => {
397
397
  });
398
398
  });
399
399
 
400
- describe('#toJSON', () => {
401
- it('should return Document as plain JS object', () => {
402
- const jsonDocument = {
403
- ...rawDocument,
404
- $dataContractId: document.getDataContractId().toString(),
405
- $dataContract: document.getDataContract().toJSON(),
406
- $id: document.getId().toString(),
407
- $ownerId: document.getOwnerId().toString(),
408
- };
409
-
410
- expect(document.toJSON()).to.deep.equal(jsonDocument);
411
- });
412
- });
413
-
414
- describe('#toObject', () => {
415
- it('should return Document as object', () => {
416
- const result = document.toObject();
417
-
418
- expect(rawDocumentWithBuffers).to.deep.equal(result);
419
- });
420
- });
421
-
422
400
  describe('#toBuffer', () => {
423
401
  it('should return serialized Document', () => {
424
402
  const buffer = document.toBuffer();