Skip to content

Conversation

@shumkov
Copy link
Collaborator

@shumkov shumkov commented Dec 28, 2025

Issue being fixed or feature implemented

Currently, state transition methods accept many arguments instead of typed objects, which is a better UX.

What was done?

  • Refactored state transitions methods to accept typed objects with a signer.
  • Updated return values.

How Has This Been Tested?

With functional tests

Breaking Changes

Public API of Evo SDK is changed

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

    • Six new document operations available: create, replace, delete, transfer, purchase, and set price.
  • Refactor

    • Simplified contract and identity operation signatures to accept single options objects instead of multiple parameters.
    • Enhanced result types with structured getters for improved data access.
    • Strengthened TypeScript bindings and input validation across state transition operations.

✏️ Tip: You can customize this high-level summary in your review settings.

@shumkov shumkov self-assigned this Dec 28, 2025
@github-actions github-actions bot added this to the v3.0.0 milestone Dec 28, 2025
@shumkov shumkov moved this to In review / testing in Platform team Dec 28, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 28, 2025

📝 Walkthrough

Walkthrough

The PR refactors the WASM SDK API from granular, multi-parameter method signatures to a consolidated options-based approach. It introduces helper functions for extracting and converting values from JavaScript option objects, replaces contract and identity state transition methods with option-driven signatures, and adds comprehensive document operation support with strongly-typed result objects.

Changes

Cohort / File(s) Summary
Helper Functions for Options Extraction
packages/wasm-dpp2/src/data_contract/model.rs, packages/wasm-dpp2/src/identity/public_key.rs, packages/wasm-sdk/src/settings.rs
Adds three new public helper methods: DataContractWasm::try_from_options(), IdentityPublicKeyWasm::try_from_options(), and extract_settings_from_options(). Each retrieves and validates a typed field from a JavaScript options object, returning errors for missing, undefined, or null values, and handles type conversion via to_wasm() or dedicated parsing.
Contract State Transitions
packages/wasm-sdk/src/state_transitions/contracts/mod.rs
Refactors contract_publish() and contract_update() methods to accept single option objects (ContractPublishOptionsJs, ContractUpdateOptionsJs) instead of individual parameters. Introduces option extraction via helper functions (try_from_options(), extract_settings_from_options()) for contract, signer, and settings data. Removes manual per-field argument handling and consolidates broadcast logic.
Document State Transitions
packages/wasm-sdk/src/state_transitions/documents/mod.rs
Adds six new async methods (document_create, document_replace, document_delete, document_transfer, document_purchase, document_set_price) with corresponding option types and result wrappers. Introduces consistent pattern: parse options, extract identity/contract data, construct document instances, build batch transitions, and broadcast. Replaces ad-hoc signer/key handling with new WASM-based bindings.
Identity State Transitions
packages/wasm-sdk/src/state_transitions/identity/mod.rs
Refactors six methods (identity_create, identity_top_up, identity_credit_transfer, identity_credit_withdrawal, identity_update, masternode_vote) from multi-parameter signatures to single option object parameters. Introduces corresponding option input types, result wrappers with typed getters, and deserialization helpers. Replaces manual cryptographic argument parsing with WASM-dpp2 abstractions for asset lock proofs, private keys, and signers.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 Options bundled, parameters freed,
From scattered args to structs we plead,
Document ops bloom in six-fold grace,
Each broadcast finds its helper place,
The API garden grows more neat!

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: refactoring state transition methods to accept typed parameters instead of individual arguments, which is the primary objective across multiple files.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refactor/state-transition-methods

📜 Recent review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 517862d and 0129f34.

📒 Files selected for processing (7)
  • packages/wasm-dpp2/src/data_contract/model.rs
  • packages/wasm-dpp2/src/identity/public_key.rs
  • packages/wasm-sdk/src/settings.rs
  • packages/wasm-sdk/src/state_transitions/contracts/mod.rs
  • packages/wasm-sdk/src/state_transitions/documents/mod.rs
  • packages/wasm-sdk/src/state_transitions/identity/mod.rs
  • packages/wasm-sdk/src/state_transitions/tokens/mod.rs
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.rs: Rust code must pass cargo clippy --workspace linter checks
Rust code must be formatted using cargo fmt --all

**/*.rs: Use 4-space indent for Rust files
Follow rustfmt defaults and keep code clippy-clean for Rust modules
Use snake_case for Rust module names
Use PascalCase for Rust type names
Use SCREAMING_SNAKE_CASE for Rust constants

Files:

  • packages/wasm-sdk/src/settings.rs
  • packages/wasm-dpp2/src/identity/public_key.rs
  • packages/wasm-dpp2/src/data_contract/model.rs
  • packages/wasm-sdk/src/state_transitions/identity/mod.rs
  • packages/wasm-sdk/src/state_transitions/contracts/mod.rs
  • packages/wasm-sdk/src/state_transitions/documents/mod.rs
🧠 Learnings (20)
📓 Common learnings
Learnt from: QuantumExplorer
Repo: dashpay/platform PR: 2711
File: packages/wasm-sdk/AI_REFERENCE.md:771-783
Timestamp: 2025-07-28T20:00:08.502Z
Learning: In packages/wasm-sdk/AI_REFERENCE.md, the documentation correctly shows the actual SDK method signatures (including identityCreate and identityTopUp with their full parameter lists), which may differ from the UI inputs shown in fixed_definitions.json. The UI may collect fewer parameters from users while handling additional requirements internally.
Learnt from: thephez
Repo: dashpay/platform PR: 2754
File: packages/wasm-sdk/api-definitions.json:1285-1285
Timestamp: 2025-09-03T19:33:21.688Z
Learning: In packages/wasm-sdk/api-definitions.json, thephez prefers to keep the existing "ripemd160hash20bytes1234" placeholder for ECDSA_HASH160 data field in documentation examples rather than using a valid base64-encoded format, maintaining consistency with the previous documentation approach.
Learnt from: lklimek
Repo: dashpay/platform PR: 2405
File: packages/wasm-sdk/src/verify.rs:26-68
Timestamp: 2025-02-10T11:26:36.709Z
Learning: In the wasm-sdk package, empty vectors and placeholder values are intentionally used in verification functions during the proof-of-concept stage to ensure proper compilation and type checking.
Learnt from: thephez
Repo: dashpay/platform PR: 2739
File: packages/wasm-sdk/test/ui-automation/tests/state-transitions.spec.js:1-171
Timestamp: 2025-09-02T13:30:17.703Z
Learning: In packages/wasm-sdk/index.html, state transition definitions are loaded dynamically from api-definitions.json via the loadApiDefinitions() function that fetches './api-definitions.json'. The UI doesn't have hardcoded transition definitions - instead it populates categories, types, inputs, and labels from this JSON configuration file at runtime.
Learnt from: thephez
Repo: dashpay/platform PR: 2739
File: packages/wasm-sdk/test/ui-automation/tests/state-transitions.spec.js:1-171
Timestamp: 2025-09-02T13:30:17.703Z
Learning: In packages/wasm-sdk/index.html, state transition definitions are loaded dynamically from api-definitions.json rather than being hardcoded in the HTML file. The UI loads transition categories, types, inputs, and labels from this JSON configuration file.
📚 Learning: 2024-11-20T10:01:50.837Z
Learnt from: QuantumExplorer
Repo: dashpay/platform PR: 2257
File: packages/rs-drive-abci/src/platform_types/platform_state/v0/old_structures/mod.rs:94-94
Timestamp: 2024-11-20T10:01:50.837Z
Learning: In `packages/rs-drive-abci/src/platform_types/platform_state/v0/old_structures/mod.rs`, when converting with `PublicKey::try_from`, it's acceptable to use `.expect()` to handle potential conversion errors.

Applied to files:

  • packages/wasm-dpp2/src/identity/public_key.rs
📚 Learning: 2024-10-06T16:11:34.946Z
Learnt from: QuantumExplorer
Repo: dashpay/platform PR: 2215
File: packages/rs-drive-abci/src/execution/platform_events/core_based_updates/update_masternode_identities/create_owner_identity/v1/mod.rs:19-30
Timestamp: 2024-10-06T16:11:34.946Z
Learning: In the Rust file `packages/rs-drive-abci/src/execution/platform_events/core_based_updates/update_masternode_identities/create_owner_identity/v1/mod.rs`, within the `create_owner_identity_v1` function, the `add_public_keys` method of the `Identity` struct cannot fail and does not require explicit error handling.

Applied to files:

  • packages/wasm-dpp2/src/identity/public_key.rs
  • packages/wasm-sdk/src/state_transitions/identity/mod.rs
📚 Learning: 2025-08-05T13:55:39.147Z
Learnt from: thephez
Repo: dashpay/platform PR: 2718
File: packages/wasm-sdk/index.html:0-0
Timestamp: 2025-08-05T13:55:39.147Z
Learning: The get_identity_keys_with_proof_info function in the Rust WASM bindings does not support the "search" key request type and lacks the searchPurposeMap parameter. When proof mode is enabled with keyRequestType === 'search', the implementation falls back to the non-proof version (get_identity_keys) to maintain functionality.

Applied to files:

  • packages/wasm-dpp2/src/identity/public_key.rs
📚 Learning: 2024-11-20T16:05:40.200Z
Learnt from: QuantumExplorer
Repo: dashpay/platform PR: 2257
File: packages/rs-drive-abci/src/platform_types/signature_verification_quorum_set/v0/for_saving.rs:148-151
Timestamp: 2024-11-20T16:05:40.200Z
Learning: In `packages/rs-drive-abci/src/platform_types/signature_verification_quorum_set/v0/for_saving.rs`, when converting public keys from `QuorumForSavingV0` to `VerificationQuorum`, it's acceptable to use `.expect()` for public key conversion, as the conversion has been verified and panics are acceptable in this context.

Applied to files:

  • packages/wasm-dpp2/src/identity/public_key.rs
📚 Learning: 2025-07-28T20:00:08.502Z
Learnt from: QuantumExplorer
Repo: dashpay/platform PR: 2711
File: packages/wasm-sdk/AI_REFERENCE.md:771-783
Timestamp: 2025-07-28T20:00:08.502Z
Learning: In packages/wasm-sdk/AI_REFERENCE.md, the documentation correctly shows the actual SDK method signatures (including identityCreate and identityTopUp with their full parameter lists), which may differ from the UI inputs shown in fixed_definitions.json. The UI may collect fewer parameters from users while handling additional requirements internally.

Applied to files:

  • packages/wasm-sdk/src/state_transitions/identity/mod.rs
  • packages/wasm-sdk/src/state_transitions/contracts/mod.rs
  • packages/wasm-sdk/src/state_transitions/documents/mod.rs
📚 Learning: 2024-10-03T11:51:06.980Z
Learnt from: shumkov
Repo: dashpay/platform PR: 2201
File: packages/rs-platform-version/src/version/v2.rs:1186-1188
Timestamp: 2024-10-03T11:51:06.980Z
Learning: In the `IdentityTransitionVersions` structure within `packages/rs-platform-version/src/version/v2.rs`, the field `credit_withdrawal` does not need the `identity_` prefix since it is already encompassed within identity state transitions.

Applied to files:

  • packages/wasm-sdk/src/state_transitions/identity/mod.rs
  • packages/wasm-sdk/src/state_transitions/contracts/mod.rs
📚 Learning: 2025-09-02T13:30:17.703Z
Learnt from: thephez
Repo: dashpay/platform PR: 2739
File: packages/wasm-sdk/test/ui-automation/tests/state-transitions.spec.js:1-171
Timestamp: 2025-09-02T13:30:17.703Z
Learning: In packages/wasm-sdk/index.html, state transition definitions are loaded dynamically from api-definitions.json via the loadApiDefinitions() function that fetches './api-definitions.json'. The UI doesn't have hardcoded transition definitions - instead it populates categories, types, inputs, and labels from this JSON configuration file at runtime.

Applied to files:

  • packages/wasm-sdk/src/state_transitions/identity/mod.rs
  • packages/wasm-sdk/src/state_transitions/contracts/mod.rs
  • packages/wasm-sdk/src/state_transitions/documents/mod.rs
📚 Learning: 2025-09-02T13:30:17.703Z
Learnt from: thephez
Repo: dashpay/platform PR: 2739
File: packages/wasm-sdk/test/ui-automation/tests/state-transitions.spec.js:1-171
Timestamp: 2025-09-02T13:30:17.703Z
Learning: In packages/wasm-sdk/index.html, state transition definitions are loaded dynamically from api-definitions.json rather than being hardcoded in the HTML file. The UI loads transition categories, types, inputs, and labels from this JSON configuration file.

Applied to files:

  • packages/wasm-sdk/src/state_transitions/identity/mod.rs
  • packages/wasm-sdk/src/state_transitions/contracts/mod.rs
  • packages/wasm-sdk/src/state_transitions/documents/mod.rs
📚 Learning: 2025-09-03T14:41:16.196Z
Learnt from: thephez
Repo: dashpay/platform PR: 2754
File: packages/wasm-sdk/AI_REFERENCE.md:766-766
Timestamp: 2025-09-03T14:41:16.196Z
Learning: In packages/wasm-sdk/, the AI_REFERENCE.md file is auto-generated from api-definitions.json. Any documentation fixes should be made in api-definitions.json rather than directly in AI_REFERENCE.md, as manual changes to AI_REFERENCE.md would be overwritten during regeneration.

Applied to files:

  • packages/wasm-sdk/src/state_transitions/identity/mod.rs
  • packages/wasm-sdk/src/state_transitions/contracts/mod.rs
  • packages/wasm-sdk/src/state_transitions/documents/mod.rs
📚 Learning: 2024-10-09T00:22:57.778Z
Learnt from: shumkov
Repo: dashpay/platform PR: 2186
File: packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_credit_withdrawal/mod.rs:48-54
Timestamp: 2024-10-09T00:22:57.778Z
Learning: In the identity credit withdrawal transition code, the field `platform_version.drive_abci.validation_and_processing.state_transitions.identity_credit_withdrawal_state_transition.transform_into_action` is not an `Option` type, so handling `None` cases is unnecessary.

Applied to files:

  • packages/wasm-sdk/src/state_transitions/identity/mod.rs
📚 Learning: 2024-10-09T00:22:57.778Z
Learnt from: lklimek
Repo: dashpay/platform PR: 2207
File: packages/rs-drive-proof-verifier/src/proof.rs:1646-1664
Timestamp: 2024-10-09T00:22:57.778Z
Learning: In the implementation of `FromProof<platform::GetContestedResourceIdentityVotesRequest>` in `packages/rs-drive-proof-verifier/src/proof.rs`, when matching `maybe_votes`, using `.expect()` on `v.into_iter().next()` is acceptable because the prior match arm `Some(v) if v.is_empty()` ensures that the map is not empty, preventing a panic.

Applied to files:

  • packages/wasm-sdk/src/state_transitions/identity/mod.rs
📚 Learning: 2025-11-25T13:10:23.481Z
Learnt from: CR
Repo: dashpay/platform PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T13:10:23.481Z
Learning: Use WASM bindings to connect Rust and JavaScript code

Applied to files:

  • packages/wasm-sdk/src/state_transitions/contracts/mod.rs
  • packages/wasm-sdk/src/state_transitions/documents/mod.rs
📚 Learning: 2025-04-11T09:08:05.652Z
Learnt from: pauldelucia
Repo: dashpay/platform PR: 2523
File: packages/rs-drive/src/drive/contract/update/update_contract/v1/update_description/v1/mod.rs:147-151
Timestamp: 2025-04-11T09:08:05.652Z
Learning: Description length validation for data contracts is already handled in the data contract validation process, specifically in packages/rs-dpp/src/data_contract/methods/validate_update/v0/mod.rs.

Applied to files:

  • packages/wasm-sdk/src/state_transitions/contracts/mod.rs
📚 Learning: 2025-09-03T14:42:29.958Z
Learnt from: thephez
Repo: dashpay/platform PR: 2754
File: packages/wasm-sdk/docs.html:1970-1971
Timestamp: 2025-09-03T14:42:29.958Z
Learning: In packages/wasm-sdk/, the docs.html file is auto-generated from api-definitions.json. Any documentation fixes should be made in api-definitions.json rather than directly in docs.html, as manual changes to docs.html would be overwritten during regeneration.

Applied to files:

  • packages/wasm-sdk/src/state_transitions/contracts/mod.rs
  • packages/wasm-sdk/src/state_transitions/documents/mod.rs
📚 Learning: 2025-11-25T13:10:23.481Z
Learnt from: CR
Repo: dashpay/platform PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T13:10:23.481Z
Learning: Use state transitions for updates in documents and data contracts

Applied to files:

  • packages/wasm-sdk/src/state_transitions/contracts/mod.rs
  • packages/wasm-sdk/src/state_transitions/documents/mod.rs
📚 Learning: 2024-10-29T14:40:54.727Z
Learnt from: lklimek
Repo: dashpay/platform PR: 2277
File: packages/rs-sdk/src/core/transaction.rs:0-0
Timestamp: 2024-10-29T14:40:54.727Z
Learning: In `packages/rs-sdk/src/platform/document_query.rs` and `packages/rs-sdk/src/core/transaction.rs`, certain places don't implement `IntoInner`, so direct error mappings cannot be simplified using `IntoInner`. A TODO comment has been added to address this in a future PR.

Applied to files:

  • packages/wasm-sdk/src/state_transitions/documents/mod.rs
📚 Learning: 2025-08-14T15:03:56.681Z
Learnt from: thephez
Repo: dashpay/platform PR: 2726
File: packages/wasm-sdk/check_documentation.py:69-76
Timestamp: 2025-08-14T15:03:56.681Z
Learning: In packages/wasm-sdk/api-definitions.json, the structure is nested by categories: { "queries": { "categoryName": { "label": "...", "queries": { "actualQueryName": {...} } } } }. The check_documentation.py script correctly iterates over categories and then accesses the nested 'queries'/'transitions' objects within each category to collect the actual query/transition names.

Applied to files:

  • packages/wasm-sdk/src/state_transitions/documents/mod.rs
📚 Learning: 2025-09-03T19:33:21.688Z
Learnt from: thephez
Repo: dashpay/platform PR: 2754
File: packages/wasm-sdk/api-definitions.json:1285-1285
Timestamp: 2025-09-03T19:33:21.688Z
Learning: In packages/wasm-sdk/api-definitions.json, thephez prefers to keep the existing "ripemd160hash20bytes1234" placeholder for ECDSA_HASH160 data field in documentation examples rather than using a valid base64-encoded format, maintaining consistency with the previous documentation approach.

Applied to files:

  • packages/wasm-sdk/src/state_transitions/documents/mod.rs
📚 Learning: 2025-10-01T08:37:32.168Z
Learnt from: QuantumExplorer
Repo: dashpay/platform PR: 2790
File: packages/rs-drive/src/drive/document/index_uniqueness/validate_document_purchase_transition_action_uniqueness/v1/mod.rs:65-0
Timestamp: 2025-10-01T08:37:32.168Z
Learning: In purchase document transitions (packages/rs-drive/src/drive/document/index_uniqueness/validate_document_purchase_transition_action_uniqueness/v1/mod.rs), the `changed_data_values` field in `UniquenessOfDataRequestUpdateType::ChangedDocument` should be set to an empty BTreeSet (`Cow::Owned(BTreeSet::new())`) because purchase transitions do not modify document data properties (like "price"), only ownership and transfer metadata. An empty set signals the uniqueness validation logic to skip checking unique indexes on data properties.

Applied to files:

  • packages/wasm-sdk/src/state_transitions/documents/mod.rs
🧬 Code graph analysis (5)
packages/wasm-sdk/src/settings.rs (2)
packages/wasm-sdk/src/state_transitions/addresses.rs (1)
  • extract_settings_from_options (90-103)
packages/wasm-sdk/src/error.rs (1)
  • generic (71-73)
packages/wasm-dpp2/src/identity/public_key.rs (3)
packages/wasm-dpp2/src/data_contract/model.rs (2)
  • try_from_options (545-562)
  • Reflect (68-76)
packages/wasm-sdk/src/state_transitions/identity/mod.rs (1)
  • key_js (934-935)
packages/wasm-sdk/src/error.rs (1)
  • invalid_argument (75-77)
packages/wasm-dpp2/src/data_contract/model.rs (2)
packages/wasm-dpp2/src/identity/public_key.rs (1)
  • try_from_options (356-373)
packages/wasm-sdk/src/error.rs (1)
  • invalid_argument (75-77)
packages/wasm-sdk/src/state_transitions/contracts/mod.rs (3)
packages/wasm-sdk/src/settings.rs (3)
  • extract_settings_from_options (259-270)
  • from (66-73)
  • from (203-226)
packages/wasm-dpp2/src/data_contract/model.rs (3)
  • try_from_options (545-562)
  • from (39-41)
  • from (45-47)
packages/wasm-dpp2/src/identity/public_key.rs (3)
  • try_from_options (356-373)
  • from (35-37)
  • from (41-43)
packages/wasm-sdk/src/state_transitions/documents/mod.rs (4)
packages/wasm-sdk/src/queries/utils.rs (1)
  • deserialize_required_query (11-28)
packages/wasm-sdk/src/settings.rs (3)
  • extract_settings_from_options (259-270)
  • from (66-73)
  • from (203-226)
packages/wasm-sdk/src/error.rs (4)
  • invalid_argument (75-77)
  • not_found (83-85)
  • generic (71-73)
  • serialization (79-81)
packages/wasm-dpp2/src/identity/public_key.rs (3)
  • try_from_options (356-373)
  • from (35-37)
  • from (41-43)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
  • GitHub Check: Rust packages (wasm-sdk) / Tests
  • GitHub Check: Rust packages (wasm-sdk) / Unused dependencies
  • GitHub Check: Rust packages (wasm-sdk) / Linting
  • GitHub Check: Rust packages (wasm-dpp2) / Unused dependencies
  • GitHub Check: Rust packages (wasm-dpp2) / Tests
  • GitHub Check: Rust packages (wasm-dpp2) / Linting
  • GitHub Check: Build Docker images (Dashmate helper, dashmate-helper, dashmate-helper) / Build Dashmate helper image
  • GitHub Check: Build Docker images (Drive, drive, drive-abci) / Build Drive image
  • GitHub Check: Build Docker images (RS-DAPI, rs-dapi, rs-dapi) / Build RS-DAPI image
  • GitHub Check: Build JS packages / Build JS
  • GitHub Check: Rust crates security audit
🔇 Additional comments (19)
packages/wasm-sdk/src/settings.rs (1)

254-270: LGTM! Clean implementation of the option-extraction pattern.

The function correctly handles the optional "settings" field extraction, returning Ok(None) for missing values and properly delegating to parse_put_settings for conversion. This aligns with the identical pattern in addresses.rs.

packages/wasm-dpp2/src/identity/public_key.rs (1)

351-374: LGTM! Consistent implementation of the option-extraction pattern.

The helper mirrors DataContractWasm::try_from_options exactly, providing a uniform API surface for extracting typed fields from JS option objects. The error messages clearly indicate the required nature of the field.

packages/wasm-dpp2/src/data_contract/model.rs (1)

540-562: LGTM! Well-structured option extraction helper.

This establishes the canonical pattern for extracting typed WASM objects from JS option objects, which is consistently replicated across IdentityPublicKeyWasm and IdentitySignerWasm.

packages/wasm-sdk/src/state_transitions/contracts/mod.rs (2)

1-108: LGTM! Clean refactor to option-based API for contract publishing.

The TypeScript interface is well-documented, and the extraction pattern using try_from_options helpers provides consistent, type-safe field access. The flow is straightforward: extract options → build contract → broadcast.


110-227: LGTM! Contract update follows the same clean pattern.

The update flow correctly:

  1. Extracts the updated contract and signing credentials
  2. Fetches the identity contract nonce
  3. Builds a partial identity for signing
  4. Creates and broadcasts the update transition
packages/wasm-sdk/src/state_transitions/documents/mod.rs (7)

29-264: LGTM! Document create implementation is thorough.

The flow correctly:

  1. Validates all required fields including entropy (32 bytes check)
  2. Fetches the data contract and validates the document type
  3. Creates the document and builds the state transition
  4. Broadcasts and waits for confirmation

705-714: Verify: Inconsistent use of broadcast() vs broadcast_and_wait().

document_delete uses broadcast() (fire-and-forget), while document_create, document_replace, and document_purchase use broadcast_and_wait(). The same inconsistency exists in document_transfer (line 950) and document_set_price (line 1446).

Is this intentional? If not, consider using broadcast_and_wait() for consistency, ensuring the caller knows the operation completed successfully.


266-503: LGTM! Document replace follows the established pattern.

The implementation correctly increments the revision and preserves the document structure while updating the properties.


505-715: LGTM! Document delete properly fetches existing document for revision.

The implementation correctly fetches the existing document to obtain the current revision before creating the delete transition.


717-957: LGTM! Document transfer includes proper ownership validation.

Good defensive check at lines 900-904 to verify the caller is the actual owner before allowing the transfer. The self-transfer check at lines 850-854 is also a good UX improvement.


959-1214: LGTM! Document purchase validates price match.

The price verification at lines 1150-1155 ensures the buyer pays exactly the listed price, preventing accidental overpayment or underpayment attacks.


1216-1453: LGTM! Document set price validates ownership.

The ownership check at lines 1394-1398 ensures only the document owner can modify the price.

packages/wasm-sdk/src/state_transitions/identity/mod.rs (7)

33-147: LGTM! Identity create implementation is clean.

The flow correctly extracts all required components (identity, asset lock proof, private key, signer) and delegates to the platform SDK for the actual creation.


149-303: LGTM! Identity top-up returns useful balance information.

The result struct provides both the new balance and the topped-up amount, which is helpful for UX.


305-512: LGTM! Credit transfer includes proper validations.

Good defensive checks for self-transfer (line 421) and zero-amount transfers (line 428).


514-769: LGTM! Credit withdrawal handles both address and script destinations.

The implementation correctly validates that either toAddress or outputScript is provided, with proper error messaging.


771-1040: LGTM! Identity update with key management validation.

The implementation correctly:

  1. Prevents disabling master keys (line 964)
  2. Prevents disabling critical authentication keys (lines 969-976)
  3. Prevents disabling transfer keys (lines 978-982)
  4. Auto-assigns key IDs to newly added keys (line 941)

1042-1214: Verify the masternode vote implementation works end-to-end.

Beyond the placeholder key issue noted above, the overall structure of the masternode vote flow looks correct. However, given the complexity of voting and the placeholder concern, this should be verified with functional tests.


1168-1184: Voting key should be retrieved from signer, not created with placeholder data.

The voting implementation creates an IdentityPublicKeyV0 with placeholder data (vec![0u8; 20]), claiming it will be "derived during signing." However, the established pattern in this file for other operations (transfer, withdrawal, authentication) is to look up the actual key from the identity using signer.can_sign_with(key) before passing it along. The voting flow should follow the same pattern to retrieve the actual voting key matching what the signer can sign with, rather than relying on unverified placeholder replacement during signing.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@shumkov shumkov marked this pull request as draft December 28, 2025 15:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In review / testing

Development

Successfully merging this pull request may close these issues.

2 participants