diff --git a/src/main/java/io/bitsquare/btc/AddressBasedCoinSelector.java b/src/main/java/io/bitsquare/btc/AddressBasedCoinSelector.java index ccc1d85ee7..11aed37ac3 100644 --- a/src/main/java/io/bitsquare/btc/AddressBasedCoinSelector.java +++ b/src/main/java/io/bitsquare/btc/AddressBasedCoinSelector.java @@ -54,7 +54,7 @@ public class AddressBasedCoinSelector extends DefaultCoinSelector protected boolean matchesRequiredAddress(TransactionOutput transactionOutput) { - if (!ScriptUtil.isOpReturnScript(transactionOutput)) + if (transactionOutput.getScriptPubKey().isSentToAddress() || transactionOutput.getScriptPubKey().isSentToP2SH()) { Address addressOutput = transactionOutput.getScriptPubKey().getToAddress(params); if (addressInfo != null && addressOutput.equals(addressInfo.getAddress())) diff --git a/src/main/java/io/bitsquare/btc/AddressInfo.java b/src/main/java/io/bitsquare/btc/AddressInfo.java index 774c083843..9e110f0797 100644 --- a/src/main/java/io/bitsquare/btc/AddressInfo.java +++ b/src/main/java/io/bitsquare/btc/AddressInfo.java @@ -22,22 +22,15 @@ public class AddressInfo implements Serializable private ECKey key; private NetworkParameters params; - private String label; private String tradeId = null; private AddressContext addressContext; - public AddressInfo(ECKey key, NetworkParameters params, AddressContext addressContext, String label) + public AddressInfo(ECKey key, NetworkParameters params, AddressContext addressContext) { this.key = key; this.params = params; this.addressContext = addressContext; - this.label = label; - } - - public void setLabel(String label) - { - this.label = label; } public void setTradeId(String tradeId) @@ -50,12 +43,6 @@ public class AddressInfo implements Serializable return tradeId; } - - public String getLabel() - { - return label; - } - public AddressContext getAddressContext() { return addressContext; diff --git a/src/main/java/io/bitsquare/btc/ScriptUtil.java b/src/main/java/io/bitsquare/btc/ScriptUtil.java deleted file mode 100644 index 440e74a62f..0000000000 --- a/src/main/java/io/bitsquare/btc/ScriptUtil.java +++ /dev/null @@ -1,26 +0,0 @@ -package io.bitsquare.btc; - -import com.google.bitcoin.core.TransactionOutput; -import com.google.bitcoin.script.Script; -import com.google.bitcoin.script.ScriptBuilder; -import com.google.bitcoin.script.ScriptOpCodes; - -import static com.google.bitcoin.script.ScriptOpCodes.OP_RETURN; - -public class ScriptUtil -{ - public static Script getOpReturnScript() - { - return new ScriptBuilder().op(OP_RETURN).build(); - } - - public static Script getOpReturnScriptWithData(byte[] data) - { - return new ScriptBuilder().op(OP_RETURN).data(data).build(); - } - - public static boolean isOpReturnScript(TransactionOutput transactionOutput) - { - return transactionOutput.getScriptPubKey().getChunks().get(0).equalsOpCode(ScriptOpCodes.OP_RETURN); - } -} diff --git a/src/main/java/io/bitsquare/btc/WalletFacade.java b/src/main/java/io/bitsquare/btc/WalletFacade.java index 5cdea406be..06b29dd3dd 100644 --- a/src/main/java/io/bitsquare/btc/WalletFacade.java +++ b/src/main/java/io/bitsquare/btc/WalletFacade.java @@ -30,6 +30,8 @@ import java.math.BigInteger; import java.util.*; import java.util.concurrent.ExecutionException; +import static com.google.bitcoin.script.ScriptOpCodes.OP_RETURN; + public class WalletFacade { public static final String MAIN_NET = "MAIN_NET"; @@ -128,6 +130,7 @@ public class WalletFacade public void onTransactionConfidenceChanged(Wallet wallet, Transaction tx) { log.debug("onTransactionConfidenceChanged " + tx.getConfidence()); + log.debug("onTransactionConfidenceChanged " + tx); notifyConfidenceListeners(tx); } @@ -168,7 +171,7 @@ public class WalletFacade else { ECKey registrationKey = wallet.getKeys().get(0); - AddressInfo registrationAddressInfo = new AddressInfo(registrationKey, params, AddressInfo.AddressContext.REGISTRATION_FEE, "Registration"); + AddressInfo registrationAddressInfo = new AddressInfo(registrationKey, params, AddressInfo.AddressContext.REGISTRATION_FEE); addressInfoList.add(registrationAddressInfo); saveAddressInfoList(); @@ -241,13 +244,15 @@ public class WalletFacade for (int n = 0; n < transactionOutputs.size(); n++) { TransactionOutput transactionOutput = transactionOutputs.get(n); - if (!ScriptUtil.isOpReturnScript(transactionOutput)) + if (transactionOutput.getScriptPubKey().isSentToAddress() || transactionOutput.getScriptPubKey().isSentToP2SH()) { Address address = transactionOutput.getScriptPubKey().getToAddress(params); if (address.equals(confidenceListener.getAddress())) { + log.debug("notifyConfidenceListeners address " + address.toString() + " / " + tx.getConfidence()); confidenceListener.onTransactionConfidenceChanged(tx.getConfidence()); } + } } } @@ -262,7 +267,7 @@ public class WalletFacade for (int n = 0; n < transactionOutputs.size(); n++) { TransactionOutput transactionOutput = transactionOutputs.get(n); - if (!ScriptUtil.isOpReturnScript(transactionOutput)) + if (transactionOutput.getScriptPubKey().isSentToAddress() || transactionOutput.getScriptPubKey().isSentToP2SH()) { Address address = transactionOutput.getScriptPubKey().getToAddress(params); if (address.equals(balanceListener.getAddress())) @@ -324,9 +329,9 @@ public class WalletFacade if (filteredList != null && filteredList.size() > 0) return filteredList.get(0); else - return null; + return getNewTradeAddressInfo(); } - return null; + return getNewTradeAddressInfo(); } private AddressInfo getAddressInfoByAddressContext(AddressInfo.AddressContext addressContext) @@ -363,20 +368,21 @@ public class WalletFacade return addressInfo; } + /////////////////////////////////////////////////////////////////////////////////////////// // Create new AddressInfo objects /////////////////////////////////////////////////////////////////////////////////////////// public AddressInfo getNewTradeAddressInfo() { - return getNewAddressInfo(AddressInfo.AddressContext.TRADE, "New trade"); + return getNewAddressInfo(AddressInfo.AddressContext.TRADE); } - private AddressInfo getNewAddressInfo(AddressInfo.AddressContext addressContext, String label) + private AddressInfo getNewAddressInfo(AddressInfo.AddressContext addressContext) { ECKey key = new ECKey(); wallet.addKey(key); - AddressInfo addressInfo = new AddressInfo(key, params, addressContext, label); + AddressInfo addressInfo = new AddressInfo(key, params, addressContext); addressInfoList.add(addressInfo); saveAddressInfoList(); return addressInfo; @@ -384,17 +390,17 @@ public class WalletFacade private AddressInfo getNewOfferFeeAddressInfo() { - return getNewAddressInfo(AddressInfo.AddressContext.CREATE_OFFER_FEE, "Create offer fee"); + return getNewAddressInfo(AddressInfo.AddressContext.CREATE_OFFER_FEE); } private AddressInfo getNewTakerFeeAddressInfo() { - return getNewAddressInfo(AddressInfo.AddressContext.TAKE_OFFER_FEE, "Take offer fee"); + return getNewAddressInfo(AddressInfo.AddressContext.TAKE_OFFER_FEE); } private AddressInfo getNewArbitratorDepositAddressInfo() { - return getNewAddressInfo(AddressInfo.AddressContext.ARBITRATOR_DEPOSIT, "Arbitrator deposit"); + return getNewAddressInfo(AddressInfo.AddressContext.ARBITRATOR_DEPOSIT); } @@ -413,7 +419,7 @@ public class WalletFacade for (int n = 0; n < transactionOutputs.size(); n++) { TransactionOutput transactionOutput = transactionOutputs.get(n); - if (!ScriptUtil.isOpReturnScript(transactionOutput)) + if (transactionOutput.getScriptPubKey().isSentToAddress() || transactionOutput.getScriptPubKey().isSentToP2SH()) { Address addressOutput = transactionOutput.getScriptPubKey().getToAddress(params); if (addressOutput.equals(address)) @@ -442,7 +448,7 @@ public class WalletFacade BigInteger value = BigInteger.ZERO; for (TransactionOutput transactionOutput : all) { - if (!ScriptUtil.isOpReturnScript(transactionOutput)) + if (transactionOutput.getScriptPubKey().isSentToAddress() || transactionOutput.getScriptPubKey().isSentToP2SH()) { Address addressOutput = transactionOutput.getScriptPubKey().getToAddress(params); if (addressOutput.equals(address)) @@ -495,8 +501,8 @@ public class WalletFacade Transaction tx = new Transaction(params); - byte[] dataToEmbed = cryptoFacade.getEmbeddedAccountRegistrationData(getRegistrationAddressInfo().getKey(), stringifiedBankAccounts); - tx.addOutput(Transaction.MIN_NONDUST_OUTPUT, ScriptUtil.getOpReturnScriptWithData(dataToEmbed)); + byte[] data = cryptoFacade.getEmbeddedAccountRegistrationData(getRegistrationAddressInfo().getKey(), stringifiedBankAccounts); + tx.addOutput(Transaction.MIN_NONDUST_OUTPUT, new ScriptBuilder().op(OP_RETURN).data(data).build()); BigInteger fee = FeePolicy.ACCOUNT_REGISTRATION_FEE.subtract(Transaction.MIN_NONDUST_OUTPUT).subtract(FeePolicy.TX_FEE); log.trace("fee: " + BtcFormatter.btcToString(fee)); @@ -735,7 +741,6 @@ public class WalletFacade log.trace("takersSignedConnOutAsHex=" + takersSignedConnOutAsHex); log.trace("takersSignedScriptSigAsHex=" + takersSignedScriptSigAsHex); log.trace("callback=" + callback.toString()); - log.trace("Wallet balance initial: " + wallet.getBalance()); // We create an empty tx (did not find a way to manipulate a tx input, otherwise the takers tx could be used directly and add the offerers input and output) Transaction tx = new Transaction(params); diff --git a/src/main/java/io/bitsquare/gui/funds/AddressListItem.java b/src/main/java/io/bitsquare/gui/funds/AddressListItem.java index 49917b253f..ede0c84e5f 100644 --- a/src/main/java/io/bitsquare/gui/funds/AddressListItem.java +++ b/src/main/java/io/bitsquare/gui/funds/AddressListItem.java @@ -1,31 +1,41 @@ package io.bitsquare.gui.funds; import com.google.bitcoin.core.Address; -import javafx.beans.property.BooleanProperty; -import javafx.beans.property.SimpleBooleanProperty; +import io.bitsquare.btc.AddressInfo; import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; public class AddressListItem { - private final StringProperty label = new SimpleStringProperty(); private final StringProperty addressString = new SimpleStringProperty(); - private final BooleanProperty isUsed = new SimpleBooleanProperty(); - private Address address; + private AddressInfo addressInfo; - public AddressListItem(String label, Address address, boolean isUsed) + public AddressListItem(AddressInfo addressInfo) { - this.address = address; - this.label.set(label); - this.addressString.set(address.toString()); + this.addressInfo = addressInfo; + this.addressString.set(getAddress().toString()); - this.isUsed.set(isUsed); } - // called form table columns - public final StringProperty labelProperty() + public final String getLabel() { - return this.label; + switch (addressInfo.getAddressContext()) + { + case REGISTRATION_FEE: + return "Registration fee"; + case CREATE_OFFER_FEE: + return "Create offer fee"; + case TAKE_OFFER_FEE: + return "Take offer fee"; + case TRADE: + if (addressInfo.getTradeId() != null) + return "Trade ID: " + addressInfo.getTradeId(); + else + return "Unused"; + case ARBITRATOR_DEPOSIT: + return "Arbitration deposit"; + } + return ""; } public final StringProperty addressStringProperty() @@ -33,13 +43,14 @@ public class AddressListItem return this.addressString; } - public final BooleanProperty isUsedProperty() - { - return this.isUsed; - } public Address getAddress() { - return address; + return addressInfo.getAddress(); + } + + public AddressInfo getAddressInfo() + { + return addressInfo; } } diff --git a/src/main/java/io/bitsquare/gui/funds/FundsController.java b/src/main/java/io/bitsquare/gui/funds/FundsController.java index 96c45c6cd4..4ab72067b4 100644 --- a/src/main/java/io/bitsquare/gui/funds/FundsController.java +++ b/src/main/java/io/bitsquare/gui/funds/FundsController.java @@ -17,11 +17,13 @@ import javafx.beans.property.ReadOnlyObjectWrapper; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.event.ActionEvent; +import javafx.event.EventHandler; import javafx.fxml.FXML; import javafx.fxml.Initializable; import javafx.scene.control.*; import javafx.scene.input.Clipboard; import javafx.scene.input.ClipboardContent; +import javafx.scene.input.MouseEvent; import javafx.util.Callback; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -67,6 +69,7 @@ public class FundsController implements Initializable, ChildController @Override public void initialize(URL url, ResourceBundle rb) { + setLabelColumnCellFactory(); setBalanceColumnCellFactory(); setCopyColumnCellFactory(); setConfidenceColumnCellFactory(); @@ -76,7 +79,7 @@ public class FundsController implements Initializable, ChildController for (int i = 0; i < addressInfoList.size(); i++) { AddressInfo addressInfo = addressInfoList.get(i); - addressList.add(new AddressListItem(addressInfo.getLabel(), addressInfo.getAddress(), false)); + addressList.add(new AddressListItem(addressInfo)); } addressesTable.setItems(addressList); @@ -107,7 +110,7 @@ public class FundsController implements Initializable, ChildController public void onAddNewTradeAddress(ActionEvent actionEvent) { AddressInfo addressInfo = walletFacade.getNewTradeAddressInfo(); - addressList.add(new AddressListItem(addressInfo.getLabel(), addressInfo.getAddress(), false)); + addressList.add(new AddressListItem(addressInfo)); } @@ -115,6 +118,59 @@ public class FundsController implements Initializable, ChildController // Private methods /////////////////////////////////////////////////////////////////////////////////////////// + + private void setLabelColumnCellFactory() + { + labelColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper(addressListItem.getValue())); + labelColumn.setCellFactory(new Callback, TableCell>() + { + @Override + public TableCell call(TableColumn column) + { + return new TableCell() + { + Label label; + + @Override + public void updateItem(final AddressListItem item, boolean empty) + { + super.updateItem(item, empty); + + if (item != null) + { + label = new Label(item.getLabel()); + + if (item.getAddressInfo().getTradeId() != null) + { + setId("funds-link-cell"); + + Tooltip tooltip = new Tooltip(item.getAddressInfo().getTradeId()); + Tooltip.install(label, tooltip); + + label.setUnderline(true); + label.setStyle("-fx-cursor: hand"); + label.setOnMouseClicked(new EventHandler() + { + @Override + public void handle(MouseEvent mouseEvent) + { + log.info("Show trade details " + item.getAddressInfo().getTradeId()); + } + }); + } + setGraphic(label); + } + else + { + setGraphic(null); + setId(null); + } + } + }; + } + }); + } + private void setBalanceColumnCellFactory() { balanceColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper(addressListItem.getValue())); @@ -175,7 +231,7 @@ public class FundsController implements Initializable, ChildController Label copyIcon = new Label(); { - copyIcon.setId("copy-icon"); + setId("funds-link-cell"); AwesomeDude.setIcon(copyIcon, AwesomeIcon.COPY); Tooltip.install(copyIcon, new Tooltip("Copy address to clipboard")); } @@ -194,6 +250,7 @@ public class FundsController implements Initializable, ChildController content.putString(item.addressStringProperty().get()); clipboard.setContent(content); }); + } else { @@ -226,6 +283,7 @@ public class FundsController implements Initializable, ChildController if (item != null) { progressIndicator = new ConfidenceProgressIndicator(); + progressIndicator.setId("funds-confidence"); Tooltip tooltip = new Tooltip("Not used yet"); progressIndicator.setProgress(0); progressIndicator.setPrefHeight(30); diff --git a/src/main/java/io/bitsquare/gui/funds/FundsView.fxml b/src/main/java/io/bitsquare/gui/funds/FundsView.fxml index f1c4d26fcf..9e51ba64fc 100644 --- a/src/main/java/io/bitsquare/gui/funds/FundsView.fxml +++ b/src/main/java/io/bitsquare/gui/funds/FundsView.fxml @@ -14,13 +14,9 @@ - + - - - - - + diff --git a/src/main/java/io/bitsquare/gui/global.css b/src/main/java/io/bitsquare/gui/global.css index e60717b2f3..a28e2a6d6f 100644 --- a/src/main/java/io/bitsquare/gui/global.css +++ b/src/main/java/io/bitsquare/gui/global.css @@ -79,7 +79,7 @@ -fx-background-color: transparent; } -/* table */ +/* order book table */ #orderbook-table .table-cell { -fx-alignment: center; @@ -93,6 +93,40 @@ -fx-alignment: center; } +/* funds table */ + +#funds-table .table-cell { + -fx-alignment: center; +} + +#funds-table .column-header .label { + -fx-alignment-alignment: center; +} + +#funds-table .focus { + -fx-alignment: center; +} + +#funds-table .table-row-cell:selected .text { + -fx-fill: white; +} + +#funds-table .table-row-cell:selected .text:hover { + -fx-fill: black; +} + +#funds-link-cell .text:hover { + -fx-fill: black; +} + +#funds-link-cell .text { + -fx-fill: #0096c9; +} + +#funds-confidence { + -fx-progress-color: dimgrey; +} + /* forms */ #form-header-text { -fx-font-weight: bold;