Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions packages/rs-sdk/src/platform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

pub mod block_info_from_metadata;
mod delegate;
mod document_query;
mod fetch;
pub mod fetch_current_no_parameters;
mod fetch_many;
Expand All @@ -17,10 +16,12 @@ pub mod query;
pub mod transition;
pub mod types;

pub mod documents;
pub mod group_actions;
pub mod tokens;

pub use dapi_grpc::platform::v0::{self as proto};
pub use dapi_grpc::platform::v0 as proto;
pub use documents::document_query::DocumentQuery;
pub use dpp::{
self as dpp,
document::Document,
Expand All @@ -32,7 +33,6 @@ pub use drive_proof_verifier::ContextProvider;
pub use drive_proof_verifier::MockContextProvider;
pub use rs_dapi_client as dapi;
pub use {
document_query::DocumentQuery,
fetch::Fetch,
fetch_many::FetchMany,
fetch_unproved::FetchUnproved,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use rs_dapi_client::transport::{
AppliedRequestSettings, BoxFuture, TransportError, TransportRequest,
};

use super::fetch::Fetch;
use crate::platform::Fetch;

// TODO: remove DocumentQuery once ContextProvider that provides data contracts is merged.

Expand Down
2 changes: 2 additions & 0 deletions packages/rs-sdk/src/platform/documents/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub mod document_query;
pub mod transitions;
219 changes: 219 additions & 0 deletions packages/rs-sdk/src/platform/documents/transitions/create.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
use crate::platform::transition::broadcast::BroadcastStateTransition;
use crate::platform::transition::put_settings::PutSettings;
use crate::{Error, Sdk};
use dpp::data_contract::accessors::v0::DataContractV0Getters;
use dpp::data_contract::document_type::DocumentType;
use dpp::data_contract::DataContract;
use dpp::document::{Document, DocumentV0Getters};
use dpp::identity::signer::Signer;
use dpp::identity::IdentityPublicKey;
use dpp::prelude::UserFeeIncrease;
use dpp::state_transition::batch_transition::methods::v0::DocumentsBatchTransitionMethodsV0;
use dpp::state_transition::batch_transition::methods::StateTransitionCreationOptions;
use dpp::state_transition::batch_transition::BatchTransition;
use dpp::state_transition::proof_result::StateTransitionProofResult;
use dpp::state_transition::StateTransition;
use dpp::tokens::token_payment_info::TokenPaymentInfo;
use dpp::version::PlatformVersion;

/// A builder to configure and broadcast document create transitions
pub struct DocumentCreateTransitionBuilder<'a> {
data_contract: &'a DataContract,
document_type: DocumentType,
document: Document,
document_state_transition_entropy: [u8; 32],
token_payment_info: Option<TokenPaymentInfo>,
settings: Option<PutSettings>,
user_fee_increase: Option<UserFeeIncrease>,
}

impl<'a> DocumentCreateTransitionBuilder<'a> {
/// Start building a create document request for the provided DataContract.
///
/// # Arguments
///
/// * `data_contract` - A reference to the data contract
/// * `document_type` - The document type to create
/// * `document` - The document to create
/// * `document_state_transition_entropy` - Entropy for the state transition
///
/// # Returns
///
/// * `Self` - The new builder instance
pub fn new(
data_contract: &'a DataContract,
document_type: DocumentType,
document: Document,
document_state_transition_entropy: [u8; 32],
) -> Self {
Self {
data_contract,
document_type,
document,
document_state_transition_entropy,
token_payment_info: None,
settings: None,
user_fee_increase: None,
}
}

/// Adds token payment info to the document create transition
///
/// # Arguments
///
/// * `token_payment_info` - The token payment info to add
///
/// # Returns
///
/// * `Self` - The updated builder
pub fn with_token_payment_info(mut self, token_payment_info: TokenPaymentInfo) -> Self {
self.token_payment_info = Some(token_payment_info);
self
}

/// Adds a user fee increase to the document create transition
///
/// # Arguments
///
/// * `user_fee_increase` - The user fee increase to add
///
/// # Returns
///
/// * `Self` - The updated builder
pub fn with_user_fee_increase(mut self, user_fee_increase: UserFeeIncrease) -> Self {
self.user_fee_increase = Some(user_fee_increase);
self
}

/// Adds settings to the document create transition
///
/// # Arguments
///
/// * `settings` - The settings to add
///
/// # Returns
///
/// * `Self` - The updated builder
pub fn with_settings(mut self, settings: PutSettings) -> Self {
self.settings = Some(settings);
self
}

/// Signs the document create transition
///
/// # Arguments
///
/// * `sdk` - The SDK instance
/// * `identity_public_key` - The public key of the identity
/// * `signer` - The signer instance
/// * `platform_version` - The platform version
/// * `options` - Optional state transition creation options
///
/// # Returns
///
/// * `Result<StateTransition, Error>` - The signed state transition or an error
pub async fn sign(
&self,
sdk: &Sdk,
identity_public_key: &IdentityPublicKey,
signer: &impl Signer,
platform_version: &PlatformVersion,
options: Option<StateTransitionCreationOptions>,
) -> Result<StateTransition, Error> {
let identity_contract_nonce = sdk
.get_identity_contract_nonce(
self.document.owner_id(),
self.data_contract.id(),
true,
self.settings,
)
.await?;

let state_transition = BatchTransition::new_document_creation_transition_from_document(
self.document.clone(),
self.document_type.as_ref(),
self.document_state_transition_entropy,
identity_public_key,
identity_contract_nonce,
self.user_fee_increase.unwrap_or_default(),
self.token_payment_info,
signer,
platform_version,
options,
)?;

Ok(state_transition)
}
}

/// Result types returned from document creation operations.
#[derive(Debug)]
pub enum DocumentCreateResult {
/// Document creation result containing the created document.
Document(Document),
}

impl Sdk {
/// Creates a new document on the platform.
///
/// This method broadcasts a document creation transition to add a new document
/// to the specified data contract. The result contains the created document.
///
/// # Arguments
///
/// * `create_document_transition_builder` - Builder containing document creation parameters
/// * `signing_key` - The identity public key for signing the transition
/// * `signer` - Implementation of the Signer trait for cryptographic signing
///
/// # Returns
///
/// Returns a `Result` containing a `DocumentCreateResult` on success, or an `Error` on failure.
///
/// # Errors
///
/// This function will return an error if:
/// - The transition signing fails
/// - Broadcasting the transition fails
/// - The proof verification returns an unexpected result type
/// - Document validation fails
pub async fn document_create<S: Signer>(
&self,
create_document_transition_builder: DocumentCreateTransitionBuilder<'_>,
signing_key: &IdentityPublicKey,
signer: &S,
) -> Result<DocumentCreateResult, Error> {
let platform_version = self.version();

let state_transition = create_document_transition_builder
.sign(self, signing_key, signer, platform_version, None)
.await?;

let proof_result = state_transition
.broadcast_and_wait::<StateTransitionProofResult>(self, None)
.await?;

match proof_result {
StateTransitionProofResult::VerifiedDocuments(documents) => {
if let Some((_, Some(document))) = documents.into_iter().next() {
Ok(DocumentCreateResult::Document(document))
} else {
Err(Error::DriveProofError(
drive::error::proof::ProofError::UnexpectedResultProof(
"Expected document in VerifiedDocuments result for create transition"
.to_string(),
),
vec![],
Default::default(),
))
}
}
_ => Err(Error::DriveProofError(
drive::error::proof::ProofError::UnexpectedResultProof(
"Expected VerifiedDocuments for document create transition".to_string(),
),
vec![],
Default::default(),
)),
}
}
}
Loading
Loading