Skip to content

Conversation

shumkov
Copy link
Collaborator

@shumkov shumkov commented Sep 10, 2025

Issue being fixed or feature implemented

We need to ship javascript SDK as NPM module that will work in both Node.JS and browser.

What was done?

  • Updated WasmSdk
    • Better error reporting with WasmSdkError
    • Free functions to instance methods
    • Unit and functional tests
    • Bundling into single ESM module for both NodeJS and browser
    • Rename methods to camelCase
    • Readme
    • CI
  • Introduced EvoSDK thin TypeScript wrapper around WasmSdk
    • Unit tests
    • Bundling into single ESM module for both NodeJS and browser
    • CI
    • Website
    • Functional tests
    • Documentation

How Has This Been Tested?

With unit and functional tests

Breaking Changes

None

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

    • Publishes @dashevo/wasm-sdk v2.0.0 and adds @dashevo/evo-sdk: a modular EvoSDK with lazy connect, high-level facades (documents, identities, contracts, tokens, voting, epoch, protocol, system, group, DPNS), bundled single-file WASM runtime, and cross-environment init helpers.
  • Refactor

    • Centralized WASM API behind SDK instances, unified typed error surface, and runtime logging control.
  • Documentation

    • Complete WASM SDK README rewrite (usage, bundling, init).
  • Tests

    • Comprehensive new unit and functional test suites for the JS SDK.
  • Chores

    • Workspace/workflow updates, bundling scripts, package filters; removed legacy CI workflows.

Copy link
Contributor

coderabbitai bot commented Sep 10, 2025

Walkthrough

Adds a new TypeScript EvoSDK package and integrates it with a refactored Rust WASM SDK: many wasm free exports were moved to WasmSdk instance methods, a structured WasmSdkError and logging layer were introduced, bundling/build scripts and workspace/package-filter entries were added, plus JS facades and tests.

Changes

Cohort / File(s) Summary
Repo & workspace config
Cargo.toml, package.json, .pnp.cjs, .github/package-filters/*, Dockerfile
Register wasm-sdk and js-evo-sdk as workspace members; update Yarn PnP runtime state; add package-filter anchors/aliases; include packages/wasm-sdk in Docker COPYs.
CI / Workflows
.github/workflows/*
Remove dedicated WASM SDK build/docs/UI-test workflows; replace wasm-opt caching steps with "Install wasm-pack" in JS build/release workflows; adjust workflow triggers and delete obsolete wasm-specific files.
WASM packaging & build scripts
packages/scripts/build-wasm.sh, packages/wasm-sdk/scripts/*, packages/wasm-sdk/scripts/bundle.cjs
Clean output directory, log feature flags, tighten cargo release profile flags, change script paths, and add bundler producing single-file inlined dist/sdk.js plus dist/raw.
WASM package manifest & docs
packages/wasm-sdk/package.json, packages/wasm-sdk/README.md, packages/wasm-sdk/Cargo.toml, packages/wasm-sdk/.gitignore, .mocharc.yml
Rework wasm-sdk to publish as @dashevo/wasm-sdk v2.0.0 (ES module), add exports/raw modes, update README for new packaging model, adjust ignores, and add test/dev metadata.
JS EvoSDK package manifest & workspace
packages/js-evo-sdk/package.json, root package.json
Add @dashevo/evo-sdk package (ESM manifest, build/test scripts) and include new workspaces and dependency on @dashevo/wasm-sdk.
JS EvoSDK tooling & configs
packages/js-evo-sdk/tsconfig.json, webpack.config.cjs, .mocharc.yml, .gitignore, ESLint files
Add TypeScript, Webpack, Mocha/Karma, and ESLint configs and testing scaffolding for js-evo-sdk.
EvoSDK core & wasm wrapper
packages/js-evo-sdk/src/sdk.ts, packages/js-evo-sdk/src/wasm.ts, packages/js-evo-sdk/src/util.ts
Add EvoSDK class with lazy connect/getWasmSdkConnected, factory helpers, re-exports of facades; add ensureInitialized wrapper around @dashevo/wasm-sdk; add asJsonString util.
JS facades
packages/js-evo-sdk/src/*/facade.ts (documents, identities, contracts, tokens, dpns, epoch, protocol, system, group, voting)
Add facade classes that obtain a connected Wasm SDK and forward calls (including proof variants), applying JSON/BigInt/nullable normalization and minimal argument shaping.
JS tests & test infra
packages/js-evo-sdk/tests/**, packages/js-evo-sdk/tests/karma/*, packages/js-evo-sdk/tests/fixtures/*
Add unit and functional tests for facades, Karma configs (unit/functional), bootstrap hooks, fixtures, and many functional specs exercising testnet.
WASM Rust: central error & logging
packages/wasm-sdk/src/error.rs, packages/wasm-sdk/src/logging.rs, packages/wasm-sdk/src/lib.rs
Introduce WasmSdkError and WasmSdkErrorKind, replace JsError/JsValue in public signatures, add reloadable tracing-based logging (set_log_level), and re-export new error types.
WASM Rust: API refactor (queries & verify)
packages/wasm-sdk/src/queries/*, packages/wasm-sdk/src/verify.rs
Move many free wasm_bindgen exports into WasmSdk instance methods with js_name, add WithProofInfo variants, standardize serialization, and use WasmSdkError.
WASM Rust: state transitions & wallet
packages/wasm-sdk/src/state_transitions/*, packages/wasm-sdk/src/wallet/*, packages/wasm-sdk/src/dpp.rs, packages/wasm-sdk/src/dpns.rs, packages/wasm-sdk/src/sdk.rs
Convert state-transition and wallet public bindings to return WasmSdkError, move functions into WasmSdk impl where applicable, centralize error handling, and replace console logs with tracing.
Packaging filters & CI package groups
.github/package-filters/*
Add JS and RS package filter entries for @dashevo/wasm-sdk and @dashevo/evo-sdk, introduce YAML anchors/aliases and new direct/no-workflows groups.
Misc additions
packages/wasm-sdk/*, packages/js-evo-sdk/*
Add bundling scripts, test harness files, many new source files for JS facades and wasm bindings, Karma/Mocha configs, and fixtures.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant App as Application
  participant Evo as EvoSDK (JS)
  participant WasmInit as wasm.ts (ensureInitialized)
  participant Builder as WasmSdkBuilder
  participant Wasm as WasmSdk (WASM)

  App->>Evo: new EvoSDK(options)
  App->>Evo: connect()
  Evo->>WasmInit: ensureInitialized()
  Note right of WasmInit #e6f7ff: initialize @dashevo/wasm-sdk once (cached)
  WasmInit-->>Evo: wasm module ready
  Evo->>Builder: configure(network, trusted, version, proofs)
  Builder->>Wasm: build() → WasmSdk instance
  Wasm-->>Evo: WasmSdk instance returned
  Evo-->>App: connected

  App->>Evo: evo.documents.query(params)
  Evo->>Wasm: getDocuments(contractId, type, JSON(where), ...)
  Wasm-->>Evo: JsValue (result or proof)
  Evo-->>App: result
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120+ minutes

Possibly related PRs

Suggested labels

enhancement, js-sdk

Poem

Hop hop! I bind the wasm tight,
Facades whisper through the night.
Errors named, logs set free,
Single-file wings for you and me.
Tests parade — the burrow's bright. 🐇✨

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 "feat: evo sdk" is concise, uses a conventional commit prefix, and directly reflects the main change in the PR (adding the Evo SDK / js-evo-sdk package and associated wrapper/tests/CI), so it accurately summarizes the primary intent for a reviewer skimming history.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch evo-sdk

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 ready for review September 14, 2025 15:08
@shumkov shumkov marked this pull request as draft September 14, 2025 15:08
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: 52

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (13)
.github/workflows/wasm-sdk-documentation-check.yml (2)

62-68: Fix docs_modified detection (currently always false).

You’re diffing the working tree vs HEAD. To know if the PR already includes doc changes, compare against the base branch on pull_request or the previous commit on push.

-# so this check will only detect if the PR already includes documentation changes
-if git diff --quiet HEAD -- docs.html docs_manifest.json AI_REFERENCE.md; then
-  echo "docs_modified=false" >> $GITHUB_OUTPUT
-else
-  echo "docs_modified=true" >> $GITHUB_OUTPUT
-fi
+# Detect whether the PR/commit already includes documentation changes
+if [ "${{ github.event_name }}" = "pull_request" ]; then
+  git fetch --no-tags --depth=1 origin "${{ github.base_ref }}"
+  if git diff --quiet "origin/${{ github.base_ref }}...HEAD" -- docs.html docs_manifest.json AI_REFERENCE.md; then
+    echo "docs_modified=false" >> $GITHUB_OUTPUT
+  else
+    echo "docs_modified=true" >> $GITHUB_OUTPUT
+  fi
+else
+  # push event: compare with the previous commit
+  if git diff --quiet HEAD~1 -- docs.html docs_manifest.json AI_REFERENCE.md; then
+    echo "docs_modified=false" >> $GITHUB_OUTPUT
+  else
+    echo "docs_modified=true" >> $GITHUB_OUTPUT
+  fi
+fi

135-149: Protected-branch flow doesn’t generate docs → empty PR.

You never run generate_docs.py before create-pull-request. Add a generation step and restrict add-paths. This aligns with our WASM SDK docs-sync guidance.

-      - name: Create documentation update PR (protected branches)
-        if: github.event_name == 'push' && (contains(github.ref, 'master') || contains(github.ref, 'main')) && steps.doc-check.outputs.status == 'failure'
-        uses: peter-evans/create-pull-request@v5
+      - name: Generate documentation (protected branches)
+        if: github.event_name == 'push' && (contains(github.ref, 'master') || contains(github.ref, 'main')) && steps.doc-check.outputs.status == 'failure'
+        working-directory: packages/wasm-sdk
+        run: |
+          python3 generate_docs.py
+
+      - name: Create documentation update PR (protected branches)
+        if: github.event_name == 'push' && (contains(github.ref, 'master') || contains(github.ref, 'main')) && steps.doc-check.outputs.status == 'failure'
+        uses: peter-evans/create-pull-request@v5
         with:
           token: ${{ secrets.GITHUB_TOKEN }}
           commit-message: "chore: update WASM SDK documentation"
           title: "chore: update WASM SDK documentation"
           body: |
             This PR updates the WASM SDK documentation to match the current implementation.
 
             Auto-generated by GitHub Actions.
           branch: auto-update-wasm-docs-${{ github.run_number }}
           base: ${{ github.ref_name }}
-          path: packages/wasm-sdk
+          path: packages/wasm-sdk
+          add-paths: |
+            packages/wasm-sdk/docs.html
+            packages/wasm-sdk/docs_manifest.json
+            packages/wasm-sdk/AI_REFERENCE.md
packages/scripts/build-wasm.sh (2)

111-121: Bug: passing --features default is incorrect and may break builds.

Cargo enables default features implicitly; there is no “default” feature to pass. This can fail if the crate doesn’t define a feature literally named “default”.

Apply this minimal fix:

-    else
-        echo "CARGO_BUILD_FEATURES is not set, using default features"
-        # Explicitly pass default features to ensure they're used
-        FEATURES_ARG="--features default"
+    else
+        echo "CARGO_BUILD_FEATURES is not set; using Cargo default features"
+        FEATURES_ARG=""

Optional hardenings:

  • Support disabling defaults via env (e.g., CARGO_NO_DEFAULT_FEATURES=true -> add --no-default-features).
  • Use an array for args to avoid word-splitting issues with multiple features.

241-249: Also avoid in-place write in minimal optimization.

Mirror the atomic write pattern here too.

-        wasm-opt \
-            --strip-producers \
-            -O2 \
-            --enable-bulk-memory \
-            --enable-nontrapping-float-to-int \
-            "$WASM_PATH" \
-            -o \
-            "$WASM_PATH"
+        TMP_OUT="${WASM_PATH}.opt"
+        wasm-opt --strip-producers -O2 --enable-bulk-memory --enable-nontrapping-float-to-int \
+            "$WASM_PATH" -o "$TMP_OUT"
+        mv -f "$TMP_OUT" "$WASM_PATH"
packages/wasm-sdk/src/lib.rs (1)

27-38: Make #[wasm_bindgen(start)] synchronous and return () — remove WasmSdkError

The start function must take no arguments and return () or Result<(), JsValue>. (rustwasm.github.io)
Async start may be accepted syntactically but init() does not await it (it only kicks off the future), so do not make start async when you expect initialization to be complete before other exports run. (github.com)
A custom WasmSdkError will not map to JS unless it implements Into; use () or Result<(), JsValue> (or convert the error to a JsValue) instead. (alexcrichton.github.io)

-#[wasm_bindgen(start)]
-pub async fn start() -> Result<(), WasmSdkError> {
+#[wasm_bindgen(start)]
+pub fn start() {
     // We use tracing-wasm together with console_error_panic_hook to get logs from the wasm module.
     // Other alternatives are:
     // * https://github.com/jquesada2016/tracing_subscriber_wasm
     // * https://crates.io/crates/tracing-web
     console_error_panic_hook::set_once();
 
     tracing_wasm::set_as_global_default();
-
-    Ok(())
 }

Verify with cargo build + wasm-bindgen that no signature/conversion complaints remain.

packages/wasm-sdk/src/dpns.rs (1)

121-129: Avoid leaking the preorder JS callback on error paths

If register_dpns_name(input).await fails, we return early via ? and never clear the thread‑local PREORDER_CALLBACK, leaking the js_sys::Function. Clear it on both success and error.

Apply this diff:

-    let result = sdk
-        .as_ref()
-        .register_dpns_name(input)
-        .await?;
-
-    // Clear the thread-local callback
-    PREORDER_CALLBACK.with(|cb| {
-        *cb.borrow_mut() = None;
-    });
+    let result = match sdk.as_ref().register_dpns_name(input).await {
+        Ok(r) => r,
+        Err(e) => {
+            PREORDER_CALLBACK.with(|cb| *cb.borrow_mut() = None);
+            return Err(WasmSdkError::from(e));
+        }
+    };
+
+    // Clear the thread-local callback
+    PREORDER_CALLBACK.with(|cb| {
+        cb.borrow_mut().take();
+    });
packages/wasm-sdk/src/state_transitions/identity/mod.rs (2)

54-72: Remove sensitive debug logging (leaks private key material via public_keys)

public_keys JSON may contain privateKeyHex/privateKeyWif. Logging it verbatim leaks secrets to browser consoles. Please remove or strictly gate these logs.

Apply this diff to strip the verbose logs:

-        // Debug log all parameters
-        web_sys::console::log_1(&JsValue::from_str(&format!("identityCreate called with:")));
-        web_sys::console::log_1(&JsValue::from_str(&format!(
-            "  asset_lock_proof (length {}): {}",
-            asset_lock_proof.len(),
-            if asset_lock_proof.len() > 100 {
-                format!("{}...", &asset_lock_proof[..100])
-            } else {
-                asset_lock_proof.clone()
-            }
-        )));
-        web_sys::console::log_1(&JsValue::from_str(&format!(
-            "  asset_lock_proof_private_key: [REDACTED] (length: {})",
-            asset_lock_proof_private_key.len()
-        )));
-        web_sys::console::log_1(&JsValue::from_str(&format!(
-            "  public_keys: {}",
-            public_keys
-        )));
+        // Intentionally avoid logging sensitive inputs in production.

769-807: Fix key-purpose check for withdrawals (invalid Purpose::OWNER)

Purpose::OWNER isn’t a defined DPP purpose (you already map and use AUTHENTICATION/TRANSFER elsewhere). For withdrawals, allow either TRANSFER keys or MASTER AUTHENTICATION keys.

Apply this diff:

-                .filter(|key| {
-                    (key.purpose() == Purpose::TRANSFER || key.purpose() == Purpose::OWNER)
-                        && key.key_type() == KeyType::ECDSA_HASH160
-                        && key.data().as_slice() == public_key_hash160.as_slice()
-                })
+                .filter(|key| {
+                    (key.purpose() == Purpose::TRANSFER
+                        || (key.purpose() == Purpose::AUTHENTICATION
+                            && key.security_level() == SecurityLevel::MASTER))
+                        && key.key_type() == KeyType::ECDSA_HASH160
+                        && key.data().as_slice() == public_key_hash160.as_slice()
+                })
@@
-                .or_else(|| {
-                    identity.public_keys().iter().find(|(_, key)| {
-                        key.purpose() == Purpose::OWNER
-                            && key.key_type() == KeyType::ECDSA_HASH160
-                            && key.data().as_slice() == public_key_hash160.as_slice()
-                    })
-                })
+                .or_else(|| {
+                    identity.public_keys().iter().find(|(_, key)| {
+                        key.purpose() == Purpose::AUTHENTICATION
+                            && key.security_level() == SecurityLevel::MASTER
+                            && key.key_type() == KeyType::ECDSA_HASH160
+                            && key.data().as_slice() == public_key_hash160.as_slice()
+                    })
+                })
packages/wasm-sdk/src/state_transitions/documents/mod.rs (2)

347-359: Don’t .unwrap() on JS property sets; propagate as WasmSdkError.

A failed Reflect::set will panic the WASM. Use your existing error type or a tiny helper.

- js_sys::Reflect::set(&js_result, &JsValue::from_str("type"), &JsValue::from_str("DocumentCreated")).unwrap();
+ js_sys::Reflect::set(&js_result, &JsValue::from_str("type"), &JsValue::from_str("DocumentCreated"))
+   .map_err(|e| WasmSdkError::generic(format!("Failed to set type: {:?}", e)))?;

Optionally add a helper next to build_js_result_object:

+#[inline]
+fn set_prop(obj: &js_sys::Object, key: &str, value: JsValue) -> Result<(), WasmSdkError> {
+  js_sys::Reflect::set(obj, &JsValue::from_str(key), &value)
+    .map_err(|e| WasmSdkError::generic(format!("Failed to set {}: {:?}", key, e)))?;
+  Ok(())
+}

Also applies to: 354-360, 361-391, 392-399, 401-409, 410-417, 419-446


321-332: Prefer build_js_result_object for uniform responses.

You already have a helper that sets type/documentId and handles errors. Using it reduces repeated JS glue and unwraps.

Also applies to: 483-505

packages/wasm-sdk/src/state_transitions/tokens/mod.rs (1)

71-82: Replace direct sdk.network accesses with self.network() — compile error

The inner SDK's network field is not public across crates; use the WasmSdk accessor self.network().

-    match sdk.network {
+    match self.network() {
      dash_sdk::dpp::dashcore::Network::Testnet => { ... }
      dash_sdk::dpp::dashcore::Network::Dash => { ... }
      _ => {}
    }
- let signer = crate::sdk::WasmSdk::create_signer_from_wif(&private_key_wif, sdk.network)?;
+ let signer = crate::sdk::WasmSdk::create_signer_from_wif(&private_key_wif, self.network())?;

Locations: packages/wasm-sdk/src/state_transitions/tokens/mod.rs — lines 71, 187, 269, 356, 448, 539, 630, 767, 957, 1059, 1280

packages/wasm-sdk/src/queries/document.rs (2)

180-226: Identifier detection: remove length/alnum heuristic; attempt parse instead.

Heuristic len()==44 && is_alphanumeric can misclassify strings and miss valid identifiers. Try parsing as Identifier first; fall back to text on error.

-        JsonValue::String(s) => {
-            // Check if it's an identifier (base58 encoded)
-            if s.len() == 44 && s.chars().all(|c| c.is_alphanumeric()) {
-                // Try to parse as identifier
-                match Identifier::from_string(
-                    s,
-                    dash_sdk::dpp::platform_value::string_encoding::Encoding::Base58,
-                ) {
-                    Ok(id) => Ok(platform_value!(id)),
-                    Err(_) => Ok(Value::Text(s.clone())),
-                }
-            } else {
-                Ok(Value::Text(s.clone()))
-            }
-        }
+        JsonValue::String(s) => {
+            match Identifier::from_string(
+                s,
+                dash_sdk::dpp::platform_value::string_encoding::Encoding::Base58,
+            ) {
+                Ok(id) => Ok(platform_value!(id)),
+                Err(_) => Ok(Value::Text(s.clone())),
+            }
+        }

96-144: Add NotEqual (and optional Contains) and unify operator parsing across modules

  • Found: WhereOperator (packages/rs-drive/src/query/conditions.rs) defines Equal, GreaterThan, GreaterThanOrEquals, LessThan, LessThanOrEquals, Between*, In, StartsWith — it lacks NotEqual and Contains.
  • Affected: packages/wasm-sdk/src/queries/document.rs (parse_where_clause) and packages/rs-sdk-ffi/src/document/queries/search.rs (parse_where_operator) do not accept '!=' / not-equal synonyms; verifier mappings (packages/wasm-drive-verify/src/document/*.rs) use different canonical names and also don’t cover NotEqual.
  • Action: add NotEqual (and Contains if AI_REFERENCE.md requires) to WhereOperator and implement Display, from_string, from_sql_operator (map SQL NotEq); extend wasm-sdk and FFI parsers to accept '!=', 'ne', 'notEqual', 'not_equal' (and 'contains' synonyms); update verifier mappings and AI_REFERENCE.md; run query/FFI tests to validate behavior.
🧹 Nitpick comments (107)
.github/workflows/wasm-sdk-documentation-check.yml (4)

3-4: Replace stray TODO with a concise purpose line.

Avoid TODO noise in CI files; state the workflow’s intent.

-# TODO: Update
+# Purpose: Detect WASM SDK docs drift and auto-update or open a PR when out of date.

70-76: Prevent artifact step from failing when report is missing.

Set if-no-files-found to warn. check_documentation.py may not always emit a report.

       - name: Upload documentation check report
         if: always()
         uses: actions/upload-artifact@v4
         with:
           name: documentation-check-report
           path: packages/wasm-sdk/documentation-check-report.txt
+          if-no-files-found: warn

120-134: Non-protected auto-update: reduce push races.

Rebase before pushing to avoid occasional non-fast-forward failures.

           if ! git diff --quiet docs.html docs_manifest.json AI_REFERENCE.md; then
             git config --local user.email "github-actions[bot]@users.noreply.github.com"
             git config --local user.name "github-actions[bot]"
+            git pull --rebase --autostash || true
             git add docs.html docs_manifest.json AI_REFERENCE.md
             git commit -m "chore: update WASM SDK documentation [skip ci]"
             git push
           fi

154-154: Make the failure message maximally actionable.

Include the exact commands and note that docs are generated from sources.

-echo "Documentation is out of date. Please run 'python3 generate_docs.py' in packages/wasm-sdk/"
+echo "Documentation is out of date.
+To regenerate locally:
+  cd packages/wasm-sdk
+  python3 generate_docs.py
+Then commit docs.html, docs_manifest.json, and AI_REFERENCE.md."
packages/wasm-sdk/README.md (6)

55-56: Document with_settings(...) parameter names.

Avoid magic numbers by noting param order (e.g., requestTimeoutMs, connectTimeoutMs, retries, verifyProofs).

-builder = builder.with_settings(5000, 10000, 3, true);
+// with_settings(requestTimeoutMs, connectTimeoutMs, retries, verifyProofs)
+builder = builder.with_settings(5000, 10000, 3, true);

58-61: Clarify DPNS example network.

Add a note that the contract ID is an example (likely testnet) to prevent users trying it on mainnet.

-const DPNS = 'GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec';
+// Example DPNS contract ID (testnet). Replace with your target network’s ID.
+const DPNS = 'GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec';

59-60: Unify null/undefined usage in examples.

Elsewhere Option‑like params use undefined. Consider using it consistently for clarity.

-const docs = await sdk.get_documents(client, DPNS, 'domain', null, null, 5, null, null);
+const docs = await sdk.get_documents(client, DPNS, 'domain', undefined, undefined, 5, undefined, undefined);

175-177: Consider bumping minimum Node to 18+.

Node 16 is EOL; recommending 18+ reduces support risk for WASM/Workers and fetch.


183-189: Add SSR troubleshooting note.

Call out Next.js/Vite SSR patterns to prevent init during SSR.

 - Always `await init()` before calling functions.
+ - Always `await init()` before calling functions.
+ - SSR (e.g., Next.js): import and call `init()` only in browser code paths
+   (e.g., inside `useEffect` or behind `typeof window !== 'undefined'`).

1-200: Keep generated docs in sync.

If API surface changed (method-based calls, params), regenerate AI_REFERENCE.md and docs.html from api-definitions.json via generate_docs.py to prevent drift.

packages/js-evo-sdk/.gitignore (1)

1-1: Add common build artefacts to ignore list

Consider also ignoring TypeScript build info and OS cruft to avoid accidental commits.

 dist
+*.tsbuildinfo
+.DS_Store
+Thumbs.db
+coverage
packages/wasm-sdk/scripts/build-optimized.sh (1)

19-19: Use pushd/popd and check directory exists

Safer directory handling and clearer logs.

-cd "$SCRIPT_DIR/../pkg"
+PKG_DIR="$SCRIPT_DIR/../pkg"
+test -d "$PKG_DIR" || { echo "Error: $PKG_DIR not found"; exit 1; }
+pushd "$PKG_DIR" >/dev/null
...
+popd >/dev/null
packages/js-evo-sdk/tsconfig.json (1)

15-17: Prefer project refs or package-root fallback — current path maps are fragile

packages/wasm-sdk/package.json already declares "types": "./dist/sdk.d.ts" and exports, but packages/wasm-sdk/dist/sdk.d.ts is not present; packages/js-evo-sdk/tsconfig.json currently maps to "../wasm-sdk/dist/sdk.d.ts".

  • Preferred: remove compilerOptions.paths from packages/js-evo-sdk/tsconfig.json and add "references": [{ "path": "../wasm-sdk" }]; add packages/wasm-sdk/tsconfig.json with compilerOptions { "composite": true, "declaration": true, "outDir": "dist" } so tsc --build orders and emits .d.ts.
  • Alternative: remove paths and rely on package exports/types (package.json already has "types") but ensure CI/build produces packages/wasm-sdk/dist before building js-evo-sdk.
  • If keeping paths: add a package-root fallback: "@dashevo/wasm-sdk": ["../wasm-sdk", "../wasm-sdk/dist/sdk.d.ts"].
packages/scripts/build-wasm.sh (3)

174-175: Unused variable: WASM_OPT_VERSION.

It’s assigned but never read. Remove it or use it to gate flags.

-        WASM_OPT_VERSION=$(wasm-opt --version 2>/dev/null || echo "")
+        # (removed) WASM_OPT_VERSION was unused

176-195: nit: repeated -Oz flags and eclectic core list.

Repeated -Oz is redundant and makes logs noisy. Consider trimming to a deliberate minimal set.

-            -Oz
-            --converge
-            --vacuum
-            --merge-blocks
-            --simplify-locals
-            --remove-unused-brs
-            --remove-unused-module-elements
-            --remove-unused-names
-            -Oz
-            -Oz
+            -Oz
+            --converge --vacuum --merge-blocks --simplify-locals \
+            --remove-unused-brs --remove-unused-module-elements --remove-unused-names

214-223: Many probe runs of wasm-opt can slow builds.

Feature-probing each optional flag runs wasm-opt N times. Prefer version-based gating to reduce build time.

packages/wasm-sdk/scripts/bundle.cjs (2)

64-70: Consider guarding pkg/ removal behind an env flag.

Removing pkg/ is fine for publish, but can surprise local dev flows. Make it opt-out via KEEP_PKG=1.

-try {
-  fs.rmSync(pkgDir, { recursive: true, force: true });
-  console.log('Removed pkg/ directory after bundling');
-} catch (e) {
+try {
+  if (!process.env.KEEP_PKG) {
+    fs.rmSync(pkgDir, { recursive: true, force: true });
+    console.log('Removed pkg/ directory after bundling');
+  } else {
+    console.log('KEEP_PKG=1 set; preserving pkg/ directory');
+  }
+} catch (e) {
   console.warn('Warning: failed to remove pkg/ directory:', e?.message || e);
 }

21-22: nit: unused typesDir.

Drop it to avoid confusion.

-const typesDir = path.join(root, 'types');
.pnp.cjs (13)

5475-5510: Duplicate virtual blocks for @webpack-cli/configtest suggest diverging peer graphs.

Consider unifying webpack/cli peer versions across packages to dedupe.


5574-5603: Duplicate virtual blocks for @webpack-cli/info.

Same recommendation: align peers (webpack-cli, types) to reduce virtual variants.


5679-5714: Duplicate virtual blocks for @webpack-cli/serve.

Align webpack-cli and webpack-dev-server peer ranges across packages.


13484-13499: Duplicate karma-webpack virtual instance (set A).

Likely caused by differing webpack peer trees; unify versions if possible.


13516-13531: Duplicate karma-webpack virtual instance (set B).

Same as above.


18810-18839: Multiple terser-webpack-plugin virtuals (set A).

Unify webpack and terser-plugin versions to dedupe.


18989-19019: Multiple terser-webpack-plugin virtuals (set B).

Same as above.


19300-19321: Multiple ts-loader virtuals.

Prefer a single ts-loader and TypeScript version across packages.


20426-20461: Duplicate webpack virtual (set A).

Standard symptom of diverging peers (webpack-cli, terser-plugin). Align to reduce cache/install churn.


20498-20533: Duplicate webpack virtual (set B).

Same as above.


20661-20701: Duplicate webpack-cli virtual (set A).

Unify cli and related peer deps across packages.


20743-20783: Duplicate webpack-cli virtual (set B).

Same as above.


3113-3146: Update @types/node to match CI Node 20 (wasm packages)

CI/workflows use Node 20 and dashmate declares engines >=20, but packages/wasm-sdk, packages/wasm-dpp and packages/js-dash-sdk still depend on @types/node ^14.6.0 — align to ^20.0.0 (or at least >=18) to avoid TypeScript lib mismatches. Update these package.json entries and regenerate the lockfile (yarn install).

Files to change: packages/wasm-sdk/package.json, packages/wasm-dpp/package.json, packages/js-dash-sdk/package.json.

packages/wasm-sdk/src/wallet/extended_derivation.rs (3)

136-155: Identity ID decoding: support hex without 0x and validate length.

Current logic assumes non-0x input is base58. Accept 64-char hex too; validate 32 bytes post-decode.

Apply this diff:

-        let sender_id_formatted = if sender_identity_id.starts_with("0x") {
-            sender_identity_id.to_string()
-        } else {
-            // Decode base58 to bytes, then convert to hex
-            let bytes = bs58::decode(sender_identity_id)
-                .into_vec()
-                .map_err(|e| WasmSdkError::invalid_argument(format!("Invalid sender identity ID: {}", e)))?;
-            format!("0x{}", hex::encode(bytes))
-        };
+        let sender_id_formatted = if sender_identity_id.starts_with("0x") {
+            sender_identity_id.to_string()
+        } else if sender_identity_id.len() == 64 && sender_identity_id.chars().all(|c| c.is_ascii_hexdigit()) {
+            format!("0x{}", sender_identity_id)
+        } else {
+            let bytes = bs58::decode(sender_identity_id)
+                .into_vec()
+                .map_err(|e| WasmSdkError::invalid_argument(format!("Invalid sender identity ID: {}", e)))?;
+            if bytes.len() != 32 {
+                return Err(WasmSdkError::invalid_argument("Sender identity ID must be 32 bytes"));
+            }
+            format!("0x{}", hex::encode(bytes))
+        };
@@
-        let receiver_id_formatted = if receiver_identity_id.starts_with("0x") {
-            receiver_identity_id.to_string()
-        } else {
-            // Decode base58 to bytes, then convert to hex
-            let bytes = bs58::decode(receiver_identity_id)
-                .into_vec()
-                .map_err(|e| WasmSdkError::invalid_argument(format!("Invalid receiver identity ID: {}", e)))?;
-            format!("0x{}", hex::encode(bytes))
-        };
+        let receiver_id_formatted = if receiver_identity_id.starts_with("0x") {
+            receiver_identity_id.to_string()
+        } else if receiver_identity_id.len() == 64 && receiver_identity_id.chars().all(|c| c.is_ascii_hexdigit()) {
+            format!("0x{}", receiver_identity_id)
+        } else {
+            let bytes = bs58::decode(receiver_identity_id)
+                .into_vec()
+                .map_err(|e| WasmSdkError::invalid_argument(format!("Invalid receiver identity ID: {}", e)))?;
+            if bytes.len() != 32 {
+                return Err(WasmSdkError::invalid_argument("Receiver identity ID must be 32 bytes"));
+            }
+            format!("0x{}", hex::encode(bytes))
+        };

67-118: JS ergonomics: add camelCase aliases for returned fields.

Keep snake_case for compatibility, but also set camelCase keys (privateKeyWif/Hex, publicKey, xprv/xpub ok, address, addressIndex already camelCase). This eases TS/JS usage.

Apply this diff:

         js_sys::Reflect::set(&obj, &JsValue::from_str("path"), &JsValue::from_str(path))?;
+        js_sys::Reflect::set(&obj, &JsValue::from_str("derivationPath"), &JsValue::from_str(path))?;
@@
         js_sys::Reflect::set(
             &obj,
             &JsValue::from_str("private_key_wif"),
             &JsValue::from_str(&private_key.to_wif()),
         )?;
+        js_sys::Reflect::set(&obj, &JsValue::from_str("privateKeyWif"), &JsValue::from_str(&private_key.to_wif()))?;
@@
         js_sys::Reflect::set(
             &obj,
             &JsValue::from_str("private_key_hex"),
             &JsValue::from_str(&hex::encode(private_key.inner.secret_bytes())),
         )?;
+        js_sys::Reflect::set(&obj, &JsValue::from_str("privateKeyHex"), &JsValue::from_str(&hex::encode(private_key.inner.secret_bytes())))?;
@@
         js_sys::Reflect::set(
             &obj,
             &JsValue::from_str("public_key"),
             &JsValue::from_str(&hex::encode(public_key.to_bytes())),
         )?;
+        js_sys::Reflect::set(&obj, &JsValue::from_str("publicKey"), &JsValue::from_str(&hex::encode(public_key.to_bytes())))?;

31-35: Network handling: accept regtest/devnet or expose SDK-configured network

Currently only "mainnet"/"testnet" are handled in packages/wasm-sdk/src/wallet/extended_derivation.rs (lines 31-35 and 159-163). Add "regtest"/"devnet" or provide an instance wrapper that uses self.network().

Apply this diff to broaden acceptance:

-        let net = match network {
-            "mainnet" => dashcore::Network::Dash,
-            "testnet" => dashcore::Network::Testnet,
-            _ => return Err(WasmSdkError::invalid_argument("Invalid network")),
-        };
+        let net = match network {
+            "mainnet" => dashcore::Network::Dash,
+            "testnet" => dashcore::Network::Testnet,
+            "regtest" => dashcore::Network::Regtest,
+            "devnet" => dashcore::Network::Devnet,
+            _ => return Err(WasmSdkError::invalid_argument("Invalid network")),
+        };

Optional instance wrapper:

#[wasm_bindgen(js_name = "deriveKeyFromSeedWithExtendedPathUsingSdkNetwork")]
pub fn derive_key_from_seed_with_extended_path_using_sdk_network(
    &self,
    mnemonic: &str,
    passphrase: Option<String>,
    path: &str,
) -> Result<JsValue, WasmSdkError> {
    let network = match self.network() {
        dash_sdk::dpp::dashcore::Network::Dash => "mainnet",
        dash_sdk::dpp::dashcore::Network::Testnet => "testnet",
        dash_sdk::dpp::dashcore::Network::Regtest => "regtest",
        dash_sdk::dpp::dashcore::Network::Devnet => "devnet",
        _ => "mainnet",
    };
    Self::derive_key_from_seed_with_extended_path(mnemonic, passphrase, path, network)
}
packages/wasm-sdk/src/error.rs (1)

6-6: Duplicate import; remove to avoid shadowing/glob conflicts.

Apply this diff:

-use dash_sdk::Error::{EpochNotFound, TotalCreditsNotFound};
packages/wasm-sdk/src/dpp.rs (1)

301-311: DataContract JSON: tidy error messages and use serde::Serialize import.

Apply this diff:

-            .map_err(|e| WasmSdkError::serialization(format!("failed to convert data contract convert to json: {}", e)))?;
+            .map_err(|e| WasmSdkError::serialization(format!("failed to convert data contract to json: {}", e)))?;
@@
-        json.serialize(&serializer).map_err(|e| WasmSdkError::serialization(format!("can't serialize to json: {}", e)))
+        json.serialize(&serializer).map_err(|e| WasmSdkError::serialization(format!("failed to serialize to JSON: {}", e)))

Outside selected lines, prefer:

// outside selected lines (supporting)
use serde::Serialize;
packages/js-evo-sdk/tests/stubs/wasm-sdk-stub.mjs (1)

26-33: Add wallet derivation stubs to cover new JS surface.

Apply this diff:

 export class WasmSdk {}
 
 // Documents
@@
 export function get_document_with_proof_info(...args) { const r = record('get_document_with_proof_info', args); calls.push(r); return Promise.resolve(r); }
 
+// Wallet derivation (new)
+export function deriveKeyFromSeedWithExtendedPath(...args) { const r = record('deriveKeyFromSeedWithExtendedPath', args); calls.push(r); return Promise.resolve({ ...r, xpub: 'xpub...', xprv: 'xprv...', address: 'X...' }); }
+export function deriveDashpayContactKey(...args) { const r = record('deriveDashpayContactKey', args); calls.push(r); return Promise.resolve({ ...r, dipStandard: 'DIP15' }); }
+
packages/js-evo-sdk/.mocharc.yml (1)

1-4: Increase timeout and ensure clean exit to avoid flakey CI runs

WASM init/build can be slow on CI. Recommend bumping timeout and enabling Mocha’s forced exit.

Apply:

 require:
   - tests/bootstrap.cjs
 recursive: true
-timeout: 8000
+timeout: 20000
+exit: true
packages/js-evo-sdk/tests/unit/sdk.spec.mjs (1)

12-17: Avoid accidental real WASM initialization in unit tests

Per repo guidance, unit tests shouldn’t touch the network or heavy native init. Consider stubbing the WASM SDK builder (or using EvoSDK.fromWasm with a minimal stub) so connect() doesn’t load real bindings.

If you want, I can provide a lightweight builder stub pattern that works in Node Mocha without Karma aliases.

packages/js-evo-sdk/src/util.ts (1)

1-5: Handle BigInt/circular structures to prevent JSON.stringify crashes

JSON.stringify throws on BigInt and circular refs. Add safe handling to avoid unexpected test/runtime failures.

Apply:

 export function asJsonString(value: unknown): string | undefined {
   if (value == null) return undefined;
   if (typeof value === 'string') return value;
-  return JSON.stringify(value);
+  try {
+    if (typeof value === 'bigint') {
+      // Preserve numeric meaning as string; callers can parse if needed
+      return value.toString();
+    }
+    const seen = new WeakSet();
+    return JSON.stringify(value, (_k, v) => {
+      if (typeof v === 'object' && v !== null) {
+        if (seen.has(v as object)) return '[Circular]';
+        seen.add(v as object);
+      }
+      if (typeof v === 'bigint') return v.toString();
+      return v;
+    });
+  } catch (e) {
+    // Fallback to toString to never throw in utility
+    return String(value);
+  }
 }
packages/js-evo-sdk/src/wasm.ts (2)

4-11: Make ensureInitialized truly return Promise

Currently it resolves to the wasm namespace (any). Keep the cache, but resolve to void to match the signature and avoid accidental misuse.

-let initPromise: Promise<any> | undefined;
+let initPromise: Promise<void> | undefined;

 export async function ensureInitialized(): Promise<void> {
   if (!initPromise) {
-    initPromise = initWasmSdk().then(() => wasm);
+    initPromise = (async () => { await initWasmSdk(); })();
   }
   return initPromise;
 }

Confirm all call sites import it as a side-effectful init (e.g., import { ensureInitialized as initWasm } from './wasm'). If any rely on a returned value, they should be updated.


13-15: Re-exporting default and all symbols is fine; consider tree-shakeability

If bundle size matters, consider marking @dashevo/wasm-sdk as external in webpack rather than bundling through re-exports.

packages/js-evo-sdk/tests/unit/facades/group.spec.mjs (1)

5-9: Prefer a before hook with this.skip() over early return

Early return inside describe works but can surprise reporters. Use a top-level before to skip the suite in Node.

 describe('GroupFacade', () => {
-  if (!isBrowser) {
-    it('skips in Node environment (browser-only)', function () { this.skip(); });
-    return;
-  }
+  before(function () {
+    if (!isBrowser) this.skip();
+  });
packages/js-evo-sdk/webpack.config.cjs (3)

4-18: Resolve config looks good; consider aliasing tests to stubs in web builds

If desired, add a conditional alias for tests so @dashevo/wasm-sdk maps to the test stub during Karma runs (keeps unit tests fast/deterministic).

Example (guarded by env like KARMA=1):

 resolve: {
   extensions: ['.ts', '.js', '.json'],
   extensionAlias: { '.js': ['.ts', '.js'] },
+  alias: process.env.KARMA ? {
+    '@dashevo/wasm-sdk': path.resolve(__dirname, 'tests/stubs/wasm-sdk-stub.mjs'),
+  } : {},
 },

19-24: Minification config: preserve function/class names if tests rely on them

You keep class names; if any tests/assertions rely on function names, consider keep_fnames too.

-    minimizer: [new TerserPlugin({ terserOptions: { keep_classnames: true } })],
+    minimizer: [new TerserPlugin({ terserOptions: { keep_classnames: true, keep_fnames: true } })],

27-37: Consider externalizing @dashevo/wasm-sdk for smaller ESM bundle

If consumers already load the WASM SDK separately, declare it external to reduce bundle size.

Example:

 const esm = {
   ...base,
   experiments: { outputModule: true },
+  externals: {
+    '@dashevo/wasm-sdk': 'module @dashevo/wasm-sdk',
+  },
   output: {
packages/js-evo-sdk/tests/karma/karma.conf.cjs (1)

3-16: Add 'sourcemap' preprocessor to karma.conf.cjs

Confirmed packages/js-evo-sdk/tests/karma/options.cjs declares frameworks ['mocha','chai','webpack'], karmaWebpack plugin and reporters ['mocha']; add sourcemap to get accurate stack traces.

Apply:

   preprocessors: {
-      '../bootstrap.cjs': ['webpack'],
-      '../unit/**/*.spec.mjs': ['webpack'],
+      '../bootstrap.cjs': ['webpack', 'sourcemap'],
+      '../unit/**/*.spec.mjs': ['webpack', 'sourcemap'],
   },
