From 3b511ce9b5dd4d4a0aba426e8a9b8c0a3589413b Mon Sep 17 00:00:00 2001 From: pshenmic Date: Sat, 5 Oct 2024 23:45:52 +0700 Subject: [PATCH 01/31] feat(wasm-dpp): add transfer transition to documents batch wip --- .../src/document/document_factory/v0/mod.rs | 87 +++++ packages/wasm-dpp/src/document/factory.rs | 8 + .../document_transfer_transition.rs | 300 ++++++++++++++++++ .../document_transition/mod.rs | 1 + 4 files changed, 396 insertions(+) create mode 100644 packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_transfer_transition.rs diff --git a/packages/rs-dpp/src/document/document_factory/v0/mod.rs b/packages/rs-dpp/src/document/document_factory/v0/mod.rs index 58fc96de91a..5aa64b775a3 100644 --- a/packages/rs-dpp/src/document/document_factory/v0/mod.rs +++ b/packages/rs-dpp/src/document/document_factory/v0/mod.rs @@ -507,6 +507,93 @@ impl DocumentFactoryV0 { // Ok(raw_transitions) } + #[cfg(feature = "state-transitions")] + fn document_transfer_transitions( + documents: Vec<(Document, DocumentTypeRef)>, + nonce_counter: &mut BTreeMap<(Identifier, Identifier), u64>, //IdentityID/ContractID -> nonce + platform_version: &PlatformVersion, + ) -> Result, ProtocolError> { + documents + .into_iter() + .map(|(mut document, document_type)| { + if !document_type.documents_mutable() { + return Err(DocumentError::TryingToReplaceImmutableDocument { + document: Box::new(document), + } + .into()); + } + if document.revision().is_none() { + return Err(DocumentError::RevisionAbsentError { + document: Box::new(document), + } + .into()); + }; + + document.increment_revision()?; + document.set_updated_at(Some(Utc::now().timestamp_millis() as TimestampMillis)); + + let recipient_owner_id = document.owner_id(); + + let nonce = nonce_counter + .entry((document.owner_id(), document_type.data_contract_id())) + .or_default(); + + let transition = DocumentTransferTransition::from_document( + document, + document_type, + *nonce, + recipient_owner_id, + platform_version, + None, + None, + )?; + + *nonce += 1; + + Ok(transition.into()) + }) + .collect() + // let mut raw_transitions = vec![]; + // for (document, document_type) in documents { + // if !document_type.documents_mutable() { + // return Err(DocumentError::TryingToReplaceImmutableDocument { + // document: Box::new(document), + // } + // .into()); + // } + // let Some(document_revision) = document.revision() else { + // return Err(DocumentError::RevisionAbsentError { + // document: Box::new(document), + // }.into()); + // }; + // let mut map = document.to_map_value()?; + // + // map.retain(|key, _| { + // !key.starts_with('$') || DOCUMENT_REPLACE_KEYS_TO_STAY.contains(&key.as_str()) + // }); + // map.insert( + // PROPERTY_ACTION.to_string(), + // Value::U8(DocumentTransitionActionType::Replace as u8), + // ); + // let new_revision = document_revision + 1; + // map.insert(PROPERTY_REVISION.to_string(), Value::U64(new_revision)); + // + // // If document have an originally set `updatedAt` + // // we should update it then + // let contains_updated_at = document_type + // .required_fields() + // .contains(PROPERTY_UPDATED_AT); + // + // if contains_updated_at { + // let now = Utc::now().timestamp_millis() as TimestampMillis; + // map.insert(PROPERTY_UPDATED_AT.to_string(), Value::U64(now)); + // } + // + // raw_transitions.push(map.into()); + // } + // Ok(raw_transitions) + } + #[cfg(feature = "state-transitions")] fn document_delete_transitions( documents: Vec<(Document, DocumentTypeRef)>, diff --git a/packages/wasm-dpp/src/document/factory.rs b/packages/wasm-dpp/src/document/factory.rs index 0b927a60803..038fb8db998 100644 --- a/packages/wasm-dpp/src/document/factory.rs +++ b/packages/wasm-dpp/src/document/factory.rs @@ -32,6 +32,7 @@ pub struct DocumentTransitions { create: Vec, replace: Vec, delete: Vec, + transfer: Vec, } #[wasm_bindgen(js_class=DocumentTransitions)] @@ -55,6 +56,11 @@ impl DocumentTransitions { pub fn add_transition_delete(&mut self, transition: ExtendedDocumentWasm) { self.delete.push(transition) } + + #[wasm_bindgen(js_name = "addTransitionTransfer")] + pub fn add_transition_transfer(&mut self, transition: ExtendedDocumentWasm) { + self.transfer.push(transition) + } } #[wasm_bindgen(js_name = DocumentFactory)] @@ -278,10 +284,12 @@ fn extract_documents_by_action( let documents_create = extract_documents_of_action(documents, "create").with_js_error()?; let documents_replace = extract_documents_of_action(documents, "replace").with_js_error()?; let documents_delete = extract_documents_of_action(documents, "delete").with_js_error()?; + let documents_transfer = extract_documents_of_action(documents, "transfer").with_js_error()?; documents_by_action.insert(DocumentTransitionActionType::Create, documents_create); documents_by_action.insert(DocumentTransitionActionType::Replace, documents_replace); documents_by_action.insert(DocumentTransitionActionType::Delete, documents_delete); + documents_by_action.insert(DocumentTransitionActionType::Transfer, documents_transfer); Ok(documents_by_action) } diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_transfer_transition.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_transfer_transition.rs new file mode 100644 index 00000000000..b6e9cdfba7e --- /dev/null +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_transfer_transition.rs @@ -0,0 +1,300 @@ +use std::convert; + +use serde_json::Value as JsonValue; + +use dpp::platform_value::btreemap_extensions::{ + BTreeValueMapHelper, BTreeValueMapReplacementPathHelper, +}; +use dpp::platform_value::ReplacementType; +use dpp::prelude::Revision; +use dpp::{ + prelude::{Identifier}, + ProtocolError, +}; +use wasm_bindgen::prelude::*; +use dpp::data_contract::accessors::v0::DataContractV0Getters; +use dpp::state_transition::documents_batch_transition::document_base_transition::v0::v0_methods::DocumentBaseTransitionV0Methods; + +use crate::{ + buffer::Buffer, + document::state_transition::document_batch_transition::document_transition::to_object, + identifier::IdentifierWrapper, + lodash::lodash_set, + utils::{ToSerdeJSONExt, WithJsError}, + BinaryType, DataContractWasm, +}; +use dpp::state_transition::documents_batch_transition::document_transition::action_type::DocumentTransitionActionType; +use dpp::state_transition::documents_batch_transition::document_transition::document_transfer_transition::v0::v0_methods::DocumentTransferTransitionV0Methods; +use dpp::state_transition::documents_batch_transition::document_transition::DocumentTransferTransition; + +#[wasm_bindgen(js_name=DocumentTransferTransition)] +#[derive(Debug, Clone)] +pub struct DocumentTransferTransitionWasm { + inner: DocumentTransferTransition, +} + +impl From for DocumentTransferTransitionWasm { + fn from(v: DocumentTransferTransition) -> Self { + Self { inner: v } + } +} + +impl From for DocumentTransferTransition { + fn from(v: DocumentTransferTransitionWasm) -> Self { + v.inner + } +} + +#[wasm_bindgen(js_class=DocumentTransferTransition)] +impl DocumentTransferTransitionWasm { + // #[wasm_bindgen(constructor)] + // pub fn from_object( + // raw_object: JsValue, + // data_contract: &DataContractWasm, + // ) -> Result { + // let mut value = raw_object.with_serde_to_platform_value_map()?; + // let document_type_name = value + // .get_string(dpp::document::extended_document::property_names::DOCUMENT_TYPE_NAME) + // .map_err(ProtocolError::ValueError) + // .with_js_error()?; + // + // let document_type = data_contract + // .inner() + // .document_type_for_name(&document_type_name) + // .with_js_error()?; + // let identifier_paths = document_type.identifier_paths(); + // let binary_paths = document_type.binary_paths(); + // + // value + // .replace_at_paths(identifier_paths, ReplacementType::Identifier) + // .map_err(ProtocolError::ValueError) + // .with_js_error()?; + // + // value + // .replace_at_paths(binary_paths, ReplacementType::BinaryBytes) + // .map_err(ProtocolError::ValueError) + // .with_js_error()?; + // let transition = + // DocumentTransferTransition::from_value_map(value, data_contract).with_js_error()?; + // + // Ok(transition.into()) + // } + // + // #[wasm_bindgen(js_name=getAction)] + // pub fn action(&self) -> u8 { + // DocumentTransitionActionType::Transfer as u8; + // } + // + // #[wasm_bindgen(js_name=getRevision)] + // pub fn revision(&self) -> Revision { + // self.inner.revision() + // } + // + // #[wasm_bindgen(js_name=getUpdatedAt)] + // pub fn updated_at(&self) -> Option { + // self.inner + // .updated_at() + // .map(|timestamp| js_sys::Date::new(&JsValue::from_f64(timestamp as f64))) + // } + // + // #[wasm_bindgen(js_name=toObject)] + // pub fn to_object( + // &self, + // options: &JsValue, + // data_contract: DataContractWasm, + // ) -> Result { + // let document_type = data_contract + // .inner() + // .document_type_for_name(self.inner.base().document_type_name()) + // .with_js_error()?; + // let identifier_paths = document_type.identifier_paths(); + // let binary_paths = document_type.binary_paths(); + // + // to_object( + // self.inner.to_object().with_js_error()?, + // options, + // identifier_paths + // .into_iter() + // .chain(document_transfer_transition::v0::IDENTIFIER_FIELDS), + // binary_paths, + // ) + // } + // + // #[wasm_bindgen(js_name=toJSON)] + // pub fn to_json(&self) -> Result { + // let value = self.inner.to_json().with_js_error()?; + // let serializer = serde_wasm_bindgen::Serializer::json_compatible(); + // let js_value = value.serialize(&serializer)?; + // Ok(js_value) + // } + // + // // AbstractDataDocumentTransition + // #[wasm_bindgen(js_name=getData)] + // pub fn get_data(&self, data_contract: DataContractWasm) -> Result { + // let data = if let Some(ref data) = self.inner.data() { + // data + // } else { + // return Ok(JsValue::undefined()); + // }; + // + // let js_value = data.serialize(&serde_wasm_bindgen::Serializer::json_compatible())?; + // let document_type = data_contract + // .inner() + // .document_type_for_name(self.inner.base().document_type_name()) + // .with_js_error()?; + // let identifier_paths = document_type.identifier_paths(); + // let binary_paths = document_type.binary_paths(); + // + // for path in identifier_paths { + // let bytes = data + // .get_identifier_bytes_at_path(path) + // .map_err(ProtocolError::ValueError) + // .with_js_error()?; + // let id = >::from( + // Identifier::from_bytes(&bytes).unwrap(), + // ); + // lodash_set(&js_value, path, id.into()); + // } + // for path in binary_paths { + // let bytes = data + // .get_binary_bytes_at_path(path) + // .map_err(ProtocolError::ValueError) + // .with_js_error()?; + // let buffer = Buffer::from_bytes(&bytes); + // lodash_set(&js_value, path, buffer.into()); + // } + // + // Ok(js_value) + // } + // + // // AbstractDocumentTransition + // #[wasm_bindgen(js_name=getId)] + // pub fn id(&self) -> IdentifierWrapper { + // self.inner.base().id().into() + // } + // + // #[wasm_bindgen(js_name=getType)] + // pub fn document_type(&self) -> String { + // self.inner.base().document_type_name().clone() + // } + // + // #[wasm_bindgen(js_name=getDataContractId)] + // pub fn data_contract_id(&self) -> IdentifierWrapper { + // self.inner.base().data_contract_id().into() + // } + // + // #[wasm_bindgen(js_name=get)] + // pub fn get(&self, path: String) -> Result { + // let document_data = if let Some(ref data) = self.inner.data() { + // data + // } else { + // return Ok(JsValue::undefined()); + // }; + // + // let value = if let Ok(value) = document_data.get_at_path(&path) { + // value.to_owned() + // } else { + // return Ok(JsValue::undefined()); + // }; + // + // match self.get_binary_type_of_path(&path) { + // BinaryType::Buffer => { + // let bytes: Vec = serde_json::from_value( + // value + // .try_into() + // .map_err(ProtocolError::ValueError) + // .with_js_error()?, + // ) + // .unwrap(); + // let buffer = Buffer::from_bytes(&bytes); + // return Ok(buffer.into()); + // } + // BinaryType::Identifier => { + // let bytes: Vec = serde_json::from_value( + // value + // .try_into() + // .map_err(ProtocolError::ValueError) + // .with_js_error()?, + // ) + // .unwrap(); + // let id = >::from( + // Identifier::from_bytes(&bytes).unwrap(), + // ); + // return Ok(id.into()); + // } + // BinaryType::None => { + // // Do nothing. If is 'None' it means that binary may contain binary data + // // or may not captain it at all + // } + // } + // + // let json_value: JsonValue = value + // .clone() + // .try_into() + // .map_err(ProtocolError::ValueError) + // .with_js_error()?; + // let map = value + // .to_btree_ref_string_map() + // .map_err(ProtocolError::ValueError) + // .with_js_error()?; + // let js_value = json_value.serialize(&serde_wasm_bindgen::Serializer::json_compatible())?; + // let (identifier_paths, binary_paths) = self + // .inner + // .base() + // .data_contract() + // .get_identifiers_and_binary_paths(&self.inner.base().document_type_name()) + // .with_js_error()?; + // + // for property_path in identifier_paths { + // if property_path.starts_with(&path) { + // let (_, suffix) = property_path.split_at(path.len() + 1); + // + // if let Some(bytes) = map + // .get_optional_bytes_at_path(suffix) + // .map_err(ProtocolError::ValueError) + // .with_js_error()? + // { + // let id = >::from( + // Identifier::from_bytes(&bytes).unwrap(), + // ); + // lodash_set(&js_value, suffix, id.into()); + // } + // } + // } + // + // for property_path in binary_paths { + // if property_path.starts_with(&path) { + // let (_, suffix) = property_path.split_at(path.len() + 1); + // + // if let Some(bytes) = map + // .get_optional_bytes_at_path(suffix) + // .map_err(ProtocolError::ValueError) + // .with_js_error()? + // { + // let buffer = Buffer::from_bytes(&bytes); + // lodash_set(&js_value, suffix, buffer.into()); + // } + // } + // } + // + // Ok(js_value) + // } +} + +impl DocumentTransferTransitionWasm { + // fn get_binary_type_of_path(&self, path: &String) -> BinaryType { + // let maybe_binary_properties = self + // .inner + // .get_binary_properties(&self.inner.base().document_type_name()); + // + // if let Ok(binary_properties) = maybe_binary_properties { + // if let Some(data) = binary_properties.get(path) { + // if data.is_type_of_identifier() { + // return BinaryType::Identifier; + // } + // return BinaryType::Buffer; + // } + // } + // BinaryType::None + // } +} diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/mod.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/mod.rs index a26d579d7de..36199f0fb0c 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/mod.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/mod.rs @@ -1,4 +1,5 @@ mod document_create_transition; +mod document_transfer_transition; // mod document_delete_transition; // mod document_replace_transition; From d3383a19b3de297ae349267b01861a40b77c4847 Mon Sep 17 00:00:00 2001 From: pshenmic Date: Sat, 5 Oct 2024 23:46:30 +0700 Subject: [PATCH 02/31] feat(js-dash-sk): add transfer to document broadcast --- .../src/SDK/Client/Platform/methods/documents/broadcast.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/broadcast.ts b/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/broadcast.ts index 4bbe6b6479d..10031938e11 100644 --- a/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/broadcast.ts +++ b/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/broadcast.ts @@ -18,7 +18,8 @@ export default async function broadcast( documents: { create?: ExtendedDocument[], replace?: ExtendedDocument[], - delete?: ExtendedDocument[] + delete?: ExtendedDocument[], + transfer?: ExtendedDocument[] }, identity: any, ): Promise { @@ -26,6 +27,7 @@ export default async function broadcast( create: documents.create?.length || 0, replace: documents.replace?.length || 0, delete: documents.delete?.length || 0, + transfer: documents.transfer?.length || 0, }); await this.initialize(); @@ -36,6 +38,7 @@ export default async function broadcast( ...(documents.create || []), ...(documents.replace || []), ...(documents.delete || []), + ...(documents.transfer || []), ][0]?.getDataContractId(); if (!dataContractId) { @@ -79,6 +82,7 @@ export default async function broadcast( create: documents.create?.length || 0, replace: documents.replace?.length || 0, delete: documents.delete?.length || 0, + transfer: documents.transfer?.length || 0, }); return documentsBatchTransition; From fae59153a23d6bdc483b8d7bea72eef59dea01e2 Mon Sep 17 00:00:00 2001 From: pshenmic Date: Sat, 5 Oct 2024 23:59:01 +0700 Subject: [PATCH 03/31] fix(dpp): add missing import --- packages/rs-dpp/src/document/document_factory/v0/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/rs-dpp/src/document/document_factory/v0/mod.rs b/packages/rs-dpp/src/document/document_factory/v0/mod.rs index 5aa64b775a3..68be2142af8 100644 --- a/packages/rs-dpp/src/document/document_factory/v0/mod.rs +++ b/packages/rs-dpp/src/document/document_factory/v0/mod.rs @@ -32,6 +32,7 @@ use crate::state_transition::documents_batch_transition::{ DocumentsBatchTransition, DocumentsBatchTransitionV0, }; use itertools::Itertools; +use crate::state_transition::documents_batch_transition::document_transition::DocumentTransferTransition; const PROPERTY_FEATURE_VERSION: &str = "$version"; const PROPERTY_ENTROPY: &str = "$entropy"; From fd48355ff013ca72b8cfa2b126733eeefb515ee8 Mon Sep 17 00:00:00 2001 From: pshenmic Date: Sun, 6 Oct 2024 00:01:16 +0700 Subject: [PATCH 04/31] feat(js-dash-sdk): add transfer function wip --- .../src/SDK/Client/Platform/Platform.ts | 3 ++ .../Platform/methods/documents/transfer.ts | 40 +++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/transfer.ts diff --git a/packages/js-dash-sdk/src/SDK/Client/Platform/Platform.ts b/packages/js-dash-sdk/src/SDK/Client/Platform/Platform.ts index 873fe62c53d..cd105ed87b7 100644 --- a/packages/js-dash-sdk/src/SDK/Client/Platform/Platform.ts +++ b/packages/js-dash-sdk/src/SDK/Client/Platform/Platform.ts @@ -9,6 +9,7 @@ import createAssetLockTransaction from './createAssetLockTransaction'; import broadcastDocument from './methods/documents/broadcast'; import createDocument from './methods/documents/create'; +import transferDocument from './methods/documents/transfer'; import getDocument from './methods/documents/get'; import publishContract from './methods/contracts/publish'; @@ -58,6 +59,7 @@ export interface PlatformOpts { interface Records { broadcast: Function, create: Function, + transfer: Function, get: Function, } @@ -165,6 +167,7 @@ export class Platform { this.documents = { broadcast: broadcastDocument.bind(this), create: createDocument.bind(this), + transfer: transferDocument.bind(this), get: getDocument.bind(this), }; this.contracts = { diff --git a/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/transfer.ts b/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/transfer.ts new file mode 100644 index 00000000000..0e27ce2bb6e --- /dev/null +++ b/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/transfer.ts @@ -0,0 +1,40 @@ +import { Platform } from '../../Platform'; +import broadcastStateTransition from '../../broadcastStateTransition'; + +/** + * Transfer document in the platform + * + * @param {Platform} this - bound instance class + * @param {string} typeLocator - type locator + * @param identity - identity + * @param {Object} [data] - options + */ +export async function transfer( + this: Platform, + documentId: string, + identity: any, +): Promise { + this.logger.debug(`[Document#transfer] Transfer document`); + await this.initialize(); + + const { dpp } = this; + + const document = await this.documents.get(documentId); + + this.logger.silly(`[Document#create] Obtained document ${document.getId()}`); + + if (document === null) { + throw new Error(`Document ${documentId} not found. Ensure contractId ${documentId} is correct.`); + } + + document.setOwnerId(identity); + + const transition = dpp.document.createStateTransition( + { transfer: [document] }, + identity.getId(), + ); + + await broadcastStateTransition(this, transition); +} + +export default transfer; From fbe5dbcc47dec94826ff2fa322fc732a5a0f5ef5 Mon Sep 17 00:00:00 2001 From: pshenmic Date: Wed, 25 Dec 2024 00:21:50 +0700 Subject: [PATCH 05/31] feat(js-sdk): implement working document transfers --- .../Platform/methods/documents/broadcast.ts | 9 ++--- .../Platform/methods/documents/transfer.ts | 32 +++++++---------- .../src/document/document_factory/v0/mod.rs | 20 +++++++++-- .../specialized_document_factory/v0/mod.rs | 17 +++++++-- .../documents_batch/transformer/v0/mod.rs | 2 +- .../src/document/extended_document.rs | 36 ++++++++++++++++--- .../document_transfer_transition.rs | 28 +-------------- 7 files changed, 83 insertions(+), 61 deletions(-) diff --git a/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/broadcast.ts b/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/broadcast.ts index 10031938e11..fdcd18d51d2 100644 --- a/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/broadcast.ts +++ b/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/broadcast.ts @@ -6,12 +6,12 @@ import { signStateTransition } from '../../signStateTransition'; /** * Broadcast document onto the platform * - * @param {Platform} this - bound instance class * @param {Object} documents * @param {ExtendedDocument[]} [documents.create] * @param {ExtendedDocument[]} [documents.replace] * @param {ExtendedDocument[]} [documents.delete] * @param identity - identity + * @param keyIndex - identity key index */ export default async function broadcast( this: Platform, @@ -19,15 +19,14 @@ export default async function broadcast( create?: ExtendedDocument[], replace?: ExtendedDocument[], delete?: ExtendedDocument[], - transfer?: ExtendedDocument[] }, identity: any, + keyIndex : number, ): Promise { this.logger.debug('[Document#broadcast] Broadcast documents', { create: documents.create?.length || 0, replace: documents.replace?.length || 0, delete: documents.delete?.length || 0, - transfer: documents.transfer?.length || 0, }); await this.initialize(); @@ -38,7 +37,6 @@ export default async function broadcast( ...(documents.create || []), ...(documents.replace || []), ...(documents.delete || []), - ...(documents.transfer || []), ][0]?.getDataContractId(); if (!dataContractId) { @@ -56,7 +54,7 @@ export default async function broadcast( this.logger.silly('[Document#broadcast] Created documents batch transition'); - await signStateTransition(this, documentsBatchTransition, identity, 1); + await signStateTransition(this, documentsBatchTransition, identity, keyIndex ?? 1); // Broadcast state transition also wait for the result to be obtained await broadcastStateTransition(this, documentsBatchTransition); @@ -82,7 +80,6 @@ export default async function broadcast( create: documents.create?.length || 0, replace: documents.replace?.length || 0, delete: documents.delete?.length || 0, - transfer: documents.transfer?.length || 0, }); return documentsBatchTransition; diff --git a/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/transfer.ts b/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/transfer.ts index 0e27ce2bb6e..43ccb1b39a7 100644 --- a/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/transfer.ts +++ b/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/transfer.ts @@ -1,6 +1,7 @@ +import { Identity, ExtendedDocument } from '@dashevo/wasm-dpp'; import { Platform } from '../../Platform'; import broadcastStateTransition from '../../broadcastStateTransition'; - +import { signStateTransition } from '../../signStateTransition'; /** * Transfer document in the platform * @@ -8,33 +9,26 @@ import broadcastStateTransition from '../../broadcastStateTransition'; * @param {string} typeLocator - type locator * @param identity - identity * @param {Object} [data] - options + * @returns {StateTransition} */ export async function transfer( this: Platform, - documentId: string, - identity: any, + document: ExtendedDocument, + receiver: Identity, + sender: Identity, ): Promise { - this.logger.debug(`[Document#transfer] Transfer document`); + this.logger.debug('[Document#transfer] Transfer document'); await this.initialize(); - const { dpp } = this; - - const document = await this.documents.get(documentId); - - this.logger.silly(`[Document#create] Obtained document ${document.getId()}`); - - if (document === null) { - throw new Error(`Document ${documentId} not found. Ensure contractId ${documentId} is correct.`); - } + const identityContractNonce = await this.nonceManager + .bumpIdentityContractNonce(sender.getId(), document.getDataContractId()); - document.setOwnerId(identity); + const documentsBatchTransition = document + .createTransferTransition(receiver.getId(), BigInt(identityContractNonce)); - const transition = dpp.document.createStateTransition( - { transfer: [document] }, - identity.getId(), - ); + await signStateTransition(this, documentsBatchTransition, sender, 1); - await broadcastStateTransition(this, transition); + await broadcastStateTransition(this, documentsBatchTransition); } export default transfer; diff --git a/packages/rs-dpp/src/document/document_factory/v0/mod.rs b/packages/rs-dpp/src/document/document_factory/v0/mod.rs index 68be2142af8..0280286f346 100644 --- a/packages/rs-dpp/src/document/document_factory/v0/mod.rs +++ b/packages/rs-dpp/src/document/document_factory/v0/mod.rs @@ -263,9 +263,25 @@ impl DocumentFactoryV0 { nonce_counter, platform_version, ), - _ => Err(ProtocolError::InvalidStateTransitionType( - "action type not accounted for".to_string(), + DocumentTransitionActionType::Transfer => Self::document_transfer_transitions( + documents + .into_iter() + .map(|(document, document_type, _)| (document, document_type)) + .collect(), + nonce_counter, + platform_version, + ), + DocumentTransitionActionType::Purchase => { + Err(ProtocolError::InvalidStateTransitionType( + "action type not accounted for Transfer".to_string(), + )) + } + DocumentTransitionActionType::UpdatePrice => Err(ProtocolError::InvalidStateTransitionType( + "action type not accounted for UpdatePrice".to_string(), )), + DocumentTransitionActionType::IgnoreWhileBumpingRevision => Err(ProtocolError::InvalidStateTransitionType( + "action type not accounted for IgnoreWhileBumpingRevision".to_string(), + )) }) .collect::, ProtocolError>>()? .into_iter() diff --git a/packages/rs-dpp/src/document/specialized_document_factory/v0/mod.rs b/packages/rs-dpp/src/document/specialized_document_factory/v0/mod.rs index e482d3822a7..56193af6ad8 100644 --- a/packages/rs-dpp/src/document/specialized_document_factory/v0/mod.rs +++ b/packages/rs-dpp/src/document/specialized_document_factory/v0/mod.rs @@ -270,9 +270,22 @@ impl SpecializedDocumentFactoryV0 { nonce_counter, platform_version, ), - _ => Err(ProtocolError::InvalidStateTransitionType( - "action type not accounted for".to_string(), + DocumentTransitionActionType::Transfer => { + Err(ProtocolError::InvalidStateTransitionType( + "action type not accounted for Transfer".to_string(), + )) + }, + DocumentTransitionActionType::Purchase => { + Err(ProtocolError::InvalidStateTransitionType( + "action type not accounted for Purchase".to_string(), + )) + } + DocumentTransitionActionType::UpdatePrice => Err(ProtocolError::InvalidStateTransitionType( + "action type not accounted for UpdatePrice".to_string(), )), + DocumentTransitionActionType::IgnoreWhileBumpingRevision => Err(ProtocolError::InvalidStateTransitionType( + "action type not accounted for IgnoreWhileBumpingRevision".to_string(), + )) }) .collect::, ProtocolError>>()? .into_iter() diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/transformer/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/transformer/v0/mod.rs index 68ec4de478e..1de6aa765cd 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/transformer/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/transformer/v0/mod.rs @@ -720,7 +720,7 @@ impl DocumentsBatchTransitionInternalTransformerV0 for DocumentsBatchTransition StateError::InvalidDocumentRevisionError(InvalidDocumentRevisionError::new( document_id, Some(previous_revision), - transition_revision, + expected_revision, )), )) } diff --git a/packages/wasm-dpp/src/document/extended_document.rs b/packages/wasm-dpp/src/document/extended_document.rs index 08d81ff81cd..cc321418b72 100644 --- a/packages/wasm-dpp/src/document/extended_document.rs +++ b/packages/wasm-dpp/src/document/extended_document.rs @@ -1,10 +1,8 @@ -use dpp::document::{ - DocumentV0Getters, DocumentV0Setters, ExtendedDocument, EXTENDED_DOCUMENT_IDENTIFIER_FIELDS, -}; +use dpp::document::{DocumentV0Getters, DocumentV0Setters, ExtendedDocument, EXTENDED_DOCUMENT_IDENTIFIER_FIELDS}; use serde_json::Value as JsonValue; use dpp::platform_value::{Bytes32, Value}; -use dpp::prelude::{Identifier, Revision, TimestampMillis}; +use dpp::prelude::{Identifier, IdentityNonce, Revision, TimestampMillis, UserFeeIncrease}; use dpp::util::json_value::JsonValueExt; @@ -16,12 +14,15 @@ use dpp::ProtocolError; use serde::{Deserialize, Serialize}; use std::convert::TryInto; use wasm_bindgen::prelude::*; +use dpp::state_transition::documents_batch_transition::document_transition::DocumentTransferTransition; +use dpp::state_transition::documents_batch_transition::{DocumentsBatchTransition, DocumentsBatchTransitionV0}; use crate::buffer::Buffer; use crate::data_contract::DataContractWasm; #[allow(deprecated)] // BinaryType is unsed in unused code below use crate::document::BinaryType; use crate::document::{ConversionOptions, DocumentWasm}; +use crate::document_batch_transition::DocumentsBatchTransitionWasm; use crate::errors::RustConversionError; use crate::identifier::{identifier_from_js_value, IdentifierWrapper}; use crate::lodash::lodash_set; @@ -235,6 +236,33 @@ impl ExtendedDocumentWasm { .set_created_at(ts.map(|t| t.get_time() as TimestampMillis)); } + #[wasm_bindgen(js_name=createTransferTransition)] + pub fn create_transfer_transition(&mut self, recipient: IdentifierWrapper, identity_contract_nonce: IdentityNonce) -> DocumentsBatchTransitionWasm { + let mut cloned_document = self.0.document().clone(); + + cloned_document.set_revision(Some(cloned_document.revision().unwrap() + 1)); + + let transfer_transition = DocumentTransferTransition::from_document( + cloned_document, + self.0.document_type().unwrap(), + identity_contract_nonce, + recipient.try_into().expect("identity into failed"), + PlatformVersion::latest(), + None, + None, + ).unwrap(); + + let documents_batch_transition: DocumentsBatchTransition = DocumentsBatchTransitionV0 { + owner_id: self.0.owner_id(), + transitions: vec![transfer_transition.into()], + user_fee_increase: Default::default(), + signature_public_key_id: Default::default(), + signature: Default::default(), + }.try_into().expect("Failed to convert into DocumentsBatchTransition"); + + documents_batch_transition.try_into().expect("Failed to convert into DocumentsBatchTransitionWasm") + } + #[wasm_bindgen(js_name=setUpdatedAt)] pub fn set_updated_at(&mut self, ts: Option) { self.0 diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_transfer_transition.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_transfer_transition.rs index b6e9cdfba7e..0ebbf8e508c 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_transfer_transition.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_transfer_transition.rs @@ -1,30 +1,4 @@ -use std::convert; - -use serde_json::Value as JsonValue; - -use dpp::platform_value::btreemap_extensions::{ - BTreeValueMapHelper, BTreeValueMapReplacementPathHelper, -}; -use dpp::platform_value::ReplacementType; -use dpp::prelude::Revision; -use dpp::{ - prelude::{Identifier}, - ProtocolError, -}; -use wasm_bindgen::prelude::*; -use dpp::data_contract::accessors::v0::DataContractV0Getters; -use dpp::state_transition::documents_batch_transition::document_base_transition::v0::v0_methods::DocumentBaseTransitionV0Methods; - -use crate::{ - buffer::Buffer, - document::state_transition::document_batch_transition::document_transition::to_object, - identifier::IdentifierWrapper, - lodash::lodash_set, - utils::{ToSerdeJSONExt, WithJsError}, - BinaryType, DataContractWasm, -}; -use dpp::state_transition::documents_batch_transition::document_transition::action_type::DocumentTransitionActionType; -use dpp::state_transition::documents_batch_transition::document_transition::document_transfer_transition::v0::v0_methods::DocumentTransferTransitionV0Methods; +use wasm_bindgen::prelude::wasm_bindgen; use dpp::state_transition::documents_batch_transition::document_transition::DocumentTransferTransition; #[wasm_bindgen(js_name=DocumentTransferTransition)] From 8f79b69a9d12d20098a819aea0e157fbd7a3914c Mon Sep 17 00:00:00 2001 From: pshenmic Date: Wed, 25 Dec 2024 00:28:32 +0700 Subject: [PATCH 06/31] chore(js-sdk): cleanup --- packages/wasm-dpp/src/document/extended_document.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/wasm-dpp/src/document/extended_document.rs b/packages/wasm-dpp/src/document/extended_document.rs index cc321418b72..92f7e164e07 100644 --- a/packages/wasm-dpp/src/document/extended_document.rs +++ b/packages/wasm-dpp/src/document/extended_document.rs @@ -236,8 +236,8 @@ impl ExtendedDocumentWasm { .set_created_at(ts.map(|t| t.get_time() as TimestampMillis)); } - #[wasm_bindgen(js_name=createTransferTransition)] - pub fn create_transfer_transition(&mut self, recipient: IdentifierWrapper, identity_contract_nonce: IdentityNonce) -> DocumentsBatchTransitionWasm { + #[wasm_bindgen(js_name=createTransferStateTransition)] + pub fn create_transfer_state_transition(&mut self, recipient: IdentifierWrapper, identity_contract_nonce: IdentityNonce) -> DocumentsBatchTransitionWasm { let mut cloned_document = self.0.document().clone(); cloned_document.set_revision(Some(cloned_document.revision().unwrap() + 1)); @@ -246,7 +246,7 @@ impl ExtendedDocumentWasm { cloned_document, self.0.document_type().unwrap(), identity_contract_nonce, - recipient.try_into().expect("identity into failed"), + recipient.into(), PlatformVersion::latest(), None, None, @@ -258,9 +258,9 @@ impl ExtendedDocumentWasm { user_fee_increase: Default::default(), signature_public_key_id: Default::default(), signature: Default::default(), - }.try_into().expect("Failed to convert into DocumentsBatchTransition"); + }.into(); - documents_batch_transition.try_into().expect("Failed to convert into DocumentsBatchTransitionWasm") + documents_batch_transition.into() } #[wasm_bindgen(js_name=setUpdatedAt)] From 9925a685cdf8be3d64db9d3033393be9104af8c5 Mon Sep 17 00:00:00 2001 From: pshenmic Date: Wed, 25 Dec 2024 00:48:47 +0700 Subject: [PATCH 07/31] chore(js-sdk): cleanup --- .../src/SDK/Client/Platform/methods/documents/broadcast.ts | 5 ++--- .../src/SDK/Client/Platform/methods/documents/transfer.ts | 5 +++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/broadcast.ts b/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/broadcast.ts index fdcd18d51d2..e01cf3e2174 100644 --- a/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/broadcast.ts +++ b/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/broadcast.ts @@ -6,12 +6,12 @@ import { signStateTransition } from '../../signStateTransition'; /** * Broadcast document onto the platform * + * @param {Platform} this - bound instance class * @param {Object} documents * @param {ExtendedDocument[]} [documents.create] * @param {ExtendedDocument[]} [documents.replace] * @param {ExtendedDocument[]} [documents.delete] * @param identity - identity - * @param keyIndex - identity key index */ export default async function broadcast( this: Platform, @@ -21,7 +21,6 @@ export default async function broadcast( delete?: ExtendedDocument[], }, identity: any, - keyIndex : number, ): Promise { this.logger.debug('[Document#broadcast] Broadcast documents', { create: documents.create?.length || 0, @@ -54,7 +53,7 @@ export default async function broadcast( this.logger.silly('[Document#broadcast] Created documents batch transition'); - await signStateTransition(this, documentsBatchTransition, identity, keyIndex ?? 1); + await signStateTransition(this, documentsBatchTransition, identity, 1); // Broadcast state transition also wait for the result to be obtained await broadcastStateTransition(this, documentsBatchTransition); diff --git a/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/transfer.ts b/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/transfer.ts index 43ccb1b39a7..31fa427d113 100644 --- a/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/transfer.ts +++ b/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/transfer.ts @@ -17,14 +17,15 @@ export async function transfer( receiver: Identity, sender: Identity, ): Promise { - this.logger.debug('[Document#transfer] Transfer document'); + this.logger.debug(`[Document#transfer] Transfer document ${document.getId().toString()} + from ${sender.getId().toString} to {${receiver.getId().toString()}`); await this.initialize(); const identityContractNonce = await this.nonceManager .bumpIdentityContractNonce(sender.getId(), document.getDataContractId()); const documentsBatchTransition = document - .createTransferTransition(receiver.getId(), BigInt(identityContractNonce)); + .createTransferStateTransition(receiver.getId(), BigInt(identityContractNonce)); await signStateTransition(this, documentsBatchTransition, sender, 1); From e8defe89aebe2271824af6ca1d02c9cbbb9dd791 Mon Sep 17 00:00:00 2001 From: pshenmic Date: Wed, 25 Dec 2024 00:49:10 +0700 Subject: [PATCH 08/31] chore(wasm-dpp): cleanup --- .../src/document/document_factory/v0/mod.rs | 107 +------- .../specialized_document_factory/v0/mod.rs | 17 +- packages/wasm-dpp/src/document/factory.rs | 8 - .../document_transfer_transition.rs | 247 ------------------ 4 files changed, 4 insertions(+), 375 deletions(-) diff --git a/packages/rs-dpp/src/document/document_factory/v0/mod.rs b/packages/rs-dpp/src/document/document_factory/v0/mod.rs index 0280286f346..6dc531398c7 100644 --- a/packages/rs-dpp/src/document/document_factory/v0/mod.rs +++ b/packages/rs-dpp/src/document/document_factory/v0/mod.rs @@ -263,25 +263,9 @@ impl DocumentFactoryV0 { nonce_counter, platform_version, ), - DocumentTransitionActionType::Transfer => Self::document_transfer_transitions( - documents - .into_iter() - .map(|(document, document_type, _)| (document, document_type)) - .collect(), - nonce_counter, - platform_version, - ), - DocumentTransitionActionType::Purchase => { - Err(ProtocolError::InvalidStateTransitionType( - "action type not accounted for Transfer".to_string(), - )) - } - DocumentTransitionActionType::UpdatePrice => Err(ProtocolError::InvalidStateTransitionType( - "action type not accounted for UpdatePrice".to_string(), + _ => Err(ProtocolError::InvalidStateTransitionType( + "action type not accounted for".to_string(), )), - DocumentTransitionActionType::IgnoreWhileBumpingRevision => Err(ProtocolError::InvalidStateTransitionType( - "action type not accounted for IgnoreWhileBumpingRevision".to_string(), - )) }) .collect::, ProtocolError>>()? .into_iter() @@ -524,93 +508,6 @@ impl DocumentFactoryV0 { // Ok(raw_transitions) } - #[cfg(feature = "state-transitions")] - fn document_transfer_transitions( - documents: Vec<(Document, DocumentTypeRef)>, - nonce_counter: &mut BTreeMap<(Identifier, Identifier), u64>, //IdentityID/ContractID -> nonce - platform_version: &PlatformVersion, - ) -> Result, ProtocolError> { - documents - .into_iter() - .map(|(mut document, document_type)| { - if !document_type.documents_mutable() { - return Err(DocumentError::TryingToReplaceImmutableDocument { - document: Box::new(document), - } - .into()); - } - if document.revision().is_none() { - return Err(DocumentError::RevisionAbsentError { - document: Box::new(document), - } - .into()); - }; - - document.increment_revision()?; - document.set_updated_at(Some(Utc::now().timestamp_millis() as TimestampMillis)); - - let recipient_owner_id = document.owner_id(); - - let nonce = nonce_counter - .entry((document.owner_id(), document_type.data_contract_id())) - .or_default(); - - let transition = DocumentTransferTransition::from_document( - document, - document_type, - *nonce, - recipient_owner_id, - platform_version, - None, - None, - )?; - - *nonce += 1; - - Ok(transition.into()) - }) - .collect() - // let mut raw_transitions = vec![]; - // for (document, document_type) in documents { - // if !document_type.documents_mutable() { - // return Err(DocumentError::TryingToReplaceImmutableDocument { - // document: Box::new(document), - // } - // .into()); - // } - // let Some(document_revision) = document.revision() else { - // return Err(DocumentError::RevisionAbsentError { - // document: Box::new(document), - // }.into()); - // }; - // let mut map = document.to_map_value()?; - // - // map.retain(|key, _| { - // !key.starts_with('$') || DOCUMENT_REPLACE_KEYS_TO_STAY.contains(&key.as_str()) - // }); - // map.insert( - // PROPERTY_ACTION.to_string(), - // Value::U8(DocumentTransitionActionType::Replace as u8), - // ); - // let new_revision = document_revision + 1; - // map.insert(PROPERTY_REVISION.to_string(), Value::U64(new_revision)); - // - // // If document have an originally set `updatedAt` - // // we should update it then - // let contains_updated_at = document_type - // .required_fields() - // .contains(PROPERTY_UPDATED_AT); - // - // if contains_updated_at { - // let now = Utc::now().timestamp_millis() as TimestampMillis; - // map.insert(PROPERTY_UPDATED_AT.to_string(), Value::U64(now)); - // } - // - // raw_transitions.push(map.into()); - // } - // Ok(raw_transitions) - } - #[cfg(feature = "state-transitions")] fn document_delete_transitions( documents: Vec<(Document, DocumentTypeRef)>, diff --git a/packages/rs-dpp/src/document/specialized_document_factory/v0/mod.rs b/packages/rs-dpp/src/document/specialized_document_factory/v0/mod.rs index 56193af6ad8..e482d3822a7 100644 --- a/packages/rs-dpp/src/document/specialized_document_factory/v0/mod.rs +++ b/packages/rs-dpp/src/document/specialized_document_factory/v0/mod.rs @@ -270,22 +270,9 @@ impl SpecializedDocumentFactoryV0 { nonce_counter, platform_version, ), - DocumentTransitionActionType::Transfer => { - Err(ProtocolError::InvalidStateTransitionType( - "action type not accounted for Transfer".to_string(), - )) - }, - DocumentTransitionActionType::Purchase => { - Err(ProtocolError::InvalidStateTransitionType( - "action type not accounted for Purchase".to_string(), - )) - } - DocumentTransitionActionType::UpdatePrice => Err(ProtocolError::InvalidStateTransitionType( - "action type not accounted for UpdatePrice".to_string(), + _ => Err(ProtocolError::InvalidStateTransitionType( + "action type not accounted for".to_string(), )), - DocumentTransitionActionType::IgnoreWhileBumpingRevision => Err(ProtocolError::InvalidStateTransitionType( - "action type not accounted for IgnoreWhileBumpingRevision".to_string(), - )) }) .collect::, ProtocolError>>()? .into_iter() diff --git a/packages/wasm-dpp/src/document/factory.rs b/packages/wasm-dpp/src/document/factory.rs index 038fb8db998..0b927a60803 100644 --- a/packages/wasm-dpp/src/document/factory.rs +++ b/packages/wasm-dpp/src/document/factory.rs @@ -32,7 +32,6 @@ pub struct DocumentTransitions { create: Vec, replace: Vec, delete: Vec, - transfer: Vec, } #[wasm_bindgen(js_class=DocumentTransitions)] @@ -56,11 +55,6 @@ impl DocumentTransitions { pub fn add_transition_delete(&mut self, transition: ExtendedDocumentWasm) { self.delete.push(transition) } - - #[wasm_bindgen(js_name = "addTransitionTransfer")] - pub fn add_transition_transfer(&mut self, transition: ExtendedDocumentWasm) { - self.transfer.push(transition) - } } #[wasm_bindgen(js_name = DocumentFactory)] @@ -284,12 +278,10 @@ fn extract_documents_by_action( let documents_create = extract_documents_of_action(documents, "create").with_js_error()?; let documents_replace = extract_documents_of_action(documents, "replace").with_js_error()?; let documents_delete = extract_documents_of_action(documents, "delete").with_js_error()?; - let documents_transfer = extract_documents_of_action(documents, "transfer").with_js_error()?; documents_by_action.insert(DocumentTransitionActionType::Create, documents_create); documents_by_action.insert(DocumentTransitionActionType::Replace, documents_replace); documents_by_action.insert(DocumentTransitionActionType::Delete, documents_delete); - documents_by_action.insert(DocumentTransitionActionType::Transfer, documents_transfer); Ok(documents_by_action) } diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_transfer_transition.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_transfer_transition.rs index 0ebbf8e508c..c9c745d4098 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_transfer_transition.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_transfer_transition.rs @@ -21,254 +21,7 @@ impl From for DocumentTransferTransition { #[wasm_bindgen(js_class=DocumentTransferTransition)] impl DocumentTransferTransitionWasm { - // #[wasm_bindgen(constructor)] - // pub fn from_object( - // raw_object: JsValue, - // data_contract: &DataContractWasm, - // ) -> Result { - // let mut value = raw_object.with_serde_to_platform_value_map()?; - // let document_type_name = value - // .get_string(dpp::document::extended_document::property_names::DOCUMENT_TYPE_NAME) - // .map_err(ProtocolError::ValueError) - // .with_js_error()?; - // - // let document_type = data_contract - // .inner() - // .document_type_for_name(&document_type_name) - // .with_js_error()?; - // let identifier_paths = document_type.identifier_paths(); - // let binary_paths = document_type.binary_paths(); - // - // value - // .replace_at_paths(identifier_paths, ReplacementType::Identifier) - // .map_err(ProtocolError::ValueError) - // .with_js_error()?; - // - // value - // .replace_at_paths(binary_paths, ReplacementType::BinaryBytes) - // .map_err(ProtocolError::ValueError) - // .with_js_error()?; - // let transition = - // DocumentTransferTransition::from_value_map(value, data_contract).with_js_error()?; - // - // Ok(transition.into()) - // } - // - // #[wasm_bindgen(js_name=getAction)] - // pub fn action(&self) -> u8 { - // DocumentTransitionActionType::Transfer as u8; - // } - // - // #[wasm_bindgen(js_name=getRevision)] - // pub fn revision(&self) -> Revision { - // self.inner.revision() - // } - // - // #[wasm_bindgen(js_name=getUpdatedAt)] - // pub fn updated_at(&self) -> Option { - // self.inner - // .updated_at() - // .map(|timestamp| js_sys::Date::new(&JsValue::from_f64(timestamp as f64))) - // } - // - // #[wasm_bindgen(js_name=toObject)] - // pub fn to_object( - // &self, - // options: &JsValue, - // data_contract: DataContractWasm, - // ) -> Result { - // let document_type = data_contract - // .inner() - // .document_type_for_name(self.inner.base().document_type_name()) - // .with_js_error()?; - // let identifier_paths = document_type.identifier_paths(); - // let binary_paths = document_type.binary_paths(); - // - // to_object( - // self.inner.to_object().with_js_error()?, - // options, - // identifier_paths - // .into_iter() - // .chain(document_transfer_transition::v0::IDENTIFIER_FIELDS), - // binary_paths, - // ) - // } - // - // #[wasm_bindgen(js_name=toJSON)] - // pub fn to_json(&self) -> Result { - // let value = self.inner.to_json().with_js_error()?; - // let serializer = serde_wasm_bindgen::Serializer::json_compatible(); - // let js_value = value.serialize(&serializer)?; - // Ok(js_value) - // } - // - // // AbstractDataDocumentTransition - // #[wasm_bindgen(js_name=getData)] - // pub fn get_data(&self, data_contract: DataContractWasm) -> Result { - // let data = if let Some(ref data) = self.inner.data() { - // data - // } else { - // return Ok(JsValue::undefined()); - // }; - // - // let js_value = data.serialize(&serde_wasm_bindgen::Serializer::json_compatible())?; - // let document_type = data_contract - // .inner() - // .document_type_for_name(self.inner.base().document_type_name()) - // .with_js_error()?; - // let identifier_paths = document_type.identifier_paths(); - // let binary_paths = document_type.binary_paths(); - // - // for path in identifier_paths { - // let bytes = data - // .get_identifier_bytes_at_path(path) - // .map_err(ProtocolError::ValueError) - // .with_js_error()?; - // let id = >::from( - // Identifier::from_bytes(&bytes).unwrap(), - // ); - // lodash_set(&js_value, path, id.into()); - // } - // for path in binary_paths { - // let bytes = data - // .get_binary_bytes_at_path(path) - // .map_err(ProtocolError::ValueError) - // .with_js_error()?; - // let buffer = Buffer::from_bytes(&bytes); - // lodash_set(&js_value, path, buffer.into()); - // } - // - // Ok(js_value) - // } - // - // // AbstractDocumentTransition - // #[wasm_bindgen(js_name=getId)] - // pub fn id(&self) -> IdentifierWrapper { - // self.inner.base().id().into() - // } - // - // #[wasm_bindgen(js_name=getType)] - // pub fn document_type(&self) -> String { - // self.inner.base().document_type_name().clone() - // } - // - // #[wasm_bindgen(js_name=getDataContractId)] - // pub fn data_contract_id(&self) -> IdentifierWrapper { - // self.inner.base().data_contract_id().into() - // } - // - // #[wasm_bindgen(js_name=get)] - // pub fn get(&self, path: String) -> Result { - // let document_data = if let Some(ref data) = self.inner.data() { - // data - // } else { - // return Ok(JsValue::undefined()); - // }; - // - // let value = if let Ok(value) = document_data.get_at_path(&path) { - // value.to_owned() - // } else { - // return Ok(JsValue::undefined()); - // }; - // - // match self.get_binary_type_of_path(&path) { - // BinaryType::Buffer => { - // let bytes: Vec = serde_json::from_value( - // value - // .try_into() - // .map_err(ProtocolError::ValueError) - // .with_js_error()?, - // ) - // .unwrap(); - // let buffer = Buffer::from_bytes(&bytes); - // return Ok(buffer.into()); - // } - // BinaryType::Identifier => { - // let bytes: Vec = serde_json::from_value( - // value - // .try_into() - // .map_err(ProtocolError::ValueError) - // .with_js_error()?, - // ) - // .unwrap(); - // let id = >::from( - // Identifier::from_bytes(&bytes).unwrap(), - // ); - // return Ok(id.into()); - // } - // BinaryType::None => { - // // Do nothing. If is 'None' it means that binary may contain binary data - // // or may not captain it at all - // } - // } - // - // let json_value: JsonValue = value - // .clone() - // .try_into() - // .map_err(ProtocolError::ValueError) - // .with_js_error()?; - // let map = value - // .to_btree_ref_string_map() - // .map_err(ProtocolError::ValueError) - // .with_js_error()?; - // let js_value = json_value.serialize(&serde_wasm_bindgen::Serializer::json_compatible())?; - // let (identifier_paths, binary_paths) = self - // .inner - // .base() - // .data_contract() - // .get_identifiers_and_binary_paths(&self.inner.base().document_type_name()) - // .with_js_error()?; - // - // for property_path in identifier_paths { - // if property_path.starts_with(&path) { - // let (_, suffix) = property_path.split_at(path.len() + 1); - // - // if let Some(bytes) = map - // .get_optional_bytes_at_path(suffix) - // .map_err(ProtocolError::ValueError) - // .with_js_error()? - // { - // let id = >::from( - // Identifier::from_bytes(&bytes).unwrap(), - // ); - // lodash_set(&js_value, suffix, id.into()); - // } - // } - // } - // - // for property_path in binary_paths { - // if property_path.starts_with(&path) { - // let (_, suffix) = property_path.split_at(path.len() + 1); - // - // if let Some(bytes) = map - // .get_optional_bytes_at_path(suffix) - // .map_err(ProtocolError::ValueError) - // .with_js_error()? - // { - // let buffer = Buffer::from_bytes(&bytes); - // lodash_set(&js_value, suffix, buffer.into()); - // } - // } - // } - // - // Ok(js_value) - // } } impl DocumentTransferTransitionWasm { - // fn get_binary_type_of_path(&self, path: &String) -> BinaryType { - // let maybe_binary_properties = self - // .inner - // .get_binary_properties(&self.inner.base().document_type_name()); - // - // if let Ok(binary_properties) = maybe_binary_properties { - // if let Some(data) = binary_properties.get(path) { - // if data.is_type_of_identifier() { - // return BinaryType::Identifier; - // } - // return BinaryType::Buffer; - // } - // } - // BinaryType::None - // } } From 1f0f7c697497264d231a35ba947e1ebe378e5913 Mon Sep 17 00:00:00 2001 From: pshenmic Date: Wed, 25 Dec 2024 03:30:02 +0700 Subject: [PATCH 09/31] chore(js-sdk): cleanup --- .../src/SDK/Client/Platform/methods/documents/transfer.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/transfer.ts b/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/transfer.ts index 31fa427d113..6f8f847d096 100644 --- a/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/transfer.ts +++ b/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/transfer.ts @@ -17,8 +17,7 @@ export async function transfer( receiver: Identity, sender: Identity, ): Promise { - this.logger.debug(`[Document#transfer] Transfer document ${document.getId().toString()} - from ${sender.getId().toString} to {${receiver.getId().toString()}`); + this.logger.debug(`[Document#transfer] Transfer document ${document.getId().toString()} from ${sender.getId().toString} to {${receiver.getId().toString()}`); await this.initialize(); const identityContractNonce = await this.nonceManager From 43cc7f1d3d94d1b096a64e27ee488478a7a38dfa Mon Sep 17 00:00:00 2001 From: pshenmic Date: Wed, 25 Dec 2024 03:33:10 +0700 Subject: [PATCH 10/31] chore(js-sdk): revert --- .../src/SDK/Client/Platform/methods/documents/broadcast.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/broadcast.ts b/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/broadcast.ts index e01cf3e2174..eeab6b36fad 100644 --- a/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/broadcast.ts +++ b/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/broadcast.ts @@ -25,7 +25,7 @@ export default async function broadcast( this.logger.debug('[Document#broadcast] Broadcast documents', { create: documents.create?.length || 0, replace: documents.replace?.length || 0, - delete: documents.delete?.length || 0, + delete: documents.delete?.length || 0 }); await this.initialize(); From cf99fe6ca9e7e7bae5bd15912ec5660d53b5841b Mon Sep 17 00:00:00 2001 From: pshenmic Date: Wed, 25 Dec 2024 03:33:51 +0700 Subject: [PATCH 11/31] chore(js-sdk): cleanup --- .../src/SDK/Client/Platform/methods/documents/broadcast.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/broadcast.ts b/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/broadcast.ts index eeab6b36fad..7b6bc0fc1c5 100644 --- a/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/broadcast.ts +++ b/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/broadcast.ts @@ -25,7 +25,7 @@ export default async function broadcast( this.logger.debug('[Document#broadcast] Broadcast documents', { create: documents.create?.length || 0, replace: documents.replace?.length || 0, - delete: documents.delete?.length || 0 + delete: documents.delete?.length || 0, }); await this.initialize(); @@ -35,7 +35,7 @@ export default async function broadcast( const dataContractId = [ ...(documents.create || []), ...(documents.replace || []), - ...(documents.delete || []), + ...(documents.delete || []) ][0]?.getDataContractId(); if (!dataContractId) { From 44df2e63ff64a7194f6bfaba07a6098accc0e77d Mon Sep 17 00:00:00 2001 From: pshenmic Date: Wed, 25 Dec 2024 03:34:14 +0700 Subject: [PATCH 12/31] chore(js-sdk): cleanup --- .../src/SDK/Client/Platform/methods/documents/broadcast.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/broadcast.ts b/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/broadcast.ts index 7b6bc0fc1c5..eeab6b36fad 100644 --- a/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/broadcast.ts +++ b/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/broadcast.ts @@ -25,7 +25,7 @@ export default async function broadcast( this.logger.debug('[Document#broadcast] Broadcast documents', { create: documents.create?.length || 0, replace: documents.replace?.length || 0, - delete: documents.delete?.length || 0, + delete: documents.delete?.length || 0 }); await this.initialize(); @@ -35,7 +35,7 @@ export default async function broadcast( const dataContractId = [ ...(documents.create || []), ...(documents.replace || []), - ...(documents.delete || []) + ...(documents.delete || []), ][0]?.getDataContractId(); if (!dataContractId) { From 5894a7f8fd389edc7eae5159fb84fb900579091a Mon Sep 17 00:00:00 2001 From: pshenmic Date: Wed, 25 Dec 2024 03:35:06 +0700 Subject: [PATCH 13/31] chore(js-sdk): cleanup --- .../src/SDK/Client/Platform/methods/documents/broadcast.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/broadcast.ts b/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/broadcast.ts index eeab6b36fad..4bbe6b6479d 100644 --- a/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/broadcast.ts +++ b/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/broadcast.ts @@ -18,14 +18,14 @@ export default async function broadcast( documents: { create?: ExtendedDocument[], replace?: ExtendedDocument[], - delete?: ExtendedDocument[], + delete?: ExtendedDocument[] }, identity: any, ): Promise { this.logger.debug('[Document#broadcast] Broadcast documents', { create: documents.create?.length || 0, replace: documents.replace?.length || 0, - delete: documents.delete?.length || 0 + delete: documents.delete?.length || 0, }); await this.initialize(); From d7d5d9012afce9c3db683b9c42aea076b22ad916 Mon Sep 17 00:00:00 2001 From: pshenmic Date: Wed, 25 Dec 2024 03:37:10 +0700 Subject: [PATCH 14/31] chore(js-sdk): update doc --- .../src/SDK/Client/Platform/methods/documents/transfer.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/transfer.ts b/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/transfer.ts index 6f8f847d096..e211364b27b 100644 --- a/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/transfer.ts +++ b/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/transfer.ts @@ -6,10 +6,9 @@ import { signStateTransition } from '../../signStateTransition'; * Transfer document in the platform * * @param {Platform} this - bound instance class - * @param {string} typeLocator - type locator - * @param identity - identity - * @param {Object} [data] - options - * @returns {StateTransition} + * @param {ExtendedDocument} document - document from the DAPI + * @param {Identifier} receiver - identifier of the document recipient ownership + * @param {Identifier} sender - identifier of the document owner */ export async function transfer( this: Platform, From 2131f00d9b8b7cdba7a24cf4cffc8070aaede56c Mon Sep 17 00:00:00 2001 From: pshenmic Date: Wed, 25 Dec 2024 03:38:29 +0700 Subject: [PATCH 15/31] chore(wasm-dpp): cleanup --- packages/rs-dpp/src/document/document_factory/v0/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/rs-dpp/src/document/document_factory/v0/mod.rs b/packages/rs-dpp/src/document/document_factory/v0/mod.rs index 6dc531398c7..58fc96de91a 100644 --- a/packages/rs-dpp/src/document/document_factory/v0/mod.rs +++ b/packages/rs-dpp/src/document/document_factory/v0/mod.rs @@ -32,7 +32,6 @@ use crate::state_transition::documents_batch_transition::{ DocumentsBatchTransition, DocumentsBatchTransitionV0, }; use itertools::Itertools; -use crate::state_transition::documents_batch_transition::document_transition::DocumentTransferTransition; const PROPERTY_FEATURE_VERSION: &str = "$version"; const PROPERTY_ENTROPY: &str = "$entropy"; From 9bca0cd753628b2164a4e795e0825bb9b2feb5df Mon Sep 17 00:00:00 2001 From: pshenmic Date: Mon, 20 Jan 2025 18:18:50 +0700 Subject: [PATCH 16/31] feat(wasm-dpp): add nft operations --- .../src/document/extended_document.rs | 86 ++++++++++++++++++- 1 file changed, 85 insertions(+), 1 deletion(-) diff --git a/packages/wasm-dpp/src/document/extended_document.rs b/packages/wasm-dpp/src/document/extended_document.rs index 08d81ff81cd..529e856dae2 100644 --- a/packages/wasm-dpp/src/document/extended_document.rs +++ b/packages/wasm-dpp/src/document/extended_document.rs @@ -4,7 +4,7 @@ use dpp::document::{ use serde_json::Value as JsonValue; use dpp::platform_value::{Bytes32, Value}; -use dpp::prelude::{Identifier, Revision, TimestampMillis}; +use dpp::prelude::{Identifier, IdentityNonce, Revision, TimestampMillis}; use dpp::util::json_value::JsonValueExt; @@ -16,12 +16,15 @@ use dpp::ProtocolError; use serde::{Deserialize, Serialize}; use std::convert::TryInto; use wasm_bindgen::prelude::*; +use dpp::state_transition::documents_batch_transition::document_transition::{DocumentPurchaseTransition, DocumentTransferTransition, DocumentUpdatePriceTransition}; +use dpp::state_transition::documents_batch_transition::{DocumentsBatchTransition, DocumentsBatchTransitionV0}; use crate::buffer::Buffer; use crate::data_contract::DataContractWasm; #[allow(deprecated)] // BinaryType is unsed in unused code below use crate::document::BinaryType; use crate::document::{ConversionOptions, DocumentWasm}; +use crate::document_batch_transition::DocumentsBatchTransitionWasm; use crate::errors::RustConversionError; use crate::identifier::{identifier_from_js_value, IdentifierWrapper}; use crate::lodash::lodash_set; @@ -235,6 +238,87 @@ impl ExtendedDocumentWasm { .set_created_at(ts.map(|t| t.get_time() as TimestampMillis)); } + #[wasm_bindgen(js_name=createTransferStateTransition)] + pub fn create_transfer_state_transition(&mut self, recipient: IdentifierWrapper, identity_contract_nonce: IdentityNonce) -> DocumentsBatchTransitionWasm { + let mut cloned_document = self.0.document().clone(); + + cloned_document.set_revision(Some(cloned_document.revision().unwrap() + 1)); + + let transfer_transition = DocumentTransferTransition::from_document( + cloned_document, + self.0.document_type().unwrap(), + identity_contract_nonce, + recipient.into(), + PlatformVersion::latest(), + None, + None, + ).unwrap(); + + let documents_batch_transition: DocumentsBatchTransition = DocumentsBatchTransitionV0 { + owner_id: self.0.owner_id(), + transitions: vec![transfer_transition.into()], + user_fee_increase: Default::default(), + signature_public_key_id: Default::default(), + signature: Default::default(), + }.into(); + + documents_batch_transition.into() + } + + #[wasm_bindgen(js_name=createUpdatePriceStateTransition)] + pub fn create_update_price_state_transition(&mut self, amount: u32, identity_contract_nonce: IdentityNonce) -> DocumentsBatchTransitionWasm { + let mut cloned_document = self.0.document().clone(); + + cloned_document.set_revision(Some(cloned_document.revision().unwrap() + 1)); + + let update_price_transition = DocumentUpdatePriceTransition::from_document( + cloned_document, + self.0.document_type().unwrap(), + amount as u64, + identity_contract_nonce, + PlatformVersion::latest(), + None, + None, + ).unwrap(); + + let documents_batch_transition: DocumentsBatchTransition = DocumentsBatchTransitionV0 { + owner_id: self.0.owner_id(), + transitions: vec![update_price_transition.into()], + user_fee_increase: Default::default(), + signature_public_key_id: Default::default(), + signature: Default::default(), + }.into(); + + documents_batch_transition.into() + } + + #[wasm_bindgen(js_name=createPurchaseStateTransition)] + pub fn create_update_purchase_transition(&mut self, buyer: IdentifierWrapper, amount: u32, identity_contract_nonce: IdentityNonce) -> DocumentsBatchTransitionWasm { + let mut cloned_document = self.0.document().clone(); + + cloned_document.set_revision(Some(cloned_document.revision().unwrap() + 1)); + + let purchase_transition = DocumentPurchaseTransition::from_document( + cloned_document, + self.0.document_type().unwrap(), + amount as u64, + identity_contract_nonce, + PlatformVersion::latest(), + None, + None, + ).unwrap(); + + let documents_batch_transition: DocumentsBatchTransition = DocumentsBatchTransitionV0 { + owner_id: buyer.into(), + transitions: vec![purchase_transition.into()], + user_fee_increase: Default::default(), + signature_public_key_id: Default::default(), + signature: Default::default(), + }.into(); + + documents_batch_transition.into() + } + #[wasm_bindgen(js_name=setUpdatedAt)] pub fn set_updated_at(&mut self, ts: Option) { self.0 From 9dad661e56c3095c0a2d020c16c0cc5ac1d12ff7 Mon Sep 17 00:00:00 2001 From: pshenmic Date: Mon, 20 Jan 2025 18:19:47 +0700 Subject: [PATCH 17/31] feat(js-sdk): add transfer def in Platform.ts --- packages/js-dash-sdk/src/SDK/Client/Platform/Platform.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/packages/js-dash-sdk/src/SDK/Client/Platform/Platform.ts b/packages/js-dash-sdk/src/SDK/Client/Platform/Platform.ts index 873fe62c53d..7e72d2fa68e 100644 --- a/packages/js-dash-sdk/src/SDK/Client/Platform/Platform.ts +++ b/packages/js-dash-sdk/src/SDK/Client/Platform/Platform.ts @@ -9,6 +9,9 @@ import createAssetLockTransaction from './createAssetLockTransaction'; import broadcastDocument from './methods/documents/broadcast'; import createDocument from './methods/documents/create'; +import transferDocument from './methods/documents/transfer'; +import updatePriceDocument from './methods/documents/updatePrice'; +import purchaseDocument from './methods/documents/purchase'; import getDocument from './methods/documents/get'; import publishContract from './methods/contracts/publish'; @@ -58,6 +61,9 @@ export interface PlatformOpts { interface Records { broadcast: Function, create: Function, + transfer: Function, + updatePrice: Function, + purchase: Function, get: Function, } @@ -165,6 +171,9 @@ export class Platform { this.documents = { broadcast: broadcastDocument.bind(this), create: createDocument.bind(this), + transfer: transferDocument.bind(this), + updatePrice: updatePriceDocument.bind(this), + purchase: purchaseDocument.bind(this), get: getDocument.bind(this), }; this.contracts = { From cbc86c42891aa051085944149cb75e25ca70fd60 Mon Sep 17 00:00:00 2001 From: pshenmic Date: Sun, 26 Jan 2025 21:07:57 +0700 Subject: [PATCH 18/31] feat(js-dash-sdk): uncomment --- .../Platform/methods/documents/purchase.ts | 36 +++++++++++++++++++ .../Platform/methods/documents/updatePrice.ts | 33 +++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/purchase.ts create mode 100644 packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/updatePrice.ts diff --git a/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/purchase.ts b/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/purchase.ts new file mode 100644 index 00000000000..e1c593ffed7 --- /dev/null +++ b/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/purchase.ts @@ -0,0 +1,36 @@ +import { Identity, ExtendedDocument } from '@dashevo/wasm-dpp'; +import { Platform } from '../../Platform'; +import broadcastStateTransition from '../../broadcastStateTransition'; +import { signStateTransition } from '../../signStateTransition'; +/** + * Transfer document in the platform + * + * @param {Platform} this - bound instance class + * @param {ExtendedDocument} document - document from the DAPI + * @param {Identifier} receiver - identifier of the document recipient ownership + * @param {Identifier} sender - identifier of the document owner + */ +export async function purchase( + this: Platform, + document: ExtendedDocument, + amount: number, + buyer: Identity, + seller: Identity, +): Promise { + this.logger.debug(`[Document#transfer] Update price for document ${document.getId().toString()} to ${amount}`); + await this.initialize(); + + const identityContractNonce = await this.nonceManager + .bumpIdentityContractNonce(buyer.getId(), document.getDataContractId()); + + const documentsBatchTransition = document + .createPurchaseStateTransition(buyer.getId(), amount, BigInt(identityContractNonce)); + + await signStateTransition(this, documentsBatchTransition, buyer, 1); + + console.log(documentsBatchTransition.toBuffer().toString('hex')); + + await broadcastStateTransition(this, documentsBatchTransition); +} + +export default purchase; diff --git a/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/updatePrice.ts b/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/updatePrice.ts new file mode 100644 index 00000000000..1216bc98bf6 --- /dev/null +++ b/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/updatePrice.ts @@ -0,0 +1,33 @@ +import { Identity, ExtendedDocument } from '@dashevo/wasm-dpp'; +import { Platform } from '../../Platform'; +import broadcastStateTransition from '../../broadcastStateTransition'; +import { signStateTransition } from '../../signStateTransition'; +/** + * Transfer document in the platform + * + * @param {Platform} this - bound instance class + * @param {ExtendedDocument} document - document from the DAPI + * @param {Identifier} receiver - identifier of the document recipient ownership + * @param {Identifier} sender - identifier of the document owner + */ +export async function updatePrice( + this: Platform, + document: ExtendedDocument, + amount: number, + identity: Identity, +): Promise { + this.logger.debug(`[Document#transfer] Update price for document ${document.getId().toString()} to ${amount}`); + await this.initialize(); + + const identityContractNonce = await this.nonceManager + .bumpIdentityContractNonce(identity.getId(), document.getDataContractId()); + + const documentsBatchTransition = document + .createUpdatePriceStateTransition(amount, BigInt(identityContractNonce)); + + await signStateTransition(this, documentsBatchTransition, identity, 1); + + await broadcastStateTransition(this, documentsBatchTransition); +} + +export default updatePrice; From 7940a092670aafd625f06986942db8d90b64266c Mon Sep 17 00:00:00 2001 From: pshenmic Date: Thu, 30 Jan 2025 15:26:37 +0700 Subject: [PATCH 19/31] feat(wasm-dpp): move nft create state transition from extended document to factory --- .../src/document/document_factory/mod.rs | 5 +- .../src/document/document_factory/v0/mod.rs | 150 +++++++++++++++++- packages/rs-dpp/src/document/errors.rs | 3 + .../wasm-dpp/src/document/document_facade.rs | 10 +- packages/wasm-dpp/src/document/errors/mod.rs | 5 + ...transfer_nontransferable_document_error.rs | 19 +++ .../src/document/extended_document.rs | 85 +--------- packages/wasm-dpp/src/document/factory.rs | 13 +- 8 files changed, 199 insertions(+), 91 deletions(-) create mode 100644 packages/wasm-dpp/src/document/errors/trying_to_transfer_nontransferable_document_error.rs diff --git a/packages/rs-dpp/src/document/document_factory/mod.rs b/packages/rs-dpp/src/document/document_factory/mod.rs index 75db720fd59..8245a079f3c 100644 --- a/packages/rs-dpp/src/document/document_factory/mod.rs +++ b/packages/rs-dpp/src/document/document_factory/mod.rs @@ -18,6 +18,7 @@ use crate::state_transition::documents_batch_transition::{ }; use crate::util::entropy_generator::EntropyGenerator; pub use v0::DocumentFactoryV0; +use crate::fee::Credits; /// # Document Factory /// @@ -120,9 +121,11 @@ impl DocumentFactory { ), >, nonce_counter: &mut BTreeMap<(Identifier, Identifier), u64>, //IdentityID/ContractID -> nonce + recipient: Option, + price: Option, ) -> Result { match self { - DocumentFactory::V0(v0) => v0.create_state_transition(documents_iter, nonce_counter), + DocumentFactory::V0(v0) => v0.create_state_transition(documents_iter, nonce_counter, recipient, price), } } diff --git a/packages/rs-dpp/src/document/document_factory/v0/mod.rs b/packages/rs-dpp/src/document/document_factory/v0/mod.rs index 58fc96de91a..38ae3d73433 100644 --- a/packages/rs-dpp/src/document/document_factory/v0/mod.rs +++ b/packages/rs-dpp/src/document/document_factory/v0/mod.rs @@ -32,6 +32,8 @@ use crate::state_transition::documents_batch_transition::{ DocumentsBatchTransition, DocumentsBatchTransitionV0, }; use itertools::Itertools; +use crate::fee::Credits; +use crate::state_transition::documents_batch_transition::document_transition::{DocumentPurchaseTransition, DocumentTransferTransition, DocumentUpdatePriceTransition}; const PROPERTY_FEATURE_VERSION: &str = "$version"; const PROPERTY_ENTROPY: &str = "$entropy"; @@ -209,7 +211,9 @@ impl DocumentFactoryV0 { Vec<(Document, DocumentTypeRef<'a>, Bytes32)>, ), >, - nonce_counter: &mut BTreeMap<(Identifier, Identifier), u64>, //IdentityID/ContractID -> nonce + nonce_counter: &mut BTreeMap<(Identifier, Identifier), u64>, //IdentityID/ContractID -> nonce, + recipient: Option, + price: Option ) -> Result { let platform_version = PlatformVersion::get(self.protocol_version)?; let documents: Vec<( @@ -262,6 +266,33 @@ impl DocumentFactoryV0 { nonce_counter, platform_version, ), + DocumentTransitionActionType::Transfer => Self::document_transfer_transitions( + documents + .into_iter() + .map(|(document, document_type, _)| (document, document_type)) + .collect(), + nonce_counter, + platform_version, + recipient.unwrap() + ), + DocumentTransitionActionType::UpdatePrice => Self::document_update_price_transitions( + documents + .into_iter() + .map(|(document, document_type, _)| (document, document_type)) + .collect(), + nonce_counter, + platform_version, + price.unwrap() + ), + DocumentTransitionActionType::Purchase => Self::document_purchase_transitions( + documents + .into_iter() + .map(|(document, document_type, _)| (document, document_type)) + .collect(), + nonce_counter, + platform_version, + price.unwrap() + ), _ => Err(ProtocolError::InvalidStateTransitionType( "action type not accounted for".to_string(), )), @@ -548,6 +579,123 @@ impl DocumentFactoryV0 { .collect() } + #[cfg(feature = "state-transitions")] + fn document_transfer_transitions( + documents: Vec<(Document, DocumentTypeRef)>, + nonce_counter: &mut BTreeMap<(Identifier, Identifier), u64>, //IdentityID/ContractID -> nonce + platform_version: &PlatformVersion, + recipient_owner_id: Identifier + ) -> Result, ProtocolError> { + documents + .into_iter() + .map(|(document, document_type)| { + if !document_type.documents_transferable().is_transferable() { + return Err(DocumentError::TryingToTransferNonTransferableDocument { + document: Box::new(document), + } + .into()); + } + let Some(_document_revision) = document.revision() else { + return Err(DocumentError::RevisionAbsentError { + document: Box::new(document), + } + .into()); + }; + + let nonce = nonce_counter + .entry((document.owner_id(), document_type.data_contract_id())) + .or_default(); + let transition = DocumentTransferTransition::from_document( + document, + document_type, + *nonce, + recipient_owner_id, + platform_version, + None, + None, + )?; + + *nonce += 1; + + Ok(transition.into()) + }) + .collect() + } + + #[cfg(feature = "state-transitions")] + fn document_update_price_transitions( + documents: Vec<(Document, DocumentTypeRef)>, + nonce_counter: &mut BTreeMap<(Identifier, Identifier), u64>, //IdentityID/ContractID -> nonce + platform_version: &PlatformVersion, + price: Credits + ) -> Result, ProtocolError> { + documents + .into_iter() + .map(|(document, document_type)| { + let Some(_document_revision) = document.revision() else { + return Err(DocumentError::RevisionAbsentError { + document: Box::new(document), + } + .into()); + }; + + let nonce = nonce_counter + .entry((document.owner_id(), document_type.data_contract_id())) + .or_default(); + let transition = DocumentUpdatePriceTransition::from_document( + document, + document_type, + price, + *nonce, + platform_version, + None, + None, + )?; + + *nonce += 1; + + Ok(transition.into()) + }) + .collect() + } + + #[cfg(feature = "state-transitions")] + fn document_purchase_transitions( + documents: Vec<(Document, DocumentTypeRef)>, + nonce_counter: &mut BTreeMap<(Identifier, Identifier), u64>, //IdentityID/ContractID -> nonce + platform_version: &PlatformVersion, + price: Credits + ) -> Result, ProtocolError> { + documents + .into_iter() + .map(|(document, document_type)| { + let Some(_document_revision) = document.revision() else { + return Err(DocumentError::RevisionAbsentError { + document: Box::new(document), + } + .into()); + }; + + let nonce = nonce_counter + .entry((document.owner_id(), document_type.data_contract_id())) + .or_default(); + let transition = DocumentPurchaseTransition::from_document( + document, + document_type, + price, + *nonce, + platform_version, + None, + None, + )?; + + *nonce += 1; + + Ok(transition.into()) + }) + .collect() + } + fn is_ownership_the_same<'a>(ids: impl IntoIterator) -> bool { ids.into_iter().all_equal() } diff --git a/packages/rs-dpp/src/document/errors.rs b/packages/rs-dpp/src/document/errors.rs index d16ca16f1ea..e053bf88605 100644 --- a/packages/rs-dpp/src/document/errors.rs +++ b/packages/rs-dpp/src/document/errors.rs @@ -47,6 +47,9 @@ pub enum DocumentError { #[error("Trying to delete indelible document")] TryingToDeleteIndelibleDocument { document: Box }, + #[error("Trying to transfer non-transferable document")] + TryingToTransferNonTransferableDocument { document: Box }, + #[error("Documents have mixed owner ids")] MismatchOwnerIdsError { documents: Vec }, diff --git a/packages/wasm-dpp/src/document/document_facade.rs b/packages/wasm-dpp/src/document/document_facade.rs index 609794eaa99..a62fe8a083a 100644 --- a/packages/wasm-dpp/src/document/document_facade.rs +++ b/packages/wasm-dpp/src/document/document_facade.rs @@ -1,10 +1,12 @@ use std::rc::Rc; use wasm_bindgen::{prelude::*, JsValue}; - +use dpp::fee::Credits; +use dpp::identifier::Identifier; use crate::document::factory::DocumentFactoryWASM; use crate::{DataContractWasm, ExtendedDocumentWasm}; use crate::document::state_transition::document_batch_transition::DocumentsBatchTransitionWasm; +use crate::identifier::IdentifierWrapper; #[derive(Clone)] #[wasm_bindgen(js_name=DocumentFacade)] @@ -95,10 +97,12 @@ impl DocumentFacadeWasm { pub fn create_state_transition( &self, documents: &JsValue, - nonce_counter_value: &js_sys::Object, //IdentityID/ContractID -> nonce + nonce_counter_value: &js_sys::Object, //IdentityID/ContractID -> nonce, + recipient: Option, + price: Option ) -> Result { self.factory - .create_state_transition(documents, nonce_counter_value) + .create_state_transition(documents, nonce_counter_value, recipient, price) } // /// Creates Documents State Transition diff --git a/packages/wasm-dpp/src/document/errors/mod.rs b/packages/wasm-dpp/src/document/errors/mod.rs index 7b90ac63dbd..f900fde35d1 100644 --- a/packages/wasm-dpp/src/document/errors/mod.rs +++ b/packages/wasm-dpp/src/document/errors/mod.rs @@ -6,6 +6,7 @@ use crate::document::errors::invalid_action_error::InvalidActionError; use crate::document::errors::revision_absent_error::RevisionAbsentError; use crate::document::errors::trying_to_delete_immutable_document_error::TryingToDeleteImmutableDocumentError; use crate::document::errors::trying_to_replace_immutable_document_error::TryingToReplaceImmutableDocumentError; +use crate::document::errors::trying_to_transfer_nontransferable_document_error::TryingToTransferNonTransferableDocumentError; pub use document_already_exists_error::*; pub use document_not_provided_error::*; use dpp::document::errors::DocumentError; @@ -32,6 +33,7 @@ mod no_documents_supplied_error; mod revision_absent_error; mod trying_to_delete_immutable_document_error; mod trying_to_replace_immutable_document_error; +mod trying_to_transfer_nontransferable_document_error; pub fn from_document_to_js_error(e: DocumentError) -> JsValue { match e { @@ -77,6 +79,9 @@ pub fn from_document_to_js_error(e: DocumentError) -> JsValue { DocumentError::InvalidActionError(action) => InvalidActionError::new(action.into()).into(), DocumentError::TryingToDeleteIndelibleDocument { document } => { TryingToDeleteImmutableDocumentError::new((*document).into()).into() + }, + DocumentError::TryingToTransferNonTransferableDocument { document } => { + TryingToTransferNonTransferableDocumentError::new((*document).into()).into() } } } diff --git a/packages/wasm-dpp/src/document/errors/trying_to_transfer_nontransferable_document_error.rs b/packages/wasm-dpp/src/document/errors/trying_to_transfer_nontransferable_document_error.rs new file mode 100644 index 00000000000..60ff00f03d4 --- /dev/null +++ b/packages/wasm-dpp/src/document/errors/trying_to_transfer_nontransferable_document_error.rs @@ -0,0 +1,19 @@ +use crate::document::DocumentWasm; +use thiserror::Error; + +use super::*; + +#[wasm_bindgen] +#[derive(Error, Debug)] +#[error("Trying to transfer an non transferable document")] +pub struct TryingToTransferNonTransferableDocumentError { + document: DocumentWasm, +} + +#[wasm_bindgen] +impl TryingToTransferNonTransferableDocumentError { + #[wasm_bindgen(constructor)] + pub fn new(document: DocumentWasm) -> Self { + TryingToTransferNonTransferableDocumentError { document } + } +} diff --git a/packages/wasm-dpp/src/document/extended_document.rs b/packages/wasm-dpp/src/document/extended_document.rs index 600958c8a33..a321e5f46b9 100644 --- a/packages/wasm-dpp/src/document/extended_document.rs +++ b/packages/wasm-dpp/src/document/extended_document.rs @@ -2,7 +2,7 @@ use dpp::document::{DocumentV0Getters, DocumentV0Setters, ExtendedDocument, EXTE use serde_json::Value as JsonValue; use dpp::platform_value::{Bytes32, Value}; -use dpp::prelude::{Identifier, IdentityNonce, Revision, TimestampMillis, UserFeeIncrease}; +use dpp::prelude::{Identifier, Revision, TimestampMillis}; use dpp::util::json_value::JsonValueExt; @@ -14,8 +14,6 @@ use dpp::ProtocolError; use serde::{Deserialize, Serialize}; use std::convert::TryInto; use wasm_bindgen::prelude::*; -use dpp::state_transition::documents_batch_transition::document_transition::{DocumentPurchaseTransition, DocumentTransferTransition, DocumentUpdatePriceTransition}; -use dpp::state_transition::documents_batch_transition::{DocumentsBatchTransition, DocumentsBatchTransitionV0}; use crate::buffer::Buffer; use crate::data_contract::DataContractWasm; @@ -236,87 +234,6 @@ impl ExtendedDocumentWasm { .set_created_at(ts.map(|t| t.get_time() as TimestampMillis)); } - #[wasm_bindgen(js_name=createTransferStateTransition)] - pub fn create_transfer_state_transition(&mut self, recipient: IdentifierWrapper, identity_contract_nonce: IdentityNonce) -> DocumentsBatchTransitionWasm { - let mut cloned_document = self.0.document().clone(); - - cloned_document.set_revision(Some(cloned_document.revision().unwrap() + 1)); - - let transfer_transition = DocumentTransferTransition::from_document( - cloned_document, - self.0.document_type().unwrap(), - identity_contract_nonce, - recipient.into(), - PlatformVersion::latest(), - None, - None, - ).unwrap(); - - let documents_batch_transition: DocumentsBatchTransition = DocumentsBatchTransitionV0 { - owner_id: self.0.owner_id(), - transitions: vec![transfer_transition.into()], - user_fee_increase: Default::default(), - signature_public_key_id: Default::default(), - signature: Default::default(), - }.into(); - - documents_batch_transition.into() - } - - #[wasm_bindgen(js_name=createUpdatePriceStateTransition)] - pub fn create_update_price_state_transition(&mut self, amount: u32, identity_contract_nonce: IdentityNonce) -> DocumentsBatchTransitionWasm { - let mut cloned_document = self.0.document().clone(); - - cloned_document.set_revision(Some(cloned_document.revision().unwrap() + 1)); - - let update_price_transition = DocumentUpdatePriceTransition::from_document( - cloned_document, - self.0.document_type().unwrap(), - amount as u64, - identity_contract_nonce, - PlatformVersion::latest(), - None, - None, - ).unwrap(); - - let documents_batch_transition: DocumentsBatchTransition = DocumentsBatchTransitionV0 { - owner_id: self.0.owner_id(), - transitions: vec![update_price_transition.into()], - user_fee_increase: Default::default(), - signature_public_key_id: Default::default(), - signature: Default::default(), - }.into(); - - documents_batch_transition.into() - } - - #[wasm_bindgen(js_name=createPurchaseStateTransition)] - pub fn create_update_purchase_transition(&mut self, buyer: IdentifierWrapper, amount: u32, identity_contract_nonce: IdentityNonce) -> DocumentsBatchTransitionWasm { - let mut cloned_document = self.0.document().clone(); - - cloned_document.set_revision(Some(cloned_document.revision().unwrap() + 1)); - - let purchase_transition = DocumentPurchaseTransition::from_document( - cloned_document, - self.0.document_type().unwrap(), - amount as u64, - identity_contract_nonce, - PlatformVersion::latest(), - None, - None, - ).unwrap(); - - let documents_batch_transition: DocumentsBatchTransition = DocumentsBatchTransitionV0 { - owner_id: buyer.into(), - transitions: vec![purchase_transition.into()], - user_fee_increase: Default::default(), - signature_public_key_id: Default::default(), - signature: Default::default(), - }.into(); - - documents_batch_transition.into() - } - #[wasm_bindgen(js_name=setUpdatedAt)] pub fn set_updated_at(&mut self, ts: Option) { self.0 diff --git a/packages/wasm-dpp/src/document/factory.rs b/packages/wasm-dpp/src/document/factory.rs index 0b927a60803..a6724bdc6c5 100644 --- a/packages/wasm-dpp/src/document/factory.rs +++ b/packages/wasm-dpp/src/document/factory.rs @@ -17,7 +17,7 @@ use dpp::identifier::Identifier; use dpp::state_transition::documents_batch_transition::document_transition::action_type::DocumentTransitionActionType; use dpp::version::PlatformVersion; use std::convert::TryFrom; - +use dpp::fee::Credits; use crate::document_batch_transition::DocumentsBatchTransitionWasm; use crate::entropy_generator::ExternalEntropyGenerator; use crate::{ @@ -25,6 +25,7 @@ use crate::{ utils::{IntoWasm, ToSerdeJSONExt, WithJsError}, DataContractWasm, ExtendedDocumentWasm, }; +use crate::identifier::IdentifierWrapper; #[wasm_bindgen(js_name=DocumentTransitions)] #[derive(Debug, Default)] @@ -109,6 +110,8 @@ impl DocumentFactoryWASM { &self, documents: &JsValue, nonce_counter_value: &js_sys::Object, //IdentityID/ContractID -> nonce + recipient: Option, + price: Option ) -> Result { let mut nonce_counter = BTreeMap::new(); let mut contract_ids_to_check = HashSet::<&Identifier>::new(); @@ -176,7 +179,7 @@ impl DocumentFactoryWASM { let batch_transition = self .0 - .create_state_transition(documents, &mut nonce_counter) + .create_state_transition(documents, &mut nonce_counter, recipient.map(|e| { Identifier::from(e)}), price) .with_js_error()?; Ok(batch_transition.into()) @@ -278,10 +281,16 @@ fn extract_documents_by_action( let documents_create = extract_documents_of_action(documents, "create").with_js_error()?; let documents_replace = extract_documents_of_action(documents, "replace").with_js_error()?; let documents_delete = extract_documents_of_action(documents, "delete").with_js_error()?; + let documents_transfer = extract_documents_of_action(documents, "transfer").with_js_error()?; + let documents_update_price = extract_documents_of_action(documents, "updatePrice").with_js_error()?; + let documents_purchase = extract_documents_of_action(documents, "purchase").with_js_error()?; documents_by_action.insert(DocumentTransitionActionType::Create, documents_create); documents_by_action.insert(DocumentTransitionActionType::Replace, documents_replace); documents_by_action.insert(DocumentTransitionActionType::Delete, documents_delete); + documents_by_action.insert(DocumentTransitionActionType::Transfer, documents_transfer); + documents_by_action.insert(DocumentTransitionActionType::UpdatePrice, documents_update_price); + documents_by_action.insert(DocumentTransitionActionType::Purchase, documents_purchase); Ok(documents_by_action) } From dac6932d5b39c60ef75954e0b2c298d839a5c211 Mon Sep 17 00:00:00 2001 From: pshenmic Date: Thu, 30 Jan 2025 20:11:32 +0700 Subject: [PATCH 20/31] fix(js-dash-sdk): fix types --- .../src/SDK/Client/Platform/Platform.ts | 9 ----- .../Platform/methods/documents/broadcast.ts | 14 ++++++-- .../Platform/methods/documents/purchase.ts | 36 ------------------- .../Platform/methods/documents/transfer.ts | 33 ----------------- .../Platform/methods/documents/updatePrice.ts | 33 ----------------- 5 files changed, 12 insertions(+), 113 deletions(-) delete mode 100644 packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/purchase.ts delete mode 100644 packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/transfer.ts delete mode 100644 packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/updatePrice.ts diff --git a/packages/js-dash-sdk/src/SDK/Client/Platform/Platform.ts b/packages/js-dash-sdk/src/SDK/Client/Platform/Platform.ts index 7e72d2fa68e..873fe62c53d 100644 --- a/packages/js-dash-sdk/src/SDK/Client/Platform/Platform.ts +++ b/packages/js-dash-sdk/src/SDK/Client/Platform/Platform.ts @@ -9,9 +9,6 @@ import createAssetLockTransaction from './createAssetLockTransaction'; import broadcastDocument from './methods/documents/broadcast'; import createDocument from './methods/documents/create'; -import transferDocument from './methods/documents/transfer'; -import updatePriceDocument from './methods/documents/updatePrice'; -import purchaseDocument from './methods/documents/purchase'; import getDocument from './methods/documents/get'; import publishContract from './methods/contracts/publish'; @@ -61,9 +58,6 @@ export interface PlatformOpts { interface Records { broadcast: Function, create: Function, - transfer: Function, - updatePrice: Function, - purchase: Function, get: Function, } @@ -171,9 +165,6 @@ export class Platform { this.documents = { broadcast: broadcastDocument.bind(this), create: createDocument.bind(this), - transfer: transferDocument.bind(this), - updatePrice: updatePriceDocument.bind(this), - purchase: purchaseDocument.bind(this), get: getDocument.bind(this), }; this.contracts = { diff --git a/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/broadcast.ts b/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/broadcast.ts index 4bbe6b6479d..f9723a48c84 100644 --- a/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/broadcast.ts +++ b/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/broadcast.ts @@ -18,14 +18,18 @@ export default async function broadcast( documents: { create?: ExtendedDocument[], replace?: ExtendedDocument[], - delete?: ExtendedDocument[] + delete?: ExtendedDocument[], + transfer?: ExtendedDocument[] }, identity: any, + options: any, ): Promise { + console.log(documents) this.logger.debug('[Document#broadcast] Broadcast documents', { create: documents.create?.length || 0, replace: documents.replace?.length || 0, delete: documents.delete?.length || 0, + transfer: documents.transfer?.length || 0, }); await this.initialize(); @@ -36,12 +40,17 @@ export default async function broadcast( ...(documents.create || []), ...(documents.replace || []), ...(documents.delete || []), + ...(documents.transfer || []), ][0]?.getDataContractId(); if (!dataContractId) { throw new Error('Data contract ID is not found'); } + if (documents.transfer?.length && !options.recipient) { + throw new Error('Receiver identity is not found for transfer transition'); + } + const identityContractNonce = await this.nonceManager .bumpIdentityContractNonce(identityId, dataContractId); @@ -49,7 +58,7 @@ export default async function broadcast( [identityId.toString()]: { [dataContractId.toString()]: identityContractNonce, }, - }); + }, options.recipient, options.price); this.logger.silly('[Document#broadcast] Created documents batch transition'); @@ -79,6 +88,7 @@ export default async function broadcast( create: documents.create?.length || 0, replace: documents.replace?.length || 0, delete: documents.delete?.length || 0, + transfer: documents.transfer?.length || 0, }); return documentsBatchTransition; diff --git a/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/purchase.ts b/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/purchase.ts deleted file mode 100644 index e1c593ffed7..00000000000 --- a/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/purchase.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Identity, ExtendedDocument } from '@dashevo/wasm-dpp'; -import { Platform } from '../../Platform'; -import broadcastStateTransition from '../../broadcastStateTransition'; -import { signStateTransition } from '../../signStateTransition'; -/** - * Transfer document in the platform - * - * @param {Platform} this - bound instance class - * @param {ExtendedDocument} document - document from the DAPI - * @param {Identifier} receiver - identifier of the document recipient ownership - * @param {Identifier} sender - identifier of the document owner - */ -export async function purchase( - this: Platform, - document: ExtendedDocument, - amount: number, - buyer: Identity, - seller: Identity, -): Promise { - this.logger.debug(`[Document#transfer] Update price for document ${document.getId().toString()} to ${amount}`); - await this.initialize(); - - const identityContractNonce = await this.nonceManager - .bumpIdentityContractNonce(buyer.getId(), document.getDataContractId()); - - const documentsBatchTransition = document - .createPurchaseStateTransition(buyer.getId(), amount, BigInt(identityContractNonce)); - - await signStateTransition(this, documentsBatchTransition, buyer, 1); - - console.log(documentsBatchTransition.toBuffer().toString('hex')); - - await broadcastStateTransition(this, documentsBatchTransition); -} - -export default purchase; diff --git a/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/transfer.ts b/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/transfer.ts deleted file mode 100644 index e211364b27b..00000000000 --- a/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/transfer.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { Identity, ExtendedDocument } from '@dashevo/wasm-dpp'; -import { Platform } from '../../Platform'; -import broadcastStateTransition from '../../broadcastStateTransition'; -import { signStateTransition } from '../../signStateTransition'; -/** - * Transfer document in the platform - * - * @param {Platform} this - bound instance class - * @param {ExtendedDocument} document - document from the DAPI - * @param {Identifier} receiver - identifier of the document recipient ownership - * @param {Identifier} sender - identifier of the document owner - */ -export async function transfer( - this: Platform, - document: ExtendedDocument, - receiver: Identity, - sender: Identity, -): Promise { - this.logger.debug(`[Document#transfer] Transfer document ${document.getId().toString()} from ${sender.getId().toString} to {${receiver.getId().toString()}`); - await this.initialize(); - - const identityContractNonce = await this.nonceManager - .bumpIdentityContractNonce(sender.getId(), document.getDataContractId()); - - const documentsBatchTransition = document - .createTransferStateTransition(receiver.getId(), BigInt(identityContractNonce)); - - await signStateTransition(this, documentsBatchTransition, sender, 1); - - await broadcastStateTransition(this, documentsBatchTransition); -} - -export default transfer; diff --git a/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/updatePrice.ts b/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/updatePrice.ts deleted file mode 100644 index 1216bc98bf6..00000000000 --- a/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/updatePrice.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { Identity, ExtendedDocument } from '@dashevo/wasm-dpp'; -import { Platform } from '../../Platform'; -import broadcastStateTransition from '../../broadcastStateTransition'; -import { signStateTransition } from '../../signStateTransition'; -/** - * Transfer document in the platform - * - * @param {Platform} this - bound instance class - * @param {ExtendedDocument} document - document from the DAPI - * @param {Identifier} receiver - identifier of the document recipient ownership - * @param {Identifier} sender - identifier of the document owner - */ -export async function updatePrice( - this: Platform, - document: ExtendedDocument, - amount: number, - identity: Identity, -): Promise { - this.logger.debug(`[Document#transfer] Update price for document ${document.getId().toString()} to ${amount}`); - await this.initialize(); - - const identityContractNonce = await this.nonceManager - .bumpIdentityContractNonce(identity.getId(), document.getDataContractId()); - - const documentsBatchTransition = document - .createUpdatePriceStateTransition(amount, BigInt(identityContractNonce)); - - await signStateTransition(this, documentsBatchTransition, identity, 1); - - await broadcastStateTransition(this, documentsBatchTransition); -} - -export default updatePrice; From b7da3822b343fd66c101ff7c3249432681bb9fe9 Mon Sep 17 00:00:00 2001 From: pshenmic Date: Fri, 31 Jan 2025 18:06:00 +0700 Subject: [PATCH 21/31] fix(js-dash-sdk): finalize nft transitions --- .../Platform/methods/documents/broadcast.ts | 48 +++++++++++++---- .../src/document/document_factory/v0/mod.rs | 53 +++++++++++++------ .../document_transition/action_type.rs | 17 ++++++ 3 files changed, 93 insertions(+), 25 deletions(-) diff --git a/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/broadcast.ts b/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/broadcast.ts index f9723a48c84..82b8fb81f48 100644 --- a/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/broadcast.ts +++ b/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/broadcast.ts @@ -1,17 +1,23 @@ -import { ExtendedDocument } from '@dashevo/wasm-dpp'; +import { ExtendedDocument, Identifier } from '@dashevo/wasm-dpp'; import { Platform } from '../../Platform'; import broadcastStateTransition from '../../broadcastStateTransition'; import { signStateTransition } from '../../signStateTransition'; +class DocumentTransitionParams { + receiver?: Identifier; + + price?: bigint; +} + /** * Broadcast document onto the platform * - * @param {Platform} this - bound instance class * @param {Object} documents * @param {ExtendedDocument[]} [documents.create] * @param {ExtendedDocument[]} [documents.replace] * @param {ExtendedDocument[]} [documents.delete] - * @param identity - identity + * @param {Identity} identity + * @param options {DocumentTransitionParams} optional params for NFT functions */ export default async function broadcast( this: Platform, @@ -19,17 +25,20 @@ export default async function broadcast( create?: ExtendedDocument[], replace?: ExtendedDocument[], delete?: ExtendedDocument[], - transfer?: ExtendedDocument[] + transfer?: ExtendedDocument[], + updatePrice?: ExtendedDocument[], + purchase?: ExtendedDocument[], }, identity: any, - options: any, + options?: DocumentTransitionParams, ): Promise { - console.log(documents) this.logger.debug('[Document#broadcast] Broadcast documents', { create: documents.create?.length || 0, replace: documents.replace?.length || 0, delete: documents.delete?.length || 0, transfer: documents.transfer?.length || 0, + updatePrice: documents.updatePrice?.length || 0, + purchase: documents.purchase?.length || 0, }); await this.initialize(); @@ -41,24 +50,45 @@ export default async function broadcast( ...(documents.replace || []), ...(documents.delete || []), ...(documents.transfer || []), + ...(documents.updatePrice || []), + ...(documents.purchase || []), ][0]?.getDataContractId(); if (!dataContractId) { throw new Error('Data contract ID is not found'); } - if (documents.transfer?.length && !options.recipient) { + if (documents.transfer?.length && !options?.receiver) { throw new Error('Receiver identity is not found for transfer transition'); } + if (documents.updatePrice?.length && !options?.price) { + throw new Error('Price must be provided for UpdatePrice operation'); + } + + if (documents.purchase?.length) { + if (!options?.price && !options?.receiver) { + throw new Error('Price and Receiver must be provided for Purchase operation'); + } + + documents.purchase.forEach((document) => document.setOwnerId(options.receiver)); + } + const identityContractNonce = await this.nonceManager .bumpIdentityContractNonce(identityId, dataContractId); - const documentsBatchTransition = dpp.document.createStateTransition(documents, { + const identityNonceObj = { [identityId.toString()]: { [dataContractId.toString()]: identityContractNonce, }, - }, options.recipient, options.price); + }; + + const documentsBatchTransition = dpp.document.createStateTransition( + documents, + identityNonceObj, + options?.receiver, + options?.price, + ); this.logger.silly('[Document#broadcast] Created documents batch transition'); diff --git a/packages/rs-dpp/src/document/document_factory/v0/mod.rs b/packages/rs-dpp/src/document/document_factory/v0/mod.rs index 38ae3d73433..36ed8e1e480 100644 --- a/packages/rs-dpp/src/document/document_factory/v0/mod.rs +++ b/packages/rs-dpp/src/document/document_factory/v0/mod.rs @@ -273,7 +273,7 @@ impl DocumentFactoryV0 { .collect(), nonce_counter, platform_version, - recipient.unwrap() + recipient ), DocumentTransitionActionType::UpdatePrice => Self::document_update_price_transitions( documents @@ -282,7 +282,7 @@ impl DocumentFactoryV0 { .collect(), nonce_counter, platform_version, - price.unwrap() + price ), DocumentTransitionActionType::Purchase => Self::document_purchase_transitions( documents @@ -291,11 +291,15 @@ impl DocumentFactoryV0 { .collect(), nonce_counter, platform_version, - price.unwrap() + price, + recipient ), - _ => Err(ProtocolError::InvalidStateTransitionType( - "action type not accounted for".to_string(), - )), + _ => { + let action_type_name: &str = action.into(); + + Err(ProtocolError::InvalidStateTransitionType( + action_type_name.to_string(), + ))}, }) .collect::, ProtocolError>>()? .into_iter() @@ -584,11 +588,11 @@ impl DocumentFactoryV0 { documents: Vec<(Document, DocumentTypeRef)>, nonce_counter: &mut BTreeMap<(Identifier, Identifier), u64>, //IdentityID/ContractID -> nonce platform_version: &PlatformVersion, - recipient_owner_id: Identifier + recipient_owner_id: Option ) -> Result, ProtocolError> { documents .into_iter() - .map(|(document, document_type)| { + .map(|(mut document, document_type)| { if !document_type.documents_transferable().is_transferable() { return Err(DocumentError::TryingToTransferNonTransferableDocument { document: Box::new(document), @@ -602,14 +606,18 @@ impl DocumentFactoryV0 { .into()); }; + document.increment_revision()?; + document.set_updated_at(Some(Utc::now().timestamp_millis() as TimestampMillis)); + let nonce = nonce_counter .entry((document.owner_id(), document_type.data_contract_id())) .or_default(); + let transition = DocumentTransferTransition::from_document( document, document_type, *nonce, - recipient_owner_id, + recipient_owner_id.unwrap(), platform_version, None, None, @@ -627,11 +635,11 @@ impl DocumentFactoryV0 { documents: Vec<(Document, DocumentTypeRef)>, nonce_counter: &mut BTreeMap<(Identifier, Identifier), u64>, //IdentityID/ContractID -> nonce platform_version: &PlatformVersion, - price: Credits + price: Option ) -> Result, ProtocolError> { documents .into_iter() - .map(|(document, document_type)| { + .map(|(mut document, document_type)| { let Some(_document_revision) = document.revision() else { return Err(DocumentError::RevisionAbsentError { document: Box::new(document), @@ -642,10 +650,17 @@ impl DocumentFactoryV0 { let nonce = nonce_counter .entry((document.owner_id(), document_type.data_contract_id())) .or_default(); + + let now = Utc::now().timestamp_millis() as TimestampMillis; + + document.increment_revision()?; + document.set_updated_at(Some(now)); + document.set_transferred_at(Some(now)); + let transition = DocumentUpdatePriceTransition::from_document( document, document_type, - price, + price.unwrap(), *nonce, platform_version, None, @@ -664,11 +679,12 @@ impl DocumentFactoryV0 { documents: Vec<(Document, DocumentTypeRef)>, nonce_counter: &mut BTreeMap<(Identifier, Identifier), u64>, //IdentityID/ContractID -> nonce platform_version: &PlatformVersion, - price: Credits + price: Option, + recipient: Option ) -> Result, ProtocolError> { documents .into_iter() - .map(|(document, document_type)| { + .map(|(mut document, document_type)| { let Some(_document_revision) = document.revision() else { return Err(DocumentError::RevisionAbsentError { document: Box::new(document), @@ -677,12 +693,17 @@ impl DocumentFactoryV0 { }; let nonce = nonce_counter - .entry((document.owner_id(), document_type.data_contract_id())) + .entry((recipient.unwrap(), document_type.data_contract_id())) .or_default(); + + //document.set_owner_id(recipient.unwrap()); + document.increment_revision()?; + document.set_updated_at(Some(Utc::now().timestamp_millis() as TimestampMillis)); + let transition = DocumentPurchaseTransition::from_document( document, document_type, - price, + price.unwrap(), *nonce, platform_version, None, diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/action_type.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/action_type.rs index fd7c376f7b9..fb4cf51ccf1 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/action_type.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/action_type.rs @@ -39,9 +39,26 @@ impl TryFrom<&str> for DocumentTransitionActionType { "replace" => Ok(DocumentTransitionActionType::Replace), "delete" => Ok(DocumentTransitionActionType::Delete), "transfer" => Ok(DocumentTransitionActionType::Transfer), + "updatePrice" => Ok(DocumentTransitionActionType::UpdatePrice), + "purchase" => Ok(DocumentTransitionActionType::Purchase), action_type => Err(ProtocolError::Generic(format!( "unknown action type {action_type}" ))), } } } + + +impl From for &str { + fn from(value: DocumentTransitionActionType) -> Self { + match value { + DocumentTransitionActionType::Create => "Create", + DocumentTransitionActionType::Replace => "Replace", + DocumentTransitionActionType::Delete => "Delete", + DocumentTransitionActionType::Transfer => "Transfer", + DocumentTransitionActionType::Purchase => "Purchase", + DocumentTransitionActionType::UpdatePrice => "UpdatePrice", + DocumentTransitionActionType::IgnoreWhileBumpingRevision => "IgnoreWhileBumpingRevision" + } + } +} From 1a2520ee743262af397ca237a2bca62e1743a11f Mon Sep 17 00:00:00 2001 From: pshenmic Date: Fri, 31 Jan 2025 18:18:52 +0700 Subject: [PATCH 22/31] fix(wasm-dpp): lint fix --- .../src/document/document_factory/mod.rs | 6 ++- .../src/document/document_factory/v0/mod.rs | 41 +++++++++++-------- .../document_transition/action_type.rs | 5 ++- .../get_document_transitions_fixture.rs | 2 +- 4 files changed, 31 insertions(+), 23 deletions(-) diff --git a/packages/rs-dpp/src/document/document_factory/mod.rs b/packages/rs-dpp/src/document/document_factory/mod.rs index 8245a079f3c..b8aa2f56e9b 100644 --- a/packages/rs-dpp/src/document/document_factory/mod.rs +++ b/packages/rs-dpp/src/document/document_factory/mod.rs @@ -12,13 +12,13 @@ use crate::data_contract::document_type::DocumentTypeRef; use crate::document::Document; #[cfg(feature = "extended-document")] use crate::document::ExtendedDocument; +use crate::fee::Credits; #[cfg(feature = "state-transitions")] use crate::state_transition::documents_batch_transition::{ document_transition::action_type::DocumentTransitionActionType, DocumentsBatchTransition, }; use crate::util::entropy_generator::EntropyGenerator; pub use v0::DocumentFactoryV0; -use crate::fee::Credits; /// # Document Factory /// @@ -125,7 +125,9 @@ impl DocumentFactory { price: Option, ) -> Result { match self { - DocumentFactory::V0(v0) => v0.create_state_transition(documents_iter, nonce_counter, recipient, price), + DocumentFactory::V0(v0) => { + v0.create_state_transition(documents_iter, nonce_counter, recipient, price) + } } } diff --git a/packages/rs-dpp/src/document/document_factory/v0/mod.rs b/packages/rs-dpp/src/document/document_factory/v0/mod.rs index 36ed8e1e480..efca3e23801 100644 --- a/packages/rs-dpp/src/document/document_factory/v0/mod.rs +++ b/packages/rs-dpp/src/document/document_factory/v0/mod.rs @@ -22,7 +22,11 @@ use crate::document::{ extended_document::v0::ExtendedDocumentV0, serialization_traits::DocumentPlatformConversionMethodsV0, ExtendedDocument, }; +use crate::fee::Credits; use crate::prelude::{BlockHeight, CoreBlockHeight, TimestampMillis}; +use crate::state_transition::documents_batch_transition::document_transition::{ + DocumentPurchaseTransition, DocumentTransferTransition, DocumentUpdatePriceTransition, +}; #[cfg(feature = "state-transitions")] use crate::state_transition::documents_batch_transition::{ document_transition::{ @@ -32,8 +36,6 @@ use crate::state_transition::documents_batch_transition::{ DocumentsBatchTransition, DocumentsBatchTransitionV0, }; use itertools::Itertools; -use crate::fee::Credits; -use crate::state_transition::documents_batch_transition::document_transition::{DocumentPurchaseTransition, DocumentTransferTransition, DocumentUpdatePriceTransition}; const PROPERTY_FEATURE_VERSION: &str = "$version"; const PROPERTY_ENTROPY: &str = "$entropy"; @@ -213,7 +215,7 @@ impl DocumentFactoryV0 { >, nonce_counter: &mut BTreeMap<(Identifier, Identifier), u64>, //IdentityID/ContractID -> nonce, recipient: Option, - price: Option + price: Option, ) -> Result { let platform_version = PlatformVersion::get(self.protocol_version)?; let documents: Vec<( @@ -273,17 +275,19 @@ impl DocumentFactoryV0 { .collect(), nonce_counter, platform_version, - recipient - ), - DocumentTransitionActionType::UpdatePrice => Self::document_update_price_transitions( - documents - .into_iter() - .map(|(document, document_type, _)| (document, document_type)) - .collect(), - nonce_counter, - platform_version, - price + recipient, ), + DocumentTransitionActionType::UpdatePrice => { + Self::document_update_price_transitions( + documents + .into_iter() + .map(|(document, document_type, _)| (document, document_type)) + .collect(), + nonce_counter, + platform_version, + price, + ) + } DocumentTransitionActionType::Purchase => Self::document_purchase_transitions( documents .into_iter() @@ -292,14 +296,15 @@ impl DocumentFactoryV0 { nonce_counter, platform_version, price, - recipient + recipient, ), _ => { let action_type_name: &str = action.into(); Err(ProtocolError::InvalidStateTransitionType( action_type_name.to_string(), - ))}, + )) + } }) .collect::, ProtocolError>>()? .into_iter() @@ -588,7 +593,7 @@ impl DocumentFactoryV0 { documents: Vec<(Document, DocumentTypeRef)>, nonce_counter: &mut BTreeMap<(Identifier, Identifier), u64>, //IdentityID/ContractID -> nonce platform_version: &PlatformVersion, - recipient_owner_id: Option + recipient_owner_id: Option, ) -> Result, ProtocolError> { documents .into_iter() @@ -635,7 +640,7 @@ impl DocumentFactoryV0 { documents: Vec<(Document, DocumentTypeRef)>, nonce_counter: &mut BTreeMap<(Identifier, Identifier), u64>, //IdentityID/ContractID -> nonce platform_version: &PlatformVersion, - price: Option + price: Option, ) -> Result, ProtocolError> { documents .into_iter() @@ -680,7 +685,7 @@ impl DocumentFactoryV0 { nonce_counter: &mut BTreeMap<(Identifier, Identifier), u64>, //IdentityID/ContractID -> nonce platform_version: &PlatformVersion, price: Option, - recipient: Option + recipient: Option, ) -> Result, ProtocolError> { documents .into_iter() diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/action_type.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/action_type.rs index fb4cf51ccf1..afc2943983f 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/action_type.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/action_type.rs @@ -48,7 +48,6 @@ impl TryFrom<&str> for DocumentTransitionActionType { } } - impl From for &str { fn from(value: DocumentTransitionActionType) -> Self { match value { @@ -58,7 +57,9 @@ impl From for &str { DocumentTransitionActionType::Transfer => "Transfer", DocumentTransitionActionType::Purchase => "Purchase", DocumentTransitionActionType::UpdatePrice => "UpdatePrice", - DocumentTransitionActionType::IgnoreWhileBumpingRevision => "IgnoreWhileBumpingRevision" + DocumentTransitionActionType::IgnoreWhileBumpingRevision => { + "IgnoreWhileBumpingRevision" + } } } } diff --git a/packages/rs-dpp/src/tests/fixtures/get_document_transitions_fixture.rs b/packages/rs-dpp/src/tests/fixtures/get_document_transitions_fixture.rs index dfb531b5546..9c78a2b2e6e 100644 --- a/packages/rs-dpp/src/tests/fixtures/get_document_transitions_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/get_document_transitions_fixture.rs @@ -24,7 +24,7 @@ pub fn get_document_transitions_fixture<'a>( DocumentFactory::new(protocol_version).expect("expected to get document factory"); document_factory - .create_state_transition(documents, nonce_counter) + .create_state_transition(documents, nonce_counter, None, None) .expect("the transitions should be created") .transitions() .to_owned() From dbf1b7cbaa84c4c487946ee02d6a11d1e552665e Mon Sep 17 00:00:00 2001 From: pshenmic Date: Fri, 31 Jan 2025 18:24:06 +0700 Subject: [PATCH 23/31] chore(wasm-dpp): remove unused --- .../document_transfer_transition.rs | 27 ------------------- .../document_transition/mod.rs | 1 - 2 files changed, 28 deletions(-) delete mode 100644 packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_transfer_transition.rs diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_transfer_transition.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_transfer_transition.rs deleted file mode 100644 index c9c745d4098..00000000000 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_transfer_transition.rs +++ /dev/null @@ -1,27 +0,0 @@ -use wasm_bindgen::prelude::wasm_bindgen; -use dpp::state_transition::documents_batch_transition::document_transition::DocumentTransferTransition; - -#[wasm_bindgen(js_name=DocumentTransferTransition)] -#[derive(Debug, Clone)] -pub struct DocumentTransferTransitionWasm { - inner: DocumentTransferTransition, -} - -impl From for DocumentTransferTransitionWasm { - fn from(v: DocumentTransferTransition) -> Self { - Self { inner: v } - } -} - -impl From for DocumentTransferTransition { - fn from(v: DocumentTransferTransitionWasm) -> Self { - v.inner - } -} - -#[wasm_bindgen(js_class=DocumentTransferTransition)] -impl DocumentTransferTransitionWasm { -} - -impl DocumentTransferTransitionWasm { -} diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/mod.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/mod.rs index 05c6d9c30d7..834f4b56c06 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/mod.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/mod.rs @@ -1,5 +1,4 @@ mod document_create_transition; -mod document_transfer_transition; // mod document_delete_transition; // mod document_replace_transition; From 1207597eef9d6e5cbd00ef77ba86c00dba2b7d57 Mon Sep 17 00:00:00 2001 From: pshenmic Date: Fri, 31 Jan 2025 18:55:48 +0700 Subject: [PATCH 24/31] feat(js-dash-sdk): add NFT state transitions docs --- .../docs/platform/documents/broadcast.md | 18 ++++++---- .../docs/platform/documents/purchase.md | 33 +++++++++++++++++++ .../docs/platform/documents/transfer.md | 31 +++++++++++++++++ .../docs/platform/documents/updatePrice.md | 29 ++++++++++++++++ 4 files changed, 104 insertions(+), 7 deletions(-) create mode 100644 packages/js-dash-sdk/docs/platform/documents/purchase.md create mode 100644 packages/js-dash-sdk/docs/platform/documents/transfer.md create mode 100644 packages/js-dash-sdk/docs/platform/documents/updatePrice.md diff --git a/packages/js-dash-sdk/docs/platform/documents/broadcast.md b/packages/js-dash-sdk/docs/platform/documents/broadcast.md index 67e59a2d991..8ee2238d0ed 100644 --- a/packages/js-dash-sdk/docs/platform/documents/broadcast.md +++ b/packages/js-dash-sdk/docs/platform/documents/broadcast.md @@ -3,13 +3,17 @@ Parameters: -| parameters | type | required | Description | -|----------------------------|------------|----------|------------------------------------------------------------------------------| -| **documents** | Object | yes | | -| **documents.create** | ExtendedDocument[] | no | array of valid [created document](../documents/create.md) to create | -| **documents.replace** | ExtendedDocument[] | no | array of valid [created document](../documents/create.md) to replace | -| **documents.delete** | ExtendedDocument[] | no | array of valid [created document](../documents/create.md) to delete | -| **identity** | Identity | yes | A valid [registered identity](../identities/register.md) | +| parameters | type | required | Description | +|---------------------------|--------------------|----------|----------------------------------------------------------------------------------------| +| **documents** | Object | yes | | +| **documents.create** | ExtendedDocument[] | no | array of valid [created document](../documents/create.md) to create | +| **documents.replace** | ExtendedDocument[] | no | array of valid [created document](../documents/create.md) to replace | +| **documents.delete** | ExtendedDocument[] | no | array of valid [created document](../documents/create.md) to delete | +| **documents.transfer** | ExtendedDocument[] | no | array of valid [created document](../documents/create.md) to transfer | +| **documents.updatePrice** | ExtendedDocument[] | no | array of valid [created document](../documents/create.md) to set price | +| **documents.purchase** | ExtendedDocument[] | no | array of valid [created document](../documents/create.md) to purchase | +| **identity** | Identity | yes | A valid [registered identity](../identities/register.md) | +| **options** | DocumentTransitionParams | no | An object with two optional fields `price` and `receiver` that is used for NFT actions | **Example**: diff --git a/packages/js-dash-sdk/docs/platform/documents/purchase.md b/packages/js-dash-sdk/docs/platform/documents/purchase.md new file mode 100644 index 00000000000..e88d17db08a --- /dev/null +++ b/packages/js-dash-sdk/docs/platform/documents/purchase.md @@ -0,0 +1,33 @@ +**Usage**: `client.platform.documents.broadcast(documents, identity, options)` +**Description**: This method will broadcast a purchase state transition that buys the given document from other Identity. + +Parameters: + +| parameters | type | required | Description | +|------------------------|---------|------------------ |-------------------------------------------------------------------| +| **documents.purchase** | ExtendedDocument[] | no | array of valid [created document](../documents/create.md) to buy | +| **identity** | Identity | yes | A valid [registered identity](../identities/register.md) | +| **options** | DocumentTransitionParams | no | An object with field `price` (BigInt) and `receiver` (Identifier) | + +**Example**: +```js +const identityId = '';// Your identity identifier +const receiverId = ''; // Receiver identity identifier +const documentId = '' // Your document id +const price = BigInt(1000000) + +const identity = await client.platform.identities.get(identityId); +const receiverIdentity = await client.platform.identities.get(receiverId); + +const identity = await client.platform.identities.get(identityId); + +const [document] = await dash.platform.documents.get( + 'helloWorldContract.note', + { where: [['$id', '==', documentId]] }, +); + +await dash.platform.documents.broadcast({ updatePrice: [document], }, identity, { price, receiver: receiverIdentity.getId() }); +``` +**Note**: This method will change the ownership of the document to your identity, and seller identity will be credited with the amount specified in the updatePrice deducted from your balance. + +Returns: DocumentsBatchTransition diff --git a/packages/js-dash-sdk/docs/platform/documents/transfer.md b/packages/js-dash-sdk/docs/platform/documents/transfer.md new file mode 100644 index 00000000000..9200618a547 --- /dev/null +++ b/packages/js-dash-sdk/docs/platform/documents/transfer.md @@ -0,0 +1,31 @@ +**Usage**: `client.platform.documents.broadcast(documents, identity, options)` +**Description**: This method will broadcast a document transfer + +Parameters: + +| parameters | type | required | Description | +|-------------------|---------|------------------ |-----------------------------------------------------------------------| +| **documents.transfer** | ExtendedDocument[] | no | array of valid [created document](../documents/create.md) to transfer | +| **identity** | Identity | yes | A valid [registered identity](../identities/register.md) | +| **options** | DocumentTransitionParams | no | An object with `receiver` field | + +**Example**: +```js +const identityId = '';// Your identity identifier +const receiverId = ''; // Receiver identity identifier +const documentId = '' // Your document id + +const identity = await client.platform.identities.get(identityId); +const receiverIdentity = await client.platform.identities.get(receiverId); + +const [document] = await dash.platform.documents.get( + 'helloWorldContract.note', + { where: [['$id', '==', documentId]] }, +); + +await dash.platform.documents.broadcast({ transfer: [document], }, identity, { receiver: receiverIdentity.getId() }); +``` + +**Note**: Transfer transition changes the ownership of the given document to the receiver identity + +Returns: DocumentsBatchTransition diff --git a/packages/js-dash-sdk/docs/platform/documents/updatePrice.md b/packages/js-dash-sdk/docs/platform/documents/updatePrice.md new file mode 100644 index 00000000000..d1c4c284b10 --- /dev/null +++ b/packages/js-dash-sdk/docs/platform/documents/updatePrice.md @@ -0,0 +1,29 @@ +**Usage**: `client.platform.documents.broadcast(documents, identity, options)` +**Description**: This method will broadcast an update price state transition that sets a price for the given document. + +Parameters: + +| parameters | type | required | Description | +|---------------------------|---------|------------------ |---------------------------------------------------------------------------| +| **documents.updatePrice** | ExtendedDocument[] | no | array of valid [created document](../documents/create.md) to update price | +| **identity** | Identity | yes | A valid [registered identity](../identities/register.md) | +| **options** | DocumentTransitionParams | no | An object with field `price` (BigInt) | + +**Example**: +```js +const identityId = '';// Your identity identifier +const documentId = '' // Your document id +const price = BigInt(1000000) + +const identity = await client.platform.identities.get(identityId); + +const [document] = await dash.platform.documents.get( + 'helloWorldContract.note', + { where: [['$id', '==', documentId]] }, +); + +await dash.platform.documents.broadcast({ updatePrice: [document], }, identity, { price }); +``` +**Note**: This method sets the same price on all documents in the batch (only one is possible right now) + +Returns: DocumentsBatchTransition From 3443b3f2d0f50c6eeca9ab8ab256887ebd985272 Mon Sep 17 00:00:00 2001 From: pshenmic Date: Fri, 31 Jan 2025 18:57:10 +0700 Subject: [PATCH 25/31] chore(wasm-dpp): fix lint --- .../wasm-dpp/src/document/document_facade.rs | 10 +++---- packages/wasm-dpp/src/document/errors/mod.rs | 2 +- .../src/document/extended_document.rs | 4 ++- packages/wasm-dpp/src/document/factory.rs | 29 ++++++++++++------- 4 files changed, 28 insertions(+), 17 deletions(-) diff --git a/packages/wasm-dpp/src/document/document_facade.rs b/packages/wasm-dpp/src/document/document_facade.rs index a62fe8a083a..005b1b42239 100644 --- a/packages/wasm-dpp/src/document/document_facade.rs +++ b/packages/wasm-dpp/src/document/document_facade.rs @@ -1,9 +1,9 @@ -use std::rc::Rc; -use wasm_bindgen::{prelude::*, JsValue}; -use dpp::fee::Credits; -use dpp::identifier::Identifier; use crate::document::factory::DocumentFactoryWASM; use crate::{DataContractWasm, ExtendedDocumentWasm}; +use dpp::fee::Credits; +use dpp::identifier::Identifier; +use std::rc::Rc; +use wasm_bindgen::{prelude::*, JsValue}; use crate::document::state_transition::document_batch_transition::DocumentsBatchTransitionWasm; use crate::identifier::IdentifierWrapper; @@ -99,7 +99,7 @@ impl DocumentFacadeWasm { documents: &JsValue, nonce_counter_value: &js_sys::Object, //IdentityID/ContractID -> nonce, recipient: Option, - price: Option + price: Option, ) -> Result { self.factory .create_state_transition(documents, nonce_counter_value, recipient, price) diff --git a/packages/wasm-dpp/src/document/errors/mod.rs b/packages/wasm-dpp/src/document/errors/mod.rs index f900fde35d1..3b3b2018d38 100644 --- a/packages/wasm-dpp/src/document/errors/mod.rs +++ b/packages/wasm-dpp/src/document/errors/mod.rs @@ -79,7 +79,7 @@ pub fn from_document_to_js_error(e: DocumentError) -> JsValue { DocumentError::InvalidActionError(action) => InvalidActionError::new(action.into()).into(), DocumentError::TryingToDeleteIndelibleDocument { document } => { TryingToDeleteImmutableDocumentError::new((*document).into()).into() - }, + } DocumentError::TryingToTransferNonTransferableDocument { document } => { TryingToTransferNonTransferableDocumentError::new((*document).into()).into() } diff --git a/packages/wasm-dpp/src/document/extended_document.rs b/packages/wasm-dpp/src/document/extended_document.rs index a321e5f46b9..8fd0f7c8de8 100644 --- a/packages/wasm-dpp/src/document/extended_document.rs +++ b/packages/wasm-dpp/src/document/extended_document.rs @@ -1,4 +1,6 @@ -use dpp::document::{DocumentV0Getters, DocumentV0Setters, ExtendedDocument, EXTENDED_DOCUMENT_IDENTIFIER_FIELDS}; +use dpp::document::{ + DocumentV0Getters, DocumentV0Setters, ExtendedDocument, EXTENDED_DOCUMENT_IDENTIFIER_FIELDS, +}; use serde_json::Value as JsonValue; use dpp::platform_value::{Bytes32, Value}; diff --git a/packages/wasm-dpp/src/document/factory.rs b/packages/wasm-dpp/src/document/factory.rs index a6724bdc6c5..80aaa3f2ca9 100644 --- a/packages/wasm-dpp/src/document/factory.rs +++ b/packages/wasm-dpp/src/document/factory.rs @@ -13,19 +13,19 @@ use dpp::document::Document; use dpp::prelude::ExtendedDocument; -use dpp::identifier::Identifier; -use dpp::state_transition::documents_batch_transition::document_transition::action_type::DocumentTransitionActionType; -use dpp::version::PlatformVersion; -use std::convert::TryFrom; -use dpp::fee::Credits; use crate::document_batch_transition::DocumentsBatchTransitionWasm; use crate::entropy_generator::ExternalEntropyGenerator; +use crate::identifier::IdentifierWrapper; use crate::{ identifier::identifier_from_js_value, utils::{IntoWasm, ToSerdeJSONExt, WithJsError}, DataContractWasm, ExtendedDocumentWasm, }; -use crate::identifier::IdentifierWrapper; +use dpp::fee::Credits; +use dpp::identifier::Identifier; +use dpp::state_transition::documents_batch_transition::document_transition::action_type::DocumentTransitionActionType; +use dpp::version::PlatformVersion; +use std::convert::TryFrom; #[wasm_bindgen(js_name=DocumentTransitions)] #[derive(Debug, Default)] @@ -111,7 +111,7 @@ impl DocumentFactoryWASM { documents: &JsValue, nonce_counter_value: &js_sys::Object, //IdentityID/ContractID -> nonce recipient: Option, - price: Option + price: Option, ) -> Result { let mut nonce_counter = BTreeMap::new(); let mut contract_ids_to_check = HashSet::<&Identifier>::new(); @@ -179,7 +179,12 @@ impl DocumentFactoryWASM { let batch_transition = self .0 - .create_state_transition(documents, &mut nonce_counter, recipient.map(|e| { Identifier::from(e)}), price) + .create_state_transition( + documents, + &mut nonce_counter, + recipient.map(|e| Identifier::from(e)), + price, + ) .with_js_error()?; Ok(batch_transition.into()) @@ -282,14 +287,18 @@ fn extract_documents_by_action( let documents_replace = extract_documents_of_action(documents, "replace").with_js_error()?; let documents_delete = extract_documents_of_action(documents, "delete").with_js_error()?; let documents_transfer = extract_documents_of_action(documents, "transfer").with_js_error()?; - let documents_update_price = extract_documents_of_action(documents, "updatePrice").with_js_error()?; + let documents_update_price = + extract_documents_of_action(documents, "updatePrice").with_js_error()?; let documents_purchase = extract_documents_of_action(documents, "purchase").with_js_error()?; documents_by_action.insert(DocumentTransitionActionType::Create, documents_create); documents_by_action.insert(DocumentTransitionActionType::Replace, documents_replace); documents_by_action.insert(DocumentTransitionActionType::Delete, documents_delete); documents_by_action.insert(DocumentTransitionActionType::Transfer, documents_transfer); - documents_by_action.insert(DocumentTransitionActionType::UpdatePrice, documents_update_price); + documents_by_action.insert( + DocumentTransitionActionType::UpdatePrice, + documents_update_price, + ); documents_by_action.insert(DocumentTransitionActionType::Purchase, documents_purchase); Ok(documents_by_action) From 16e2a507cd9db312a8cc15977d01d7e5a1a60fdf Mon Sep 17 00:00:00 2001 From: pshenmic Date: Fri, 31 Jan 2025 19:02:44 +0700 Subject: [PATCH 26/31] chore(rs-dpp): fix lint --- .../document_transition/mod.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/mod.rs index 477847b113a..56b41be407f 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/mod.rs @@ -171,11 +171,11 @@ impl DocumentTransitionV0Methods for DocumentTransition { fn entropy(&self) -> Option> { match self { DocumentTransition::Create(t) => Some(Vec::from(t.entropy())), - DocumentTransition::Replace(t) => None, - DocumentTransition::Delete(t) => None, - DocumentTransition::Transfer(t) => None, - DocumentTransition::UpdatePrice(t) => None, - DocumentTransition::Purchase(t) => None, + DocumentTransition::Replace(_) => None, + DocumentTransition::Delete(_) => None, + DocumentTransition::Transfer(_) => None, + DocumentTransition::UpdatePrice(_) => None, + DocumentTransition::Purchase(_) => None, } } From cfe2b60e7dbf220de5d5a8591e696bf0d1117f58 Mon Sep 17 00:00:00 2001 From: pshenmic Date: Fri, 31 Jan 2025 19:02:56 +0700 Subject: [PATCH 27/31] fix(rs-dpp): fix features --- packages/rs-dpp/src/document/document_factory/v0/mod.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/rs-dpp/src/document/document_factory/v0/mod.rs b/packages/rs-dpp/src/document/document_factory/v0/mod.rs index efca3e23801..01c6ae99386 100644 --- a/packages/rs-dpp/src/document/document_factory/v0/mod.rs +++ b/packages/rs-dpp/src/document/document_factory/v0/mod.rs @@ -24,14 +24,12 @@ use crate::document::{ }; use crate::fee::Credits; use crate::prelude::{BlockHeight, CoreBlockHeight, TimestampMillis}; -use crate::state_transition::documents_batch_transition::document_transition::{ - DocumentPurchaseTransition, DocumentTransferTransition, DocumentUpdatePriceTransition, -}; #[cfg(feature = "state-transitions")] use crate::state_transition::documents_batch_transition::{ document_transition::{ action_type::DocumentTransitionActionType, DocumentCreateTransition, DocumentDeleteTransition, DocumentReplaceTransition, DocumentTransition, + DocumentPurchaseTransition, DocumentTransferTransition, DocumentUpdatePriceTransition, }, DocumentsBatchTransition, DocumentsBatchTransitionV0, }; From eb4c95333a058159312bf4062360bf6959949b9e Mon Sep 17 00:00:00 2001 From: pshenmic Date: Fri, 31 Jan 2025 19:05:41 +0700 Subject: [PATCH 28/31] fix(rs-dpp): lint fix --- packages/rs-dpp/src/document/document_factory/v0/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/rs-dpp/src/document/document_factory/v0/mod.rs b/packages/rs-dpp/src/document/document_factory/v0/mod.rs index 01c6ae99386..84508aa3cf5 100644 --- a/packages/rs-dpp/src/document/document_factory/v0/mod.rs +++ b/packages/rs-dpp/src/document/document_factory/v0/mod.rs @@ -28,8 +28,8 @@ use crate::prelude::{BlockHeight, CoreBlockHeight, TimestampMillis}; use crate::state_transition::documents_batch_transition::{ document_transition::{ action_type::DocumentTransitionActionType, DocumentCreateTransition, - DocumentDeleteTransition, DocumentReplaceTransition, DocumentTransition, - DocumentPurchaseTransition, DocumentTransferTransition, DocumentUpdatePriceTransition, + DocumentDeleteTransition, DocumentPurchaseTransition, DocumentReplaceTransition, + DocumentTransferTransition, DocumentTransition, DocumentUpdatePriceTransition, }, DocumentsBatchTransition, DocumentsBatchTransitionV0, }; From 30e86b7953fc34225411af14bc57f041e3e8fe1c Mon Sep 17 00:00:00 2001 From: pshenmic Date: Sat, 8 Feb 2025 01:19:18 +0700 Subject: [PATCH 29/31] fix(sdk): fix clippy warnings --- .../rs-dpp/src/data_contract/document_type/property/array.rs | 2 +- packages/rs-dpp/src/data_contract/document_type/property/mod.rs | 2 +- packages/wasm-dpp/src/document/document_facade.rs | 1 - packages/wasm-dpp/src/document/extended_document.rs | 1 - 4 files changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/document_type/property/array.rs b/packages/rs-dpp/src/data_contract/document_type/property/array.rs index fd4e533fd2b..1c7d9516fd9 100644 --- a/packages/rs-dpp/src/data_contract/document_type/property/array.rs +++ b/packages/rs-dpp/src/data_contract/document_type/property/array.rs @@ -70,7 +70,7 @@ impl ArrayItemType { } pub fn encode_value_ref_with_size(&self, value: &Value) -> Result, ProtocolError> { - return match self { + match self { ArrayItemType::String(_, _) => { let value_as_text = value.as_text().ok_or_else(get_field_type_matching_error)?; let vec = value_as_text.as_bytes().to_vec(); diff --git a/packages/rs-dpp/src/data_contract/document_type/property/mod.rs b/packages/rs-dpp/src/data_contract/document_type/property/mod.rs index 393fb89980f..808b643bda7 100644 --- a/packages/rs-dpp/src/data_contract/document_type/property/mod.rs +++ b/packages/rs-dpp/src/data_contract/document_type/property/mod.rs @@ -983,7 +983,7 @@ impl DocumentPropertyType { if value.is_null() { return Ok(vec![]); } - return match self { + match self { DocumentPropertyType::String(_) => { let value_as_text = value .as_text() diff --git a/packages/wasm-dpp/src/document/document_facade.rs b/packages/wasm-dpp/src/document/document_facade.rs index 005b1b42239..8df64a97f35 100644 --- a/packages/wasm-dpp/src/document/document_facade.rs +++ b/packages/wasm-dpp/src/document/document_facade.rs @@ -1,7 +1,6 @@ use crate::document::factory::DocumentFactoryWASM; use crate::{DataContractWasm, ExtendedDocumentWasm}; use dpp::fee::Credits; -use dpp::identifier::Identifier; use std::rc::Rc; use wasm_bindgen::{prelude::*, JsValue}; diff --git a/packages/wasm-dpp/src/document/extended_document.rs b/packages/wasm-dpp/src/document/extended_document.rs index 8fd0f7c8de8..08d81ff81cd 100644 --- a/packages/wasm-dpp/src/document/extended_document.rs +++ b/packages/wasm-dpp/src/document/extended_document.rs @@ -22,7 +22,6 @@ use crate::data_contract::DataContractWasm; #[allow(deprecated)] // BinaryType is unsed in unused code below use crate::document::BinaryType; use crate::document::{ConversionOptions, DocumentWasm}; -use crate::document_batch_transition::DocumentsBatchTransitionWasm; use crate::errors::RustConversionError; use crate::identifier::{identifier_from_js_value, IdentifierWrapper}; use crate::lodash::lodash_set; From e0798b509624784fe4369a58829d06cc9623824b Mon Sep 17 00:00:00 2001 From: pshenmic Date: Sat, 8 Feb 2025 10:38:06 +0700 Subject: [PATCH 30/31] fix(wasm-dpp): revert some lint --- .../rs-dpp/src/data_contract/document_type/property/array.rs | 2 +- .../rs-dpp/src/data_contract/document_type/property/mod.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/document_type/property/array.rs b/packages/rs-dpp/src/data_contract/document_type/property/array.rs index 1c7d9516fd9..fd4e533fd2b 100644 --- a/packages/rs-dpp/src/data_contract/document_type/property/array.rs +++ b/packages/rs-dpp/src/data_contract/document_type/property/array.rs @@ -70,7 +70,7 @@ impl ArrayItemType { } pub fn encode_value_ref_with_size(&self, value: &Value) -> Result, ProtocolError> { - match self { + return match self { ArrayItemType::String(_, _) => { let value_as_text = value.as_text().ok_or_else(get_field_type_matching_error)?; let vec = value_as_text.as_bytes().to_vec(); diff --git a/packages/rs-dpp/src/data_contract/document_type/property/mod.rs b/packages/rs-dpp/src/data_contract/document_type/property/mod.rs index 808b643bda7..ac8e79b8b1a 100644 --- a/packages/rs-dpp/src/data_contract/document_type/property/mod.rs +++ b/packages/rs-dpp/src/data_contract/document_type/property/mod.rs @@ -983,8 +983,8 @@ impl DocumentPropertyType { if value.is_null() { return Ok(vec![]); } - match self { - DocumentPropertyType::String(_) => { + return match self { + DocumentPropertyType::String(_) => { let value_as_text = value .as_text() .ok_or_else(|| get_field_type_matching_error(value))?; From c79d7e37e0c4367c6bcb5c80af950f26505b5395 Mon Sep 17 00:00:00 2001 From: pshenmic Date: Sat, 8 Feb 2025 10:46:32 +0700 Subject: [PATCH 31/31] fix(wasm-dpp): lint fix --- packages/rs-dpp/src/data_contract/document_type/property/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/rs-dpp/src/data_contract/document_type/property/mod.rs b/packages/rs-dpp/src/data_contract/document_type/property/mod.rs index ac8e79b8b1a..393fb89980f 100644 --- a/packages/rs-dpp/src/data_contract/document_type/property/mod.rs +++ b/packages/rs-dpp/src/data_contract/document_type/property/mod.rs @@ -984,7 +984,7 @@ impl DocumentPropertyType { return Ok(vec![]); } return match self { - DocumentPropertyType::String(_) => { + DocumentPropertyType::String(_) => { let value_as_text = value .as_text() .ok_or_else(|| get_field_type_matching_error(value))?;