mirror of
https://github.com/sparrowwallet/sparrow.git
synced 2024-12-25 21:26:43 +00:00
support reading revised ur tags including v3 output descriptors
This commit is contained in:
parent
20df1dbd8b
commit
2b8a513adf
3 changed files with 69 additions and 2 deletions
|
@ -89,7 +89,7 @@ dependencies {
|
||||||
implementation('com.github.arteam:simple-json-rpc-server:1.3') {
|
implementation('com.github.arteam:simple-json-rpc-server:1.3') {
|
||||||
exclude group: 'org.slf4j'
|
exclude group: 'org.slf4j'
|
||||||
}
|
}
|
||||||
implementation('com.sparrowwallet:hummingbird:1.6.7')
|
implementation('com.sparrowwallet:hummingbird:1.7.3')
|
||||||
implementation('co.nstant.in:cbor:0.9')
|
implementation('co.nstant.in:cbor:0.9')
|
||||||
implementation("com.nativelibs4java:bridj${targetName}:0.7-20140918-3") {
|
implementation("com.nativelibs4java:bridj${targetName}:0.7-20140918-3") {
|
||||||
exclude group: 'com.google.android.tools', module: 'dx'
|
exclude group: 'com.google.android.tools', module: 'dx'
|
||||||
|
|
2
drongo
2
drongo
|
@ -1 +1 @@
|
||||||
Subproject commit 6f90d0fa82d1f64444a9c16b068fd76bb19633eb
|
Subproject commit 78944a7114f5e22d0622dd07ca426e04acdce5b7
|
|
@ -442,6 +442,39 @@ public class QRScanDialog extends Dialog<QRScanDialog.Result> {
|
||||||
CryptoBip39 cryptoBip39 = (CryptoBip39)ur.decodeFromRegistry();
|
CryptoBip39 cryptoBip39 = (CryptoBip39)ur.decodeFromRegistry();
|
||||||
DeterministicSeed seed = getSeed(cryptoBip39);
|
DeterministicSeed seed = getSeed(cryptoBip39);
|
||||||
return new Result(seed);
|
return new Result(seed);
|
||||||
|
} else if(urRegistryType.equals(RegistryType.PSBT)) {
|
||||||
|
URPSBT urPSBT = (URPSBT)ur.decodeFromRegistry();
|
||||||
|
try {
|
||||||
|
PSBT psbt = new PSBT(urPSBT.getPsbt(), false);
|
||||||
|
return new Result(psbt);
|
||||||
|
} catch(Exception e) {
|
||||||
|
log.error("Error parsing PSBT from UR type " + urRegistryType, e);
|
||||||
|
return new Result(new URException("Error parsing PSBT from UR type " + urRegistryType, e));
|
||||||
|
}
|
||||||
|
} else if(urRegistryType.equals(RegistryType.ADDRESS)) {
|
||||||
|
URAddress urAddress = (URAddress)ur.decodeFromRegistry();
|
||||||
|
Address address = getAddress(urAddress);
|
||||||
|
if(address != null) {
|
||||||
|
return new Result(BitcoinURI.fromAddress(address));
|
||||||
|
} else {
|
||||||
|
return new Result(new URException("Unknown " + urRegistryType + " type of " + urAddress.getType()));
|
||||||
|
}
|
||||||
|
} else if(urRegistryType.equals(RegistryType.HDKEY)) {
|
||||||
|
URHDKey urHDKey = (URHDKey)ur.decodeFromRegistry();
|
||||||
|
ExtendedKey extendedKey = getExtendedKey(urHDKey);
|
||||||
|
return new Result(extendedKey, urHDKey.getName());
|
||||||
|
} else if(urRegistryType.equals(RegistryType.OUTPUT_DESCRIPTOR)) {
|
||||||
|
UROutputDescriptor urOutputDescriptor = (UROutputDescriptor)ur.decodeFromRegistry();
|
||||||
|
OutputDescriptor outputDescriptor = getOutputDescriptor(urOutputDescriptor);
|
||||||
|
return new Result(outputDescriptor);
|
||||||
|
} else if(urRegistryType.equals(RegistryType.ACCOUNT_DESCRIPTOR)) {
|
||||||
|
URAccountDescriptor urAccountDescriptor = (URAccountDescriptor)ur.decodeFromRegistry();
|
||||||
|
List<Wallet> wallets = getWallets(urAccountDescriptor);
|
||||||
|
return new Result(wallets);
|
||||||
|
} else if(urRegistryType.equals(RegistryType.SEED)) {
|
||||||
|
URSeed urSeed = (URSeed)ur.decodeFromRegistry();
|
||||||
|
DeterministicSeed seed = getSeed(urSeed);
|
||||||
|
return new Result(seed);
|
||||||
} else {
|
} else {
|
||||||
log.error("Unsupported UR type " + urRegistryType);
|
log.error("Unsupported UR type " + urRegistryType);
|
||||||
return new Result(new URException("UR type " + urRegistryType + " is not supported"));
|
return new Result(new URException("UR type " + urRegistryType + " is not supported"));
|
||||||
|
@ -584,6 +617,40 @@ public class QRScanDialog extends Dialog<QRScanDialog.Result> {
|
||||||
private DeterministicSeed getSeed(CryptoBip39 cryptoBip39) {
|
private DeterministicSeed getSeed(CryptoBip39 cryptoBip39) {
|
||||||
return new DeterministicSeed(cryptoBip39.getWords(), null, System.currentTimeMillis(), DeterministicSeed.Type.BIP39);
|
return new DeterministicSeed(cryptoBip39.getWords(), null, System.currentTimeMillis(), DeterministicSeed.Type.BIP39);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private OutputDescriptor getOutputDescriptor(UROutputDescriptor urOutputDescriptor) {
|
||||||
|
String source = urOutputDescriptor.getSource();
|
||||||
|
List<RegistryItem> keys = urOutputDescriptor.getKeys();
|
||||||
|
Map<ExtendedKey, String> mapExtendedPublicKeyLabels = new LinkedHashMap<>();
|
||||||
|
|
||||||
|
for(int i = 0; i < keys.size(); i++) {
|
||||||
|
RegistryItem key = keys.get(i);
|
||||||
|
if(key instanceof URHDKey urhdKey) {
|
||||||
|
ExtendedKey extendedKey = getExtendedKey(urhdKey);
|
||||||
|
KeyDerivation keyDerivation = getKeyDerivation(urhdKey.getOrigin());
|
||||||
|
source = source.replaceAll("@" + i, OutputDescriptor.writeKey(extendedKey, keyDerivation, null, true, true));
|
||||||
|
if(urhdKey.getName() != null) {
|
||||||
|
mapExtendedPublicKeyLabels.put(extendedKey, urhdKey.getName());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Only extended HD keys are supported in output descriptors");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return OutputDescriptor.getOutputDescriptor(source, mapExtendedPublicKeyLabels);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Wallet> getWallets(URAccountDescriptor urAccountDescriptor) {
|
||||||
|
List<Wallet> wallets = new ArrayList<>();
|
||||||
|
String masterFingerprint = Utils.bytesToHex(urAccountDescriptor.getMasterFingerprint());
|
||||||
|
for(UROutputDescriptor urOutputDescriptor : urAccountDescriptor.getOutputDescriptors()) {
|
||||||
|
OutputDescriptor outputDescriptor = getOutputDescriptor(urOutputDescriptor);
|
||||||
|
Wallet wallet = outputDescriptor.toKeystoreWallet(masterFingerprint);
|
||||||
|
wallets.add(wallet);
|
||||||
|
}
|
||||||
|
|
||||||
|
return wallets;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class QRScanListener implements WebcamListener {
|
private class QRScanListener implements WebcamListener {
|
||||||
|
|
Loading…
Reference in a new issue