mirror of
https://github.com/sparrowwallet/sparrow.git
synced 2024-11-02 20:36:44 +00:00
broadcast tx
This commit is contained in:
parent
75f5fd2e12
commit
c9d7b03afc
6 changed files with 109 additions and 8 deletions
|
@ -24,6 +24,7 @@ public class BalanceChart extends LineChart<Number, Number> {
|
|||
}
|
||||
|
||||
public void initialize(WalletTransactionsEntry walletTransactionsEntry) {
|
||||
managedProperty().bind(visibleProperty());
|
||||
balanceSeries = new XYChart.Series<>();
|
||||
getData().add(balanceSeries);
|
||||
update(walletTransactionsEntry);
|
||||
|
@ -33,6 +34,10 @@ public class BalanceChart extends LineChart<Number, Number> {
|
|||
}
|
||||
|
||||
public void update(WalletTransactionsEntry walletTransactionsEntry) {
|
||||
if(walletTransactionsEntry.getChildren().isEmpty()) {
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
balanceSeries.getData().clear();
|
||||
|
||||
List<Data<Number, Number>> balanceDataList = walletTransactionsEntry.getChildren().stream()
|
||||
|
|
|
@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
|||
import com.github.arteam.simplejsonrpc.client.*;
|
||||
import com.github.arteam.simplejsonrpc.client.builder.BatchRequestBuilder;
|
||||
import com.github.arteam.simplejsonrpc.client.exception.JsonRpcBatchException;
|
||||
import com.github.arteam.simplejsonrpc.client.exception.JsonRpcException;
|
||||
import com.github.arteam.simplejsonrpc.core.annotation.JsonRpcMethod;
|
||||
import com.github.arteam.simplejsonrpc.core.annotation.JsonRpcParam;
|
||||
import com.github.arteam.simplejsonrpc.core.annotation.JsonRpcService;
|
||||
|
@ -594,6 +595,26 @@ public class ElectrumServer {
|
|||
return targetBlocksFeeRatesSats;
|
||||
}
|
||||
|
||||
public Sha256Hash broadcastTransaction(Transaction transaction) throws ServerException {
|
||||
byte[] rawtxBytes = transaction.bitcoinSerialize();
|
||||
String rawtxHex = Utils.bytesToHex(rawtxBytes);
|
||||
|
||||
JsonRpcClient client = new JsonRpcClient(getTransport());
|
||||
try {
|
||||
String strTxHash = client.createRequest().returnAs(String.class).method("blockchain.transaction.broadcast").id(1).param("raw_tx", rawtxHex).execute();
|
||||
Sha256Hash receivedTxid = Sha256Hash.wrap(strTxHash);
|
||||
if(!receivedTxid.equals(transaction.getTxId())) {
|
||||
throw new ServerException("Received txid was different (" + receivedTxid + ")");
|
||||
}
|
||||
|
||||
return receivedTxid;
|
||||
} catch(JsonRpcException e) {
|
||||
throw new ServerException(e.getErrorMessage().getMessage());
|
||||
} catch(IllegalStateException e) {
|
||||
throw new ServerException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public static String getScriptHash(Wallet wallet, WalletNode node) {
|
||||
byte[] hash = Sha256Hash.hash(wallet.getOutputScript(node).getProgram());
|
||||
byte[] reversed = Utils.reverseBytes(hash);
|
||||
|
@ -1139,6 +1160,24 @@ public class ElectrumServer {
|
|||
}
|
||||
}
|
||||
|
||||
public static class BroadcastTransactionService extends Service<Sha256Hash> {
|
||||
private final Transaction transaction;
|
||||
|
||||
public BroadcastTransactionService(Transaction transaction) {
|
||||
this.transaction = transaction;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Task<Sha256Hash> createTask() {
|
||||
return new Task<>() {
|
||||
protected Sha256Hash call() throws ServerException {
|
||||
ElectrumServer electrumServer = new ElectrumServer();
|
||||
return electrumServer.broadcastTransaction(transaction);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public enum Protocol {
|
||||
TCP {
|
||||
@Override
|
||||
|
|
|
@ -10,6 +10,7 @@ import com.sparrowwallet.sparrow.EventManager;
|
|||
import com.sparrowwallet.sparrow.control.*;
|
||||
import com.sparrowwallet.sparrow.event.*;
|
||||
import com.sparrowwallet.sparrow.glyphfont.FontAwesome5Brands;
|
||||
import com.sparrowwallet.sparrow.io.ElectrumServer;
|
||||
import com.sparrowwallet.sparrow.io.Storage;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.event.ActionEvent;
|
||||
|
@ -154,6 +155,9 @@ public class HeadersController extends TransactionFormController implements Init
|
|||
@FXML
|
||||
private SignaturesProgressBar signaturesProgressBar;
|
||||
|
||||
@FXML
|
||||
private ProgressBar broadcastProgressBar;
|
||||
|
||||
@FXML
|
||||
private HBox signButtonBox;
|
||||
|
||||
|
@ -163,6 +167,12 @@ public class HeadersController extends TransactionFormController implements Init
|
|||
@FXML
|
||||
private HBox broadcastButtonBox;
|
||||
|
||||
@FXML
|
||||
private Button viewFinalButton;
|
||||
|
||||
@FXML
|
||||
private Button broadcastButton;
|
||||
|
||||
@Override
|
||||
public void initialize(URL location, ResourceBundle resources) {
|
||||
EventManager.get().register(this);
|
||||
|
@ -302,6 +312,10 @@ public class HeadersController extends TransactionFormController implements Init
|
|||
signButtonBox.managedProperty().bind(signButtonBox.visibleProperty());
|
||||
broadcastButtonBox.managedProperty().bind(broadcastButtonBox.visibleProperty());
|
||||
|
||||
signaturesProgressBar.managedProperty().bind(signaturesProgressBar.visibleProperty());
|
||||
broadcastProgressBar.managedProperty().bind(broadcastProgressBar.visibleProperty());
|
||||
broadcastProgressBar.visibleProperty().bind(signaturesProgressBar.visibleProperty().not());
|
||||
|
||||
blockchainForm.setVisible(false);
|
||||
signingWalletForm.setVisible(false);
|
||||
sigHashForm.setVisible(false);
|
||||
|
@ -312,7 +326,7 @@ public class HeadersController extends TransactionFormController implements Init
|
|||
|
||||
if(headersForm.getBlockTransaction() != null) {
|
||||
blockchainForm.setVisible(true);
|
||||
updateBlockchainForm(headersForm.getBlockTransaction());
|
||||
updateBlockchainForm(headersForm.getBlockTransaction(), AppController.getCurrentBlockHeight());
|
||||
} else if(headersForm.getPsbt() != null) {
|
||||
PSBT psbt = headersForm.getPsbt();
|
||||
|
||||
|
@ -397,10 +411,9 @@ public class HeadersController extends TransactionFormController implements Init
|
|||
feeRate.setText(String.format("%.2f", feeRateAmt) + " sats/vByte");
|
||||
}
|
||||
|
||||
private void updateBlockchainForm(BlockTransaction blockTransaction) {
|
||||
private void updateBlockchainForm(BlockTransaction blockTransaction, Integer currentHeight) {
|
||||
blockchainForm.setVisible(true);
|
||||
|
||||
Integer currentHeight = AppController.getCurrentBlockHeight();
|
||||
if(currentHeight == null) {
|
||||
blockStatus.setText("Unknown");
|
||||
} else {
|
||||
|
@ -604,7 +617,6 @@ public class HeadersController extends TransactionFormController implements Init
|
|||
}
|
||||
|
||||
public void extractTransaction(ActionEvent event) {
|
||||
Button viewFinalButton = (Button)event.getSource();
|
||||
viewFinalButton.setDisable(true);
|
||||
|
||||
Transaction finalTx = headersForm.getPsbt().extractTransaction();
|
||||
|
@ -613,9 +625,22 @@ public class HeadersController extends TransactionFormController implements Init
|
|||
}
|
||||
|
||||
public void broadcastTransaction(ActionEvent event) {
|
||||
broadcastButton.setDisable(true);
|
||||
extractTransaction(event);
|
||||
|
||||
ElectrumServer.BroadcastTransactionService broadcastTransactionService = new ElectrumServer.BroadcastTransactionService(headersForm.getTransaction());
|
||||
broadcastTransactionService.setOnSucceeded(workerStateEvent -> {
|
||||
//Do nothing and wait for WalletNodeHistoryChangedEvent to indicate tx is in mempool
|
||||
});
|
||||
broadcastTransactionService.setOnFailed(workerStateEvent -> {
|
||||
broadcastProgressBar.setProgress(0);
|
||||
AppController.showErrorDialog("Error broadcasting transaction", workerStateEvent.getSource().getException().getMessage());
|
||||
broadcastButton.setDisable(false);
|
||||
});
|
||||
|
||||
signaturesProgressBar.setVisible(false);
|
||||
broadcastProgressBar.setProgress(-1);
|
||||
broadcastTransactionService.start();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
|
@ -635,7 +660,7 @@ public class HeadersController extends TransactionFormController implements Init
|
|||
public void blockTransactionFetched(BlockTransactionFetchedEvent event) {
|
||||
if(event.getTxId().equals(headersForm.getTransaction().getTxId())) {
|
||||
if(event.getBlockTransaction() != null) {
|
||||
updateBlockchainForm(event.getBlockTransaction());
|
||||
updateBlockchainForm(event.getBlockTransaction(), AppController.getCurrentBlockHeight());
|
||||
}
|
||||
|
||||
Long feeAmt = calculateFee(event.getInputTransactions());
|
||||
|
@ -766,4 +791,29 @@ public class HeadersController extends TransactionFormController implements Init
|
|||
updateTxId();
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void walletNodeHistoryChanged(WalletNodeHistoryChangedEvent event) {
|
||||
if(headersForm.getSigningWallet() != null && event.getWalletNode(headersForm.getSigningWallet()) != null) {
|
||||
Sha256Hash txid = headersForm.getTransaction().getTxId();
|
||||
ElectrumServer.TransactionReferenceService transactionReferenceService = new ElectrumServer.TransactionReferenceService(Set.of(txid));
|
||||
transactionReferenceService.setOnSucceeded(successEvent -> {
|
||||
Map<Sha256Hash, BlockTransaction> transactionMap = transactionReferenceService.getValue();
|
||||
BlockTransaction blockTransaction = transactionMap.get(txid);
|
||||
if(blockTransaction != null) {
|
||||
headersForm.setBlockTransaction(blockTransaction);
|
||||
signaturesForm.setVisible(false);
|
||||
updateBlockchainForm(blockTransaction, AppController.getCurrentBlockHeight());
|
||||
}
|
||||
});
|
||||
transactionReferenceService.start();
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void walletBlockHeightChanged(WalletBlockHeightChangedEvent event) {
|
||||
if(headersForm.getSigningWallet() != null && event.getWallet() == headersForm.getSigningWallet() && headersForm.getBlockTransaction() != null) {
|
||||
updateBlockchainForm(headersForm.getBlockTransaction(), event.getBlockHeight());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package com.sparrowwallet.sparrow.transaction;
|
||||
|
||||
import com.sparrowwallet.drongo.protocol.Transaction;
|
||||
import com.sparrowwallet.drongo.wallet.BlockTransaction;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Node;
|
||||
|
||||
|
@ -15,6 +16,10 @@ public class HeadersForm extends TransactionForm {
|
|||
txdata.setTransaction(finalTransaction);
|
||||
}
|
||||
|
||||
void setBlockTransaction(BlockTransaction blockTransaction) {
|
||||
txdata.setBlockTransaction(blockTransaction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node getContents() throws IOException {
|
||||
FXMLLoader loader = new FXMLLoader(getClass().getResource("headers.fxml"));
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
-fx-max-width: Infinity;
|
||||
}
|
||||
|
||||
.signatures-progress-bar {
|
||||
.signatures-progress-bar, #broadcastProgressBar {
|
||||
-fx-padding: 10 0 10 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.Hyperlink?>
|
||||
<?import com.sparrowwallet.sparrow.control.SignaturesProgressBar?>
|
||||
<?import javafx.scene.control.ProgressBar?>
|
||||
|
||||
<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>
|
||||
|
@ -174,6 +175,7 @@
|
|||
<Fieldset text="Signatures" inputGrow="SOMETIMES">
|
||||
<VBox>
|
||||
<SignaturesProgressBar fx:id="signaturesProgressBar" />
|
||||
<ProgressBar fx:id="broadcastProgressBar" maxWidth="Infinity" prefHeight="50" />
|
||||
</VBox>
|
||||
<VBox>
|
||||
<HBox fx:id="signButtonBox" styleClass="signatures-buttons" spacing="20">
|
||||
|
@ -212,12 +214,12 @@
|
|||
</Button>
|
||||
</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">
|
||||
<Button fx:id="viewFinalButton" 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">
|
||||
<Button fx:id="broadcastButton" 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>
|
||||
|
|
Loading…
Reference in a new issue