packages/js-evo-sdk/package.json (1)

7-15: Export types on subpath for TS consumers

Optional: expose types for "./module" too for consistent TS resolution.

   "exports": {
     ".": {
       "types": "./dist/sdk.d.ts",
       "import": "./dist/evo-sdk.module.js"
     },
     "./module": {
-      "import": "./dist/evo-sdk.module.js"
+      "types": "./dist/sdk.d.ts",
+      "import": "./dist/evo-sdk.module.js"
     }
   },
packages/wasm-sdk/src/queries/protocol.rs (1)

74-77: Unused import

MasternodeProtocolVoteEx isn’t used; remove to keep clippy clean.

-        use dash_sdk::platform::types::version_votes::MasternodeProtocolVoteEx;
packages/js-evo-sdk/tests/unit/facades/tokens.spec.mjs (1)

16-60: Add one spot‑check for a “with_proof” query’s args

You already spot‑check priceByContract. Add a quick args check for one _with_proof call (e.g., statusesWithProof) to ensure the wasm handle is first and placeholders (if any) are correct.

packages/js-evo-sdk/tests/karma/options.cjs (2)

31-37: Trim polyfills to only what’s needed

Node fallbacks and ProvidePlugin adds weight. If tests don’t use fs/url/events/assert/string_decoder/util, drop them to speed up bundling.

Also applies to: 45-55


62-64: Make singleRun and launcher CI‑aware

Defaulting to watch mode is fine locally, but CI should be single-run and often needs no‑sandbox. Suggest:

-  browsers: ['ChromeHeadlessInsecure'],
-  singleRun: false,
+  browsers: [process.env.CI ? 'ChromeHeadlessNoSandbox' : 'ChromeHeadlessInsecure'],
+  singleRun: !!process.env.CI,
@@
   customLaunchers: {
     ChromeHeadlessInsecure: {
       base: 'ChromeHeadless',
       flags: [
         '--allow-insecure-localhost',
       ],
       displayName: 'Chrome w/o security',
     },
+    ChromeHeadlessNoSandbox: {
+      base: 'ChromeHeadless',
+      flags: ['--no-sandbox', '--disable-dev-shm-usage'],
+      displayName: 'Chrome CI no-sandbox',
+    },
   },

Also applies to: 79-87

packages/js-evo-sdk/tests/unit/facades/documents.spec.mjs (1)

36-43: Optional extra: proof args spot‑check

Consider one explicit args check for queryWithProof/getWithProof placeholders (nulls) similar to getHistory tests in contracts.

packages/js-evo-sdk/src/system/facade.ts (1)

14-16: Double‑check blocking call behavior

waitForStateTransitionResult can be long‑running; consider documenting typical timeouts or exposing an optional timeout in a follow‑up.

packages/js-evo-sdk/src/epoch/facade.ts (3)

35-43: Validate epoch and ids before forwarding

Guard against negative epoch and empty/oversized ids arrays to fail fast in JS and avoid confusing WASM errors.

   async evonodesProposedBlocksByIds(epoch: number, ids: string[]): Promise<any> {
+    if (!Number.isInteger(epoch) || epoch < 0) throw new TypeError('epoch must be a non-negative integer');
+    if (!Array.isArray(ids) || ids.length === 0) throw new TypeError('ids must be a non-empty array');
     const w = await this.sdk.getWasmSdkConnected();
     return wasm.get_evonodes_proposed_epoch_blocks_by_ids(w, epoch, ids);
   }

45-55: Range query: add basic input checks

Validate epoch, limit bounds, and startAfter type to catch client bugs early.

   async evonodesProposedBlocksByRange(epoch: number, opts: { limit?: number; startAfter?: string; orderAscending?: boolean } = {}): Promise<any> {
-    const { limit, startAfter, orderAscending } = opts;
+    const { limit, startAfter, orderAscending } = opts;
+    if (!Number.isInteger(epoch) || epoch < 0) throw new TypeError('epoch must be a non-negative integer');
+    if (limit != null && (!Number.isInteger(limit) || limit <= 0)) throw new TypeError('limit must be a positive integer');
+    if (startAfter != null && typeof startAfter !== 'string') throw new TypeError('startAfter must be a string');
     const w = await this.sdk.getWasmSdkConnected();
     return wasm.get_evonodes_proposed_epoch_blocks_by_range(w, epoch, limit ?? null, startAfter ?? null, orderAscending ?? null);
   }

8-18: Consider tightening return types

All methods return Promise. If we have WASM TS types (e.g., EpochInfo[], proofs), expose them to improve DX and catch mistakes at compile time.

Can you confirm available TS types from ../wasm.js for these calls? If present, I can propose a typed facade surface.

Also applies to: 20-30, 32-34

packages/js-evo-sdk/src/identities/facade.ts (5)

42-46: Avoid non-null assertions; validate required payloads

asJsonString(...)! will pass undefined at runtime if callers use JS and omit fields. Validate and throw a clear error.

   async create(args: { assetLockProof: unknown; assetLockPrivateKeyWif: string; publicKeys: unknown[] }): Promise<any> {
     const { assetLockProof, assetLockPrivateKeyWif, publicKeys } = args;
     const w = await this.sdk.getWasmSdkConnected();
-    return w.identityCreate(asJsonString(assetLockProof)!, assetLockPrivateKeyWif, asJsonString(publicKeys)!);
+    const proofJson = asJsonString(assetLockProof);
+    const pubKeysJson = asJsonString(publicKeys);
+    if (proofJson == null) throw new TypeError('assetLockProof is required');
+    if (pubKeysJson == null) throw new TypeError('publicKeys are required');
+    return w.identityCreate(proofJson, assetLockPrivateKeyWif, pubKeysJson);
   }

48-52: Same here: validate topUp payload

Mirror the create() guard for topUp.

   async topUp(args: { identityId: string; assetLockProof: unknown; assetLockPrivateKeyWif: string }): Promise<any> {
     const { identityId, assetLockProof, assetLockPrivateKeyWif } = args;
     const w = await this.sdk.getWasmSdkConnected();
-    return w.identityTopUp(identityId, asJsonString(assetLockProof)!, assetLockPrivateKeyWif);
+    const proofJson = asJsonString(assetLockProof);
+    if (proofJson == null) throw new TypeError('assetLockProof is required');
+    return w.identityTopUp(identityId, proofJson, assetLockPrivateKeyWif);
   }

60-64: Do not default coreFeePerByte to 1

Let the SDK/server default apply unless explicitly provided; passing 1 silently alters fee calculation.

-  async creditWithdrawal(args: { identityId: string; toAddress: string; amount: number | bigint | string; coreFeePerByte?: number; privateKeyWif: string; keyId?: number }): Promise<any> {
-    const { identityId, toAddress, amount, coreFeePerByte = 1, privateKeyWif, keyId } = args;
+  async creditWithdrawal(args: { identityId: string; toAddress: string; amount: number | bigint | string; coreFeePerByte?: number; privateKeyWif: string; keyId?: number }): Promise<any> {
+    const { identityId, toAddress, amount, coreFeePerByte, privateKeyWif, keyId } = args;
     const w = await this.sdk.getWasmSdkConnected();
     return w.identityCreditWithdrawal(identityId, toAddress, BigInt(amount), coreFeePerByte ?? null, privateKeyWif, keyId ?? null);
   }

54-58: BigInt conversion: guard non-integer strings

BigInt('1.2') or BigInt(1.1) throws. Add a minimal check to fail fast.

-    return w.identityCreditTransfer(senderId, recipientId, BigInt(amount), privateKeyWif, keyId ?? null);
+    const asBig = typeof amount === 'bigint' ? amount
+      : typeof amount === 'number' ? BigInt(Math.trunc(amount))
+      : (/^\d+$/u.test(amount) ? BigInt(amount) : (() => { throw new TypeError('amount must be an integer'); })());
+    return w.identityCreditTransfer(senderId, recipientId, asBig, privateKeyWif, keyId ?? null);

Apply the same pattern in creditWithdrawal if desired.

Also applies to: 60-64


27-40: getKeys: align inputs with request type

Enforce that specificKeyIds is provided for 'specific', and searchPurposeMap for 'search', to avoid server-side errors.

   async getKeys(args: { identityId: string; keyRequestType: 'all' | 'specific' | 'search'; specificKeyIds?: number[]; searchPurposeMap?: unknown; limit?: number; offset?: number }): Promise<any> {
     const { identityId, keyRequestType, specificKeyIds, searchPurposeMap, limit, offset } = args;
+    if (keyRequestType === 'specific' && (!specificKeyIds || specificKeyIds.length === 0)) {
+      throw new TypeError('specificKeyIds is required when keyRequestType is "specific"');
+    }
+    if (keyRequestType === 'search' && searchPurposeMap == null) {
+      throw new TypeError('searchPurposeMap is required when keyRequestType is "search"');
+    }
packages/wasm-sdk/src/state_transitions/contracts/mod.rs (3)

139-161: Reflect::set generic error mapping: OK, but keep messages stable

Messages are user-facing; consider shorter, stable strings (without debug {:?}) to avoid leaking internals.

Also applies to: 175-181, 182-189, 367-385, 386-393


14-15: Remove unused import

use js_sys; is unused; rely on fully qualified paths or import specific items.

-use js_sys;

312-319: Version increment check: good, keep message concise

Check is correct; consider a shorter error to reduce payload size over WASM.

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

633-641: with_version validation: good; update docs

Returning Result with a clear invalid_argument mapping is great. Please regenerate docs so the JS surface shows this change.

I can run/update generate_docs.py changes if needed.


98-318: Static address lists: consider externalization

Non-blocking: huge hardcoded lists increase diff noise and maintenance. Consider moving to a resource file or allowing override via JS to ease updates.

Also applies to: 335-577

packages/js-evo-sdk/src/contracts/facade.ts (4)

56-60: Validate required inputs; avoid non-null assertions

Ensure definition is present to prevent undefined crossing the WASM boundary.

   async create(args: { ownerId: string; definition: unknown; privateKeyWif: string; keyId?: number }): Promise<any> {
     const { ownerId, definition, privateKeyWif, keyId } = args;
     const w = await this.sdk.getWasmSdkConnected();
-    return w.contractCreate(ownerId, asJsonString(definition)!, privateKeyWif, keyId ?? null);
+    const defJson = asJsonString(definition);
+    if (defJson == null) throw new TypeError('definition is required');
+    return w.contractCreate(ownerId, defJson, privateKeyWif, keyId ?? null);
   }

62-66: Same for update: validate updates

   async update(args: { contractId: string; ownerId: string; updates: unknown; privateKeyWif: string; keyId?: number }): Promise<any> {
     const { contractId, ownerId, updates, privateKeyWif, keyId } = args;
     const w = await this.sdk.getWasmSdkConnected();
-    return w.contractUpdate(contractId, ownerId, asJsonString(updates)!, privateKeyWif, keyId ?? null);
+    const updatesJson = asJsonString(updates);
+    if (updatesJson == null) throw new TypeError('updates are required');
+    return w.contractUpdate(contractId, ownerId, updatesJson, privateKeyWif, keyId ?? null);
   }

22-32: BigInt conversion for startAtMs: guard non-integers

BigInt will throw on non-integer input; add a small check if this can be user-supplied.

If startAtMs can come from Date.now(), it’s integer already; otherwise consider sanitizing.

Also applies to: 34-44


12-20: Return typing

fetch returns DataContractWasm (good). For others, consider explicit TS return types if available from wasm.d.ts to improve ergonomics.

Also applies to: 46-54

packages/wasm-sdk/src/dpns.rs (1)

1-1: Remember to regenerate WASM SDK docs after public API/error changes

This file switches DPNS exports to return WasmSdkError. Per repo guidelines, regenerate docs (generate_docs.py) to keep them in sync.

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

1226-1229: Avoid unwrap on number-to-f64 conversion

n.as_f64().unwrap() can panic for non-finite numbers. Convert to an error instead.

Apply this diff:

-                        Ok(dash_sdk::dpp::platform_value::Value::Float(
-                            n.as_f64().unwrap(),
-                        ))
+                        n.as_f64()
+                            .map(dash_sdk::dpp::platform_value::Value::Float)
+                            .ok_or_else(|| WasmSdkError::invalid_argument("Invalid number value"))?

1-1: Regenerate WASM SDK docs after these public API/error changes

Identity APIs now return WasmSdkError. Per guidelines, please run the docs generator to keep browser docs in sync.

packages/js-evo-sdk/src/documents/facade.ts (2)

68-71: Type getWithProof/get return shapes for stronger DX

If the wasm returns a specific proof container, consider exporting a TS type and returning Promise<ProofMetadataResponse> (and Promise<DocumentJson> for get). Non‑blocking.


73-91: Require data for create to avoid passing undefined

asJsonString(data)! asserts non‑null, but callers can still pass null/undefined. Either validate or default to "{}" to match wasm expectations.

Example minimal guard:

-      asJsonString(data)!,
+      asJsonString(data) ?? "{}",
packages/wasm-sdk/src/queries/data_contract.rs (3)

69-75: Remove unwrap() on PlatformVersion; use SDK version handle

Avoid potential panics by using the SDK’s version handle directly.

Apply this diff:

-                    data: contract
-                        .to_json(&dash_sdk::dpp::version::PlatformVersion::get(self.version()).unwrap())
+                    data: contract
+                        .to_json(self.as_ref().version())

11-12: Import path consistency for WasmSdkError

Other modules import via crate::error::WasmSdkError; this file uses crate::WasmSdkError. Prefer one style repo‑wide.


1-1: Regenerate WASM SDK docs after query surface changes

Method-based bindings and error surface changed; please update generated docs.

packages/js-evo-sdk/src/dpns/facade.ts (2)

28-31: Type resolveName more precisely

Wasm returns a base58 string or null; type as Promise<string | null> for better ergonomics.

-  async resolveName(name: string): Promise<any> {
+  async resolveName(name: string): Promise<string | null> {

33-37: Expose a typed result for registerName

Consider exporting a RegisterDpnsNameResult TS type to match wasm (preorderDocumentId, domainDocumentId, fullDomainName). Improves autocompletion and reduces casting.

packages/wasm-sdk/src/queries/dpns.rs (2)

34-38: Remove redundant .into() on WasmSdkError.

Functions return Result<JsValue, WasmSdkError>; returning Err(WasmSdkError::...) is sufficient.

-            )
-                .into());
+            ));

Also applies to: 100-104


49-66: Limit query to 1 result.

You only consume the first result; add a small limit to avoid fetching more than needed.

Confirm the builder exposes .with_limit(1); if so, insert before fetch.

Also applies to: 67-71

packages/wasm-sdk/src/state_transitions/documents/mod.rs (1)

108-117: Avoid logging key material in production; gate console logs.

Current logs print public key bytes and hashes. Wrap these in a debug-only guard.

-// Log debug information
-web_sys::console::log_1(&JsValue::from_str(&format!( ... )));
-...
-web_sys::console::log_1(&JsValue::from_str(&format!( ... )));
+if cfg!(debug_assertions) {
+  web_sys::console::log_1(&JsValue::from_str(&format!( ... )));
+  web_sys::console::log_1(&JsValue::from_str(&format!( ... )));
+}

Also applies to: 137-144

packages/js-evo-sdk/src/voting/facade.ts (2)

6-7: Mark the SDK field as readonly.

It’s never reassigned and should be immutable.

-  private sdk: EvoSDK;
+  private readonly sdk: EvoSDK;

39-45: BigInt conversion: guard against non-integer numbers.

BigInt(numberWithFraction) throws. Truncate if a number is passed.

-const start = startTimeMs != null ? BigInt(startTimeMs) : null;
-const end = endTimeMs != null ? BigInt(endTimeMs) : null;
+const toBigInt = (v: number | bigint | null | undefined) =>
+  v == null ? null : (typeof v === 'bigint' ? v : BigInt(Math.trunc(v)));
+const start = toBigInt(startTimeMs);
+const end = toBigInt(endTimeMs);
packages/js-evo-sdk/src/sdk.ts (2)

88-89: Version check should allow 0; check for undefined instead of truthiness.

0 would be skipped today.

-    if (version) b = b.with_version(version);
+    if (version != null) b = b.with_version(version);

61-64: Error message clarity on unconnected SDK.

Consider including a hint to call await sdk.connect() in the thrown message.

packages/wasm-sdk/src/state_transitions/tokens/mod.rs (1)

90-133: Result formatting: centralize all serialization errors via one helper.

format_token_result repeats identical map_err chains. Consider a small to_js helper to keep this tight.

packages/wasm-sdk/src/queries/system.rs (2)

468-486: Avoid relying on tuple-struct internals ("credits.0").

The comment “likely a newtype” signals uncertainty. Pattern‑match the concrete type or use an accessor to extract the inner value instead of credits.0. This prevents breakage if the type changes.


152-377: Minor: standardize serialization approach.

You mix to_value and Serializer::json_compatible(). Consider using json_compatible consistently for JS interop, especially where maps/Vec are present.

packages/wasm-sdk/src/queries/document.rs (2)

756-770: JS interop: prefer typed serialization over manipulating JsValue arrays.

Instead of inspecting JsValue as js_sys::Array, deserialize to Vec<String> then map. This avoids brittle JS boundary logic.


502-510: Minor: unnecessary .into() in map_err.

map_err(|e| WasmSdkError::serialization(...)) returns the correct type; extra .into() is redundant.

Also applies to: 660-666, 861-862

packages/wasm-sdk/src/queries/token.rs (3)

397-399: Remove redundant .into() in map_err.

The closure already returns WasmSdkError.


555-604: Direct gRPC path: timeouts/retries.

Consider passing SDK settings (timeouts/retries) explicitly as done elsewhere to avoid hanging calls on poor networks.


720-729: Total supply null vs. zero semantics.

Returning null when missing and a string when present is good. Document this for JS consumers to avoid loose equality pitfalls.

packages/js-evo-sdk/src/tokens/facade.ts (2)

48-52: Unused options (limit/offset).

identityTokenInfos destructures opts but doesn’t use it. Remove the param or wire it through if supported.

-  async identityTokenInfos(identityId: string, tokenIds: string[], opts: { limit?: number; offset?: number } = {}): Promise<any> {
-    const { limit, offset } = opts;
+  async identityTokenInfos(identityId: string, tokenIds: string[]): Promise<any> {
     const w = await this.sdk.getWasmSdkConnected();
     return wasm.get_identity_token_infos(w, identityId, tokenIds);
   }

1-160: Type safety: avoid Promise.

Add lightweight TS types for responses (e.g., { tokenId: string; currentPrice: string; basePrice: string }). This will prevent silent breakage if wasm responses change.

packages/wasm-sdk/src/queries/epoch.rs (3)

178-201: Minor: handle non-32-byte identifiers without unwrap.

You check len() == 32 but still unwrap() the try_into. Replace with a guarded conversion to avoid accidental panics.


435-463: NIY endpoints: track as TODO with issue/feature flag.

Consider gating these exports behind a feature flag and open an issue to implement once SDK Query support lands.

Do you want me to open a tracking issue with acceptance criteria?


55-168: Docs sync required for public WASM API changes.

Adding/renaming exported methods requires regenerating WASM SDK docs. Please run generate_docs.py and commit the results to keep docs.html in sync.

Also applies to: 283-343, 347-433

packages/wasm-sdk/src/queries/group.rs (2)

271-277: Console warning in WASM bindings

console::warn_1 is fine for browsers, but Node users won’t see it in a typed way. Also expose a structured warning in the response or document the limitation.


331-349: Inconsistent response shapes across endpoints

Some return typed structs (GroupContractPositionInfo), others ad-hoc JSON ({ groupInfos: [...] }). Standardize to reduce JS surface area complexity.

Also applies to: 344-348, 671-673

packages/wasm-sdk/src/queries/voting.rs (1)

140-153: Index values accept only strings

You’re serializing only String values into Value::Text. If index values can be numbers/byte arrays, support additional types (e.g., detect numbers, hex/base58, or accept typed objects).

I can add a JsValue -> Value converter with type checks.

Also applies to: 429-442, 537-550, 839-852

packages/js-evo-sdk/tests/unit/facades/voting.spec.mjs (3)

12-15: Restore Sinon between tests

Future stubs/spies can leak across tests. Add a restore for hygiene.

   beforeEach(() => { wasmStubModule.__clearCalls(); });
+  afterEach(() => { sinon.restore(); });

36-42: Good: tests JSON.stringify for indexValues on masternodeVote

Consider also asserting the return value and adding a negative case (indexValues already stringified stays unchanged).

-    await sdk.voting.masternodeVote({ masternodeProTxHash: 'h', contractId: 'c', documentTypeName: 'dt', indexName: 'i', indexValues: ['x', 'y'], voteChoice: 'yes', votingKeyWif: 'w' });
+    const res = await sdk.voting.masternodeVote({ masternodeProTxHash: 'h', contractId: 'c', documentTypeName: 'dt', indexName: 'i', indexValues: ['x', 'y'], voteChoice: 'yes', votingKeyWif: 'w' });
     const args = wasm.masternodeVote.firstCall.args;
     expect(args).to.deep.equal(['h', 'c', 'dt', 'i', JSON.stringify(['x', 'y']), 'yes', 'w']);
+    expect(res).to.equal('ok');

16-34: Also assert forwarded arguments (use corrected expectations)

Good coverage — add arg-shape checks in packages/js-evo-sdk/tests/unit/facades/voting.spec.mjs, but use the facade's actual forwarding (queries pass arrays, masternodeVote stringifies, WithProof converts ms→BigInt). Minimal checklist to assert:

  • get_contested_resource_vote_state / get_contested_resource_vote_state_with_proof_info

    • indexValues forwarded as an array: expect(byName('get_contested_resource_vote_state').args[4]).to.deep.equal(['v1']);
    • with_proof: expect args include true, 's', 2, false for the proof-specific params.
  • get_contested_resource_identity_votes

    • expect identityId, limit 3, startAtVotePollIdInfo 's', orderAscending true.
  • get_contested_resource_identity_votes_with_proof_info

    • expect identityId, limit 4, offset 1, orderAscending false.
  • get_vote_polls_by_end_date

    • forwards info strings: expect start/end args include 'a' and 'b'.
  • get_vote_polls_by_end_date_with_proof_info

    • converts ms → BigInt: expect start/end args equal 10n and 20n (and limit/offset/orderAscending as passed).
  • masternodeVote

    • already stringifies array indexValues (keep existing test).

Suggested test pattern:
const calls = wasmStubModule.__getCalls(); const byName = n => calls.find(c => c.called === n); assert specific args via .args[index] (use deep.equal for arrays, 10n for BigInt). Also assert each expected call appears once.

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.

Review continued from previous batch...

@shumkov shumkov changed the title evo-sdk feat: evo sdk Sep 15, 2025
@shumkov shumkov self-assigned this Sep 15, 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

🧹 Nitpick comments (3)
.github/package-filters/rs-packages-no-workflows.yml (1)

72-75: Remove tests workflow glob from the “no-workflows” filter file.

This file is the “no-workflows” variant; including .github/workflows/tests* here breaks the convention used above (no other blocks include workflow globs in this file).

Apply:

 wasm-sdk:
-  - .github/workflows/tests*
   - packages/wasm-sdk/**
   - *sdk

Also confirm that pulling in *sdk here (bringing rs‑sdk, proof verifier, dapi client, drive) is intentional for wasm grouping.

.github/package-filters/rs-packages-direct.yml (1)

46-47: Optional: co-locate with wasm-dpp for readability

Consider moving the wasm-sdk block next to wasm-dpp to keep WASM packages grouped.

@@
 wasm-dpp:
   - packages/wasm-dpp/**
 
+wasm-sdk:
+  - packages/wasm-sdk/**
@@
-rs-sdk-ffi:
-  - packages/rs-sdk-ffi/**
-
-wasm-sdk:
-  - packages/wasm-sdk/**
+rs-sdk-ffi:
+  - packages/rs-sdk-ffi/**
.github/package-filters/js-packages-direct.yml (1)

49-53: Nit: keep entries alphabetized to reduce future diffs

Consider moving the two new blocks to their sorted positions among other scoped packages.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 39516a8 and 22e6583.

📒 Files selected for processing (5)
  • .github/package-filters/js-packages-direct.yml (1 hunks)
  • .github/package-filters/js-packages-no-workflows.yml (1 hunks)
  • .github/package-filters/rs-packages-direct.yml (1 hunks)
  • .github/package-filters/rs-packages-no-workflows.yml (2 hunks)
  • .github/package-filters/rs-packages.yml (2 hunks)
🧰 Additional context used
🧠 Learnings (16)
📓 Common learnings
Learnt from: CR
PR: dashpay/platform#0
File: packages/wasm-sdk/CLAUDE.md:0-0
Timestamp: 2025-07-23T08:31:42.268Z
Learning: Applies to packages/wasm-sdk/src/**/*.rs : The WASM SDK now fully supports where and orderBy clauses for document queries; use the specified JSON array formats and supported operators.
Learnt from: CR
PR: dashpay/platform#0
File: packages/wasm-sdk/CLAUDE.md:0-0
Timestamp: 2025-07-23T08:31:42.268Z
Learning: Applies to packages/wasm-sdk/**/index.html : The WASM SDK now fully supports where and orderBy clauses for document queries; use the specified JSON array formats and supported operators.
Learnt from: CR
PR: dashpay/platform#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-07T22:18:50.883Z
Learning: Applies to packages/wasm-sdk/** : Keep WASM SDK docs in sync (run generate_docs.py) when updating the WASM SDK
Learnt from: CR
PR: dashpay/platform#0
File: packages/wasm-sdk/CLAUDE.md:0-0
Timestamp: 2025-07-23T08:31:42.268Z
Learning: Applies to packages/wasm-sdk/src/**/*.rs : When implementing WASM SDK functionality, always refer to AI_REFERENCE.md first for accurate method signatures and examples.
Learnt from: CR
PR: dashpay/platform#0
File: packages/wasm-sdk/CLAUDE.md:0-0
Timestamp: 2025-07-23T08:31:42.268Z
Learning: Applies to packages/wasm-sdk/src/**/*.rs : For WASM builds, fix 'time not implemented on this platform' errors by using js_sys::Date::now().
Learnt from: CR
PR: dashpay/platform#0
File: packages/wasm-sdk/CLAUDE.md:0-0
Timestamp: 2025-07-23T08:31:42.268Z
Learning: Applies to packages/wasm-sdk/src/**/*.rs : Token functions are methods on WasmSdk, not standalone functions; avoid importing them as standalone.
Learnt from: CR
PR: dashpay/platform#0
File: packages/wasm-sdk/CLAUDE.md:0-0
Timestamp: 2025-07-23T08:31:42.268Z
Learning: Applies to packages/wasm-sdk/**/index.html : When adding new queries or state transitions, update the definitions in index.html.
📚 Learning: 2025-09-12T13:18:08.661Z
Learnt from: CR
PR: dashpay/platform#0
File: AGENTS.md:0-0
Timestamp: 2025-09-12T13:18:08.661Z
Learning: Applies to packages/rs-sdk-ffi/** : Keep iOS/FFI Rust SDK artifacts in packages/rs-sdk-ffi

Applied to files:

  • .github/package-filters/rs-packages-direct.yml
  • .github/package-filters/rs-packages-no-workflows.yml
  • .github/package-filters/rs-packages.yml
📚 Learning: 2025-09-07T22:18:50.883Z
Learnt from: CR
PR: dashpay/platform#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-07T22:18:50.883Z
Learning: Applies to packages/rs-sdk-ffi/**/*.{h,rs} : Follow unified SDK function prefixes: dash_core_sdk_* for Core, dash_sdk_* for Platform, dash_unified_sdk_* for unified APIs

Applied to files:

  • .github/package-filters/rs-packages-direct.yml
  • .github/package-filters/js-packages-direct.yml
  • .github/package-filters/js-packages-no-workflows.yml
  • .github/package-filters/rs-packages-no-workflows.yml
  • .github/package-filters/rs-packages.yml
📚 Learning: 2025-07-23T08:31:42.268Z
Learnt from: CR
PR: dashpay/platform#0
File: packages/wasm-sdk/CLAUDE.md:0-0
Timestamp: 2025-07-23T08:31:42.268Z
Learning: Applies to packages/wasm-sdk/src/**/*.rs : Token functions are methods on WasmSdk, not standalone functions; avoid importing them as standalone.

Applied to files:

  • .github/package-filters/rs-packages-direct.yml
  • .github/package-filters/rs-packages-no-workflows.yml
  • .github/package-filters/rs-packages.yml
📚 Learning: 2025-07-23T08:31:42.268Z
Learnt from: CR
PR: dashpay/platform#0
File: packages/wasm-sdk/CLAUDE.md:0-0
Timestamp: 2025-07-23T08:31:42.268Z
Learning: Applies to packages/wasm-sdk/src/**/*.rs : When implementing WASM SDK functionality, always refer to AI_REFERENCE.md first for accurate method signatures and examples.

Applied to files:

  • .github/package-filters/rs-packages-direct.yml
  • .github/package-filters/rs-packages-no-workflows.yml
  • .github/package-filters/rs-packages.yml
📚 Learning: 2025-09-07T22:18:50.883Z
Learnt from: CR
PR: dashpay/platform#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-07T22:18:50.883Z
Learning: Applies to packages/wasm-sdk/** : Keep WASM SDK docs in sync (run generate_docs.py) when updating the WASM SDK

Applied to files:

  • .github/package-filters/rs-packages-direct.yml
  • .github/package-filters/js-packages-direct.yml
  • .github/package-filters/js-packages-no-workflows.yml
  • .github/package-filters/rs-packages-no-workflows.yml
  • .github/package-filters/rs-packages.yml
📚 Learning: 2025-07-23T08:31:42.268Z
Learnt from: CR
PR: dashpay/platform#0
File: packages/wasm-sdk/CLAUDE.md:0-0
Timestamp: 2025-07-23T08:31:42.268Z
Learning: Applies to packages/wasm-sdk/src/**/*.rs : The WASM SDK now fully supports where and orderBy clauses for document queries; use the specified JSON array formats and supported operators.

Applied to files:

  • .github/package-filters/rs-packages-direct.yml
📚 Learning: 2025-09-12T13:18:08.661Z
Learnt from: CR
PR: dashpay/platform#0
File: AGENTS.md:0-0
Timestamp: 2025-09-12T13:18:08.661Z
Learning: Applies to packages/rs-*/**/*.rs : Keep Rust code clippy-clean (cargo clippy)

Applied to files:

  • .github/package-filters/rs-packages-direct.yml
📚 Learning: 2025-09-12T13:18:08.661Z
Learnt from: CR
PR: dashpay/platform#0
File: AGENTS.md:0-0
Timestamp: 2025-09-12T13:18:08.661Z
Learning: Applies to packages/swift-sdk/** : Keep the Swift app and SDK code in packages/swift-sdk

Applied to files:

  • .github/package-filters/rs-packages-direct.yml
  • .github/package-filters/rs-packages-no-workflows.yml
  • .github/package-filters/rs-packages.yml
📚 Learning: 2025-09-12T13:18:08.661Z
Learnt from: CR
PR: dashpay/platform#0
File: AGENTS.md:0-0
Timestamp: 2025-09-12T13:18:08.661Z
Learning: Applies to packages/rs-*/**/*.rs : Use rustfmt defaults for Rust code (format via cargo fmt --all)

Applied to files:

  • .github/package-filters/rs-packages-direct.yml
📚 Learning: 2025-07-23T08:31:42.268Z
Learnt from: CR
PR: dashpay/platform#0
File: packages/wasm-sdk/CLAUDE.md:0-0
Timestamp: 2025-07-23T08:31:42.268Z
Learning: Applies to packages/wasm-sdk/src/**/*.rs : For WASM builds, fix 'time not implemented on this platform' errors by using js_sys::Date::now().

Applied to files:

  • .github/package-filters/rs-packages-direct.yml
📚 Learning: 2025-09-12T13:18:08.661Z
Learnt from: CR
PR: dashpay/platform#0
File: AGENTS.md:0-0
Timestamp: 2025-09-12T13:18:08.661Z
Learning: Applies to packages/platform-test-suite/** : Keep all E2E tests exclusively in packages/platform-test-suite

Applied to files:

  • .github/package-filters/js-packages-direct.yml
  • .github/package-filters/js-packages-no-workflows.yml
📚 Learning: 2025-09-12T13:18:08.661Z
Learnt from: CR
PR: dashpay/platform#0
File: AGENTS.md:0-0
Timestamp: 2025-09-12T13:18:08.661Z
Learning: Applies to packages/platform-test-suite/** : Keep end-to-end tests and helpers in packages/platform-test-suite

Applied to files:

  • .github/package-filters/js-packages-direct.yml
  • .github/package-filters/js-packages-no-workflows.yml
📚 Learning: 2025-09-12T13:18:08.661Z
Learnt from: CR
PR: dashpay/platform#0
File: AGENTS.md:0-0
Timestamp: 2025-09-12T13:18:08.661Z
Learning: Applies to packages/* : Place all source packages (JS/TS packages and Rust crates) under packages/*

Applied to files:

  • .github/package-filters/js-packages-direct.yml
📚 Learning: 2025-09-03T16:37:11.605Z
Learnt from: QuantumExplorer
PR: dashpay/platform#2756
File: packages/rs-drive-abci/src/execution/platform_events/core_based_updates/update_masternode_list/update_state_masternode_list/v0/mod.rs:11-11
Timestamp: 2025-09-03T16:37:11.605Z
Learning: In packages/rs-dpp/Cargo.toml, the abci feature already includes core_rpc_client, and core_rpc_client is defined as ["dep:dashcore-rpc"]. This means rs-drive-abci can access dashcore-rpc types through dpp when using the abci feature.

Applied to files:

  • .github/package-filters/rs-packages-no-workflows.yml
📚 Learning: 2025-09-07T22:19:59.217Z
Learnt from: CR
PR: dashpay/platform#0
File: packages/swift-sdk/SwiftExampleApp/CLAUDE.md:0-0
Timestamp: 2025-09-07T22:19:59.217Z
Learning: Applies to packages/swift-sdk/SwiftExampleApp/**/*.swift : Use Platform SDK functions with the dash_sdk_* prefix

Applied to files:

  • .github/package-filters/rs-packages-no-workflows.yml
  • .github/package-filters/rs-packages.yml
⏰ 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). (8)
  • GitHub Check: Rust packages (wasm-sdk) / Tests
  • GitHub Check: Rust packages (wasm-sdk) / Linting
  • GitHub Check: Rust packages (wasm-sdk) / Unused dependencies
  • GitHub Check: Build Docker images (DAPI, dapi, dapi) / Build DAPI image
  • 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 JS packages / Build JS
  • GitHub Check: Rust crates security audit
🔇 Additional comments (7)
.github/package-filters/rs-packages-no-workflows.yml (1)

59-64: Anchor on dash-sdk looks good and consistent with existing pattern.

Declaring dash-sdk: &sdk enables reuse and matches the alias usage style already present elsewhere in this file.

.github/package-filters/rs-packages.yml (2)

72-78: Good reuse: introduced &sdk anchor on dash-sdk.

Matches the repo’s anchor/alias style and reduces duplication.


87-90: wasm-sdk block reuse reads correctly.

packages/wasm-sdk/** plus *sdk keeps wasm filters aligned with dash-sdk dependencies and includes tests globs appropriate for this “workflows” file.

Please confirm CI’s filter parser flattens sequence aliases (it already does for other *anchor items in this file); if not, we should inline the expanded list here as a fallback.

.github/package-filters/rs-packages-direct.yml (1)

46-47: LGTM — wasm-sdk filter added and verified

tests workflow (.github/workflows/tests.yml:56) consumes .github/package-filters/rs-packages-direct.yml; JS filters (.github/package-filters/js-packages.yml, js-packages-direct.yml, js-packages-no-workflows.yml) include '@dashevo/wasm-sdk' -> packages/wasm-sdk/**; PR workflow (.github/workflows/pr.yml:52) also references wasm-sdk.

.github/package-filters/js-packages-direct.yml (1)

49-53: LGTM: correct mappings for new SDK packages

The new direct filters point to the expected paths:

  • '@dashevo/wasm-sdk' -> packages/wasm-sdk/**
  • '@dashevo/evo-sdk' -> packages/js-evo-sdk/**

This aligns with the repo’s package layout.

.github/package-filters/js-packages-no-workflows.yml (2)

90-92: Approved — path and package name align for EvoSDK.
packages/js-evo-sdk exists and its package.json "name" is "@dashevo/evo-sdk".


81-89: Validate &wasm-sdk crate list — verification failed (no repo results)

Verification script returned no output, so I couldn't confirm these paths exist in the repository. Ensure the &wasm-sdk anchor exactly matches the transitive crates the WasmSdk bundle depends on and update if needed.

  • Expected entries: packages/wasm-sdk/, packages/rs-drive-proof-verifier/, packages/rs-sdk/, packages/rs-dapi-client/, packages/rs-platform-version/, packages/rs-dapi-grpc-macros/, packages/dapi-grpc/**
  • Action: remove obsolete entries or add missing crates (e.g., ffi variants) to avoid CI cache misses.

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

♻️ Duplicate comments (8)
packages/wasm-sdk/src/dpp.rs (3)

189-196: Avoid stringify + JSON.parse; serialize directly to JsValue.

Reduces allocations and preserves error context.

-        let json = value
-            .try_into_validating_json()
-            .map_err(|e| WasmSdkError::serialization(e.to_string()))?
-            .to_string();
-
-        js_sys::JSON::parse(&json)
-            .map_err(|e| WasmSdkError::serialization(format!("failed to parse JSON: {:?}", e)))
+        let json = value
+            .try_into_validating_json()
+            .map_err(|e| WasmSdkError::serialization(e.to_string()))?;
+        serde_wasm_bindgen::to_value(&json)
+            .map_err(|e| WasmSdkError::serialization(format!("failed to serialize to JsValue: {}", e)))

14-14: Remove invalid import (compile error).

web_sys::js_sys doesn’t exist; js_sys is a separate crate.

-use web_sys::js_sys;

62-66: setPublicKeys() is a no‑op; keys are never set.

You only validate and return existing length. Implement conversion and apply keys.

-    pub fn set_public_keys(&mut self, public_keys: js_sys::Array) -> Result<usize, WasmSdkError> {
-        if public_keys.length() == 0 {
-            return Err(WasmSdkError::invalid_argument(format!("Setting public keys failed. The input ('{}') is invalid. You must use array of PublicKeys", public_keys.to_string())));
-        }
-        Ok(self.inner.public_keys().len())
-    }
+    pub fn set_public_keys(&mut self, public_keys: js_sys::Array) -> Result<usize, WasmSdkError> {
+        if public_keys.length() == 0 {
+            return Err(WasmSdkError::invalid_argument(
+                "Setting public keys failed. You must pass a non-empty array of PublicKeys",
+            ));
+        }
+        let mut map = dash_sdk::platform::identity::KeyMap::default();
+        for v in public_keys.iter() {
+            let wasm = v
+                .dyn_into::<crate::identity_public_key::IdentityPublicKeyWasm>()
+                .map_err(|_| WasmSdkError::invalid_argument("Expected IdentityPublicKey"))?;
+            let key: dash_sdk::platform::identity::IdentityPublicKey = wasm.into();
+            map.insert(key.id(), key);
+        }
+        self.inner.set_public_keys(map);
+        Ok(self.inner.public_keys().len())
+    }

Add supporting imports outside the hunk:

use wasm_bindgen::JsCast;
use dash_sdk::platform::identity::{IdentityPublicKey, KeyMap};
use crate::identity_public_key::IdentityPublicKeyWasm;

Also applies to: 81-82

packages/wasm-sdk/src/queries/group.rs (4)

96-97: Validate lossy casts (u32u16/GroupContractPosition).

as can truncate. Validate and return InvalidArgument when out of range.

Add helper (outside hunks):

fn u32_to_u16_checked(v: u32) -> Result<u16, WasmSdkError> {
    u16::try_from(v).map_err(|_| WasmSdkError::invalid_argument(format!("value {} exceeds u16::MAX", v)))
}

Apply:

-    group_contract_position: group_contract_position as GroupContractPosition,
+    group_contract_position: u32_to_u16_checked(group_contract_position)? as GroupContractPosition,

-    limit: count.map(|c| c as u16),
+    limit: if let Some(c) = count { Some(u32_to_u16_checked(c)?) } else { None },

Also applies to: 133-136, 429-433, 661-663


312-324: Don’t swallow invalid pagination “start_at_*” info.

Parsing errors return None, hiding mistakes. Propagate InvalidArgument.

Example:

-                match info {
-                    Ok(json) => { /* ... */ }
-                    Err(_) => None,
-                }
+                let json = info.map_err(|e| WasmSdkError::invalid_argument(
+                    format!("Invalid startAt info: {:?}", e)))?;
+                // existing extraction...

Also applies to: 642-653, 401-421, 955-975


215-218: Fix .into() in map_err (compile errors).

These change the error type to JsValue. Drop .into().

Example patch (apply to all similar spots):

-        response.serialize(&serializer).map_err(|e| {
-            WasmSdkError::serialization(format!("Failed to serialize response: {}", e)).into()
-        })
+        response.serialize(&serializer).map_err(|e| {
+            WasmSdkError::serialization(format!("Failed to serialize response: {}", e))
+        })

Also applies to: 291-293, 457-459, 525-527, 619-621, 692-694, 809-812, 921-922, 1019-1020, 1094-1096, 1176-1177


840-872: Proof aggregation across multiple contracts is misleading.

You keep only the first (metadata, proof) and discard the rest. Either:

  • return an array of { data, metadata, proof } per contract, or
  • enforce single‑contract input and error on len > 1.

Also applies to: 898-917, 1104-1171

packages/wasm-sdk/src/queries/epoch.rs (1)

256-263: Avoid panic: handle invalid identifier bytes when creating Hash.

from_slice(...).unwrap() can panic on bad input. Map error to InvalidArgument.

-                let hash =
-                    dash_sdk::dpp::dashcore::hashes::sha256d::Hash::from_slice(&bytes).unwrap();
+                let hash = match dash_sdk::dpp::dashcore::hashes::sha256d::Hash::from_slice(&bytes) {
+                    Ok(h) => h,
+                    Err(e) => {
+                        return Err(WasmSdkError::invalid_argument(format!(
+                            "Invalid ProTxHash bytes (len={}): {}",
+                            bytes.len(),
+                            e
+                        )))
+                    }
+                };
🧹 Nitpick comments (8)
packages/wasm-sdk/src/error.rs (2)

193-233: name(): avoid extra allocation (nit).

Return &'static str and expose as String at the binding if needed. Minor/no‑op.


1-1: Please update generated docs.

After introducing WasmSdkError, regenerate wasm-sdk docs (generate_docs.py) to keep docs in sync.

Would you like a small script to run the doc generator in CI?

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

104-117: Potential precision loss: u64 ↔ f64 conversions.

Balance/revision can exceed JS’s safe integer range. Consider BigInt or string exposure.

Also applies to: 119-127, 129-137

packages/wasm-sdk/src/queries/document.rs (2)

60-63: Use serialization error kind (not generic).

Converting platform Value → JSON is a serialization concern.

-            let json_value: JsonValue = value.clone().try_into().map_err(|e| {
-                WasmSdkError::generic(format!("Failed to convert value to JSON: {:?}", e))
-            })?;
+            let json_value: JsonValue = value.clone().try_into().map_err(|e| {
+                WasmSdkError::serialization(format!("Failed to convert value to JSON: {:?}", e))
+            })?;

193-205: Fragile identifier detection (length == 44 heuristic).

Try parsing as Identifier first; fallback to text if parse fails. The fixed length check can misclassify.

-        JsonValue::String(s) => {
-            // Check if it's an identifier (base58 encoded)
-            if s.len() == 44 && s.chars().all(|c| c.is_alphanumeric()) {
-                // Try to parse as identifier
-                match Identifier::from_string(
-                    s,
-                    dash_sdk::dpp::platform_value::string_encoding::Encoding::Base58,
-                ) {
-                    Ok(id) => Ok(platform_value!(id)),
-                    Err(_) => Ok(Value::Text(s.clone())),
-                }
-            } else {
-                Ok(Value::Text(s.clone()))
-            }
-        }
+        JsonValue::String(s) => {
+            match Identifier::from_string(
+                s,
+                dash_sdk::dpp::platform_value::string_encoding::Encoding::Base58,
+            ) {
+                Ok(id) => Ok(platform_value!(id)),
+                Err(_) => Ok(Value::Text(s.clone())),
+            }
+        }
packages/wasm-sdk/src/queries/dpns.rs (1)

31-33: De‑duplicate DPNS constants (optional).

Consider a single shared const for DPNS contract/doc type to avoid drift.

Also applies to: 103-105

packages/wasm-sdk/src/queries/group.rs (2)

371-399: Status parsing OK; remove stray .into() on invalid status.

Return WasmSdkError directly.

-                ))
-                .into())
+                )))

Also applies to: 462-495, 925-952, 1046-1056


1-1: Type duplication: IdentityGroupInfo defined twice.

