Skip to content

chore: merge v1.0-dev into e2e#666

Merged
PastaPastaPasta merged 89 commits intodashpay:e2efrom
thepastaclaw:e2e
Feb 26, 2026
Merged

chore: merge v1.0-dev into e2e#666
PastaPastaPasta merged 89 commits intodashpay:e2efrom
thepastaclaw:e2e

Conversation

@thepastaclaw
Copy link
Copy Markdown
Collaborator

Merges latest v1.0-dev into the e2e branch to resolve conflicts and bring it up to date.

Conflicts resolved:

  • Cargo.toml — merged duplicate [features] sections
  • tests/e2e/navigation.rs + tests/e2e/wallet_flows.rs — deleted (consolidated earlier in e2e)
  • tests/kittest/main.rs — kept both mod interactions and mod message_banner

cargo check passes clean.

PastaPastaPasta and others added 30 commits February 11, 2026 22:29
Added local DB cache lookup and Platform profile fetching for identity
IDs in contact requests, so incoming requests show display names/usernames
instead of raw identity IDs, and outgoing requests show recipient names.

Task: 7.2a

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Load contact data from local DB on screen creation (dashpay_contacts,
  dashpay_profiles, contact_private_info tables)
- Trigger FetchContactProfile backend task on screen arrival for fresh
  Platform data
- Save contact info edits to both local DB (immediately) and Platform
  (via DashPayTask::UpdateContactInfo with encrypted data)
- Handle ContactProfile, ContactInfoUpdated, and ContactsWithInfo
  task results
- Replace non-functional Remove/Block Contact buttons with
  informational text
- Use DashColors semantic constants instead of inline Color32 values

Task: 7.2b
Replace mock "alice.dash" contact name in SendPaymentScreen with
actual DB lookup. Implement load_payment_history() to query the
dashpay_payments table. Update LoadPaymentHistory backend handler
to return real DB records with resolved contact names.

Task: 7.2c
Added created_at field to Contact struct, populated from DB StoredContact.
Implemented SearchFilter::Recent (7-day window) and SortOrder::DateAdded
(newest first) which previously had TODO stubs.

Task: 7.2e

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Previously, load_contacts() fetched each contact's DashPay profile and
DPNS username sequentially (2N network round-trips for N contacts).
Now processes contacts in chunks of 10 using futures::join_all, running
all fetches within each chunk concurrently. Reduces total fetch time
by roughly 10x for large contact lists.

Task: 7.2g

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace DashPayResult sub-enum references with flat
BackendTaskSuccessResult variants that exist on v1.0-dev.
Replace DashColors::WARNING_ORANGE with inline Color32.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The SearchFilter::Recent and SortOrder::DateAdded options existed in code
but were missing from the combo box dropdowns, making them unreachable.

Addresses CodeRabbit review feedback on PR dashpay#564.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…er screen refresh

Log identity-load failures with tracing::warn instead of silently
swallowing them via unwrap_or_default().

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

- Replace guard-then-unwrap with match/let-else in all 8 token screens
- Move identity UI removal after successful DB deletion
- Add backend security level validation for identity key purposes
- Show user-facing error message on identity deletion failure

Co-authored-by: PastaClaw <thepastaclaw@users.noreply.github.com>
Merges v1.0-dev into feat/dashpay-contacts-improvements.

Conflict in contacts.rs: kept PR's parallelized profile fetching
structure but applied the publicMessage field fix from dashpay#582
(publicMessage is the correct DashPay contract field, not bio).
* refactor(context): replace RwLock<Sdk> with ArcSwap<Sdk>

Sdk is internally thread-safe (Arc, ArcSwapOption, atomics) and all
methods take &self. The RwLock was adding unnecessary contention across
backend tasks.

Using ArcSwap instead of plain Sdk because reinit_core_client_and_sdk()
needs to atomically swap the entire Sdk instance when config changes.
ArcSwap provides lock-free reads with atomic swap for the rare write.

Suggested-by: lklimek

* fix: address CodeRabbit review findings for ArcSwap migration

- Fix import ordering: move arc_swap::ArcSwap before crossbeam_channel
- Remove redundant SDK loads in load_identity_from_wallet, register_dpns_name,
  and load_identity — use the sdk parameter already passed to these functions
- Fix stale TODO referencing removed sdk.read().unwrap() API
- Rename sdk_guard → sdk in transfer, withdraw_from_identity, and
  refresh_loaded_identities_dpns_names (no longer lock guards)
- Pass &sdk to run_platform_info_task from dispatch site instead of
  reloading internally
- Fix leftover sdk.write() call in context_provider.rs (RwLock remnant)
- Add missing Color32 import in wallets dialogs

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

* refactor: address remaining CodeRabbit review feedback on ArcSwap migration

- Move SDK load outside for loop in refresh_loaded_identities_dpns_names.rs
  so it's loaded once for the batch instead of on each iteration
- Update stale TODO comment in default_platform_version() to reflect that
  this is a free function with no sdk access

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

* refactor: consolidate double read-lock on spv_context_provider

Clone the SPV provider in a single lock acquisition, then bind app
context on the clone instead of locking twice.

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

---------

Co-authored-by: PastaClaw <thepastaclaw@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…hpay#597)

* refactor: remove unused Insight API references

The `insight_api_url` field in `NetworkConfig` and its associated
`insight_api_uri()` method were never used in production code (both
marked `#[allow(dead_code)]`). Remove the field, method, config
entries, env example lines, and related tests.

https://claude.ai/code/session_01HWPmCJHT8KTZGP9bFiksjn

