Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(sdk): add NFT actions in the JS Dash SDK #2444

Open
wants to merge 36 commits into
base: v2.0-dev
Choose a base branch
from

Conversation

pshenmic
Copy link
Collaborator

@pshenmic pshenmic commented Jan 26, 2025

Issue being fixed or feature implemented

WASM DPP and JS Dash SDK is missing functions for creating NFT document transactions, there are 3 of them:

  • Transfer document (from one identity to another)
  • UpdatePrice document (sets a price for a document)
  • Purchase document (buys a document from someone)

This PR implements all three missing functions making it able to perform such operations from the browsers (Web).

What was done?

  • Added createTransferStateTransition method to ExtendedDocumentWasm
  • Added document transfer method in the JS Dash SDK
  • Fixed DPP incorrect error revision mismatch message
    tbd.

How Has This Been Tested?

In the testnet, with JS Dash SDK

https://testnet.platform-explorer.com/transaction/42175A63E25A316B5E0666317A3FF36A407EDDBA01D844982F68A6D10CBBFAF7
https://testnet.platform-explorer.com/transaction/36F3002686CA5ED23ED1FEFAD58803493055EFE55FC07517779AB267C8151747
https://testnet.platform-explorer.com/transaction/5CA156E676FA503CA4A520831484BE73B16EBE15599BB307605DE520B623AC1A

Breaking Changes

No

Checklist:

  • [] I have performed a self-review of my own code
  • [] I have commented my code, particularly in hard-to-understand areas
  • [] I have added or updated relevant unit/integration/functional/e2e tests
  • [] I have added "!" to the title and described breaking changes in the corresponding section if my code contains any
  • I have made corresponding changes to the documentation if needed

For repository code-owners and collaborators only

  • [] I have assigned this pull request to a milestone

Summary by CodeRabbit

  • New Features
    • Extended document state transitions to support optional recipient and pricing details.
    • Introduced capabilities for transfer, price update, and purchase document operations.
  • Bug Fixes
    • Improved error handling by providing clearer messages for non-transferable document operations.
    • Enhanced revision validation to report expected values more accurately.
  • Documentation
    • Updated API guides and examples to reflect new parameters and document transition actions.

@pshenmic pshenmic added the js-sdk JS Dash SDK related label Jan 26, 2025
@pshenmic pshenmic self-assigned this Jan 26, 2025
Copy link
Contributor

coderabbitai bot commented Jan 26, 2025

Walkthrough

The changes expand the document state transition functionality. Both core and WebAssembly factories now accept additional optional parameters—recipient and price—for enhanced document operations. New methods are introduced for handling transfer, update price, and purchase transitions, while error handling is improved through an added non-transferable document error. Documentation and broadcast logic in the JavaScript SDK have been updated to reflect these changes, and minor internal adjustments (including revision error reporting, cosmetic match refinements, and test fixture updates) have been applied.

Changes

