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..e211364b27b --- /dev/null +++ b/packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/transfer.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 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/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..92f7e164e07 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=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=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 new file mode 100644 index 00000000000..c9c745d4098 --- /dev/null +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_transfer_transition.rs @@ -0,0 +1,27 @@ +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 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;