* refactor: remove unused `show_in_ui` field from NetworkConfig

The `show_in_ui` field was defined on `NetworkConfig` and serialized in
`save()`, but never read by any production code to control network
visibility. Remove the field, its serialization, env example lines,
and test references.

https://claude.ai/code/session_01HWPmCJHT8KTZGP9bFiksjn

* fix: add missing `Color32` import in wallet dialogs

https://claude.ai/code/session_01HWPmCJHT8KTZGP9bFiksjn

---------

Co-authored-by: Claude <noreply@anthropic.com>
* build: remove snap version

* build: add Flatpak packaging and CI workflow

Add Flatpak build manifest, desktop entry, AppStream metadata, and
GitHub Actions workflow for building and distributing Flatpak bundles.
Uses freedesktop 25.08 runtime with rust-stable and llvm21 extensions.
No application source code changes required - works in SPV mode by default.

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

* build: address review findings for Flatpak packaging

- Pin GitHub Actions to commit SHAs for supply chain security
- Upgrade softprops/action-gh-release from v1 to v2.2.2
- Remove redundant --socket=x11 (fallback-x11 suffices)
- Remove duplicate tag trigger preventing double builds on release
- Remove duplicate env vars inherited from top-level build-options
- Add Flatpak build artifacts to .gitignore
- Add bugtracker URL to AppStream metainfo
- Remove deprecated <categories> from metainfo (use .desktop instead)
- Add Terminal=false and Keywords to desktop entry
- Add disk space check after SDK install in CI
- Rename artifact to include architecture suffix

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

* build: simplify CI workflows for Linux-only releases

- Remove "Free disk space" step from flatpak and release workflows
- Remove Windows and macOS builds from release workflow
- Use "ubuntu" runner image instead of pinned versions
- Clean up unused matrix.ext references

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

* build: attach to existing releases instead of creating new ones

- Replace release-creating job with attach-to-release (only on release event)
- Add 14-day retention for build artifacts
- On tag push or workflow_dispatch, only upload artifacts (no release)

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

* revert: restore release.yml to original v1.0-dev version

The release workflow changes were out of scope for the Flatpak PR.

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

* fix: address CodeRabbit review comments

- Fix CRLF line endings in Flatpak manifest (convert to LF)
- Set app_id on ViewportBuilder to match desktop StartupWMClass
- Use --locked flag for reproducible cargo builds in Flatpak
- Rename --repo=repo to --repo=flatpak-repo to match .gitignore
- Add architecture note for protoc x86_64 binary

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

* docs: add Flatpak install instructions to README

Add a dedicated section for installing via Flatpak on Linux,
clarify that prerequisites are only needed for building from source,
and rename "Installation" to "Build from Source" for clarity.

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

* fix: match StartupWMClass to Flatpak app_id

Use reverse-DNS format org.dash.DashEvoTool to match the
Wayland app_id set via ViewportBuilder::with_app_id().

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

* fix: use ** glob for branch trigger to match feat/flatpak

Single * doesn't match path separators in GitHub Actions branch filters.

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

* feat: add aarch64 Flatpak build and caching to CI

- Add matrix strategy for parallel x86_64 and aarch64 builds
- Patch protoc URL/sha256 per architecture at build time
- Cache .flatpak-builder directory keyed on arch + manifest + lockfile
- Pin actions/cache to SHA

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

* fix: convert desktop and metainfo files to LF line endings

Flatpak builder validates desktop files and rejects CRLF line endings.

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

* build: cancel in-progress Flatpak builds on new push

Add concurrency group keyed on git ref so a new push cancels
any running build for the same branch or release.

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

* fix: address PR review findings for Flatpak packaging

- Remove unnecessary --filesystem=xdg-config/dash-evo-tool:create
  (Flatpak already redirects XDG_CONFIG_HOME to sandbox)
- Add categories and keywords to AppStream metainfo for discoverability
- Update README with both x86_64/aarch64 install commands, uninstall
  instructions, and Flatpak data path note
- Clarify aarch64 comment in manifest to reference CI sed patching

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

* chore: workflow timeout and perms

* fix: move permissions to job level in Flatpak workflow

Step-level permissions are not valid in GitHub Actions. Move
contents: write to the job level where it is needed for release
attachment.

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

* build: cache Cargo registry and target in Flatpak CI

Bind-mount host-side cargo-cache and cargo-target directories into the
Flatpak build sandbox so CARGO_HOME and target/ persist across builds.
Uses split restore/save with cleanup of incremental and registry/src
(similar to Swatinem/rust-cache).

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

* fix: scope cargo cache bind-mount sed to build-args only

The previous sed matched --share=network in both finish-args and
build-args, corrupting finish-args. Use a sed range to only target
the build-args section.

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

* Apply suggestions from code review

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…-safety

fix: identity & token screen safety and validation
…rovements

feat: DashPay contacts improvements
* fix(wallets): prevent duplicate main account labels

* fix(wallets): align BIP44 validation between lifecycle and UI (CodeRabbit)
lklimek and others added 28 commits February 23, 2026 14:03
…ashpay#615)

Update dashpay/platform dependency from d6f4eb9a to b445b6f0e0bd4863
(3.0.1 → 3.1.0-dev.1). Remove the [patch] section that pinned
rust-dashcore crates to a separate rev, as the new platform commit
resolves them correctly on its own.

https://claude.ai/code/session_015AD2pCWoJdV2VDydcqFHPG

Co-authored-by: Claude <noreply@anthropic.com>
…pay#614)

* fix: address issue 612 error-handling inconsistencies

* fix: replace remaining expect() with FromSqlConversionFailure in identity loading

Address CodeRabbit nitpick: the wallet seed hash conversion in the
identity loading path (get_wallets) still used .expect() which would
panic on corrupted data. Replace with the same FromSqlConversionFailure
+ CorruptedBlobError pattern used for the other three conversions.

---------

Co-authored-by: PastaClaw <thepastaclaw@users.noreply.github.com>
)

Co-authored-by: PastaClaw <thepastaclaw@users.noreply.github.com>
)

* feat(ui): tri-state connection indicator (red/orange/green)

Replace the binary connected/disconnected indicator with a three-state
model: Disconnected (red), Syncing (orange), and Synced (green). This
provides consistent status terminology between the top-bar circle and
the Networks tab, resolving confusion when Dash Core is connected but
still syncing blocks.

Closes dashpay#333
Closes dashpay#62

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

* fix(ui): use get_live_addresses() for accurate DAPI endpoint count

Replace get_live_address() (returns Option, max 1) with
get_live_addresses() (returns Vec of all non-banned endpoints)
now that the pinned platform SDK revision supports it.

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

* chore: fix rabbit nitpick

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…ashpay#627)

During SPV reconciliation, per_address_sum only contains addresses with
current UTXOs. Addresses whose funds were fully spent never had their
balance reset to zero, causing the address table to display stale
non-zero balances even though UTXO count correctly showed 0.

Now explicitly zeroes address_balances for any known address absent from
the refreshed UTXO map before applying current sums.

Closes dashpay#571

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…ashpay#613)

* fix: handle malformed YAML gracefully in load_testnet_nodes_from_yml

Replace .expect() with match expression to avoid panicking when
.testnet_nodes.yml contains malformed YAML. Instead, logs the error
with tracing::error and returns None, allowing the application to
continue without crashing.

Closes dashpay#557

Co-authored-by: lklimek <lklimek@users.noreply.github.com>

* fix: propagate YAML parse errors to UI and remove unwrap calls

- Change load_testnet_nodes_from_yml to return Result<Option<TestnetNodes>, String>
  so parse errors display in the UI error banner instead of only logging
- Use explicit type annotation on serde_yaml_ng::from_str::<TestnetNodes>
- Replace .unwrap() with .and_then() in fill_random_hpmn/fill_random_masternode

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

---------

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: lklimek <lklimek@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* chore: move doc/ contents into docs/ and update references

Consolidate documentation under a single docs/ directory.

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