File(s) Change Summary
packages/rs-dpp/src/document/document_factory/{mod.rs, v0/mod.rs} Updated create_state_transition signature to include optional recipient and price parameters; added methods for document_transfer_transitions, document_update_price_transitions, and document_purchase_transitions.
packages/rs-dpp/src/document/{errors.rs} and packages/wasm-dpp/src/document/errors/{mod.rs, trying_to_transfer_nontransferable_document_error.rs} Added new error variant/type (TryingToTransferNonTransferableDocument) and integrated its JS conversion to improve error handling for non-transferable document transfers.
packages/wasm-dpp/src/document/{document_facade.rs, factory.rs} Extended create_state_transition signatures with recipient and price parameters; added extraction logic for new document actions (“transfer”, “updatePrice”, “purchase”).
packages/js-dash-sdk/{src/SDK/Client/Platform/methods/documents/broadcast.ts, docs/platform/documents/*.md} Enhanced the broadcast method by introducing DocumentTransitionParams; updated documentation to describe new optional properties for transfer, updatePrice, and purchase actions.
packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/action_type.rs Extended the DocumentTransitionActionType mapping with a new “purchase” case and implemented From trait conversion for string slices.
packages/rs-drive-abci/src/.../transformer/v0/mod.rs, packages/rs-dpp/src/data_contract/.../mod.rs, packages/rs-dpp/src/state_transition/.../mod.rs, packages/rs-dpp/src/tests/fixtures/get_document_transitions_fixture.rs, src/calculator.py Modified revision error reporting by using the expected revision; refined string encoding error handling; applied cosmetic adjustments to match arms; updated test fixtures to pass additional parameters; renamed a global variable in calculator.py.

Sequence Diagram(s)

sequenceDiagram
    participant C as Client
    participant B as Broadcast (js-dash-sdk)
    participant F as DocumentFacade (WASM)
    participant DF as DocumentFactory (rs-dpp)
    participant DFV0 as DocumentFactoryV0 (rs-dpp)
    participant TH as Transition Handler

    C->>B: call broadcast(documents, identity, options)
    B->>F: forward call with recipient & price
    F->>DF: invoke create_state_transition(documents, nonce_counter, recipient, price)
    DF->>DFV0: pass documents & parameters
    alt Action Type: Transfer
        DFV0->>TH: document_transfer_transitions(recipient)
    else Action Type: UpdatePrice
        DFV0->>TH: document_update_price_transitions(price)
    else Action Type: Purchase
        DFV0->>TH: document_purchase_transitions(recipient, price)
    end
    DFV0-->>DF: return state transition
    DF-->>F: return updated state transition
    F-->>B: return result
    B-->>C: respond with DocumentsBatchTransition
Loading

Possibly related PRs

Suggested reviewers

  • QuantumExplorer
  • shumkov

Poem

I'm a rabbit in the code, hopping through each line,
Adding recipient and price so everything aligns.
New transitions for transfers, updates, and purchase in view,
Error hops and docs updated—oh, what a breakthrough!
With a twitch and a hop, our code now sings anew! 🐇


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 30e86b7 and e0798b5.

📒 Files selected for processing (1)
  • packages/rs-dpp/src/data_contract/document_type/property/mod.rs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/rs-dpp/src/data_contract/document_type/property/mod.rs
⏰ Context from checks skipped due to timeout of 90000ms (18)
  • GitHub Check: Rust packages (drive-abci) / Tests
  • GitHub Check: Rust packages (drive-abci) / Linting
  • GitHub Check: Rust packages (drive-abci) / Formatting
  • GitHub Check: Rust packages (drive) / Unused dependencies
  • GitHub Check: Rust packages (drive-abci) / Check each feature
  • GitHub Check: Rust packages (drive) / Linting
  • GitHub Check: Rust packages (drive) / Formatting
  • GitHub Check: Rust packages (dpp) / Tests
  • GitHub Check: Rust packages (dpp) / Linting
  • GitHub Check: Rust packages (dpp) / Check each feature
  • GitHub Check: Rust packages (dash-sdk) / Tests
  • GitHub Check: Rust packages (dash-sdk) / Check each feature
  • GitHub Check: Rust packages (dash-sdk) / Formatting
  • GitHub Check: Rust packages (dash-sdk) / Linting
  • GitHub Check: Build Docker images (Drive, drive, drive-abci) / Build Drive image
  • GitHub Check: Build Docker images (DAPI, dapi, dapi) / Build DAPI image
  • GitHub Check: Build Docker images (Dashmate helper, dashmate-helper, dashmate-helper) / Build Dashmate helper image
  • GitHub Check: Build JS packages / Build JS

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

# Conflicts:
#	packages/js-dash-sdk/src/SDK/Client/Platform/Platform.ts
#	packages/wasm-dpp/src/document/extended_document.rs
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cbddb8d and 9dad661.

📒 Files selected for processing (2)
  • packages/js-dash-sdk/src/SDK/Client/Platform/Platform.ts (3 hunks)
  • packages/wasm-dpp/src/document/extended_document.rs (3 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
packages/js-dash-sdk/src/SDK/Client/Platform/Platform.ts

[error] 64-64: Don't use 'Function' as a type.

Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.

(lint/complexity/noBannedTypes)


[error] 65-65: Don't use 'Function' as a type.

Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.

(lint/complexity/noBannedTypes)


[error] 66-66: Don't use 'Function' as a type.

Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.

(lint/complexity/noBannedTypes)

⏰ Context from checks skipped due to timeout of 90000ms (7)
  • GitHub Check: Rust packages (wasm-dpp) / Tests
  • GitHub Check: Rust packages (wasm-dpp) / Linting
  • GitHub Check: Rust packages (wasm-dpp) / Formatting
  • GitHub Check: Build Docker images (Drive, drive, drive-abci) / Build Drive image
  • GitHub Check: Build Docker images (Dashmate helper, dashmate-helper, dashmate-helper) / Build Dashmate helper image
  • GitHub Check: Build Docker images (DAPI, dapi, dapi) / Build DAPI image
  • GitHub Check: Build JS packages / Build JS
🔇 Additional comments (2)
packages/js-dash-sdk/src/SDK/Client/Platform/Platform.ts (2)

12-14: LGTM! New document method imports are properly organized.

The imports for NFT-related document methods are correctly added and follow the existing import pattern.


174-176: LGTM! Method bindings are correctly implemented.

The new NFT-related methods are properly bound to the Platform instance in the constructor.

packages/js-dash-sdk/src/SDK/Client/Platform/Platform.ts Outdated Show resolved Hide resolved
packages/wasm-dpp/src/document/extended_document.rs Outdated Show resolved Hide resolved
packages/wasm-dpp/src/document/extended_document.rs Outdated Show resolved Hide resolved
packages/wasm-dpp/src/document/extended_document.rs Outdated Show resolved Hide resolved
packages/wasm-dpp/src/document/extended_document.rs Outdated Show resolved Hide resolved
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 10

🔭 Outside diff range comments (1)
packages/wasm-dpp/src/document/factory.rs (1)

Line range hint 117-141: Consider improving nonce counter error handling.

The TODO comment and unwrap usage in the nonce counter processing could lead to runtime panics. Consider implementing proper error handling for robustness.

- // TODO: move to a function and handle errors instead of doing unwraps
- {
-     js_sys::Object::entries(nonce_counter_value)
-         .iter()
-         .for_each(|entry| {
-             let key_value = js_sys::Array::from(&entry);
-             let identity_id = identifier_from_js_value(&key_value.get(0)).unwrap();
+ fn process_nonce_counter(
+     nonce_counter_value: &js_sys::Object,
+     nonce_counter: &mut BTreeMap<(Identifier, Identifier), u64>
+ ) -> Result<(), JsValue> {
+     for entry in js_sys::Object::entries(nonce_counter_value).iter() {
+         let key_value = js_sys::Array::from(&entry);
+         let identity_id = identifier_from_js_value(&key_value.get(0))
+             .map_err(|_| JsValue::from_str("Invalid identity ID in nonce counter"))?;
🧹 Nitpick comments (11)
packages/rs-dpp/src/document/document_factory/v0/mod.rs (4)

35-36: Consider gating these new imports under the same feature flags.
Although these imports are needed for state transition operations, you may want to wrap them under #[cfg(feature = "state-transitions")] to avoid potential compilation issues when that feature isn’t enabled.


582-624: Consider incrementing revision or updatedAt when transferring documents.
Currently, the code does not increment revision or update any timestamps when transferring a document. If transfers logically constitute a mutation, you may wish to track them via the document’s revision or updatedAt fields, or clarify if it is intentional to leave them as is.


625-661: Add revision increment for price updates.
A document’s price is part of its data, implying a change that typically warrants incrementing revision or updating timestamps. Not accounting for it here could create confusion or conflicts.


662-698: Add revision increment for purchases or clarify immutability.
Purchasing a document might constitute an ownership or data change. Consider incrementing revision or marking updatedAt for clarity.

packages/wasm-dpp/src/document/errors/trying_to_transfer_nontransferable_document_error.rs (1)

1-19: Improve error message phrasing and reduce stored data.

  1. Minor grammar: "Trying to transfer a non-transferable document" would be clearer.
  2. Consider storing only the document ID in the error (instead of the entire DocumentWasm) unless you need the entire document. This can help minimize memory usage.
packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/updatePrice.ts (2)

5-12: JSDoc block references “Transfer document” instead of “Update price.”
Update the JSDoc to accurately reflect that this function updates the price, not that it transfers a document.

- /**
-  * Transfer document in the platform
-  *
+ /**
+  * Update price of the document in the platform
+  *

13-31: Rename debug message for clarity.
Although the function properly updates a document’s price, the debug log uses [Document#transfer]. Consider reflecting the method name for consistency.

- this.logger.debug(`[Document#transfer] Update price for document ${document.getId().toString()} to ${amount}`);
+ this.logger.debug(`[Document#updatePrice] Update price for document ${document.getId().toString()} to ${amount}`);
packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/transfer.ts (1)

13-18: Consider using a more specific return type.

The function currently returns Promise<any>. Consider defining a specific return type that represents the result of the state transition broadcast.

- ): Promise<any> {
+ ): Promise<StateTransitionBroadcastResult> {
packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/purchase.ts (1)

13-19: Consider using a more specific return type.

The function currently returns Promise<any>. Consider defining a specific return type that represents the result of the state transition broadcast.

- ): Promise<any> {
+ ): Promise<StateTransitionBroadcastResult> {
packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_transfer_transition.rs (2)

1-8: Add documentation for the WASM wrapper struct.

Consider adding documentation comments to explain:

  • The purpose of this WASM wrapper
  • How it relates to NFT document transfers
  • Usage examples from JavaScript

Add this documentation above the struct:

+/// WASM wrapper for DocumentTransferTransition to enable NFT document transfer operations
+/// from JavaScript/TypeScript code.
+///
+/// # Example (JavaScript)
+/// ```javascript
+/// const transfer = new DocumentTransferTransition();
+/// // ... configure transfer properties
+/// ```
 #[wasm_bindgen(js_name=DocumentTransferTransition)]
 #[derive(Debug, Clone)]
 pub struct DocumentTransferTransitionWasm {

10-20: Document conversion behavior and potential failure cases.

The From implementations look correct, but consider documenting any potential edge cases or data loss scenarios that might occur during conversion.

Add documentation to both From implementations:

+/// Converts from the DPP DocumentTransferTransition to its WASM wrapper.
+/// This conversion is infallible and preserves all data.
 impl From<DocumentTransferTransition> for DocumentTransferTransitionWasm {

+/// Converts from the WASM wrapper back to the DPP DocumentTransferTransition.
+/// This conversion is infallible and preserves all data.
 impl From<DocumentTransferTransitionWasm> for DocumentTransferTransition {
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9dad661 and 7940a09.

📒 Files selected for processing (14)
  • packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/purchase.ts (1 hunks)
  • packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/transfer.ts (1 hunks)
  • packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/updatePrice.ts (1 hunks)
  • packages/rs-dpp/src/document/document_factory/mod.rs (2 hunks)
  • packages/rs-dpp/src/document/document_factory/v0/mod.rs (4 hunks)
  • packages/rs-dpp/src/document/errors.rs (1 hunks)
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/transformer/v0/mod.rs (1 hunks)
  • packages/wasm-dpp/src/document/document_facade.rs (2 hunks)
  • packages/wasm-dpp/src/document/errors/mod.rs (3 hunks)
  • packages/wasm-dpp/src/document/errors/trying_to_transfer_nontransferable_document_error.rs (1 hunks)
  • packages/wasm-dpp/src/document/extended_document.rs (2 hunks)
  • packages/wasm-dpp/src/document/factory.rs (4 hunks)
  • packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_transfer_transition.rs (1 hunks)
  • packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/mod.rs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/wasm-dpp/src/document/extended_document.rs
⏰ Context from checks skipped due to timeout of 90000ms (20)
  • GitHub Check: Rust packages (drive-abci) / Tests
  • GitHub Check: Rust packages (drive-abci) / Formatting
  • GitHub Check: Rust packages (drive-abci) / Check each feature
  • GitHub Check: Rust packages (drive) / Unused dependencies
  • GitHub Check: Rust packages (drive) / Tests
  • GitHub Check: Rust packages (drive) / Linting
  • GitHub Check: Rust packages (drive) / Formatting
  • GitHub Check: Rust packages (dpp) / Unused dependencies
  • GitHub Check: Rust packages (dpp) / Tests
  • GitHub Check: Rust packages (dpp) / Linting
  • GitHub Check: Rust packages (dpp) / Check each feature
  • GitHub Check: Rust packages (dash-sdk) / Tests
  • GitHub Check: Rust packages (dash-sdk) / Unused dependencies
  • GitHub Check: Rust packages (dash-sdk) / Check each feature
  • GitHub Check: Rust packages (dash-sdk) / Formatting
  • GitHub Check: Rust packages (dash-sdk) / Linting
  • GitHub Check: Build Docker images (Drive, drive, drive-abci) / Build Drive image
  • GitHub Check: Build Docker images (Dashmate helper, dashmate-helper, dashmate-helper) / Build Dashmate helper image
  • GitHub Check: Build Docker images (DAPI, dapi, dapi) / Build DAPI image
  • GitHub Check: Build JS packages / Build JS
🔇 Additional comments (14)
packages/rs-dpp/src/document/document_factory/v0/mod.rs (1)

214-216: Validate optional parameters better.
recipient.unwrap() and price.unwrap() are used later but they are only assigned as optional here. It might be safer to explicitly match on the presence or absence of these parameters rather than unwrapping, to prevent runtime panics.

packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/updatePrice.ts (2)

1-4: Imports are consistent and straightforward.
No issues found with these import statements.


33-33: Default export is appropriate.
Exporting this function as the default aligns with your naming conventions for other methods in the directory.

packages/rs-dpp/src/document/errors.rs (1)

50-51: LGTM!

The new error variant follows the existing pattern and provides clear error messaging.

packages/wasm-dpp/src/document/errors/mod.rs (1)

9-9: LGTM!

The new error handling implementation follows the existing pattern and correctly integrates with the error handling system.

Also applies to: 36-36, 82-85

packages/wasm-dpp/src/document/document_facade.rs (2)

3-4: LGTM! New imports support NFT functionality.

The addition of Credits and Identifier types, along with IdentifierWrapper, provides the necessary types for handling NFT operations (prices and recipients).

Also applies to: 9-9


100-102: LGTM! Method signature enhancement for NFT support.

The create_state_transition method signature has been updated to include:

  • recipient: For document transfer operations
  • price: For document pricing operations

These changes align well with the PR objectives for NFT functionality.

packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/mod.rs (1)

2-2: LGTM! Added document transfer transition module.

The addition of document_transfer_transition module aligns with the PR objectives by providing the necessary infrastructure for NFT transfer operations.

packages/rs-dpp/src/document/document_factory/mod.rs (2)

21-21: LGTM! Added Credits type for NFT pricing.

The addition of the Credits import supports the price-related functionality for NFTs.


124-125: LGTM! Enhanced state transition creation for NFT support.

The create_state_transition method has been updated to:

  • Accept recipient information for transfers
  • Handle price information for NFT operations
  • Properly propagate these parameters to the V0 implementation

The changes maintain consistency with the WASM interface.

Also applies to: 128-128

packages/wasm-dpp/src/document/factory.rs (3)

20-20: LGTM! Added necessary imports for NFT support.

The addition of Credits and IdentifierWrapper imports supports the new NFT functionality.

Also applies to: 28-28


113-114: LGTM! Enhanced state transition creation with NFT parameters.

The create_state_transition method now properly handles:

  • Optional recipient for transfers
  • Optional price for NFT operations
  • Correct conversion of IdentifierWrapper to Identifier

Also applies to: 182-182


284-286: LGTM! Added NFT-specific document actions.

Successfully implemented the three new document actions required by the PR objectives:

  • transfer: For NFT ownership transfers
  • updatePrice: For updating NFT prices
  • purchase: For NFT purchases

The implementation follows the existing pattern for document actions.

Also applies to: 291-293

packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/transformer/v0/mod.rs (1)

723-723: Improved error message clarity for revision mismatch.

The change enhances error reporting by including the expected revision number instead of the actual revision. This makes it clearer to developers what revision number they should use to fix the error.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7940a09 and dac6932.

📒 Files selected for processing (1)
  • packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/broadcast.ts (3 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (18)
  • GitHub Check: Rust packages (drive-abci) / Linting
  • GitHub Check: Rust packages (drive-abci) / Tests
  • GitHub Check: Rust packages (drive-abci) / Formatting
  • GitHub Check: Rust packages (drive-abci) / Check each feature
  • GitHub Check: Rust packages (drive) / Unused dependencies
  • GitHub Check: Rust packages (drive) / Tests
  • GitHub Check: Rust packages (drive) / Linting
  • GitHub Check: Rust packages (dpp) / Unused dependencies
  • GitHub Check: Rust packages (dpp) / Tests
  • GitHub Check: Rust packages (dpp) / Linting
  • GitHub Check: Rust packages (dpp) / Check each feature
  • GitHub Check: Rust packages (dash-sdk) / Unused dependencies
  • GitHub Check: Rust packages (dash-sdk) / Tests
  • GitHub Check: Rust packages (dash-sdk) / Check each feature
  • GitHub Check: Rust packages (dash-sdk) / Linting
  • GitHub Check: Build Docker images (DAPI, dapi, dapi) / Build DAPI image
  • GitHub Check: Build Docker images (Dashmate helper, dashmate-helper, dashmate-helper) / Build Dashmate helper image
  • GitHub Check: Build JS packages / Build JS
🔇 Additional comments (2)
packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/broadcast.ts (2)

32-32: LGTM! Logging changes are consistent.

The debug logging has been properly updated to include transfer operations tracking.

Also applies to: 91-91


43-43: Verify integration with DPP state transition creation.

The changes look correct, but let's verify the integration with the DPP package:

Also applies to: 61-61

✅ Verification successful

Transfer documents are properly integrated with DPP state transition creation

The implementation correctly:

  • Includes transfer documents in the state transition array
  • Validates recipient presence for transfer operations
  • Follows consistent patterns with other document types (create, replace, delete)
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that the DPP package properly handles the new parameters

# Check if the DPP document.createStateTransition method accepts recipient and price
ast-grep --pattern 'createStateTransition($$$, $_, $recipient, $price)' 

# Check for any related tests
rg -l "createStateTransition.*recipient.*price" -g "*.spec.ts" -g "*.test.ts"

Length of output: 153


Script:

#!/bin/bash
# Find state transition creation implementation with broader patterns
ast-grep --pattern 'createStateTransition($_)'

# Also search for files containing state transition creation
rg -l "createStateTransition" --type ts

# Look for document array handling
rg "documents\." -A 5 -B 5 --type ts

Length of output: 33146

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (3)
packages/rs-dpp/src/document/document_factory/v0/mod.rs (1)

214-216: Consider documenting new parameters.

The newly added parameters recipient and price would benefit from doc comments clarifying their purpose and expected usage.

packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/action_type.rs (1)

52-64: Ensure consistency for variant-to-string mappings.

Some variants return uppercase version names (e.g. "Create", "Replace"), whereas the string keys in try_from are lowercase. Consider standardizing for clarity.

packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/broadcast.ts (1)

6-10: Add doc comments for DocumentTransitionParams.

Consider explaining the intended usage of bigint for price versus number, to reduce confusion for callers.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dac6932 and b7da382.

📒 Files selected for processing (3)
  • packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/broadcast.ts (3 hunks)
  • packages/rs-dpp/src/document/document_factory/v0/mod.rs (4 hunks)
  • packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/action_type.rs (1 hunks)
🔇 Additional comments (18)
packages/rs-dpp/src/document/document_factory/v0/mod.rs (5)

35-36: Imports look consistent with new functionality.

The newly added imports for Credits and the new transition types are aligned with the changes below.


269-297: Graceful handling of optional values is recommended.

These lines invoke transition methods (transfer, update price, purchase) with optional recipient/price. Ensure that cases where these options are missing trigger a safe and descriptive error rather than relying on usage in upstream code.


586-631: Avoid forced unwrap for recipient_owner_id.

Calling recipient_owner_id.unwrap() in DocumentTransferTransition::from_document can trigger a panic if recipient is None.


633-675: Avoid forced unwrap for price in document_update_price_transitions.

The code calls price.unwrap() at line 663, which will panic if price is absent.


677-718: Avoid forced unwrap for both recipient and price in document_purchase_transitions.

Lines 696 and 706 (recipient.unwrap() and price.unwrap()) risk panics. Also verify whether the commented-out ownership change (line 699) is intended.

packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/action_type.rs (1)

42-43: String matching for new action types looks correct.

Mapping "updatePrice" and "purchase" aligns well with the newly introduced transitions.

packages/js-dash-sdk/src/SDK/Client/Platform/methods/documents/broadcast.ts (12)

1-1: Import statements appear valid.

Importing ExtendedDocument and Identifier from @dashevo/wasm-dpp is consistent with the new NFT functionalities.


19-20: Documentation updated properly.

The new JSDoc params for identity and options provide clarity for these arguments.


27-30: Additional operations recognized (transfer, updatePrice, purchase).

Expanding the documents object to handle these new arrays is consistent with the underlying transitions.


33-33: Optional parameters integrated smoothly.

Optional options parameter properly references DocumentTransitionParams.


39-41: Enhanced logging to include new operations.

Providing counts for transfer, update price, and purchase is helpful for debugging.


52-54: Merging new document types into a single list is coherent.

Ensures consistent handling of all document operations in a unified flow.


61-63: Receiver check prevents runtime errors.

Throwing an error when documents.transfer is non-empty but options?.receiver is missing protects from invalid usage.


65-67: Enforces required price for updatePrice.

Ensures users cannot proceed without specifying the price for update operations.


69-75: Purchase operation validation is precise.

Checking both price and receiver fields ensures correct usage, and setting the new owner properly.


80-85: Correctly manages the identity contract nonce.

Mapping the identityContractNonce to the identity and contract ensures correct sequence for transitions.


86-91: State transition creation respects new parameters.

createStateTransition passing options?.receiver and options?.price is aligned with the Rust side changes.


121-121: Logging of transfer documents is consistent with earlier logs.

Matching the new operation logs fosters debugging consistency.

Comment on lines +101 to +102
recipient: Option<IdentifierWrapper>,
price: Option<Credits>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks strange here, to be honest. For which exact document it applies? I think these params must be a part of document information

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For NFT operations, like transfer, updatePrice or purchase. Neither Document or ExtendedDocument have such fields

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then we need to accept another structure that will contain document and params

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just wondering why do we need document for transfer? We need just ID, isn't ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then we need to accept another structure that will contain document and params

Should I revert back to this approach?
image

I just wondering why do we need document for transfer? We need just ID, isn't ?

Yes, it is possible, however there are no such methods in the rs-dpp yet (only from_document)

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🔭 Outside diff range comments (1)
packages/js-dash-sdk/docs/platform/documents/broadcast.md (1)

1-1: Update method signature to include options parameter.

The method signature in the usage section should be updated to reflect the new optional parameter.

-**Usage**: `client.platform.document.broadcast(documents, identity)`
+**Usage**: `client.platform.document.broadcast(documents, identity, options)`

Also applies to: 16-16

🧹 Nitpick comments (6)
packages/js-dash-sdk/docs/platform/documents/transfer.md (2)

4-11: Table Formatting: Replace Hard Tabs with Spaces
The parameter table is informative; however, static analysis indicates that hard tabs are used (see line 7). To adhere to markdownlint conventions, please replace any hard tabs with spaces to ensure consistent table formatting.

🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

7-7: Hard tabs
Column: 50

(MD010, no-hard-tabs)


29-31: Informative Note with Return Information
The note at the end effectively clarifies that the transfer transition alters document ownership. The return type ("DocumentsBatchTransition") is clearly stated. Optionally, you might expand on any side effects or subsequent steps for users after invoking the broadcast method.

packages/rs-dpp/src/document/document_factory/v0/mod.rs (1)

702-702: Remove commented out code.

The commented line //document.set_owner_id(recipient.unwrap()); should be removed if it's no longer needed.

packages/js-dash-sdk/docs/platform/documents/updatePrice.md (2)

14-16: Add type annotations in example code.

The example should include type annotations for better clarity:

-const identityId = '';// Your identity identifier
-const documentId = '' // Your document id
-const price = BigInt(1000000)
+const identityId: string = '';// Your identity identifier
+const documentId: string = '' // Your document id
+const price: bigint = BigInt(1000000)

27-27: Clarify batch limitation in note.

The note about batch limitation should be more specific about why only one price is possible and whether this is a temporary limitation.

-**Note**: This method sets the same price on all documents in the batch (only one is possible right now)
+**Note**: This method sets the same price on all documents in the batch. Currently, the platform only supports setting one price per batch. This limitation may be removed in future versions.
packages/js-dash-sdk/docs/platform/documents/broadcast.md (1)

31-32: Add examples for new NFT actions.

The example section only shows document creation. Consider adding examples for transfer, updatePrice, and purchase actions.

Would you like me to generate example code for the new NFT actions?

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ccf0921 and 30e86b7.

📒 Files selected for processing (14)
  • packages/js-dash-sdk/docs/platform/documents/broadcast.md (1 hunks)
  • packages/js-dash-sdk/docs/platform/documents/purchase.md (1 hunks)
  • packages/js-dash-sdk/docs/platform/documents/transfer.md (1 hunks)
  • packages/js-dash-sdk/docs/platform/documents/updatePrice.md (1 hunks)
  • packages/rs-dpp/src/data_contract/document_type/property/array.rs (1 hunks)
  • packages/rs-dpp/src/data_contract/document_type/property/mod.rs (1 hunks)
  • packages/rs-dpp/src/document/document_factory/mod.rs (2 hunks)
  • packages/rs-dpp/src/document/document_factory/v0/mod.rs (4 hunks)
  • packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/action_type.rs (1 hunks)
  • packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/mod.rs (1 hunks)
  • packages/rs-dpp/src/tests/fixtures/get_document_transitions_fixture.rs (1 hunks)
  • packages/wasm-dpp/src/document/document_facade.rs (2 hunks)
  • packages/wasm-dpp/src/document/errors/mod.rs (3 hunks)
  • packages/wasm-dpp/src/document/factory.rs (4 hunks)
✅ Files skipped from review due to trivial changes (2)
  • packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/mod.rs
  • packages/rs-dpp/src/data_contract/document_type/property/mod.rs
🚧 Files skipped from review as they are similar to previous changes (3)
  • packages/wasm-dpp/src/document/errors/mod.rs
  • packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/action_type.rs
  • packages/wasm-dpp/src/document/document_facade.rs
🧰 Additional context used
🪛 markdownlint-cli2 (0.17.2)
packages/js-dash-sdk/docs/platform/documents/transfer.md

7-7: Hard tabs
Column: 50

(MD010, no-hard-tabs)

packages/js-dash-sdk/docs/platform/documents/purchase.md

7-7: Hard tabs
Column: 55

(MD010, no-hard-tabs)

packages/js-dash-sdk/docs/platform/documents/updatePrice.md

7-7: Hard tabs
Column: 58

(MD010, no-hard-tabs)

⏰ Context from checks skipped due to timeout of 90000ms (11)
  • GitHub Check: Rust packages (wasm-dpp) / Unused dependencies
  • GitHub Check: Rust packages (wasm-dpp) / Tests
  • GitHub Check: Rust packages (wasm-dpp) / Linting
  • GitHub Check: Rust packages (drive-abci) / Unused dependencies
  • GitHub Check: Rust packages (drive-abci) / Tests
  • GitHub Check: Rust packages (drive-abci) / Check each feature
  • GitHub Check: Rust packages (drive-abci) / Linting
  • GitHub Check: Rust packages (drive) / Tests
  • GitHub Check: Rust packages (dpp) / Tests
  • GitHub Check: Build Docker images (Drive, drive, drive-abci) / Build Drive image
  • GitHub Check: Build JS packages / Build JS
🔇 Additional comments (13)
packages/js-dash-sdk/docs/platform/documents/transfer.md (2)

1-3: Clear and Concise Overview for API Usage
The "Usage" and "Description" sections clearly communicate how to invoke the new broadcast method for transferring documents. The instructions are straightforward and provide a good entry point for users.


12-27: Example Code Block is Well-Structured
The provided example clearly demonstrates how to retrieve identities/documents and subsequently call the broadcast method. This helps in understanding the flow of NFT document transfer. Consider, if possible, mentioning what the expected return (DocumentsBatchTransition) looks like or linking to further documentation on its structure.

packages/rs-dpp/src/tests/fixtures/get_document_transitions_fixture.rs (1)

26-27: LGTM!

The test fixture has been correctly updated to support the new NFT actions by adding optional parameters for recipient and price.

packages/rs-dpp/src/data_contract/document_type/property/array.rs (1)

72-119: LGTM!

The changes consistently use the to_* method naming pattern, improving code readability while maintaining the same functionality.

🧰 Tools
🪛 GitHub Check: Rust packages (drive) / Linting

[failure] 72-72: mismatched types
error[E0308]: mismatched types
--> packages/rs-dpp/src/data_contract/document_type/property/array.rs:72:64
|
72 | pub fn encode_value_ref_with_size(&self, value: &Value) -> Result<Vec, ProtocolError> {
| -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected Result<Vec<u8>, ProtocolError>, found ()
| |
| implicitly returns () as its body has no tail or return expression
...
119 | };
| - help: remove this semicolon to return this value
|
= note: expected enum std::result::Result<std::vec::Vec<u8>, errors::protocol_error::ProtocolError>
found unit type ()

🪛 GitHub Check: Rust packages (dpp) / Linting

[failure] 72-72: mismatched types
error[E0308]: mismatched types
--> packages/rs-dpp/src/data_contract/document_type/property/array.rs:72:64
|
72 | pub fn encode_value_ref_with_size(&self, value: &Value) -> Result<Vec, ProtocolError> {
| -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected Result<Vec<u8>, ProtocolError>, found ()
| |
| implicitly returns () as its body has no tail or return expression
...
119 | };
| - help: remove this semicolon to return this value
|
= note: expected enum std::result::Result<std::vec::Vec<u8>, errors::protocol_error::ProtocolError>
found unit type ()

🪛 GitHub Check: Rust packages (dash-sdk) / Linting

[failure] 72-72: mismatched types
error[E0308]: mismatched types
--> packages/rs-dpp/src/data_contract/document_type/property/array.rs:72:64
|
72 | pub fn encode_value_ref_with_size(&self, value: &Value) -> Result<Vec, ProtocolError> {
| -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected Result<Vec<u8>, ProtocolError>, found ()
| |
| implicitly returns () as its body has no tail or return expression
...
119 | };
| - help: remove this semicolon to return this value
|
= note: expected enum std::result::Result<std::vec::Vec<u8>, errors::protocol_error::ProtocolError>
found unit type ()

packages/rs-dpp/src/document/document_factory/mod.rs (1)

114-126: LGTM!

The changes correctly implement the NFT actions by:

  1. Adding optional parameters for recipient and price
  2. Properly delegating to the versioned factory implementation

The implementation aligns well with the PR objectives for supporting NFT document transactions.

Also applies to: 127-131

packages/wasm-dpp/src/document/factory.rs (3)

119-120: Address the TODO comment about error handling.

The comment indicates that error handling needs improvement. Consider implementing proper error handling instead of using unwrap.

Would you like me to help implement proper error handling for the nonce counter parsing?


289-292: LGTM! New NFT actions added.

The implementation correctly adds support for the three NFT actions:

  • transfer: For transferring documents between identities
  • updatePrice: For setting document prices
  • purchase: For purchasing documents

297-302: LGTM! Action mapping implemented correctly.

The new NFT actions are properly mapped to their corresponding transition types in the documents_by_action hashmap.

packages/rs-dpp/src/document/document_factory/v0/mod.rs (4)

619-624: Avoid forced unwrap for recipient_owner_id in Transfer transitions.

Similar to previous review comments, using unwrap() on recipient_owner_id can cause a panic. Return a descriptive error instead.

-    recipient_owner_id.unwrap(),
+    recipient_owner_id.ok_or_else(|| ProtocolError::GenericError(
+        "Recipient is required for a transfer transition".to_string()
+    ))?,

663-667: Avoid forced unwrap for price in UpdatePrice transitions.

Similar to previous review comments, using unwrap() on price can cause a panic. Return a descriptive error instead.

-    price.unwrap(),
+    price.ok_or_else(|| ProtocolError::GenericError(
+        "Price is required for an update price transition".to_string()
+    ))?,

698-700: Avoid forced unwrap for recipient in Purchase transitions.

Using unwrap() on recipient can cause a panic. Return a descriptive error instead.

-    entry((recipient.unwrap(), document_type.data_contract_id()))
+    entry((recipient.ok_or_else(|| ProtocolError::GenericError(
+        "Recipient is required for a purchase transition".to_string()
+    ))?, document_type.data_contract_id()))

706-710: Avoid forced unwrap for price in Purchase transitions.

Similar to previous review comments, using unwrap() on price can cause a panic. Return a descriptive error instead.

-    price.unwrap(),
+    price.ok_or_else(|| ProtocolError::GenericError(
+        "Price is required for a purchase transition".to_string()
+    ))?,
packages/js-dash-sdk/docs/platform/documents/purchase.md (1)

22-22: ⚠️ Potential issue

Remove duplicate identity initialization.

The identity is initialized twice in the example code.

-const identity = await client.platform.identities.get(identityId);

Likely invalid or redundant comment.

{ where: [['$id', '==', documentId]] },
);

await dash.platform.documents.broadcast({ updatePrice: [document], }, identity, { price, receiver: receiverIdentity.getId() });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix incorrect action type in example code.

The example uses updatePrice instead of purchase in the broadcast call.

-await dash.platform.documents.broadcast({ updatePrice: [document], }, identity, { price, receiver: receiverIdentity.getId() });
+await dash.platform.documents.broadcast({ purchase: [document], }, identity, { price, receiver: receiverIdentity.getId() });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
await dash.platform.documents.broadcast({ updatePrice: [document], }, identity, { price, receiver: receiverIdentity.getId() });
await dash.platform.documents.broadcast({ purchase: [document], }, identity, { price, receiver: receiverIdentity.getId() });

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
js-sdk JS Dash SDK related
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants