mirror of
https://github.com/sparrowwallet/sparrow.git
synced 2024-12-25 05:06:45 +00:00
finalise tx with signing wallet and sighash
This commit is contained in:
parent
8e02f7103e
commit
c86f7d32cb
15 changed files with 313 additions and 15 deletions
2
drongo
2
drongo
|
@ -1 +1 @@
|
||||||
Subproject commit a56684240a1a9a44f96b2a57fd10799bb9f8a18a
|
Subproject commit dcd4218ba14ecea9113925b80af02fdc3287079a
|
|
@ -28,6 +28,7 @@ import javafx.animation.*;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.beans.property.BooleanProperty;
|
import javafx.beans.property.BooleanProperty;
|
||||||
import javafx.beans.property.SimpleBooleanProperty;
|
import javafx.beans.property.SimpleBooleanProperty;
|
||||||
|
import javafx.collections.ListChangeListener;
|
||||||
import javafx.concurrent.Worker;
|
import javafx.concurrent.Worker;
|
||||||
import javafx.event.ActionEvent;
|
import javafx.event.ActionEvent;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
|
@ -158,6 +159,13 @@ public class AppController implements Initializable {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
tabs.setTabDragPolicy(TabPane.TabDragPolicy.REORDER);
|
||||||
|
tabs.getTabs().addListener((ListChangeListener<Tab>) c -> {
|
||||||
|
if(c.next() && (c.wasAdded() || c.wasRemoved())) {
|
||||||
|
EventManager.get().post(new OpenWalletsEvent(getOpenWallets()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
BitcoinUnit unit = Config.get().getBitcoinUnit();
|
BitcoinUnit unit = Config.get().getBitcoinUnit();
|
||||||
if(unit == null) {
|
if(unit == null) {
|
||||||
unit = BitcoinUnit.AUTO;
|
unit = BitcoinUnit.AUTO;
|
||||||
|
@ -401,6 +409,20 @@ public class AppController implements Initializable {
|
||||||
return fiatCurrencyExchangeRate;
|
return fiatCurrencyExchangeRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Wallet> getOpenWallets() {
|
||||||
|
List<Wallet> openWallets = new ArrayList<>();
|
||||||
|
|
||||||
|
for(Tab tab : tabs.getTabs()) {
|
||||||
|
TabData tabData = (TabData)tab.getUserData();
|
||||||
|
if(tabData.getType() == TabData.TabType.WALLET) {
|
||||||
|
WalletTabData walletTabData = (WalletTabData) tabData;
|
||||||
|
openWallets.add(walletTabData.getWallet());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return openWallets;
|
||||||
|
}
|
||||||
|
|
||||||
public static void showErrorDialog(String title, String content) {
|
public static void showErrorDialog(String title, String content) {
|
||||||
Alert alert = new Alert(Alert.AlertType.ERROR);
|
Alert alert = new Alert(Alert.AlertType.ERROR);
|
||||||
alert.setTitle(title);
|
alert.setTitle(title);
|
||||||
|
@ -887,4 +909,14 @@ public class AppController implements Initializable {
|
||||||
public void exchangeRatesUpdated(ExchangeRatesUpdatedEvent event) {
|
public void exchangeRatesUpdated(ExchangeRatesUpdatedEvent event) {
|
||||||
fiatCurrencyExchangeRate = event.getCurrencyRate();
|
fiatCurrencyExchangeRate = event.getCurrencyRate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void requestOpenWallets(RequestOpenWalletsEvent event) {
|
||||||
|
EventManager.get().post(new OpenWalletsEvent(getOpenWallets()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void requestWalletOpen(RequestWalletOpenEvent event) {
|
||||||
|
openWallet(null);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.sparrowwallet.sparrow.event;
|
||||||
|
|
||||||
|
import com.sparrowwallet.drongo.psbt.PSBT;
|
||||||
|
import com.sparrowwallet.drongo.wallet.Wallet;
|
||||||
|
|
||||||
|
public class FinalizePSBTEvent {
|
||||||
|
private final PSBT psbt;
|
||||||
|
private final Wallet signingWallet;
|
||||||
|
|
||||||
|
public FinalizePSBTEvent(PSBT psbt, Wallet signingWallet) {
|
||||||
|
this.psbt = psbt;
|
||||||
|
this.signingWallet = signingWallet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PSBT getPsbt() {
|
||||||
|
return psbt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Wallet getSigningWallet() {
|
||||||
|
return signingWallet;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package com.sparrowwallet.sparrow.event;
|
||||||
|
|
||||||
|
import com.sparrowwallet.drongo.wallet.Wallet;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class OpenWalletsEvent {
|
||||||
|
private final List<Wallet> wallets;
|
||||||
|
|
||||||
|
public OpenWalletsEvent(List<Wallet> wallets) {
|
||||||
|
this.wallets = wallets;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Wallet> getWallets() {
|
||||||
|
return wallets;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
package com.sparrowwallet.sparrow.event;
|
||||||
|
|
||||||
|
public class RequestOpenWalletsEvent {
|
||||||
|
//Empty event class used to request a List of opened wallets
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
package com.sparrowwallet.sparrow.event;
|
||||||
|
|
||||||
|
public class RequestWalletOpenEvent {
|
||||||
|
//Empty event class used to request the wallet open dialog
|
||||||
|
}
|
|
@ -26,6 +26,7 @@ public class FontAwesome5 extends GlyphFont {
|
||||||
LAPTOP('\uf109'),
|
LAPTOP('\uf109'),
|
||||||
LOCK('\uf023'),
|
LOCK('\uf023'),
|
||||||
LOCK_OPEN('\uf3c1'),
|
LOCK_OPEN('\uf3c1'),
|
||||||
|
PEN_FANCY('\uf5ac'),
|
||||||
QUESTION_CIRCLE('\uf059'),
|
QUESTION_CIRCLE('\uf059'),
|
||||||
SD_CARD('\uf7c2'),
|
SD_CARD('\uf7c2'),
|
||||||
SEARCH('\uf002'),
|
SEARCH('\uf002'),
|
||||||
|
|
|
@ -1,19 +1,17 @@
|
||||||
package com.sparrowwallet.sparrow.transaction;
|
package com.sparrowwallet.sparrow.transaction;
|
||||||
|
|
||||||
import com.sparrowwallet.drongo.protocol.Sha256Hash;
|
import com.sparrowwallet.drongo.protocol.*;
|
||||||
import com.sparrowwallet.drongo.protocol.Transaction;
|
import com.sparrowwallet.drongo.psbt.PSBT;
|
||||||
import com.sparrowwallet.drongo.protocol.TransactionInput;
|
import com.sparrowwallet.drongo.psbt.PSBTInput;
|
||||||
import com.sparrowwallet.drongo.protocol.TransactionOutput;
|
|
||||||
import com.sparrowwallet.drongo.wallet.BlockTransaction;
|
import com.sparrowwallet.drongo.wallet.BlockTransaction;
|
||||||
|
import com.sparrowwallet.drongo.wallet.Wallet;
|
||||||
import com.sparrowwallet.sparrow.AppController;
|
import com.sparrowwallet.sparrow.AppController;
|
||||||
import com.sparrowwallet.sparrow.EventManager;
|
import com.sparrowwallet.sparrow.EventManager;
|
||||||
import com.sparrowwallet.sparrow.control.CoinLabel;
|
import com.sparrowwallet.sparrow.control.CoinLabel;
|
||||||
import com.sparrowwallet.sparrow.control.IdLabel;
|
import com.sparrowwallet.sparrow.control.IdLabel;
|
||||||
import com.sparrowwallet.sparrow.control.CopyableLabel;
|
import com.sparrowwallet.sparrow.control.CopyableLabel;
|
||||||
import com.sparrowwallet.sparrow.event.BitcoinUnitChangedEvent;
|
import com.sparrowwallet.sparrow.event.*;
|
||||||
import com.sparrowwallet.sparrow.event.BlockTransactionFetchedEvent;
|
import javafx.collections.FXCollections;
|
||||||
import com.sparrowwallet.sparrow.event.TransactionChangedEvent;
|
|
||||||
import com.sparrowwallet.sparrow.event.TransactionLocktimeChangedEvent;
|
|
||||||
import javafx.event.ActionEvent;
|
import javafx.event.ActionEvent;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.fxml.Initializable;
|
import javafx.fxml.Initializable;
|
||||||
|
@ -29,8 +27,10 @@ import tornadofx.control.Form;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.time.*;
|
import java.time.*;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.ResourceBundle;
|
import java.util.ResourceBundle;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class HeadersController extends TransactionFormController implements Initializable {
|
public class HeadersController extends TransactionFormController implements Initializable {
|
||||||
public static final String LOCKTIME_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
|
public static final String LOCKTIME_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
|
||||||
|
@ -107,6 +107,30 @@ public class HeadersController extends TransactionFormController implements Init
|
||||||
@FXML
|
@FXML
|
||||||
private IdLabel blockHash;
|
private IdLabel blockHash;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private Form finalizeForm;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private ComboBox<Wallet> signingWallet;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private Label noWalletsWarning;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private Hyperlink noWalletsWarningLink;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private ComboBox<SigHash> sigHash;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private Button finalizeTransaction;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private Form signaturesForm;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private Form broadcastForm;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialize(URL location, ResourceBundle resources) {
|
public void initialize(URL location, ResourceBundle resources) {
|
||||||
EventManager.get().register(this);
|
EventManager.get().register(this);
|
||||||
|
@ -237,10 +261,49 @@ public class HeadersController extends TransactionFormController implements Init
|
||||||
}
|
}
|
||||||
|
|
||||||
blockchainForm.managedProperty().bind(blockchainForm.visibleProperty());
|
blockchainForm.managedProperty().bind(blockchainForm.visibleProperty());
|
||||||
|
finalizeForm.managedProperty().bind(finalizeForm.visibleProperty());
|
||||||
|
signaturesForm.managedProperty().bind(signaturesForm.visibleProperty());
|
||||||
|
broadcastForm.managedProperty().bind(broadcastForm.visibleProperty());
|
||||||
|
|
||||||
|
blockchainForm.setVisible(false);
|
||||||
|
finalizeForm.setVisible(false);
|
||||||
|
signaturesForm.setVisible(false);
|
||||||
|
broadcastForm.setVisible(false);
|
||||||
|
|
||||||
if(headersForm.getBlockTransaction() != null) {
|
if(headersForm.getBlockTransaction() != null) {
|
||||||
|
blockchainForm.setVisible(true);
|
||||||
updateBlockchainForm(headersForm.getBlockTransaction());
|
updateBlockchainForm(headersForm.getBlockTransaction());
|
||||||
} else {
|
} else if(headersForm.getPsbt() != null) {
|
||||||
blockchainForm.setVisible(false);
|
PSBT psbt = headersForm.getPsbt();
|
||||||
|
|
||||||
|
if(headersForm.isEditable()) {
|
||||||
|
finalizeForm.setVisible(true);
|
||||||
|
} else if(headersForm.getPsbt().isSigned()) {
|
||||||
|
broadcastForm.setVisible(true);
|
||||||
|
} else {
|
||||||
|
signaturesForm.setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
signingWallet.valueProperty().addListener((observable, oldValue, newValue) -> headersForm.setSigningWallet(newValue));
|
||||||
|
EventManager.get().post(new RequestOpenWalletsEvent());
|
||||||
|
|
||||||
|
signingWallet.managedProperty().bind(signingWallet.visibleProperty());
|
||||||
|
noWalletsWarning.managedProperty().bind(noWalletsWarning.visibleProperty());
|
||||||
|
noWalletsWarningLink.managedProperty().bind(noWalletsWarningLink.visibleProperty());
|
||||||
|
noWalletsWarningLink.visibleProperty().bind(noWalletsWarning.visibleProperty());
|
||||||
|
|
||||||
|
SigHash psbtSigHash = SigHash.ALL;
|
||||||
|
for(PSBTInput psbtInput : psbt.getPsbtInputs()) {
|
||||||
|
if(psbtInput.getSigHash() != null) {
|
||||||
|
psbtSigHash = psbtInput.getSigHash();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sigHash.setValue(psbtSigHash);
|
||||||
|
sigHash.valueProperty().addListener((observable, oldValue, newValue) -> {
|
||||||
|
for(PSBTInput psbtInput : psbt.getPsbtInputs()) {
|
||||||
|
psbtInput.setSigHash(newValue);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -331,6 +394,14 @@ public class HeadersController extends TransactionFormController implements Init
|
||||||
Clipboard.getSystemClipboard().setContent(content);
|
Clipboard.getSystemClipboard().setContent(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void openWallet(ActionEvent event) {
|
||||||
|
EventManager.get().post(new RequestWalletOpenEvent());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void finalizeTransaction(ActionEvent event) {
|
||||||
|
EventManager.get().post(new FinalizePSBTEvent(headersForm.getPsbt(), headersForm.getSigningWallet()));
|
||||||
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void transactionChanged(TransactionChangedEvent event) {
|
public void transactionChanged(TransactionChangedEvent event) {
|
||||||
if(headersForm.getTransaction().equals(event.getTransaction())) {
|
if(headersForm.getTransaction().equals(event.getTransaction())) {
|
||||||
|
@ -362,4 +433,41 @@ public class HeadersController extends TransactionFormController implements Init
|
||||||
public void bitcoinUnitChanged(BitcoinUnitChangedEvent event) {
|
public void bitcoinUnitChanged(BitcoinUnitChangedEvent event) {
|
||||||
fee.refresh(event.getBitcoinUnit());
|
fee.refresh(event.getBitcoinUnit());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void openWallets(OpenWalletsEvent event) {
|
||||||
|
if(headersForm.getPsbt() != null && headersForm.isEditable()) {
|
||||||
|
List<Wallet> availableWallets = event.getWallets().stream().filter(wallet -> wallet.canSign(headersForm.getPsbt())).collect(Collectors.toList());
|
||||||
|
signingWallet.setItems(FXCollections.observableList(availableWallets));
|
||||||
|
if(!availableWallets.isEmpty()) {
|
||||||
|
if(availableWallets.contains(headersForm.getSigningWallet())) {
|
||||||
|
signingWallet.setValue(headersForm.getSigningWallet());
|
||||||
|
} else {
|
||||||
|
signingWallet.setValue(availableWallets.get(0));
|
||||||
|
}
|
||||||
|
noWalletsWarning.setVisible(false);
|
||||||
|
signingWallet.setVisible(true);
|
||||||
|
finalizeTransaction.setDisable(false);
|
||||||
|
} else {
|
||||||
|
noWalletsWarning.setVisible(true);
|
||||||
|
signingWallet.setVisible(false);
|
||||||
|
finalizeTransaction.setDisable(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void finalizePSBT(FinalizePSBTEvent event) {
|
||||||
|
if(headersForm.getPsbt() == event.getPsbt()) {
|
||||||
|
version.setDisable(true);
|
||||||
|
locktimeNoneType.setDisable(true);
|
||||||
|
locktimeBlockType.setDisable(true);
|
||||||
|
locktimeDateType.setDisable(true);
|
||||||
|
locktimeBlock.setDisable(true);
|
||||||
|
locktimeDate.setDisable(true);
|
||||||
|
|
||||||
|
finalizeForm.setVisible(false);
|
||||||
|
signaturesForm.setVisible(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -500,4 +500,17 @@ public class InputController extends TransactionFormController implements Initia
|
||||||
public void bitcoinUnitChanged(BitcoinUnitChangedEvent event) {
|
public void bitcoinUnitChanged(BitcoinUnitChangedEvent event) {
|
||||||
spends.refresh(event.getBitcoinUnit());
|
spends.refresh(event.getBitcoinUnit());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void finalizePSBT(FinalizePSBTEvent event) {
|
||||||
|
if(inputForm.getPsbt() == event.getPsbt()) {
|
||||||
|
rbf.setDisable(true);
|
||||||
|
locktimeNoneType.setDisable(true);
|
||||||
|
locktimeAbsoluteType.setDisable(true);
|
||||||
|
locktimeRelativeType.setDisable(true);
|
||||||
|
locktimeRelativeBlocks.setDisable(true);
|
||||||
|
locktimeRelativeSeconds.setDisable(true);
|
||||||
|
locktimeRelativeCombo.setDisable(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import com.sparrowwallet.drongo.protocol.Sha256Hash;
|
||||||
import com.sparrowwallet.drongo.protocol.Transaction;
|
import com.sparrowwallet.drongo.protocol.Transaction;
|
||||||
import com.sparrowwallet.drongo.psbt.PSBT;
|
import com.sparrowwallet.drongo.psbt.PSBT;
|
||||||
import com.sparrowwallet.drongo.wallet.BlockTransaction;
|
import com.sparrowwallet.drongo.wallet.BlockTransaction;
|
||||||
|
import com.sparrowwallet.drongo.wallet.Wallet;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -20,6 +21,8 @@ public class TransactionData {
|
||||||
private int minOutputFetched;
|
private int minOutputFetched;
|
||||||
private int maxOutputFetched;
|
private int maxOutputFetched;
|
||||||
|
|
||||||
|
private Wallet signingWallet;
|
||||||
|
|
||||||
public TransactionData(PSBT psbt) {
|
public TransactionData(PSBT psbt) {
|
||||||
this.transaction = psbt.getTransaction();
|
this.transaction = psbt.getTransaction();
|
||||||
this.psbt = psbt;
|
this.psbt = psbt;
|
||||||
|
@ -109,4 +112,12 @@ public class TransactionData {
|
||||||
public boolean allOutputsFetched() {
|
public boolean allOutputsFetched() {
|
||||||
return minOutputFetched == 0 && maxOutputFetched == transaction.getOutputs().size();
|
return minOutputFetched == 0 && maxOutputFetched == transaction.getOutputs().size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Wallet getSigningWallet() {
|
||||||
|
return signingWallet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSigningWallet(Wallet signingWallet) {
|
||||||
|
this.signingWallet = signingWallet;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import com.sparrowwallet.drongo.protocol.Sha256Hash;
|
||||||
import com.sparrowwallet.drongo.protocol.Transaction;
|
import com.sparrowwallet.drongo.protocol.Transaction;
|
||||||
import com.sparrowwallet.drongo.psbt.PSBT;
|
import com.sparrowwallet.drongo.psbt.PSBT;
|
||||||
import com.sparrowwallet.drongo.wallet.BlockTransaction;
|
import com.sparrowwallet.drongo.wallet.BlockTransaction;
|
||||||
|
import com.sparrowwallet.drongo.wallet.Wallet;
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -53,8 +54,27 @@ public abstract class TransactionForm {
|
||||||
return txdata.allOutputsFetched();
|
return txdata.allOutputsFetched();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Wallet getSigningWallet() {
|
||||||
|
return txdata.getSigningWallet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSigningWallet(Wallet signingWallet) {
|
||||||
|
txdata.setSigningWallet(signingWallet);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isEditable() {
|
public boolean isEditable() {
|
||||||
return txdata.getBlockTransaction() == null;
|
if(getBlockTransaction() != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(getPsbt() != null) {
|
||||||
|
if(getPsbt().hasSignatures() || getPsbt().isSigned()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return txdata.getSigningWallet() == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract Node getContents() throws IOException;
|
public abstract Node getContents() throws IOException;
|
||||||
|
|
|
@ -54,7 +54,7 @@
|
||||||
</Form>
|
</Form>
|
||||||
|
|
||||||
<StackPane GridPane.columnIndex="0" GridPane.rowIndex="1">
|
<StackPane GridPane.columnIndex="0" GridPane.rowIndex="1">
|
||||||
<Button fx:id="testConnection" text="Test Connection">
|
<Button fx:id="testConnection" graphicTextGap="5" text="Test Connection">
|
||||||
<graphic>
|
<graphic>
|
||||||
<Glyph fontFamily="FontAwesome" icon="QUESTION_CIRCLE" prefWidth="13" />
|
<Glyph fontFamily="FontAwesome" icon="QUESTION_CIRCLE" prefWidth="13" />
|
||||||
</graphic>
|
</graphic>
|
||||||
|
|
|
@ -19,3 +19,17 @@
|
||||||
.witness-data { -fx-fill: #a626a4 }
|
.witness-data { -fx-fill: #a626a4 }
|
||||||
|
|
||||||
.locktime { -fx-fill: #986801 }
|
.locktime { -fx-fill: #986801 }
|
||||||
|
|
||||||
|
.signatures-button {
|
||||||
|
-fx-padding: 10 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#finalizeForm .input-container {
|
||||||
|
-fx-alignment: center-left;
|
||||||
|
-fx-pref-height: 30;
|
||||||
|
}
|
||||||
|
|
||||||
|
#noWalletsWarning .glyph-font {
|
||||||
|
-fx-text-fill: rgb(202, 18, 67);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,11 @@
|
||||||
<?import com.sparrowwallet.sparrow.control.CoinLabel?>
|
<?import com.sparrowwallet.sparrow.control.CoinLabel?>
|
||||||
<?import javafx.scene.control.Button?>
|
<?import javafx.scene.control.Button?>
|
||||||
<?import org.controlsfx.glyphfont.Glyph?>
|
<?import org.controlsfx.glyphfont.Glyph?>
|
||||||
|
<?import javafx.scene.control.ComboBox?>
|
||||||
|
<?import com.sparrowwallet.drongo.protocol.SigHash?>
|
||||||
|
<?import javafx.collections.FXCollections?>
|
||||||
|
<?import javafx.scene.control.Label?>
|
||||||
|
<?import javafx.scene.control.Hyperlink?>
|
||||||
|
|
||||||
<GridPane hgap="10.0" vgap="10.0" styleClass="tx-pane" xmlns="http://javafx.com/javafx/10.0.2-internal" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.sparrowwallet.sparrow.transaction.HeadersController" stylesheets="@headers.css, @transaction.css, @../general.css">
|
<GridPane hgap="10.0" vgap="10.0" styleClass="tx-pane" xmlns="http://javafx.com/javafx/10.0.2-internal" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.sparrowwallet.sparrow.transaction.HeadersController" stylesheets="@headers.css, @transaction.css, @../general.css">
|
||||||
<padding>
|
<padding>
|
||||||
|
@ -123,4 +128,49 @@
|
||||||
</Fieldset>
|
</Fieldset>
|
||||||
</Form>
|
</Form>
|
||||||
|
|
||||||
|
<Form fx:id="finalizeForm" GridPane.columnIndex="0" GridPane.columnSpan="2" GridPane.rowIndex="6">
|
||||||
|
<Fieldset text="Signatures" inputGrow="SOMETIMES">
|
||||||
|
<Field text="Signing Wallet:">
|
||||||
|
<ComboBox fx:id="signingWallet" />
|
||||||
|
<Label fx:id="noWalletsWarning" graphicTextGap="5" text="No open wallets can sign this PSBT. ">
|
||||||
|
<graphic>
|
||||||
|
<Glyph fontFamily="Font Awesome 5 Free Solid" fontSize="12" icon="EXCLAMATION_CIRCLE" />
|
||||||
|
</graphic>
|
||||||
|
</Label>
|
||||||
|
<Hyperlink fx:id="noWalletsWarningLink" text="Open another wallet?" onAction="#openWallet" />
|
||||||
|
</Field>
|
||||||
|
<Field text="Sighash:">
|
||||||
|
<ComboBox fx:id="sigHash">
|
||||||
|
<items>
|
||||||
|
<FXCollections fx:factory="observableArrayList">
|
||||||
|
<SigHash fx:constant="ALL" />
|
||||||
|
<SigHash fx:constant="NONE" />
|
||||||
|
<SigHash fx:constant="SINGLE" />
|
||||||
|
<SigHash fx:constant="ANYONECANPAY_ALL" />
|
||||||
|
<SigHash fx:constant="ANYONECANPAY_NONE" />
|
||||||
|
<SigHash fx:constant="ANYONECANPAY_SINGLE" />
|
||||||
|
</FXCollections>
|
||||||
|
</items>
|
||||||
|
</ComboBox>
|
||||||
|
</Field>
|
||||||
|
</Fieldset>
|
||||||
|
<StackPane styleClass="signatures-button">
|
||||||
|
<Button fx:id="finalizeTransaction" graphicTextGap="5" text="Finalize Transaction for Signing" prefWidth="Infinity" defaultButton="true" onAction="#finalizeTransaction">
|
||||||
|
<graphic>
|
||||||
|
<Glyph fontFamily="Font Awesome 5 Free Solid" fontSize="10" icon="LOCK" />
|
||||||
|
</graphic>
|
||||||
|
</Button>
|
||||||
|
</StackPane>
|
||||||
|
</Form>
|
||||||
|
|
||||||
|
<Form fx:id="signaturesForm" GridPane.columnIndex="0" GridPane.columnSpan="2" GridPane.rowIndex="6">
|
||||||
|
<Fieldset text="Signatures" inputGrow="SOMETIMES">
|
||||||
|
</Fieldset>
|
||||||
|
</Form>
|
||||||
|
|
||||||
|
<Form fx:id="broadcastForm" GridPane.columnIndex="0" GridPane.columnSpan="2" GridPane.rowIndex="6">
|
||||||
|
<Fieldset text="Send" inputGrow="SOMETIMES">
|
||||||
|
</Fieldset>
|
||||||
|
</Form>
|
||||||
|
|
||||||
</GridPane>
|
</GridPane>
|
||||||
|
|
|
@ -85,7 +85,7 @@
|
||||||
<padding>
|
<padding>
|
||||||
<Insets left="25.0" right="25.0" bottom="25.0" />
|
<Insets left="25.0" right="25.0" bottom="25.0" />
|
||||||
</padding>
|
</padding>
|
||||||
<Button fx:id="nextAddress" text="Get Next Address" defaultButton="true" AnchorPane.rightAnchor="10" onAction="#getNewAddress">
|
<Button fx:id="nextAddress" graphicTextGap="5" text="Get Next Address" defaultButton="true" AnchorPane.rightAnchor="10" onAction="#getNewAddress">
|
||||||
<graphic>
|
<graphic>
|
||||||
<Glyph fontFamily="FontAwesome" icon="ARROW_DOWN" fontSize="12" />
|
<Glyph fontFamily="FontAwesome" icon="ARROW_DOWN" fontSize="12" />
|
||||||
</graphic>
|
</graphic>
|
||||||
|
|
Loading…
Reference in a new issue