Skip to content

feat(sdk)!: pure DPNS and DashPay document builders shared with embedders - #4632

Draft
PastaPastaPasta wants to merge 2 commits into
v4.2-devfrom
feat/shared-dpns-dashpay-builders
Draft

feat(sdk)!: pure DPNS and DashPay document builders shared with embedders#4632
PastaPastaPasta wants to merge 2 commits into
v4.2-devfrom
feat/shared-dpns-dashpay-builders

Conversation

@PastaPastaPasta

Copy link
Copy Markdown
Member

Issue being fixed or feature implemented

Stacked on #4631 (review from feat(sdk) onward). Carries forward the pure-builder half of #4619, without that PR's request-driven FromProof<GetDocumentsRequest> verifier, which the SDK-first C++ embedding (dashpay/dash#7512, next PR in this series) no longer needs: the SDK retains the rich query it built and verifies against it, so no wire request is reconstructed from bytes.

dash-sdk's register_dpns_name and create_contact_request assemble DPNS and DashPay documents inline. An embedder that signs with a wallet-held key (Dash Core's platform GUI) needs the same assembly as a pure function over caller-supplied entropy, salt and ciphertexts, and must not reimplement it in C++.

What was done?

Pure document builders, in dash-platform-queries:

  • dpns_usernames::{build_dpns_preorder_document, build_dpns_domain_document, salted_domain_hash} and dashpay::build_contact_request_document, the assembly halves of dash-sdk's register_dpns_name / create_contact_request as pure functions. dash-sdk's networked flows now call them.
  • They reuse what exists: normalization is dpp's consensus convert_to_homograph_safe_chars (the crate's to_ascii_lowercase copy, which differed from the data trigger on non-ASCII input, is replaced by a re-export); the preorder commitment uses dpp::util::hash::hash_double; property names come from the dpns-contract / dashpay-contract constants; the DashPay byte bounds are read from the contract schema's DocumentPropertyType sizes. The domain builder rejects a label the contract pattern refuses before a preorder is paid for.
  • The entropy/document-id consistency check moves into dpp's DocumentCreateTransitionV0::from_document, so every create-transition caller (SDK, wasm, FFI, embedders) inherits it instead of remembering an opt-in helper; it fails with the same InvalidDocumentTransitionIdError Drive would return after the nonce bump. dash-sdk's private ensure_entropy_matches_document_id is removed.

How Has This Been Tested?

  • dash-platform-queries: 61 lib tests pass, including builder tests against the real DPNS/DashPay system contracts (preorder commitment matches the domain document's salt+label, id derivation, label-pattern rejection, schema byte-bound enforcement).
  • dpp: from_document_refuses_an_id_the_entropy_does_not_derive; the document_create_transition suites pass.
  • dash-sdk --lib: 185 pass. cargo fmt --check clean.
  • Not done here: a live-network run of register_dpns_name / send_contact_request; the on-wire behaviour is byte-identical by construction (assembly moved, not changed) and the unit tests pin the property maps. The C++ crate in the next PR pins the transitions built from these documents byte for byte against rs-dpp-generated vectors.

Breaking Changes

API shape on unreleased v4.2-dev (not on crates.io): dash_sdk::platform::dashpay::ContactRequestResult now carries the assembled document plus entropy instead of id / owner_id / properties. No consumer outside rs-sdk uses it. register_dpns_name now rejects a label the DPNS contract pattern refuses locally instead of after the preorder is broadcast.

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

@coderabbitai

coderabbitai Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

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.

cargo vendor --locked refused the workspace with two dual-source packages: serde-wasm-bindgen came from the QuantumExplorer fork (wasm-dpp) and the dashpay fork (wasm-sdk, wasm-dpp2) at once, and versioned-feature-core 1.0.0 came from crates.io (via grovedb-version) and from git (rs-platform-version). Offline build systems that vendor the workspace, such as Dash Core's depends packaging of the C++ embedding crate, cannot proceed past that error.

Point wasm-dpp at the dashpay fork, which is the QuantumExplorer branch plus the uint8array fix and the current wasm-bindgen pin, and point rs-platform-version at the crates.io release of versioned-feature-core, which is the same commit the git pin held (the repo's only substantive commit, published as 1.0.0 two days after the pin was written; src/lib.rs is byte-identical). The lockfile loses the two duplicate entries and nothing else changes.

Validated: cargo check for platform-version, dash-platform-queries, dash-sdk, rs-sdk-ffi and drive-abci on the host; wasm-dpp, wasm-sdk and wasm-dpp2 check for wasm32-unknown-unknown; the tests-rs-workspace transport-free guards still pass; cargo vendor --locked now succeeds (829 crates).
dash-platform-queries gains build_dpns_preorder_document / build_dpns_domain_document / salted_domain_hash (dpns_usernames) and build_contact_request_document (new dashpay module): the document-assembly halves of dash-sdk's register_dpns_name and create_contact_request as pure functions that take caller-supplied entropy, salt and ciphertexts and touch no network or randomness. dash-sdk's networked flows now call them, so an embedder that assembles its own transitions (the Dash Core platform GUI) and the SDK share one implementation.

The builders lean on what the codebase already has rather than re-deriving it: normalization is dpp's consensus convert_to_homograph_safe_chars (the crate's ASCII-only copy, whose non-ASCII behaviour differed from the data trigger's, is replaced by a re-export); the preorder commitment uses dpp::util::hash::hash_double; property names come from the dpns-contract / dashpay-contract constants; and the DashPay byte-array bounds (96 / 48-80 / 38-102) are read from the contract schema instead of being hard-coded. The DPNS domain builder rejects a label the contract's pattern refuses before a preorder is paid for.

The entropy/document-id consistency check moves into dpp's DocumentCreateTransitionV0::from_document, where every create-transition caller (SDK, wasm, FFI, embedders) inherits it instead of having to remember an opt-in helper; it refuses with the same InvalidDocumentTransitionIdError Drive would return after the nonce bump. dash-sdk's private ensure_entropy_matches_document_id and its tests are removed in favour of that.

API shape (unreleased v4.2-dev): ContactRequestResult now carries the assembled document plus entropy instead of id/owner_id/properties; send_contact_request no longer hand-rebuilds a DocumentV0.
@PastaPastaPasta
PastaPastaPasta force-pushed the build/vendor-locked-single-source branch from 05927f9 to 1e8f252 Compare September 8, 2026 21:16
@PastaPastaPasta
PastaPastaPasta force-pushed the feat/shared-dpns-dashpay-builders branch from 0631c07 to 5279114 Compare September 8, 2026 21:16
Base automatically changed from build/vendor-locked-single-source to v4.2-dev September 8, 2026 21:57
@github-actions github-actions Bot added this to the v4.2.0 milestone Sep 8, 2026
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.

1 participant