add wallet export to electrum personal server config file

This commit is contained in:
Craig Raw 2022-08-22 14:33:03 +02:00
parent bd421e877a
commit d139ca2706
7 changed files with 118 additions and 4 deletions

2
drongo

@ -1 +1 @@
Subproject commit aa459d0084b3cc72c49c8922d571338c4f5efaf4 Subproject commit 311afd0409b7cb442e5ee1efebdc3c7dd628346a

View file

@ -42,9 +42,9 @@ public class WalletExportDialog extends Dialog<Wallet> {
List<WalletExport> exporters; List<WalletExport> exporters;
if(wallet.getPolicyType() == PolicyType.SINGLE) { if(wallet.getPolicyType() == PolicyType.SINGLE) {
exporters = List.of(new Electrum(), new Descriptor(), new SpecterDesktop(), new Sparrow()); exporters = List.of(new Electrum(), new ElectrumPersonalServer(), new Descriptor(), new SpecterDesktop(), new Sparrow());
} else if(wallet.getPolicyType() == PolicyType.MULTI) { } else if(wallet.getPolicyType() == PolicyType.MULTI) {
exporters = List.of(new CaravanMultisig(), new ColdcardMultisig(), new CoboVaultMultisig(), new Electrum(), new KeystoneMultisig(), new Descriptor(), new PassportMultisig(), new SpecterDesktop(), new BlueWalletMultisig(), new SpecterDIY(), new Sparrow()); exporters = List.of(new CaravanMultisig(), new ColdcardMultisig(), new CoboVaultMultisig(), new Electrum(), new ElectrumPersonalServer(), new KeystoneMultisig(), new Descriptor(), new PassportMultisig(), new SpecterDesktop(), new BlueWalletMultisig(), new SpecterDIY(), new Sparrow());
} else { } else {
throw new UnsupportedOperationException("Cannot export wallet with policy type " + wallet.getPolicyType()); throw new UnsupportedOperationException("Cannot export wallet with policy type " + wallet.getPolicyType());
} }

View file

@ -0,0 +1,114 @@
package com.sparrowwallet.sparrow.io;
import com.sparrowwallet.drongo.ExtendedKey;
import com.sparrowwallet.drongo.KeyPurpose;
import com.sparrowwallet.drongo.policy.PolicyType;
import com.sparrowwallet.drongo.protocol.ScriptType;
import com.sparrowwallet.drongo.wallet.Keystore;
import com.sparrowwallet.drongo.wallet.Wallet;
import com.sparrowwallet.drongo.wallet.WalletModel;
import com.sparrowwallet.drongo.wallet.WalletNode;
import java.io.BufferedWriter;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;
public class ElectrumPersonalServer implements WalletExport {
@Override
public String getName() {
return "Electrum Personal Server";
}
@Override
public WalletModel getWalletModel() {
return WalletModel.EPS;
}
@Override
public void exportWallet(Wallet wallet, OutputStream outputStream) throws ExportException {
if(wallet.getScriptType() == ScriptType.P2TR) {
throw new ExportException(getName() + " does not support Taproot wallets.");
}
try {
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream, StandardCharsets.UTF_8));
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 into [master-public-keys] section\n");
writer.write(wallet.getFullName().replace(' ', '_') + " = ");
ExtendedKey.Header xpubHeader = ExtendedKey.Header.fromScriptType(wallet.getScriptType(), false);
if(wallet.getPolicyType() == PolicyType.MULTI) {
writer.write(wallet.getDefaultPolicy().getNumSignaturesRequired() + " ");
}
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();
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(" ");
}
}
if(purposeIterator.hasNext()) {
writer.write(" ");
}
}
writer.newLine();
}
}
writer.write("\n# Important: If this wallet receives any BIP47 payments, redo this export");
}
writer.flush();
} catch(Exception e) {
throw new ExportException("Could not export wallet", e);
}
}
@Override
public String getWalletExportDescription() {
return "Export this wallet as a configuration file fragment to copy into your Electrum Personal Server (EPS) config.ini file.";
}
@Override
public String getExportFileExtension(Wallet wallet) {
return "ini";
}
@Override
public boolean isWalletExportScannable() {
return false;
}
@Override
public boolean walletExportRequiresDecryption() {
return false;
}
}

View file

@ -364,7 +364,7 @@ public class ElectrumServer {
} }
private int getGapLimitSize(Wallet wallet, Map<WalletNode, Set<BlockTransactionHash>> nodeTransactionMap) { private int getGapLimitSize(Wallet wallet, Map<WalletNode, Set<BlockTransactionHash>> nodeTransactionMap) {
int highestIndex = nodeTransactionMap.keySet().stream().map(WalletNode::getIndex).max(Comparator.comparing(Integer::valueOf)).orElse(-1); int highestIndex = nodeTransactionMap.keySet().stream().filter(node -> node.getDerivation().size() > 1).map(WalletNode::getIndex).max(Comparator.comparing(Integer::valueOf)).orElse(-1);
return highestIndex + wallet.getGapLimit() + 1; return highestIndex + wallet.getGapLimit() + 1;
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB