Skip to content

fix(spv): no-op ensure_address_imported when backend is SPV#839

Merged
lklimek merged 11 commits into
v1.0-devfrom
fix/spv-qr-funding-identity-creation
Apr 25, 2026
Merged

fix(spv): no-op ensure_address_imported when backend is SPV#839
lklimek merged 11 commits into
v1.0-devfrom
fix/spv-qr-funding-identity-creation

Conversation

@lklimek
Copy link
Copy Markdown
Contributor

@lklimek lklimek commented Apr 23, 2026

Summary

  • Bug. In SPV mode (default since feat: default to SPV connection; gate Dash Core RPC behind Expert mode #836), creating an identity through "Address with QR code" fails before rendering the QR with Could not connect to Dash Core at 127.0.0.1:19998. The same failure path affects identity top-up via QR and the Create Asset Lock wallet tool.
  • Root cause. Two functions in AppContext unconditionally called Dash Core RPC to watch newly-derived receive addresses. In SPV mode there is no Dash Core node to reach, so those calls failed with CoreRpcConnectionFailed and the user never saw the QR code:
    • ensure_address_imported (src/context/mod.rs) — called via get_address_info + import_address
    • try_import_address (src/context/wallet_lifecycle.rs) — the async companion used in the wallet lifecycle path
  • Fix. Both functions now early-return Ok(()) when core_backend_mode() != CoreBackendMode::Rpc. The import is unnecessary in SPV mode because Wallet::receive_address -> unused_bip_44_public_key -> register_address already inserts the address into known_addresses; the SPV wallet manager (loaded from the same xprv via WalletAccountCreationOptions::Default) watches the entire standard BIP44 account. Incoming UTXOs reach wallet.utxos through received_transaction_finality, which is the exact map the QR flow polls via capture_qr_funding_utxo_if_available. Matches the precedent already in Wallet::register_address and the broadcast dispatcher shipped in fix(spv): disable features not available in spv mode #837.
  • Doc fix. Updated the ensure_address_imported doc comment to accurately describe the SPV UTXO delivery path (previously the comment described only the RPC path).

Diff scope: 4 source files + 1 .gitignore entry — SPV no-op guards, doc correction, and the PasswordInput secondary changes below.

Secondary changes — PasswordInput improvements

While working in the password input area, several small correctness and quality issues were addressed:

Change Commit Detail
Default input width 8ba789db Sets a sensible default width so the widget renders correctly before the caller provides an explicit size
Char limit 66 → 64 for private-key hex input 9a0e0029 A hex-encoded 32-byte private key is exactly 64 characters; 66 allowed impossible inputs that would silently fail later
Avoid double-alloc per frame in width measurement 15a069c0 Typography::measure_text_width now accepts impl Into<String> instead of String, eliminating one allocation per frame during rendering
Single source of truth for reveal-icon margin 6e6cf2c4 PASSWORD_INPUT_REVEAL_ICON_WIDTH constant now drives the TextEdit right-margin directly, removing a duplicated magic number

Verification performed

  • HD vs single-key wallet reachability. All three affected screens (AddNewIdentityScreen, TopUpIdentityScreen, CreateAssetLockScreen) hold Option<Arc<RwLock<Wallet>>>Wallet is structurally HD-only (has master_bip44_ecdsa_extended_public_key). SingleKeyWallet is a distinct type kept in a separate AppContext.single_key_wallets map, so single-key wallets cannot reach these flows. No risk of silently hiding a single-key-in-SPV bug.
  • rust-dashcore PR fix: profile bio guideline text and unsaved changes dialog #554 interaction. Orthogonal. fix: profile bio guideline text and unsaved changes dialog #554 adds DIP-9 identity-authentication account types at m/9'/coinType'/5'/subfeature'/index. This PR only affects BIP44 funding addresses at m/44'/coinType'/0'/0/index, already covered by WalletAccountCreationOptions::Default.
  • list_core_wallets / try_detect_core_wallet_for_address siblings. Audited all callers: add_new_wallet_screen and import_mnemonic_screen have explicit SPV short-circuits; wallets_screen/mod.rs and with_wallet_recovery only fire on TaskError::CoreWalletNotConfigured, which in SPV mode is preempted by CoreRpcConnectionFailed. No sibling fixes required.

Test plan

SPV QR funding (primary fix)

  • In SPV mode (default), open "Create Identity" → select a wallet → choose "Address with QR Code" → verify a QR code and pay-URI render instead of the connection error.
  • In SPV mode, send a small Dash payment to the displayed address on testnet → verify the flow advances from "Waiting for funds" to "Funds received" without a banner error, and the identity registration proceeds.
  • In SPV mode, repeat on the "Top Up Identity" → "Address with QR Code" flow.
  • In SPV mode, open Tools → "Create Asset Lock" → verify the QR renders and funds landing advances state.
  • In Expert + Local Dash Core mode, repeat the identity-creation QR flow → confirm ensure_address_imported still imports the address into Core's wallet (existing behaviour unchanged).

PasswordInput secondary changes

  • Open any screen that shows a private-key import field — verify it accepts exactly 64 hex characters and rejects a 65th character.
  • Visually confirm the password input renders at a sensible default width before any explicit size is set by the caller.
  • cargo +nightly fmt --all -- --check → clean.
  • cargo clippy --all-features --all-targets -- -D warnings → clean.

🤖 Co-authored by Claudius the Magnificent AI Agent

Summary by CodeRabbit

Release Notes

  • Bug Fixes

    • Fixed wallet address import behavior to properly handle SPV mode operations
  • Improvements

    • Enhanced password input field width calculation based on character limits
    • Added 66-character maximum limit to private key input field

The QR funding flow for identity creation (and identity top-up, and the
Create Asset Lock wallet tool) called AppContext::ensure_address_imported
unconditionally to register the derived receive address with Dash Core's
wallet. In SPV mode there is no Dash Core RPC to talk to, so the call
failed with CoreRpcConnectionFailed(127.0.0.1:19998) and the user saw
"Could not connect to Dash Core" instead of a QR code.

The RPC import is not needed in SPV mode: Wallet::receive_address feeds
Wallet::register_address, which populates known_addresses and the SPV
bloom filter. Incoming UTXOs on those addresses are already delivered to
wallet.utxos via received_transaction_finality(), which is the exact map
the QR flow polls through capture_qr_funding_utxo_if_available().

Gate the RPC body of ensure_address_imported on
core_backend_mode() == CoreBackendMode::Rpc, matching the precedent
already in register_address (src/model/wallet/mod.rs) and the broadcast
dispatcher shipped in PR #837. Fixes the reported identity-creation-by-
QR bug and the same issue in identity top-up QR and Create Asset Lock.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 23, 2026

Warning

Rate limit exceeded

@lklimek has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 48 minutes and 10 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 48 minutes and 10 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: f2b64ae9-5d84-491f-aa6b-94ca056a7c42

📥 Commits

Reviewing files that changed from the base of the PR and between 764977c and c777f59.

📒 Files selected for processing (4)
  • src/context/mod.rs
  • src/ui/components/password_input.rs
  • src/ui/identities/keys/add_key_screen.rs
  • src/ui/theme.rs
📝 Walkthrough

Walkthrough

The pull request introduces input validation improvements and backend mode handling refinements. A character limit is added to private key input, password input width calculation now supports char-limit-driven measurement with a new text width utility, the address import logic early-exits in non-RPC modes, and Claude workspace directories are added to .gitignore.

Changes

Cohort / File(s) Summary
Configuration
.gitignore
Adds .claude/worktrees directory to git ignore list.
Context & Backend Mode
src/context/mod.rs
Updates ensure_address_imported to immediately return Ok(()) for non-RPC modes; adds documentation detailing SPV-mode address handling through HD-derived wallet registration and bloom filter integration.
UI Input & Measurement
src/ui/components/password_input.rs, src/ui/identities/keys/add_key_screen.rs, src/ui/theme.rs
Introduces Typography::measure_text_width utility for text width measurement; enhances PasswordInput width calculation with char-limit-driven measurement path; constrains private key input to 66-character maximum across all AddKeyScreen constructors.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 A rabbit's delight in measured widths so fine,
Character limits dance in a 66-line,
SPV modes hop right past the import gate,
While password fields measure their perfect weight!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title directly and accurately describes the main change: adding an early return to ensure_address_imported when in SPV mode, which is the primary bug fix across all changes.
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/spv-qr-funding-identity-creation

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 lklimek marked this pull request as ready for review April 24, 2026 06:59
@thepastaclaw
Copy link
Copy Markdown
Collaborator

thepastaclaw commented Apr 24, 2026

✅ Review complete (commit c777f59)

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
src/context/mod.rs (1)

709-716: Minor: clarify what actually feeds the SPV bloom filter.

The phrase "Wallet::register_address (which populates known_addresses and feeds the SPV bloom filter)" is a bit misleading. Looking at src/model/wallet/mod.rs:1162-1210, register_address only updates known_addresses/watched_addresses and persists to the DB; it does not call SpvManager::register_addresses (compare src/backend_task/dashpay/incoming_payments.rs:130-190, where bloom-filter registration is an explicit, separately-tracked step). SPV coverage for HD receive addresses comes from the SPV wallet manager watching the BIP44 account derived from the same xprv, as you note in the PR description — not from register_address itself. Rewording to reflect that would prevent future readers from assuming register_address is the bloom-filter hook.

📝 Suggested wording
     /// In SPV mode this is a no-op: there is no Dash Core node to import into,
     /// and HD-derived addresses are already tracked by the SPV subsystem via
-    /// `Wallet::register_address` (which populates `known_addresses` and feeds
-    /// the SPV bloom filter). Incoming UTXOs on these addresses are delivered
-    /// through `received_transaction_finality()` from InstantLock/ChainLock
-    /// events — the same path the QR funding flows poll via
-    /// `capture_qr_funding_utxo_if_available`.
+    /// `Wallet::register_address` (which populates `known_addresses`). The SPV
+    /// wallet manager watches the BIP44 account derived from the same xprv,
+    /// so every address derived from that account is covered without a
+    /// per-address bloom-filter registration. Incoming UTXOs are delivered
+    /// through `received_transaction_finality()` from InstantLock/ChainLock
+    /// events — the same path the QR funding flows poll via
+    /// `capture_qr_funding_utxo_if_available`.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/context/mod.rs` around lines 709 - 716, The doc comment incorrectly
implies Wallet::register_address populates the SPV bloom filter; update the
wording in the comment around Wallet::register_address to state it only updates
known_addresses/watched_addresses and persists them, and explicitly note that
SPV coverage is provided by the SPV wallet manager watching the BIP44 account
(not by Wallet::register_address), while keeping the rest of the sentence about
received_transaction_finality and capture_qr_funding_utxo_if_available intact;
mention SpvManager::register_addresses as the separate code path that actually
registers addresses with the bloom filter.
src/ui/components/password_input.rs (1)

161-177: Font resolution for measurement should match TextEdit's actual font.

text_edit is styled via egui::TextStyle::Monospace (line 152), whose concrete FontId is resolved from ui.style().text_styles when rendering. However, the measurement here uses hardcoded Typography::monospace() (SCALE_BASE = 16.0). If the active style or theme ever customizes the Monospace or Body text style sizes, the computed desired_width will diverge proportionally from the actual rendered width.

Low-impact today since the theme doesn't override those sizes and relies on egui's defaults, but resolving the font from the style would make this self-consistent and future-proof:

♻️ Optional: resolve the font from the active style
-            let font_id = if self.monospace {
-                Typography::monospace()
-            } else {
-                Typography::body()
-            };
+            let font_id = ui
+                .style()
+                .text_styles
+                .get(if self.monospace {
+                    &egui::TextStyle::Monospace
+                } else {
+                    &egui::TextStyle::Body
+                })
+                .cloned()
+                .unwrap_or_else(|| {
+                    if self.monospace {
+                        Typography::monospace()
+                    } else {
+                        Typography::body()
+                    }
+                });

Also: "W".repeat(limit) overestimates width for typical content (addresses, keys, passwords). Using the widest glyph as a safe upper bound is fine, but be aware the field will tend to be wider than strictly needed when sizing PASSWORD_INPUT_HORIZONTAL_PADDING and PASSWORD_INPUT_REVEAL_ICON_WIDTH.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/ui/components/password_input.rs` around lines 161 - 177, The width
measurement uses hardcoded Typography::monospace()/Typography::body() instead of
the actual FontId resolved from the current UI style, so change the measurement
to resolve the FontId from ui.style().text_styles (e.g.
ui.style().text_styles.get(&egui::TextStyle::Monospace).cloned().or_else(||
ui.style().text_styles.get(&egui::TextStyle::Body).cloned()).unwrap_or_else(||
Typography::monospace())) and pass that resolved FontId into
Typography::measure_text_width when computing measured_width for the
text_edit.desired_width; keep the existing sample generation logic (but you can
keep "0".repeat(limit) for monospace and "W".repeat(limit) for proportional) so
measurement matches the actual TextEdit font style.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/ui/identities/keys/add_key_screen.rs`:
- Line 79: The char_limit on the private key input is incorrectly set to 66
while validate_and_add_key expects a 32-byte hex (64 hex chars); update the
three constructors (new, new_for_dashpay_encryption, new_for_dashpay_decryption)
to use .with_char_limit(64) and ensure the input hint remains "Private key
(hex)"; alternatively if WIF should be supported, update the validator in
validate_and_add_key and the hint text to reflect "WIF or 64-char hex"
instead—prefer tightening to 64 across the three constructors to match existing
codebase conventions.

---

Nitpick comments:
In `@src/context/mod.rs`:
- Around line 709-716: The doc comment incorrectly implies
Wallet::register_address populates the SPV bloom filter; update the wording in
the comment around Wallet::register_address to state it only updates
known_addresses/watched_addresses and persists them, and explicitly note that
SPV coverage is provided by the SPV wallet manager watching the BIP44 account
(not by Wallet::register_address), while keeping the rest of the sentence about
received_transaction_finality and capture_qr_funding_utxo_if_available intact;
mention SpvManager::register_addresses as the separate code path that actually
registers addresses with the bloom filter.

In `@src/ui/components/password_input.rs`:
- Around line 161-177: The width measurement uses hardcoded
Typography::monospace()/Typography::body() instead of the actual FontId resolved
from the current UI style, so change the measurement to resolve the FontId from
ui.style().text_styles (e.g.
ui.style().text_styles.get(&egui::TextStyle::Monospace).cloned().or_else(||
ui.style().text_styles.get(&egui::TextStyle::Body).cloned()).unwrap_or_else(||
Typography::monospace())) and pass that resolved FontId into
Typography::measure_text_width when computing measured_width for the
text_edit.desired_width; keep the existing sample generation logic (but you can
keep "0".repeat(limit) for monospace and "W".repeat(limit) for proportional) so
measurement matches the actual TextEdit font style.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: a6b96f37-df56-4995-b3fe-7ab282efc245

📥 Commits

Reviewing files that changed from the base of the PR and between bc6c0c2 and 764977c.

📒 Files selected for processing (5)
  • .gitignore
  • src/context/mod.rs
  • src/ui/components/password_input.rs
  • src/ui/identities/keys/add_key_screen.rs
  • src/ui/theme.rs

Comment thread src/ui/identities/keys/add_key_screen.rs Outdated
A 66-character hex input decodes to 33 bytes, which always fails the
32-byte validator in validate_and_add_key(). Correct limit is 64 (32 bytes
hex), consistent with the hex-only validator and sibling screens.

Fixes finding from CodeRabbit review of PR #839.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes SPV-mode QR-based funding flows by preventing Core-RPC address import attempts when running with the SPV backend, and includes small UI/input ergonomics updates.

Changes:

  • Make AppContext::ensure_address_imported a no-op when core_backend_mode != Rpc to unblock SPV-mode QR flows.
  • Add text-width measurement helper and use it to size PasswordInput based on character limits.
  • Add a 66-character limit to identity key “Private key (hex)” inputs; update .gitignore for Claude worktrees.

Reviewed changes

Copilot reviewed 4 out of 5 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
src/context/mod.rs Early-return in SPV mode for ensure_address_imported, plus explanatory doc comment.
src/ui/theme.rs Adds Typography::measure_text_width helper for egui font-metric sizing.
src/ui/components/password_input.rs Uses char-limit-based text measurement to set TextEdit desired width; adds sizing constants.
src/ui/identities/keys/add_key_screen.rs Applies a character limit to private key hex input fields.
.gitignore Ignores .claude/worktrees.

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

Comment thread src/context/mod.rs Outdated
Comment thread src/context/mod.rs
Comment thread src/context/mod.rs
Comment thread src/ui/components/password_input.rs
Comment thread src/ui/identities/keys/add_key_screen.rs Outdated
Comment thread src/ui/components/password_input.rs
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

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 4 out of 5 changed files in this pull request and generated 5 comments.


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

Comment thread src/context/mod.rs Outdated
Comment thread src/ui/components/password_input.rs Outdated
Comment thread src/ui/components/password_input.rs Outdated
Comment thread src/ui/theme.rs Outdated
Comment thread src/ui/identities/keys/add_key_screen.rs
lklimek and others added 3 commits April 24, 2026 09:39
…ted doc

The doc comment incorrectly claimed that in SPV mode incoming UTXOs are
delivered via `received_transaction_finality()` (which is ZMQ-driven and
only available in Core/RPC mode) and that `Wallet::register_address` feeds
the SPV bloom filter (it only updates `known_addresses` in wallet state).

Replace both inaccuracies: SPV UTXOs are populated by `reconcile_spv_wallets()`
and HD-derived addresses are tracked by the SPV wallet manager watching the
BIP44 account xprv, not via per-address bloom-filter registration.

Fixes CodeRabbit nitpick (thread r3136009337) and Copilot finding
(thread r3136166317) from PR #839 review.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Mirror the SPV early-return from ensure_address_imported. Previously,
every BIP44 address derivation called try_import_address which opened
an RPC client and failed silently in SPV mode — wasting resources on
every unused_bip_44_public_key call.

Fixes Copilot thread r3136077639 from PR #839 review.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Typography::measure_text_width cloned the sample string via to_owned()
even though the caller had already allocated it with repeat(limit).
Change the signature to consume the sample (impl Into<String>) so the
single allocation flows straight into egui's layout_no_wrap.

Fixes Copilot thread r3136166368 from PR #839 review.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

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 4 out of 5 changed files in this pull request and generated 3 comments.


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

Comment thread src/context/mod.rs
Comment thread src/context/mod.rs
Comment thread src/ui/components/password_input.rs
lklimek and others added 3 commits April 24, 2026 09:52
…f truth

Previously the reveal-icon width appeared as both a typed constant
(f32 = 28.0) used for TextEdit desired_width and as a hardcoded
literal (right: 28) in the egui::Margin. Bind the latter to the
constant so the two cannot drift out of sync.

Fixes Copilot thread r3136235773 from PR #839 review.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…measurement

Previously the width measurement used hardcoded Typography::monospace()/body()
while the TextEdit font was driven by TextStyle::Monospace. Any theme or
per-screen override of those TextStyles would cause the computed desired_width
to drift from the actual rendered width. Read the FontId from the active
style so measurement and rendering stay in lockstep.

Fixes Copilot thread r3136166359 and the related CodeRabbit nitpick on
src/ui/components/password_input.rs from PR #839 review.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
In a monospace font every glyph has the same advance width, so
"0".repeat(limit) and "W".repeat(limit) measure identically. The
branch was doing defensive work that isn't needed. Collapse to the
proportional-safe "W" sample for both modes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Collaborator

@thepastaclaw thepastaclaw left a comment

Choose a reason for hiding this comment

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

@/tmp/review_839_body.txt

Copy link
Copy Markdown
Collaborator

@thepastaclaw thepastaclaw left a comment

Choose a reason for hiding this comment

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

This rerun reviewed commit 764977c0 specifically.

Overall: the PR fixes the user-visible SPV QR funding failure in ensure_address_imported(), but the same SPV receive-address path still contains one unconditional Core import helper. I also confirmed that the add-key UI still allows impossible 66-character "hex" private-key input even though validation only accepts 32 decoded bytes.

Findings:

  1. src/context/mod.rs:739

    • try_import_address() still performs Core RPC work in SPV mode.
    • ensure_address_imported() now short-circuits outside RPC mode, but Wallet::unused_bip_44_public_key() still reaches try_import_address() when deriving a fresh receive address. In SPV mode that means we still do a pointless synchronous Core RPC attempt whose error is silently discarded. register_address() already guards its own import path by backend mode, so try_import_address() should do the same.
  2. src/ui/identities/keys/add_key_screen.rs:79

    • The add-key forms allow 65-66 character hex private keys that can never validate.
    • All three constructors use with_char_limit(66), but submission only accepts hex::decode(...) output with decoded length exactly 32 bytes, i.e. 64 hex characters. The UI currently permits two extra characters that are guaranteed to fail later at submit time.

Copy link
Copy Markdown
Collaborator

@thepastaclaw thepastaclaw left a comment

Choose a reason for hiding this comment

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

Code Review

Both agents independently reviewed the four-file delta from 764977c to c777f59 and found no new issues. The two prior findings (SPV guard in try_import_address, char limit in add-key forms) are both fixed on the current head. The follow-up password-input cleanup is a benign refactor with no correctness issues.

Reviewed commit: c777f59

@lklimek lklimek merged commit 3087259 into v1.0-dev Apr 25, 2026
5 checks passed
@lklimek lklimek deleted the fix/spv-qr-funding-identity-creation branch April 25, 2026 09:12
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.

3 participants