mirror of
https://github.com/sparrowwallet/sparrow.git
synced 2024-12-24 12:46:45 +00:00
view extracted transaction from psbt
This commit is contained in:
parent
658ab2f81c
commit
29cfda7908
10 changed files with 125 additions and 25 deletions
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -31,6 +31,7 @@ public class FontAwesome5 extends GlyphFont {
|
||||||
PEN_FANCY('\uf5ac'),
|
PEN_FANCY('\uf5ac'),
|
||||||
QRCODE('\uf029'),
|
QRCODE('\uf029'),
|
||||||
QUESTION_CIRCLE('\uf059'),
|
QUESTION_CIRCLE('\uf059'),
|
||||||
|
SATELLITE_DISH('\uf7c0'),
|
||||||
SD_CARD('\uf7c2'),
|
SD_CARD('\uf7c2'),
|
||||||
SEARCH('\uf002'),
|
SEARCH('\uf002'),
|
||||||
TOOLS('\uf7d9'),
|
TOOLS('\uf7d9'),
|
||||||
|
|
|
@ -669,7 +669,7 @@ public class ElectrumServer {
|
||||||
}
|
}
|
||||||
|
|
||||||
public BlockTransaction getBlockTransaction() {
|
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ import javafx.fxml.Initializable;
|
||||||
import javafx.scene.control.*;
|
import javafx.scene.control.*;
|
||||||
import javafx.scene.input.Clipboard;
|
import javafx.scene.input.Clipboard;
|
||||||
import javafx.scene.input.ClipboardContent;
|
import javafx.scene.input.ClipboardContent;
|
||||||
|
import javafx.scene.layout.HBox;
|
||||||
import javafx.scene.layout.VBox;
|
import javafx.scene.layout.VBox;
|
||||||
import javafx.stage.FileChooser;
|
import javafx.stage.FileChooser;
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
|
@ -107,12 +108,21 @@ public class HeadersController extends TransactionFormController implements Init
|
||||||
@FXML
|
@FXML
|
||||||
private CopyableLabel blockStatus;
|
private CopyableLabel blockStatus;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private Field blockHeightField;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private CopyableLabel blockHeight;
|
private CopyableLabel blockHeight;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private Field blockTimestampField;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private CopyableLabel blockTimestamp;
|
private CopyableLabel blockTimestamp;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private Field blockHashField;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private IdLabel blockHash;
|
private IdLabel blockHash;
|
||||||
|
|
||||||
|
@ -146,11 +156,14 @@ public class HeadersController extends TransactionFormController implements Init
|
||||||
@FXML
|
@FXML
|
||||||
private SignaturesProgressBar signaturesProgressBar;
|
private SignaturesProgressBar signaturesProgressBar;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private HBox signButtonBox;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private Button signButton;
|
private Button signButton;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private Form broadcastForm;
|
private HBox broadcastButtonBox;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialize(URL location, ResourceBundle resources) {
|
public void initialize(URL location, ResourceBundle resources) {
|
||||||
|
@ -290,12 +303,14 @@ public class HeadersController extends TransactionFormController implements Init
|
||||||
finalizeButtonBox.visibleProperty().bind(signingWalletForm.visibleProperty());
|
finalizeButtonBox.visibleProperty().bind(signingWalletForm.visibleProperty());
|
||||||
|
|
||||||
signaturesForm.managedProperty().bind(signaturesForm.visibleProperty());
|
signaturesForm.managedProperty().bind(signaturesForm.visibleProperty());
|
||||||
broadcastForm.managedProperty().bind(broadcastForm.visibleProperty());
|
signButtonBox.managedProperty().bind(signButtonBox.visibleProperty());
|
||||||
|
broadcastButtonBox.managedProperty().bind(broadcastButtonBox.visibleProperty());
|
||||||
|
|
||||||
blockchainForm.setVisible(false);
|
blockchainForm.setVisible(false);
|
||||||
signingWalletForm.setVisible(false);
|
signingWalletForm.setVisible(false);
|
||||||
signaturesForm.setVisible(false);
|
signaturesForm.setVisible(false);
|
||||||
broadcastForm.setVisible(false);
|
signButtonBox.setVisible(false);
|
||||||
|
broadcastButtonBox.setVisible(false);
|
||||||
|
|
||||||
if(headersForm.getBlockTransaction() != null) {
|
if(headersForm.getBlockTransaction() != null) {
|
||||||
blockchainForm.setVisible(true);
|
blockchainForm.setVisible(true);
|
||||||
|
@ -306,9 +321,11 @@ public class HeadersController extends TransactionFormController implements Init
|
||||||
if(headersForm.isEditable()) {
|
if(headersForm.isEditable()) {
|
||||||
signingWalletForm.setVisible(true);
|
signingWalletForm.setVisible(true);
|
||||||
} else if(headersForm.getPsbt().isSigned()) {
|
} else if(headersForm.getPsbt().isSigned()) {
|
||||||
broadcastForm.setVisible(true);
|
signaturesForm.setVisible(true);
|
||||||
|
broadcastButtonBox.setVisible(true);
|
||||||
} else {
|
} else {
|
||||||
signaturesForm.setVisible(true);
|
signaturesForm.setVisible(true);
|
||||||
|
signButtonBox.setVisible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
EventManager.get().post(new RequestOpenWalletsEvent());
|
EventManager.get().post(new RequestOpenWalletsEvent());
|
||||||
|
@ -387,21 +404,32 @@ public class HeadersController extends TransactionFormController implements Init
|
||||||
blockStatus.setText("Unknown");
|
blockStatus.setText("Unknown");
|
||||||
} else {
|
} else {
|
||||||
int confirmations = currentHeight - blockTransaction.getHeight() + 1;
|
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) {
|
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.setText(blockTransaction.getBlockHash().toString());
|
||||||
blockHash.setContextMenu(new BlockHeightContextMenu(blockTransaction.getBlockHash()));
|
blockHash.setContextMenu(new BlockHeightContextMenu(blockTransaction.getBlockHash()));
|
||||||
} else {
|
} 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
|
@Subscribe
|
||||||
public void transactionChanged(TransactionChangedEvent event) {
|
public void transactionChanged(TransactionChangedEvent event) {
|
||||||
if(headersForm.getTransaction().equals(event.getTransaction())) {
|
if(headersForm.getTransaction().equals(event.getTransaction())) {
|
||||||
|
@ -637,6 +677,7 @@ public class HeadersController extends TransactionFormController implements Init
|
||||||
|
|
||||||
signingWalletForm.setVisible(false);
|
signingWalletForm.setVisible(false);
|
||||||
signaturesForm.setVisible(true);
|
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
|
@Subscribe
|
||||||
public void keystoreSigned(KeystoreSignedEvent event) {
|
public void keystoreSigned(KeystoreSignedEvent event) {
|
||||||
if(headersForm.getSignedKeystores().contains(event.getKeystore()) && headersForm.getPsbt() != null) {
|
if(headersForm.getSignedKeystores().contains(event.getKeystore()) && headersForm.getPsbt() != null) {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.sparrowwallet.sparrow.transaction;
|
package com.sparrowwallet.sparrow.transaction;
|
||||||
|
|
||||||
|
import com.sparrowwallet.drongo.protocol.Transaction;
|
||||||
import javafx.fxml.FXMLLoader;
|
import javafx.fxml.FXMLLoader;
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
|
|
||||||
|
@ -10,6 +11,10 @@ public class HeadersForm extends TransactionForm {
|
||||||
super(txdata);
|
super(txdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setFinalTransaction(Transaction finalTransaction) {
|
||||||
|
txdata.setTransaction(finalTransaction);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Node getContents() throws IOException {
|
public Node getContents() throws IOException {
|
||||||
FXMLLoader loader = new FXMLLoader(getClass().getResource("headers.fxml"));
|
FXMLLoader loader = new FXMLLoader(getClass().getResource("headers.fxml"));
|
||||||
|
|
|
@ -535,4 +535,11 @@ public class InputController extends TransactionFormController implements Initia
|
||||||
updateSignatures(inputForm.getPsbtInput());
|
updateSignatures(inputForm.getPsbtInput());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void transactionExtracted(TransactionExtractedEvent event) {
|
||||||
|
if(event.getPsbt().equals(inputForm.getPsbt())) {
|
||||||
|
updateScriptFields(event.getFinalTransaction().getInputs().get(inputForm.getIndex()), null);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -490,4 +490,12 @@ public class TransactionController implements Initializable {
|
||||||
txdata.updateOutputsFetchedRange(event.getPageStart(), event.getPageEnd());
|
txdata.updateOutputsFetchedRange(event.getPageStart(), event.getPageEnd());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void transactionExtracted(TransactionExtractedEvent event) {
|
||||||
|
if(event.getPsbt().equals(getPSBT())) {
|
||||||
|
txhex.setTransaction(getTransaction());
|
||||||
|
highlightTxHex();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -16,7 +16,7 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class TransactionData {
|
public class TransactionData {
|
||||||
private final Transaction transaction;
|
private Transaction transaction;
|
||||||
private String name;
|
private String name;
|
||||||
private PSBT psbt;
|
private PSBT psbt;
|
||||||
private BlockTransaction blockTransaction;
|
private BlockTransaction blockTransaction;
|
||||||
|
@ -50,6 +50,10 @@ public class TransactionData {
|
||||||
return transaction;
|
return transaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setTransaction(Transaction transaction) {
|
||||||
|
this.transaction = transaction;
|
||||||
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public abstract class TransactionForm {
|
public abstract class TransactionForm {
|
||||||
private final TransactionData txdata;
|
protected final TransactionData txdata;
|
||||||
|
|
||||||
public TransactionForm(TransactionData txdata) {
|
public TransactionForm(TransactionData txdata) {
|
||||||
this.txdata = txdata;
|
this.txdata = txdata;
|
||||||
|
|
|
@ -117,13 +117,13 @@
|
||||||
<Field text="Status:">
|
<Field text="Status:">
|
||||||
<CopyableLabel fx:id="blockStatus" />
|
<CopyableLabel fx:id="blockStatus" />
|
||||||
</Field>
|
</Field>
|
||||||
<Field text="Block Height:">
|
<Field fx:id="blockHeightField" text="Block Height:">
|
||||||
<CopyableLabel fx:id="blockHeight" />
|
<CopyableLabel fx:id="blockHeight" />
|
||||||
</Field>
|
</Field>
|
||||||
<Field text="Timestamp:">
|
<Field fx:id="blockTimestampField" text="Timestamp:">
|
||||||
<CopyableLabel fx:id="blockTimestamp" />
|
<CopyableLabel fx:id="blockTimestamp" />
|
||||||
</Field>
|
</Field>
|
||||||
<Field text="Block Hash:">
|
<Field fx:id="blockHashField" text="Block Hash:">
|
||||||
<IdLabel fx:id="blockHash" />
|
<IdLabel fx:id="blockHash" />
|
||||||
</Field>
|
</Field>
|
||||||
</Fieldset>
|
</Fieldset>
|
||||||
|
@ -176,7 +176,7 @@
|
||||||
<SignaturesProgressBar fx:id="signaturesProgressBar" />
|
<SignaturesProgressBar fx:id="signaturesProgressBar" />
|
||||||
</VBox>
|
</VBox>
|
||||||
<VBox>
|
<VBox>
|
||||||
<HBox styleClass="signatures-buttons" spacing="20">
|
<HBox fx:id="signButtonBox" styleClass="signatures-buttons" spacing="20">
|
||||||
<SegmentedButton HBox.hgrow="ALWAYS">
|
<SegmentedButton HBox.hgrow="ALWAYS">
|
||||||
<buttons>
|
<buttons>
|
||||||
<ToggleButton HBox.hgrow="ALWAYS" text="Show QR" contentDisplay="TOP" wrapText="true" textAlignment="CENTER" onAction="#showPSBT">
|
<ToggleButton HBox.hgrow="ALWAYS" text="Show QR" contentDisplay="TOP" wrapText="true" textAlignment="CENTER" onAction="#showPSBT">
|
||||||
|
@ -211,13 +211,19 @@
|
||||||
</graphic>
|
</graphic>
|
||||||
</Button>
|
</Button>
|
||||||
</HBox>
|
</HBox>
|
||||||
|
<HBox fx:id="broadcastButtonBox" styleClass="signatures-buttons" spacing="20">
|
||||||
|
<Button HBox.hgrow="ALWAYS" text="View Final Transaction" contentDisplay="TOP" wrapText="true" textAlignment="CENTER" onAction="#extractTransaction">
|
||||||
|
<graphic>
|
||||||
|
<Glyph fontFamily="Font Awesome 5 Free Solid" fontSize="20" icon="SEARCH" />
|
||||||
|
</graphic>
|
||||||
|
</Button>
|
||||||
|
<Button defaultButton="true" HBox.hgrow="ALWAYS" text="Broadcast Transaction" contentDisplay="TOP" wrapText="true" textAlignment="CENTER" onAction="#broadcastTransaction">
|
||||||
|
<graphic>
|
||||||
|
<Glyph fontFamily="Font Awesome 5 Free Solid" fontSize="20" icon="SATELLITE_DISH" />
|
||||||
|
</graphic>
|
||||||
|
</Button>
|
||||||
|
</HBox>
|
||||||
</VBox>
|
</VBox>
|
||||||
</Fieldset>
|
</Fieldset>
|
||||||
</Form>
|
</Form>
|
||||||
|
|
||||||
<Form fx:id="broadcastForm" GridPane.columnIndex="0" GridPane.columnSpan="2" GridPane.rowIndex="6">
|
|
||||||
<Fieldset text="Send" inputGrow="SOMETIMES">
|
|
||||||
</Fieldset>
|
|
||||||
</Form>
|
|
||||||
|
|
||||||
</GridPane>
|
</GridPane>
|
||||||
|
|
Loading…
Reference in a new issue