fix handling of non-standard key derivations when writing output descriptors
What changed, and why it matters
This commit fixes how Sparrow Wallet writes output descriptors when a wallet uses a non-standard key derivation path. Previously, the code stripped the leading 'm/' from the derivation path in a simplistic way, which could produce incorrect descriptors for unusual paths. The fix now uses a dedicated parser/formatter (KeyDerivation.parsePath/writePath) to handle the path correctly. This is primarily a correctness/reliability fix, but incorrect descriptors could in theory lead to users backing up or sharing wrong wallet configuration data.
Review the drongo submodule update to confirm KeyDerivation.parsePath/writePath handle all edge cases (hardened markers, empty paths, non-standard prefixes). Add tests for non-standard derivation paths in output descriptors. Users relying on wallet exports with custom derivations should verify generated descriptors after upgrading.
Security signals we found
Incorrect output descriptor generation for non-standard derivation paths
Potential for wallet backup/export data to be malformed
Fix uses structured parsing instead of regex normalization
Evidence from the diff
The change replaces a regex-based derivation path normalization with a round-trip through KeyDerivation.parsePath() and KeyDerivation.writePath(). The old code did .replaceFirst(“^m?/”, “”) then prepended ‘/’, which assumes a standard m/… path. For non-standard or edge-case derivations, this could produce an invalid or misleading [fingerprint/path]xpub fragment in output descriptors. The new approach parses the path into a structured form and writes it back, dropping only the leading ‘m’ via substring(1). The drongo submodule reference was also updated, likely to include the new KeyDerivation helpers.
Changed components
BaseController.javaOutput descriptor generationWallet export/backup code pathsdrongo submodule (KeyDerivation class)Inspect captured patch +3 / −3
diff --git a/src/main/java/com/sparrowwallet/sparrow/BaseController.java b/src/main/java/com/sparrowwallet/sparrow/BaseController.java
index 3b7f4fa..7263ef2 100644
--- a/src/main/java/com/sparrowwallet/sparrow/BaseController.java
+++ b/src/main/java/com/sparrowwallet/sparrow/BaseController.java
@@ -1,5 +1,6 @@
package com.sparrowwallet.sparrow;
+import com.sparrowwallet.drongo.KeyDerivation;
import com.sparrowwallet.drongo.policy.PolicyType;
import com.sparrowwallet.drongo.protocol.ScriptChunk;
import com.sparrowwallet.drongo.wallet.Keystore;
@@ -72,8 +73,7 @@ public abstract class BaseController {
StringBuilder builder = new StringBuilder();
builder.append("[");
builder.append(keystore.getKeyDerivation().getMasterFingerprint());
- builder.append("/");
- builder.append(keystore.getKeyDerivation().getDerivationPath().replaceFirst("^m?/", ""));
+ builder.append(KeyDerivation.writePath(KeyDerivation.parsePath(keystore.getKeyDerivation().getDerivationPath())).substring(1));
builder.append("]");
builder.append(keystore.getExtendedPublicKey().toString());
Why this scored 32/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.