mirror of
https://github.com/sparrowwallet/sparrow.git
synced 2024-12-24 12:46:45 +00:00
add wallet export to electrum personal server config file
This commit is contained in:
parent
bd421e877a
commit
d139ca2706
7 changed files with 118 additions and 4 deletions
2
drongo
2
drongo
|
@ -1 +1 @@
|
|||
Subproject commit aa459d0084b3cc72c49c8922d571338c4f5efaf4
|
||||
Subproject commit 311afd0409b7cb442e5ee1efebdc3c7dd628346a
|
|
@ -42,9 +42,9 @@ public class WalletExportDialog extends Dialog<Wallet> {
|
|||
|
||||
List<WalletExport> exporters;
|
||||
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) {
|
||||
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 {
|
||||
throw new UnsupportedOperationException("Cannot export wallet with policy type " + wallet.getPolicyType());
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -364,7 +364,7 @@ public class ElectrumServer {
|
|||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
BIN
src/main/resources/image/eps.png
Normal file
BIN
src/main/resources/image/eps.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.1 KiB |
BIN
src/main/resources/image/eps@2x.png
Normal file
BIN
src/main/resources/image/eps@2x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.8 KiB |
BIN
src/main/resources/image/eps@3x.png
Normal file
BIN
src/main/resources/image/eps@3x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.5 KiB |
Loading…
Reference in a new issue