Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
74d6958
docs(user-stories): add missing entries surfaced by v1.0 parity audit
lklimek Jul 13, 2026
27467fe
refactor(network-chooser): drop dead dashmate_password_input field
lklimek Jul 13, 2026
0a64eae
merge: group6 — expert-mode toggle audit + dead RPC-password field cl…
lklimek Jul 13, 2026
4d26fe3
docs: close v1.0 parity audit disclosure gaps (group 8)
lklimek Jul 13, 2026
8324ec7
merge: group8 — v1.0 parity audit disclosure closure (B1/B2/B4)
lklimek Jul 13, 2026
3599597
fix(tokens): keep dismissed token balances out of refresh watch sets
lklimek Jul 13, 2026
138cb91
merge: group5 — fix token "stop tracking" not surviving refresh (A9)
lklimek Jul 13, 2026
a209288
feat(shielded): restore shielded receive-address view and copy
lklimek Jul 13, 2026
6724ef9
feat(identity-hub): wire Contacts actions, real contact list, alias, …
lklimek Jul 13, 2026
3ab07d9
fix(dashpay): clear a stale rejection marker when re-adding a contact
lklimek Jul 13, 2026
5a6dc76
merge: group3 — restore shielded receive-address view (A6, High sever…
lklimek Jul 13, 2026
4386531
fix(migration): import settings, scheduled votes and top-ups from leg…
lklimek Jul 13, 2026
025cf27
fix(wallets): remove dead RPC-mode gate on single-key send, surface l…
lklimek Jul 13, 2026
361b260
feat(nav): wire the masternode and Wallets global-nav pills
lklimek Jul 13, 2026
c55d643
merge: group1 — Identity Hub Contacts: A1-A4
lklimek Jul 13, 2026
0110add
merge: group7 — settings/data migration on upgrade (A12, High severity)
lklimek Jul 13, 2026
444d735
merge: group4 — single-key wallet send/monitoring: blocked upstream (…
lklimek Jul 13, 2026
860e2b8
merge: group2 — global nav pills: masternode object pill + Wallets pi…
lklimek Jul 13, 2026
4902fb5
fix(dashpay): narrow the cancel race window and add a way back for hi…
lklimek Jul 13, 2026
e6057db
docs(user-stories): record the hidden-contact recovery path in DPY-009
lklimek Jul 13, 2026
273c042
fix(ui,tokens): re-disable single-key send, ungate DashPay pay button…
lklimek Jul 13, 2026
167b5ff
docs: drop stale Resync references from shielded_tab doc comments
lklimek Jul 13, 2026
8120110
merge: fix-contacts — QA follow-up (cancel-race narrowing, unhide, sh…
lklimek Jul 13, 2026
74d2af8
fix(migration): stop a corrupt vote row from blocking the wallet drain
lklimek Jul 13, 2026
42830e9
merge: fix-single-key-a4 — QA follow-up (send-screen safety, gating c…
lklimek Jul 13, 2026
875920f
merge: fix-migration — QA-101/QA-103: decouple vote import from walle…
lklimek Jul 13, 2026
108af44
refactor: consolidate six duplicated code paths from the DRY audit
lklimek Jul 13, 2026
0fcb6e7
test(migration): lock the v0.9.3 -> v1.0 upgrade path end to end
lklimek Jul 13, 2026
771b9d7
fix(tokens): stop concurrent dismissals from clobbering each other
lklimek Jul 13, 2026
27f5291
fix(dashpay): scope contact results to their identity, split resoluti…
lklimek Jul 13, 2026
86e6cc2
merge: fix-contact-requests — bot-review fixes 2, 7, 9
lklimek Jul 13, 2026
c61da82
fix(migration): stop the legacy import from losing top-ups, votes and…
lklimek Jul 13, 2026
cd7f034
merge: fix-migration-2 — bot-review fixes 5, 6, 8
lklimek Jul 13, 2026
ff05c3a
fix(dashpay): stop the Contacts tab losing loads, clicks and accepted…
lklimek Jul 13, 2026
c56139f
merge: fix-contacts-ui — bot-review fixes 1, 3, 4 (+ legacy wipe)
lklimek Jul 13, 2026
f6d89a2
merge: reconcile with v0.9.3 upgrade-path lock test (0fcb6e7e)
lklimek Jul 13, 2026
54e9374
test: allow-list v093_upgrade.rs's legacy wallet-table fixture read
lklimek Jul 13, 2026
64a6d3d
test: stabilize suite timing and close kittest wiring race (#884)
lklimek Jul 13, 2026
b94a868
merge: bring PR #860 (platform-wallet rewrite) into the v1.0 parity b…
lklimek Jul 13, 2026
1d61b22
test(wallets): pin the pill-click mirroring seam on the Wallets page
lklimek Jul 13, 2026
6161674
feat(migration): import legacy v0.9.3 identities and their keys (#885)
Claudius-Maginificent Jul 14, 2026
f6f01db
fix: live-QA follow-up batch (masternodes, wallets, fonts) (#887)
lklimek Jul 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,17 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
reproduced. Re-establishing the contact from both sides restores full
functionality.

- **Shielded notes — no per-note detail view**: the Shielded tab no longer lists
individual notes (value, block height, spent/unspent status) or a synced-index
and note-count summary. Your shielded balance total is still accurate; only the
note-level breakdown is unavailable in this release.

### Removed

- Proof log screen (internal developer tool, not part of the public feature set).
Proof-log records now go only to the `tracing` log target — both the persisted
history and the in-app viewer are gone; there is no replacement UI to inspect
past entries.
- QR-code wallet import flow for identity funding and top-up screens.
- The "fund identity directly from a transaction output" option on the identity
registration and top-up screens (replaced by the single asset-lock funding flow
Expand All @@ -148,9 +156,25 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
- The unreachable Dash-Qt launcher and its settings — the executable path, the
overwrite-config option, and the close-on-exit option. There was no way to launch
Dash-Qt from the app, so the controls had no effect and have been removed.
- The Masternode List Diff inspector (Tools), which showed additions, removals, and
changes to the masternode list between blocks. No replacement is planned.
- The "Total Received (DASH)" column on the wallet address table. There is no
upstream source for cumulative historical receipts post-migration, so the column
cannot be populated.

### Fixed

- **Your settings and scheduled votes now survive an upgrade**: upgrading from an
earlier version no longer starts the app with a blank configuration. The first
launch after the upgrade brings across your selected network, start screen,
theme, onboarding state, Dash-Qt path and the remaining toggles — so a testnet
user is no longer relaunched on Mainnet — along with your scheduled DPNS votes
(choice, time and already-cast state) and your identities' top-up history.
Scheduled votes are imported even on an install whose wallets were already
moved by a previous launch. If a scheduled vote cannot be read, the app says so
in a banner with a "Retry now" action instead of dropping it silently; the
original data is never deleted from the previous version's storage.

- **Expert mode now reveals the Masternodes tab without a restart**: turning on
Expert mode in Settings immediately shows the "Masternodes" entry in the left
nav. Previously the Expert-mode flag was stored separately per network, so the
Expand Down
21 changes: 21 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,13 @@ serde = "1.0.219"
serde_json = "1.0.140"
serde_yaml_ng = { version = "0.10.0" }
tokio = { version = "1.46.1", features = ["full"] }
# Pin is deliberate; do not "fix" the audit warning by bumping. bincode is flagged
# unmaintained (RUSTSEC-2025-0141, INFO-level — no known vulnerability). The advisory
# covers *all* versions, so no bump can clear it: 2.0.1 is the last functional release
# and 3.0.0 is a tombstone whose lib.rs is a bare `compile_error!`. This crate encodes
# the on-disk wallet-secret envelopes and QualifiedIdentity blobs, so switching encoders
# changes the wire format of data users already have on disk — that needs a designed
# read-old/write-new migration, not a dependency bump.
bincode = { version = "=2.0.1", features = ["serde"] }
hex = { version = "0.4.3" }
async-trait = "0.1.89"
Expand Down Expand Up @@ -151,6 +158,20 @@ winres = "0.1"
[profile.dev.package."*"]
debug = "line-tables-only"

# Argon2id is deliberately memory-hard; unoptimized (opt-level=0) each 64 MiB
# derivation runs for seconds AND holds its memory that whole time, so the
# wallet_backend secret-storage tests both ran slowly (5-23s each) and, under
# whole-suite parallelism, overlapped enough to push the host into swap.
# opt-level=3 shrinks each derivation to tens of ms, which also collapses the
# memory-hold window and the swap pressure. This mirrors platform's own root
# argon2 stanza, which does NOT propagate downstream: Cargo honors [profile.*]
# tables only from the workspace root, so DET must declare its own.
[profile.dev.package.argon2]
opt-level = 3

[profile.test.package.argon2]
opt-level = 3

[lints.rust.unexpected_cfgs]
level = "warn"
check-cfg = ["cfg(tokio_unstable)", "cfg(feature, values(\"testing\", \"bench\", \"mcp\", \"cli\", \"headless\"))"]
Expand Down
93 changes: 93 additions & 0 deletions assets/Fonts/Noto_Sans_Symbols2/OFL.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
Copyright 2022 The Noto Project Authors (https://github.com/notofonts/symbols)

This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
https://scripts.sil.org/OFL


-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------

PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.

The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.

DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.

"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).

"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).

"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.

"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.

PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:

1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.

2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.

3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.

4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.

5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.

TERMINATION
This license becomes null and void if any of the above conditions are
not met.

DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ The `BackendTask` enum (`src/backend_task/mod.rs:92-100`) and the action/channel
| `CoreTask::CreateAssetLock` | **modified** | Build via upstream; broadcast via `SpvRuntime`. Result unchanged. |
| `CoreTask::ListCoreWallets` | **hard-removed** | Named Core wallets are RPC-only; meaningless without RPC mode. Hard-removed immediately; UI entry point (Core-wallet picker) deleted same release (Decision #8). |
| `CoreTask::RecoverAssetLocks` | **hard-removed** | Upstream `AssetLockManager` tracks continuously; explicit recovery is obsolete. Hard-removed immediately; UI entry point deleted same release (Decision #8 — no one-release grace). |
| `IdentityTask::RegisterIdentity` / `IdentityTask::TopUpIdentity` | **modified — `FundWithUtxo` variants removed** | DAPI/SDK state-transition flows. `RegisterIdentityFundingMethod::FundWithUtxo` and `TopUpIdentityFundingMethod::FundWithUtxo` are removed in P4a.5 (no upstream funding-outpoint API exists at #3625 head; cannot be preserved). Accepted user-facing behavior change: identity registration and top-up are funded only from wallet-managed balance via `WalletBackend::create_asset_lock_proof`. External scanned-outpoint direct funding is removed and disclosed via the one-time post-migration notice. All other identity task variants (transfer, withdraw, add_key, load, discover, refresh) are internally rewired with signatures stable and UI unaffected. |
| `IdentityTask::RegisterIdentity` / `IdentityTask::TopUpIdentity` | **modified — `FundWithUtxo` variants removed** | DAPI/SDK state-transition flows. `RegisterIdentityFundingMethod::FundWithUtxo` and `TopUpIdentityFundingMethod::FundWithUtxo` are removed in P4a.5 (no upstream funding-outpoint API exists at #3625 head; cannot be preserved). Accepted user-facing behavior change: identity registration and top-up are funded only from wallet-managed balance via `WalletBackend::create_asset_lock_proof`. External scanned-outpoint direct funding is removed and disclosed via CHANGELOG. All other identity task variants (transfer, withdraw, add_key, load, discover, refresh) are internally rewired with signatures stable and UI unaffected. |
| `IdentityTask::*` (transfer/withdraw/add_key/load/discover/refresh) | **mostly kept, internally rewired** | DAPI/SDK state-transition flows — zero `CoreBackendMode` branches. Identity state read via upstream `IdentityManager`/`IdentityWallet`; `QualifiedIdentity` blob retained. Signatures stable; UI unaffected. `discover_identities` keeps DET Devnet path (see [open-questions.md #4](open-questions.md)). |
| `IdentityTask::RegisterDpnsName`, DPNS load/refresh | **kept** | No upstream DPNS register flow (`DpnsNameInfo` is read-only). DET-owned permanently. |
| `DashPayTask::*` (contact request/accept, profile, avatar, auto-accept, incoming payments) | **modified, hybrid** | Contact-request/established-contact/profile state + crypto via upstream; DET keeps orchestration, avatar I/O, auto-accept proof, incoming-payment detection (Decision #5 hybrid split). DIP-14/15 derivation delegated upstream (`dip14_derivation.rs`/`hd_derivation.rs` deleted, subject to migration execution). Contacts are re-established on upstream derivation unconditionally — no quarantine error path (Decision #6, 2026-05-18 re-resolution; see [data-model-and-migration.md](data-model-and-migration.md) — "Accepted fund-accessibility trade-off"). `TaskError::DashPayContactDerivationIrreconcilable` is unused by the migration path — candidate for P4 removal if no other caller. Result variants stable; UI unchanged. |
Expand All @@ -62,4 +62,4 @@ Result variants and the action/channel contract are preserved — UI screens are
2. Single-key screens show a not-supported banner (read-only view of preserved data).
3. SPV sync-progress UI fed from upstream `sync_progress()` via thin `ConnectionStatus` adapter — visual parity, different source.
4. `RefreshWalletInfo` returns near-instantly (upstream is already syncing).
5. **`FundWithUtxo` removed (P4a.5):** The option to fund an identity directly from a scanned external outpoint (QR-direct-fund UI) is no longer available. Identity registration and top-up accept only wallet-managed balance as the funding source. This change is disclosed via the one-time post-migration informational notice shown to all migrated users.
5. **`FundWithUtxo` removed (P4a.5):** The option to fund an identity directly from a scanned external outpoint (QR-direct-fund UI) is no longer available. Identity registration and top-up accept only wallet-managed balance as the funding source. This change is disclosed via CHANGELOG.
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ No funding-outpoint API exists in `platform-wallet` at PR #3625 head. The `FundW
- `top_up_asset_lock_transaction_for_utxo`
- `asset_lock_transaction_for_utxo_from_private_key`

This is a user-facing capability removal. It is disclosed via the one-time post-migration notice (see [data-model-and-migration.md § Mandatory one-time informational notice](data-model-and-migration.md#accepted-fund-accessibility-trade-off-user-decision-2026-05-18)).
This is a user-facing capability removal. It is disclosed via CHANGELOG.

**Path 3 — `received_transaction_finality` slim (asset-lock-finality-only).**
Slim `context/transaction_processing.rs::received_transaction_finality` to handle only asset-lock finality. Delete the `Wallet.utxos` / `address_balances` / legacy-`utxos`-table write branches. RETAIN the asset-lock detection and registration branch: `store_asset_lock_transaction` + the finality-wait channel that `broadcast_and_commit_asset_lock` and `wait_for_asset_lock_proof` depend on. ZMQ call sites at `app.rs:1267,1285` stay — ZMQ is still required for asset-lock detection.
Expand Down Expand Up @@ -191,8 +191,7 @@ The Smythe security audit is a **release-blocking gate** at P5. No push to #860
|---|---|---|
| **I1** | Authoritative selection at construction | No code path selects spendable inputs from `WalletSnapshot` or any `Wallet.utxos` snapshot. All coin-selection goes through `WalletBackend::create_asset_lock_proof` or `WalletBackend::send_payment` (upstream live UTXO set). |
| **I2** | No DET-side parallel spend engine | The functions `select_unspent_utxos_for`, `select_utxos_with_fee_retry`, `generic_asset_lock_transaction`, `registration_asset_lock_transaction_for_utxo`, `top_up_asset_lock_transaction_for_utxo`, `asset_lock_transaction_for_utxo_from_private_key`, `remove_selected_utxos`, `build_multi_recipient_payment_transaction` are deleted, not orphaned. No dead caller, no commented-out call, no unreachable arm. |
<!-- TODO(DOC-003): Promised one-time post-migration notice (invariant I3) never shipped -->
| **I3** | `FundWithUtxo` removal disclosed | The one-time post-migration notice text ships in the release build. `RegisterIdentityFundingMethod::FundWithUtxo` and `TopUpIdentityFundingMethod::FundWithUtxo` variants are gone. No dead erroring arm remains in any match on either enum. |
| **I3** | `FundWithUtxo` removal disclosed | The removal is disclosed via CHANGELOG (no in-app one-time notice ships). `RegisterIdentityFundingMethod::FundWithUtxo` and `TopUpIdentityFundingMethod::FundWithUtxo` variants are gone. No dead erroring arm remains in any match on either enum. |
| **I4** | Crash-retry no-double-broadcast | Asset-lock transactions are stored (durable) before broadcast. Upstream deduplication prevents double-broadcast on retry. Store-before-broadcast ordering is verified by test. |
| **I5** | Path 3 deletion leaves asset-lock detection intact | `received_transaction_finality` no longer writes to `Wallet.utxos` / `address_balances` / legacy `utxos` table. The asset-lock detection branch (`store_asset_lock_transaction` + finality-wait channel) is fully functional. `broadcast_and_commit_asset_lock` and `wait_for_asset_lock_proof` succeed in test without any `Wallet` mutation. |
| **I6** | No frame-thread blocking | No code path added in P4a, P4a.5, or P4b causes the egui frame thread to await or block on a wallet operation. All upstream calls are dispatched through `BackendTask` / `WalletBackend` async methods. |
Expand Down
32 changes: 20 additions & 12 deletions docs/ai-design/2026-05-28-migration-tool/notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -203,19 +203,27 @@ idempotency is confirmed.

### `identity` (DET source file: `src/database/identities.rs`)

- **Source:** `identity` in `data.db`
- **Destination:** `identities.entry_blob` (typed BLOB column) in `platform-wallet-storage`
- **Mapping:** Deserialize DET's stored identity representation → serialize as
bincode-encoded `QualifiedIdentity` with a leading version byte prepended
- **Per-network split:** Yes
- **Gotchas:** Upstream schema uses a leading version byte in `entry_blob` for
forward/backward compatibility — this byte must be present and set correctly, or upstream
deserialization will silently produce garbage. Confirm the byte format with the
platform-wallet-storage author before implementing. This is the highest-risk table in the
migration.
> **SUPERSEDED (2026-07-13).** Design and task breakdown now live in
> `docs/ai-design/2026-07-13-legacy-identity-migration/design.md`. The entry below is kept
> for context; two of its claims are wrong. The destination is **not** upstream's
> `identities.entry_blob` — commit `b14bf32c` moved it to DET's own per-network k/v
> (`det:identity:v1` under `DetScope::Identity`, roster at `det:identity_index:v1`). And the
> version byte needs no agreement with the platform-wallet-storage author: `DetKv::put`
> prepends `kv::SCHEMA_VERSION` automatically, so an importer that goes through
> `AppContext::insert_local_qualified_identity` gets it for free.

- **Source:** `identity` in `data.db` (`is_local = 1 AND data IS NOT NULL`)
- **Destination:** `StoredQualifiedIdentity` in DET's per-network k/v — see the design doc
- **Mapping:** `QualifiedIdentity::from_bytes(row.data)` → restore `status` from its column →
`AppContext::insert_local_qualified_identity(&qi, &wallet_link)`. The `data` BLOB carries
**all identity key material**; there is no second key table in v0.9.3.
- **Per-network split:** Yes — two-value filter (`mainnet` / legacy `dash`)
- **Gotchas:** The real risk is cross-version bincode compatibility of the `data` BLOB, not a
version byte. Every DET-side and dpp-side struct in the blob was verified unchanged between
v0.9.3 and HEAD; only the `bincode` rc.3 → 2.0.1 wire format is unproven, and a golden-blob
test closes it. Still the highest-risk table in the migration.
- **Status:** DONE for new-install path — see commit `b14bf32c` (identities + tokens →
per-network k/v). Migration tool still needs to import legacy rows with the version-byte
contract correct.
per-network k/v). Migration tool still needs to import legacy rows.

---

Expand Down
Loading
Loading