Reuse the top‑level struct; drop the inner duplicate to avoid drift.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 22e6583 and e9b2a2a.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (11)
  • packages/wasm-sdk/Cargo.toml (2 hunks)
  • packages/wasm-sdk/src/dpns.rs (3 hunks)
  • packages/wasm-sdk/src/dpp.rs (7 hunks)
  • packages/wasm-sdk/src/error.rs (1 hunks)
  • packages/wasm-sdk/src/lib.rs (3 hunks)
  • packages/wasm-sdk/src/logging.rs (1 hunks)
  • packages/wasm-sdk/src/queries/data_contract.rs (1 hunks)
  • packages/wasm-sdk/src/queries/document.rs (10 hunks)
  • packages/wasm-sdk/src/queries/dpns.rs (2 hunks)
  • packages/wasm-sdk/src/queries/epoch.rs (3 hunks)
  • packages/wasm-sdk/src/queries/group.rs (5 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • packages/wasm-sdk/Cargo.toml
  • packages/wasm-sdk/src/lib.rs
  • packages/wasm-sdk/src/queries/data_contract.rs
  • packages/wasm-sdk/src/dpns.rs
🧰 Additional context used
📓 Path-based instructions (3)
packages/wasm-sdk/src/**/*.rs

📄 CodeRabbit inference engine (packages/wasm-sdk/CLAUDE.md)

packages/wasm-sdk/src/**/*.rs: When implementing WASM SDK functionality, always refer to AI_REFERENCE.md first for accurate method signatures and examples.
For WASM builds, fix 'time not implemented on this platform' errors by using js_sys::Date::now().
Token functions are methods on WasmSdk, not standalone functions; avoid importing them as standalone.
The WASM SDK now fully supports where and orderBy clauses for document queries; use the specified JSON array formats and supported operators.

Files:

  • packages/wasm-sdk/src/logging.rs
  • packages/wasm-sdk/src/queries/dpns.rs
  • packages/wasm-sdk/src/error.rs
  • packages/wasm-sdk/src/dpp.rs
  • packages/wasm-sdk/src/queries/document.rs
  • packages/wasm-sdk/src/queries/group.rs
  • packages/wasm-sdk/src/queries/epoch.rs
**/*.rs

📄 CodeRabbit inference engine (CLAUDE.md)

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

Files:

  • packages/wasm-sdk/src/logging.rs
  • packages/wasm-sdk/src/queries/dpns.rs
  • packages/wasm-sdk/src/error.rs
  • packages/wasm-sdk/src/dpp.rs
  • packages/wasm-sdk/src/queries/document.rs
  • packages/wasm-sdk/src/queries/group.rs
  • packages/wasm-sdk/src/queries/epoch.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/logging.rs
  • packages/wasm-sdk/src/queries/dpns.rs
  • packages/wasm-sdk/src/error.rs
  • packages/wasm-sdk/src/dpp.rs
  • packages/wasm-sdk/src/queries/document.rs
  • packages/wasm-sdk/src/queries/group.rs
  • packages/wasm-sdk/src/queries/epoch.rs
🧠 Learnings (16)
📓 Common learnings
Learnt from: CR
PR: dashpay/platform#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-07T22:18:50.883Z
Learning: Applies to packages/wasm-sdk/** : Keep WASM SDK docs in sync (run generate_docs.py) when updating the WASM SDK
Learnt from: CR
PR: dashpay/platform#0
File: packages/wasm-sdk/CLAUDE.md:0-0
Timestamp: 2025-07-23T08:31:42.268Z
Learning: Applies to packages/wasm-sdk/src/**/*.rs : For WASM builds, fix 'time not implemented on this platform' errors by using js_sys::Date::now().
Learnt from: CR
PR: dashpay/platform#0
File: packages/wasm-sdk/CLAUDE.md:0-0
Timestamp: 2025-07-23T08:31:42.268Z
Learning: Applies to packages/wasm-sdk/src/**/*.rs : The WASM SDK now fully supports where and orderBy clauses for document queries; use the specified JSON array formats and supported operators.
Learnt from: CR
PR: dashpay/platform#0
File: packages/wasm-sdk/CLAUDE.md:0-0
Timestamp: 2025-07-23T08:31:42.268Z
Learning: Applies to packages/wasm-sdk/src/**/*.rs : Token functions are methods on WasmSdk, not standalone functions; avoid importing them as standalone.
Learnt from: CR
PR: dashpay/platform#0
File: packages/wasm-sdk/CLAUDE.md:0-0
Timestamp: 2025-07-23T08:31:42.268Z
Learning: Applies to packages/wasm-sdk/src/**/*.rs : When implementing WASM SDK functionality, always refer to AI_REFERENCE.md first for accurate method signatures and examples.
📚 Learning: 2025-07-23T08:31:42.268Z
Learnt from: CR
PR: dashpay/platform#0
File: packages/wasm-sdk/CLAUDE.md:0-0
Timestamp: 2025-07-23T08:31:42.268Z
Learning: Applies to packages/wasm-sdk/src/**/*.rs : Token functions are methods on WasmSdk, not standalone functions; avoid importing them as standalone.

Applied to files:

  • packages/wasm-sdk/src/queries/dpns.rs
  • packages/wasm-sdk/src/error.rs
  • packages/wasm-sdk/src/dpp.rs
  • packages/wasm-sdk/src/queries/document.rs
  • packages/wasm-sdk/src/queries/group.rs
  • packages/wasm-sdk/src/queries/epoch.rs
📚 Learning: 2025-07-23T08:31:42.268Z
Learnt from: CR
PR: dashpay/platform#0
File: packages/wasm-sdk/CLAUDE.md:0-0
Timestamp: 2025-07-23T08:31:42.268Z
Learning: Applies to packages/wasm-sdk/src/**/*.rs : When implementing WASM SDK functionality, always refer to AI_REFERENCE.md first for accurate method signatures and examples.

Applied to files:

  • packages/wasm-sdk/src/queries/dpns.rs
  • packages/wasm-sdk/src/error.rs
  • packages/wasm-sdk/src/dpp.rs
  • packages/wasm-sdk/src/queries/document.rs
  • packages/wasm-sdk/src/queries/group.rs
  • packages/wasm-sdk/src/queries/epoch.rs
📚 Learning: 2025-07-23T08:31:42.268Z
Learnt from: CR
PR: dashpay/platform#0
File: packages/wasm-sdk/CLAUDE.md:0-0
Timestamp: 2025-07-23T08:31:42.268Z
Learning: Applies to packages/wasm-sdk/src/**/*.rs : The WASM SDK now fully supports where and orderBy clauses for document queries; use the specified JSON array formats and supported operators.

Applied to files:

  • packages/wasm-sdk/src/queries/dpns.rs
  • packages/wasm-sdk/src/error.rs
  • packages/wasm-sdk/src/dpp.rs
  • packages/wasm-sdk/src/queries/document.rs
  • packages/wasm-sdk/src/queries/group.rs
  • packages/wasm-sdk/src/queries/epoch.rs
📚 Learning: 2025-07-23T08:31:42.268Z
Learnt from: CR
PR: dashpay/platform#0
File: packages/wasm-sdk/CLAUDE.md:0-0
Timestamp: 2025-07-23T08:31:42.268Z
Learning: Applies to packages/wasm-sdk/src/**/*.rs : For WASM builds, fix 'time not implemented on this platform' errors by using js_sys::Date::now().

Applied to files:

  • packages/wasm-sdk/src/error.rs
  • packages/wasm-sdk/src/dpp.rs
  • packages/wasm-sdk/src/queries/group.rs
  • packages/wasm-sdk/src/queries/epoch.rs
📚 Learning: 2025-07-28T20:00:08.502Z
Learnt from: QuantumExplorer
PR: dashpay/platform#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/dpp.rs
  • packages/wasm-sdk/src/queries/document.rs
📚 Learning: 2024-11-20T16:05:40.200Z
Learnt from: QuantumExplorer
PR: dashpay/platform#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-sdk/src/dpp.rs
📚 Learning: 2024-10-06T16:11:34.946Z
Learnt from: QuantumExplorer
PR: dashpay/platform#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-sdk/src/dpp.rs
📚 Learning: 2025-07-23T08:31:42.268Z
Learnt from: CR
PR: dashpay/platform#0
File: packages/wasm-sdk/CLAUDE.md:0-0
Timestamp: 2025-07-23T08:31:42.268Z
Learning: Applies to packages/wasm-sdk/**/index.html : The WASM SDK now fully supports where and orderBy clauses for document queries; use the specified JSON array formats and supported operators.

Applied to files:

  • packages/wasm-sdk/src/queries/document.rs
📚 Learning: 2024-10-29T14:40:54.727Z
Learnt from: lklimek
PR: dashpay/platform#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/queries/document.rs
  • packages/wasm-sdk/src/queries/group.rs
📚 Learning: 2025-09-03T14:41:16.196Z
Learnt from: thephez
PR: dashpay/platform#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/queries/document.rs
📚 Learning: 2025-09-03T14:42:29.958Z
Learnt from: thephez
PR: dashpay/platform#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/queries/document.rs
📚 Learning: 2024-10-29T14:16:00.141Z
Learnt from: lklimek
PR: dashpay/platform#2277
File: packages/dapi-grpc/src/mock.rs:125-145
Timestamp: 2024-10-29T14:16:00.141Z
Learning: Using `serde_json` encoding produces deterministic output required to identify requests and responses by hash, therefore `serde_json` is used as the basic serialization algorithm for mocking.

Applied to files:

  • packages/wasm-sdk/src/queries/document.rs
📚 Learning: 2024-12-03T15:00:50.385Z
Learnt from: lklimek
PR: dashpay/platform#1924
File: packages/rs-sdk/src/sdk.rs:855-870
Timestamp: 2024-12-03T15:00:50.385Z
Learning: In `packages/rs-sdk/src/sdk.rs`, remember that `rustls_pemfile::certs` returns an iterator over `Result`, not a `Result` directly. Handle it accordingly in future code reviews.

Applied to files:

  • packages/wasm-sdk/src/queries/group.rs
📚 Learning: 2024-10-29T14:44:01.184Z
Learnt from: lklimek
PR: dashpay/platform#2277
File: packages/rs-dapi-client/src/executor.rs:38-38
Timestamp: 2024-10-29T14:44:01.184Z
Learning: In `packages/rs-dapi-client/src/executor.rs`, for the structs `ExecutionError<E>` and `ExecutionResponse<R>`, only the serde derives (`Serialize`, `Deserialize`) should be conditional based on the "mocks" feature; the other derives (`Debug`, `Clone`, `Eq`, `PartialEq`) should always be present.

Applied to files:

  • packages/wasm-sdk/src/queries/group.rs
📚 Learning: 2025-08-05T13:55:39.147Z
Learnt from: thephez
PR: dashpay/platform#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-sdk/src/queries/group.rs
🧬 Code graph analysis (7)
packages/wasm-sdk/src/logging.rs (3)
packages/rs-drive-abci/src/logging/logger.rs (1)
  • layer (325-353)
packages/wasm-sdk/src/error.rs (3)
  • new (56-68)
  • invalid_argument (74-76)
  • generic (70-72)
packages/wasm-sdk/src/sdk.rs (1)
  • set_log_level (737-739)
packages/wasm-sdk/src/queries/dpns.rs (3)
packages/wasm-sdk/src/error.rs (3)
  • invalid_argument (74-76)
  • serialization (78-80)
  • not_found (82-84)
packages/rs-sdk/src/platform/documents/document_query.rs (1)
  • new_with_data_contract_id (88-102)
packages/rs-sdk/src/platform/fetch_many.rs (1)
  • fetch_many_with_metadata_and_proof (203-253)
packages/wasm-sdk/src/error.rs (2)
packages/dapi-grpc/clients/platform/v0/web/platform_pb.d.ts (1)
  • StateTransitionBroadcastError (97-117)
packages/wasm-sdk/src/dpp.rs (2)
  • new (40-50)
  • id (308-310)
packages/wasm-sdk/src/dpp.rs (1)
packages/wasm-sdk/src/error.rs (3)
  • new (56-68)
  • invalid_argument (74-76)
  • serialization (78-80)
packages/wasm-sdk/src/queries/document.rs (4)
packages/wasm-sdk/src/error.rs (5)
  • generic (70-72)
  • invalid_argument (74-76)
  • not_found (82-84)
  • new (56-68)
  • serialization (78-80)
packages/rs-sdk/src/platform/documents/document_query.rs (1)
  • new_with_data_contract_id (88-102)
packages/rs-sdk/src/platform/fetch_many.rs (1)
  • fetch_many_with_metadata_and_proof (203-253)
packages/rs-sdk/src/platform/fetch.rs (1)
  • fetch_with_metadata_and_proof (154-200)
packages/wasm-sdk/src/queries/group.rs (3)
packages/wasm-sdk/src/error.rs (3)
  • invalid_argument (74-76)
  • serialization (78-80)
  • new (56-68)
packages/rs-sdk/src/platform/fetch.rs (1)
  • fetch_with_metadata_and_proof (154-200)
packages/rs-sdk/src/platform/fetch_many.rs (1)
  • fetch_many_with_metadata_and_proof (203-253)
packages/wasm-sdk/src/queries/epoch.rs (3)
packages/wasm-sdk/src/error.rs (7)
  • serialization (78-80)
  • invalid_argument (74-76)
  • new (56-68)
  • from (88-174)
  • from (177-179)
  • from (183-190)
  • generic (70-72)
packages/wasm-sdk/src/sdk.rs (1)
  • from (44-46)
packages/wasm-sdk/src/queries/mod.rs (2)
  • from (59-68)
  • from (73-84)
⏰ 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). (9)
  • 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-sdk) / Formatting
  • 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 (DAPI, dapi, dapi) / Build DAPI image
  • GitHub Check: Build JS packages / Build JS
  • GitHub Check: Rust crates security audit
🔇 Additional comments (3)
packages/wasm-sdk/src/error.rs (1)

87-175: Error surface looks solid; mappings are comprehensive.

Enum coverage and From conversions are consistent; timeout/credits/epoch messages are helpful.

Also applies to: 182-191, 193-251

packages/wasm-sdk/src/logging.rs (1)

29-52: LGTM: reloadable filter for WASM.

Initialization + hot‑reload via OnceCell is clean. Error mapping is consistent.

packages/wasm-sdk/src/queries/epoch.rs (1)

87-169: Epoch queries: overall LGTM.

Bounds checks for finalized range and proof variants look correct; serialization path is consistent.

Also applies to: 334-352

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

♻️ Duplicate comments (1)
packages/wasm-sdk/src/error.rs (1)

41-43: Resolved: wasm_bindgen inheritance fixed to extend js_sys::Error.

The previous compile error is addressed. Good change.

🧹 Nitpick comments (3)
packages/wasm-sdk/src/error.rs (3)

2-5: Remove unused imports (clippy warning).

EpochNotFound, TotalCreditsNotFound, and Display aren’t used (you pattern‑import SdkError::* inside the match). Drop these to keep the file warning‑free.

Apply:

-use dash_sdk::Error::{EpochNotFound, TotalCreditsNotFound};
-use std::fmt::Display;
+// unused imports removed

48-51: Avoid magic sentinel for “no code”; prefer Option.

Exposing -1 as “absent” is error‑prone in JS. Consider storing Option<i32> and exposing number | undefined to consumers.

Apply:

-    /// Optional numeric code for some errors (e.g., broadcast error code).
-    code: i32,
+    /// Optional numeric code for some errors (e.g., broadcast error code).
+    code: Option<i32>,
@@
-        code: Option<i32>,
+        code: Option<i32>,
@@
-            code: code.unwrap_or(-1),
+            code,
@@
-    pub fn code(&self) -> i32 {
-        self.code
+    pub fn code(&self) -> Option<i32> {
+        self.code

Note: This is a public API tweak; only proceed if EvoSDK and callers don’t depend on -1.

Also applies to: 60-67, 241-245


183-192: Retry semantics for StateTransitionBroadcastError: double‑check.

You hardcode retriable: false. Some broadcast failures (e.g., transient mempool/full, ABORTED/UNAVAILABLE) may be safe to retry. If the Rust type exposes a code enum or hint, map it to retriable similarly to SdkError::can_retry().

Please confirm intended semantics. If some codes are retryable, add a small mapper and tests.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e9b2a2a and ca0d9c3.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (2)
  • packages/wasm-sdk/Cargo.toml (3 hunks)
  • packages/wasm-sdk/src/error.rs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/wasm-sdk/Cargo.toml
🧰 Additional context used
📓 Path-based instructions (3)
packages/wasm-sdk/src/**/*.rs

📄 CodeRabbit inference engine (packages/wasm-sdk/CLAUDE.md)

packages/wasm-sdk/src/**/*.rs: When implementing WASM SDK functionality, always refer to AI_REFERENCE.md first for accurate method signatures and examples.
For WASM builds, fix 'time not implemented on this platform' errors by using js_sys::Date::now().
Token functions are methods on WasmSdk, not standalone functions; avoid importing them as standalone.
The WASM SDK now fully supports where and orderBy clauses for document queries; use the specified JSON array formats and supported operators.

Files:

  • packages/wasm-sdk/src/error.rs
**/*.rs

📄 CodeRabbit inference engine (CLAUDE.md)

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

Files:

  • packages/wasm-sdk/src/error.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/error.rs
🧠 Learnings (5)
📓 Common learnings
Learnt from: CR
PR: dashpay/platform#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-07T22:18:50.883Z
Learning: Applies to packages/wasm-sdk/** : Keep WASM SDK docs in sync (run generate_docs.py) when updating the WASM SDK
Learnt from: CR
PR: dashpay/platform#0
File: packages/wasm-sdk/CLAUDE.md:0-0
Timestamp: 2025-07-23T08:31:42.268Z
Learning: Applies to packages/wasm-sdk/src/**/*.rs : For WASM builds, fix 'time not implemented on this platform' errors by using js_sys::Date::now().
Learnt from: CR
PR: dashpay/platform#0
File: packages/wasm-sdk/CLAUDE.md:0-0
Timestamp: 2025-07-23T08:31:42.268Z
Learning: Applies to packages/wasm-sdk/src/**/*.rs : The WASM SDK now fully supports where and orderBy clauses for document queries; use the specified JSON array formats and supported operators.
Learnt from: CR
PR: dashpay/platform#0
File: packages/wasm-sdk/CLAUDE.md:0-0
Timestamp: 2025-07-23T08:31:42.268Z
Learning: Applies to packages/wasm-sdk/src/**/*.rs : Token functions are methods on WasmSdk, not standalone functions; avoid importing them as standalone.
Learnt from: CR
PR: dashpay/platform#0
File: packages/wasm-sdk/CLAUDE.md:0-0
Timestamp: 2025-07-23T08:31:42.268Z
Learning: Applies to packages/wasm-sdk/src/**/*.rs : When implementing WASM SDK functionality, always refer to AI_REFERENCE.md first for accurate method signatures and examples.
📚 Learning: 2025-07-23T08:31:42.268Z
Learnt from: CR
PR: dashpay/platform#0
File: packages/wasm-sdk/CLAUDE.md:0-0
Timestamp: 2025-07-23T08:31:42.268Z
Learning: Applies to packages/wasm-sdk/src/**/*.rs : Token functions are methods on WasmSdk, not standalone functions; avoid importing them as standalone.

Applied to files:

  • packages/wasm-sdk/src/error.rs
📚 Learning: 2025-07-23T08:31:42.268Z
Learnt from: CR
PR: dashpay/platform#0
File: packages/wasm-sdk/CLAUDE.md:0-0
Timestamp: 2025-07-23T08:31:42.268Z
Learning: Applies to packages/wasm-sdk/src/**/*.rs : When implementing WASM SDK functionality, always refer to AI_REFERENCE.md first for accurate method signatures and examples.

Applied to files:

  • packages/wasm-sdk/src/error.rs
📚 Learning: 2025-07-23T08:31:42.268Z
Learnt from: CR
PR: dashpay/platform#0
File: packages/wasm-sdk/CLAUDE.md:0-0
Timestamp: 2025-07-23T08:31:42.268Z
Learning: Applies to packages/wasm-sdk/src/**/*.rs : For WASM builds, fix 'time not implemented on this platform' errors by using js_sys::Date::now().

Applied to files:

  • packages/wasm-sdk/src/error.rs
📚 Learning: 2025-07-23T08:31:42.268Z
Learnt from: CR
PR: dashpay/platform#0
File: packages/wasm-sdk/CLAUDE.md:0-0
Timestamp: 2025-07-23T08:31:42.268Z
Learning: Applies to packages/wasm-sdk/src/**/*.rs : The WASM SDK now fully supports where and orderBy clauses for document queries; use the specified JSON array formats and supported operators.

Applied to files:

  • packages/wasm-sdk/src/error.rs
🧬 Code graph analysis (1)
packages/wasm-sdk/src/error.rs (3)
packages/dapi-grpc/clients/platform/v0/web/platform_pb.d.ts (1)
  • StateTransitionBroadcastError (97-117)
packages/wasm-sdk/src/dpp.rs (2)
  • new (40-50)
  • id (308-310)
packages/wasm-sdk/tests/functional/voting.spec.mjs (2)
  • msg (35-35)
  • msg (51-51)
⏰ 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). (9)
  • 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-sdk) / Formatting
  • 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: Rust crates security audit
  • GitHub Check: Build Docker images (DAPI, dapi, dapi) / Build DAPI image
  • GitHub Check: Build JS packages / Build JS
🔇 Additional comments (2)
packages/wasm-sdk/src/error.rs (2)

116-123: Feature gating vs. surface stability (DapiMocksError).

WasmSdkErrorKind::DapiMocksError is always present, but the From<SdkError> arm is behind cfg(feature="mocks"). That’s fine if you want a stable public enum across builds. If not, consider gating the enum variant too.

Do you want the enum shape to be identical in prod vs. mocks builds? If yes, keep as‑is; otherwise gate the variant for consistency.

Also applies to: 200-231


1-86: Run cargo fmt / clippy and regenerate WASM SDK docs.

  • Ensure formatting and lints pass: run cargo fmt --all -- --check and cargo clippy --workspace -D warnings — fix unused imports/warnings that will fail CI.
  • Regenerate WASM SDK docs: python3 packages/wasm-sdk/generate_docs.py.

Verification attempt produced no output; re-run the checks locally or attach CI/log output for confirmation.

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

♻️ Duplicate comments (3)
packages/wasm-sdk/src/queries/group.rs (2)

96-97: Validate lossy casts (u32 → GroupContractPosition/u16).

as truncates. Use checked conversions and return InvalidArgument on overflow.

Example fix (apply to all similar sites):

-            group_contract_position: group_contract_position as GroupContractPosition,
+            group_contract_position: u16::try_from(group_contract_position)
+                .map_err(|_| WasmSdkError::invalid_argument("groupContractPosition exceeds u16::MAX"))?
+                as GroupContractPosition,

And for limits:

-            limit: count.map(|c| c as u16),
+            limit: if let Some(c) = count {
+                Some(u16::try_from(c).map_err(|_| WasmSdkError::invalid_argument("count exceeds u16::MAX"))?)
+            } else { None },

Also applies to: 135-136, 427-431, 497-500, 599-600, 655-660, 714-716, 979-983, 1055-1059


312-323: Don’t swallow malformed start_at/start_at_info JSON.

Parsing errors fall back to None, hiding user mistakes. Propagate InvalidArgument.

-                match info {
-                    Ok(json) => { /* ... */ }
-                    Err(_) => None,
-                }
+                let json = info.map_err(|e| WasmSdkError::invalid_argument(
+                    format!("Invalid startAt info: {:?}", e)
+                ))?;
+                // continue extracting fields from `json`...

Apply to all similar branches.

Also applies to: 640-651, 952-971

packages/wasm-sdk/src/queries/epoch.rs (1)

253-256: Replace unwrap() when converting bytes to Hash to avoid panics.

Bad-length inputs will panic. Validate and return InvalidArgument.

-                let hash =
-                    dash_sdk::dpp::dashcore::hashes::sha256d::Hash::from_slice(&bytes).unwrap();
+                let hash = match dash_sdk::dpp::dashcore::hashes::sha256d::Hash::from_slice(&bytes) {
+                    Ok(h) => h,
+                    Err(e) => {
+                        return Err(WasmSdkError::invalid_argument(
+                            format!("Invalid identifier bytes for ProTxHash: {}", e)
+                        ))
+                    }
+                };
🧹 Nitpick comments (7)
packages/wasm-sdk/src/error.rs (2)

39-50: Expose as a real JS Error (extend js_sys::Error).

To support instanceof Error and standard JS error semantics, export WasmSdkError as a subclass of JS Error.

Apply:

