diff --git a/src/main/java/com/sparrowwallet/sparrow/wallet/AddressesController.java b/src/main/java/com/sparrowwallet/sparrow/wallet/AddressesController.java index 65dd950f..d3e5a99e 100644 --- a/src/main/java/com/sparrowwallet/sparrow/wallet/AddressesController.java +++ b/src/main/java/com/sparrowwallet/sparrow/wallet/AddressesController.java @@ -3,6 +3,7 @@ package com.sparrowwallet.sparrow.wallet; import com.csvreader.CsvWriter; import com.google.common.eventbus.Subscribe; import com.sparrowwallet.drongo.KeyPurpose; +import com.sparrowwallet.drongo.wallet.Wallet; import com.sparrowwallet.drongo.wallet.WalletNode; import com.sparrowwallet.sparrow.AppServices; import com.sparrowwallet.sparrow.EventManager; @@ -20,10 +21,12 @@ import java.io.*; import java.net.URL; import java.nio.charset.StandardCharsets; import java.util.List; +import java.util.Optional; import java.util.ResourceBundle; public class AddressesController extends WalletFormController implements Initializable { private static final Logger log = LoggerFactory.getLogger(AddressesController.class); + public static final int DEFAULT_EXPORT_ADDRESSES_LENGTH = 250; @FXML private AddressTreeTable receiveTable; @@ -96,26 +99,36 @@ public class AddressesController extends WalletFormController implements Initial } public void exportReceiveAddresses(ActionEvent event) { - exportFile(); + exportAddresses(KeyPurpose.RECEIVE); } - private void exportFile() { + public void exportChangeAddresses(ActionEvent event) { + exportAddresses(KeyPurpose.CHANGE); + } + + private void exportAddresses(KeyPurpose keyPurpose) { Stage window = new Stage(); FileChooser fileChooser = new FileChooser(); - fileChooser.setTitle("Export Addresses File"); - String extension = "txt"; - fileChooser.setInitialFileName(getWalletForm().getWallet().getName() + "-addresses.txt"); + fileChooser.setTitle("Export Addresses to CSV"); + fileChooser.setInitialFileName(getWalletForm().getWallet().getName() + "-" + keyPurpose.name().toLowerCase() + "-addresses.txt"); + + Wallet copy = getWalletForm().getWallet().copy(); + WalletNode purposeNode = copy.getNode(keyPurpose); + purposeNode.fillToIndex(Math.max(purposeNode.getChildren().size(), DEFAULT_EXPORT_ADDRESSES_LENGTH)); File file = fileChooser.showSaveDialog(window); if(file != null) { try(FileOutputStream outputStream = new FileOutputStream(file)) { CsvWriter writer = new CsvWriter(outputStream, ',', StandardCharsets.UTF_8); - writer.writeRecord(new String[] {"Index", "Payment Address"}); - for(Entry entry : getWalletForm().getNodeEntry(KeyPurpose.RECEIVE).getChildren()) { - NodeEntry childEntry = (NodeEntry)entry; - writer.write(childEntry.getNode().getIndex() + ""); - writer.write(childEntry.getAddress().toString()); + writer.writeRecord(new String[] {"Index", "Payment Address", "Derivation", "Label"}); + for(WalletNode indexNode : purposeNode.getChildren()) { + writer.write(Integer.toString(indexNode.getIndex())); + writer.write(copy.getAddress(indexNode).toString()); + writer.write(getDerivationPath(indexNode)); + Optional optLabelEntry = getWalletForm().getNodeEntry(keyPurpose).getChildren().stream() + .filter(entry -> ((NodeEntry)entry).getNode().getIndex() == indexNode.getIndex()).findFirst(); + writer.write(optLabelEntry.isPresent() ? optLabelEntry.get().getLabel() : ""); writer.endRecord(); } writer.close(); diff --git a/src/main/java/com/sparrowwallet/sparrow/wallet/ReceiveController.java b/src/main/java/com/sparrowwallet/sparrow/wallet/ReceiveController.java index a6a61492..8e1cb2bb 100644 --- a/src/main/java/com/sparrowwallet/sparrow/wallet/ReceiveController.java +++ b/src/main/java/com/sparrowwallet/sparrow/wallet/ReceiveController.java @@ -117,20 +117,7 @@ public class ReceiveController extends WalletFormController implements Initializ } private void updateDerivationPath(NodeEntry nodeEntry) { - KeyDerivation firstDerivation = getWalletForm().getWallet().getKeystores().get(0).getKeyDerivation(); - boolean singleDerivationPath = true; - for(Keystore keystore : getWalletForm().getWallet().getKeystores()) { - if(!keystore.getKeyDerivation().getDerivationPath().equals(firstDerivation.getDerivationPath())) { - singleDerivationPath = false; - break; - } - } - - if(singleDerivationPath) { - derivationPath.setText(firstDerivation.extend(nodeEntry.getNode().getDerivation()).getDerivationPath()); - } else { - derivationPath.setText(nodeEntry.getNode().getDerivationPath().replace("m", "multi")); - } + derivationPath.setText(getDerivationPath(nodeEntry.getNode())); } private void updateLastUsed() { diff --git a/src/main/java/com/sparrowwallet/sparrow/wallet/WalletFormController.java b/src/main/java/com/sparrowwallet/sparrow/wallet/WalletFormController.java index 9d71a396..b59304dc 100644 --- a/src/main/java/com/sparrowwallet/sparrow/wallet/WalletFormController.java +++ b/src/main/java/com/sparrowwallet/sparrow/wallet/WalletFormController.java @@ -1,6 +1,9 @@ package com.sparrowwallet.sparrow.wallet; import com.google.common.eventbus.Subscribe; +import com.sparrowwallet.drongo.KeyDerivation; +import com.sparrowwallet.drongo.wallet.Keystore; +import com.sparrowwallet.drongo.wallet.WalletNode; import com.sparrowwallet.sparrow.BaseController; import com.sparrowwallet.sparrow.EventManager; import com.sparrowwallet.sparrow.WalletTabData; @@ -30,4 +33,24 @@ public abstract class WalletFormController extends BaseController { } } } + + protected boolean isSingleDerivationPath() { + KeyDerivation firstDerivation = getWalletForm().getWallet().getKeystores().get(0).getKeyDerivation(); + for(Keystore keystore : getWalletForm().getWallet().getKeystores()) { + if(!keystore.getKeyDerivation().getDerivationPath().equals(firstDerivation.getDerivationPath())) { + return false; + } + } + + return true; + } + + protected String getDerivationPath(WalletNode node) { + if(isSingleDerivationPath()) { + KeyDerivation firstDerivation = getWalletForm().getWallet().getKeystores().get(0).getKeyDerivation(); + return firstDerivation.extend(node.getDerivation()).getDerivationPath(); + } + + return node.getDerivationPath().replace("m", "multi"); + } } diff --git a/src/main/resources/com/sparrowwallet/sparrow/general.css b/src/main/resources/com/sparrowwallet/sparrow/general.css index cb3310dd..6d510fa4 100644 --- a/src/main/resources/com/sparrowwallet/sparrow/general.css +++ b/src/main/resources/com/sparrowwallet/sparrow/general.css @@ -171,4 +171,16 @@ .alert .content.label { -fx-padding: 20px 20px 20px 20px; +} + +.icon-button { + -fx-border-style: none; + -fx-border-width: 0; + -fx-border-insets: 0; + -fx-background-color: transparent; + -fx-opacity: 0.7; +} + +.icon-button:hover { + -fx-opacity: 1.0; } \ No newline at end of file diff --git a/src/main/resources/com/sparrowwallet/sparrow/wallet/addresses.fxml b/src/main/resources/com/sparrowwallet/sparrow/wallet/addresses.fxml index 8d869ce1..c9cf57dc 100644 --- a/src/main/resources/com/sparrowwallet/sparrow/wallet/addresses.fxml +++ b/src/main/resources/com/sparrowwallet/sparrow/wallet/addresses.fxml @@ -8,6 +8,8 @@ + + @@ -21,14 +23,17 @@ - - - - - +
@@ -36,7 +41,17 @@ -
diff --git a/src/main/resources/com/sparrowwallet/sparrow/wallet/transactions.css b/src/main/resources/com/sparrowwallet/sparrow/wallet/transactions.css index a324d0b4..afbf945e 100644 --- a/src/main/resources/com/sparrowwallet/sparrow/wallet/transactions.css +++ b/src/main/resources/com/sparrowwallet/sparrow/wallet/transactions.css @@ -23,15 +23,3 @@ .chart-line-symbol.selected { -fx-background-color: rgba(30, 136, 207, 0.6); } - -#exportCsv { - -fx-border-style: none; - -fx-border-width: 0; - -fx-border-insets: 0; - -fx-background-color: transparent; - -fx-opacity: 0.7; -} - -#exportCsv:hover { - -fx-opacity: 1.0; -} \ No newline at end of file diff --git a/src/main/resources/com/sparrowwallet/sparrow/wallet/transactions.fxml b/src/main/resources/com/sparrowwallet/sparrow/wallet/transactions.fxml index 590505ad..15ae32f8 100644 --- a/src/main/resources/com/sparrowwallet/sparrow/wallet/transactions.fxml +++ b/src/main/resources/com/sparrowwallet/sparrow/wallet/transactions.fxml @@ -41,7 +41,7 @@ -