Skip to content

Conversation

thephez
Copy link
Collaborator

@thephez thephez commented Oct 1, 2025

Issue being fixed or feature implemented

The wasm-sdk was not returning groups and tokens fields when fetching data contracts that define tokens, making it impossible to properly work with token contracts through the SDK.

What was done?

Fixed the data contract serialization in wasm-sdk to use the SDK's platform version instead of hardcoded PlatformVersion::first(). This ensures that contracts are serialized using the V1 format which includes groups and tokens fields when the platform version supports it.

Changes made:

  • Modified DataContractWasm struct to store the platform version reference
  • Updated to_json() method to use the stored platform version
  • Fixed all DataContractWasm instantiation points to pass the correct platform version

How Has This Been Tested?

  • Successfully built the wasm-sdk with the changes
  • Verified that the build completes without errors
  • The fix ensures backward compatibility by falling back to PlatformVersion::first() when needed

Breaking Changes

None - This is a backward-compatible fix that preserves existing behavior while enabling proper serialization for newer platform versions.

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

    • Data contract serialization now requires and respects an explicit platform version, making responses platform-version aware.
    • Fetch and verification flows consistently return data contracts tied to the requested platform version.
  • Bug Fixes

    • Improved error handling when an unknown platform version is requested, returning a clear invalid-argument error instead of silently using a default.

DataContractWasm was using PlatformVersion::first() which defaults to V0
serialization format that excludes groups and tokens fields. Updated to
use the SDK's platform version for proper V1 serialization support.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Copy link
Contributor

coderabbitai bot commented Oct 1, 2025

Walkthrough

Removed the From<DataContract> impl and added DataContractWasm::from_data_contract(DataContract); updated call sites to use it. DataContractWasm::to_json now takes platform_version: u32 and resolves the platform via PlatformVersion::get(...), returning WasmSdkError::invalid_argument on unknown versions.

Changes

Cohort / File(s) Summary
DataContractWasm constructor & serialization
packages/wasm-sdk/src/dpp.rs
Removed impl From<DataContract> for DataContractWasm. Added pub(crate) fn from_data_contract(data_contract: DataContract) -> Self. Changed to_json(&self)to_json(&self, platform_version: u32) and now resolves platform version with PlatformVersion::get(platform_version).map_err(...), returning WasmSdkError::invalid_argument on unknown versions.
Query: return constructed DataContractWasm
packages/wasm-sdk/src/queries/data_contract.rs
After fetching, bind awaited contract, keep not-found handling, and return DataContractWasm::from_data_contract(contract) instead of mapping via Into::into.
Verification: use new constructor
packages/wasm-sdk/src/verify.rs
Switched construction from DataContractWasm::from(contract) to DataContractWasm::from_data_contract(contract) inside verify_data_contract mapping.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Caller as Caller
  participant Store as DataContract Store
  participant DCW as DataContractWasm

  Caller->>Store: fetch_by_identifier(...)
  alt found
    Store-->>Caller: DataContract
    Caller->>DCW: DataContractWasm::from_data_contract(contract)
    DCW-->>Caller: DataContractWasm
  else not found
    Store-->>Caller: NotFound
  end
Loading
sequenceDiagram
  autonumber
  participant Caller as Caller
  participant DCW as DataContractWasm
  participant PV as PlatformVersion

  Caller->>DCW: to_json(platform_version: u32)
  DCW->>PV: PlatformVersion::get(platform_version)
  alt known
    PV-->>DCW: &PlatformVersion
    DCW-->>Caller: JsValue (serialized)
  else unknown
    PV-->>DCW: Err
    DCW-->>Caller: WasmSdkError::invalid_argument
  end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Suggested reviewers

  • QuantumExplorer
  • pauldelucia

Poem

A rabbit hops with careful art,
Replaces From and plays its part.
Pass the version, call to_json true,
Errors mapped when numbers skew.
Thump — the contract’s fresh and new. 🐇

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 clearly and concisely summarizes the primary change, indicating that the wasm-sdk has been fixed to include the missing groups and tokens fields during data contract serialization, which aligns directly with the implementation updates in to_json and constructor adjustments.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch wasm-sdk-fix-contract-version

📜 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 19ecdda and ce71548.

📒 Files selected for processing (1)
  • packages/wasm-sdk/src/dpp.rs (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/wasm-sdk/src/dpp.rs
⏰ 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). (6)
  • GitHub Check: Rust packages (wasm-sdk) / Tests
  • GitHub Check: Rust packages (wasm-sdk) / Formatting
  • GitHub Check: Rust packages (wasm-sdk) / Linting
  • GitHub Check: Build Docker images (Drive, drive, drive-abci) / Build Drive image
  • GitHub Check: Build JS packages / Build JS
  • GitHub Check: Rust crates security audit

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.

Copy link
Collaborator Author

@thephez thephez left a comment

Choose a reason for hiding this comment

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

@coderabbitai review

@thephez thephez added this to the v2.1.0 milestone Oct 1, 2025
@thephez thephez marked this pull request as ready for review October 1, 2025 16:49
@thephez thephez marked this pull request as draft October 1, 2025 16:53
@thephez thephez marked this pull request as ready for review October 1, 2025 17:38
@thephez thephez requested a review from shumkov October 1, 2025 17:38
@thephez
Copy link
Collaborator Author

thephez commented Oct 1, 2025

@coderabbitai full review

Copy link
Contributor

coderabbitai bot commented Oct 1, 2025

✅ Actions performed

Full review triggered.

@dashpay dashpay deleted a comment from coderabbitai bot Oct 1, 2025
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: 3

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f9d09e7 and 90451af.

📒 Files selected for processing (3)
  • packages/wasm-sdk/src/dpp.rs (2 hunks)
  • packages/wasm-sdk/src/queries/data_contract.rs (1 hunks)
  • packages/wasm-sdk/src/verify.rs (1 hunks)