-#[wasm_bindgen]
+#[wasm_bindgen(extends = js_sys::Error)]
 #[derive(thiserror::Error, Debug, Clone)]
 #[error("{message}")]
 pub struct WasmSdkError {

Optionally document that callers can check e instanceof Error and e.name.


18-19: Gate DapiMocksError behind feature for a tighter public surface.

Enum always exposes DapiMocksError even when "mocks" is disabled. Consider cfg-gating the variant to avoid unreachable kinds at runtime.

-    DapiMocksError,
+    #[cfg(feature = "mocks")]
+    DapiMocksError,
packages/wasm-sdk/src/queries/document.rs (4)

58-63: Use SerializationError instead of Generic for JSON conversion failures.

This is a serialization path, not a generic error.

-            let json_value: JsonValue = value.clone().try_into().map_err(|e| {
-                WasmSdkError::generic(format!("Failed to convert value to JSON: {:?}", e))
-            })?;
+            let json_value: JsonValue = value.clone().try_into().map_err(|e| {
+                WasmSdkError::serialization(format!("Failed to convert value to JSON: {:?}", e))
+            })?;

193-206: Avoid heuristic Identifier detection; try-parse then fallback.

Length/alnum heuristics can misclassify. Attempt parse first; on error treat as text.

-        JsonValue::String(s) => {
-            // Check if it's an identifier (base58 encoded)
-            if s.len() == 44 && s.chars().all(|c| c.is_alphanumeric()) {
-                // Try to parse as identifier
-                match Identifier::from_string(
-                    s,
-                    dash_sdk::dpp::platform_value::string_encoding::Encoding::Base58,
-                ) {
-                    Ok(id) => Ok(platform_value!(id)),
-                    Err(_) => Ok(Value::Text(s.clone())),
-                }
-            } else {
-                Ok(Value::Text(s.clone()))
-            }
-        }
+        JsonValue::String(s) => match Identifier::from_string(
+            s,
+            dash_sdk::dpp::platform_value::string_encoding::Encoding::Base58,
+        ) {
+            Ok(id) => Ok(platform_value!(id)),
+            Err(_) => Ok(Value::Text(s.clone())),
+        }

321-340: Redundant data contract fetch; remove to reduce latency.

You fetch the contract just to build a document_type_ref that isn’t used by from_document. Drop this fetch for getDocuments (and the proof variant) or make from_document actually use it.

-        // Fetch the data contract to get the document type
-        let data_contract = dash_sdk::platform::DataContract::fetch(self.as_ref(), contract_id)
-            .await?
-            .ok_or_else(|| WasmSdkError::not_found("Data contract not found"))?;
-
-        // Get the document type
-        let document_type_ref = data_contract
-            .document_type_for_name(document_type)
-            .map_err(|e| WasmSdkError::not_found(format!("Document type not found: {}", e)))?;
-
         // Convert documents to response format
         let mut responses: Vec<DocumentResponse> = Vec::new();
         for (_, doc_opt) in documents_result {
             if let Some(doc) = doc_opt {
-                responses.push(DocumentResponse::from_document(
-                    &doc,
-                    &data_contract,
-                    document_type_ref,
-                )?);
+                responses.push(DocumentResponse::from_document(&doc)?);
             }
         }

And adjust the helper signature:

-    fn from_document(
-        doc: &Document,
-        _data_contract: &dash_sdk::platform::DataContract,
-        _document_type: dash_sdk::dpp::data_contract::document_type::DocumentTypeRef,
-    ) -> Result<Self, WasmSdkError> {
+    fn from_document(doc: &Document) -> Result<Self, WasmSdkError> {

Update the three call sites similarly (Lines 335-340, 451-456, 516-517).


614-631: DPNS: hardcoded testnet contract ID.

Consider passing DPNS contract ID via config/env or WasmSdk to support multiple networks.

packages/wasm-sdk/src/queries/epoch.rs (1)

109-114: Validate count downcast when computing end_epoch.

(limit - 1) as u16 can truncate. Convert safely.

-        let end_epoch = if is_ascending {
-            start.saturating_add((limit - 1) as u16)
-        } else {
-            start.saturating_sub((limit - 1) as u16)
-        };
+        let span = u16::try_from(limit.saturating_sub(1))
+            .map_err(|_| WasmSdkError::invalid_argument("count exceeds u16::MAX"))?;
+        let end_epoch = if is_ascending {
+            start.saturating_add(span)
+        } else {
+            start.saturating_sub(span)
+        };

Apply same fix in getFinalizedEpochInfosWithProofInfo.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ca0d9c3 and 099b4b7.

📒 Files selected for processing (8)
  • packages/wasm-sdk/src/dpns.rs (3 hunks)
  • packages/wasm-sdk/src/error.rs (1 hunks)
  • packages/wasm-sdk/src/lib.rs (3 hunks)
  • packages/wasm-sdk/src/queries/data_contract.rs (1 hunks)
  • packages/wasm-sdk/src/queries/document.rs (10 hunks)
  • packages/wasm-sdk/src/queries/dpns.rs (2 hunks)
  • packages/wasm-sdk/src/queries/epoch.rs (3 hunks)
  • packages/wasm-sdk/src/queries/group.rs (5 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/wasm-sdk/src/queries/dpns.rs
  • packages/wasm-sdk/src/dpns.rs
🧰 Additional context used
📓 Path-based instructions (3)
packages/wasm-sdk/src/**/*.rs

📄 CodeRabbit inference engine (packages/wasm-sdk/CLAUDE.md)

packages/wasm-sdk/src/**/*.rs: When implementing WASM SDK functionality, always refer to AI_REFERENCE.md first for accurate method signatures and examples.
For WASM builds, fix 'time not implemented on this platform' errors by using js_sys::Date::now().
Token functions are methods on WasmSdk, not standalone functions; avoid importing them as standalone.
The WASM SDK now fully supports where and orderBy clauses for document queries; use the specified JSON array formats and supported operators.

Files:

  • packages/wasm-sdk/src/error.rs
  • packages/wasm-sdk/src/queries/document.rs
  • packages/wasm-sdk/src/queries/group.rs
  • packages/wasm-sdk/src/lib.rs
  • packages/wasm-sdk/src/queries/epoch.rs
  • packages/wasm-sdk/src/queries/data_contract.rs
**/*.rs

📄 CodeRabbit inference engine (CLAUDE.md)

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

Files:

  • packages/wasm-sdk/src/error.rs
  • packages/wasm-sdk/src/queries/document.rs
  • packages/wasm-sdk/src/queries/group.rs
  • packages/wasm-sdk/src/lib.rs
  • packages/wasm-sdk/src/queries/epoch.rs
  • packages/wasm-sdk/src/queries/data_contract.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/error.rs
  • packages/wasm-sdk/src/queries/document.rs
  • packages/wasm-sdk/src/queries/group.rs
  • packages/wasm-sdk/src/lib.rs
  • packages/wasm-sdk/src/queries/epoch.rs
  • packages/wasm-sdk/src/queries/data_contract.rs
🧠 Learnings (14)
📓 Common learnings
Learnt from: CR
PR: dashpay/platform#0
File: packages/wasm-sdk/CLAUDE.md:0-0
Timestamp: 2025-07-23T08:31:42.268Z
Learning: Applies to packages/wasm-sdk/src/**/*.rs : Token functions are methods on WasmSdk, not standalone functions; avoid importing them as standalone.
Learnt from: CR
PR: dashpay/platform#0
File: packages/wasm-sdk/CLAUDE.md:0-0
Timestamp: 2025-07-23T08:31:42.268Z
Learning: Applies to packages/wasm-sdk/src/**/*.rs : When implementing WASM SDK functionality, always refer to AI_REFERENCE.md first for accurate method signatures and examples.
Learnt from: CR
PR: dashpay/platform#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-07T22:18:50.883Z
Learning: Applies to packages/wasm-sdk/** : Keep WASM SDK docs in sync (run generate_docs.py) when updating the WASM SDK
Learnt from: CR
PR: dashpay/platform#0
File: packages/wasm-sdk/CLAUDE.md:0-0
Timestamp: 2025-07-23T08:31:42.268Z
Learning: Applies to packages/wasm-sdk/src/**/*.rs : For WASM builds, fix 'time not implemented on this platform' errors by using js_sys::Date::now().
Learnt from: CR
PR: dashpay/platform#0
File: packages/wasm-sdk/CLAUDE.md:0-0
Timestamp: 2025-07-23T08:31:42.268Z
Learning: Applies to packages/wasm-sdk/src/**/*.rs : The WASM SDK now fully supports where and orderBy clauses for document queries; use the specified JSON array formats and supported operators.
Learnt from: CR
PR: dashpay/platform#0
File: packages/wasm-sdk/CLAUDE.md:0-0
Timestamp: 2025-07-23T08:31:42.268Z
Learning: Applies to packages/wasm-sdk/**/index.html : When adding new queries or state transitions, update the definitions in index.html.
📚 Learning: 2025-07-23T08:31:42.268Z
Learnt from: CR
PR: dashpay/platform#0
File: packages/wasm-sdk/CLAUDE.md:0-0
Timestamp: 2025-07-23T08:31:42.268Z
Learning: Applies to packages/wasm-sdk/src/**/*.rs : Token functions are methods on WasmSdk, not standalone functions; avoid importing them as standalone.

Applied to files:

  • packages/wasm-sdk/src/error.rs
  • packages/wasm-sdk/src/queries/document.rs
  • packages/wasm-sdk/src/queries/group.rs
  • packages/wasm-sdk/src/lib.rs
  • packages/wasm-sdk/src/queries/epoch.rs
  • packages/wasm-sdk/src/queries/data_contract.rs
📚 Learning: 2025-07-23T08:31:42.268Z
Learnt from: CR
PR: dashpay/platform#0
File: packages/wasm-sdk/CLAUDE.md:0-0
Timestamp: 2025-07-23T08:31:42.268Z
Learning: Applies to packages/wasm-sdk/src/**/*.rs : When implementing WASM SDK functionality, always refer to AI_REFERENCE.md first for accurate method signatures and examples.

Applied to files:

  • packages/wasm-sdk/src/error.rs
  • packages/wasm-sdk/src/queries/document.rs
  • packages/wasm-sdk/src/queries/group.rs
  • packages/wasm-sdk/src/lib.rs
  • packages/wasm-sdk/src/queries/epoch.rs
  • packages/wasm-sdk/src/queries/data_contract.rs
📚 Learning: 2025-07-23T08:31:42.268Z
Learnt from: CR
PR: dashpay/platform#0
File: packages/wasm-sdk/CLAUDE.md:0-0
Timestamp: 2025-07-23T08:31:42.268Z
Learning: Applies to packages/wasm-sdk/src/**/*.rs : For WASM builds, fix 'time not implemented on this platform' errors by using js_sys::Date::now().

Applied to files:

  • packages/wasm-sdk/src/error.rs
  • packages/wasm-sdk/src/queries/document.rs
  • packages/wasm-sdk/src/queries/group.rs
  • packages/wasm-sdk/src/lib.rs
  • packages/wasm-sdk/src/queries/epoch.rs
  • packages/wasm-sdk/src/queries/data_contract.rs
📚 Learning: 2025-07-23T08:31:42.268Z
Learnt from: CR
PR: dashpay/platform#0
File: packages/wasm-sdk/CLAUDE.md:0-0
Timestamp: 2025-07-23T08:31:42.268Z
Learning: Applies to packages/wasm-sdk/src/**/*.rs : The WASM SDK now fully supports where and orderBy clauses for document queries; use the specified JSON array formats and supported operators.

Applied to files:

  • packages/wasm-sdk/src/error.rs
  • packages/wasm-sdk/src/queries/document.rs
  • packages/wasm-sdk/src/queries/group.rs
  • packages/wasm-sdk/src/lib.rs
  • packages/wasm-sdk/src/queries/epoch.rs
  • packages/wasm-sdk/src/queries/data_contract.rs
📚 Learning: 2025-07-23T08:31:42.268Z
Learnt from: CR
PR: dashpay/platform#0
File: packages/wasm-sdk/CLAUDE.md:0-0
Timestamp: 2025-07-23T08:31:42.268Z
Learning: Applies to packages/wasm-sdk/**/index.html : The WASM SDK now fully supports where and orderBy clauses for document queries; use the specified JSON array formats and supported operators.

Applied to files:

  • packages/wasm-sdk/src/queries/document.rs
📚 Learning: 2024-10-29T14:40:54.727Z
Learnt from: lklimek
PR: dashpay/platform#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/queries/document.rs
  • packages/wasm-sdk/src/queries/group.rs
📚 Learning: 2025-07-28T20:00:08.502Z
Learnt from: QuantumExplorer
PR: dashpay/platform#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/queries/document.rs
📚 Learning: 2025-09-03T14:42:29.958Z
Learnt from: thephez
PR: dashpay/platform#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/queries/document.rs
📚 Learning: 2025-09-03T14:41:16.196Z
Learnt from: thephez
PR: dashpay/platform#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/queries/document.rs
📚 Learning: 2024-10-29T14:44:01.184Z
Learnt from: lklimek
PR: dashpay/platform#2277
File: packages/rs-dapi-client/src/executor.rs:38-38
Timestamp: 2024-10-29T14:44:01.184Z
Learning: In `packages/rs-dapi-client/src/executor.rs`, for the structs `ExecutionError<E>` and `ExecutionResponse<R>`, only the serde derives (`Serialize`, `Deserialize`) should be conditional based on the "mocks" feature; the other derives (`Debug`, `Clone`, `Eq`, `PartialEq`) should always be present.

Applied to files:

  • packages/wasm-sdk/src/queries/document.rs
  • packages/wasm-sdk/src/queries/group.rs
📚 Learning: 2024-10-29T14:16:00.141Z
Learnt from: lklimek
PR: dashpay/platform#2277
File: packages/dapi-grpc/src/mock.rs:125-145
Timestamp: 2024-10-29T14:16:00.141Z
Learning: Using `serde_json` encoding produces deterministic output required to identify requests and responses by hash, therefore `serde_json` is used as the basic serialization algorithm for mocking.

Applied to files:

  • packages/wasm-sdk/src/queries/document.rs
📚 Learning: 2025-08-05T13:55:39.147Z
Learnt from: thephez
PR: dashpay/platform#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-sdk/src/queries/document.rs
  • packages/wasm-sdk/src/queries/group.rs
📚 Learning: 2024-12-03T15:00:50.385Z
Learnt from: lklimek
PR: dashpay/platform#1924
File: packages/rs-sdk/src/sdk.rs:855-870
Timestamp: 2024-12-03T15:00:50.385Z
Learning: In `packages/rs-sdk/src/sdk.rs`, remember that `rustls_pemfile::certs` returns an iterator over `Result`, not a `Result` directly. Handle it accordingly in future code reviews.

Applied to files:

  • packages/wasm-sdk/src/queries/group.rs
🧬 Code graph analysis (5)
packages/wasm-sdk/src/error.rs (3)
packages/dapi-grpc/clients/platform/v0/web/platform_pb.d.ts (2)
  • StateTransitionBroadcastError (97-117)
  • Protocol (5222-5241)
packages/wasm-sdk/src/dpp.rs (2)
  • new (40-50)
  • id (308-310)
packages/rs-dpp/src/data_contract/data_contract_facade.rs (1)
  • new (31-35)
packages/wasm-sdk/src/queries/document.rs (3)
packages/wasm-sdk/src/error.rs (5)
  • generic (69-71)
  • invalid_argument (73-75)
  • not_found (81-83)
  • new (55-67)
  • serialization (77-79)
packages/wasm-sdk/src/wallet/key_derivation.rs (1)
  • from_string (99-125)
packages/wasm-sdk/src/dpp.rs (1)
  • new (40-50)
packages/wasm-sdk/src/queries/group.rs (3)
packages/wasm-sdk/src/error.rs (3)
  • invalid_argument (73-75)
  • serialization (77-79)
  • new (55-67)
packages/rs-sdk/src/platform/fetch.rs (1)
  • fetch_with_metadata_and_proof (154-200)
packages/rs-sdk/src/platform/fetch_many.rs (1)
  • fetch_many_with_metadata_and_proof (203-253)
packages/wasm-sdk/src/queries/epoch.rs (5)
packages/rs-sdk/src/platform/query.rs (17)
  • query (98-98)
  • query (106-111)
  • query (115-125)
  • query (129-139)
  • query (143-160)
  • query (165-183)
  • query (187-193)
  • query (244-259)
  • query (263-270)
  • query (274-280)
  • query (284-296)
  • query (301-303)
  • query (308-310)
  • query (315-322)
  • query (326-332)
  • query (336-360)
  • new (539-544)
packages/wasm-sdk/src/error.rs (7)
  • serialization (77-79)
  • invalid_argument (73-75)
  • new (55-67)
  • from (87-173)
  • from (176-178)
  • from (182-189)
  • generic (69-71)
packages/wasm-sdk/src/sdk.rs (1)
  • from (38-40)
packages/wasm-sdk/src/queries/mod.rs (2)
  • from (50-59)
  • from (64-75)
packages/rs-sdk/src/platform/fetch_many.rs (1)
  • fetch_many_with_metadata_and_proof (203-253)
packages/wasm-sdk/src/queries/data_contract.rs (5)
packages/wasm-sdk/src/dpp.rs (2)
  • id (308-310)
  • new (40-50)
packages/wasm-sdk/src/error.rs (4)
  • invalid_argument (73-75)
  • not_found (81-83)
  • serialization (77-79)
  • new (55-67)
packages/rs-sdk/src/platform/fetch.rs (2)
  • fetch_by_identifier (242-247)
  • fetch_with_metadata_and_proof (154-200)
packages/wasm-sdk/src/sdk.rs (1)
  • version (45-47)
packages/rs-sdk/src/platform/fetch_many.rs (1)
  • fetch_many_with_metadata_and_proof (203-253)
⏰ 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). (1)
  • GitHub Check: Build JS packages / Build JS
🔇 Additional comments (6)
packages/wasm-sdk/src/queries/data_contract.rs (2)

111-126: LGTM: history JSON conversion and error mapping are consistent.


156-175: LGTM: bulk fetch maps Option contracts to JSON cleanly.

packages/wasm-sdk/src/queries/epoch.rs (1)

171-211: LGTM: ID parsing and serialization path are solid.

packages/wasm-sdk/src/queries/group.rs (2)

116-221: LGTM: getGroupMembers pagination and output format.


370-458: LGTM: getGroupActions validation and TODO marker.

Please confirm tests cover both ACTIVE and CLOSED statuses with startAt present/absent.

packages/wasm-sdk/src/lib.rs (1)

7-8: LGTM: logging module exposure.

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: 7

♻️ Duplicate comments (3)
packages/js-evo-sdk/tests/functional/identities.spec.mjs (1)

10-12: Enable proofs for with-proof calls.

fetchWithProof() typically requires builder.withProofs(true). Instantiate SDK with { proofs: true }.

-    sdk = EvoSDK.testnetTrusted();
+    sdk = EvoSDK.testnetTrusted({ proofs: true });
packages/js-evo-sdk/tests/functional/contracts.spec.mjs (1)

1-1: Add missing Chai import.

expect is used but not imported.

+import { expect } from 'chai';
 import { EvoSDK } from '../../dist/sdk.js';
 import { TEST_IDS } from '../fixtures/testnet.mjs';
packages/wasm-sdk/package.json (1)

22-25: sideEffects + engines: resolved.

These were requested earlier and are now present. Thanks.

🧹 Nitpick comments (10)
packages/js-evo-sdk/tests/functional/identities.spec.mjs (1)

35-37: Remove redundant inner skip.

Test is already it.skip(...); inner this.skip() is dead code.

-    if (!TEST_SECRETS.identityId || !TEST_SECRETS.privateKeyWif) {
-      this.skip();
-    }
+    // secrets gate handled by .skip at the test definition
packages/js-evo-sdk/tests/functional/contracts.spec.mjs (1)

10-12: Enable proofs for with-proof call in this suite.

fetchWithProof() likely requires proofs mode.

-    sdk = EvoSDK.testnetTrusted();
+    sdk = EvoSDK.testnetTrusted({ proofs: true });
packages/wasm-sdk/package.json (4)

4-6: Consider dropping redundant "main".

With Node >=18.18 and a full "exports" map, "main" is unused and can drift.

Apply this diff:

-  "main": "./dist/sdk.js",

65-66: Align webpack-cli with webpack 5.

webpack 5 pairs best with webpack-cli 5. Recommend upgrading.

Apply this diff:

-    "webpack-cli": "^4.9.1"
+    "webpack-cli": "^5.0.0"

2-6: Add standard package metadata (license/repository/bugs/homepage).

Important for npm consumers and compliance. Populate with project‑correct values.


2-4: Breaking-surface check: ESM‑only + scoped rename.

Moving to ESM‑only and the @dashevo scope is a breaking change for CJS/old imports. Ensure CHANGELOG/README and release notes call this out with migration examples.

Also applies to: 7-17

packages/js-evo-sdk/src/.eslintrc.cjs (1)

19-22: Optional: enforce consistent type-only imports.

Helps tree‑shaking and clarity in TS wrappers.

Apply this diff:

   rules: {
     'import/extensions': 'off',
     '@typescript-eslint/no-explicit-any': 'off',
+    '@typescript-eslint/consistent-type-imports': ['warn', { prefer: 'type-imports' }],
   },
packages/js-evo-sdk/tests/.eslintrc.yml (3)

4-7: Enable browser env for Karma/browser tests.

Prevents no-undef on window/document in browser runs.

Apply this diff:

 env:
   es2020: true
   node: true
   mocha: true
+  browser: true

1-7: Add parserOptions for modern syntax/modules.

Keeps parsing consistent with ESM test code.

Apply this diff:

 extends:
   - airbnb-base
   - plugin:jsdoc/recommended
+parserOptions:
+  ecmaVersion: latest
+  sourceType: module
 env:
   es2020: true
   node: true
   mocha: true

8-25: Guard against accidental .only/.skip in tests.

Add the mocha ESLint plugin and per-test-file overrides to error on exclusive tests and warn on skipped tests — scan found skipped tests in packages/js-evo-sdk/tests/functional/identities.spec.mjs and packages/js-evo-sdk/tests/functional/contracts.spec.mjs.

 rules:
   eol-last:
     - error
     - always
   import/extensions: off
   class-methods-use-this: off
   import/no-extraneous-dependencies: off
   curly:
     - error
     - all
   no-restricted-syntax:
     - error
     - selector: "LabeledStatement"
       message: Labels are a form of GOTO; using them makes code confusing and hard to maintain and understand.
     - selector: "WithStatement"
       message: "`with` is disallowed in strict mode because it makes code impossible to predict and optimize."
+plugins:
+  - mocha
+overrides:
+  - files: ["**/*.{test,spec}.?(c|m)js", "**/*.{test,spec}.ts"]
+    rules:
+      mocha/no-exclusive-tests: error
+      mocha/no-skipped-tests: warn
 globals:
   expect: true
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 099b4b7 and 6f58d3b.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (29)
  • .pnp.cjs (19 hunks)
  • packages/js-evo-sdk/package.json (1 hunks)
  • packages/js-evo-sdk/src/.eslintrc.cjs (1 hunks)
  • packages/js-evo-sdk/tests/.eslintrc.yml (1 hunks)
  • packages/js-evo-sdk/tests/bootstrap.cjs (1 hunks)
  • packages/js-evo-sdk/tests/fixtures/testnet.mjs (1 hunks)
  • packages/js-evo-sdk/tests/functional/contracts.spec.mjs (1 hunks)
  • packages/js-evo-sdk/tests/functional/documents.spec.mjs (1 hunks)
  • packages/js-evo-sdk/tests/functional/dpns.spec.mjs (1 hunks)
  • packages/js-evo-sdk/tests/functional/epoch.spec.mjs (1 hunks)
  • packages/js-evo-sdk/tests/functional/group.spec.mjs (1 hunks)
  • packages/js-evo-sdk/tests/functional/identities.spec.mjs (1 hunks)
  • packages/js-evo-sdk/tests/functional/protocol.spec.mjs (1 hunks)
  • packages/js-evo-sdk/tests/functional/system.spec.mjs (1 hunks)
  • packages/js-evo-sdk/tests/functional/tokens.spec.mjs (1 hunks)
  • packages/js-evo-sdk/tests/functional/voting.spec.mjs (1 hunks)
  • packages/js-evo-sdk/tests/karma/options.cjs (1 hunks)
  • packages/js-evo-sdk/tests/unit/facades/contracts.spec.mjs (1 hunks)
  • packages/js-evo-sdk/tests/unit/facades/documents.spec.mjs (1 hunks)
  • packages/js-evo-sdk/tests/unit/facades/dpns.spec.mjs (1 hunks)
  • packages/js-evo-sdk/tests/unit/facades/epoch.spec.mjs (1 hunks)
  • packages/js-evo-sdk/tests/unit/facades/group.spec.mjs (1 hunks)
  • packages/js-evo-sdk/tests/unit/facades/identities.spec.mjs (1 hunks)
  • packages/js-evo-sdk/tests/unit/facades/protocol.spec.mjs (1 hunks)
  • packages/js-evo-sdk/tests/unit/facades/system.spec.mjs (1 hunks)
  • packages/js-evo-sdk/tests/unit/facades/tokens.spec.mjs (1 hunks)
  • packages/js-evo-sdk/tests/unit/facades/voting.spec.mjs (1 hunks)
  • packages/js-evo-sdk/tests/unit/sdk.spec.mjs (1 hunks)
  • packages/wasm-sdk/package.json (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (22)
  • packages/js-evo-sdk/tests/functional/group.spec.mjs
  • packages/js-evo-sdk/tests/functional/protocol.spec.mjs
  • packages/js-evo-sdk/tests/bootstrap.cjs
  • packages/js-evo-sdk/tests/fixtures/testnet.mjs
  • packages/js-evo-sdk/tests/functional/tokens.spec.mjs
  • packages/js-evo-sdk/tests/unit/facades/epoch.spec.mjs
  • packages/js-evo-sdk/tests/unit/facades/contracts.spec.mjs
  • packages/js-evo-sdk/package.json
  • packages/js-evo-sdk/tests/unit/facades/identities.spec.mjs
  • packages/js-evo-sdk/tests/unit/facades/voting.spec.mjs
  • packages/js-evo-sdk/tests/unit/facades/system.spec.mjs
  • packages/js-evo-sdk/tests/unit/facades/group.spec.mjs
  • packages/js-evo-sdk/tests/functional/dpns.spec.mjs
  • packages/js-evo-sdk/tests/karma/options.cjs
  • packages/js-evo-sdk/tests/unit/facades/protocol.spec.mjs
  • packages/js-evo-sdk/tests/functional/documents.spec.mjs
  • .pnp.cjs
  • packages/js-evo-sdk/tests/unit/facades/dpns.spec.mjs
  • packages/js-evo-sdk/tests/unit/facades/tokens.spec.mjs
  • packages/js-evo-sdk/tests/unit/sdk.spec.mjs
  • packages/js-evo-sdk/tests/functional/voting.spec.mjs
  • packages/js-evo-sdk/tests/unit/facades/documents.spec.mjs
🧰 Additional context used
📓 Path-based instructions (2)
packages/**/tests/**

📄 CodeRabbit inference engine (AGENTS.md)

Place unit and integration tests alongside each package in packages//tests

Files:

  • packages/js-evo-sdk/tests/functional/identities.spec.mjs
  • packages/js-evo-sdk/tests/functional/contracts.spec.mjs
  • packages/js-evo-sdk/tests/functional/epoch.spec.mjs
  • packages/js-evo-sdk/tests/functional/system.spec.mjs
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/package.json
🧠 Learnings (12)
📓 Common learnings
Learnt from: CR
PR: dashpay/platform#0
File: packages/wasm-sdk/CLAUDE.md:0-0
Timestamp: 2025-07-23T08:31:42.268Z
Learning: Applies to packages/wasm-sdk/src/**/*.rs : Token functions are methods on WasmSdk, not standalone functions; avoid importing them as standalone.
Learnt from: CR
PR: dashpay/platform#0
File: packages/wasm-sdk/CLAUDE.md:0-0
Timestamp: 2025-07-23T08:31:42.268Z
Learning: Applies to packages/wasm-sdk/src/**/*.rs : When implementing WASM SDK functionality, always refer to AI_REFERENCE.md first for accurate method signatures and examples.
Learnt from: CR
PR: dashpay/platform#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-07T22:18:50.883Z
Learning: Applies to packages/wasm-sdk/** : Keep WASM SDK docs in sync (run generate_docs.py) when updating the WASM SDK
Learnt from: CR
PR: dashpay/platform#0
File: packages/wasm-sdk/CLAUDE.md:0-0
Timestamp: 2025-07-23T08:31:42.268Z
Learning: Applies to packages/wasm-sdk/src/**/*.rs : For WASM builds, fix 'time not implemented on this platform' errors by using js_sys::Date::now().
Learnt from: CR
PR: dashpay/platform#0
File: packages/wasm-sdk/CLAUDE.md:0-0
Timestamp: 2025-07-23T08:31:42.268Z
Learning: Applies to packages/wasm-sdk/src/**/*.rs : The WASM SDK now fully supports where and orderBy clauses for document queries; use the specified JSON array formats and supported operators.
📚 Learning: 2025-09-12T13:18:08.661Z
Learnt from: CR
PR: dashpay/platform#0
File: AGENTS.md:0-0
Timestamp: 2025-09-12T13:18:08.661Z
Learning: Applies to packages/**/**/*.{js,ts,jsx,tsx} : Adhere to ESLint with Airbnb/TypeScript configs for JS/TS code

Applied to files:

  • packages/js-evo-sdk/src/.eslintrc.cjs
  • packages/js-evo-sdk/tests/.eslintrc.yml
📚 Learning: 2025-08-05T13:55:39.147Z
Learnt from: thephez
PR: dashpay/platform#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/js-evo-sdk/tests/functional/identities.spec.mjs
📚 Learning: 2024-10-30T11:19:59.163Z
Learnt from: lklimek
PR: dashpay/platform#2277
File: packages/rs-sdk/tests/fetch/config.rs:233-233
Timestamp: 2024-10-30T11:19:59.163Z
Learning: In the Rust SDK's `rs-sdk/tests` integration tests (e.g., in `packages/rs-sdk/tests/fetch/config.rs`), we cannot create objects during tests because there is no support for object creation in this context. Therefore, hardcoded values for test identities must be used.

Applied to files:

  • packages/js-evo-sdk/tests/functional/identities.spec.mjs
📚 Learning: 2024-10-18T15:37:36.387Z
Learnt from: shumkov
PR: dashpay/platform#2249
File: packages/dashmate/test/unit/status/scopes/platform.spec.js:77-78
Timestamp: 2024-10-18T15:37:36.387Z
Learning: In `packages/dashmate/test/unit/status/scopes/platform.spec.js`, prefer to keep mocks explicitly in tests to increase readability, rather than refactoring them into shared `beforeEach` blocks or helper functions.

Applied to files:

  • packages/js-evo-sdk/tests/functional/contracts.spec.mjs
📚 Learning: 2024-10-18T15:37:21.329Z
Learnt from: shumkov
PR: dashpay/platform#2249
File: packages/dashmate/test/unit/status/scopes/platform.spec.js:466-467
Timestamp: 2024-10-18T15:37:21.329Z
Learning: In test files for the dashmate project, such as `packages/dashmate/test/unit/status/scopes/platform.spec.js`, prefer to keep mocks explicitly in tests rather than consolidating them, to increase readability.

Applied to files:

  • packages/js-evo-sdk/tests/functional/contracts.spec.mjs
📚 Learning: 2024-11-06T07:27:01.722Z
Learnt from: shumkov
PR: dashpay/platform#2314
File: packages/wallet-contract/test/bootstrap.js:14-16
Timestamp: 2024-11-06T07:27:01.722Z
Learning: In `packages/wallet-contract/test/bootstrap.js`, for Mocha tests in Node.js, async functions like `loadWasmDpp` can be assigned directly to `beforeAll` without wrapping them in another async function.

Applied to files:

  • packages/js-evo-sdk/tests/functional/contracts.spec.mjs
📚 Learning: 2025-09-03T14:42:29.958Z
Learnt from: thephez
PR: dashpay/platform#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/package.json
📚 Learning: 2025-07-23T08:31:42.268Z
Learnt from: CR
PR: dashpay/platform#0
File: packages/wasm-sdk/CLAUDE.md:0-0
Timestamp: 2025-07-23T08:31:42.268Z
Learning: Applies to packages/wasm-sdk/**/index.html : The WASM SDK now fully supports where and orderBy clauses for document queries; use the specified JSON array formats and supported operators.

Applied to files:

  • packages/wasm-sdk/package.json
📚 Learning: 2025-09-03T14:41:16.196Z
Learnt from: thephez
PR: dashpay/platform#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/package.json
📚 Learning: 2025-09-07T22:18:50.883Z
Learnt from: CR
PR: dashpay/platform#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-07T22:18:50.883Z
Learning: Applies to packages/wasm-sdk/** : Keep WASM SDK docs in sync (run generate_docs.py) when updating the WASM SDK

Applied to files:

  • packages/wasm-sdk/package.json
📚 Learning: 2025-07-23T08:31:42.268Z
Learnt from: CR
PR: dashpay/platform#0
File: packages/wasm-sdk/CLAUDE.md:0-0
Timestamp: 2025-07-23T08:31:42.268Z
Learning: Applies to packages/wasm-sdk/**/index.html : When adding new queries or state transitions, update the definitions in index.html.

Applied to files:

  • packages/wasm-sdk/package.json
🧬 Code graph analysis (5)
packages/js-evo-sdk/src/.eslintrc.cjs (1)
packages/wasm-drive-verify/scripts/generate-size-matrix.js (1)
  • __dirname (8-8)
packages/js-evo-sdk/tests/functional/identities.spec.mjs (2)
packages/js-evo-sdk/src/sdk.ts (1)
  • EvoSDK (34-121)
packages/js-evo-sdk/tests/fixtures/testnet.mjs (4)
  • TEST_IDS (5-19)
  • TEST_IDS (5-19)
  • TEST_SECRETS (22-26)
  • TEST_SECRETS (22-26)
packages/js-evo-sdk/tests/functional/contracts.spec.mjs (2)
packages/js-evo-sdk/src/sdk.ts (1)
  • EvoSDK (34-121)
packages/js-evo-sdk/tests/fixtures/testnet.mjs (2)
  • TEST_IDS (5-19)
  • TEST_IDS (5-19)
packages/js-evo-sdk/tests/functional/epoch.spec.mjs (2)
packages/js-evo-sdk/src/sdk.ts (1)
  • EvoSDK (34-121)
packages/js-evo-sdk/tests/fixtures/testnet.mjs (2)
  • TEST_IDS (5-19)
  • TEST_IDS (5-19)
packages/js-evo-sdk/tests/functional/system.spec.mjs (2)
packages/js-evo-sdk/src/sdk.ts (1)
  • EvoSDK (34-121)
packages/js-evo-sdk/tests/fixtures/testnet.mjs (2)
  • TEST_IDS (5-19)
  • TEST_IDS (5-19)
⏰ 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). (7)
  • GitHub Check: Rust packages (wasm-sdk) / Formatting
  • 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 (DAPI, dapi, dapi) / Build DAPI image
  • GitHub Check: Build Docker images (Dashmate helper, dashmate-helper, dashmate-helper) / Build Dashmate helper image
  • GitHub Check: Rust crates security audit
🔇 Additional comments (2)
packages/wasm-sdk/package.json (1)

4-17: ESM packaging and subpath exports look solid.

"type": "module" with an exports map for "." and "./raw" is coherent with Node ≥18 and browser ESM. Typings are correctly wired.

packages/js-evo-sdk/src/.eslintrc.cjs (1)

12-15: Solid base config choice (Airbnb + TS).

The extends stack is appropriate for TS + ESM in a mixed Node/browser SDK.

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

♻️ Duplicate comments (5)
packages/js-evo-sdk/src/.eslintrc.cjs (1)

3-6: Add TS import resolver and set ecmaVersion/sourceType for robust ESM + path aliases

Without the TS resolver, import/no-unresolved will misfire on tsconfig path aliases; adding ecmaVersion/sourceType avoids parser ambiguity. Also install eslint-import-resolver-typescript.

Apply this diff:

 module.exports = {
   parser: '@typescript-eslint/parser',
   parserOptions: {
     project: ['../tsconfig.json'],
     tsconfigRootDir: __dirname,
+    ecmaVersion: 'latest',
+    sourceType: 'module',
   },
@@
   plugins: [
     '@typescript-eslint',
   ],
+  settings: {
+    'import/resolver': {
+      typescript: {
+        project: ['../tsconfig.json'],
+      },
+    },
+  },

Then ensure the resolver package is present (repo root or package scope):

#!/bin/bash
set -euo pipefail

echo "TS path aliases (if any):"
jq '.compilerOptions.paths // {}' packages/js-evo-sdk/tsconfig.json

echo -e "\nResolver config present in ESLint config:"
rg -nC2 "import/resolver" packages/js-evo-sdk/src/.eslintrc.cjs || true

echo -e "\neslint-import-resolver-typescript presence:"
for f in package.json packages/js-evo-sdk/package.json; do
  if [[ -f "$f" ]]; then
    printf "%s -> " "$f"
    jq -r '.devDependencies["eslint-import-resolver-typescript"] // .dependencies["eslint-import-resolver-typescript"] // "missing"' "$f"
  fi
done

Also applies to: 16-18

.pnp.cjs (2)

2728-2769: TypeScript 3.9.10 with ts-loader 9.5.0 will break builds; align versions.

This block shows ts-loader 9.5.0 together with a patched TypeScript 3.9.10. ts-loader 9 expects TS ≥ 4.x. Upgrade TypeScript (recommended) or downgrade ts-loader; prefer upgrading TS to 5.x for long-term support.

Apply in packages/js-evo-sdk/package.json (and any other TS packages):

 {
   "devDependencies": {
-    "typescript": "^3.9.5",
-    "ts-loader": "^9.5.0",
+    "typescript": "^5.4.5",
+    "ts-loader": "^9.5.0",
     ...
   }
 }

Then remove the TS 3.9 patch/resolution at the root (if present) and reinstall to regenerate .pnp.cjs.

#!/bin/bash
# Audit TS/ts-loader across workspaces and spot legacy patches
jq -r 'paths | join(".")' package.json >/dev/null 2>&1 || true
echo "== Declared TypeScript versions per package =="
fd package.json packages -td -x bash -lc 'echo "--- {}"; jq -r ".name, (.devDependencies.typescript // .dependencies.typescript // \"<none>\")" {}'
echo
echo "== ts-loader versions per package =="
fd package.json packages -td -x bash -lc 'echo "--- {}"; jq -r ".name, (.devDependencies[\"ts-loader\"] // .dependencies[\"ts-loader\"] // \"<none>\")" {}'
echo
echo "== Any yarn patches or resolutions pinning TS 3.x =="
rg -n --hidden --no-ignore -S "typescript@npm:3.9.10|resolutions|overrides|patch:"

19337-19358: ts-loader still peers with TS 3.9.10 here — fix with TS upgrade.

Same root cause as earlier; resolve by upgrading TypeScript and regenerating lockfile.

#!/bin/bash
# Confirm effective TS version ts-loader will resolve to
rg -n --hidden --no-ignore -C2 'ts-loader|typescript@npm:3\.9\.10' .pnp.cjs
packages/js-evo-sdk/src/tokens/facade.ts (2)

134-138: Remove non-null assertion; pass null or validate priceData

asJsonString(priceData)! can be undefined when priceData is null/undefined, risking a runtime failure. Pass null (if wasm expects Option) or validate before calling.

Apply this diff:

   async setPriceForDirectPurchase(args: { contractId: string; tokenPosition: number; identityId: string; priceType: string; priceData: unknown; privateKeyWif: string; publicNote?: string }): Promise<any> {
     const { contractId, tokenPosition, identityId, priceType, priceData, privateKeyWif, publicNote } = args;
     const w = await this.sdk.getWasmSdkConnected();
-    return w.tokenSetPriceForDirectPurchase(contractId, tokenPosition, identityId, priceType, asJsonString(priceData)!, privateKeyWif, publicNote ?? null);
+    const priceJson = asJsonString(priceData);
+    return w.tokenSetPriceForDirectPurchase(
+      contractId, tokenPosition, identityId, priceType,
+      priceJson ?? null,
+      privateKeyWif, publicNote ?? null
+    );
   }
#!/bin/bash
# Verify wasm signatures allow null for price/config JSON
rg -n -C2 'tokenSetPriceForDirectPurchase\s*\('
rg -n -C2 'tokenConfigUpdate\s*\('

152-156: Same here: avoid non-null assertion for configValue

asJsonString(configValue)! has the same risk; handle undefined.

   async configUpdate(args: { contractId: string; tokenPosition: number; configItemType: string; configValue: unknown; identityId: string; privateKeyWif: string; publicNote?: string }): Promise<any> {
     const { contractId, tokenPosition, configItemType, configValue, identityId, privateKeyWif, publicNote } = args;
     const w = await this.sdk.getWasmSdkConnected();
-    return w.tokenConfigUpdate(contractId, tokenPosition, configItemType, asJsonString(configValue)!, identityId, privateKeyWif, publicNote ?? null);
+    const cfg = asJsonString(configValue);
+    return w.tokenConfigUpdate(
+      contractId, tokenPosition, configItemType,
+      cfg ?? null,
+      identityId, privateKeyWif, publicNote ?? null
+    );
   }
🧹 Nitpick comments (21)
packages/js-evo-sdk/src/.eslintrc.cjs (2)

19-29: Keep public API types tight: downgrade any to a warning (not off)

For an SDK, surfacing any freely degrades consumer DX. Consider warning to keep intentional uses explicit.

-    '@typescript-eslint/no-explicit-any': 'off',
+    '@typescript-eslint/no-explicit-any': 'warn',

30-32: Ignore build/coverage outputs to speed up lint and avoid noise

Commonly exclude generated artifacts.

   ignorePatterns: [
     '*.d.ts',
+    'dist/**',
+    'coverage/**',
   ],
packages/js-evo-sdk/src/protocol/facade.ts (4)

3-5: Make sdk param readonly and use a parameter property

Reduces boilerplate and prevents accidental reassignment.

-export class ProtocolFacade {
-  private sdk: EvoSDK;
-  constructor(sdk: EvoSDK) { this.sdk = sdk; }
+export class ProtocolFacade {
+  constructor(private readonly sdk: EvoSDK) {}

7-9: Avoid any; use unknown and multiline formatting

Prevents type unsafety and meets common max-len rules.

-  async versionUpgradeState(): Promise<any> { const w = await this.sdk.getWasmSdkConnected(); return w.getProtocolVersionUpgradeState(); }
-  async versionUpgradeStateWithProof(): Promise<any> { const w = await this.sdk.getWasmSdkConnected(); return w.getProtocolVersionUpgradeStateWithProofInfo(); }
+  async versionUpgradeState(): Promise<unknown> {
+    const w = await this.sdk.getWasmSdkConnected();
+    return w.getProtocolVersionUpgradeState();
+  }
+
+  async versionUpgradeStateWithProof(): Promise<unknown> {
+    const w = await this.sdk.getWasmSdkConnected();
+    return w.getProtocolVersionUpgradeStateWithProofInfo();
+  }

10-14: Type params/returns; destructure in signature; optional input guard

Replace any, simplify signature, and (optionally) guard count.

-  async versionUpgradeVoteStatus(params: { startProTxHash: string; count: number }): Promise<any> {
-    const { startProTxHash, count } = params;
-    const w = await this.sdk.getWasmSdkConnected();
-    return w.getProtocolVersionUpgradeVoteStatus(startProTxHash, count);
-  }
+  async versionUpgradeVoteStatus(
+    { startProTxHash, count }: VersionUpgradeVoteStatusParams,
+  ): Promise<unknown> {
+    // Optional: enable if wasm expects positive count
+    // if (!Number.isInteger(count) || count <= 0) throw new TypeError('count must be a positive integer');
+    const w = await this.sdk.getWasmSdkConnected();
+    return w.getProtocolVersionUpgradeVoteStatus(startProTxHash, count);
+  }

Add this shared type near the top of the file:

export type VersionUpgradeVoteStatusParams = { startProTxHash: string; count: number };

16-20: Mirror types/destructuring for withProof variant

Keep both methods consistent; avoid any.

-  async versionUpgradeVoteStatusWithProof(params: { startProTxHash: string; count: number }): Promise<any> {
-    const { startProTxHash, count } = params;
-    const w = await this.sdk.getWasmSdkConnected();
-    return w.getProtocolVersionUpgradeVoteStatusWithProofInfo(startProTxHash, count);
-  }
+  async versionUpgradeVoteStatusWithProof(
+    { startProTxHash, count }: VersionUpgradeVoteStatusParams,
+  ): Promise<unknown> {
+    const w = await this.sdk.getWasmSdkConnected();
+    return w.getProtocolVersionUpgradeVoteStatusWithProofInfo(startProTxHash, count);
+  }
.pnp.cjs (7)

5482-5516: Duplicate webpack virtuals for @webpack-cli/configtest — benign, but can be deduped.

If desired, align peer trees to a single webpack virtual to shrink lockfile.


5581-5609: Duplicate webpack virtuals for @webpack-cli/info — optional dedupe.


5686-5720: Duplicate webpack virtuals for @webpack-cli/serve — optional dedupe.


13523-13538: Additional karma-webpack virtual — optional to consolidate.


18877-18906: Second terser-webpack-plugin virtual — same suggestion to pin/dedupe.


19026-19056: terser-webpack-plugin 5.3.11 also present — align to one.


18817-18846: Consolidate terser-webpack-plugin versions (5.3.10 vs 5.3.11).

yarn.lock and .pnp.cjs contain both 5.3.10 and 5.3.11; packages/js-evo-sdk/package.json:62 and packages/js-dash-sdk/package.json:100 declare ^5.3.11. Force a single version (recommend 5.3.11) via a root "resolutions" or by updating the transitive that pulls 5.3.10.

packages/js-evo-sdk/src/tokens/facade.ts (4)

97-114: Validate and normalize tokenPosition/amount before calling wasm

Guard against negative/unsafe integers and malformed numeric strings to fail fast on the client.

Example for mint (replicate in burn/transfer):

   async mint(args: { contractId: string; tokenPosition: number; amount: number | string | bigint; identityId: string; privateKeyWif: string; recipientId?: string; publicNote?: string }): Promise<any> {
     const { contractId, tokenPosition, amount, identityId, privateKeyWif, recipientId, publicNote } = args;
     const w = await this.sdk.getWasmSdkConnected();
-    return w.tokenMint(contractId, tokenPosition, String(amount), identityId, privateKeyWif, recipientId ?? null, publicNote ?? null);
+    if (!Number.isSafeInteger(tokenPosition) || tokenPosition < 0) {
+      throw new TypeError('tokenPosition must be a non-negative safe integer');
+    }
+    const amt = typeof amount === 'bigint' ? amount.toString(10) : String(amount);
+    if (!/^\d+$/.test(amt)) {
+      throw new TypeError('amount must be a non-negative integer');
+    }
+    return w.tokenMint(contractId, tokenPosition, amt, identityId, privateKeyWif, recipientId ?? null, publicNote ?? null);
   }

116-132: Apply the same input guards to freeze/unfreeze/destroyFrozen

These also rely on tokenPosition; add the same non-negative safe-int check as in mint.


4-9: Minor: use a parameter property and readonly for sdk

Tightens immutability and trims boilerplate.

-export class TokensFacade {
-  private sdk: EvoSDK;
-
-  constructor(sdk: EvoSDK) {
-    this.sdk = sdk;
-  }
-}
+export class TokensFacade {
+  constructor(private readonly sdk: EvoSDK) {}
+}

47-50: Remove unused _opts or forward limit/offset to wasm

_opts is unused in packages/js-evo-sdk/src/tokens/facade.ts (identityTokenInfos — lines 47–50). Remove the parameter to avoid a dead API surface, or thread its limit/offset through to w.getIdentityTokenInfos once the wasm SDK supports pagination.

packages/js-evo-sdk/src/voting/facade.ts (4)

1-52: Tighten public types: avoid any and derive precise return types from wasm.

Improves DX, lint compliance, and prevents accidental misuse.

 import { asJsonString } from '../util.js';
 import type { EvoSDK } from '../sdk.js';
+import type * as wasm from '../wasm.js';
+
+// Derive concrete return types from wasm surface
+type CRVoteState = Awaited<ReturnType<wasm.WasmSdk['getContestedResourceVoteState']>>;
+type CRVoteStateWithProofInfo = Awaited<ReturnType<wasm.WasmSdk['getContestedResourceVoteStateWithProofInfo']>>;
+type CRIdentityVotes = Awaited<ReturnType<wasm.WasmSdk['getContestedResourceIdentityVotes']>>;
+type CRIdentityVotesWithProofInfo = Awaited<ReturnType<wasm.WasmSdk['getContestedResourceIdentityVotesWithProofInfo']>>;
+type VotePollsByEndDate = Awaited<ReturnType<wasm.WasmSdk['getVotePollsByEndDate']>>;
+type VotePollsByEndDateWithProofInfo = Awaited<ReturnType<wasm.WasmSdk['getVotePollsByEndDateWithProofInfo']>>;
+type MasternodeVoteResult = Awaited<ReturnType<wasm.WasmSdk['masternodeVote']>>;

 export class VotingFacade {
   private sdk: EvoSDK;
   constructor(sdk: EvoSDK) { this.sdk = sdk; }

-  async contestedResourceVoteState(params: { contractId: string; documentTypeName: string; indexName: string; indexValues: any[]; resultType: string; allowIncludeLockedAndAbstainingVoteTally?: boolean; startAtIdentifierInfo?: string; count?: number; orderAscending?: boolean }): Promise<any> {
+  async contestedResourceVoteState(params: { contractId: string; documentTypeName: string; indexName: string; indexValues: ReadonlyArray<unknown>; resultType: string; allowIncludeLockedAndAbstainingVoteTally?: boolean; startAtIdentifierInfo?: string; count?: number; orderAscending?: boolean }): Promise<CRVoteState> {
     const { contractId, documentTypeName, indexName, indexValues, resultType, allowIncludeLockedAndAbstainingVoteTally, startAtIdentifierInfo, count, orderAscending } = params;
     const w = await this.sdk.getWasmSdkConnected();
     return w.getContestedResourceVoteState(contractId, documentTypeName, indexName, indexValues, resultType, allowIncludeLockedAndAbstainingVoteTally ?? null, startAtIdentifierInfo ?? null, count ?? null, orderAscending ?? null);
   }

-  async contestedResourceVoteStateWithProof(params: { contractId: string; documentTypeName: string; indexName: string; indexValues: any[]; resultType: string; allowIncludeLockedAndAbstainingVoteTally?: boolean; startAtIdentifierInfo?: string; count?: number; orderAscending?: boolean }): Promise<any> {
+  async contestedResourceVoteStateWithProof(params: { contractId: string; documentTypeName: string; indexName: string; indexValues: ReadonlyArray<unknown>; resultType: string; allowIncludeLockedAndAbstainingVoteTally?: boolean; startAtIdentifierInfo?: string; count?: number; orderAscending?: boolean }): Promise<CRVoteStateWithProofInfo> {
     const { contractId, documentTypeName, indexName, indexValues, resultType, allowIncludeLockedAndAbstainingVoteTally, startAtIdentifierInfo, count, orderAscending } = params;
     const w = await this.sdk.getWasmSdkConnected();
     return w.getContestedResourceVoteStateWithProofInfo(contractId, documentTypeName, indexName, indexValues, resultType, allowIncludeLockedAndAbstainingVoteTally ?? null, startAtIdentifierInfo ?? null, count ?? null, orderAscending ?? null);
   }

-  async contestedResourceIdentityVotes(identityId: string, opts: { limit?: number; startAtVotePollIdInfo?: string; orderAscending?: boolean } = {}): Promise<any> {
+  async contestedResourceIdentityVotes(identityId: string, opts: { limit?: number; startAtVotePollIdInfo?: string; orderAscending?: boolean } = {}): Promise<CRIdentityVotes> {
     const { limit, startAtVotePollIdInfo, orderAscending } = opts;
     const w = await this.sdk.getWasmSdkConnected();
     return w.getContestedResourceIdentityVotes(identityId, limit ?? null, startAtVotePollIdInfo ?? null, orderAscending ?? null);
   }

-  async contestedResourceIdentityVotesWithProof(identityId: string, opts: { limit?: number; offset?: number; orderAscending?: boolean } = {}): Promise<any> {
+  async contestedResourceIdentityVotesWithProof(identityId: string, opts: { limit?: number; offset?: number; orderAscending?: boolean } = {}): Promise<CRIdentityVotesWithProofInfo> {
     const { limit, offset, orderAscending } = opts;
     const w = await this.sdk.getWasmSdkConnected();
     return w.getContestedResourceIdentityVotesWithProofInfo(identityId, limit ?? null, offset ?? null, orderAscending ?? null);
   }

-  async votePollsByEndDate(opts: { startTimeInfo?: string; endTimeInfo?: string; limit?: number; orderAscending?: boolean } = {}): Promise<any> {
+  async votePollsByEndDate(opts: { startTimeInfo?: string; endTimeInfo?: string; limit?: number; orderAscending?: boolean } = {}): Promise<VotePollsByEndDate> {
     const { startTimeInfo, endTimeInfo, limit, orderAscending } = opts;
     const w = await this.sdk.getWasmSdkConnected();
     return w.getVotePollsByEndDate(startTimeInfo ?? null, endTimeInfo ?? null, limit ?? null, orderAscending ?? null);
   }

-  async votePollsByEndDateWithProof(opts: { startTimeMs?: number | bigint | null; endTimeMs?: number | bigint | null; limit?: number; offset?: number; orderAscending?: boolean } = {}): Promise<any> {
+  async votePollsByEndDateWithProof(opts: { startTimeMs?: number | bigint | null; endTimeMs?: number | bigint | null; limit?: number; offset?: number; orderAscending?: boolean } = {}): Promise<VotePollsByEndDateWithProofInfo> {
     const { startTimeMs, endTimeMs, limit, offset, orderAscending } = opts;
     const start = startTimeMs != null ? BigInt(startTimeMs) : null;
     const end = endTimeMs != null ? BigInt(endTimeMs) : null;
     const w = await this.sdk.getWasmSdkConnected();
     return w.getVotePollsByEndDateWithProofInfo(start ?? null, end ?? null, limit ?? null, offset ?? null, orderAscending ?? null);
   }

-  async masternodeVote(args: { masternodeProTxHash: string; contractId: string; documentTypeName: string; indexName: string; indexValues: string | any[]; voteChoice: string; votingKeyWif: string }): Promise<any> {
+  async masternodeVote(args: { masternodeProTxHash: string; contractId: string; documentTypeName: string; indexName: string; indexValues: string | ReadonlyArray<unknown>; voteChoice: string; votingKeyWif: string }): Promise<MasternodeVoteResult> {
     const { masternodeProTxHash, contractId, documentTypeName, indexName, indexValues, voteChoice, votingKeyWif } = args;
-    const indexValuesStr = typeof indexValues === 'string' ? indexValues : asJsonString(indexValues)!;
+    const indexValuesStr = typeof indexValues === 'string' ? indexValues : asJsonString(indexValues)!;
     const w = await this.sdk.getWasmSdkConnected();
     return w.masternodeVote(masternodeProTxHash, contractId, documentTypeName, indexName, indexValuesStr, voteChoice, votingKeyWif);
   }
 }

46-51: Avoid non-null assertion on indexValues; validate input and fail fast.

Prevents obscure wasm errors if callers pass null/undefined.

   async masternodeVote(args: { masternodeProTxHash: string; contractId: string; documentTypeName: string; indexName: string; indexValues: string | ReadonlyArray<unknown>; voteChoice: string; votingKeyWif: string }): Promise<MasternodeVoteResult> {
     const { masternodeProTxHash, contractId, documentTypeName, indexName, indexValues, voteChoice, votingKeyWif } = args;
-    const indexValuesStr = typeof indexValues === 'string' ? indexValues : asJsonString(indexValues)!;
+    if (indexValues == null) {
+      throw new TypeError('masternodeVote: indexValues is required (string or JSON-serializable array).');
+    }
+    const indexValuesStr = typeof indexValues === 'string' ? indexValues : asJsonString(indexValues);
+    if (indexValuesStr == null) {
+      throw new TypeError('masternodeVote: indexValues must be a string or JSON-serializable array.');
+    }
     const w = await this.sdk.getWasmSdkConnected();
     return w.masternodeVote(masternodeProTxHash, contractId, documentTypeName, indexName, indexValuesStr, voteChoice, votingKeyWif);
   }

38-44: Optional: accept Date for convenience and centralize ms→BigInt conversion.

Small ergonomics win for callers; keeps wasm input unchanged.

-  async votePollsByEndDateWithProof(opts: { startTimeMs?: number | bigint | null; endTimeMs?: number | bigint | null; limit?: number; offset?: number; orderAscending?: boolean } = {}): Promise<VotePollsByEndDateWithProofInfo> {
-    const { startTimeMs, endTimeMs, limit, offset, orderAscending } = opts;
-    const start = startTimeMs != null ? BigInt(startTimeMs) : null;
-    const end = endTimeMs != null ? BigInt(endTimeMs) : null;
+  async votePollsByEndDateWithProof(opts: { startTimeMs?: number | bigint | Date | null; endTimeMs?: number | bigint | Date | null; limit?: number; offset?: number; orderAscending?: boolean } = {}): Promise<VotePollsByEndDateWithProofInfo> {
+    const { startTimeMs, endTimeMs, limit, offset, orderAscending } = opts;
+    const toBigIntMs = (v: number | bigint | Date | null | undefined) =>
+      v == null ? null : (v instanceof Date ? BigInt(v.getTime()) : BigInt(v));
+    const start = toBigIntMs(startTimeMs);
+    const end = toBigIntMs(endTimeMs);
     const w = await this.sdk.getWasmSdkConnected();
     return w.getVotePollsByEndDateWithProofInfo(start ?? null, end ?? null, limit ?? null, offset ?? null, orderAscending ?? null);
   }

26-30: Clarify pagination parameter mismatch in with/without proof variants.

Doc note reduces confusion between startAtVotePollIdInfo vs offset.

   async contestedResourceIdentityVotesWithProof(identityId: string, opts: { limit?: number; offset?: number; orderAscending?: boolean } = {}): Promise<CRIdentityVotesWithProofInfo> {
+    /** Note: withProof variant uses numeric `offset` pagination while non-proof uses `startAtVotePollIdInfo` (string), mirroring wasm API. */
     const { limit, offset, orderAscending } = opts;
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6f58d3b and 6a4174b.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (9)
  • .pnp.cjs (19 hunks)
  • packages/js-evo-sdk/src/.eslintrc.cjs (1 hunks)
  • packages/js-evo-sdk/src/documents/facade.ts (1 hunks)
  • packages/js-evo-sdk/src/epoch/facade.ts (1 hunks)
  • packages/js-evo-sdk/src/group/facade.ts (1 hunks)
  • packages/js-evo-sdk/src/protocol/facade.ts (1 hunks)
  • packages/js-evo-sdk/src/system/facade.ts (1 hunks)
  • packages/js-evo-sdk/src/tokens/facade.ts (1 hunks)
  • packages/js-evo-sdk/src/voting/facade.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • packages/js-evo-sdk/src/group/facade.ts
  • packages/js-evo-sdk/src/epoch/facade.ts
  • packages/js-evo-sdk/src/documents/facade.ts
  • packages/js-evo-sdk/src/system/facade.ts
🧰 Additional context used
📓 Path-based instructions (1)
packages/**/**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

packages/**/**/*.{js,ts,jsx,tsx}: Adhere to ESLint with Airbnb/TypeScript configs for JS/TS code
Use camelCase for JS/TS variables and functions
Use PascalCase for JS/TS classes
Prefer kebab-case filenames within JS packages

Files:

  • packages/js-evo-sdk/src/protocol/facade.ts
  • packages/js-evo-sdk/src/tokens/facade.ts
  • packages/js-evo-sdk/src/voting/facade.ts
🧠 Learnings (4)
📓 Common learnings
Learnt from: CR
PR: dashpay/platform#0
File: packages/wasm-sdk/CLAUDE.md:0-0
Timestamp: 2025-07-23T08:31:42.268Z
Learning: Applies to packages/wasm-sdk/src/**/*.rs : Token functions are methods on WasmSdk, not standalone functions; avoid importing them as standalone.
Learnt from: CR
PR: dashpay/platform#0
File: packages/wasm-sdk/CLAUDE.md:0-0
Timestamp: 2025-07-23T08:31:42.268Z
Learning: Applies to packages/wasm-sdk/src/**/*.rs : When implementing WASM SDK functionality, always refer to AI_REFERENCE.md first for accurate method signatures and examples.
Learnt from: CR
PR: dashpay/platform#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-07T22:18:50.883Z
Learning: Applies to packages/wasm-sdk/** : Keep WASM SDK docs in sync (run generate_docs.py) when updating the WASM SDK
Learnt from: CR
PR: dashpay/platform#0
File: packages/wasm-sdk/CLAUDE.md:0-0
Timestamp: 2025-07-23T08:31:42.268Z
Learning: Applies to packages/wasm-sdk/src/**/*.rs : For WASM builds, fix 'time not implemented on this platform' errors by using js_sys::Date::now().
Learnt from: CR
PR: dashpay/platform#0
File: packages/wasm-sdk/CLAUDE.md:0-0
Timestamp: 2025-07-23T08:31:42.268Z
Learning: Applies to packages/wasm-sdk/src/**/*.rs : The WASM SDK now fully supports where and orderBy clauses for document queries; use the specified JSON array formats and supported operators.
📚 Learning: 2025-09-12T13:18:08.661Z
Learnt from: CR
PR: dashpay/platform#0
File: AGENTS.md:0-0
Timestamp: 2025-09-12T13:18:08.661Z
Learning: Applies to packages/**/**/*.{js,ts,jsx,tsx} : Adhere to ESLint with Airbnb/TypeScript configs for JS/TS code

Applied to files:

  • packages/js-evo-sdk/src/.eslintrc.cjs
📚 Learning: 2025-07-28T20:00:08.502Z
Learnt from: QuantumExplorer
PR: dashpay/platform#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/js-evo-sdk/src/tokens/facade.ts
📚 Learning: 2025-09-07T22:18:50.883Z
Learnt from: CR
PR: dashpay/platform#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-07T22:18:50.883Z
Learning: Applies to packages/rs-sdk-ffi/**/*.{h,rs} : Follow unified SDK function prefixes: dash_core_sdk_* for Core, dash_sdk_* for Platform, dash_unified_sdk_* for unified APIs

Applied to files:

  • .pnp.cjs
🧬 Code graph analysis (3)
packages/js-evo-sdk/src/protocol/facade.ts (1)
packages/js-evo-sdk/src/sdk.ts (2)
  • ProtocolFacade (129-129)
  • EvoSDK (34-121)
packages/js-evo-sdk/src/tokens/facade.ts (2)
packages/js-evo-sdk/src/sdk.ts (2)
  • TokensFacade (126-126)
  • EvoSDK (34-121)
packages/js-evo-sdk/src/util.ts (1)
  • asJsonString (1-5)
packages/js-evo-sdk/src/voting/facade.ts (2)
packages/js-evo-sdk/src/sdk.ts (2)
  • VotingFacade (132-132)
  • EvoSDK (34-121)
packages/js-evo-sdk/src/util.ts (1)
  • asJsonString (1-5)
⏰ 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). (8)
  • GitHub Check: Rust packages (wasm-sdk) / Tests
  • GitHub Check: Rust packages (wasm-sdk) / Unused dependencies
  • GitHub Check: Rust packages (wasm-sdk) / Formatting
  • GitHub Check: Rust packages (wasm-sdk) / Linting
  • 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
  • GitHub Check: Rust crates security audit
🔇 Additional comments (16)
packages/js-evo-sdk/src/.eslintrc.cjs (1)

12-18: Baseline config choice looks good

Airbnb base + airbnb-typescript/base with @typescript-eslint aligns with repo standards.

packages/js-evo-sdk/src/protocol/facade.ts (2)

1-1: Type-only import: LGTM

Correct for TS+ESM builds and helps treeshaking.


10-14: Validate/normalize startProTxHash to base64; verify count limits

  • startProTxHash must be base64 for gRPC — validate input or accept hex and convert to base64 before calling w.getProtocolVersionUpgradeVoteStatus. (docs.dash.org)
  • Confirm allowed range/max for count (not specified in platform docs) and enforce or document a safe clamp/validation. Location: packages/js-evo-sdk/src/protocol/facade.ts (lines 10–14, 16–20). (docs.dash.org)
.pnp.cjs (10)

115-115: Mapping includes evo-sdk — OK.


126-126: Mapping includes wasm-sdk — OK.


13491-13506: karma-webpack tied to one webpack virtual — OK.


20456-20491: Multiple webpack virtuals — OK for differing peer graphs.

No action unless you want to reduce lockfile size.


20528-20563: Another webpack virtual block — OK.


20773-20813: Additional webpack-cli virtual — OK.


96-99: Workspace entry for @dashevo/wasm-sdk is fine — generate_docs.py missing; verify docs workflow

CLAUDE.md:132 and .github/scripts/check-grpc-coverage.py:352 still reference python3 generate_docs.py. Add/restore generate_docs.py under packages/wasm-sdk and run it to regenerate the WASM docs, or update these instructions to the current docs-generation workflow.


20691-20731: CI Node version is 20 — no action required.

Workflows use actions/setup-node@v4 with node-version "20" (.github/workflows/tests.yml:156–158, .github/workflows/prebuild-devcontainers.yml:28–30, .github/actions/nodejs/action.yaml:8–10); package.json does not constrain engines. Node 20 satisfies the webpack/CLI/mocha >=14 requirement.


56-59: Workspace entry for @dashevo/evo-sdk confirmed — no occurrences of misscoped "@dashevoevo/evo-sdk".
Repository search shows all references use "@dashevo/evo-sdk".


3120-3153: Keep webpack/karma/browser shims (buffer, process, util, path-browserify, url) dev-only and out of published artifacts.

package.json lists those packages in devDependencies and "files" = ["dist/**","README.md"], but dist/ is currently missing — ensure the built dist only contains ESM/WASM artifacts and that the build/publish step does not bundle or require Buffer/process/path-browserify/url/util at runtime.

Relevant locations:

  • packages/wasm-sdk/package.json
  • packages/wasm-sdk/tests/karma/options.cjs
  • packages/wasm-sdk/scripts/bundle.cjs
  • packages/wasm-sdk/tests/unit/key-generation.spec.mjs
packages/js-evo-sdk/src/tokens/facade.ts (1)

11-96: Replace Promise with concrete proto/wasm types

Replace Promise on token query methods in packages/js-evo-sdk/src/tokens/facade.ts with concrete response types imported from the generated TypeScript declarations — prefer wasm-sdk's exported .d.ts if available; no wasm-sdk .d.ts was found in the repo, but protobuf TS types exist at packages/dapi-grpc/clients/platform/v0/web/platform_pb.d.ts (use the appropriate response/message classes such as GetTokenStatusesResponse, GetTokenTotalSupplyResponse, GetTokenDirectPurchasePricesResponse, GetTokenContractInfoResponse, GetTokenPerpetualDistributionLastClaimResponse, etc.) and update the method signatures and imports accordingly.

packages/js-evo-sdk/src/voting/facade.ts (2)

4-7: Solid facade shape and wasm-connection pattern.

Consistent null→nullish normalization and single connect per call. Looks good.


1-52: Verify wasm surface parity (names/arg order) — grep returned no matches

  • Confirm packages/js-evo-sdk/src/wasm.ts exports these exact methods with matching signatures/arg order: getContestedResourceVoteState, getContestedResourceVoteStateWithProofInfo, getContestedResourceIdentityVotes, getContestedResourceIdentityVotesWithProofInfo, getVotePollsByEndDate, getVotePollsByEndDateWithProofInfo, masternodeVote.
  • Ensure unit/functional tests under packages/js-evo-sdk/tests cover VotingFacade → wasm wiring or add tests to prevent runtime mismatches.

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 (4)
packages/js-evo-sdk/tests/fixtures/testnet.mjs (4)

22-27: Avoid ReferenceError in browser runs; guard process.env and validate keyId.
Direct process access will crash in browser; also ensure keyId is numeric.

Apply this diff:

-export const TEST_SECRETS = {
-  identityId: process.env.EVO_IDENTITY_ID,
-  privateKeyWif: process.env.EVO_PRIVATE_WIF,
-  keyId: process.env.EVO_KEY_ID ? Number(process.env.EVO_KEY_ID) : undefined,
-};
+export const TEST_SECRETS = {
+  identityId:
+    typeof process !== 'undefined' && process.env ? process.env.EVO_IDENTITY_ID : undefined,
+  privateKeyWif:
+    typeof process !== 'undefined' && process.env ? process.env.EVO_PRIVATE_WIF : undefined,
+  keyId:
+    typeof process !== 'undefined' &&
+    process.env &&
+    typeof process.env.EVO_KEY_ID === 'string' &&
+    /^\d+$/.test(process.env.EVO_KEY_ID)
+      ? Number(process.env.EVO_KEY_ID)
+      : undefined,
+};

5-20: Make fixtures immutable to prevent accidental mutation in tests.
Freezing avoids flakiness from accidental writes.

Apply this diff:

   epoch: 8635,
 };
 
 // Optional environment-driven secrets for state-transition tests (skipped by default).
 export const TEST_SECRETS = {
@@
   keyId: typeof process !== 'undefined' && process.env && typeof process.env.EVO_KEY_ID === 'string' && /^\d+$/.test(process.env.EVO_KEY_ID)
       ? Number(process.env.EVO_KEY_ID)
       : undefined,
 };
+
+Object.freeze(TEST_IDS);
+Object.freeze(TEST_SECRETS);

Also applies to: 22-27


1-3: Add maintenance hint to refresh source of IDs.
Add a pointer to the docs generator/api-defs and when last validated.

Apply this diff:

 // Shared testnet fixtures used by functional tests.
-// Values are sourced from the wasm-sdk docs generator and api-definitions
+// Values are sourced from the wasm-sdk docs generator and api-definitions.
+// When updating, cross-check against the docs generator output (see generate_docs.py) and note the refresh date here.

1-27: Optional: author a .d.ts or convert to .mts for better TS ergonomics.
If TS tests import this fixture, a .d.ts or .mts avoids interop friction.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6a4174b and fddf8ea.

📒 Files selected for processing (3)
  • packages/js-evo-sdk/tests/fixtures/testnet.mjs (1 hunks)
  • packages/js-evo-sdk/tests/functional/dpns.spec.mjs (1 hunks)
  • packages/js-evo-sdk/tests/functional/tokens.spec.mjs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/js-evo-sdk/tests/functional/tokens.spec.mjs
  • packages/js-evo-sdk/tests/functional/dpns.spec.mjs
🧰 Additional context used
📓 Path-based instructions (1)
packages/**/tests/**

📄 CodeRabbit inference engine (AGENTS.md)

Place unit and integration tests alongside each package in packages//tests

Files:

  • packages/js-evo-sdk/tests/fixtures/testnet.mjs
🧠 Learnings (2)
📓 Common learnings
Learnt from: CR
PR: dashpay/platform#0
File: packages/wasm-sdk/CLAUDE.md:0-0
Timestamp: 2025-07-23T08:31:42.268Z
Learning: Applies to packages/wasm-sdk/src/**/*.rs : Token functions are methods on WasmSdk, not standalone functions; avoid importing them as standalone.
Learnt from: CR
PR: dashpay/platform#0
File: packages/wasm-sdk/CLAUDE.md:0-0
Timestamp: 2025-07-23T08:31:42.268Z
Learning: Applies to packages/wasm-sdk/src/**/*.rs : When implementing WASM SDK functionality, always refer to AI_REFERENCE.md first for accurate method signatures and examples.
Learnt from: CR
PR: dashpay/platform#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-07T22:18:50.883Z
Learning: Applies to packages/wasm-sdk/** : Keep WASM SDK docs in sync (run generate_docs.py) when updating the WASM SDK
Learnt from: CR
PR: dashpay/platform#0
File: packages/wasm-sdk/CLAUDE.md:0-0
Timestamp: 2025-07-23T08:31:42.268Z
Learning: Applies to packages/wasm-sdk/src/**/*.rs : For WASM builds, fix 'time not implemented on this platform' errors by using js_sys::Date::now().
Learnt from: CR
PR: dashpay/platform#0
File: packages/wasm-sdk/CLAUDE.md:0-0
Timestamp: 2025-07-23T08:31:42.268Z
Learning: Applies to packages/wasm-sdk/src/**/*.rs : The WASM SDK now fully supports where and orderBy clauses for document queries; use the specified JSON array formats and supported operators.
📚 Learning: 2024-10-30T11:19:59.163Z
Learnt from: lklimek
PR: dashpay/platform#2277
File: packages/rs-sdk/tests/fetch/config.rs:233-233
Timestamp: 2024-10-30T11:19:59.163Z
Learning: In the Rust SDK's `rs-sdk/tests` integration tests (e.g., in `packages/rs-sdk/tests/fetch/config.rs`), we cannot create objects during tests because there is no support for object creation in this context. Therefore, hardcoded values for test identities must be used.

Applied to files:

  • packages/js-evo-sdk/tests/fixtures/testnet.mjs
🪛 Gitleaks (8.27.2)
packages/js-evo-sdk/tests/fixtures/testnet.mjs

[high] 9-9: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)


[high] 11-11: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

⏰ 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) / Unused dependencies
  • GitHub Check: Rust packages (wasm-sdk) / Formatting
  • GitHub Check: Rust packages (wasm-sdk) / Linting
  • GitHub Check: Build JS packages / Build JS
  • GitHub Check: Rust crates security audit
🔇 Additional comments (5)
packages/js-evo-sdk/tests/fixtures/testnet.mjs (5)

1-3: LGTM: fixtures colocated under packages/js-evo-sdk/tests and ESM exports.
Good placement per repo guidelines.


19-19: Verify epoch stability or derive dynamically.
Hard-coding epoch 8635 may drift as testnet advances; confirm tests don’t rely on current epoch or make it configurable.


17-18: Confirm username fixture values.
Is “therealslimshaddy5” intentional (vs “slimshady”)? Please verify it resolves on testnet to avoid flaky lookups.


22-27: No secret logging found — resolving.
Search output shows "OK: no logging found" for packages/js-evo-sdk/tests; no console.log/info/debug/warn referencing TEST_SECRETS or EVO_* vars detected.


1-1: No action required — tests excluded from published package
packages/js-evo-sdk/package.json "files" contains only "dist/" and "README.md", so packages/js-evo-sdk/tests/ will not be included in the published tarball.

@QuantumExplorer QuantumExplorer merged commit 59dc8c7 into v2.1-dev Sep 17, 2025
27 checks passed
@QuantumExplorer QuantumExplorer deleted the evo-sdk branch September 17, 2025 14:07
Copy link
Collaborator

Choose a reason for hiding this comment

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

@shumkov this file is under group, but appears to actually be related to contested resources? Are the group queries actually covered somewhere?

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.

3 participants