Repository navigation
fix(platform-wallet)!: check identity creation keys and funding in the Rust core - #5645
Claudius-Maginificent wants to merge 12 commits into
Conversation
…evel
DIP-11 requires a new identity to hold at least one authentication key at
each security level. The wallet registered AUTH keys at MASTER, CRITICAL and
HIGH only, and every host (FFI, Swift, Kotlin) kept its own copy of the slot
table.
rs-platform-wallet now owns the single creation layout
(`IdentityCreationKeyLayout`): AUTH MASTER/CRITICAL/HIGH and TRANSFER
CRITICAL at ids 0-3, the optional DashPay ENC/DEC pair at 4-5, and a new
AUTH/MEDIUM ECDSA_SECP256K1 key at the next free id (4, or 6 with DashPay).
Existing ids and derivation slots do not move. The FFI, the JNI bridge,
Swift and Kotlin read the layout from Rust and only marshal it.
Every identity-creating entry point (asset-lock registration, from
addresses, invitation claim, shielded pool) takes `IdentityCreationKeys`
instead of a raw key map. This pre-flight refuses, with a typed
`IdentityCreationKeysError`, a set that lacks an enabled AUTH key AT
MASTER, CRITICAL, HIGH and MEDIUM. It checks levels and structure, never
key types, so an ECDSA_HASH160 set plus a MEDIUM key passes.
Backward compatibility: the rule applies to new creations only. Discovery,
sync, signing and recovery of existing identities are untouched. The one
exemption is resuming a tracked registration asset lock
(`FromExistingAssetLock { consume_invitation_voucher: false }`) whose
persisted amount cannot pay for the DIP-11 key set at the current platform
version's fee schedule (computed with the versioned
`calculate_min_required_fee`). Such a lock was funded for the four
pre-DIP-11 keys, so it resumes with exactly those, at no extra fee, and the
exemption is logged at info with the outpoint. Rust decides it
(`IdentityWallet::resume_key_layout`, `creation_keys_for_funding`, and the
new `platform_wallet_resume_identity_key_layout` FFI); hosts never compare
amounts. A lock built first and funded for the full set, fresh funding and
invitation reclaims always get the DIP-11 check.
Known gap: an interrupted registration started after this change whose lock
was funded below the 5-key minimum is grandfathered too, since the tracked
lock records no provenance. Follow-up (option A): persist the creation
layout on the tracked lock in every persister (SQLite, SwiftData, Room).
Breaking for callers: `register_identity_with_funding`,
`register_from_addresses`, `claim_invitation` and
`shielded_identity_create_from_pool` take `IdentityCreationKeys`; the
derive/preview FFIs take an `IdentityCreationKeyLayoutFFI` instead of a key
count. Dash Evo Tool stops compiling: it calls
`register_identity_with_funding` with its own key map (no MEDIUM key) and
must add an AUTH/MEDIUM key or adopt `IdentityCreationKeyLayout`, then build
the keys with `IdentityWallet::creation_keys_for_funding`.
Swift and Kotlin changes are unbuilt (no Xcode or JDK on the build host).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…he exact legacy resume keys `register_identity_with_funding` now refuses a `FromWalletBalance` amount below the versioned minimum for its keys (`AssetLockInsufficientFunds`) before any lock is built or broadcast, and raises a drain's floor to it, mirroring the address-funding floor. A fresh registration built by this crate can therefore never turn into an underfunded lock that later resumes under the pre-DIP-11 exemption. The remaining gap is a lock built outside this path and funded below the DIP-11 minimum; the follow-up (persist the creation layout on the tracked lock) is unchanged. The exempt resume accepts exactly the four pre-DIP-11 keys (ids 0-3: AUTH MASTER, CRITICAL, HIGH, TRANSFER CRITICAL; any key type) and refuses any other set with `IdentityCreationKeysError::NotLegacyResumeLayout`, so a host that derives the wrong layout gets a typed error instead of signing a set the lock cannot fund. Rust also owns the creation minimums hosts used to copy: `IdentityWallet::identity_creation_min_funding_duffs` and `identity_creation_from_addresses_min_fees`, exposed through `platform_wallet_identity_creation_min_funding_duffs`, `platform_wallet_identity_creation_from_addresses_min_fees` (+ `_free`) and the matching JNI exports. The FFI registration and resume paths run the creation check before touching either signer. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… apps Swift and Kotlin drop their copies of the identity-create fee schedule (per-key cost, base cost, asset-lock base, address input cost, the dead 228k constant) and the minimum arithmetic built on them. The minimum funding and the address-funded fee per input count come from the new Rust queries; a failed query is shown and blocks submit instead of falling back to zero. Kotlin's input packing is capped at the protocol's maximum input count Rust reports. Swift parses a resume's outpoint before deriving or persisting any key and fails the submission on a malformed one, with no fresh-layout fallback. The new Swift and Kotlin resume-layout docs no longer split the existing resume docs, and the resume KDoc states that the layout comes from `resumeKeyLayout`. Swift and Kotlin are unbuilt (no Xcode or JDK on the build host). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 8 minutes. View limit details
No actionable comments were generated in the recent review.
|
| Layer / File(s) | Summary |
|---|---|
Key layouts and validation packages/rs-platform-wallet/src/wallet/identity/network/creation_keys.rs, packages/rs-platform-wallet/src/error.rs, packages/rs-platform-wallet/src/wallet/identity/network/mod.rs, packages/rs-platform-wallet/src/lib.rs |
Adds base and DashPay key layouts and IdentityCreationKeys validation. Construction checks required authentication keys at MASTER, CRITICAL, and HIGH, along with key IDs and enabled status. |
Layout fees and funding floors packages/rs-platform-wallet/src/wallet/identity/network/creation_keys.rs, packages/rs-platform-wallet/src/wallet/asset_lock/sync/tracking.rs, packages/rs-platform-wallet/src/util.rs, packages/rs-platform-wallet/src/wallet/platform_addresses/fund_from_asset_lock.rs, packages/rs-platform-wallet/src/test_support.rs |
Adds layout-based fee queries and funding checks. Wallet-balance and tracked-lock funding below the required amount is rejected. Drain-account funding receives a minimum that is at least the layout requirement. |
Wallet identity-creation APIs packages/rs-platform-wallet/src/wallet/identity/network/registration.rs, packages/rs-platform-wallet/src/wallet/identity/network/register_from_addresses.rs, packages/rs-platform-wallet/src/wallet/identity/network/invitation.rs, packages/rs-platform-wallet/src/wallet/platform_wallet.rs, packages/rs-platform-wallet/src/wallet/shielded/operations.rs |
Registration and invitation claims accept validated key sets. Address-funded registration builds its placeholder identity from the keys, and shielded identity creation converts the keys for the shield operation. The shielded operation is crate-visible. |
FFI key validation and error mapping packages/rs-platform-wallet-ffi/src/error.rs, packages/rs-platform-wallet-ffi/src/identity_registration_funded_with_signer.rs, packages/rs-platform-wallet-ffi/src/identity_registration_with_signer.rs, packages/rs-platform-wallet-ffi/src/invitation.rs, packages/rs-platform-wallet-ffi/src/shielded_send.rs, packages/rs-platform-wallet-ffi/src/test_fixtures.rs |
FFI paths convert decoded keys to validated key sets and return construction errors. Validation-unavailable errors map to ErrorUnknown; other key errors map to ErrorInvalidParameter. Tests cover invalid keys, unknown wallets, and rejection before signer use. |
Priority:
Estimated code review effort: 4 (Complex) | ~45 minutes
Change: Bug fix
Sequence Diagram(s)
sequenceDiagram
participant FFI as FFI registration
participant Wallet as IdentityWallet
participant Tracking as AssetLockManager
participant Signer as Registration signers
FFI->>Wallet: Validated keys and funding
Wallet->>Tracking: Read tracked lock amount
Tracking-->>Wallet: Amount or no tracked lock
Wallet->>Signer: Continue after funding check
Possibly related issues
- dashpay/platform#5592: The issue concerns invitation identity-creation key IDs. This PR routes invitation keys through
IdentityCreationKeysvalidation, including the MASTER AUTHENTICATION key at ID 0.
Possibly related PRs
- dashpay/platform#5471: Both changes modify invitation claims. This PR passes validated
IdentityCreationKeysto the claim operation. - dashpay/platform#5476: Both changes connect to asset-lock funding APIs. This PR adds identity-registration funding pre-flight checks.
- dashpay/platform#5460: Both changes modify identity-registration funding paths. This PR validates creation keys and enforces funding floors.
Suggested reviewers: shumkov, quantumexplorer
Merge Risk: 
Minimal · previous review b1ce7
-
No actionable issue was established in this PR. Coordinate its landing with the companion app changes as planned.
Pre-merge checks: 
4 · 
1
-
Failed checks: 1 warning Passed checks: 4 passedFull details: Docstring Coverage
-
Explanation
Docstring coverage is 63.33% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 30 functions across 19 files.
Resolution
Write docstrings for the functions missing them to satisfy the coverage threshold.
-
Finishing Touches: 💡 1
-
📝 Generate docstrings: 💡
-
- Commit to this branch
- Create a new PR
🧪 Generate unit tests (beta)
-
- Commit to this branch
- Create a new PR
-
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
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.
Comment @coderabbitai help to get the list of available commands.
|
⚡ Priority review — 1st in line, starts as soon as a slot frees (commit 5f17b3b) |
…o a stacked PR Split #5645 so this PR carries only the Rust core in rs-platform-wallet (canonical creation key layout, MEDIUM key, IdentityCreationKeys pre-flight, funding floor, amount-gated resume) plus the minimal FFI wiring the existing registration entry points need to compile against the new wallet API. Returned to their v5.1-dev state here and restored in the stacked bindings PR: - the identity_creation_key_layout FFI module (layout, minimum funding, address-funded minimum fees and their frees) and its golden files - platform_wallet_resume_identity_key_layout - the layout-based signatures of dash_sdk_derive_and_persist_identity_keys and platform_wallet_preview_identity_registration_key_set - the new JNI entry points and the layout-taking previewRegistrationKeySet - every Swift and Kotlin change Kept: the existing registration FFIs (address-funded, wallet-funded, resume, invitation claim, shielded create) build IdentityCreationKeys from the decoded keys and map the typed refusal to ErrorInvalidParameter, with the wiring tests that exercise them. Until the bindings PR lands, Swift and Kotlin still send four keys without a MEDIUM authentication key, so new identity creation in the example apps is refused by the pre-flight. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Split: this PR keeps the Rust core ( 🤖 Co-authored by Claudius the Magnificent AI Agent |
|
Waiting for bot review — thepastaclaw not yet. Wait for the missing reviews, or a writer can post |
thepastaclaw
left a comment
There was a problem hiding this comment.
Final validation — Phase 1 + Phase 2
The new DashPay layout creates seven keys, but both current protocol snapshots, including the latest v15 snapshot, still enforce a maximum of six keys. Such registrations are rejected by DPP before execution, so the primary DashPay creation path cannot succeed. The wallet also has non-blocking correctness gaps around resume affordability, legacy-resume provenance, and disabled key zero handling; wallet tests covering these changes remain queued.
🔴 1 blocking | 🟡 4 suggestion(s)
Review provenance
Source: reviewer 1: muse-spark-1.3-contributor (agent: phase1-reviewer, role: general); reviewer 2: muse-spark-1.3-contributor (agent: phase1-reviewer, role: rust-quality); reviewer 3: gpt-6.1-sol (agent: phase2-reviewer, role: general); reviewer 4: gpt-6.1-sol (agent: phase2-reviewer, role: architecture-layering); reviewer 5: gpt-6.1-sol (agent: phase2-reviewer, role: ffi-engineer); reviewer 6: gpt-6.1-sol (agent: phase2-reviewer, role: platform-versioning); reviewer 7: gpt-6.1-sol (agent: phase2-reviewer, role: rust-quality); reviewer 8: gpt-6.1-sol (agent: phase2-reviewer, role: security-auditor); final verifier: gpt-6.1-sol (agent: sol-verifier, role: final-verifier)
- Triage:
criticalbygpt-6.1-sol(effort low) — This is a large, intricate change to identity key handling and registration funding inrs-platform-wallet, directly affecting cryptographic keys, signatures, asset-lock construction, and funds movement. - Phase 1 reviewers:
muse-spark-1.3-contributor— general (completed, effort xhigh); agentphase1-reviewer,muse-spark-1.3-contributor— rust-quality (completed, effort xhigh); agentphase1-reviewer - Phase 1 model:
muse-spark-1.3-contributor— not quota-gated; passed overgemini-3.8-flash-high(antigravity quota lookup failed),glm-5.3-flash(not used above high effort; tier asks max) - Single stage: Phase 1 and Phase 2 reviewed this head side by side, with no blocker gate between them (triage tier)
- Fresh verifier:
gpt-6.1-sol— final-verifier; agentsol-verifier - Phase 2 reviewers:
gpt-6.1-sol— general (completed, effort xhigh); agentphase2-reviewer,gpt-6.1-sol— architecture-layering (completed, effort xhigh); agentphase2-reviewer,gpt-6.1-sol— ffi-engineer (completed, effort xhigh); agentphase2-reviewer,gpt-6.1-sol— platform-versioning (completed, effort xhigh); agentphase2-reviewer,gpt-6.1-sol— rust-quality (completed, effort xhigh); agentphase2-reviewer,gpt-6.1-sol— security-auditor (completed, effort xhigh); agentphase2-reviewer
🤖 Prompt for all review comments with AI agents
These findings are from an automated code review. Verify each finding against the current code and only fix it if needed.
In `packages/rs-platform-wallet/src/wallet/identity/network/creation_keys.rs`:
- [BLOCKING] packages/rs-platform-wallet/src/wallet/identity/network/creation_keys.rs:186-195: Seven-key DashPay layout exceeds the protocol identity key limit
`NewIdentityWithDashPayKeys` adds encryption and decryption keys at ids 4 and 5, then appends authentication/medium at id 6, producing seven keys. DPP's identity-creation structure validation rejects key sets larger than `platform_version.dpp.state_transitions.identities.max_public_keys_in_creation`; the v4 table selected by both the v14 and v15 platform snapshots still sets that limit to 6. Therefore every DashPay identity using this layout is rejected before registration. Update the appropriate versioned protocol limit and gate the layout until that limit is active, or keep the layout within the existing limit.
- [SUGGESTION] packages/rs-platform-wallet/src/wallet/identity/network/creation_keys.rs:491-503: Resume affordability is not checked against the submitted key set
`resume_exemption` compares the tracked amount only with the five-key `NewIdentity` minimum. If a tracked lock contains enough value for five keys but less than the fee for the actual supplied set, `creation_keys_for_funding` accepts that set as a normal identity creation, while `enforce_identity_create_floor` deliberately leaves `FromExistingAssetLock` unchanged. The wallet can then sign and submit a transition that DPP deterministically rejects for insufficient asset-lock funding. For every non-legacy existing-lock resume, compare the tracked amount with the fee computed from the actual validated keys before signing.
- [SUGGESTION] packages/rs-platform-wallet/src/wallet/identity/network/creation_keys.rs:491-503: Legacy resume exemption is based on amount rather than lock provenance
`resume_exemption` uses only the persisted amount and does not inspect the tracked lock's funding type or creation provenance. A low-value tracked non-registration lock can therefore be reported by `resume_key_layout` as an `AssetLockResume`; the later resolver rejects mismatched funding roles, but the host has already been instructed to derive the wrong four-key layout. More importantly, an externally created low-value lock tracked as an identity registration can be grandfathered into the four-key path even though it was not an interrupted pre-DIP-11 registration. The exemption should be restricted to explicitly identified legacy registration locks, with creation provenance persisted through the tracked-lock storage and persisters.
- [SUGGESTION] packages/rs-platform-wallet/src/wallet/identity/network/creation_keys.rs:615-619: Key zero validation accepts a disabled key
`check_key_zero` verifies only the purpose and security level. A caller can supply a disabled master authentication key at id 0 and another enabled master authentication key at a different id, allowing `new_identity` to pass because the per-level scan finds the second key. When the key map is converted into `IdentityPublicKeyInCreation`, `disabled_at` is not represented and the id-0 key is registered as enabled. Require key zero to have `disabled_at().is_none()` so the pre-flight cannot silently change the caller's disabled key into an enabled identity key.
- [SUGGESTION] packages/rs-platform-wallet/src/wallet/identity/network/creation_keys.rs:200-203: Avoid allocating all layout slots to count keys
`key_count` constructs the complete slot vector, including cloned contract bounds for the DashPay layout, only to obtain its length. This method feeds sizing and fee-related queries, so the allocation is unnecessary. Return the statically known count for each layout variant instead.
…IUM key A creation may carry at most max_public_keys_in_creation (6) keys, so the DashPay layout with a MEDIUM authentication key (7 keys) was refused by consensus, and no system contract accepts a MEDIUM signature anyway. - NewIdentity is keys 0-3 and NewIdentityWithDashPayKeys adds the DashPay pair at 4-5, exactly what hosts register today. - The pre-flight requires an AUTHENTICATION key at MASTER, CRITICAL and HIGH (key 0 MASTER) and refuses any disabled key, since a key in creation carries no disabled state. - The AssetLockResume layout and the amount-gated legacy resume exemption are gone: a resume re-derives the NewIdentity layout, which is now the same four keys. - The funding floor also covers a tracked lock being resumed or reclaimed: one that cannot pay for its keys is refused before the finality wait or any signing. An untracked lock is still left to the funding resolver. - Every layout is run through the dpp creation structure validation at the latest platform version, so a layout over the key limit fails a test. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WunYYjpfLux1ByK7fGF7SG
|
Waiting for bot review — thepastaclaw not yet. Wait for the missing reviews, or a writer can post |
thepastaclaw
left a comment
There was a problem hiding this comment.
Re-review — Final validation — Phase 1 + Phase 2
The Rust wallet now fixes the prior six-key layout, disabled-key, and tracked-lock affordability issues. However, IdentityCreationKeys::new_identity still accepts key maps that DPP deterministically rejects, allowing funding resolution and asset-lock construction before failure; this contradicts the PR's primary pre-lock validation guarantee. CI has no reported failed code checks, but several checks remain pending.
🔴 1 blocking | 🟡 2 suggestion(s) | 💬 2 nitpick(s)
2 finding(s) not shown inline (the lines are not part of this PR's diff)
💬 Nitpick: Stale placeholder-identity documentation after keys refactor
packages/rs-platform-wallet/src/wallet/identity/network/register_from_addresses.rs:36-40
The method summary says the caller constructs the placeholder Identity, but the signature now accepts validated IdentityCreationKeys and the wallet builds the placeholder at lines 100–105. The argument documentation was updated, so the summary is the remaining stale description of the old API contract.
/// This method is a thin wrapper over `put_with_address_funding`
/// plus `IdentityManager::add_identity`. The caller passes the
/// new identity's keys (validated by
/// [`IdentityCreationKeys::new_identity`]) and both signers; the
/// wallet builds the placeholder `Identity` and carries no key
/// material itself.
source: muse-spark-1.3-contributor (phase1-reviewer: general, rust-quality)
🟡 Suggestion: Document the public platform-wallet API break in the changelog
CHANGELOG.md:1-7
This PR changes the public registration APIs from raw key maps or identity arguments to IdentityCreationKeys and adds a public PlatformWalletError variant. The repository records breaking platform-wallet API migrations in the Unreleased changelog, but this change leaves CHANGELOG.md untouched. Add a migration note for downstream Rust consumers such as Dash Evo Tool; the PR description alone will not remain available as release documentation.
source: gpt-6.1-sol (phase2-reviewer: general, architecture-layering, ffi-engineer, platform-versioning, rust-quality, security-auditor)
1 carried-forward finding(s) already raised on this PR; not re-posting as new inline comments.
Review provenance
Source: reviewer 1: muse-spark-1.3-contributor (agent: phase1-reviewer, role: general); reviewer 2: gpt-6.1-sol (agent: phase2-reviewer, role: general); reviewer 3: muse-spark-1.3-contributor (agent: phase1-reviewer, role: rust-quality); reviewer 4: gpt-6.1-sol (agent: phase2-reviewer, role: architecture-layering); reviewer 5: gpt-6.1-sol (agent: phase2-reviewer, role: ffi-engineer); reviewer 6: gpt-6.1-sol (agent: phase2-reviewer, role: platform-versioning); reviewer 7: gpt-6.1-sol (agent: phase2-reviewer, role: rust-quality); reviewer 8: gpt-6.1-sol (agent: phase2-reviewer, role: security-auditor); final verifier: gpt-6.1-sol (agent: sol-verifier, role: final-verifier)
- Triage:
criticalbygpt-6.1-sol(effort low) — This is a large, intricate change to identity key handling, cryptographic signing inputs, asset-lock funding and registration flows in the Rust wallet core, directly affecting funds movement and key handling. - Phase 1 reviewers:
muse-spark-1.3-contributor— general (completed, effort xhigh); agentphase1-reviewer,muse-spark-1.3-contributor— rust-quality (completed, effort xhigh); agentphase1-reviewer - Phase 1 model:
muse-spark-1.3-contributor— not quota-gated; passed overgemini-3.8-flash-high(antigravity quota lookup failed),glm-5.3-flash(not used above high effort; tier asks max) - Single stage: Phase 1 and Phase 2 reviewed this head side by side, with no blocker gate between them (triage tier)
- Fresh verifier:
gpt-6.1-sol— final-verifier; agentsol-verifier - Phase 2 reviewers:
gpt-6.1-sol— general (completed, effort xhigh); agentphase2-reviewer,gpt-6.1-sol— architecture-layering (completed, effort xhigh); agentphase2-reviewer,gpt-6.1-sol— ffi-engineer (completed, effort xhigh); agentphase2-reviewer,gpt-6.1-sol— platform-versioning (completed, effort xhigh); agentphase2-reviewer,gpt-6.1-sol— rust-quality (completed, effort xhigh); agentphase2-reviewer,gpt-6.1-sol— security-auditor (completed, effort xhigh); agentphase2-reviewer
🤖 Prompt for all review comments with AI agents
These findings are from an automated code review. Verify each finding against the current code and only fix it if needed.
In `packages/rs-platform-wallet/src/wallet/identity/network/creation_keys.rs`:
- [BLOCKING] packages/rs-platform-wallet/src/wallet/identity/network/creation_keys.rs:226-255: Creation preflight accepts consensus-invalid key sets
`IdentityCreationKeys::new_identity` checks required authentication roles, key-zero placement, map/key-id consistency, and disabled state, but it does not run the versioned DPP creation-structure validation. A caller can therefore pass seven keys with all required roles, two MASTER keys, duplicate public-key data under different IDs, an invalid purpose/security-level combination, or key data with invalid size for its key type. The wrapper returns `Ok`, and `register_identity_with_funding` then proceeds to `enforce_identity_create_floor` and funding resolution, which can build or resume an asset lock before the resulting transition is rejected by Platform. The new layout test only validates the built-in layouts directly through DPP; it does not validate arbitrary maps accepted by `new_identity`. Invoke DPP's platform-version-aware structure validation from this preflight, or expose an equivalent owner-level validation result, before any funding resolver or signer is reached. Add regression coverage for over-limit, duplicate-data, multiple-master, and invalid purpose/security-level inputs.
- [SUGGESTION] packages/rs-platform-wallet/src/wallet/identity/network/creation_keys.rs:171-173: Avoid allocating all layout slots to count keys
(existing thread: https://github.com/dashpay/platform/pull/5645#discussion_r4405627517)
`key_count` constructs the complete slot vector solely to return its length. For the DashPay layout this also constructs and clones the contract-bound document-type strings. The slot table should remain the source for callers that need metadata, but this count-only helper can avoid materializing it; the allocation is small and not blocking, but the method is explicitly documented as a fee-sizing helper.
In `packages/rs-platform-wallet/src/wallet/identity/network/registration.rs`:
- [NITPICK] packages/rs-platform-wallet/src/wallet/identity/network/registration.rs:187-189: Stale `keys_map` reference in placeholder comment
The registration argument is now named `keys` and has type `IdentityCreationKeys`, but the comment still refers to a `keys_map` deep clone. This makes the comment describe an identifier and ownership model that no longer exists.
In `packages/rs-platform-wallet/src/wallet/identity/network/register_from_addresses.rs`:
- [NITPICK] packages/rs-platform-wallet/src/wallet/identity/network/register_from_addresses.rs:36-40: Stale placeholder-identity documentation after keys refactor
The method summary says the caller constructs the placeholder `Identity`, but the signature now accepts validated `IdentityCreationKeys` and the wallet builds the placeholder at lines 100–105. The argument documentation was updated, so the summary is the remaining stale description of the old API contract.
In `CHANGELOG.md`:
- [SUGGESTION] CHANGELOG.md:1-7: Document the public platform-wallet API break in the changelog
This PR changes the public registration APIs from raw key maps or identity arguments to `IdentityCreationKeys` and adds a public `PlatformWalletError` variant. The repository records breaking platform-wallet API migrations in the Unreleased changelog, but this change leaves `CHANGELOG.md` untouched. Add a migration note for downstream Rust consumers such as Dash Evo Tool; the PR description alone will not remain available as release documentation.
…et-dip11-identity-key-layout Conflict: packages/rs-platform-wallet/src/lib.rs re-exports, kept both the identity creation key types and PreparedDashPayPayment. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WunYYjpfLux1ByK7fGF7SG
…ation would refuse IdentityCreationKeys::new_identity takes the platform version and runs dpp's versioned identity-create structure validation after the wallet's own checks, so a key set over the creation limit, with duplicate key data, a second MASTER key, a purpose at a disallowed level, or a wrongly sized hash key is refused before any asset lock is built, waited on or signed. The FFI reads the version from the wallet, so an unknown wallet handle now reports NotFound ahead of a key-set fault. identity_create_from_shielded_pool becomes pub(crate), closing the one way around the pre-flight. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WunYYjpfLux1ByK7fGF7SG
|
Waiting for bot review — thepastaclaw not yet. Wait for the missing reviews, or a writer can post |
thepastaclaw
left a comment
There was a problem hiding this comment.
Re-review — Final validation — Phase 1 + Phase 2
The new DPP structure preflight and funding checks cover the main asset-lock paths, but the validated key wrapper does not retain or recheck the protocol version used for validation. A native caller can validate keys under an older protocol version and then submit them through a newer wallet, allowing funding resolution and signing before Platform rejects the transition. Address-funded and shielded creation paths also miss specific preflight checks. CI currently shows Kotlin tests and policy/PR Hygiene checks still pending or in progress, with no failed code check reported.
🔴 1 blocking | 🟡 3 suggestion(s) | 💬 1 nitpick(s)
2 finding(s) not shown inline (the lines are not part of this PR's diff)
🟡 Suggestion: Invitation claims bypass the versioned identity-creation funding floor
packages/rs-sdk/src/platform/dashpay/invitation.rs:852-879
IdentityWallet::claim_invitation now validates the key wrapper but converts it back to a raw map and delegates to Sdk::claim_invitation, which only validates key shape and does not compare the fetched voucher output with the versioned identity-creation fee for those keys. MIN_INVITATION_DUFFS is a fixed creation-time floor rather than the selected protocol fee, so an externally supplied or legacy voucher, or a voucher used after a higher fee schedule is active, can still reach proof construction and signing before Platform rejects it. After selecting the voucher output, check its amount against the same versioned fee calculation before constructing or submitting the claim.
source: gpt-6.1-sol (phase2-reviewer: general, architecture-layering, ffi-engineer, platform-versioning, rust-quality, security-auditor)
💬 Nitpick: Stale placeholder-identity documentation after keys refactor
packages/rs-platform-wallet/src/wallet/identity/network/register_from_addresses.rs:36-40
The method introduction still says that the caller constructs the placeholder Identity, but the signature now accepts IdentityCreationKeys and the method constructs the placeholder internally at lines 100–105. The argument documentation was updated, so the preceding description should be brought into agreement with the new ownership model.
/// This method is a thin wrapper over `put_with_address_funding`
/// plus `IdentityManager::add_identity`. The caller supplies the
/// validated keys and both signers; the wallet builds the placeholder
/// [`Identity`] from those keys and carries no key material.
source: muse-spark-1.3-contributor (phase1-reviewer: general); gpt-6.1-sol (phase2-reviewer: general, architecture-layering, platform-versioning)
Review provenance
Source: reviewer 1: muse-spark-1.3-contributor (agent: phase1-reviewer, role: general); reviewer 2: muse-spark-1.3-contributor (agent: phase1-reviewer, role: rust-quality); reviewer 3: gpt-6.1-sol (agent: phase2-reviewer, role: general); reviewer 4: gpt-6.1-sol (agent: phase2-reviewer, role: architecture-layering); reviewer 5: gpt-6.1-sol (agent: phase2-reviewer, role: ffi-engineer); reviewer 6: gpt-6.1-sol (agent: phase2-reviewer, role: platform-versioning); reviewer 7: gpt-6.1-sol (agent: phase2-reviewer, role: rust-quality); reviewer 8: gpt-6.1-sol (agent: phase2-reviewer, role: security-auditor); final verifier: gpt-6.1-sol (agent: sol-verifier, role: final-verifier)
- Triage:
criticalbygpt-6.1-sol(effort low) — This is a large, intricate change to identity key handling, cryptographic signing inputs, asset-lock funding validation, and FFI registration paths, directly affecting funds movement and key security in files such as creation_keys.rs and identity registration functions. - Phase 1 reviewers:
muse-spark-1.3-contributor— general (completed, effort xhigh); agentphase1-reviewer,muse-spark-1.3-contributor— rust-quality (completed, effort xhigh); agentphase1-reviewer - Phase 1 model:
muse-spark-1.3-contributor— not quota-gated; passed overgemini-3.8-flash-high(antigravity quota lookup failed),glm-5.3-flash(not used above high effort; tier asks max) - Single stage: Phase 1 and Phase 2 reviewed this head side by side, with no blocker gate between them (triage tier)
- Fresh verifier:
gpt-6.1-sol— final-verifier; agentsol-verifier - Phase 2 reviewers:
gpt-6.1-sol— general (completed, effort xhigh); agentphase2-reviewer,gpt-6.1-sol— architecture-layering (completed, effort xhigh); agentphase2-reviewer,gpt-6.1-sol— ffi-engineer (completed, effort xhigh); agentphase2-reviewer,gpt-6.1-sol— platform-versioning (completed, effort xhigh); agentphase2-reviewer,gpt-6.1-sol— rust-quality (completed, effort xhigh); agentphase2-reviewer,gpt-6.1-sol— security-auditor (completed, effort xhigh); agentphase2-reviewer
🤖 Prompt for all review comments with AI agents
These findings are from an automated code review. Verify each finding against the current code and only fix it if needed.
In `packages/rs-platform-wallet/src/wallet/identity/network/creation_keys.rs`:
- [BLOCKING] packages/rs-platform-wallet/src/wallet/identity/network/creation_keys.rs:249-294: Creation-key validation is not bound to the wallet's active protocol version
`IdentityCreationKeys::new_identity` validates against the caller-supplied `PlatformVersion`, but `IdentityCreationKeys` stores only the keys. The registration methods subsequently trust the wrapper without checking it against `self.sdk.version()`. For example, the existing test demonstrates that a 19-byte `ECDSA_HASH160` key is accepted under protocol 13 and rejected by the current validation rules; a native caller can construct that wrapper with protocol 13 and pass it to a wallet using a newer protocol. The wallet can then enforce funding, resolve or resume an asset lock, and reach signing before the SDK's later structure check rejects the transition. Retain the validation version in the wrapper and verify it at every write boundary, or rerun the owner-level validation using the wallet's active version before funding or signing.
In `packages/rs-platform-wallet/src/wallet/identity/network/register_from_addresses.rs`:
- [SUGGESTION] packages/rs-platform-wallet/src/wallet/identity/network/register_from_addresses.rs:87-104: Preflight address-funded registrations against the versioned fee floor
`register_from_addresses` accepts the validated key wrapper but immediately constructs the placeholder identity and calls `put_with_address_funding_fetching_nonces`. The new `identity_creation_from_addresses_min_fees` helper is advisory only and is not used by this write path. The SDK constructor signs the identity and address witnesses before `ensure_valid_state_transition_structure`; it does not reject an input map whose credits cannot cover the versioned fee for the actual input count and optional output. Add an owner-level preflight using the actual keys, input count, and output before either signer is reached.
- [NITPICK] packages/rs-platform-wallet/src/wallet/identity/network/register_from_addresses.rs:36-40: Stale placeholder-identity documentation after keys refactor
The method introduction still says that the caller constructs the placeholder `Identity`, but the signature now accepts `IdentityCreationKeys` and the method constructs the placeholder internally at lines 100–105. The argument documentation was updated, so the preceding description should be brought into agreement with the new ownership model.
In `packages/rs-platform-wallet-ffi/src/shielded_send.rs`:
- [SUGGESTION] packages/rs-platform-wallet-ffi/src/shielded_send.rs:956-973: Shielded identity creation omits shielded-only key restrictions from preflight
The shielded FFI entry point now calls the generic `IdentityCreationKeys::new_identity` validator, but shielded identity creation has additional consensus restrictions. Drive's versioned shielded-proof validation rejects contract-group-bound keys and keys carrying budgets or expiries, while the generic creation validator accepts those fields and the shared decoder permits them. The wallet reserves shielded notes before `build_identity_create_from_shielded_pool_transition` runs, so an invalid key set can consume note-reservation work and only fail later. Add a shielded-specific owner-level validation context or method and cover both contract-bound and limited keys before note reservation.
In `packages/rs-sdk/src/platform/dashpay/invitation.rs`:
- [SUGGESTION] packages/rs-sdk/src/platform/dashpay/invitation.rs:852-879: Invitation claims bypass the versioned identity-creation funding floor
`IdentityWallet::claim_invitation` now validates the key wrapper but converts it back to a raw map and delegates to `Sdk::claim_invitation`, which only validates key shape and does not compare the fetched voucher output with the versioned identity-creation fee for those keys. `MIN_INVITATION_DUFFS` is a fixed creation-time floor rather than the selected protocol fee, so an externally supplied or legacy voucher, or a voucher used after a higher fee schedule is active, can still reach proof construction and signing before Platform rejects it. After selecting the voucher output, check its amount against the same versioned fee calculation before constructing or submitting the claim.
…form-wallet-dip11-identity-key-layout
… own version IdentityCreationKeys::new_identity let a Rust caller pick the platform version, so a key set could pass at one version while the wallet built an asset lock for a Platform running another. It becomes pub(crate), and the new IdentityWallet::identity_creation_keys reads the version from the wallet's SDK, as the funding floor does. All FFI entry points use it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WunYYjpfLux1ByK7fGF7SG
…'s current version Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WunYYjpfLux1ByK7fGF7SG
…et-dip11-identity-key-layout
|
Waiting for bot review — thepastaclaw not yet. Wait for the missing reviews, or a writer can post |
thepastaclaw
left a comment
There was a problem hiding this comment.
Re-review — Final validation — Phase 1 + Phase 2
The PR improves identity-creation key validation and asset-lock funding checks, but two blocking preflight gaps remain. Validated key wrappers are not bound to the protocol version used at the write boundary, and the preflight accepts V1 key formats on protocol versions where those formats are inactive; both cases can proceed to funding and signing before Platform rejects the transition. Invitation and address-funded paths also bypass the new versioned funding checks, and the breaking API migration is absent from the changelog. CI has no reported code failure, but several checks remain queued or in progress.
🔴 2 blocking | 🟡 3 suggestion(s) | 💬 1 nitpick(s)
3 finding(s) not shown inline (the lines are not part of this PR's diff)
🟡 Suggestion: Invitation claims bypass the versioned identity-creation funding floor
packages/rs-sdk/src/platform/dashpay/invitation.rs:862-879
The wallet now validates the submitted keys, but Sdk::claim_invitation still only performs its legacy key-0 check and then fetches the voucher proof. It never compares the voucher's credit output with calculate_min_required_fee for the actual keys and current protocol version before constructing and signing the claim at lines 889-917. The fixed MIN_INVITATION_DUFFS policy may exceed today's minimum, but it is not tied to the versioned, key-dependent fee schedule and can leave legacy or externally created low-value vouchers proceeding to a late Platform rejection. Apply the same owner-level funding admission after the voucher output is known and before proof submission or signing.
source: muse-spark-1.3-contributor (phase1-reviewer: general, rust-quality); gpt-6.1-sol (phase2-reviewer: general, architecture-layering, rust-quality)
🟡 Suggestion: Document the public platform-wallet API break in the changelog
CHANGELOG.md:1-7
The Unreleased changelog has no migration note for the breaking platform-wallet API changes. Registration, invitation-claim, and shielded identity-creation methods now require IdentityCreationKeys; direct construction is restricted; and the public error surface changed. The PR description records these changes, but downstream Rust, FFI, and JNI consumers need the migration guidance in the durable release documentation.
source: muse-spark-1.3-contributor (phase1-reviewer: general, rust-quality); gpt-6.1-sol (phase2-reviewer: general, architecture-layering)
💬 Nitpick: Stale placeholder-identity documentation after keys refactor
packages/rs-platform-wallet/src/wallet/identity/network/register_from_addresses.rs:36-40
The method now accepts keys: IdentityCreationKeys and constructs the placeholder Identity internally at lines 100-105, but this paragraph still says that the caller constructs the placeholder identity. That describes the pre-refactor API and can mislead callers integrating the breaking change.
/// This method is a thin wrapper over `put_with_address_funding`
/// plus `IdentityManager::add_identity`. The caller supplies the
/// validated keys and both signers; the placeholder identity is built
/// here, and the wallet struct carries no key material.
source: muse-spark-1.3-contributor (phase1-reviewer: general, rust-quality); gpt-6.1-sol (phase2-reviewer: general)
2 carried-forward finding(s) already raised on this PR; not re-posting as new inline comments.
Review provenance
Source: reviewer 1: muse-spark-1.3-contributor (agent: phase1-reviewer, role: general); reviewer 2: muse-spark-1.3-contributor (agent: phase1-reviewer, role: rust-quality); reviewer 3: gpt-6.1-sol (agent: phase2-reviewer, role: general); reviewer 4: gpt-6.1-sol (agent: phase2-reviewer, role: architecture-layering); reviewer 5: gpt-6.1-sol (agent: phase2-reviewer, role: ffi-engineer); reviewer 6: gpt-6.1-sol (agent: phase2-reviewer, role: platform-versioning); reviewer 7: gpt-6.1-sol (agent: phase2-reviewer, role: rust-quality); reviewer 8: gpt-6.1-sol (agent: phase2-reviewer, role: security-auditor); final verifier: gpt-6.1-sol (agent: sol-verifier, role: final-verifier)
- Triage:
criticalbygpt-6.1-sol(effort low) — This is a large, intricate change to identity creation key validation, funding and asset-lock registration across Rust wallet and FFI code, directly affecting key handling and funds movement in the listed identity registration and creation-key paths. - Phase 1 reviewers:
muse-spark-1.3-contributor— general (completed, effort xhigh); agentphase1-reviewer,muse-spark-1.3-contributor— rust-quality (completed, effort xhigh); agentphase1-reviewer - Phase 1 model:
muse-spark-1.3-contributor— not quota-gated; passed overgemini-3.8-flash-high(antigravity quota lookup failed),glm-5.3-flash(not used above high effort; tier asks max) - Single stage: Phase 1 and Phase 2 reviewed this head side by side, with no blocker gate between them (triage tier)
- Fresh verifier:
gpt-6.1-sol— final-verifier; agentsol-verifier - Phase 2 reviewers:
gpt-6.1-sol— general (completed, effort xhigh); agentphase2-reviewer,gpt-6.1-sol— architecture-layering (completed, effort xhigh); agentphase2-reviewer,gpt-6.1-sol— ffi-engineer (completed, effort xhigh); agentphase2-reviewer,gpt-6.1-sol— platform-versioning (completed, effort xhigh); agentphase2-reviewer,gpt-6.1-sol— rust-quality (completed, effort xhigh); agentphase2-reviewer,gpt-6.1-sol— security-auditor (completed, effort xhigh); agentphase2-reviewer
🤖 Prompt for all review comments with AI agents
These findings are from an automated code review. Verify each finding against the current code and only fix it if needed.
In `packages/rs-platform-wallet/src/wallet/identity/network/creation_keys.rs`:
- [BLOCKING] packages/rs-platform-wallet/src/wallet/identity/network/creation_keys.rs:280-289: Preflight accepts version-14 key formats on older wallet protocol versions
`new_identity` converts the caller's keys and invokes `validate_identity_public_keys_structure` at the wallet's current protocol version. At protocol 13 this dispatches the V0 validator, which checks counts, duplicate keys, master keys, and purpose/level combinations but does not reject a V1 key format or its limits. DPP separately makes V1 creation keys active only from protocol 14, through `StateTransition::active_version_range`. Consequently, a V1 key can pass this new preflight on a protocol-13 wallet, after which registration can resolve an asset lock and reach signing before the transition is rejected as inactive by Platform. Add an owner-level active-format validation to the preflight rather than duplicating the activation rule in the wallet.
- [BLOCKING] packages/rs-platform-wallet/src/wallet/identity/network/creation_keys.rs:238-295: Creation-key validation is not bound to the wallet's active protocol version
(existing thread: https://github.com/dashpay/platform/pull/5645#discussion_r4422653365)
`IdentityCreationKeys` stores only the key map, while `identity_creation_keys` validates it using the SDK version at the time the wrapper is created. The wrapper is public and can later be passed to another wallet, or retained while an auto-detected SDK ratchets to a newer protocol version. For example, the 19-byte HASH160 fixture accepted at protocol 13 is rejected by the newer structure rules. The asset-lock registration path then computes the funding floor and resolves or resumes the lock before the later transition construction uses the newer SDK version and rejects the keys. Store the validation version in `IdentityCreationKeys` and verify it at each write boundary, or rerun the owner-level validation against the current wallet version immediately before funding and signing.
In `packages/rs-sdk/src/platform/dashpay/invitation.rs`:
- [SUGGESTION] packages/rs-sdk/src/platform/dashpay/invitation.rs:862-879: Invitation claims bypass the versioned identity-creation funding floor
The wallet now validates the submitted keys, but `Sdk::claim_invitation` still only performs its legacy key-0 check and then fetches the voucher proof. It never compares the voucher's credit output with `calculate_min_required_fee` for the actual keys and current protocol version before constructing and signing the claim at lines 889-917. The fixed `MIN_INVITATION_DUFFS` policy may exceed today's minimum, but it is not tied to the versioned, key-dependent fee schedule and can leave legacy or externally created low-value vouchers proceeding to a late Platform rejection. Apply the same owner-level funding admission after the voucher output is known and before proof submission or signing.
In `CHANGELOG.md`:
- [SUGGESTION] CHANGELOG.md:1-7: Document the public platform-wallet API break in the changelog
The Unreleased changelog has no migration note for the breaking platform-wallet API changes. Registration, invitation-claim, and shielded identity-creation methods now require `IdentityCreationKeys`; direct construction is restricted; and the public error surface changed. The PR description records these changes, but downstream Rust, FFI, and JNI consumers need the migration guidance in the durable release documentation.
In `packages/rs-platform-wallet/src/wallet/identity/network/register_from_addresses.rs`:
- [NITPICK] packages/rs-platform-wallet/src/wallet/identity/network/register_from_addresses.rs:36-40: Stale placeholder-identity documentation after keys refactor
The method now accepts `keys: IdentityCreationKeys` and constructs the placeholder `Identity` internally at lines 100-105, but this paragraph still says that the caller constructs the placeholder identity. That describes the pre-refactor API and can mislead callers integrating the breaking change.
- [SUGGESTION] packages/rs-platform-wallet/src/wallet/identity/network/register_from_addresses.rs:87-118: Preflight address-funded registrations against the versioned fee floor
(existing thread: https://github.com/dashpay/platform/pull/5645#discussion_r4422653374)
`register_from_addresses` accepts the validated key wrapper but never uses `identity_creation_from_addresses_min_fees` before constructing the placeholder and calling the SDK path that signs. The SDK passes the caller-supplied amounts directly into the transition and always deducts the fee from input 0, so an input amount below the versioned minimum for the actual input count can be rejected locally before signer invocation even though on-chain balance fetching is still needed for the full affordability check. Wire the existing versioned helper into this write path for that deterministic lower-bound check.
TL;DR
The wallet's Rust core now decides which keys a new identity gets and how much it must be funded with. Before anything is signed or broadcast, it checks that the key set can create a working identity and that the asset lock can pay for it. New identities get the same keys they get today. Existing identities and interrupted registrations keep working.
This PR can land on its own. The current Swift and Kotlin apps already send key sets that pass the new check. The stacked PR #5647 then moves the layout and minimum-funding rules out of the apps and into Rust.
User story
As a wallet user, I want the wallet to refuse an identity it can't create before it locks my DASH, so that I'm not left with a stuck registration or an identity that can't sign the actions I need.
Scenario
Base flow
Actual behavior
Expected behavior
Detailed discussion
Layout (
rs-platform-walletwallet/identity/network/creation_keys.rs; every key is ECDSA_SECP256K1 with key id = DIP-9 key index). These are the keys the v5.1-dev hosts register today, unchanged:No AUTHENTICATION/MEDIUM key. DIP-11 asks for an authentication key at every level, MEDIUM included. We leave MEDIUM out:
max_public_keys_in_creationis 6 in every protocol version, and the DashPay layout already uses all six slots. A MEDIUM key would have made 7, which consensus refuses.The constant
REQUIRED_AUTHENTICATION_LEVELScarries a comment explaining this.Pre-flight.
IdentityWallet::identity_creation_keysbuilds the validated key set, and every identity-creating entry point takes it instead of a raw key map. It requires:It then runs dpp's
validate_identity_public_keys_structureat the wallet SDK's current protocol version, so no consensus rule is copied here and a caller cannot choose another version. An unpinned SDK's version can lag the network until its first proved response. The difference only matters to a host sending a wrong-size hash key or a key-limit violation, which the Swift, Kotlin and Dash Evo Tool key sets do not contain. Key types stay free, so caller-built HASH160 sets pass, provided their data is a 20-byte hash where that version requires it. Secp256k1 key data is left to proof of possession.Errors are typed (
IdentityCreationKeysError). A refusal maps toErrorInvalidParameterover FFI, andStructureRefusednames the consensus reasons.ValidationUnavailablemeans the validation could not run, which is not the caller's fault, and maps toErrorUnknown.Funding floor (
register_identity_with_funding). The minimum iscalculate_min_required_feefor the actual keys:FromExistingAssetLock, both resume and invitation-voucher reclaim): refused when the persisted amount is below the minimum, before the finality wait or any signing.claim_invitationdoes not go through this path.Host-facing minimums.
identity_creation_min_funding_duffsandidentity_creation_from_addresses_min_feesreturn the minimum for each layout, so the stacked PR can drop the hosts' fee constants.Consensus check of the layouts. A test runs every layout through dpp's
validate_identity_public_keys_structure, which drive-abci applies to asset-lock, address-funded and shielded identity creates. The same test runs the address-fundedIdentityCreateFromAddressesTransition::validate_structure. Both run atPlatformVersion::latest(). A control case proves one key over the limit fails withMaxIdentityPublicKeyLimitReached.FFI in this PR. A minimal shim only:
platform-wallet-ffiruns the pre-flight before either signer is touched, and after the wallet handle lookup, because the version comes from the wallet's SDK. An unknown handle therefore returnsNotFoundahead of a key-set fault; on the shielded path an unknown wallet or a manager without shielded configured returnsErrorWalletOperationfirst. The host-facing layout and minimum queries are in #5647.Placement follows
layer-ownership: the decision lives inrs-platform-wallet, and the bindings only marshal.Breaking Changes
register_identity_with_funding,register_from_addresses,claim_invitationandshielded_identity_create_from_pooltakeIdentityCreationKeysinstead of a raw key map. Dash Evo Tool stops compiling on its next platform bump. It must build its key set withwallet.identity().identity_creation_keys(keys). Its current HASH160 key set passes unchanged.IdentityCreationKeysErrorgainsStructureRefusedandValidationUnavailable, and no longer derivesClone,PartialEqorEq.wallet::shielded::operations::identity_create_from_shielded_poolispub(crate); useIdentityWallet, which takes the validated key set.PlatformWalletError::IdentityCreationKeysvariant.ErrorInvalidParameter).ErrorAssetLockInsufficientFunds).Testing
New Rust tests cover:
register_identity_with_fundingfor fresh and resumed funding, before any signer is reached;should_pass_dpp_creation_structure_validation_for_every_layout);Verification:
cargo clippy -p platform-wallet -p platform-wallet-ffi -p rs-unified-sdk-jni --all-targets --features platform-wallet-ffi/shielded -- -D warningsis clean.cargo nextest run -p platform-wallet -p platform-wallet-ffi --features platform-wallet-ffi/shielded: 2297 passed, 8 skipped.Swift and Kotlin were not built locally (no Xcode or JDK on the build host). This PR does not touch them.
Checklist
🤖 Generated with Claude Code
https://claude.ai/code/session_01WunYYjpfLux1ByK7fGF7SG
🤖 Co-authored by Claudius the Magnificent AI Agent
PR Hygiene ·
5f17b3brs-platform-wallet-ffi(packages/rs-platform-wallet-ffi/src/error.rs,packages/rs-platform-wallet-ffi/src/identity_registration_funded_with_signer.rs,packages/rs-platform-wallet-ffi/src/identity_registration_with_signer.rsand 3 more) — HashEngineering or ZocoLini or llbartekll or romchornyirs-platform-wallet(packages/rs-platform-wallet/src/error.rs,packages/rs-platform-wallet/src/lib.rs,packages/rs-platform-wallet/src/test_support.rsand 10 more) — HashEngineering or ZocoLini or llbartekll or romchornyiWhen every merge requirement is met, the
PR Hygienecheck passes. Reviewer limits do not block merging; other required GitHub checks and protections still apply.Summary by CodeRabbit