* chore: CLAUDE.md should write manual test scenarios for PRs

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…tion (dashpay#603)

* build(flatpak): use only-arches for dynamic protoc architecture selection

Replace the fragile sed-based CI patching of the Flatpak manifest with
Flatpak's native `only-arches` source selector. The protoc module now
declares both x86_64 and aarch64 sources inline, and build-commands use
a glob pattern (`protoc-*.zip`) so no per-arch fixup is needed.

Changes:
- flatpak manifest: add aarch64 protoc source with `only-arches`,
  use glob in unzip commands, remove stale CI-patching comment
- CI workflow: remove `protoc-zip`/`protoc-sha256` matrix variables
  and the "Patch manifest for architecture" step

https://claude.ai/code/session_015AD2pCWoJdV2VDydcqFHPG

* fix(flatpak): use dest-filename for deterministic protoc extraction

Use dest-filename to normalize both arch-specific protoc zips to a
common name, avoiding glob expansion in build-commands. This ensures
the unzip target is deterministic regardless of shell behavior in the
Flatpak sandbox.

https://claude.ai/code/session_015AD2pCWoJdV2VDydcqFHPG

* build: update platform to b445b6f0 and remove rust-dashcore patches

Update dashpay/platform dependency from d6f4eb9a to b445b6f0e0bd4863
(3.0.1 → 3.1.0-dev.1). Remove the [patch] section that pinned
rust-dashcore crates to a separate rev, as the new platform commit
resolves them correctly on its own.

https://claude.ai/code/session_015AD2pCWoJdV2VDydcqFHPG

---------

Co-authored-by: Claude <noreply@anthropic.com>
…ection() (dashpay#643)

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…ashpay#641)

* feat(ui): add Auto Update button for dashmate RPC password

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

* docs: add manual test scenarios for dashmate auto-update

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

* fix(ui): show error message when dashmate Auto Update fails

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

* fix(ui): use MessageBanner for dashmate Auto Update errors

Replace custom inline Frame-based error display with the codebase's
standard MessageBanner::set_global() pattern. The banner is rendered
centrally by island_central_panel() and auto-dismisses after a default
duration, providing a consistent user experience.

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
dashpay#646)

* fix(wallet): use mode-aware broadcast for platform funding in SPV mode

fund_platform_address_from_wallet_utxos() called core_client.send_raw_transaction()
directly, bypassing the mode-aware broadcast_raw_transaction() helper. This broke
core-to-platform transfers in SPV mode where no RPC connection is available.

Changes:
- Replace direct RPC broadcast with self.broadcast_raw_transaction() which
  routes to SPV manager in SPV mode and Core RPC in RPC mode
- Guard UTXO reload fallback with core_backend_mode() check: only attempt
  RPC-based reload_utxos in RPC mode; return error in SPV mode where wallet
  state is authoritative (matching register_identity.rs and top_up_identity.rs)
- Remove unused dash_sdk::dashcore_rpc::RpcApi import

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

* fix(wallet): use mode-aware broadcast for platform funding in SPV mode

fund_platform_address_from_wallet_utxos() called core_client.send_raw_transaction()
directly, bypassing the mode-aware broadcast_raw_transaction() helper. This broke
core-to-platform transfers in SPV mode where no RPC connection is available.

Changes:
- Replace direct RPC broadcast with self.broadcast_raw_transaction() which
  routes to SPV manager in SPV mode and Core RPC in RPC mode
- Guard UTXO reload fallback with core_backend_mode() check: only attempt
  RPC-based reload_utxos in RPC mode; return error in SPV mode where wallet
  state is authoritative (matching register_identity.rs and top_up_identity.rs)
- Store asset lock transaction in DB after broadcast so the SPV finality
  listener can retrieve it when processing InstantLock/ChainLock events
  (without this, the finality proof is never populated and the wait loop
  times out after 5 minutes)
- Remove unused dash_sdk::dashcore_rpc::RpcApi import

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

* refactor(wallet): simplify reload_utxos signature and callers

- Change reload_utxos from (Client, Network, Option<AppContext>) to
  (&AppContext), returning Result<bool, String> (true = UTXOs changed)
- SPV mode: no-op returning Ok(false) instead of error
- RPC mode: acquire core_client internally with map_err (SEC-03 fix)
- Callers skip retry when reload reports no changes
- Replace inline tokio::select! timeout loop in fund_platform_address
  with shared wait_for_asset_lock_proof helper (SEC-04 fix)
- Add mode-aware post-timeout recovery (RPC: refresh_wallet_info,
  SPV: tracing::warn about automatic reconciliation)

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

* fix(wallet): address review findings CODE-01, CODE-02, CODE-04

- CODE-01: Move store_asset_lock_transaction before broadcast to
  eliminate race where SPV finality listener fires before the DB row
  exists. Clean up DB row and finality tracking on broadcast failure.
- CODE-02: Guard DB persistence in reload_utxos with `if changed`
  to skip empty-set iteration when nothing changed.
- CODE-04: Renumber step comments sequentially (1-9, no gaps).

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…setup (dashpay#640)

* feat(scripts): add configure-local.sh for dashmate network setup

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

* fix(scripts): address PR review comments on configure-local.sh

- Hide RPC password from console output, show "(found)" instead
- Support DASHMATE_CMD env var for custom dashmate command
  (e.g. DASHMATE_CMD="yarn dashmate" ./configure-local.sh)

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

* fix(scripts): quote RPC password in .env output

Wrap the RPC password value in single quotes when writing to .env
to prevent mis-parsing if the password contains #, spaces, or $.

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…on input count (dashpay#636)

* fix(wallet): calculate asset lock tx fee dynamically based on input count

Replace hardcoded 3000 duff fee with dynamic fee calculation that accounts
for actual number of inputs. Estimates tx size using standard component
sizes (P2PKH input ~148B, output ~34B, header ~10B, payload ~60B) and
uses max(3000, estimated_size) to always meet the min relay fee.

Properly handles fee shortfall when allow_take_fee_from_amount is set,
and returns clear error messages for insufficient funds.

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

* docs: add manual test scenarios for asset lock fee fix

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

* Apply suggestions from code review

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* refactor(wallet): extract asset lock fee calculation to pure function

Extract fee/amount/change computation from the inline logic in
asset_lock_transaction_from_private_key() into a standalone
calculate_asset_lock_fee() function.

Uses an iterative approach that fixes a bug where the fee was computed
assuming a change output existed (based on the initial 3000-duff
estimate). When the real fee eliminated the change, the code
overestimated by 34 bytes and could trigger a false insufficient-funds
error on edge cases with many inputs.

Also removes stale edge case E3 from manual test scenarios (referenced
a database refactor not in this PR).

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

* test(wallet): add unit tests for calculate_asset_lock_fee()

Covers basic fee scenarios (minimum fee, scaling with inputs, exact
change, fee-from-amount, insufficient funds) and two regression tests
that prove the bug fixed in the previous commit — false insufficient
funds when change disappears under the real fee with many inputs.

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

* fix(wallet): overflow guard, dust threshold, and constant for fee calc

- Use checked_add for requested_amount + fee to prevent u64 overflow
- Add DUST_THRESHOLD (546 duffs) — change below this is absorbed into
  the fee instead of creating a non-standard dust output
- Replace hardcoded 3_000u64 with MIN_ASSET_LOCK_FEE constant in caller

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

* Apply suggestions from code review

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update docs/ai-design/2026-02-24-asset-lock-fee-fix/manual-test-scenarios.md

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* fix(wallet): correct UTXO rollback type mismatch in asset lock fee error path

The rollback code used `extend()` which expected `(Address, HashMap<OutPoint, TxOut>)`
but received `(OutPoint, (TxOut, Address))` from `take_unspent_utxos_for()`. Re-group
UTXOs by address using entry API to match `self.utxos` structure.

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…d signed (dashpay#645)

* fix(wallet): calculate asset lock tx fee dynamically based on input count

Replace hardcoded 3000 duff fee with dynamic fee calculation that accounts
for actual number of inputs. Estimates tx size using standard component
sizes (P2PKH input ~148B, output ~34B, header ~10B, payload ~60B) and
uses max(3000, estimated_size) to always meet the min relay fee.

Properly handles fee shortfall when allow_take_fee_from_amount is set,
and returns clear error messages for insufficient funds.

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

* docs: add manual test scenarios for asset lock fee fix

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

* Initial plan

* fix(wallet): defer UTXO removal until asset lock tx is fully built and signed

Previously, `asset_lock_transaction_from_private_key` called
`take_unspent_utxos_for` which immediately removed selected UTXOs from
`Wallet.utxos`. Since fee recalculation and signing happen afterward,
any failure at those steps (fee shortfall, missing private key, change
address derivation error) would permanently drop UTXOs — especially
dangerous in SPV mode where there is no Core RPC reload fallback.

Fix:
- Add `select_unspent_utxos_for` (`&self`, non-mutating) that performs
  the same UTXO selection logic without removing anything.
- Add `remove_selected_utxos` (`&mut self`) for explicit removal.
- Refactor `take_unspent_utxos_for` to delegate to these two methods
  (no behavior change for existing callers).
- In `asset_lock_transaction_from_private_key`, use
  `select_unspent_utxos_for` for selection and only call
  `remove_selected_utxos` after the full tx is built and signed.

Co-authored-by: lklimek <842586+lklimek@users.noreply.github.com>

* refactor(wallet): consolidate UTXO removal, DB persistence, and balance recalc into remove_selected_utxos

Previously, every backend task caller had to manually: (1) remove UTXOs
from the in-memory map, (2) drop them from the database, and (3)
recalculate affected address balances.  This was error-prone — the
payment transaction builders were missing the balance recalculation
entirely.

Now `remove_selected_utxos` accepts an optional `&AppContext` and
handles all three steps atomically.  The redundant cleanup blocks in
5 backend task callers are removed.  Also applies the safe
select-then-commit UTXO pattern to `build_standard_payment_transaction`
and `build_multi_recipient_payment_transaction`, fixing the same
UTXO-loss-on-signing-failure bug that was previously fixed only for
asset lock transactions.

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

---------

Co-authored-by: Lukasz Klimek <842586+lklimek@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
…ay#648)

* fix(wallet): calculate asset lock tx fee dynamically based on input count

Replace hardcoded 3000 duff fee with dynamic fee calculation that accounts
for actual number of inputs. Estimates tx size using standard component
sizes (P2PKH input ~148B, output ~34B, header ~10B, payload ~60B) and
uses max(3000, estimated_size) to always meet the min relay fee.

Properly handles fee shortfall when allow_take_fee_from_amount is set,
and returns clear error messages for insufficient funds.

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

* docs: add manual test scenarios for asset lock fee fix

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

* Initial plan

* fix(wallet): defer UTXO removal until asset lock tx is fully built and signed

Previously, `asset_lock_transaction_from_private_key` called
`take_unspent_utxos_for` which immediately removed selected UTXOs from
`Wallet.utxos`. Since fee recalculation and signing happen afterward,
any failure at those steps (fee shortfall, missing private key, change
address derivation error) would permanently drop UTXOs — especially
dangerous in SPV mode where there is no Core RPC reload fallback.

Fix:
- Add `select_unspent_utxos_for` (`&self`, non-mutating) that performs
  the same UTXO selection logic without removing anything.
- Add `remove_selected_utxos` (`&mut self`) for explicit removal.
- Refactor `take_unspent_utxos_for` to delegate to these two methods
  (no behavior change for existing callers).
- In `asset_lock_transaction_from_private_key`, use
  `select_unspent_utxos_for` for selection and only call
  `remove_selected_utxos` after the full tx is built and signed.

Co-authored-by: lklimek <842586+lklimek@users.noreply.github.com>

* refactor(wallet): consolidate UTXO removal, DB persistence, and balance recalc into remove_selected_utxos

Previously, every backend task caller had to manually: (1) remove UTXOs
from the in-memory map, (2) drop them from the database, and (3)
recalculate affected address balances.  This was error-prone — the
payment transaction builders were missing the balance recalculation
entirely.

Now `remove_selected_utxos` accepts an optional `&AppContext` and
handles all three steps atomically.  The redundant cleanup blocks in
5 backend task callers are removed.  Also applies the safe
select-then-commit UTXO pattern to `build_standard_payment_transaction`
and `build_multi_recipient_payment_transaction`, fixing the same
UTXO-loss-on-signing-failure bug that was previously fixed only for
asset lock transactions.

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

* fix(wallet): address audit findings from PR dashpay#645 review

- Add checked arithmetic to UTXO selection (amount + fee overflow safety)
- Replace hardcoded fee in single-UTXO path with calculate_asset_lock_fee
- Add UTXO selection retry when real fee exceeds initial estimate
- Document write-lock invariant on select_unspent_utxos_for
- Replace .unwrap() with .map_err() on wallet write locks
- Restrict Database::shared_connection visibility to pub(crate)

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

* refactor(wallet): simplify remove_selected_utxos to take &Database + Network directly

Replace Option<&AppContext> with concrete dependencies (&Database, Network),
removing the need for take_unspent_utxos_for. Extract balance recalculation
into a private helper reused by both remove_selected_utxos and the existing
AppContext-based wrapper.

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
… mode (dashpay#638)

* feat(wallet): add Mine Blocks dialog for Regtest/Devnet dev mode

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

* docs: add manual test scenarios for mine blocks dialog

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

* fix(wallet): close Mine Blocks dialog after Cancel/Mine click

The dialog stayed open (in a broken state) after clicking Mine or Cancel
because the local `open` variable was written back to `is_open` after the
dialog state had already been reset. Pass `is_open` directly to egui's
`.open()` and use a separate `close` flag for button-triggered dismissal.

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

* fix(wallet): address audit findings for Mine Blocks dialog

- Wrap `generate_to_address` in `spawn_blocking` to avoid blocking
  the async runtime thread (HIGH)
- Replace `.expect()` on core client lock with `.map_err()?` for
  graceful error handling instead of panic (HIGH)
- Cap block count at 1000 to prevent resource exhaustion on the
  Core node (HIGH)

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

* fix(wallet): filter non-numeric input in Mine Blocks block count field

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

* fix(wallet): address review comments on Mine Blocks dialog

- Replace assume_checked() with require_network() for address
  validation (CodeRabbit dashpay#2)
- Use styled Frame-with-dismiss error display matching Send dialog
  pattern (CodeRabbit dashpay#3)
- Don't open dialog when no wallet selected; show MessageBanner
  instead (CodeRabbit dashpay#4)
- Extract shared load_bip44_external_addresses() helper to eliminate
  near-duplicate code between mine and receive dialogs (CodeRabbit dashpay#5)
- Add backend-side network guard (Regtest/Devnet) for defense-in-depth
  (CodeRabbit dashpay#6)
- Rename shadowed ctx binding to refresh_ctx for clarity (CodeRabbit dashpay#7)

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

* fix(wallet): address remaining review comments on Mine Blocks dialog

- Change MineBlocksSuccess(usize) to MineBlocksSuccess(u64) for
  type consistency with block_count parameter (Claudius dashpay#5)
- Align dialog close pattern with Send/Receive: use local `open`
  variable for egui X button, reset state inside closure for
  Cancel/Mine buttons (Claudius dashpay#6)

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…ashpay#637)

* feat(ui): show nonce column for Platform Payment addresses

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

* docs: add manual test scenarios for address nonce column

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

* fix(wallet): reset sort column when switching to platform payment account

When toggling to a Platform Payment account view, the sort column could
remain set to UTXOs or TotalReceived which are not rendered for that
account type. This resets it to Balance (descending) in that case.

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

* perf(wallet): gate platform info lookup on account type

Skip get_platform_address_info() for non-platform addresses to avoid
unnecessary linear scans in the fallback path.

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…ister_addresses params (dashpay#649)

All 12 wallet functions that took `register_addresses: Option<&AppContext>`
now require `&AppContext` unconditionally (placed first after `&mut self`
per project convention). This eliminates silently skipped UTXO removal and
address registration when callers forget to pass Some(...).

For `identity_authentication_ecdsa_public_keys_data_map`, a separate
`register_addresses: bool` flag controls whether addresses are registered
in the DB, preserving the search-loop optimization in load_identity.rs.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Tests were using the production database (data.db) which risked
data corruption and made tests depend on prior app setup. Add a
`testing` feature flag that swaps AppState::new() to use an
in-memory SQLite database via the existing create_test_database()
helper. No test files need changes since `--all-features` enables
the testing feature automatically.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
… duplicate errors (dashpay#654)

* fix(ui): fix message banner icons, dismiss button, text wrapping, and duplicate errors

- Change error icon from ❌ to ⛔ to avoid confusion with dismiss button
- Use ❌ as styled dismiss button (clickable label, pointer cursor on hover)
- Fix success icon (✅) and info icon (💬) to render correctly in Noto Sans
- Wrap long banner text at word boundaries instead of overflowing window
- Left-align text within the wrapping area
- Remove duplicate error display in AddNewIdentityScreen — delegate to global MessageBanner
- Route local validation errors through MessageBanner::set_global for consistent styling

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

* fix(ui): left-align banner text and sort imports

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

* fix(ui): clamp banner text width to zero instead of 100px minimum

Prevents row overflow in very narrow windows by allowing text_width
to shrink to zero rather than forcing a 100px floor.

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

* fix(ui): reserve space for countdown annotation in banner text width

Account for annotation width (e.g. "(5s)" countdown) when calculating
text_width so it doesn't overlap long messages.

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

* test(ui): update banner tests for new icons and dismiss button

Update kittest assertions to match new dismiss button (❌ emoji label
instead of "x" small_button) and new icon mappings (⛔ error, ✅
success, 💬 info).

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

* fix(ui): address PR review comments on banner layout and error handling

- Fix comment: icon is not actually "fixed width" (#2850192960)
- Measure annotation width dynamically instead of hard-coded 52px (#2850192972)
- Prevent validation errors from re-pushing to global banner each frame
  by tracking last-sent message (#2850192953)

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

* fix(ui): reduce annotation width estimate for banner layout

Lower per-character width multiplier from 0.55 to 0.4 to match actual
rendered width of digit/paren annotation strings like "(5s)".

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix(wallet): calculate asset lock tx fee dynamically based on input count

Replace hardcoded 3000 duff fee with dynamic fee calculation that accounts
for actual number of inputs. Estimates tx size using standard component
sizes (P2PKH input ~148B, output ~34B, header ~10B, payload ~60B) and
uses max(3000, estimated_size) to always meet the min relay fee.

Properly handles fee shortfall when allow_take_fee_from_amount is set,
and returns clear error messages for insufficient funds.

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

* feat(ui): add sync status panel to wallet screen

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

* docs: add manual test scenarios for asset lock fee fix

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

* docs: add manual test scenarios for sync status panel

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

* Initial plan

* fix(wallet): defer UTXO removal until asset lock tx is fully built and signed

Previously, `asset_lock_transaction_from_private_key` called
`take_unspent_utxos_for` which immediately removed selected UTXOs from
`Wallet.utxos`. Since fee recalculation and signing happen afterward,
any failure at those steps (fee shortfall, missing private key, change
address derivation error) would permanently drop UTXOs — especially
dangerous in SPV mode where there is no Core RPC reload fallback.

Fix:
- Add `select_unspent_utxos_for` (`&self`, non-mutating) that performs
  the same UTXO selection logic without removing anything.
- Add `remove_selected_utxos` (`&mut self`) for explicit removal.
- Refactor `take_unspent_utxos_for` to delegate to these two methods
  (no behavior change for existing callers).
- In `asset_lock_transaction_from_private_key`, use
  `select_unspent_utxos_for` for selection and only call
  `remove_selected_utxos` after the full tx is built and signed.

Co-authored-by: lklimek <842586+lklimek@users.noreply.github.com>

* refactor(wallet): consolidate UTXO removal, DB persistence, and balance recalc into remove_selected_utxos

Previously, every backend task caller had to manually: (1) remove UTXOs
from the in-memory map, (2) drop them from the database, and (3)
recalculate affected address balances.  This was error-prone — the
payment transaction builders were missing the balance recalculation
entirely.

Now `remove_selected_utxos` accepts an optional `&AppContext` and
handles all three steps atomically.  The redundant cleanup blocks in
5 backend task callers are removed.  Also applies the safe
select-then-commit UTXO pattern to `build_standard_payment_transaction`
and `build_multi_recipient_payment_transaction`, fixing the same
UTXO-loss-on-signing-failure bug that was previously fixed only for
asset lock transactions.

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

* fix(wallet): address audit findings from PR dashpay#645 review

- Add checked arithmetic to UTXO selection (amount + fee overflow safety)
- Replace hardcoded fee in single-UTXO path with calculate_asset_lock_fee
- Add UTXO selection retry when real fee exceeds initial estimate
- Document write-lock invariant on select_unspent_utxos_for
- Replace .unwrap() with .map_err() on wallet write locks
- Restrict Database::shared_connection visibility to pub(crate)

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

* chore: minimal improvement in conn status tooltip

* refactor(wallet): simplify remove_selected_utxos to take &Database + Network directly

Replace Option<&AppContext> with concrete dependencies (&Database, Network),
removing the need for take_unspent_utxos_for. Extract balance recalculation
into a private helper reused by both remove_selected_utxos and the existing
AppContext-based wrapper.

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

* fix(wallet): address remaining audit findings from code review

- Refresh platform sync info cache after wallet refresh completes
- Add broadcast failure cleanup in create_asset_lock (remove stale
  finality tracking entries, replace mutex .unwrap() with .map_err())
- Replace .expect() with proper error propagation in signing loops
- Use i128 for fee logging subtraction to prevent overflow
- Renumber step comments sequentially after refactoring

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

* fix(ui): refresh sync info cache after platform balance fetch

The PlatformAddressBalances task result handler updated wallet balances
but did not refresh the platform_sync_info cache, causing the UI to
display "never synced" until the wallet was reselected.

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

* feat(ui): make sync status panel collapsible and dev-mode only

The Core/Platform sync status panel is now hidden by default and only
visible when developer mode is enabled. It uses a collapsible header
so developers can expand/collapse it as needed.

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

* fix(ui): address PR dashpay#642 review findings

- Centralize wallet selection via set_selected_hd_wallet() helper to
  keep platform_sync_info cache consistent across all code paths
- Add tracing::warn! for Mutex poisoning in asset lock cleanup paths
- Fix misleading comment about wallet refresh on broadcast failure
- Remove TS-25 from manual test scenarios (not part of this PR)

Refs: dashpay#657

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

* refactor(ui): extract shared SPV phase summary and enrich tooltip

Consolidate duplicated SPV sync phase formatting into a shared
`spv_phase_summary()` function in `connection_status.rs`. The wallet
screen now uses this shared function instead of its own copy. The
network screen retains its richer operator-facing formatter.

The connection indicator tooltip now shows detailed sync progress
(e.g. "SPV: Headers: 12345 / 27000 (45%)") instead of bare
"SPV: Syncing" when in SPV mode.

Also adjust refresh polling rates: 4s when connected, 1s when
disconnected (was 10s/2s).

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

* style: apply nightly rustfmt formatting

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

* fix(ui): address second round of PR review comments

- Update test scenarios TS-07 through TS-11 and TS-23 to reflect new
  SPV phase format: "Headers: C / T (NN%)" instead of "Headers NN%"
- Add Masternodes phase to TS-23 progression
- Add developer mode precondition to test scenarios
- Fix tooltip showing "syncing..." when SPV is fully synced (Running)
- Update stale throttle comment to reflect new refresh rates

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
…rmSyncMode (dashpay#635)

* refactor(wallet): simplify platform sync by removing PlatformSyncMode

Remove the PlatformSyncMode enum (Auto/ForceFull/TerminalOnly) and
terminal sync logic (apply_recent_balance_changes, last_terminal_block,
last_full_sync_balance). The SDK now handles incremental sync internally
via AddressProvider::current_balances() and last_sync_height().

Key changes:
- Remove PlatformSyncMode enum from backend_task::wallet
- Simplify fetch_platform_address_balances to use new SDK API with
  stored state (with_stored_state, current_balances, last_sync_height)
- Change CoreTask::RefreshWalletInfo to use bool instead of
  Option<PlatformSyncMode>
- Remove last_full_sync_balance from PlatformAddressInfo
- Simplify database sync info to 2-tuple (timestamp, height)
- Remove set_last_terminal_block from database
- Simplify RefreshMode enum (remove PlatformFull, PlatformTerminal,
  CoreAndPlatformFull, CoreAndPlatformTerminal variants)

Note: requires updated dash-sdk with new sync_address_balances API.

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

* chore: update platform SDK to rev 0fa82e6652

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

* docs: add manual test scenarios for platform sync simplification

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

* fix(wallet): address PR dashpay#635 audit findings and extract broadcast helper

- DB schema v28: drop obsolete columns (last_terminal_block,
  last_full_sync_balance), rename last_platform_sync_checkpoint →
  last_platform_sync_height, with SQLite ≥3.35 runtime check
- Store asset lock TX before broadcast to prevent SPV InstantSend race
- Defer UTXO removal until after successful broadcast
- Replace .unwrap() on RwLock with .map_err() to avoid panics
- Remove unused _is_sync_operation param and set_platform_address_info_from_sync wrapper
- Fix redundant let-mut rebinding in fetch_platform_address_balances
- Extract broadcast_and_commit_asset_lock() on AppContext to consolidate
  the store→broadcast→cleanup→UTXO-removal pattern from 5 code paths

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

* refactor(db): schema v28 — drop obsolete sync columns and clean up DB interface (dashpay#653)

- Bump DEFAULT_DB_VERSION 27 → 28
- Drop last_terminal_block from wallet table (unused after sync simplification)
- Drop last_full_sync_balance from platform_address_balances table
- Rename last_platform_sync_checkpoint → last_platform_sync_height
- Add runtime SQLite ≥3.35 check (required for DROP COLUMN)
- Idempotent migration: checks column existence before each ALTER
- Remove unused _is_sync_operation param from set_platform_address_info()
- Remove set_platform_address_info_from_sync() wrapper
- Fix redundant let-mut rebinding in fetch_platform_address_balances

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* revert(db): remove schema v28 migration from this branch

The v28 schema changes (drop obsolete sync columns, rename
last_platform_sync_checkpoint → last_platform_sync_height) will be
applied separately and should not ship on this branch.

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

* fix: address PR review comments — remove dead code and document risks

- Remove dead `_is_sync_operation` parameter from `Database::set_platform_address_info`
  and all call sites (Finding dashpay#6)
- Add doc comment on `set_platform_sync_info` explaining column name drift:
  `last_platform_sync_checkpoint` now stores SDK sync height (Finding dashpay#4)
- Remove trivial `set_platform_address_info_from_sync` delegate and update
  callers to use `set_platform_address_info` directly (Finding dashpay#7)
- Combine unnecessary `let provider` + `let mut provider = provider`
  rebinding into single `let mut` block (Finding dashpay#10)
- Document UTXO selection race window on `broadcast_and_commit_asset_lock`:
  std::sync::RwLock guard is !Send so it cannot span async broadcast

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

* style: apply nightly fmt

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: PastaClaw <thepastaclaw@users.noreply.github.com>
…gs (dashpay#623)

* fix: replace expect() on settings save in network chooser with warnings

Replace 3 panicking expect() calls on self.save() in the network
chooser screen with if-let-Err + tracing::warn. A failure to persist
a UI setting should not crash the application.

Cherry-picked from ralph/improvements (commit 73452b6).

* fix: collapse nested if to satisfy clippy collapsible_if lint

* fix(ui): surface network chooser save failures to users

---------

Co-authored-by: PastaClaw <thepastaclaw@users.noreply.github.com>
* Initial plan

* fix: copy sqlite3 import lib to mingw lib dir for Windows cross-compilation

Co-authored-by: lklimek <842586+lklimek@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: lklimek <842586+lklimek@users.noreply.github.com>
Replace unbounded loop with a capped for loop (max 50 iterations)
in the SPV fee calculation to prevent potential infinite loops when
the scale factor converges but never meets the exit condition.

Cherry-picked from ralph/improvements (commit 557acb2).

Co-authored-by: PastaClaw <thepastaclaw@users.noreply.github.com>
…hpay#665)

* refactor: introduce TaskError typed error envelope (dashpay#660)

Replace `TaskResult::Error(String)` with `TaskResult::Error(TaskError)`.
TaskError provides typed error propagation with Display for user-facing
messages and Debug for technical details, while From<String> ensures
zero-breakage backwards compatibility with all existing code.

- Create TaskError enum with Generic(String) + #[from] variants for
  SpvError, DashPayError, ConfigError, GroveSTARKError, WalletError
- Wire TaskResult::Error(TaskError) through app.rs, connection_status.rs,
  and query_dpns_contested_resources.rs
- Change run_backend_task to return Result<_, TaskError>
- app.rs handler now shows Display text in banner + Debug in details
- Document TaskError pattern in CLAUDE.md
- Add manual test scenarios

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

* refactor: add Other(Box<dyn Error>) variant, dev-only details, transparent errors

- Add Other(Box<dyn Error + Send + Sync>) catch-all variant to TaskError
- Show Debug details in error banner only in developer mode
- Use #[error(transparent)] for proper error chain propagation

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

* fix: adapt TaskError handler to v1.0-dev MessageBanner API

MessageBanner on v1.0-dev takes &str, not impl Display. Convert
TaskError to string before passing to set_global and with_details.

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

* remove testing docs, not applicable here

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
# Conflicts:
#	Cargo.toml
#	tests/e2e/navigation.rs
#	tests/e2e/wallet_flows.rs
#	tests/kittest/main.rs
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 26, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

🗂️ Base branches to auto review (2)
  • master
  • v1.0-dev

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

@PastaPastaPasta PastaPastaPasta merged commit 36c6c0f into dashpay:e2e Feb 26, 2026
1 of 3 checks passed
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.

4 participants