name the conflicting keystore when an entered extended key is not unique
What changed, and why it matters
This commit improves an error message in Sparrow Wallet. When a user enters an extended public key that is already used by another keystore in the same wallet, the app now names the conflicting keystore instead of giving a generic 'not unique' message. There is no security vulnerability here; it is a user-experience improvement.
No security action required. Treat as a normal UX improvement.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The change refactors a UI validator in KeystoreController. Previously it returned ‘Extended key is not unique’ if any other keystore had the same extended public key. Now it finds the first matching keystore and returns ‘Extended key matches
Changed components
src/main/java/com/sparrowwallet/sparrow/wallet/KeystoreController.javaInspect captured patch +9 / −2
### src/main/java/com/sparrowwallet/sparrow/wallet/KeystoreController.java
@@ -327,8 +327,15 @@ private void setupValidation() {
validationSupport.registerValidator(xpub, Validator.combine(
(Control c, String newValue) -> ValidationResult.fromErrorIf( c, Network.get().getXpubHeader().getDisplayName() + " is required", getWalletForm().getWallet().getPolicyType() != PolicyType.SINGLE_SP && newValue.trim().isEmpty()),
(Control c, String newValue) -> ValidationResult.fromErrorIf( c, Network.get().getXpubHeader().getDisplayName() + " is invalid", getWalletForm().getWallet().getPolicyType() != PolicyType.SINGLE_SP && !ExtendedKey.isValid(newValue)),
- (Control c, String newValue) -> ValidationResult.fromErrorIf( c, "Extended key is not unique", ExtendedKey.isValid(newValue) && getWalletForm().getWallet().getPolicyType() != PolicyType.SINGLE_SP &&
- walletForm.getWallet().getKeystores().stream().filter(k -> k != keystore && k.getExtendedPublicKey() != null).map(Keystore::getExtendedPublicKey).collect(Collectors.toList()).contains(ExtendedKey.fromDescriptor(newValue)))
+ (Control c, String newValue) -> {
+ if(getWalletForm().getWallet().getPolicyType() == PolicyType.SINGLE_SP || !ExtendedKey.isValid(newValue)) {
+ return new ValidationResult();
+ }
+
+ ExtendedKey extendedPublicKey = ExtendedKey.fromDescriptor(newValue);
+ return walletForm.getWallet().getKeystores().stream().filter(k -> k != keystore && extendedPublicKey.equals(k.getExtendedPublicKey())).findFirst()
+ .map(k -> ValidationResult.fromError(c, "Extended key matches " + k.getLabel())).orElseGet(ValidationResult::new);
+ }
));
validationSupport.registerValidator(spScan, Validator.combine(Why this scored 18/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.