export all related wallets when exporting to electrum personal server

This commit is contained in:
Craig Raw 2022-08-23 08:48:35 +02:00
parent d139ca2706
commit c24f953e52
4 changed files with 72 additions and 42 deletions

View file

@ -82,7 +82,7 @@ public class FileWalletExportPane extends TitledDescriptionPane {
fileChooser.setTitle("Export " + exporter.getWalletModel().toDisplayString() + " File"); fileChooser.setTitle("Export " + exporter.getWalletModel().toDisplayString() + " File");
String extension = exporter.getExportFileExtension(wallet); String extension = exporter.getExportFileExtension(wallet);
String fileName = wallet.getFullName() + "-" + exporter.getWalletModel().toDisplayString().toLowerCase(Locale.ROOT).replace(" ", ""); String fileName = wallet.getFullName() + "-" + exporter.getWalletModel().toDisplayString().toLowerCase(Locale.ROOT).replace(" ", "");
if(exporter instanceof Sparrow) { if(exporter.exportsAllWallets()) {
fileName = wallet.getMasterName(); fileName = wallet.getMasterName();
} }
fileChooser.setInitialFileName(fileName + (extension == null || extension.isEmpty() ? "" : "." + extension)); fileChooser.setInitialFileName(fileName + (extension == null || extension.isEmpty() ? "" : "." + extension));

View file

@ -4,18 +4,20 @@ import com.sparrowwallet.drongo.ExtendedKey;
import com.sparrowwallet.drongo.KeyPurpose; import com.sparrowwallet.drongo.KeyPurpose;
import com.sparrowwallet.drongo.policy.PolicyType; import com.sparrowwallet.drongo.policy.PolicyType;
import com.sparrowwallet.drongo.protocol.ScriptType; import com.sparrowwallet.drongo.protocol.ScriptType;
import com.sparrowwallet.drongo.wallet.Keystore; import com.sparrowwallet.drongo.wallet.*;
import com.sparrowwallet.drongo.wallet.Wallet; import org.slf4j.Logger;
import com.sparrowwallet.drongo.wallet.WalletModel; import org.slf4j.LoggerFactory;
import com.sparrowwallet.drongo.wallet.WalletNode;
import java.io.BufferedWriter; import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.OutputStreamWriter; import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.Iterator; import java.util.Iterator;
public class ElectrumPersonalServer implements WalletExport { public class ElectrumPersonalServer implements WalletExport {
private static final Logger log = LoggerFactory.getLogger(ElectrumPersonalServer.class);
@Override @Override
public String getName() { public String getName() {
return "Electrum Personal Server"; return "Electrum Personal Server";
@ -37,58 +39,73 @@ public class ElectrumPersonalServer implements WalletExport {
writer.write("# Electrum Personal Server configuration file fragments\n"); writer.write("# Electrum Personal Server configuration file fragments\n");
writer.write("# Copy the lines below into the relevant sections in your EPS config.ini file\n\n"); writer.write("# Copy the lines below into the relevant sections in your EPS config.ini file\n\n");
writer.write("# Copy into [master-public-keys] section\n"); writer.write("# Copy into [master-public-keys] section\n");
writer.write(wallet.getFullName().replace(' ', '_') + " = "); Wallet masterWallet = wallet.isMasterWallet() ? wallet : wallet.getMasterWallet();
writeWalletXpub(masterWallet, writer);
ExtendedKey.Header xpubHeader = ExtendedKey.Header.fromScriptType(wallet.getScriptType(), false); for(Wallet childWallet : masterWallet.getChildWallets()) {
if(wallet.getPolicyType() == PolicyType.MULTI) { if(!childWallet.isNested()) {
writer.write(wallet.getDefaultPolicy().getNumSignaturesRequired() + " "); writeWalletXpub(childWallet, writer);
}
for(Iterator<Keystore> iter = wallet.getKeystores().iterator(); iter.hasNext(); ) {
Keystore keystore = iter.next();
writer.write(keystore.getExtendedPublicKey().toString(xpubHeader));
if(iter.hasNext()) {
writer.write(" ");
} }
} }
writer.newLine(); writeBip47Addresses(masterWallet, writer);
if(wallet.hasPaymentCode()) { writer.flush();
writer.write("\n# Copy into [watch-only-addresses] section\n"); } catch(Exception e) {
WalletNode notificationNode = wallet.getNotificationWallet().getNode(KeyPurpose.NOTIFICATION); log.error("Could not export EPS wallet", e);
writer.write(wallet.getFullName().replace(' ', '_') + "-notification_addr = " + notificationNode.getAddress().toString() + "\n"); throw new ExportException("Could not export EPS wallet", e);
}
}
for(Wallet childWallet : wallet.getChildWallets()) { private static void writeWalletXpub(Wallet wallet, BufferedWriter writer) throws IOException {
if(childWallet.isBip47()) { writer.write(wallet.getFullName().replace(' ', '_') + " = ");
writer.write(childWallet.getFullName().replace(' ', '_') + " = ");
for(Iterator<KeyPurpose> purposeIterator = KeyPurpose.DEFAULT_PURPOSES.iterator(); purposeIterator.hasNext(); ) {
KeyPurpose keyPurpose = purposeIterator.next();
for(Iterator<WalletNode> iter = childWallet.getNode(keyPurpose).getChildren().iterator(); iter.hasNext(); ) {
WalletNode receiveNode = iter.next();
writer.write(receiveNode.getAddress().toString());
if(iter.hasNext()) { ExtendedKey.Header xpubHeader = ExtendedKey.Header.fromScriptType(wallet.getScriptType(), false);
writer.write(" "); if(wallet.getPolicyType() == PolicyType.MULTI) {
} writer.write(wallet.getDefaultPolicy().getNumSignaturesRequired() + " ");
} }
if(purposeIterator.hasNext()) { for(Iterator<Keystore> iter = wallet.getKeystores().iterator(); iter.hasNext(); ) {
Keystore keystore = iter.next();
writer.write(keystore.getExtendedPublicKey().toString(xpubHeader));
if(iter.hasNext()) {
writer.write(" ");
}
}
writer.newLine();
}
private static void writeBip47Addresses(Wallet wallet, BufferedWriter writer) throws IOException {
if(wallet.hasPaymentCode()) {
writer.write("\n# Copy into [watch-only-addresses] section\n");
WalletNode notificationNode = wallet.getNotificationWallet().getNode(KeyPurpose.NOTIFICATION);
writer.write(wallet.getFullName().replace(' ', '_') + "-notification_addr = " + notificationNode.getAddress().toString() + "\n");
for(Wallet childWallet : wallet.getChildWallets()) {
if(childWallet.isBip47()) {
writer.write(childWallet.getFullName().replace(' ', '_') + " = ");
for(Iterator<KeyPurpose> purposeIterator = KeyPurpose.DEFAULT_PURPOSES.iterator(); purposeIterator.hasNext(); ) {
KeyPurpose keyPurpose = purposeIterator.next();
for(Iterator<WalletNode> iter = childWallet.getNode(keyPurpose).getChildren().iterator(); iter.hasNext(); ) {
WalletNode receiveNode = iter.next();
writer.write(receiveNode.getAddress().toString());
if(iter.hasNext()) {
writer.write(" "); writer.write(" ");
} }
} }
writer.newLine(); if(purposeIterator.hasNext()) {
writer.write(" ");
}
} }
}
writer.write("\n# Important: If this wallet receives any BIP47 payments, redo this export"); writer.newLine();
}
} }
writer.flush(); writer.write("\n# Important: If this wallet receives any BIP47 payments, redo this export");
} catch(Exception e) {
throw new ExportException("Could not export wallet", e);
} }
} }
@ -111,4 +128,9 @@ public class ElectrumPersonalServer implements WalletExport {
public boolean walletExportRequiresDecryption() { public boolean walletExportRequiresDecryption() {
return false; return false;
} }
@Override
public boolean exportsAllWallets() {
return true;
}
} }

View file

@ -144,4 +144,9 @@ public class Sparrow implements WalletImport, WalletExport {
public boolean isWalletImportScannable() { public boolean isWalletImportScannable() {
return false; return false;
} }
@Override
public boolean exportsAllWallets() {
return true;
}
} }

View file

@ -10,4 +10,7 @@ public interface WalletExport extends Export {
String getExportFileExtension(Wallet wallet); String getExportFileExtension(Wallet wallet);
boolean isWalletExportScannable(); boolean isWalletExportScannable();
boolean walletExportRequiresDecryption(); boolean walletExportRequiresDecryption();
default boolean exportsAllWallets() {
return false;
}
} }