🔇 Additional comments (3)
packages/wasm-sdk/src/verify.rs (1)

125-125: Consider consistent platform version selection across verification and runtime.

This function uses PlatformVersion::latest() whereas get_data_contract in data_contract.rs uses PlatformVersion::get(self.version()). While this may be acceptable for verification/testing functions, the inconsistency could lead to subtle bugs if verification logic diverges from runtime behavior.

Consider either:

  1. Making verify functions accept a platform version parameter for consistency
  2. Documenting why latest() is appropriate for verification contexts

Based on the PR comments discussion about inconsistent platform version usage.

packages/wasm-sdk/src/dpp.rs (2)

298-298: Document the safety of the 'static lifetime requirement.

The &'static PlatformVersion reference requires that all PlatformVersion instances outlive the DataContractWasm. This is likely safe if PlatformVersion instances are global singletons, but this constraint should be documented.

Consider adding a doc comment explaining:

  • Why 'static is safe (e.g., "PlatformVersion instances are global singletons")
  • Or using a generic lifetime 'a if the 'static constraint is too restrictive

Based on the PR comments about the 'static lifetime concern.


320-326: Core fix correctly implemented.

The to_json method now uses the stored platform version (self.1) instead of the hardcoded PlatformVersion::first(). This ensures that version-specific fields like groups and tokens are included when serializing token contracts.

fn from(value: DataContract) -> Self {
Self(value)
// Use first version as fallback for backward compatibility
Self(value, PlatformVersion::first())
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't think this is a safe approach. For now, I would just pass platfrom version to all methods that require it (as rust dpp does). There are non-instance methods and you would need to do it anyway.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Pushed some updates, but I see you've been working on dpp.rs in #2791 so maybe I will pause (since I don't exactly know what I'm doing here 🤪)

thephez and others added 3 commits October 2, 2025 08:53
… methods

Remove unsafe platform version fallback from DataContractWasm:
- Remove stored &'static PlatformVersion field from struct
- Remove From<DataContract> trait implementation using PlatformVersion::first()
- Update toJSON method to accept platform_version parameter
- Add internal from_data_contract helper for codebase use

This ensures platform version is always passed explicitly to methods that require it,
following the same pattern as Rust DPP implementation.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
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

🧹 Nitpick comments (1)
packages/wasm-sdk/src/verify.rs (1)

114-125: Propagate platform version through verify_data_contract

verify_data_contract verifies the proof with PlatformVersion::latest() but returns a DataContractWasm without storing that version, while DataContractWasm.toJSON() requires the caller to supply a version. This risks version mismatches.

Consider updating DataContractWasm::from_data_contract (or its signature) to accept and store the platform version, returning it alongside the contract, or documenting that callers must forward the same version into toJSON().

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 90451af and 19ecdda.

📒 Files selected for processing (3)
  • packages/wasm-sdk/src/dpp.rs (2 hunks)
  • packages/wasm-sdk/src/queries/data_contract.rs (1 hunks)
  • packages/wasm-sdk/src/verify.rs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/wasm-sdk/src/queries/data_contract.rs
🧰 Additional context used
📓 Path-based instructions (2)
**/*.rs

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.rs: Format Rust code with cargo fmt
Run Clippy linter for Rust code

Files:

  • packages/wasm-sdk/src/verify.rs
  • packages/wasm-sdk/src/dpp.rs
packages/wasm-sdk/**

📄 CodeRabbit inference engine (CLAUDE.md)

Keep WASM SDK docs in sync (run generate_docs.py) when updating the WASM SDK

Files:

  • packages/wasm-sdk/src/verify.rs
  • packages/wasm-sdk/src/dpp.rs
🧬 Code graph analysis (2)
packages/wasm-sdk/src/verify.rs (1)
packages/wasm-sdk/src/dpp.rs (1)
  • from_data_contract (301-303)
packages/wasm-sdk/src/dpp.rs (1)
packages/wasm-sdk/src/error.rs (1)
  • invalid_argument (73-75)
⏰ 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). (6)
  • GitHub Check: Rust packages (wasm-sdk) / Unused dependencies
  • GitHub Check: Rust packages (wasm-sdk) / Tests
  • GitHub Check: Rust packages (wasm-sdk) / Linting
  • GitHub Check: Build Docker images (Drive, drive, drive-abci) / Build Drive image
  • GitHub Check: Build JS packages / Build JS
  • GitHub Check: Rust crates security audit
🔇 Additional comments (2)
packages/wasm-sdk/src/dpp.rs (2)

313-318: Platform version parameter correctly addresses root cause.

The updated signature requiring an explicit platform_version: u32 parameter directly fixes the original bug where serialization used a hardcoded PlatformVersion::first(). The error handling for unknown platform versions is appropriate.


300-330: Changes align with maintainer guidance and resolve prior concerns.

The removal of the From<DataContract> implementation and the requirement to pass platform_version explicitly to to_json() address both:

  1. The dangerous fallback that could reintroduce the bug (past review comment about PlatformVersion::first())
  2. The maintainer's preference (shumkov's comment) to pass platform version to methods as needed rather than storing it in the struct

This approach correctly ensures that serialization uses the intended platform version for each call, preventing omission of version-specific fields like groups and tokens.

Based on past review comments.

impl From<DataContract> for DataContractWasm {
fn from(value: DataContract) -> Self {
Self(value)
impl DataContractWasm {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I went through DPP methods. Actually, I think your idea to pass the platfrom version to the constructor was the best option we have. But all constructors should always require platform version then. We shouldn't create with default or first version in any case. I'm sorry, that I wasn't clear enough in my first comment, so you reverted half correct code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants