Skip to content

fix(dpp)!: make platform/orchard address decoders network-agnostic#3781

Merged
lklimek merged 6 commits into
v3.1-devfrom
fix/platform-address-hrp-network-decode-p
Jun 16, 2026
Merged

fix(dpp)!: make platform/orchard address decoders network-agnostic#3781
lklimek merged 6 commits into
v3.1-devfrom
fix/platform-address-hrp-network-decode-p

Conversation

@Claudius-Maginificent

@Claudius-Maginificent Claudius-Maginificent commented Jun 2, 2026

Copy link
Copy Markdown
Collaborator

Issue being fixed or feature implemented

PlatformAddress::from_bech32m_string / OrchardAddress::from_bech32m_string returned (Self, Network), deriving Network from the bech32m HRP. The HRP tdash is shared by Testnet/Devnet/Regtest (hrp_for_network is non-injective), so the decoder could not truthfully determine the network and always returned Network::Testnet for tdash.

On devnet (paloma) a valid devnet platform address decoded as Testnet, tripping the wrong-network guard in the wallet's shielded_unshield_to and blocking unshield-to-transparent.

Note — strict network comparison is an easy trap. Because the bech32m HRP tdash is shared by Testnet/Devnet/Regtest, code that decodes a platform address to a specific Network and then compares it for strict equality against the wallet's network silently rejects valid devnet/regtest addresses — they decode as Testnet, so Testnet != Devnet fails and the address is refused. Example of this pattern on v3.1-dev (the strict guard this PR removes): platform_wallet.rs L628–L640. Option P avoids the trap entirely: the decoder no longer derives a network from the HRP, and the wallet compares HRP class instead — so a tdash address is accepted by any non-mainnet wallet.

What was done?

Option P — network-agnostic decoders. A PlatformAddress/OrchardAddress carries no network internally (network is supplied only at to_bech32m_string(network) encode time), so:

  • from_bech32m_string(s) -> Result<Self, ProtocolError> validates the HRP is a recognized platform HRP (dash/tdash) but makes no network claim.
  • The wrong-network safety check moved to the one caller that needs it, shielded_unshield_to, via a private testable helper check_recipient_hrp(recipient, network) that compares the recipient's HRP class against the wallet network (PlatformAddress::hrp_for_network): rejects mainnet dash1… on a tdash wallet, accepts devnet tdash1… on a devnet wallet, and reports a clear "not a platform address" error for non-platform HRPs (e.g. bc1…).
  • No new public API.
  • Also included: test(dpp): feature-gate signing_tests behind shielded-client — fixes a pre-existing v3.1-dev compile failure where signing_tests imported crate::shielded::builder (only present under shielded-client), which broke cargo test -p dpp.

How Has This Been Tested?

  • cargo test -p dpp --lib address_funds → 161 passed (incl. test_bech32m_invalid_hrp_fails)
  • cargo test -p dpp --lib --features shielded-client address_funds::orchard → 8 passed
  • cargo test -p platform-wallet --features shielded check_recipient_hrp_tests → 9 passed (mainnet→testnet/devnet REJECT, devnet→devnet ACCEPT, testnet→testnet ACCEPT, tdash cross-acceptance, uppercase ACCEPT, bc1… not-a-platform-address, no-separator/empty Err)
  • cargo check + cargo clippy -- -D warnings clean on dpp, platform-wallet (--features shielded), wasm-dpp2 (changed files)
  • Live (paloma devnet): devnet platform address now accepted by shielded_unshield_to (previously rejected as wrong-network).

Breaking Changes

from_bech32m_string return type changes (Self, Network)Self (hence fix(dpp)!). It is not in any prelude — external consumers reach it only via dpp::address_funds::PlatformAddress/OrchardAddress, so the break is a loud compile error, never silent.

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

🤖 Co-authored by Claudius the Magnificent AI Agent

Summary by CodeRabbit

  • Breaking Changes

    • Address parsing no longer returns decoded network data alongside the address; it now returns only the decoded address.
  • New Features

    • Added mainnet vs non-mainnet classification for platform bech32m addresses based on HRP validation.
  • Improvements

    • Wallet shielded transfers now validate the recipient’s network class before decoding, producing clearer network-mismatch errors.
    • WASM bech32m address parsing behavior now matches the updated address parsing API.

lklimek and others added 2 commits June 2, 2026 15:44
`signing_tests` for `ShieldFromAssetLockTransition` imports
`crate::shielded::builder`, which only exists under `shielded-client`,
but the module was gated on `state-transition-signing` + `core_key_wallet`
only. With `core_key_wallet` on but `shielded-client` off, the dpp lib-test
harness failed to compile (`unresolved import crate::shielded::builder`).

Add `feature = "shielded-client"` to the module's gate (both the `mod`
declaration and the file's inner `#![cfg]`) so the test only compiles when
its `builder` dependency is available.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
`PlatformAddress::from_bech32m_string` and
`OrchardAddress::from_bech32m_string` previously returned `(Self, Network)`,
deriving the Network from the bech32m HRP. That value was untruthful: the
`tdash` HRP is shared by Testnet, Devnet, and Regtest, so the decoder
hardcoded `tdash → Testnet` and mis-reported devnet/regtest addresses as
Testnet — which broke devnet (a devnet platform address tripped a
wrong-network guard).

A `PlatformAddress`/`OrchardAddress` is network-agnostic internally; the
network is supplied only at `to_bech32m_string(network)` encode time. Both
decoders now make no network claim: they validate the HRP is a recognized
platform HRP (`dash`/`tdash`) and return just `Self`.

The wrong-network safety check moves to the one caller that needs it,
`platform-wallet::shielded_unshield_to`, as an HRP-class comparison: the
recipient's HRP (segment before the final bech32 `1` separator) is matched
case-insensitively against `hrp_for_network(wallet.network)`, catching e.g.
a mainnet `dash1…` address pasted into a `tdash` wallet. `shielded_withdraw_to`
uses a separate Base58 core-address parser and is unaffected.

BREAKING: `from_bech32m_string` return type changed `(Self, Network)` → `Self`.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8af7ab9e-72d4-43a9-81aa-ee0deafccc6b

📥 Commits

Reviewing files that changed from the base of the PR and between 0d64951 and f983080.

📒 Files selected for processing (3)
  • packages/rs-dpp/src/address_funds/orchard_address.rs
  • packages/rs-dpp/src/address_funds/platform_address.rs
  • packages/rs-platform-wallet/src/wallet/platform_wallet.rs
🚧 Files skipped from review as they are similar to previous changes (3)
  • packages/rs-platform-wallet/src/wallet/platform_wallet.rs
  • packages/rs-dpp/src/address_funds/orchard_address.rs
  • packages/rs-dpp/src/address_funds/platform_address.rs

📝 Walkthrough

Walkthrough

OrchardAddress::from_bech32m_string and PlatformAddress::from_bech32m_string are changed to return only the decoded address, dropping Network from the return type while still validating the HRP. A new PlatformAddress::is_mainnet_bech32m helper performs HRP-only mainnet classification. Wallet code is updated to call this classifier before decoding. WASM bindings and tests are adjusted accordingly.

Changes

Network-agnostic address parsing with wallet-level validation

