Skip to content

Conversation

@thephez
Copy link
Collaborator

@thephez thephez commented Oct 28, 2025

Issue being fixed or feature implemented

Developers using the DPNS registration API were encountering a cryptic error message "Invalid public key security level MASTER" when the identity key parameter was not passed. This error only appeared after attempting to sign the state transition, making it difficult to understand what went wrong and how to fix it.

What was done?

Added comprehensive early validation and helpful error messages for DPNS name registration:

  • WASM SDK validation (packages/wasm-sdk/src/dpns.rs): Validate key purpose is AUTHENTICATION, security level is CRITICAL or HIGH (not MASTER), and private key matches the specified public key before attempting cryptographic operations
  • JS SDK validation (packages/js-evo-sdk/src/dpns/facade.ts): Add input validation for publicKeyId parameter with clear error messages and comprehensive JSDoc documentation
  • Test coverage (packages/js-evo-sdk/tests/unit/facades/dpns.spec.mjs): Add 6 test cases covering validation of omitted, undefined, null, negative, non-number, and valid publicKeyId values

Error messages now explain which requirement failed, list all suitable keys available in the identity, and provide specific guidance (e.g., "Use key 1 (CRITICAL) or 2 (HIGH), NOT 0 (MASTER)").

How Has This Been Tested?

  • Unit tests added for all validation scenarios (6 new test cases, all passing)

Breaking Changes

None. This is fully backwards compatible - it only adds validation and improves error messages.

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

Release Notes

  • New Features

    • Added DPNS name registration functionality with comprehensive validation to ensure proper key configuration and security requirements are met.
  • Tests

    • Added test coverage for DPNS registration validation scenarios, including edge cases and error handling.

…election

Add comprehensive validation before signing DPNS registration state transitions to catch common errors early and provide clear, actionable error messages to developers. Fixes issue where users accidentally use MASTER key (ID 0) which is not allowed for DPNS registration, resulting in cryptic error messages only after signing attempt.
@thephez
Copy link
Collaborator Author

thephez commented Oct 28, 2025

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 28, 2025

Walkthrough

These changes introduce a new registerName public method to the DPNS facade with input validation at the TypeScript layer. The WASM layer adds corresponding key validation to ensure the public key has AUTHENTICATION purpose, appropriate security levels (CRITICAL or HIGH), and matching private key credentials before proceeding with DPNS registration.

Changes

Cohort / File(s) Summary
JavaScript/TypeScript DPNS facade
packages/js-evo-sdk/src/dpns/facade.ts, packages/js-evo-sdk/tests/unit/facades/dpns.spec.mjs
Adds registerName method to DpnsFacade with publicKeyId validation (null/undefined checks, non-negative number requirement). Companion test suite validates edge cases (missing, undefined, null, negative, non-numeric values) and positive registration path.
Rust/WASM validation layer
packages/wasm-sdk/src/dpns.rs
Introduces DPNS key validation logic: retrieves identity public key, enforces AUTHENTICATION purpose, validates security level (CRITICAL or HIGH), and verifies private key matches via signer. Returns descriptive errors with guidance for invalid keys.

Sequence Diagram

sequenceDiagram
    participant User as User Code
    participant JsFacade as JS Facade
    participant Wasm as WASM SDK
    participant KeyValidator as Key Validator
    
    User->>JsFacade: registerName(label, identityId, publicKeyId, ...)
    activate JsFacade
    JsFacade->>JsFacade: Validate publicKeyId (not null/undefined, non-negative)
    alt publicKeyId invalid
        JsFacade-->>User: Throw validation error
    else publicKeyId valid
        JsFacade->>Wasm: w.dpnsRegisterName(label, identityId, publicKeyId, privateKeyWif, ...)
        activate Wasm
        Wasm->>KeyValidator: Get and validate identity public key
        activate KeyValidator
        KeyValidator->>KeyValidator: Check purpose = AUTHENTICATION
        KeyValidator->>KeyValidator: Check security level = CRITICAL/HIGH
        KeyValidator->>KeyValidator: Verify private key matches
        alt Key validation fails
            KeyValidator-->>Wasm: Invalid key error
            Wasm-->>User: Throw validation error
        else Key validation succeeds
            KeyValidator-->>Wasm: Valid key
            Wasm->>Wasm: Register DPNS name
            Wasm-->>JsFacade: Success
            deactivate Wasm
        end
        deactivate KeyValidator
        JsFacade-->>User: Registration result
    end
    deactivate JsFacade
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • packages/js-evo-sdk/src/dpns/facade.ts — Review new public API method, ensure validation logic is comprehensive and error messages are appropriate
  • packages/wasm-sdk/src/dpns.rs — Verify key validation logic (purpose and security level checks) and private key matching via signer; confirm error handling with meaningful guidance
  • Test coverage — Confirm all validation edge cases are tested and positive path execution is verified

Poem

🐰 A new gateway opens wide,
With keys validated side by side,
AUTHENTICATION strong and true,
CRITICAL or HIGH—we'll see you through!
DPNS names now safer rise,
Beneath the rabbit's watchful eyes. 🔐

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.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Title Check ✅ Passed The pull request title "feat(sdk): add validation/tests for registerName publicKeyId parameter" clearly and accurately describes the primary change in the changeset. The title correctly identifies the feature scope (SDK), the action (adding validation and tests), and the specific aspect affected (registerName's publicKeyId parameter). While the changeset includes additional WASM SDK validation logic for key purpose, security level, and private key matching, the title's focus on the publicKeyId parameter represents the main user-facing API change in the JS SDK facade and corresponds to the test coverage added. The title is concise, specific enough for teammates to understand the primary change, and does not use vague terminology.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/dpns-key-validation

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.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 28, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@thephez thephez changed the title test: add validation tests for registerName publicKeyId parameter test: add validation/tests for registerName publicKeyId parameter Oct 28, 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: 0

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

82-141: Validation logic is correct and provides excellent error messages.

The key validation properly enforces DPNS requirements (AUTHENTICATION purpose, CRITICAL/HIGH security levels) and provides helpful guidance by listing suitable alternative keys.

Consider these minor refinements for more idiomatic Rust:

Lines 107-118: Replace the if-else and string concatenation with a match expression and format! macro:

-                    let level_name = if k.security_level() == SecurityLevel::CRITICAL {
-                        "CRITICAL"
-                    } else {
-                        "HIGH"
-                    };
-                    Some(
-                        String::from("  Key ")
-                            + &key_id.to_string()
-                            + ": "
-                            + level_name
-                            + " security level",
-                    )
+                    let level_name = match k.security_level() {
+                        SecurityLevel::CRITICAL => "CRITICAL",
+                        SecurityLevel::HIGH => "HIGH",
+                        _ => return None,
+                    };
+                    Some(format!("  Key {}: {} security level", key_id, level_name))
packages/js-evo-sdk/src/dpns/facade.ts (1)

60-81: Solid input validation with helpful error messages.

The validation logic correctly handles the common error cases (undefined, null, non-number, negative) and provides clear guidance about which keys are suitable for DPNS registration. This addresses the PR objective of providing early validation before cryptographic operations.

For completeness, you could add validation for NaN and Infinity, though these are unlikely in practice:

-    if (typeof publicKeyId !== 'number' || publicKeyId < 0) {
+    if (typeof publicKeyId !== 'number' || !Number.isFinite(publicKeyId) || publicKeyId < 0) {
       throw new Error(`publicKeyId must be a non-negative number, got: ${publicKeyId}`);
     }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f49390f and 6674a04.

📒 Files selected for processing (3)
  • packages/js-evo-sdk/src/dpns/facade.ts (1 hunks)
  • packages/js-evo-sdk/tests/unit/facades/dpns.spec.mjs (1 hunks)
  • packages/wasm-sdk/src/dpns.rs (2 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
packages/**/tests/**

📄 CodeRabbit inference engine (AGENTS.md)

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

Files:

  • packages/js-evo-sdk/tests/unit/facades/dpns.spec.mjs
**/*.rs

📄 CodeRabbit inference engine (CLAUDE.md)

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

Files:

  • packages/wasm-sdk/src/dpns.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/dpns.rs
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/dpns/facade.ts
🔇 Additional comments (4)
packages/wasm-sdk/src/dpns.rs (2)

5-7: LGTM! Imports support the new validation logic.

The imported traits and enums are necessary for the key validation functionality added below.


143-155: Excellent security validation!

Verifying that the private key matches the public key via signer.can_sign_with before proceeding prevents cryptographic failures and provides clear error messages early in the flow. This directly addresses the PR objective of catching errors before attempting to sign state transitions.

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

58-143: Excellent test coverage for publicKeyId validation!

The test suite comprehensively covers all edge cases:

  • Missing, undefined, and null values
  • Invalid types (string)
  • Invalid ranges (negative numbers)
  • Valid positive case

The error message assertions verify that users receive helpful guidance, directly supporting the PR objective of improving error messages for DPNS registration.

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

36-59: Outstanding documentation with clear security guidance!

The JSDoc provides comprehensive guidance that will help developers avoid the cryptic error described in the PR objectives. The explicit warning about key security levels and the practical example make the API much more developer-friendly.

@thephez thephez marked this pull request as ready for review October 28, 2025 19:35
@thephez thephez changed the title test: add validation/tests for registerName publicKeyId parameter feat: add validation/tests for registerName publicKeyId parameter Oct 28, 2025
@thephez thephez changed the title feat: add validation/tests for registerName publicKeyId parameter feat(sdk): add validation/tests for registerName publicKeyId parameter Oct 30, 2025
async registerName(args: { label: string; identityId: string; publicKeyId: number; privateKeyWif: string; onPreorder?: Function }): Promise<any> {
const { label, identityId, publicKeyId, privateKeyWif, onPreorder } = args;

// Validate inputs
Copy link
Collaborator

Choose a reason for hiding this comment

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

How this is possible? Typing is not allow it. Oh, when you use it form JS, not TypeScript?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes, it was from JS. Just trying to make things easier for people like me that don't know what they're doing 🤪 You can close the PR if it is a bad approach.

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