diff --git a/src/main/java/com/sparrowwallet/sparrow/event/TransactionExtractedEvent.java b/src/main/java/com/sparrowwallet/sparrow/event/TransactionExtractedEvent.java new file mode 100644 index 00000000..3c8bc9cf --- /dev/null +++ b/src/main/java/com/sparrowwallet/sparrow/event/TransactionExtractedEvent.java @@ -0,0 +1,20 @@ +package com.sparrowwallet.sparrow.event; + +import com.sparrowwallet.drongo.protocol.Transaction; +import com.sparrowwallet.drongo.psbt.PSBT; + +/** + * This event is fired when a final transaction has been extracted from a PSBT + */ +public class TransactionExtractedEvent extends PSBTEvent { + private final Transaction finalTransaction; + + public TransactionExtractedEvent(PSBT psbt, Transaction finalTransaction) { + super(psbt); + this.finalTransaction = finalTransaction; + } + + public Transaction getFinalTransaction() { + return finalTransaction; + } +} diff --git a/src/main/java/com/sparrowwallet/sparrow/glyphfont/FontAwesome5.java b/src/main/java/com/sparrowwallet/sparrow/glyphfont/FontAwesome5.java index 26b69434..421101e4 100644 --- a/src/main/java/com/sparrowwallet/sparrow/glyphfont/FontAwesome5.java +++ b/src/main/java/com/sparrowwallet/sparrow/glyphfont/FontAwesome5.java @@ -31,6 +31,7 @@ public class FontAwesome5 extends GlyphFont { PEN_FANCY('\uf5ac'), QRCODE('\uf029'), QUESTION_CIRCLE('\uf059'), + SATELLITE_DISH('\uf7c0'), SD_CARD('\uf7c2'), SEARCH('\uf002'), TOOLS('\uf7d9'), diff --git a/src/main/java/com/sparrowwallet/sparrow/io/ElectrumServer.java b/src/main/java/com/sparrowwallet/sparrow/io/ElectrumServer.java index 86804ae7..f7f397d8 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/ElectrumServer.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/ElectrumServer.java @@ -669,7 +669,7 @@ public class ElectrumServer { } public BlockTransaction getBlockTransaction() { - return new BlockTransaction(Sha256Hash.wrap(txid), getHeight(), getDate(), 0L, new Transaction(Utils.hexToBytes(hex)), Sha256Hash.wrap(blockhash)); + return new BlockTransaction(Sha256Hash.wrap(txid), getHeight(), getDate(), 0L, new Transaction(Utils.hexToBytes(hex)), blockhash == null ? null : Sha256Hash.wrap(blockhash)); } } diff --git a/src/main/java/com/sparrowwallet/sparrow/transaction/HeadersController.java b/src/main/java/com/sparrowwallet/sparrow/transaction/HeadersController.java index a7f8fe15..575dd207 100644 --- a/src/main/java/com/sparrowwallet/sparrow/transaction/HeadersController.java +++ b/src/main/java/com/sparrowwallet/sparrow/transaction/HeadersController.java @@ -21,6 +21,7 @@ import javafx.fxml.Initializable; import javafx.scene.control.*; import javafx.scene.input.Clipboard; import javafx.scene.input.ClipboardContent; +import javafx.scene.layout.HBox; import javafx.scene.layout.VBox; import javafx.stage.FileChooser; import javafx.stage.Stage; @@ -107,12 +108,21 @@ public class HeadersController extends TransactionFormController implements Init @FXML private CopyableLabel blockStatus; + @FXML + private Field blockHeightField; + @FXML private CopyableLabel blockHeight; + @FXML + private Field blockTimestampField; + @FXML private CopyableLabel blockTimestamp; + @FXML + private Field blockHashField; + @FXML private IdLabel blockHash; @@ -146,11 +156,14 @@ public class HeadersController extends TransactionFormController implements Init @FXML private SignaturesProgressBar signaturesProgressBar; + @FXML + private HBox signButtonBox; + @FXML private Button signButton; @FXML - private Form broadcastForm; + private HBox broadcastButtonBox; @Override public void initialize(URL location, ResourceBundle resources) { @@ -290,12 +303,14 @@ public class HeadersController extends TransactionFormController implements Init finalizeButtonBox.visibleProperty().bind(signingWalletForm.visibleProperty()); signaturesForm.managedProperty().bind(signaturesForm.visibleProperty()); - broadcastForm.managedProperty().bind(broadcastForm.visibleProperty()); + signButtonBox.managedProperty().bind(signButtonBox.visibleProperty()); + broadcastButtonBox.managedProperty().bind(broadcastButtonBox.visibleProperty()); blockchainForm.setVisible(false); signingWalletForm.setVisible(false); signaturesForm.setVisible(false); - broadcastForm.setVisible(false); + signButtonBox.setVisible(false); + broadcastButtonBox.setVisible(false); if(headersForm.getBlockTransaction() != null) { blockchainForm.setVisible(true); @@ -306,9 +321,11 @@ public class HeadersController extends TransactionFormController implements Init if(headersForm.isEditable()) { signingWalletForm.setVisible(true); } else if(headersForm.getPsbt().isSigned()) { - broadcastForm.setVisible(true); + signaturesForm.setVisible(true); + broadcastButtonBox.setVisible(true); } else { signaturesForm.setVisible(true); + signButtonBox.setVisible(true); } EventManager.get().post(new RequestOpenWalletsEvent()); @@ -387,21 +404,32 @@ public class HeadersController extends TransactionFormController implements Init blockStatus.setText("Unknown"); } else { int confirmations = currentHeight - blockTransaction.getHeight() + 1; - blockStatus.setText(confirmations + " Confirmations"); + if(confirmations == 0) { + blockStatus.setText("Unconfirmed"); + } else if(confirmations == 1) { + blockStatus.setText(confirmations + " Confirmation"); + } else { + blockStatus.setText(confirmations + " Confirmations"); + } } - blockHeight.setText(Integer.toString(blockTransaction.getHeight())); + blockHeightField.managedProperty().bind(blockHeightField.visibleProperty()); + blockTimestampField.managedProperty().bind(blockTimestampField.visibleProperty()); + blockHashField.managedProperty().bind(blockHashField.visibleProperty()); + blockTimestampField.visibleProperty().bind(blockHeightField.visibleProperty()); + blockHashField.visibleProperty().bind(blockHeightField.visibleProperty()); - SimpleDateFormat dateFormat = new SimpleDateFormat(BLOCK_TIMESTAMP_DATE_FORMAT); - blockTimestamp.setText(dateFormat.format(blockTransaction.getDate())); - - blockHash.managedProperty().bind(blockHash.visibleProperty()); if(blockTransaction.getBlockHash() != null) { - blockHash.setVisible(true); + blockHeightField.setVisible(true); + blockHeight.setText(Integer.toString(blockTransaction.getHeight())); + + SimpleDateFormat dateFormat = new SimpleDateFormat(BLOCK_TIMESTAMP_DATE_FORMAT); + blockTimestamp.setText(dateFormat.format(blockTransaction.getDate())); + blockHash.setText(blockTransaction.getBlockHash().toString()); blockHash.setContextMenu(new BlockHeightContextMenu(blockTransaction.getBlockHash())); } else { - blockHash.setVisible(false); + blockHeightField.setVisible(false); } } @@ -563,6 +591,18 @@ public class HeadersController extends TransactionFormController implements Init }); } + public void extractTransaction(ActionEvent event) { + Transaction finalTx = headersForm.getPsbt().extractTransaction(); + headersForm.setFinalTransaction(finalTx); + EventManager.get().post(new TransactionExtractedEvent(headersForm.getPsbt(), finalTx)); + } + + public void broadcastTransaction(ActionEvent event) { + extractTransaction(event); + + + } + @Subscribe public void transactionChanged(TransactionChangedEvent event) { if(headersForm.getTransaction().equals(event.getTransaction())) { @@ -637,6 +677,7 @@ public class HeadersController extends TransactionFormController implements Init signingWalletForm.setVisible(false); signaturesForm.setVisible(true); + signButtonBox.setVisible(true); } } @@ -647,6 +688,14 @@ public class HeadersController extends TransactionFormController implements Init } } + @Subscribe + public void psbtFinalized(PSBTFinalizedEvent event) { + if(event.getPsbt().equals(headersForm.getPsbt())) { + signButtonBox.setVisible(false); + broadcastButtonBox.setVisible(true); + } + } + @Subscribe public void keystoreSigned(KeystoreSignedEvent event) { if(headersForm.getSignedKeystores().contains(event.getKeystore()) && headersForm.getPsbt() != null) { diff --git a/src/main/java/com/sparrowwallet/sparrow/transaction/HeadersForm.java b/src/main/java/com/sparrowwallet/sparrow/transaction/HeadersForm.java index 85d85039..37455b29 100644 --- a/src/main/java/com/sparrowwallet/sparrow/transaction/HeadersForm.java +++ b/src/main/java/com/sparrowwallet/sparrow/transaction/HeadersForm.java @@ -1,5 +1,6 @@ package com.sparrowwallet.sparrow.transaction; +import com.sparrowwallet.drongo.protocol.Transaction; import javafx.fxml.FXMLLoader; import javafx.scene.Node; @@ -10,6 +11,10 @@ public class HeadersForm extends TransactionForm { super(txdata); } + void setFinalTransaction(Transaction finalTransaction) { + txdata.setTransaction(finalTransaction); + } + @Override public Node getContents() throws IOException { FXMLLoader loader = new FXMLLoader(getClass().getResource("headers.fxml")); diff --git a/src/main/java/com/sparrowwallet/sparrow/transaction/InputController.java b/src/main/java/com/sparrowwallet/sparrow/transaction/InputController.java index eb4426f7..d1f4035b 100644 --- a/src/main/java/com/sparrowwallet/sparrow/transaction/InputController.java +++ b/src/main/java/com/sparrowwallet/sparrow/transaction/InputController.java @@ -535,4 +535,11 @@ public class InputController extends TransactionFormController implements Initia updateSignatures(inputForm.getPsbtInput()); } } + + @Subscribe + public void transactionExtracted(TransactionExtractedEvent event) { + if(event.getPsbt().equals(inputForm.getPsbt())) { + updateScriptFields(event.getFinalTransaction().getInputs().get(inputForm.getIndex()), null); + } + } } diff --git a/src/main/java/com/sparrowwallet/sparrow/transaction/TransactionController.java b/src/main/java/com/sparrowwallet/sparrow/transaction/TransactionController.java index 0962226d..0fb50b31 100644 --- a/src/main/java/com/sparrowwallet/sparrow/transaction/TransactionController.java +++ b/src/main/java/com/sparrowwallet/sparrow/transaction/TransactionController.java @@ -490,4 +490,12 @@ public class TransactionController implements Initializable { txdata.updateOutputsFetchedRange(event.getPageStart(), event.getPageEnd()); } } + + @Subscribe + public void transactionExtracted(TransactionExtractedEvent event) { + if(event.getPsbt().equals(getPSBT())) { + txhex.setTransaction(getTransaction()); + highlightTxHex(); + } + } } \ No newline at end of file diff --git a/src/main/java/com/sparrowwallet/sparrow/transaction/TransactionData.java b/src/main/java/com/sparrowwallet/sparrow/transaction/TransactionData.java index 089555e6..69ff7bd3 100644 --- a/src/main/java/com/sparrowwallet/sparrow/transaction/TransactionData.java +++ b/src/main/java/com/sparrowwallet/sparrow/transaction/TransactionData.java @@ -16,7 +16,7 @@ import java.util.List; import java.util.Map; public class TransactionData { - private final Transaction transaction; + private Transaction transaction; private String name; private PSBT psbt; private BlockTransaction blockTransaction; @@ -50,6 +50,10 @@ public class TransactionData { return transaction; } + public void setTransaction(Transaction transaction) { + this.transaction = transaction; + } + public String getName() { return name; } diff --git a/src/main/java/com/sparrowwallet/sparrow/transaction/TransactionForm.java b/src/main/java/com/sparrowwallet/sparrow/transaction/TransactionForm.java index 84f9a460..dd04b2dc 100644 --- a/src/main/java/com/sparrowwallet/sparrow/transaction/TransactionForm.java +++ b/src/main/java/com/sparrowwallet/sparrow/transaction/TransactionForm.java @@ -17,7 +17,7 @@ import java.util.List; import java.util.Map; public abstract class TransactionForm { - private final TransactionData txdata; + protected final TransactionData txdata; public TransactionForm(TransactionData txdata) { this.txdata = txdata; diff --git a/src/main/resources/com/sparrowwallet/sparrow/transaction/headers.fxml b/src/main/resources/com/sparrowwallet/sparrow/transaction/headers.fxml index d9ca9538..af938a10 100644 --- a/src/main/resources/com/sparrowwallet/sparrow/transaction/headers.fxml +++ b/src/main/resources/com/sparrowwallet/sparrow/transaction/headers.fxml @@ -117,13 +117,13 @@ - + - + - + @@ -176,7 +176,7 @@ - + @@ -211,13 +211,19 @@ + + + + - -
-
-
-
-