Layer / File(s) Summary
Address parsing and HRP classification
packages/rs-dpp/src/address_funds/orchard_address.rs, packages/rs-dpp/src/address_funds/platform_address.rs
classify_platform_hrp validator added to check HRP against recognized platform HRPs (dash, tdash). OrchardAddress::from_bech32m_string and PlatformAddress::from_bech32m_string now return Result<Self, ProtocolError> (no Network), validating the HRP without deriving a network. PlatformAddress::is_mainnet_bech32m added to classify mainnet vs non-mainnet by HRP alone. FromStr implementation updated to use new parsing return type.
Address parsing tests
packages/rs-dpp/src/address_funds/orchard_address.rs, packages/rs-dpp/src/address_funds/platform_address.rs
OrchardAddress mainnet and testnet bech32m roundtrip tests updated to decode via new single-value return. PlatformAddress roundtrip tests (P2PKH/P2SH for mainnet/testnet), invalid HRP test, case-insensitivity test, and edge-case tests (all-zeros/all-ones) updated to remove tuple destructuring. Comprehensive is_mainnet_bech32m test suite added covering mainnet truth, non-mainnet across all tdash networks, case-insensitivity, and error cases.
Wallet-level HRP/network validation
packages/rs-platform-wallet/src/wallet/platform_wallet.rs
shielded_unshield_to now calls a new check_recipient_hrp helper (via PlatformAddress::is_mainnet_bech32m) before decoding, replacing the previous post-decode network comparison. PlatformWalletError::ShieldedBuildError is returned on network-class mismatch. Documentation updated to reflect network-agnostic decoder and pre-check validation. Feature-gated tests cover devnet/testnet acceptance, mainnet rejection, uppercase, and malformed inputs.
WASM binding updates
packages/wasm-dpp2/src/platform_address/address.rs
TryFrom<&str> and the fromBech32m WASM constructor updated to accept the network-agnostic parse result directly, removing the prior (addr, _network) tuple destructuring.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • dashpay/platform#3843: Changes shielded_unshield_to recipient network validation in the same file to use HRP-based classification rather than decoded Network equality, directly overlapping with this PR's wallet-level guard.

Suggested reviewers

  • shumkov
  • QuantumExplorer
  • llbartekll

🐇 No more tuples to carry around,
Just the address, pure and sound.
HRP checks the gate before you pass,
is_mainnet_bech32m checks fast!
The rabbit hops with lighter load,
One clean result along the road. 🌿

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: making platform/orchard address decoders network-agnostic by removing Network return values from their bech32m parsing functions.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/platform-address-hrp-network-decode-p

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.

lklimek and others added 2 commits June 2, 2026 16:32
…ctor

Restores the truthful subset of the network information that the
network-agnostic `from_bech32m_string` decoder no longer returns. Per
DIP-0018, a bech32m platform address carries no network byte and the prefix
`tdash` is shared by Testnet/Devnet/Regtest, so the only network fact
recoverable from an address string is mainnet vs non-mainnet.

`PlatformAddress::is_mainnet_bech32m(s) -> Result<bool, ProtocolError>`
classifies by HRP alone (no payload decode): `dash` → Ok(true), `tdash` →
Ok(false), a non-platform HRP or a malformed/separator-less string → Err.
Comparison is case-insensitive (bech32m permits all-uppercase).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…is_mainnet_bech32m

`check_recipient_hrp` no longer inlines the bech32 HRP extraction and
HRP-class comparison; it delegates network classification (and
malformed/non-platform rejection) to `PlatformAddress::is_mainnet_bech32m`,
making the dpp detector the single source of truth. The guard reduces to
`addr_is_mainnet != (network == Network::Mainnet)` — exactly the previous
HRP-class check (mainnet wallet requires `dash`, any non-mainnet wallet
requires `tdash`).

Behavior-preserving: the existing `check_recipient_hrp_tests` (network
mismatch, tdash cross-acceptance, uppercase, non-platform, missing-separator,
empty) pass unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Comment thread packages/rs-dpp/src/address_funds/platform_address.rs Outdated
Comment thread packages/rs-dpp/src/address_funds/orchard_address.rs Outdated
Comment thread packages/rs-dpp/src/address_funds/orchard_address.rs Outdated
Comment thread packages/rs-dpp/src/address_funds/platform_address.rs Outdated
@lklimek lklimek marked this pull request as ready for review June 2, 2026 15:16
@lklimek lklimek requested a review from QuantumExplorer as a code owner June 2, 2026 15:16
@lklimek

lklimek commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

@coderabbitai review all

@coderabbitai

coderabbitai Bot commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

@lklimek Sure, I'll kick off a full review of all the changes in this PR now!

✅ Actions performed

Full review triggered.

@thepastaclaw

thepastaclaw commented Jun 2, 2026

Copy link
Copy Markdown
Collaborator

✅ Review complete (commit f983080)

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Updates platform/orchard bech32m address decoding to be network-agnostic (since tdash is shared by Testnet/Devnet/Regtest), and moves the network-class guard to the wallet caller that needs it.

Changes:

  • Change PlatformAddress::from_bech32m_string / OrchardAddress::from_bech32m_string to return only the decoded address (no derived Network) and validate only that HRP is a recognized platform HRP.
  • Add PlatformAddress::is_mainnet_bech32m and use it in rs-platform-wallet to enforce mainnet vs non-mainnet recipient HRP class in shielded_unshield_to, with targeted unit tests.
  • Feature-gate shield_from_asset_lock_transition signing tests behind shielded-client; update wasm wrapper call sites for the new decoder return type.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
packages/wasm-dpp2/src/platform_address/address.rs Update wasm bindings to handle from_bech32m_string returning only PlatformAddress.
packages/rs-platform-wallet/src/wallet/platform_wallet.rs Move wrong-network enforcement to wallet via check_recipient_hrp + add tests.
packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_from_asset_lock_transition/signing_tests.rs Gate signing tests behind shielded-client feature to avoid compile failures.
packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_from_asset_lock_transition/mod.rs Gate inclusion of signing tests behind shielded-client feature.
packages/rs-dpp/src/address_funds/platform_address.rs Make platform bech32m decoder network-agnostic; add is_mainnet_bech32m helper + tests; update parsing/tests for new return type.
packages/rs-dpp/src/address_funds/orchard_address.rs Make orchard bech32m decoder network-agnostic; update tests for new return type.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/rs-platform-wallet/src/wallet/platform_wallet.rs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/rs-dpp/src/address_funds/platform_address.rs`:
- Around line 318-338: The is_mainnet_bech32m function currently only splits on
the last '1' and checks HRP, allowing malformed strings to pass; update
is_mainnet_bech32m to fully validate the bech32m string before classifying the
HRP: attempt to decode the input using the bech32 decoder (or the project’s
existing bech32/bech32m utility) and ensure the variant is Bech32m and the data
part is non-empty, then check hrp.eq_ignore_ascii_case(PLATFORM_HRP_MAINNET) or
PLATFORM_HRP_TESTNET and return Ok(true/false); on any decode/validation failure
return ProtocolError::DecodingError (keep check_recipient_hrp behavior unchanged
except it will now see validated addresses).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e5e0798f-49eb-4fcc-a3f2-093fc94f6e9f

📥 Commits

Reviewing files that changed from the base of the PR and between e01b6a3 and 71052a4.

📒 Files selected for processing (6)
  • packages/rs-dpp/src/address_funds/orchard_address.rs
  • packages/rs-dpp/src/address_funds/platform_address.rs
  • packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_from_asset_lock_transition/mod.rs
  • packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_from_asset_lock_transition/signing_tests.rs
  • packages/rs-platform-wallet/src/wallet/platform_wallet.rs
  • packages/wasm-dpp2/src/platform_address/address.rs

Comment thread packages/rs-dpp/src/address_funds/platform_address.rs Outdated
@codecov

codecov Bot commented Jun 2, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 71.20%. Comparing base (e2039e5) to head (f983080).

Additional details and impacted files
@@            Coverage Diff            @@
##           v3.1-dev    #3781   +/-   ##
=========================================
  Coverage     71.20%   71.20%           
=========================================
  Files            20       20           
  Lines          2837     2837           
=========================================
  Hits           2020     2020           
  Misses          817      817           
Components Coverage Δ
dpp ∅ <ø> (∅)
drive ∅ <ø> (∅)
drive-abci ∅ <ø> (∅)
sdk ∅ <ø> (∅)
dapi-client ∅ <ø> (∅)
platform-version ∅ <ø> (∅)
platform-value ∅ <ø> (∅)
platform-wallet ∅ <ø> (∅)
drive-proof-verifier ∅ <ø> (∅)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@thepastaclaw thepastaclaw left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Code Review

Pinned commit 71052a4 is a small, behavior-preserving refactor that routes check_recipient_hrp through the existing PlatformAddress::is_mainnet_bech32m helper to centralize network classification. The diff is a clean inversion (17 added / 29 removed) and the existing check_recipient_hrp_tests continue to cover mismatch, tdash cross-acceptance, uppercase, non-platform HRP, missing-separator and empty cases. The convergent finding from Codex/Claude about is_mainnet_bech32m doing HRP-only classification rather than full bech32m decoding targets a function added in an earlier commit (7a02728) whose docstring explicitly documents the HRP-only contract — the pinned commit does not introduce that behavior and the address is still rejected by the subsequent from_bech32m_string decode for any HRP-class-matching but malformed input.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (1)
packages/rs-dpp/src/address_funds/platform_address.rs (1)

318-338: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Validate the full address before classifying its HRP.

This helper only splits on the last 1, so malformed inputs like dash1! or dash1 still classify as mainnet. Downstream, shielded_unshield_to can then return a bogus network-mismatch error before the real decoder gets a chance to reject the invalid address. Reuse the strict bech32m parser here instead of HRP-only string splitting. (docs.rs)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/rs-dpp/src/address_funds/platform_address.rs` around lines 318 -
338, The is_mainnet_bech32m helper currently only splits on the last '1' which
misclassifies malformed inputs; replace the HRP-only split with a strict bech32
decoder (use bech32::decode) inside is_mainnet_bech32m to fully validate the
address, ensure the variant is Bech32m, extract the decoded HRP, then compare it
against PLATFORM_HRP_MAINNET and PLATFORM_HRP_TESTNET and return
Ok(true)/Ok(false) or a ProtocolError::DecodingError on invalid variant/decoding
failures; keep error messages descriptive and use the existing function name and
HRP constants to locate the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/rs-dpp/src/address_funds/orchard_address.rs`:
- Around line 100-102: OrchardAddress::from_bech32m_string currently uses
bech32::decode which accepts both Bech32 and Bech32m checksums; change it to use
the strict Bech32m API (e.g., bech32::primitives::CheckedHrpString /
decode_bech32m or equivalent decode_bech32m helper) so only Bech32m-checked
inputs succeed, map primitive decode errors into ProtocolError::DecodingError
like the current code, and update/add a unit test ensuring a Bech32
(non-Bech32m) encoded address is rejected by from_bech32m_string.

In `@packages/rs-dpp/src/address_funds/platform_address.rs`:
- Around line 259-262: PlatformAddress::from_bech32m_string currently calls
bech32::decode(s) which accepts both Bech32 and Bech32m checksums; change the
implementation to explicitly validate the checksum is Bech32m (rather than any
Bech32 variant) before proceeding. Replace the bech32::decode call in
from_bech32m_string with the bech32 primitives API that enforces Bech32m (e.g.,
the CheckedHrpstring/Bech32m-specific decode path) and map any non-Bech32m or
decode failures to ProtocolError::DecodingError so plain Bech32-checked strings
are rejected.

---

Duplicate comments:
In `@packages/rs-dpp/src/address_funds/platform_address.rs`:
- Around line 318-338: The is_mainnet_bech32m helper currently only splits on
the last '1' which misclassifies malformed inputs; replace the HRP-only split
with a strict bech32 decoder (use bech32::decode) inside is_mainnet_bech32m to
fully validate the address, ensure the variant is Bech32m, extract the decoded
HRP, then compare it against PLATFORM_HRP_MAINNET and PLATFORM_HRP_TESTNET and
return Ok(true)/Ok(false) or a ProtocolError::DecodingError on invalid
variant/decoding failures; keep error messages descriptive and use the existing
function name and HRP constants to locate the change.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a96225bb-7095-4d18-8312-24685dbb767e

📥 Commits

Reviewing files that changed from the base of the PR and between e01b6a3 and 71052a4.

📒 Files selected for processing (6)
  • packages/rs-dpp/src/address_funds/orchard_address.rs
  • packages/rs-dpp/src/address_funds/platform_address.rs
  • packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_from_asset_lock_transition/mod.rs
  • packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_from_asset_lock_transition/signing_tests.rs
  • packages/rs-platform-wallet/src/wallet/platform_wallet.rs
  • packages/wasm-dpp2/src/platform_address/address.rs

Comment thread packages/rs-dpp/src/address_funds/orchard_address.rs
Comment thread packages/rs-dpp/src/address_funds/platform_address.rs
@github-actions

github-actions Bot commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

✅ DashSDKFFI.xcframework built for this PR.

SwiftPM (host the zip at a stable URL, then use):

.binaryTarget(
  name: "DashSDKFFI",
  url: "https://your.cdn.example/DashSDKFFI.xcframework.zip",
  checksum: "7ee5be1d943795694d3ecc9080a3288fd182f7953e0785150b8d2ef22abb95fa"
)

Xcode manual integration:

  • Download 'DashSDKFFI.xcframework' artifact from the run link above.
  • Drag it into your app target (Frameworks, Libraries & Embedded Content) and set Embed & Sign.
  • If using the Swift wrapper package, point its binaryTarget to the xcframework location or add the package and place the xcframework at the expected path.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Comment thread packages/rs-dpp/src/address_funds/platform_address.rs Outdated
…ess-hrp-network-decode-p

# Conflicts:
#	packages/rs-platform-wallet/src/wallet/platform_wallet.rs

@thepastaclaw thepastaclaw left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Code Review

Cumulative verification at head 0d64951 confirms the PR's network-agnostic decoder refactor, the wallet-side check_recipient_hrp guard delegating to PlatformAddress::is_mainnet_bech32m, the WASM binding updates, and the signing-tests gate are all intact and correct. The only PR-side delta since prior commit 71052a4 is a merge with v3.1-dev plus one new test (hrp_is_shared_across_all_non_mainnet_networks in platform_address.rs) documenting the tdash-HRP sharing invariant — directly aligned with the PR's stated goal. Prior review found no in-scope issues; no carried-forward findings, and no new defects in the latest delta or cumulatively at the current head. All six agents and CodeRabbit returned zero findings.

… drop double-prefix error

A. is_mainnet_bech32m now calls bech32::decode() instead of rsplit_once('1'),
   so malformed strings like "dash1!" no longer return Ok(true) — the data
   part and checksum are fully validated before the HRP is inspected.

B. Extracted classify_platform_hrp() as a pub(crate) free function that is the
   single source of truth for HRP validation. Both from_bech32m_string
   implementations (PlatformAddress and OrchardAddress) and is_mainnet_bech32m
   delegate to it, eliminating the duplicated inline if-chain.

C. Removed the "invalid platform address: " prefix from is_mainnet_bech32m's
   error messages; check_recipient_hrp already wraps with that prefix once, so
   the previous code produced double-prefixed messages like
   "invalid platform address: Decoding Error - invalid platform address: ...".
   The final user-facing string is now clean and non-redundant.

D. Trimmed the from_bech32m_string doc comments in both platform_address.rs and
   orchard_address.rs: removed the cross-reference to to_bech32m_string, added
   a reference to is_mainnet_bech32m as the network-guard entry point.

Updated tests: constructed valid bech32m strings for non-platform HRP cases
(replacing the previously-used "bc1qexampledata" which now fails checksum
before HRP classification); updated separator-error assertions to match
bech32::decode's actual error messages; added dash1! regression test.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

@thepastaclaw thepastaclaw left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Code Review

Cumulative verification at head f983080 confirms the PR's network-agnostic decoder refactor is intact and correct: classify_platform_hrp is properly factored as a pub(crate) helper and consumed by both PlatformAddress::from_bech32m_string and OrchardAddress::from_bech32m_string; is_mainnet_bech32m is now strict via a full bech32::decode (replacing the prior pre-1 HRP sniff) and its tests were updated accordingly; check_recipient_hrp continues to compare HRP class (mainnet vs non-mainnet) rather than equating Testnet/Devnet/Regtest. Prior review at 0d64951 found no in-scope issues, so there are no carried-forward prior findings; the latest delta introduces no new defects, and all six agents plus CodeRabbit returned zero findings.

@lklimek lklimek merged commit 565676f into v3.1-dev Jun 16, 2026
33 of 34 checks passed
@lklimek lklimek deleted the fix/platform-address-hrp-network-decode-p branch June 16, 2026 07:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants