mirror of
https://github.com/sparrowwallet/sparrow.git
synced 2024-12-24 12:46:45 +00:00
refactor singleton services from appcontroller to appservices
This commit is contained in:
parent
7461b47466
commit
39d1e686f4
38 changed files with 583 additions and 529 deletions
|
@ -7,7 +7,6 @@ import com.sparrowwallet.drongo.BitcoinUnit;
|
||||||
import com.sparrowwallet.drongo.Network;
|
import com.sparrowwallet.drongo.Network;
|
||||||
import com.sparrowwallet.drongo.SecureString;
|
import com.sparrowwallet.drongo.SecureString;
|
||||||
import com.sparrowwallet.drongo.Utils;
|
import com.sparrowwallet.drongo.Utils;
|
||||||
import com.sparrowwallet.drongo.address.Address;
|
|
||||||
import com.sparrowwallet.drongo.crypto.ECKey;
|
import com.sparrowwallet.drongo.crypto.ECKey;
|
||||||
import com.sparrowwallet.drongo.crypto.EncryptionType;
|
import com.sparrowwallet.drongo.crypto.EncryptionType;
|
||||||
import com.sparrowwallet.drongo.crypto.InvalidPasswordException;
|
import com.sparrowwallet.drongo.crypto.InvalidPasswordException;
|
||||||
|
@ -19,15 +18,11 @@ import com.sparrowwallet.drongo.protocol.Transaction;
|
||||||
import com.sparrowwallet.drongo.psbt.PSBT;
|
import com.sparrowwallet.drongo.psbt.PSBT;
|
||||||
import com.sparrowwallet.drongo.psbt.PSBTInput;
|
import com.sparrowwallet.drongo.psbt.PSBTInput;
|
||||||
import com.sparrowwallet.drongo.psbt.PSBTParseException;
|
import com.sparrowwallet.drongo.psbt.PSBTParseException;
|
||||||
import com.sparrowwallet.drongo.uri.BitcoinURI;
|
|
||||||
import com.sparrowwallet.drongo.wallet.*;
|
import com.sparrowwallet.drongo.wallet.*;
|
||||||
import com.sparrowwallet.sparrow.control.*;
|
import com.sparrowwallet.sparrow.control.*;
|
||||||
import com.sparrowwallet.sparrow.event.*;
|
import com.sparrowwallet.sparrow.event.*;
|
||||||
import com.sparrowwallet.sparrow.io.*;
|
import com.sparrowwallet.sparrow.io.*;
|
||||||
import com.sparrowwallet.sparrow.net.ElectrumServer;
|
import com.sparrowwallet.sparrow.net.ElectrumServer;
|
||||||
import com.sparrowwallet.sparrow.net.ExchangeSource;
|
|
||||||
import com.sparrowwallet.sparrow.net.MempoolRateSize;
|
|
||||||
import com.sparrowwallet.sparrow.net.VersionCheckService;
|
|
||||||
import com.sparrowwallet.sparrow.preferences.PreferencesDialog;
|
import com.sparrowwallet.sparrow.preferences.PreferencesDialog;
|
||||||
import com.sparrowwallet.sparrow.transaction.TransactionController;
|
import com.sparrowwallet.sparrow.transaction.TransactionController;
|
||||||
import com.sparrowwallet.sparrow.transaction.TransactionData;
|
import com.sparrowwallet.sparrow.transaction.TransactionData;
|
||||||
|
@ -37,10 +32,7 @@ import com.sparrowwallet.sparrow.wallet.WalletForm;
|
||||||
import de.codecentric.centerdevice.MenuToolkit;
|
import de.codecentric.centerdevice.MenuToolkit;
|
||||||
import javafx.animation.*;
|
import javafx.animation.*;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.beans.property.BooleanProperty;
|
|
||||||
import javafx.beans.property.SimpleBooleanProperty;
|
|
||||||
import javafx.collections.ListChangeListener;
|
import javafx.collections.ListChangeListener;
|
||||||
import javafx.concurrent.Worker;
|
|
||||||
import javafx.event.ActionEvent;
|
import javafx.event.ActionEvent;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.fxml.FXMLLoader;
|
import javafx.fxml.FXMLLoader;
|
||||||
|
@ -55,7 +47,6 @@ import javafx.scene.image.ImageView;
|
||||||
import javafx.scene.input.Dragboard;
|
import javafx.scene.input.Dragboard;
|
||||||
import javafx.scene.input.TransferMode;
|
import javafx.scene.input.TransferMode;
|
||||||
import javafx.scene.layout.StackPane;
|
import javafx.scene.layout.StackPane;
|
||||||
import javafx.scene.text.Font;
|
|
||||||
import javafx.stage.FileChooser;
|
import javafx.stage.FileChooser;
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
import javafx.stage.StageStyle;
|
import javafx.stage.StageStyle;
|
||||||
|
@ -70,27 +61,17 @@ import java.io.*;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.time.ZoneId;
|
|
||||||
import java.time.temporal.ChronoUnit;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static com.sparrowwallet.sparrow.AppServices.*;
|
||||||
|
|
||||||
public class AppController implements Initializable {
|
public class AppController implements Initializable {
|
||||||
private static final Logger log = LoggerFactory.getLogger(AppController.class);
|
private static final Logger log = LoggerFactory.getLogger(AppController.class);
|
||||||
|
|
||||||
private static final int SERVER_PING_PERIOD = 1 * 60 * 1000;
|
|
||||||
private static final int ENUMERATE_HW_PERIOD = 30 * 1000;
|
|
||||||
private static final int RATES_PERIOD = 5 * 60 * 1000;
|
|
||||||
private static final int VERSION_CHECK_PERIOD_HOURS = 24;
|
|
||||||
private static final ExchangeSource DEFAULT_EXCHANGE_SOURCE = ExchangeSource.COINGECKO;
|
|
||||||
private static final Currency DEFAULT_FIAT_CURRENCY = Currency.getInstance("USD");
|
|
||||||
|
|
||||||
public static final String DRAG_OVER_CLASS = "drag-over";
|
public static final String DRAG_OVER_CLASS = "drag-over";
|
||||||
|
|
||||||
private MainApp application;
|
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private MenuItem saveTransaction;
|
private MenuItem saveTransaction;
|
||||||
|
|
||||||
|
@ -127,35 +108,8 @@ public class AppController implements Initializable {
|
||||||
@FXML
|
@FXML
|
||||||
private UnlabeledToggleSwitch serverToggle;
|
private UnlabeledToggleSwitch serverToggle;
|
||||||
|
|
||||||
//Determines if a change in serverToggle changes the offline/online mode
|
|
||||||
private boolean changeMode = true;
|
|
||||||
|
|
||||||
private static final BooleanProperty onlineProperty = new SimpleBooleanProperty(false);
|
|
||||||
|
|
||||||
private Timeline statusTimeline;
|
private Timeline statusTimeline;
|
||||||
|
|
||||||
private ExchangeSource.RatesService ratesService;
|
|
||||||
|
|
||||||
private ElectrumServer.ConnectionService connectionService;
|
|
||||||
|
|
||||||
private Hwi.ScheduledEnumerateService deviceEnumerateService;
|
|
||||||
|
|
||||||
private VersionCheckService versionCheckService;
|
|
||||||
|
|
||||||
private static Integer currentBlockHeight;
|
|
||||||
|
|
||||||
private static Map<Integer, Double> targetBlockFeeRates;
|
|
||||||
|
|
||||||
private static final Map<Date, Set<MempoolRateSize>> mempoolHistogram = new TreeMap<>();
|
|
||||||
|
|
||||||
private static Double minimumRelayFeeRate;
|
|
||||||
|
|
||||||
private static CurrencyRate fiatCurrencyExchangeRate;
|
|
||||||
|
|
||||||
private static List<Device> devices;
|
|
||||||
|
|
||||||
private static final Map<Address, BitcoinURI> payjoinURIs = new HashMap<>();
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialize(URL location, ResourceBundle resources) {
|
public void initialize(URL location, ResourceBundle resources) {
|
||||||
EventManager.get().register(this);
|
EventManager.get().register(this);
|
||||||
|
@ -258,152 +212,12 @@ public class AppController implements Initializable {
|
||||||
showTxHex.setSelected(Config.get().isShowTransactionHex());
|
showTxHex.setSelected(Config.get().isShowTransactionHex());
|
||||||
exportWallet.setDisable(true);
|
exportWallet.setDisable(true);
|
||||||
|
|
||||||
serverToggle.selectedProperty().addListener((observable, oldValue, newValue) -> {
|
onlineProperty().bindBidirectional(serverToggle.selectedProperty());
|
||||||
if(changeMode) {
|
|
||||||
Config.get().setMode(newValue ? Mode.ONLINE : Mode.OFFLINE);
|
|
||||||
if(newValue) {
|
|
||||||
if(connectionService.getState() == Worker.State.CANCELLED) {
|
|
||||||
connectionService.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!connectionService.isRunning()) {
|
|
||||||
connectionService.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ratesService.getState() == Worker.State.CANCELLED) {
|
|
||||||
ratesService.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!ratesService.isRunning() && ratesService.getExchangeSource() != ExchangeSource.NONE) {
|
|
||||||
ratesService.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(versionCheckService.getState() == Worker.State.CANCELLED) {
|
|
||||||
versionCheckService.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!versionCheckService.isRunning() && Config.get().isCheckNewVersions()) {
|
|
||||||
versionCheckService.start();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
connectionService.cancel();
|
|
||||||
ratesService.cancel();
|
|
||||||
versionCheckService.cancel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
onlineProperty.bindBidirectional(serverToggle.selectedProperty());
|
|
||||||
onlineProperty().addListener((observable, oldValue, newValue) -> {
|
onlineProperty().addListener((observable, oldValue, newValue) -> {
|
||||||
Platform.runLater(this::setServerToggleTooltip);
|
Platform.runLater(() -> setServerToggleTooltip(getCurrentBlockHeight()));
|
||||||
});
|
});
|
||||||
|
|
||||||
Config config = Config.get();
|
openTransactionIdItem.disableProperty().bind(onlineProperty().not());
|
||||||
connectionService = createConnectionService();
|
|
||||||
if(config.getMode() == Mode.ONLINE && config.getElectrumServer() != null && !config.getElectrumServer().isEmpty()) {
|
|
||||||
connectionService.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
ExchangeSource source = config.getExchangeSource() != null ? config.getExchangeSource() : DEFAULT_EXCHANGE_SOURCE;
|
|
||||||
Currency currency = config.getFiatCurrency() != null ? config.getFiatCurrency() : DEFAULT_FIAT_CURRENCY;
|
|
||||||
ratesService = createRatesService(source, currency);
|
|
||||||
if(config.getMode() == Mode.ONLINE && source != ExchangeSource.NONE) {
|
|
||||||
ratesService.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
versionCheckService = createVersionCheckService();
|
|
||||||
if(config.getMode() == Mode.ONLINE && config.isCheckNewVersions()) {
|
|
||||||
versionCheckService.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
openTransactionIdItem.disableProperty().bind(onlineProperty.not());
|
|
||||||
}
|
|
||||||
|
|
||||||
private ElectrumServer.ConnectionService createConnectionService() {
|
|
||||||
ElectrumServer.ConnectionService connectionService = new ElectrumServer.ConnectionService();
|
|
||||||
connectionService.setPeriod(new Duration(SERVER_PING_PERIOD));
|
|
||||||
connectionService.setRestartOnFailure(true);
|
|
||||||
|
|
||||||
EventManager.get().register(connectionService);
|
|
||||||
connectionService.statusProperty().addListener((observable, oldValue, newValue) -> {
|
|
||||||
if(connectionService.isRunning()) {
|
|
||||||
EventManager.get().post(new StatusEvent(newValue));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
connectionService.setOnSucceeded(successEvent -> {
|
|
||||||
changeMode = false;
|
|
||||||
onlineProperty.setValue(true);
|
|
||||||
changeMode = true;
|
|
||||||
|
|
||||||
if(connectionService.getValue() != null) {
|
|
||||||
EventManager.get().post(connectionService.getValue());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
connectionService.setOnFailed(failEvent -> {
|
|
||||||
//Close connection here to create a new transport next time we try
|
|
||||||
connectionService.resetConnection();
|
|
||||||
|
|
||||||
changeMode = false;
|
|
||||||
onlineProperty.setValue(false);
|
|
||||||
changeMode = true;
|
|
||||||
|
|
||||||
log.debug("Connection failed", failEvent.getSource().getException());
|
|
||||||
EventManager.get().post(new ConnectionFailedEvent(failEvent.getSource().getException()));
|
|
||||||
});
|
|
||||||
|
|
||||||
return connectionService;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ExchangeSource.RatesService createRatesService(ExchangeSource exchangeSource, Currency currency) {
|
|
||||||
ExchangeSource.RatesService ratesService = new ExchangeSource.RatesService(exchangeSource, currency);
|
|
||||||
ratesService.setPeriod(new Duration(RATES_PERIOD));
|
|
||||||
ratesService.setRestartOnFailure(true);
|
|
||||||
|
|
||||||
ratesService.setOnSucceeded(successEvent -> {
|
|
||||||
EventManager.get().post(ratesService.getValue());
|
|
||||||
});
|
|
||||||
|
|
||||||
return ratesService;
|
|
||||||
}
|
|
||||||
|
|
||||||
private VersionCheckService createVersionCheckService() {
|
|
||||||
VersionCheckService versionCheckService = new VersionCheckService();
|
|
||||||
versionCheckService.setDelay(Duration.seconds(10));
|
|
||||||
versionCheckService.setPeriod(Duration.hours(VERSION_CHECK_PERIOD_HOURS));
|
|
||||||
versionCheckService.setRestartOnFailure(true);
|
|
||||||
|
|
||||||
versionCheckService.setOnSucceeded(successEvent -> {
|
|
||||||
VersionUpdatedEvent event = versionCheckService.getValue();
|
|
||||||
if(event != null) {
|
|
||||||
EventManager.get().post(event);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return versionCheckService;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Hwi.ScheduledEnumerateService createDeviceEnumerateService() {
|
|
||||||
Hwi.ScheduledEnumerateService enumerateService = new Hwi.ScheduledEnumerateService(null);
|
|
||||||
enumerateService.setPeriod(new Duration(ENUMERATE_HW_PERIOD));
|
|
||||||
enumerateService.setOnSucceeded(workerStateEvent -> {
|
|
||||||
List<Device> devices = enumerateService.getValue();
|
|
||||||
|
|
||||||
//Null devices are returned if the app is currently prompting for a pin. Otherwise, the enumerate clears the pin screen
|
|
||||||
if(devices != null) {
|
|
||||||
//If another instance of HWI is currently accessing the usb interface, HWI returns empty device models. Ignore this run if that happens
|
|
||||||
List<Device> validDevices = devices.stream().filter(device -> device.getModel() != null).collect(Collectors.toList());
|
|
||||||
if(validDevices.size() == devices.size()) {
|
|
||||||
Platform.runLater(() -> EventManager.get().post(new UsbDeviceEvent(devices)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return enumerateService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setApplication(MainApp application) {
|
|
||||||
this.application = application;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setOsxApplicationMenu() {
|
private void setOsxApplicationMenu() {
|
||||||
|
@ -577,7 +391,7 @@ public class AppController implements Initializable {
|
||||||
log.error("Error scanning QR", result.exception);
|
log.error("Error scanning QR", result.exception);
|
||||||
showErrorDialog("Error scanning QR", result.exception.getMessage());
|
showErrorDialog("Error scanning QR", result.exception.getMessage());
|
||||||
} else {
|
} else {
|
||||||
AppController.showErrorDialog("Invalid QR Code", "Cannot parse QR code into a transaction or PSBT");
|
AppServices.showErrorDialog("Invalid QR Code", "Cannot parse QR code into a transaction or PSBT");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -626,70 +440,12 @@ public class AppController implements Initializable {
|
||||||
}
|
}
|
||||||
} catch(IOException e) {
|
} catch(IOException e) {
|
||||||
log.error("Error saving transaction", e);
|
log.error("Error saving transaction", e);
|
||||||
AppController.showErrorDialog("Error saving transaction", "Cannot write to " + file.getAbsolutePath());
|
AppServices.showErrorDialog("Error saving transaction", "Cannot write to " + file.getAbsolutePath());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isOnline() {
|
|
||||||
return onlineProperty.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void connect() {
|
|
||||||
serverToggle.selectedProperty().set(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void disconnect() {
|
|
||||||
serverToggle.selectedProperty().set(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static BooleanProperty onlineProperty() { return onlineProperty; }
|
|
||||||
|
|
||||||
public static Integer getCurrentBlockHeight() {
|
|
||||||
return currentBlockHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Map<Integer, Double> getTargetBlockFeeRates() {
|
|
||||||
return targetBlockFeeRates;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Map<Date, Set<MempoolRateSize>> getMempoolHistogram() {
|
|
||||||
return mempoolHistogram;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addMempoolRateSizes(Set<MempoolRateSize> rateSizes) {
|
|
||||||
LocalDateTime dateMinute = LocalDateTime.now().truncatedTo(ChronoUnit.MINUTES);
|
|
||||||
if(mempoolHistogram.isEmpty()) {
|
|
||||||
mempoolHistogram.put(Date.from(dateMinute.minusMinutes(1).atZone(ZoneId.systemDefault()).toInstant()), rateSizes);
|
|
||||||
}
|
|
||||||
|
|
||||||
mempoolHistogram.put(Date.from(dateMinute.atZone(ZoneId.systemDefault()).toInstant()), rateSizes);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Double getMinimumRelayFeeRate() {
|
|
||||||
return minimumRelayFeeRate == null ? Transaction.DEFAULT_MIN_RELAY_FEE : minimumRelayFeeRate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static CurrencyRate getFiatCurrencyExchangeRate() {
|
|
||||||
return fiatCurrencyExchangeRate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<Device> getDevices() {
|
|
||||||
return devices == null ? new ArrayList<>() : devices;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static BitcoinURI getPayjoinURI(Address address) {
|
|
||||||
return payjoinURIs.get(address);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void addPayjoinURI(BitcoinURI bitcoinURI) {
|
|
||||||
if(bitcoinURI.getPayjoinUrl() == null) {
|
|
||||||
throw new IllegalArgumentException("Not a payjoin URI");
|
|
||||||
}
|
|
||||||
payjoinURIs.put(bitcoinURI.getAddress(), bitcoinURI);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<Wallet, Storage> getOpenWallets() {
|
public Map<Wallet, Storage> getOpenWallets() {
|
||||||
Map<Wallet, Storage> openWallets = new LinkedHashMap<>();
|
Map<Wallet, Storage> openWallets = new LinkedHashMap<>();
|
||||||
|
|
||||||
|
@ -704,28 +460,6 @@ public class AppController implements Initializable {
|
||||||
return openWallets;
|
return openWallets;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void showErrorDialog(String title, String content) {
|
|
||||||
Alert alert = new Alert(Alert.AlertType.ERROR);
|
|
||||||
setStageIcon(alert.getDialogPane().getScene().getWindow());
|
|
||||||
alert.getDialogPane().getScene().getStylesheets().add(AppController.class.getResource("general.css").toExternalForm());
|
|
||||||
alert.setTitle(title);
|
|
||||||
alert.setHeaderText(title);
|
|
||||||
alert.setContentText(content);
|
|
||||||
alert.showAndWait();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setStageIcon(Window window) {
|
|
||||||
Stage stage = (Stage)window;
|
|
||||||
stage.getIcons().add(new Image(AppController.class.getResourceAsStream("/image/sparrow.png")));
|
|
||||||
|
|
||||||
if(stage.getScene() != null && Config.get().getTheme() == Theme.DARK) {
|
|
||||||
stage.getScene().getStylesheets().add(AppController.class.getResource("darktheme.css").toExternalForm());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Font getMonospaceFont() {
|
|
||||||
return Font.font("Roboto Mono", 13);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void selectTab(Wallet wallet) {
|
public void selectTab(Wallet wallet) {
|
||||||
for(Tab tab : tabs.getTabs()) {
|
for(Tab tab : tabs.getTabs()) {
|
||||||
|
@ -745,7 +479,7 @@ public class AppController implements Initializable {
|
||||||
|
|
||||||
public void quit(ActionEvent event) {
|
public void quit(ActionEvent event) {
|
||||||
try {
|
try {
|
||||||
application.stop();
|
AppServices.get().getApplication().stop();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("Error quitting application", e);
|
log.error("Error quitting application", e);
|
||||||
}
|
}
|
||||||
|
@ -769,8 +503,8 @@ public class AppController implements Initializable {
|
||||||
return FileType.JSON.equals(fileType) || FileType.BINARY.equals(fileType);
|
return FileType.JSON.equals(fileType) || FileType.BINARY.equals(fileType);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setServerToggleTooltip() {
|
private void setServerToggleTooltip(Integer currentBlockHeight) {
|
||||||
serverToggle.setTooltip(new Tooltip(isOnline() ? "Connected to " + Config.get().getElectrumServer() + (getCurrentBlockHeight() != null ? " at height " + getCurrentBlockHeight() : "") : "Disconnected"));
|
serverToggle.setTooltip(new Tooltip(AppServices.isOnline() ? "Connected to " + Config.get().getElectrumServer() + (currentBlockHeight != null ? " at height " + currentBlockHeight : "") : "Disconnected"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void newWallet(ActionEvent event) {
|
public void newWallet(ActionEvent event) {
|
||||||
|
@ -1266,6 +1000,7 @@ public class AppController implements Initializable {
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void tabSelected(TabSelectedEvent event) {
|
public void tabSelected(TabSelectedEvent event) {
|
||||||
|
//TODO: Handle multiple windows
|
||||||
String tabName = event.getTabName();
|
String tabName = event.getTabName();
|
||||||
if(tabs.getScene() != null) {
|
if(tabs.getScene() != null) {
|
||||||
Stage tabStage = (Stage)tabs.getScene().getWindow();
|
Stage tabStage = (Stage)tabs.getScene().getWindow();
|
||||||
|
@ -1304,11 +1039,13 @@ public class AppController implements Initializable {
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void walletSettingsChanged(WalletSettingsChangedEvent event) {
|
public void walletSettingsChanged(WalletSettingsChangedEvent event) {
|
||||||
|
//TODO: Handle multiple windows
|
||||||
exportWallet.setDisable(!event.getWallet().isValid());
|
exportWallet.setDisable(!event.getWallet().isValid());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void newWalletTransactions(NewWalletTransactionsEvent event) {
|
public void newWalletTransactions(NewWalletTransactionsEvent event) {
|
||||||
|
//TODO: Handle multiple windows
|
||||||
if(Config.get().isNotifyNewTransactions()) {
|
if(Config.get().isNotifyNewTransactions()) {
|
||||||
String text;
|
String text;
|
||||||
if(event.getBlockTransactions().size() == 1) {
|
if(event.getBlockTransactions().size() == 1) {
|
||||||
|
@ -1380,7 +1117,7 @@ public class AppController implements Initializable {
|
||||||
public void versionUpdated(VersionUpdatedEvent event) {
|
public void versionUpdated(VersionUpdatedEvent event) {
|
||||||
Hyperlink versionUpdateLabel = new Hyperlink("Sparrow " + event.getVersion() + " available");
|
Hyperlink versionUpdateLabel = new Hyperlink("Sparrow " + event.getVersion() + " available");
|
||||||
versionUpdateLabel.setOnAction(event1 -> {
|
versionUpdateLabel.setOnAction(event1 -> {
|
||||||
application.getHostServices().showDocument("https://www.sparrowwallet.com/download");
|
AppServices.get().getApplication().getHostServices().showDocument("https://www.sparrowwallet.com/download");
|
||||||
});
|
});
|
||||||
|
|
||||||
if(statusBar.getRightItems().size() > 0 && statusBar.getRightItems().get(0) instanceof Hyperlink) {
|
if(statusBar.getRightItems().size() > 0 && statusBar.getRightItems().get(0) instanceof Hyperlink) {
|
||||||
|
@ -1417,8 +1154,6 @@ public class AppController implements Initializable {
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void usbDevicesFound(UsbDeviceEvent event) {
|
public void usbDevicesFound(UsbDeviceEvent event) {
|
||||||
devices = Collections.unmodifiableList(event.getDevices());
|
|
||||||
|
|
||||||
UsbStatusButton usbStatus = null;
|
UsbStatusButton usbStatus = null;
|
||||||
for(Node node : statusBar.getRightItems()) {
|
for(Node node : statusBar.getRightItems()) {
|
||||||
if(node instanceof UsbStatusButton) {
|
if(node instanceof UsbStatusButton) {
|
||||||
|
@ -1442,46 +1177,21 @@ public class AppController implements Initializable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
|
||||||
public void newConnection(ConnectionEvent event) {
|
|
||||||
currentBlockHeight = event.getBlockHeight();
|
|
||||||
targetBlockFeeRates = event.getTargetBlockFeeRates();
|
|
||||||
addMempoolRateSizes(event.getMempoolRateSizes());
|
|
||||||
minimumRelayFeeRate = event.getMinimumRelayFeeRate();
|
|
||||||
String banner = event.getServerBanner();
|
|
||||||
String status = "Connected to " + Config.get().getElectrumServer() + " at height " + event.getBlockHeight();
|
|
||||||
EventManager.get().post(new StatusEvent(status));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Subscribe
|
|
||||||
public void connectionFailed(ConnectionFailedEvent event) {
|
|
||||||
String reason = event.getException().getCause() != null ? event.getException().getCause().getMessage() : event.getException().getMessage();
|
|
||||||
String status = "Connection error: " + reason;
|
|
||||||
EventManager.get().post(new StatusEvent(status));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void newBlock(NewBlockEvent event) {
|
public void newBlock(NewBlockEvent event) {
|
||||||
currentBlockHeight = event.getHeight();
|
setServerToggleTooltip(event.getHeight());
|
||||||
setServerToggleTooltip();
|
|
||||||
String status = "Updating to new block height " + event.getHeight();
|
|
||||||
EventManager.get().post(new StatusEvent(status));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Subscribe
|
|
||||||
public void feesUpdated(FeeRatesUpdatedEvent event) {
|
|
||||||
targetBlockFeeRates = event.getTargetBlockFeeRates();
|
|
||||||
addMempoolRateSizes(event.getMempoolRateSizes());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void viewTransaction(ViewTransactionEvent event) {
|
public void viewTransaction(ViewTransactionEvent event) {
|
||||||
|
//TODO: Handle multiple windows
|
||||||
Tab tab = addTransactionTab(event.getBlockTransaction(), event.getInitialView(), event.getInitialIndex());
|
Tab tab = addTransactionTab(event.getBlockTransaction(), event.getInitialView(), event.getInitialIndex());
|
||||||
tabs.getSelectionModel().select(tab);
|
tabs.getSelectionModel().select(tab);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void viewPSBT(ViewPSBTEvent event) {
|
public void viewPSBT(ViewPSBTEvent event) {
|
||||||
|
//TODO: Handle multiple windows
|
||||||
Tab tab = addTransactionTab(event.getLabel(), event.getPsbt());
|
Tab tab = addTransactionTab(event.getLabel(), event.getPsbt());
|
||||||
tabs.getSelectionModel().select(tab);
|
tabs.getSelectionModel().select(tab);
|
||||||
}
|
}
|
||||||
|
@ -1492,102 +1202,27 @@ public class AppController implements Initializable {
|
||||||
selectedToggle.ifPresent(toggle -> bitcoinUnit.selectToggle(toggle));
|
selectedToggle.ifPresent(toggle -> bitcoinUnit.selectToggle(toggle));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
|
||||||
public void feeRateSourceChanged(FeeRatesSourceChangedEvent event) {
|
|
||||||
ElectrumServer.FeeRatesService feeRatesService = new ElectrumServer.FeeRatesService();
|
|
||||||
feeRatesService.setOnSucceeded(workerStateEvent -> {
|
|
||||||
EventManager.get().post(feeRatesService.getValue());
|
|
||||||
});
|
|
||||||
feeRatesService.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Subscribe
|
|
||||||
public void fiatCurrencySelected(FiatCurrencySelectedEvent event) {
|
|
||||||
ratesService.cancel();
|
|
||||||
|
|
||||||
if (Config.get().getMode() != Mode.OFFLINE && event.getExchangeSource() != ExchangeSource.NONE) {
|
|
||||||
ratesService = createRatesService(event.getExchangeSource(), event.getCurrency());
|
|
||||||
ratesService.start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Subscribe
|
|
||||||
public void exchangeRatesUpdated(ExchangeRatesUpdatedEvent event) {
|
|
||||||
fiatCurrencyExchangeRate = event.getCurrencyRate();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Subscribe
|
|
||||||
public void versionCheckStatus(VersionCheckStatusEvent event) {
|
|
||||||
versionCheckService.cancel();
|
|
||||||
|
|
||||||
if(Config.get().getMode() != Mode.OFFLINE && event.isEnabled()) {
|
|
||||||
versionCheckService = createVersionCheckService();
|
|
||||||
versionCheckService.start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Subscribe
|
|
||||||
public void openWallets(OpenWalletsEvent event) {
|
|
||||||
List<File> walletFiles = event.getWalletsMap().values().stream().map(Storage::getWalletFile).collect(Collectors.toList());
|
|
||||||
Config.get().setRecentWalletFiles(walletFiles);
|
|
||||||
|
|
||||||
boolean usbWallet = false;
|
|
||||||
for(Map.Entry<Wallet, Storage> entry : event.getWalletsMap().entrySet()) {
|
|
||||||
Wallet wallet = entry.getKey();
|
|
||||||
Storage storage = entry.getValue();
|
|
||||||
|
|
||||||
if(!storage.getWalletFile().exists() || wallet.containsSource(KeystoreSource.HW_USB)) {
|
|
||||||
usbWallet = true;
|
|
||||||
|
|
||||||
if(deviceEnumerateService == null) {
|
|
||||||
deviceEnumerateService = createDeviceEnumerateService();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(deviceEnumerateService.getState() == Worker.State.CANCELLED) {
|
|
||||||
deviceEnumerateService.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!deviceEnumerateService.isRunning()) {
|
|
||||||
deviceEnumerateService.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!usbWallet && deviceEnumerateService != null && deviceEnumerateService.isRunning()) {
|
|
||||||
deviceEnumerateService.cancel();
|
|
||||||
EventManager.get().post(new UsbDeviceEvent(Collections.emptyList()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void requestOpenWallets(RequestOpenWalletsEvent event) {
|
public void requestOpenWallets(RequestOpenWalletsEvent event) {
|
||||||
|
//TODO: Handle multiple windows
|
||||||
EventManager.get().post(new OpenWalletsEvent(getOpenWallets()));
|
EventManager.get().post(new OpenWalletsEvent(getOpenWallets()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void requestWalletOpen(RequestWalletOpenEvent event) {
|
public void requestWalletOpen(RequestWalletOpenEvent event) {
|
||||||
|
//TODO: Handle multiple windows
|
||||||
openWallet(null);
|
openWallet(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void requestTransactionOpen(RequestTransactionOpenEvent event) {
|
public void requestTransactionOpen(RequestTransactionOpenEvent event) {
|
||||||
|
//TODO: Handle multiple windows
|
||||||
openTransactionFromFile(null);
|
openTransactionFromFile(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void requestQRScan(RequestQRScanEvent event) {
|
public void requestQRScan(RequestQRScanEvent event) {
|
||||||
|
//TODO: Handle multiple windows
|
||||||
openTransactionFromQR(null);
|
openTransactionFromQR(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
|
||||||
public void requestConnect(RequestConnectEvent event) {
|
|
||||||
connect();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Subscribe
|
|
||||||
public void requestDisconnect(RequestDisconnectEvent event) {
|
|
||||||
disconnect();
|
|
||||||
}
|
|
||||||
}
|
}
|
423
src/main/java/com/sparrowwallet/sparrow/AppServices.java
Normal file
423
src/main/java/com/sparrowwallet/sparrow/AppServices.java
Normal file
|
@ -0,0 +1,423 @@
|
||||||
|
package com.sparrowwallet.sparrow;
|
||||||
|
|
||||||
|
import com.google.common.eventbus.Subscribe;
|
||||||
|
import com.sparrowwallet.drongo.address.Address;
|
||||||
|
import com.sparrowwallet.drongo.protocol.Transaction;
|
||||||
|
import com.sparrowwallet.drongo.uri.BitcoinURI;
|
||||||
|
import com.sparrowwallet.drongo.wallet.KeystoreSource;
|
||||||
|
import com.sparrowwallet.drongo.wallet.Wallet;
|
||||||
|
import com.sparrowwallet.sparrow.event.*;
|
||||||
|
import com.sparrowwallet.sparrow.io.Config;
|
||||||
|
import com.sparrowwallet.sparrow.io.Device;
|
||||||
|
import com.sparrowwallet.sparrow.io.Hwi;
|
||||||
|
import com.sparrowwallet.sparrow.io.Storage;
|
||||||
|
import com.sparrowwallet.sparrow.net.ElectrumServer;
|
||||||
|
import com.sparrowwallet.sparrow.net.ExchangeSource;
|
||||||
|
import com.sparrowwallet.sparrow.net.MempoolRateSize;
|
||||||
|
import com.sparrowwallet.sparrow.net.VersionCheckService;
|
||||||
|
import javafx.application.Platform;
|
||||||
|
import javafx.beans.property.BooleanProperty;
|
||||||
|
import javafx.beans.property.SimpleBooleanProperty;
|
||||||
|
import javafx.beans.value.ChangeListener;
|
||||||
|
import javafx.beans.value.ObservableValue;
|
||||||
|
import javafx.concurrent.ScheduledService;
|
||||||
|
import javafx.concurrent.Worker;
|
||||||
|
import javafx.scene.control.Alert;
|
||||||
|
import javafx.scene.image.Image;
|
||||||
|
import javafx.scene.text.Font;
|
||||||
|
import javafx.stage.Stage;
|
||||||
|
import javafx.stage.Window;
|
||||||
|
import javafx.util.Duration;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.ZoneId;
|
||||||
|
import java.time.temporal.ChronoUnit;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class AppServices {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(AppServices.class);
|
||||||
|
|
||||||
|
private static final int SERVER_PING_PERIOD = 1 * 60 * 1000;
|
||||||
|
private static final int ENUMERATE_HW_PERIOD = 30 * 1000;
|
||||||
|
private static final int RATES_PERIOD = 5 * 60 * 1000;
|
||||||
|
private static final int VERSION_CHECK_PERIOD_HOURS = 24;
|
||||||
|
private static final ExchangeSource DEFAULT_EXCHANGE_SOURCE = ExchangeSource.COINGECKO;
|
||||||
|
private static final Currency DEFAULT_FIAT_CURRENCY = Currency.getInstance("USD");
|
||||||
|
|
||||||
|
private static AppServices INSTANCE;
|
||||||
|
|
||||||
|
private final MainApp application;
|
||||||
|
|
||||||
|
private static final BooleanProperty onlineProperty = new SimpleBooleanProperty(false);
|
||||||
|
|
||||||
|
private ExchangeSource.RatesService ratesService;
|
||||||
|
|
||||||
|
private final ElectrumServer.ConnectionService connectionService;
|
||||||
|
|
||||||
|
private Hwi.ScheduledEnumerateService deviceEnumerateService;
|
||||||
|
|
||||||
|
private VersionCheckService versionCheckService;
|
||||||
|
|
||||||
|
private static Integer currentBlockHeight;
|
||||||
|
|
||||||
|
private static Map<Integer, Double> targetBlockFeeRates;
|
||||||
|
|
||||||
|
private static final Map<Date, Set<MempoolRateSize>> mempoolHistogram = new TreeMap<>();
|
||||||
|
|
||||||
|
private static Double minimumRelayFeeRate;
|
||||||
|
|
||||||
|
private static CurrencyRate fiatCurrencyExchangeRate;
|
||||||
|
|
||||||
|
private static List<Device> devices;
|
||||||
|
|
||||||
|
private static final Map<Address, BitcoinURI> payjoinURIs = new HashMap<>();
|
||||||
|
|
||||||
|
private final ChangeListener<Boolean> onlineServicesListener = new ChangeListener<>() {
|
||||||
|
@Override
|
||||||
|
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean online) {
|
||||||
|
Config.get().setMode(online ? Mode.ONLINE : Mode.OFFLINE);
|
||||||
|
if(online) {
|
||||||
|
restartService(connectionService);
|
||||||
|
|
||||||
|
if(ratesService.getExchangeSource() != ExchangeSource.NONE) {
|
||||||
|
restartService(ratesService);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Config.get().isCheckNewVersions()) {
|
||||||
|
restartService(versionCheckService);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
connectionService.cancel();
|
||||||
|
ratesService.cancel();
|
||||||
|
versionCheckService.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private void restartService(ScheduledService<?> service) {
|
||||||
|
if(service.getState() == Worker.State.CANCELLED) {
|
||||||
|
service.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!service.isRunning()) {
|
||||||
|
service.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public AppServices(MainApp application) {
|
||||||
|
this.application = application;
|
||||||
|
|
||||||
|
EventManager.get().register(this);
|
||||||
|
|
||||||
|
Config config = Config.get();
|
||||||
|
connectionService = createConnectionService();
|
||||||
|
if(config.getMode() == Mode.ONLINE && config.getElectrumServer() != null && !config.getElectrumServer().isEmpty()) {
|
||||||
|
connectionService.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
ExchangeSource source = config.getExchangeSource() != null ? config.getExchangeSource() : DEFAULT_EXCHANGE_SOURCE;
|
||||||
|
Currency currency = config.getFiatCurrency() != null ? config.getFiatCurrency() : DEFAULT_FIAT_CURRENCY;
|
||||||
|
ratesService = createRatesService(source, currency);
|
||||||
|
if(config.getMode() == Mode.ONLINE && source != ExchangeSource.NONE) {
|
||||||
|
ratesService.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
versionCheckService = createVersionCheckService();
|
||||||
|
if(config.getMode() == Mode.ONLINE && config.isCheckNewVersions()) {
|
||||||
|
versionCheckService.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
onlineProperty.addListener(onlineServicesListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ElectrumServer.ConnectionService createConnectionService() {
|
||||||
|
ElectrumServer.ConnectionService connectionService = new ElectrumServer.ConnectionService();
|
||||||
|
connectionService.setPeriod(new Duration(SERVER_PING_PERIOD));
|
||||||
|
connectionService.setRestartOnFailure(true);
|
||||||
|
|
||||||
|
EventManager.get().register(connectionService);
|
||||||
|
connectionService.statusProperty().addListener((observable, oldValue, newValue) -> {
|
||||||
|
if(connectionService.isRunning()) {
|
||||||
|
EventManager.get().post(new StatusEvent(newValue));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
connectionService.setOnSucceeded(successEvent -> {
|
||||||
|
onlineProperty.removeListener(onlineServicesListener);
|
||||||
|
onlineProperty.setValue(true);
|
||||||
|
onlineProperty.addListener(onlineServicesListener);
|
||||||
|
|
||||||
|
if(connectionService.getValue() != null) {
|
||||||
|
EventManager.get().post(connectionService.getValue());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
connectionService.setOnFailed(failEvent -> {
|
||||||
|
//Close connection here to create a new transport next time we try
|
||||||
|
connectionService.resetConnection();
|
||||||
|
|
||||||
|
onlineProperty.removeListener(onlineServicesListener);
|
||||||
|
onlineProperty.setValue(false);
|
||||||
|
onlineProperty.addListener(onlineServicesListener);
|
||||||
|
|
||||||
|
log.debug("Connection failed", failEvent.getSource().getException());
|
||||||
|
EventManager.get().post(new ConnectionFailedEvent(failEvent.getSource().getException()));
|
||||||
|
});
|
||||||
|
|
||||||
|
return connectionService;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ExchangeSource.RatesService createRatesService(ExchangeSource exchangeSource, Currency currency) {
|
||||||
|
ExchangeSource.RatesService ratesService = new ExchangeSource.RatesService(exchangeSource, currency);
|
||||||
|
ratesService.setPeriod(new Duration(RATES_PERIOD));
|
||||||
|
ratesService.setRestartOnFailure(true);
|
||||||
|
|
||||||
|
ratesService.setOnSucceeded(successEvent -> {
|
||||||
|
EventManager.get().post(ratesService.getValue());
|
||||||
|
});
|
||||||
|
|
||||||
|
return ratesService;
|
||||||
|
}
|
||||||
|
|
||||||
|
private VersionCheckService createVersionCheckService() {
|
||||||
|
VersionCheckService versionCheckService = new VersionCheckService();
|
||||||
|
versionCheckService.setDelay(Duration.seconds(10));
|
||||||
|
versionCheckService.setPeriod(Duration.hours(VERSION_CHECK_PERIOD_HOURS));
|
||||||
|
versionCheckService.setRestartOnFailure(true);
|
||||||
|
|
||||||
|
versionCheckService.setOnSucceeded(successEvent -> {
|
||||||
|
VersionUpdatedEvent event = versionCheckService.getValue();
|
||||||
|
if(event != null) {
|
||||||
|
EventManager.get().post(event);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return versionCheckService;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Hwi.ScheduledEnumerateService createDeviceEnumerateService() {
|
||||||
|
Hwi.ScheduledEnumerateService enumerateService = new Hwi.ScheduledEnumerateService(null);
|
||||||
|
enumerateService.setPeriod(new Duration(ENUMERATE_HW_PERIOD));
|
||||||
|
enumerateService.setOnSucceeded(workerStateEvent -> {
|
||||||
|
List<Device> devices = enumerateService.getValue();
|
||||||
|
|
||||||
|
//Null devices are returned if the app is currently prompting for a pin. Otherwise, the enumerate clears the pin screen
|
||||||
|
if(devices != null) {
|
||||||
|
//If another instance of HWI is currently accessing the usb interface, HWI returns empty device models. Ignore this run if that happens
|
||||||
|
List<Device> validDevices = devices.stream().filter(device -> device.getModel() != null).collect(Collectors.toList());
|
||||||
|
if(validDevices.size() == devices.size()) {
|
||||||
|
Platform.runLater(() -> EventManager.get().post(new UsbDeviceEvent(devices)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return enumerateService;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void initialize(MainApp application) {
|
||||||
|
INSTANCE = new AppServices(application);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AppServices get() {
|
||||||
|
return INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MainApp getApplication() {
|
||||||
|
return application;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isOnline() {
|
||||||
|
return onlineProperty.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BooleanProperty onlineProperty() {
|
||||||
|
return onlineProperty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Integer getCurrentBlockHeight() {
|
||||||
|
return currentBlockHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map<Integer, Double> getTargetBlockFeeRates() {
|
||||||
|
return targetBlockFeeRates;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map<Date, Set<MempoolRateSize>> getMempoolHistogram() {
|
||||||
|
return mempoolHistogram;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addMempoolRateSizes(Set<MempoolRateSize> rateSizes) {
|
||||||
|
LocalDateTime dateMinute = LocalDateTime.now().truncatedTo(ChronoUnit.MINUTES);
|
||||||
|
if(mempoolHistogram.isEmpty()) {
|
||||||
|
mempoolHistogram.put(Date.from(dateMinute.minusMinutes(1).atZone(ZoneId.systemDefault()).toInstant()), rateSizes);
|
||||||
|
}
|
||||||
|
|
||||||
|
mempoolHistogram.put(Date.from(dateMinute.atZone(ZoneId.systemDefault()).toInstant()), rateSizes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Double getMinimumRelayFeeRate() {
|
||||||
|
return minimumRelayFeeRate == null ? Transaction.DEFAULT_MIN_RELAY_FEE : minimumRelayFeeRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CurrencyRate getFiatCurrencyExchangeRate() {
|
||||||
|
return fiatCurrencyExchangeRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<Device> getDevices() {
|
||||||
|
return devices == null ? new ArrayList<>() : devices;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BitcoinURI getPayjoinURI(Address address) {
|
||||||
|
return payjoinURIs.get(address);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void addPayjoinURI(BitcoinURI bitcoinURI) {
|
||||||
|
if(bitcoinURI.getPayjoinUrl() == null) {
|
||||||
|
throw new IllegalArgumentException("Not a payjoin URI");
|
||||||
|
}
|
||||||
|
payjoinURIs.put(bitcoinURI.getAddress(), bitcoinURI);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void showErrorDialog(String title, String content) {
|
||||||
|
Alert alert = new Alert(Alert.AlertType.ERROR);
|
||||||
|
setStageIcon(alert.getDialogPane().getScene().getWindow());
|
||||||
|
alert.getDialogPane().getScene().getStylesheets().add(AppServices.class.getResource("general.css").toExternalForm());
|
||||||
|
alert.setTitle(title);
|
||||||
|
alert.setHeaderText(title);
|
||||||
|
alert.setContentText(content);
|
||||||
|
alert.showAndWait();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setStageIcon(Window window) {
|
||||||
|
Stage stage = (Stage)window;
|
||||||
|
stage.getIcons().add(new Image(AppServices.class.getResourceAsStream("/image/sparrow.png")));
|
||||||
|
|
||||||
|
if(stage.getScene() != null && Config.get().getTheme() == Theme.DARK) {
|
||||||
|
stage.getScene().getStylesheets().add(AppServices.class.getResource("darktheme.css").toExternalForm());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Font getMonospaceFont() {
|
||||||
|
return Font.font("Roboto Mono", 13);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void newConnection(ConnectionEvent event) {
|
||||||
|
currentBlockHeight = event.getBlockHeight();
|
||||||
|
targetBlockFeeRates = event.getTargetBlockFeeRates();
|
||||||
|
addMempoolRateSizes(event.getMempoolRateSizes());
|
||||||
|
minimumRelayFeeRate = event.getMinimumRelayFeeRate();
|
||||||
|
String banner = event.getServerBanner();
|
||||||
|
String status = "Connected to " + Config.get().getElectrumServer() + " at height " + event.getBlockHeight();
|
||||||
|
EventManager.get().post(new StatusEvent(status));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void connectionFailed(ConnectionFailedEvent event) {
|
||||||
|
String reason = event.getException().getCause() != null ? event.getException().getCause().getMessage() : event.getException().getMessage();
|
||||||
|
String status = "Connection error: " + reason;
|
||||||
|
EventManager.get().post(new StatusEvent(status));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void usbDevicesFound(UsbDeviceEvent event) {
|
||||||
|
devices = Collections.unmodifiableList(event.getDevices());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void newBlock(NewBlockEvent event) {
|
||||||
|
currentBlockHeight = event.getHeight();
|
||||||
|
String status = "Updating to new block height " + event.getHeight();
|
||||||
|
EventManager.get().post(new StatusEvent(status));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void feesUpdated(FeeRatesUpdatedEvent event) {
|
||||||
|
targetBlockFeeRates = event.getTargetBlockFeeRates();
|
||||||
|
addMempoolRateSizes(event.getMempoolRateSizes());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void feeRateSourceChanged(FeeRatesSourceChangedEvent event) {
|
||||||
|
ElectrumServer.FeeRatesService feeRatesService = new ElectrumServer.FeeRatesService();
|
||||||
|
feeRatesService.setOnSucceeded(workerStateEvent -> {
|
||||||
|
EventManager.get().post(feeRatesService.getValue());
|
||||||
|
});
|
||||||
|
//Perform once-off fee rates retrieval to immediately change displayed rates
|
||||||
|
feeRatesService.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void fiatCurrencySelected(FiatCurrencySelectedEvent event) {
|
||||||
|
ratesService.cancel();
|
||||||
|
|
||||||
|
if(Config.get().getMode() != Mode.OFFLINE && event.getExchangeSource() != ExchangeSource.NONE) {
|
||||||
|
ratesService = createRatesService(event.getExchangeSource(), event.getCurrency());
|
||||||
|
ratesService.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void exchangeRatesUpdated(ExchangeRatesUpdatedEvent event) {
|
||||||
|
fiatCurrencyExchangeRate = event.getCurrencyRate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void versionCheckStatus(VersionCheckStatusEvent event) {
|
||||||
|
versionCheckService.cancel();
|
||||||
|
|
||||||
|
if(Config.get().getMode() != Mode.OFFLINE && event.isEnabled()) {
|
||||||
|
versionCheckService = createVersionCheckService();
|
||||||
|
versionCheckService.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void openWallets(OpenWalletsEvent event) {
|
||||||
|
List<File> walletFiles = event.getWalletsMap().values().stream().map(Storage::getWalletFile).collect(Collectors.toList());
|
||||||
|
//TODO: Handle multiple windows
|
||||||
|
Config.get().setRecentWalletFiles(walletFiles);
|
||||||
|
|
||||||
|
boolean usbWallet = false;
|
||||||
|
for(Map.Entry<Wallet, Storage> entry : event.getWalletsMap().entrySet()) {
|
||||||
|
Wallet wallet = entry.getKey();
|
||||||
|
Storage storage = entry.getValue();
|
||||||
|
|
||||||
|
if(!storage.getWalletFile().exists() || wallet.containsSource(KeystoreSource.HW_USB)) {
|
||||||
|
usbWallet = true;
|
||||||
|
|
||||||
|
if(deviceEnumerateService == null) {
|
||||||
|
deviceEnumerateService = createDeviceEnumerateService();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(deviceEnumerateService.getState() == Worker.State.CANCELLED) {
|
||||||
|
deviceEnumerateService.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!deviceEnumerateService.isRunning()) {
|
||||||
|
deviceEnumerateService.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!usbWallet && deviceEnumerateService != null && deviceEnumerateService.isRunning()) {
|
||||||
|
deviceEnumerateService.cancel();
|
||||||
|
EventManager.get().post(new UsbDeviceEvent(Collections.emptyList()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void requestConnect(RequestConnectEvent event) {
|
||||||
|
onlineProperty.set(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void requestDisconnect(RequestDisconnectEvent event) {
|
||||||
|
onlineProperty.set(false);
|
||||||
|
}
|
||||||
|
}
|
|
@ -49,7 +49,7 @@ public class MainApp extends Application {
|
||||||
|
|
||||||
GlyphFontRegistry.register(new FontAwesome5());
|
GlyphFontRegistry.register(new FontAwesome5());
|
||||||
GlyphFontRegistry.register(new FontAwesome5Brands());
|
GlyphFontRegistry.register(new FontAwesome5Brands());
|
||||||
Font.loadFont(AppController.class.getResourceAsStream("/font/RobotoMono-Regular.ttf"), 13);
|
Font.loadFont(AppServices.class.getResourceAsStream("/font/RobotoMono-Regular.ttf"), 13);
|
||||||
|
|
||||||
boolean createNewWallet = false;
|
boolean createNewWallet = false;
|
||||||
Mode mode = Config.get().getMode();
|
Mode mode = Config.get().getMode();
|
||||||
|
@ -68,10 +68,11 @@ public class MainApp extends Application {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AppServices.initialize(this);
|
||||||
|
|
||||||
FXMLLoader transactionLoader = new FXMLLoader(getClass().getResource("app.fxml"));
|
FXMLLoader transactionLoader = new FXMLLoader(getClass().getResource("app.fxml"));
|
||||||
Parent root = transactionLoader.load();
|
Parent root = transactionLoader.load();
|
||||||
AppController appController = transactionLoader.getController();
|
AppController appController = transactionLoader.getController();
|
||||||
appController.setApplication(this);
|
|
||||||
|
|
||||||
Scene scene = new Scene(root);
|
Scene scene = new Scene(root);
|
||||||
scene.getStylesheets().add(getClass().getResource("app.css").toExternalForm());
|
scene.getStylesheets().add(getClass().getResource("app.css").toExternalForm());
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package com.sparrowwallet.sparrow.control;
|
package com.sparrowwallet.sparrow.control;
|
||||||
|
|
||||||
import com.sparrowwallet.drongo.wallet.WalletNode;
|
import com.sparrowwallet.drongo.wallet.WalletNode;
|
||||||
import com.sparrowwallet.sparrow.AppController;
|
import com.sparrowwallet.sparrow.AppServices;
|
||||||
import com.sparrowwallet.sparrow.EventManager;
|
import com.sparrowwallet.sparrow.EventManager;
|
||||||
import com.sparrowwallet.sparrow.event.ReceiveActionEvent;
|
import com.sparrowwallet.sparrow.event.ReceiveActionEvent;
|
||||||
import com.sparrowwallet.sparrow.event.ReceiveToEvent;
|
import com.sparrowwallet.sparrow.event.ReceiveToEvent;
|
||||||
|
@ -33,7 +33,7 @@ public class AddressTreeTable extends CoinTreeTable {
|
||||||
getColumns().add(addressCol);
|
getColumns().add(addressCol);
|
||||||
|
|
||||||
if(address != null) {
|
if(address != null) {
|
||||||
addressCol.setMinWidth(TextUtils.computeTextWidth(AppController.getMonospaceFont(), address, 0.0));
|
addressCol.setMinWidth(TextUtils.computeTextWidth(AppServices.getMonospaceFont(), address, 0.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
TreeTableColumn<Entry, String> labelCol = new TreeTableColumn<>("Label");
|
TreeTableColumn<Entry, String> labelCol = new TreeTableColumn<>("Label");
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package com.sparrowwallet.sparrow.control;
|
package com.sparrowwallet.sparrow.control;
|
||||||
|
|
||||||
import com.sparrowwallet.sparrow.AppController;
|
import com.sparrowwallet.sparrow.AppServices;
|
||||||
import com.sparrowwallet.sparrow.EventManager;
|
import com.sparrowwallet.sparrow.EventManager;
|
||||||
import com.sparrowwallet.sparrow.event.UsbDeviceEvent;
|
import com.sparrowwallet.sparrow.event.UsbDeviceEvent;
|
||||||
import com.sparrowwallet.sparrow.glyphfont.FontAwesome5Brands;
|
import com.sparrowwallet.sparrow.glyphfont.FontAwesome5Brands;
|
||||||
|
@ -33,8 +33,8 @@ public abstract class DeviceDialog<R> extends Dialog<R> {
|
||||||
this.operationFingerprints = operationFingerprints;
|
this.operationFingerprints = operationFingerprints;
|
||||||
|
|
||||||
final DialogPane dialogPane = getDialogPane();
|
final DialogPane dialogPane = getDialogPane();
|
||||||
dialogPane.getStylesheets().add(AppController.class.getResource("general.css").toExternalForm());
|
dialogPane.getStylesheets().add(AppServices.class.getResource("general.css").toExternalForm());
|
||||||
AppController.setStageIcon(dialogPane.getScene().getWindow());
|
AppServices.setStageIcon(dialogPane.getScene().getWindow());
|
||||||
|
|
||||||
StackPane stackPane = new StackPane();
|
StackPane stackPane = new StackPane();
|
||||||
dialogPane.setContent(stackPane);
|
dialogPane.setContent(stackPane);
|
||||||
|
@ -67,7 +67,7 @@ public abstract class DeviceDialog<R> extends Dialog<R> {
|
||||||
|
|
||||||
stackPane.getChildren().addAll(anchorPane, scanBox);
|
stackPane.getChildren().addAll(anchorPane, scanBox);
|
||||||
|
|
||||||
List<Device> devices = AppController.getDevices();
|
List<Device> devices = AppServices.getDevices();
|
||||||
if(devices == null || devices.isEmpty()) {
|
if(devices == null || devices.isEmpty()) {
|
||||||
scanBox.setVisible(true);
|
scanBox.setVisible(true);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -5,7 +5,7 @@ import com.sparrowwallet.drongo.address.Address;
|
||||||
import com.sparrowwallet.drongo.protocol.Transaction;
|
import com.sparrowwallet.drongo.protocol.Transaction;
|
||||||
import com.sparrowwallet.drongo.protocol.TransactionOutput;
|
import com.sparrowwallet.drongo.protocol.TransactionOutput;
|
||||||
import com.sparrowwallet.drongo.wallet.*;
|
import com.sparrowwallet.drongo.wallet.*;
|
||||||
import com.sparrowwallet.sparrow.AppController;
|
import com.sparrowwallet.sparrow.AppServices;
|
||||||
import com.sparrowwallet.sparrow.EventManager;
|
import com.sparrowwallet.sparrow.EventManager;
|
||||||
import com.sparrowwallet.sparrow.event.*;
|
import com.sparrowwallet.sparrow.event.*;
|
||||||
import com.sparrowwallet.sparrow.glyphfont.FontAwesome5;
|
import com.sparrowwallet.sparrow.glyphfont.FontAwesome5;
|
||||||
|
@ -202,11 +202,11 @@ class EntryCell extends TreeTableCell<Entry, Entry> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Double getMaxFeeRate() {
|
private static Double getMaxFeeRate() {
|
||||||
if(AppController.getTargetBlockFeeRates().isEmpty()) {
|
if(AppServices.getTargetBlockFeeRates().isEmpty()) {
|
||||||
return 100.0;
|
return 100.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return AppController.getTargetBlockFeeRates().values().iterator().next();
|
return AppServices.getTargetBlockFeeRates().values().iterator().next();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void sendSelectedUtxos(TreeTableView<Entry> treeTableView, HashIndexEntry hashIndexEntry) {
|
private static void sendSelectedUtxos(TreeTableView<Entry> treeTableView, HashIndexEntry hashIndexEntry) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package com.sparrowwallet.sparrow.control;
|
package com.sparrowwallet.sparrow.control;
|
||||||
|
|
||||||
import com.sparrowwallet.sparrow.AppController;
|
import com.sparrowwallet.sparrow.AppServices;
|
||||||
|
|
||||||
public class IdLabel extends CopyableLabel {
|
public class IdLabel extends CopyableLabel {
|
||||||
public IdLabel() {
|
public IdLabel() {
|
||||||
|
@ -9,6 +9,6 @@ public class IdLabel extends CopyableLabel {
|
||||||
|
|
||||||
public IdLabel(String text) {
|
public IdLabel(String text) {
|
||||||
super(text);
|
super(text);
|
||||||
setFont(AppController.getMonospaceFont());
|
setFont(AppServices.getMonospaceFont());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package com.sparrowwallet.sparrow.control;
|
package com.sparrowwallet.sparrow.control;
|
||||||
|
|
||||||
import com.sparrowwallet.drongo.wallet.Keystore;
|
import com.sparrowwallet.drongo.wallet.Keystore;
|
||||||
import com.sparrowwallet.sparrow.AppController;
|
import com.sparrowwallet.sparrow.AppServices;
|
||||||
import com.sparrowwallet.sparrow.glyphfont.FontAwesome5;
|
import com.sparrowwallet.sparrow.glyphfont.FontAwesome5;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.scene.control.ButtonType;
|
import javafx.scene.control.ButtonType;
|
||||||
|
@ -25,8 +25,8 @@ public class KeystorePassphraseDialog extends Dialog<String> {
|
||||||
final DialogPane dialogPane = getDialogPane();
|
final DialogPane dialogPane = getDialogPane();
|
||||||
setTitle("Keystore Passphrase" + (walletName != null ? " - " + walletName : ""));
|
setTitle("Keystore Passphrase" + (walletName != null ? " - " + walletName : ""));
|
||||||
dialogPane.setHeaderText("Please enter the passphrase for keystore: \n" + keystore.getLabel());
|
dialogPane.setHeaderText("Please enter the passphrase for keystore: \n" + keystore.getLabel());
|
||||||
dialogPane.getStylesheets().add(AppController.class.getResource("general.css").toExternalForm());
|
dialogPane.getStylesheets().add(AppServices.class.getResource("general.css").toExternalForm());
|
||||||
AppController.setStageIcon(dialogPane.getScene().getWindow());
|
AppServices.setStageIcon(dialogPane.getScene().getWindow());
|
||||||
dialogPane.getButtonTypes().addAll(ButtonType.CANCEL, ButtonType.OK);
|
dialogPane.getButtonTypes().addAll(ButtonType.CANCEL, ButtonType.OK);
|
||||||
dialogPane.setPrefWidth(380);
|
dialogPane.setPrefWidth(380);
|
||||||
dialogPane.setPrefHeight(200);
|
dialogPane.setPrefHeight(200);
|
||||||
|
|
|
@ -12,7 +12,7 @@ import com.sparrowwallet.drongo.wallet.Keystore;
|
||||||
import com.sparrowwallet.drongo.wallet.KeystoreSource;
|
import com.sparrowwallet.drongo.wallet.KeystoreSource;
|
||||||
import com.sparrowwallet.drongo.wallet.Wallet;
|
import com.sparrowwallet.drongo.wallet.Wallet;
|
||||||
import com.sparrowwallet.drongo.wallet.WalletNode;
|
import com.sparrowwallet.drongo.wallet.WalletNode;
|
||||||
import com.sparrowwallet.sparrow.AppController;
|
import com.sparrowwallet.sparrow.AppServices;
|
||||||
import com.sparrowwallet.sparrow.EventManager;
|
import com.sparrowwallet.sparrow.EventManager;
|
||||||
import com.sparrowwallet.sparrow.event.OpenWalletsEvent;
|
import com.sparrowwallet.sparrow.event.OpenWalletsEvent;
|
||||||
import com.sparrowwallet.sparrow.event.RequestOpenWalletsEvent;
|
import com.sparrowwallet.sparrow.event.RequestOpenWalletsEvent;
|
||||||
|
@ -37,8 +37,6 @@ import java.security.SignatureException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
import static com.sparrowwallet.sparrow.AppController.setStageIcon;
|
|
||||||
|
|
||||||
public class MessageSignDialog extends Dialog<ButtonBar.ButtonData> {
|
public class MessageSignDialog extends Dialog<ButtonBar.ButtonData> {
|
||||||
private static final Logger log = LoggerFactory.getLogger(MessageSignDialog.class);
|
private static final Logger log = LoggerFactory.getLogger(MessageSignDialog.class);
|
||||||
|
|
||||||
|
@ -84,8 +82,8 @@ public class MessageSignDialog extends Dialog<ButtonBar.ButtonData> {
|
||||||
this.walletNode = walletNode;
|
this.walletNode = walletNode;
|
||||||
|
|
||||||
final DialogPane dialogPane = getDialogPane();
|
final DialogPane dialogPane = getDialogPane();
|
||||||
dialogPane.getStylesheets().add(AppController.class.getResource("general.css").toExternalForm());
|
dialogPane.getStylesheets().add(AppServices.class.getResource("general.css").toExternalForm());
|
||||||
AppController.setStageIcon(dialogPane.getScene().getWindow());
|
AppServices.setStageIcon(dialogPane.getScene().getWindow());
|
||||||
dialogPane.setHeaderText(wallet == null ? "Verify Message" : "Sign/Verify Message");
|
dialogPane.setHeaderText(wallet == null ? "Verify Message" : "Sign/Verify Message");
|
||||||
|
|
||||||
Image image = new Image("image/seed.png", 50, 50, false, false);
|
Image image = new Image("image/seed.png", 50, 50, false, false);
|
||||||
|
@ -209,7 +207,7 @@ public class MessageSignDialog extends Dialog<ButtonBar.ButtonData> {
|
||||||
|
|
||||||
private void signMessage() {
|
private void signMessage() {
|
||||||
if(walletNode == null) {
|
if(walletNode == null) {
|
||||||
AppController.showErrorDialog("Address not in wallet", "The provided address is not present in the currently selected wallet.");
|
AppServices.showErrorDialog("Address not in wallet", "The provided address is not present in the currently selected wallet.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,7 +232,7 @@ public class MessageSignDialog extends Dialog<ButtonBar.ButtonData> {
|
||||||
signature.appendText(signatureText);
|
signature.appendText(signatureText);
|
||||||
} catch(Exception e) {
|
} catch(Exception e) {
|
||||||
log.error("Could not sign message", e);
|
log.error("Could not sign message", e);
|
||||||
AppController.showErrorDialog("Could not sign message", e.getMessage());
|
AppServices.showErrorDialog("Could not sign message", e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,19 +270,19 @@ public class MessageSignDialog extends Dialog<ButtonBar.ButtonData> {
|
||||||
|
|
||||||
if(verified) {
|
if(verified) {
|
||||||
Alert alert = new Alert(Alert.AlertType.INFORMATION);
|
Alert alert = new Alert(Alert.AlertType.INFORMATION);
|
||||||
setStageIcon(alert.getDialogPane().getScene().getWindow());
|
AppServices.setStageIcon(alert.getDialogPane().getScene().getWindow());
|
||||||
alert.setTitle("Verification Succeeded");
|
alert.setTitle("Verification Succeeded");
|
||||||
alert.setHeaderText("Verification Succeeded");
|
alert.setHeaderText("Verification Succeeded");
|
||||||
alert.setContentText("The signature verified against the message.");
|
alert.setContentText("The signature verified against the message.");
|
||||||
alert.showAndWait();
|
alert.showAndWait();
|
||||||
} else {
|
} else {
|
||||||
AppController.showErrorDialog("Verification failed", "The provided signature did not match the message for this address.");
|
AppServices.showErrorDialog("Verification failed", "The provided signature did not match the message for this address.");
|
||||||
}
|
}
|
||||||
} catch(IllegalArgumentException e) {
|
} catch(IllegalArgumentException e) {
|
||||||
AppController.showErrorDialog("Could not verify message", e.getMessage());
|
AppServices.showErrorDialog("Could not verify message", e.getMessage());
|
||||||
} catch(Exception e) {
|
} catch(Exception e) {
|
||||||
log.error("Could not verify message", e);
|
log.error("Could not verify message", e);
|
||||||
AppController.showErrorDialog("Could not verify message", e.getMessage());
|
AppServices.showErrorDialog("Could not verify message", e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -320,7 +318,7 @@ public class MessageSignDialog extends Dialog<ButtonBar.ButtonData> {
|
||||||
});
|
});
|
||||||
decryptWalletService.setOnFailed(workerStateEvent -> {
|
decryptWalletService.setOnFailed(workerStateEvent -> {
|
||||||
EventManager.get().post(new StorageEvent(storage.getWalletFile(), TimedEvent.Action.END, "Failed"));
|
EventManager.get().post(new StorageEvent(storage.getWalletFile(), TimedEvent.Action.END, "Failed"));
|
||||||
AppController.showErrorDialog("Incorrect Password", decryptWalletService.getException().getMessage());
|
AppServices.showErrorDialog("Incorrect Password", decryptWalletService.getException().getMessage());
|
||||||
});
|
});
|
||||||
EventManager.get().post(new StorageEvent(storage.getWalletFile(), TimedEvent.Action.START, "Decrypting wallet..."));
|
EventManager.get().post(new StorageEvent(storage.getWalletFile(), TimedEvent.Action.START, "Decrypting wallet..."));
|
||||||
decryptWalletService.start();
|
decryptWalletService.start();
|
||||||
|
|
|
@ -7,7 +7,7 @@ import com.google.zxing.common.BitMatrix;
|
||||||
import com.google.zxing.qrcode.QRCodeWriter;
|
import com.google.zxing.qrcode.QRCodeWriter;
|
||||||
import com.sparrowwallet.hummingbird.LegacyUREncoder;
|
import com.sparrowwallet.hummingbird.LegacyUREncoder;
|
||||||
import com.sparrowwallet.hummingbird.registry.RegistryType;
|
import com.sparrowwallet.hummingbird.registry.RegistryType;
|
||||||
import com.sparrowwallet.sparrow.AppController;
|
import com.sparrowwallet.sparrow.AppServices;
|
||||||
import com.sparrowwallet.sparrow.glyphfont.FontAwesome5;
|
import com.sparrowwallet.sparrow.glyphfont.FontAwesome5;
|
||||||
import com.sparrowwallet.sparrow.io.ImportException;
|
import com.sparrowwallet.sparrow.io.ImportException;
|
||||||
import com.sparrowwallet.hummingbird.UR;
|
import com.sparrowwallet.hummingbird.UR;
|
||||||
|
@ -63,7 +63,7 @@ public class QRDisplayDialog extends Dialog<UR> {
|
||||||
|
|
||||||
final DialogPane dialogPane = new QRDisplayDialogPane();
|
final DialogPane dialogPane = new QRDisplayDialogPane();
|
||||||
setDialogPane(dialogPane);
|
setDialogPane(dialogPane);
|
||||||
AppController.setStageIcon(dialogPane.getScene().getWindow());
|
AppServices.setStageIcon(dialogPane.getScene().getWindow());
|
||||||
|
|
||||||
StackPane stackPane = new StackPane();
|
StackPane stackPane = new StackPane();
|
||||||
qrImageView = new ImageView();
|
qrImageView = new ImageView();
|
||||||
|
@ -102,7 +102,7 @@ public class QRDisplayDialog extends Dialog<UR> {
|
||||||
this.encoder = null;
|
this.encoder = null;
|
||||||
|
|
||||||
final DialogPane dialogPane = getDialogPane();
|
final DialogPane dialogPane = getDialogPane();
|
||||||
AppController.setStageIcon(dialogPane.getScene().getWindow());
|
AppServices.setStageIcon(dialogPane.getScene().getWindow());
|
||||||
|
|
||||||
StackPane stackPane = new StackPane();
|
StackPane stackPane = new StackPane();
|
||||||
qrImageView = new ImageView();
|
qrImageView = new ImageView();
|
||||||
|
|
|
@ -19,10 +19,10 @@ import com.sparrowwallet.drongo.wallet.Keystore;
|
||||||
import com.sparrowwallet.drongo.wallet.Wallet;
|
import com.sparrowwallet.drongo.wallet.Wallet;
|
||||||
import com.sparrowwallet.hummingbird.LegacyURDecoder;
|
import com.sparrowwallet.hummingbird.LegacyURDecoder;
|
||||||
import com.sparrowwallet.hummingbird.registry.*;
|
import com.sparrowwallet.hummingbird.registry.*;
|
||||||
import com.sparrowwallet.sparrow.AppController;
|
|
||||||
import com.sparrowwallet.hummingbird.ResultType;
|
import com.sparrowwallet.hummingbird.ResultType;
|
||||||
import com.sparrowwallet.hummingbird.UR;
|
import com.sparrowwallet.hummingbird.UR;
|
||||||
import com.sparrowwallet.hummingbird.URDecoder;
|
import com.sparrowwallet.hummingbird.URDecoder;
|
||||||
|
import com.sparrowwallet.sparrow.AppServices;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.beans.value.ChangeListener;
|
import javafx.beans.value.ChangeListener;
|
||||||
import javafx.beans.value.ObservableValue;
|
import javafx.beans.value.ObservableValue;
|
||||||
|
@ -66,7 +66,7 @@ public class QRScanDialog extends Dialog<QRScanDialog.Result> {
|
||||||
WebcamView webcamView = new WebcamView(webcamService);
|
WebcamView webcamView = new WebcamView(webcamService);
|
||||||
|
|
||||||
final DialogPane dialogPane = getDialogPane();
|
final DialogPane dialogPane = getDialogPane();
|
||||||
AppController.setStageIcon(dialogPane.getScene().getWindow());
|
AppServices.setStageIcon(dialogPane.getScene().getWindow());
|
||||||
|
|
||||||
StackPane stackPane = new StackPane();
|
StackPane stackPane = new StackPane();
|
||||||
stackPane.getChildren().add(webcamView.getView());
|
stackPane.getChildren().add(webcamView.getView());
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package com.sparrowwallet.sparrow.control;
|
package com.sparrowwallet.sparrow.control;
|
||||||
|
|
||||||
import com.sparrowwallet.drongo.wallet.Keystore;
|
import com.sparrowwallet.drongo.wallet.Keystore;
|
||||||
import com.sparrowwallet.sparrow.AppController;
|
import com.sparrowwallet.sparrow.AppServices;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.scene.control.*;
|
import javafx.scene.control.*;
|
||||||
import javafx.scene.layout.AnchorPane;
|
import javafx.scene.layout.AnchorPane;
|
||||||
|
@ -10,8 +10,8 @@ import javafx.scene.layout.StackPane;
|
||||||
public class SeedDisplayDialog extends Dialog<Void> {
|
public class SeedDisplayDialog extends Dialog<Void> {
|
||||||
public SeedDisplayDialog(Keystore decryptedKeystore) {
|
public SeedDisplayDialog(Keystore decryptedKeystore) {
|
||||||
final DialogPane dialogPane = getDialogPane();
|
final DialogPane dialogPane = getDialogPane();
|
||||||
dialogPane.getStylesheets().add(AppController.class.getResource("general.css").toExternalForm());
|
dialogPane.getStylesheets().add(AppServices.class.getResource("general.css").toExternalForm());
|
||||||
AppController.setStageIcon(dialogPane.getScene().getWindow());
|
AppServices.setStageIcon(dialogPane.getScene().getWindow());
|
||||||
|
|
||||||
int lines = decryptedKeystore.getSeed().getMnemonicCode().size() / 3;
|
int lines = decryptedKeystore.getSeed().getMnemonicCode().size() / 3;
|
||||||
int height = lines * 40;
|
int height = lines * 40;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package com.sparrowwallet.sparrow.control;
|
package com.sparrowwallet.sparrow.control;
|
||||||
|
|
||||||
import com.sparrowwallet.sparrow.AppController;
|
import com.sparrowwallet.sparrow.AppServices;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.beans.NamedArg;
|
import javafx.beans.NamedArg;
|
||||||
import javafx.scene.control.*;
|
import javafx.scene.control.*;
|
||||||
|
@ -29,8 +29,8 @@ public class TextAreaDialog extends Dialog<String> {
|
||||||
this.defaultValue = defaultValue;
|
this.defaultValue = defaultValue;
|
||||||
|
|
||||||
dialogPane.setContent(hbox);
|
dialogPane.setContent(hbox);
|
||||||
dialogPane.getStylesheets().add(AppController.class.getResource("general.css").toExternalForm());
|
dialogPane.getStylesheets().add(AppServices.class.getResource("general.css").toExternalForm());
|
||||||
AppController.setStageIcon(dialogPane.getScene().getWindow());
|
AppServices.setStageIcon(dialogPane.getScene().getWindow());
|
||||||
|
|
||||||
dialogPane.getStyleClass().add("text-input-dialog");
|
dialogPane.getStyleClass().add("text-input-dialog");
|
||||||
dialogPane.getButtonTypes().addAll(ButtonType.OK, ButtonType.CANCEL);
|
dialogPane.getButtonTypes().addAll(ButtonType.OK, ButtonType.CANCEL);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package com.sparrowwallet.sparrow.control;
|
package com.sparrowwallet.sparrow.control;
|
||||||
|
|
||||||
import com.sparrowwallet.sparrow.AppController;
|
import com.sparrowwallet.sparrow.AppServices;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.geometry.Insets;
|
import javafx.geometry.Insets;
|
||||||
import javafx.geometry.Pos;
|
import javafx.geometry.Pos;
|
||||||
|
@ -21,7 +21,7 @@ public class TitledDescriptionPane extends TitledPane {
|
||||||
protected HBox buttonBox;
|
protected HBox buttonBox;
|
||||||
|
|
||||||
public TitledDescriptionPane(String title, String description, String content, String imageUrl) {
|
public TitledDescriptionPane(String title, String description, String content, String imageUrl) {
|
||||||
getStylesheets().add(AppController.class.getResource("general.css").toExternalForm());
|
getStylesheets().add(AppServices.class.getResource("general.css").toExternalForm());
|
||||||
getStyleClass().add("titled-description-pane");
|
getStyleClass().add("titled-description-pane");
|
||||||
|
|
||||||
setPadding(Insets.EMPTY);
|
setPadding(Insets.EMPTY);
|
||||||
|
|
|
@ -7,7 +7,7 @@ import com.sparrowwallet.drongo.wallet.BlockTransactionHashIndex;
|
||||||
import com.sparrowwallet.drongo.wallet.Payment;
|
import com.sparrowwallet.drongo.wallet.Payment;
|
||||||
import com.sparrowwallet.drongo.wallet.WalletNode;
|
import com.sparrowwallet.drongo.wallet.WalletNode;
|
||||||
import com.sparrowwallet.drongo.wallet.WalletTransaction;
|
import com.sparrowwallet.drongo.wallet.WalletTransaction;
|
||||||
import com.sparrowwallet.sparrow.AppController;
|
import com.sparrowwallet.sparrow.AppServices;
|
||||||
import com.sparrowwallet.sparrow.EventManager;
|
import com.sparrowwallet.sparrow.EventManager;
|
||||||
import com.sparrowwallet.sparrow.event.ExcludeUtxoEvent;
|
import com.sparrowwallet.sparrow.event.ExcludeUtxoEvent;
|
||||||
import com.sparrowwallet.sparrow.glyphfont.FontAwesome5;
|
import com.sparrowwallet.sparrow.glyphfont.FontAwesome5;
|
||||||
|
@ -103,7 +103,7 @@ public class TransactionDiagram extends GridPane {
|
||||||
for(Payment payment : walletTx.getPayments()) {
|
for(Payment payment : walletTx.getPayments()) {
|
||||||
try {
|
try {
|
||||||
Address address = payment.getAddress();
|
Address address = payment.getAddress();
|
||||||
BitcoinURI bitcoinURI = AppController.getPayjoinURI(address);
|
BitcoinURI bitcoinURI = AppServices.getPayjoinURI(address);
|
||||||
if(bitcoinURI != null) {
|
if(bitcoinURI != null) {
|
||||||
return bitcoinURI;
|
return bitcoinURI;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ package com.sparrowwallet.sparrow.control;
|
||||||
|
|
||||||
import com.sparrowwallet.drongo.Utils;
|
import com.sparrowwallet.drongo.Utils;
|
||||||
import com.sparrowwallet.drongo.protocol.Sha256Hash;
|
import com.sparrowwallet.drongo.protocol.Sha256Hash;
|
||||||
import com.sparrowwallet.sparrow.AppController;
|
import com.sparrowwallet.sparrow.AppServices;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.beans.binding.Bindings;
|
import javafx.beans.binding.Bindings;
|
||||||
import javafx.beans.binding.BooleanBinding;
|
import javafx.beans.binding.BooleanBinding;
|
||||||
|
@ -23,13 +23,13 @@ public class TransactionIdDialog extends Dialog<Sha256Hash> {
|
||||||
|
|
||||||
public TransactionIdDialog() {
|
public TransactionIdDialog() {
|
||||||
this.txid = (CustomTextField) TextFields.createClearableTextField();
|
this.txid = (CustomTextField) TextFields.createClearableTextField();
|
||||||
txid.setFont(AppController.getMonospaceFont());
|
txid.setFont(AppServices.getMonospaceFont());
|
||||||
final DialogPane dialogPane = getDialogPane();
|
final DialogPane dialogPane = getDialogPane();
|
||||||
AppController.setStageIcon(dialogPane.getScene().getWindow());
|
AppServices.setStageIcon(dialogPane.getScene().getWindow());
|
||||||
|
|
||||||
setTitle("Load Transaction");
|
setTitle("Load Transaction");
|
||||||
dialogPane.setHeaderText("Enter the transaction ID:");
|
dialogPane.setHeaderText("Enter the transaction ID:");
|
||||||
dialogPane.getStylesheets().add(AppController.class.getResource("general.css").toExternalForm());
|
dialogPane.getStylesheets().add(AppServices.class.getResource("general.css").toExternalForm());
|
||||||
dialogPane.getButtonTypes().addAll(ButtonType.CANCEL);
|
dialogPane.getButtonTypes().addAll(ButtonType.CANCEL);
|
||||||
dialogPane.setPrefWidth(550);
|
dialogPane.setPrefWidth(550);
|
||||||
dialogPane.setPrefHeight(200);
|
dialogPane.setPrefHeight(200);
|
||||||
|
|
|
@ -3,7 +3,7 @@ package com.sparrowwallet.sparrow.control;
|
||||||
import com.google.common.eventbus.Subscribe;
|
import com.google.common.eventbus.Subscribe;
|
||||||
import com.sparrowwallet.drongo.policy.PolicyType;
|
import com.sparrowwallet.drongo.policy.PolicyType;
|
||||||
import com.sparrowwallet.drongo.wallet.Wallet;
|
import com.sparrowwallet.drongo.wallet.Wallet;
|
||||||
import com.sparrowwallet.sparrow.AppController;
|
import com.sparrowwallet.sparrow.AppServices;
|
||||||
import com.sparrowwallet.sparrow.EventManager;
|
import com.sparrowwallet.sparrow.EventManager;
|
||||||
import com.sparrowwallet.sparrow.event.WalletExportEvent;
|
import com.sparrowwallet.sparrow.event.WalletExportEvent;
|
||||||
import com.sparrowwallet.sparrow.io.*;
|
import com.sparrowwallet.sparrow.io.*;
|
||||||
|
@ -23,7 +23,7 @@ public class WalletExportDialog extends Dialog<Wallet> {
|
||||||
});
|
});
|
||||||
|
|
||||||
final DialogPane dialogPane = getDialogPane();
|
final DialogPane dialogPane = getDialogPane();
|
||||||
AppController.setStageIcon(dialogPane.getScene().getWindow());
|
AppServices.setStageIcon(dialogPane.getScene().getWindow());
|
||||||
|
|
||||||
StackPane stackPane = new StackPane();
|
StackPane stackPane = new StackPane();
|
||||||
dialogPane.setContent(stackPane);
|
dialogPane.setContent(stackPane);
|
||||||
|
|
|
@ -2,7 +2,7 @@ package com.sparrowwallet.sparrow.control;
|
||||||
|
|
||||||
import com.google.common.eventbus.Subscribe;
|
import com.google.common.eventbus.Subscribe;
|
||||||
import com.sparrowwallet.drongo.wallet.Wallet;
|
import com.sparrowwallet.drongo.wallet.Wallet;
|
||||||
import com.sparrowwallet.sparrow.AppController;
|
import com.sparrowwallet.sparrow.AppServices;
|
||||||
import com.sparrowwallet.sparrow.EventManager;
|
import com.sparrowwallet.sparrow.EventManager;
|
||||||
import com.sparrowwallet.sparrow.event.WalletImportEvent;
|
import com.sparrowwallet.sparrow.event.WalletImportEvent;
|
||||||
import com.sparrowwallet.sparrow.io.*;
|
import com.sparrowwallet.sparrow.io.*;
|
||||||
|
@ -22,7 +22,7 @@ public class WalletImportDialog extends Dialog<Wallet> {
|
||||||
});
|
});
|
||||||
|
|
||||||
final DialogPane dialogPane = getDialogPane();
|
final DialogPane dialogPane = getDialogPane();
|
||||||
AppController.setStageIcon(dialogPane.getScene().getWindow());
|
AppServices.setStageIcon(dialogPane.getScene().getWindow());
|
||||||
|
|
||||||
StackPane stackPane = new StackPane();
|
StackPane stackPane = new StackPane();
|
||||||
dialogPane.setContent(stackPane);
|
dialogPane.setContent(stackPane);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package com.sparrowwallet.sparrow.control;
|
package com.sparrowwallet.sparrow.control;
|
||||||
|
|
||||||
import com.sparrowwallet.sparrow.AppController;
|
import com.sparrowwallet.sparrow.AppServices;
|
||||||
import com.sparrowwallet.sparrow.glyphfont.FontAwesome5;
|
import com.sparrowwallet.sparrow.glyphfont.FontAwesome5;
|
||||||
import com.sparrowwallet.sparrow.io.Storage;
|
import com.sparrowwallet.sparrow.io.Storage;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
|
@ -22,11 +22,11 @@ public class WalletNameDialog extends Dialog<String> {
|
||||||
public WalletNameDialog() {
|
public WalletNameDialog() {
|
||||||
this.name = (CustomTextField)TextFields.createClearableTextField();
|
this.name = (CustomTextField)TextFields.createClearableTextField();
|
||||||
final DialogPane dialogPane = getDialogPane();
|
final DialogPane dialogPane = getDialogPane();
|
||||||
AppController.setStageIcon(dialogPane.getScene().getWindow());
|
AppServices.setStageIcon(dialogPane.getScene().getWindow());
|
||||||
|
|
||||||
setTitle("Wallet Name");
|
setTitle("Wallet Name");
|
||||||
dialogPane.setHeaderText("Enter a name for this wallet:");
|
dialogPane.setHeaderText("Enter a name for this wallet:");
|
||||||
dialogPane.getStylesheets().add(AppController.class.getResource("general.css").toExternalForm());
|
dialogPane.getStylesheets().add(AppServices.class.getResource("general.css").toExternalForm());
|
||||||
dialogPane.getButtonTypes().addAll(ButtonType.CANCEL);
|
dialogPane.getButtonTypes().addAll(ButtonType.CANCEL);
|
||||||
dialogPane.setPrefWidth(380);
|
dialogPane.setPrefWidth(380);
|
||||||
dialogPane.setPrefHeight(200);
|
dialogPane.setPrefHeight(200);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package com.sparrowwallet.sparrow.control;
|
package com.sparrowwallet.sparrow.control;
|
||||||
|
|
||||||
import com.sparrowwallet.drongo.SecureString;
|
import com.sparrowwallet.drongo.SecureString;
|
||||||
import com.sparrowwallet.sparrow.AppController;
|
import com.sparrowwallet.sparrow.AppServices;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.beans.binding.Bindings;
|
import javafx.beans.binding.Bindings;
|
||||||
import javafx.beans.binding.BooleanBinding;
|
import javafx.beans.binding.BooleanBinding;
|
||||||
|
@ -37,8 +37,8 @@ public class WalletPasswordDialog extends Dialog<SecureString> {
|
||||||
final DialogPane dialogPane = getDialogPane();
|
final DialogPane dialogPane = getDialogPane();
|
||||||
setTitle("Wallet Password" + (walletName != null ? " - " + walletName : ""));
|
setTitle("Wallet Password" + (walletName != null ? " - " + walletName : ""));
|
||||||
dialogPane.setHeaderText(walletName != null ? requirement.description.substring(0, requirement.description.length() - 1) + " for " + walletName + ":" : requirement.description);
|
dialogPane.setHeaderText(walletName != null ? requirement.description.substring(0, requirement.description.length() - 1) + " for " + walletName + ":" : requirement.description);
|
||||||
dialogPane.getStylesheets().add(AppController.class.getResource("general.css").toExternalForm());
|
dialogPane.getStylesheets().add(AppServices.class.getResource("general.css").toExternalForm());
|
||||||
AppController.setStageIcon(dialogPane.getScene().getWindow());
|
AppServices.setStageIcon(dialogPane.getScene().getWindow());
|
||||||
dialogPane.getButtonTypes().addAll(ButtonType.CANCEL);
|
dialogPane.getButtonTypes().addAll(ButtonType.CANCEL);
|
||||||
dialogPane.setPrefWidth(380);
|
dialogPane.setPrefWidth(380);
|
||||||
dialogPane.setPrefHeight(260);
|
dialogPane.setPrefHeight(260);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package com.sparrowwallet.sparrow.control;
|
package com.sparrowwallet.sparrow.control;
|
||||||
|
|
||||||
import com.sparrowwallet.sparrow.AppController;
|
import com.sparrowwallet.sparrow.AppServices;
|
||||||
import com.sparrowwallet.sparrow.Mode;
|
import com.sparrowwallet.sparrow.Mode;
|
||||||
import javafx.application.HostServices;
|
import javafx.application.HostServices;
|
||||||
import javafx.geometry.Insets;
|
import javafx.geometry.Insets;
|
||||||
|
@ -27,8 +27,8 @@ public class WelcomeDialog extends Dialog<Mode> {
|
||||||
|
|
||||||
setTitle("Welcome to Sparrow");
|
setTitle("Welcome to Sparrow");
|
||||||
dialogPane.setHeaderText("Welcome to Sparrow!");
|
dialogPane.setHeaderText("Welcome to Sparrow!");
|
||||||
dialogPane.getStylesheets().add(AppController.class.getResource("general.css").toExternalForm());
|
dialogPane.getStylesheets().add(AppServices.class.getResource("general.css").toExternalForm());
|
||||||
AppController.setStageIcon(dialogPane.getScene().getWindow());
|
AppServices.setStageIcon(dialogPane.getScene().getWindow());
|
||||||
dialogPane.setPrefWidth(600);
|
dialogPane.setPrefWidth(600);
|
||||||
dialogPane.setPrefHeight(480);
|
dialogPane.setPrefHeight(480);
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ package com.sparrowwallet.sparrow.keystoreimport;
|
||||||
|
|
||||||
import com.sparrowwallet.drongo.wallet.KeystoreSource;
|
import com.sparrowwallet.drongo.wallet.KeystoreSource;
|
||||||
import com.sparrowwallet.drongo.wallet.Wallet;
|
import com.sparrowwallet.drongo.wallet.Wallet;
|
||||||
import com.sparrowwallet.sparrow.AppController;
|
import com.sparrowwallet.sparrow.AppServices;
|
||||||
import com.sparrowwallet.sparrow.io.Device;
|
import com.sparrowwallet.sparrow.io.Device;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
|
@ -84,7 +84,7 @@ public class KeystoreImportController implements Initializable {
|
||||||
importPane.getChildren().removeAll(importPane.getChildren());
|
importPane.getChildren().removeAll(importPane.getChildren());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
FXMLLoader importLoader = new FXMLLoader(AppController.class.getResource("keystoreimport/" + fxmlName + ".fxml"));
|
FXMLLoader importLoader = new FXMLLoader(AppServices.class.getResource("keystoreimport/" + fxmlName + ".fxml"));
|
||||||
Node importTypeNode = importLoader.load();
|
Node importTypeNode = importLoader.load();
|
||||||
KeystoreImportDetailController controller = importLoader.getController();
|
KeystoreImportDetailController controller = importLoader.getController();
|
||||||
controller.setMasterController(this);
|
controller.setMasterController(this);
|
||||||
|
|
|
@ -7,7 +7,7 @@ import com.sparrowwallet.drongo.wallet.Keystore;
|
||||||
import com.sparrowwallet.drongo.wallet.KeystoreSource;
|
import com.sparrowwallet.drongo.wallet.KeystoreSource;
|
||||||
import com.sparrowwallet.drongo.wallet.Wallet;
|
import com.sparrowwallet.drongo.wallet.Wallet;
|
||||||
import com.sparrowwallet.drongo.wallet.WalletModel;
|
import com.sparrowwallet.drongo.wallet.WalletModel;
|
||||||
import com.sparrowwallet.sparrow.AppController;
|
import com.sparrowwallet.sparrow.AppServices;
|
||||||
import com.sparrowwallet.sparrow.EventManager;
|
import com.sparrowwallet.sparrow.EventManager;
|
||||||
import com.sparrowwallet.sparrow.event.KeystoreImportEvent;
|
import com.sparrowwallet.sparrow.event.KeystoreImportEvent;
|
||||||
import javafx.fxml.FXMLLoader;
|
import javafx.fxml.FXMLLoader;
|
||||||
|
@ -32,10 +32,10 @@ public class KeystoreImportDialog extends Dialog<Keystore> {
|
||||||
});
|
});
|
||||||
|
|
||||||
final DialogPane dialogPane = getDialogPane();
|
final DialogPane dialogPane = getDialogPane();
|
||||||
AppController.setStageIcon(dialogPane.getScene().getWindow());
|
AppServices.setStageIcon(dialogPane.getScene().getWindow());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
FXMLLoader ksiLoader = new FXMLLoader(AppController.class.getResource("keystoreimport/keystoreimport.fxml"));
|
FXMLLoader ksiLoader = new FXMLLoader(AppServices.class.getResource("keystoreimport/keystoreimport.fxml"));
|
||||||
dialogPane.setContent(Borders.wrap(ksiLoader.load()).emptyBorder().buildAll());
|
dialogPane.setContent(Borders.wrap(ksiLoader.load()).emptyBorder().buildAll());
|
||||||
keystoreImportController = ksiLoader.getController();
|
keystoreImportController = ksiLoader.getController();
|
||||||
keystoreImportController.initializeView(wallet);
|
keystoreImportController.initializeView(wallet);
|
||||||
|
|
|
@ -7,7 +7,7 @@ import com.sparrowwallet.drongo.Utils;
|
||||||
import com.sparrowwallet.drongo.protocol.Sha256Hash;
|
import com.sparrowwallet.drongo.protocol.Sha256Hash;
|
||||||
import com.sparrowwallet.drongo.protocol.Transaction;
|
import com.sparrowwallet.drongo.protocol.Transaction;
|
||||||
import com.sparrowwallet.drongo.wallet.Wallet;
|
import com.sparrowwallet.drongo.wallet.Wallet;
|
||||||
import com.sparrowwallet.sparrow.AppController;
|
import com.sparrowwallet.sparrow.AppServices;
|
||||||
import com.sparrowwallet.sparrow.EventManager;
|
import com.sparrowwallet.sparrow.EventManager;
|
||||||
import com.sparrowwallet.sparrow.event.WalletHistoryStatusEvent;
|
import com.sparrowwallet.sparrow.event.WalletHistoryStatusEvent;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
@ -209,7 +209,7 @@ public class SimpleElectrumServerRpc implements ElectrumServerRpc {
|
||||||
VerboseTransaction verboseTransaction = new VerboseTransaction();
|
VerboseTransaction verboseTransaction = new VerboseTransaction();
|
||||||
verboseTransaction.txid = id;
|
verboseTransaction.txid = id;
|
||||||
verboseTransaction.hex = rawTxHex;
|
verboseTransaction.hex = rawTxHex;
|
||||||
verboseTransaction.confirmations = (height <= 0 ? 0 : AppController.getCurrentBlockHeight() - height + 1);
|
verboseTransaction.confirmations = (height <= 0 ? 0 : AppServices.getCurrentBlockHeight() - height + 1);
|
||||||
verboseTransaction.blockhash = Sha256Hash.ZERO_HASH.toString();
|
verboseTransaction.blockhash = Sha256Hash.ZERO_HASH.toString();
|
||||||
result.put(txid, verboseTransaction);
|
result.put(txid, verboseTransaction);
|
||||||
} catch(Exception ex) {
|
} catch(Exception ex) {
|
||||||
|
|
|
@ -5,7 +5,7 @@ import com.sparrowwallet.drongo.Utils;
|
||||||
import com.sparrowwallet.drongo.protocol.Sha256Hash;
|
import com.sparrowwallet.drongo.protocol.Sha256Hash;
|
||||||
import com.sparrowwallet.drongo.protocol.Transaction;
|
import com.sparrowwallet.drongo.protocol.Transaction;
|
||||||
import com.sparrowwallet.drongo.wallet.BlockTransaction;
|
import com.sparrowwallet.drongo.wallet.BlockTransaction;
|
||||||
import com.sparrowwallet.sparrow.AppController;
|
import com.sparrowwallet.sparrow.AppServices;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ class VerboseTransaction {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Integer currentHeight = AppController.getCurrentBlockHeight();
|
Integer currentHeight = AppServices.getCurrentBlockHeight();
|
||||||
if(currentHeight != null) {
|
if(currentHeight != null) {
|
||||||
return currentHeight - confirmations + 1;
|
return currentHeight - confirmations + 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
package com.sparrowwallet.sparrow.preferences;
|
package com.sparrowwallet.sparrow.preferences;
|
||||||
|
|
||||||
import com.sparrowwallet.drongo.wallet.KeystoreSource;
|
import com.sparrowwallet.sparrow.AppServices;
|
||||||
import com.sparrowwallet.drongo.wallet.Wallet;
|
|
||||||
import com.sparrowwallet.sparrow.AppController;
|
|
||||||
import com.sparrowwallet.sparrow.io.Config;
|
import com.sparrowwallet.sparrow.io.Config;
|
||||||
import com.sparrowwallet.sparrow.keystoreimport.KeystoreImportDetailController;
|
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.fxml.FXMLLoader;
|
import javafx.fxml.FXMLLoader;
|
||||||
|
@ -63,7 +60,7 @@ public class PreferencesController implements Initializable {
|
||||||
preferencesPane.getChildren().removeAll(preferencesPane.getChildren());
|
preferencesPane.getChildren().removeAll(preferencesPane.getChildren());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
FXMLLoader preferencesDetailLoader = new FXMLLoader(AppController.class.getResource("preferences/" + fxmlName + ".fxml"));
|
FXMLLoader preferencesDetailLoader = new FXMLLoader(AppServices.class.getResource("preferences/" + fxmlName + ".fxml"));
|
||||||
Node preferenceGroupNode = preferencesDetailLoader.load();
|
Node preferenceGroupNode = preferencesDetailLoader.load();
|
||||||
PreferencesDetailController controller = preferencesDetailLoader.getController();
|
PreferencesDetailController controller = preferencesDetailLoader.getController();
|
||||||
controller.setMasterController(this);
|
controller.setMasterController(this);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package com.sparrowwallet.sparrow.preferences;
|
package com.sparrowwallet.sparrow.preferences;
|
||||||
|
|
||||||
import com.sparrowwallet.sparrow.AppController;
|
import com.sparrowwallet.sparrow.AppServices;
|
||||||
import com.sparrowwallet.sparrow.EventManager;
|
import com.sparrowwallet.sparrow.EventManager;
|
||||||
import com.sparrowwallet.sparrow.event.RequestConnectEvent;
|
import com.sparrowwallet.sparrow.event.RequestConnectEvent;
|
||||||
import com.sparrowwallet.sparrow.io.Config;
|
import com.sparrowwallet.sparrow.io.Config;
|
||||||
|
@ -27,10 +27,10 @@ public class PreferencesDialog extends Dialog<Boolean> {
|
||||||
|
|
||||||
public PreferencesDialog(PreferenceGroup initialGroup, boolean initialSetup) {
|
public PreferencesDialog(PreferenceGroup initialGroup, boolean initialSetup) {
|
||||||
final DialogPane dialogPane = getDialogPane();
|
final DialogPane dialogPane = getDialogPane();
|
||||||
AppController.setStageIcon(dialogPane.getScene().getWindow());
|
AppServices.setStageIcon(dialogPane.getScene().getWindow());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
FXMLLoader preferencesLoader = new FXMLLoader(AppController.class.getResource("preferences/preferences.fxml"));
|
FXMLLoader preferencesLoader = new FXMLLoader(AppServices.class.getResource("preferences/preferences.fxml"));
|
||||||
dialogPane.setContent(Borders.wrap(preferencesLoader.load()).emptyBorder().buildAll());
|
dialogPane.setContent(Borders.wrap(preferencesLoader.load()).emptyBorder().buildAll());
|
||||||
PreferencesController preferencesController = preferencesLoader.getController();
|
PreferencesController preferencesController = preferencesLoader.getController();
|
||||||
preferencesController.initializeView(Config.get());
|
preferencesController.initializeView(Config.get());
|
||||||
|
|
|
@ -11,7 +11,7 @@ import com.sparrowwallet.drongo.uri.BitcoinURI;
|
||||||
import com.sparrowwallet.drongo.wallet.*;
|
import com.sparrowwallet.drongo.wallet.*;
|
||||||
import com.sparrowwallet.hummingbird.UR;
|
import com.sparrowwallet.hummingbird.UR;
|
||||||
import com.sparrowwallet.hummingbird.registry.RegistryType;
|
import com.sparrowwallet.hummingbird.registry.RegistryType;
|
||||||
import com.sparrowwallet.sparrow.AppController;
|
import com.sparrowwallet.sparrow.AppServices;
|
||||||
import com.sparrowwallet.sparrow.EventManager;
|
import com.sparrowwallet.sparrow.EventManager;
|
||||||
import com.sparrowwallet.sparrow.control.*;
|
import com.sparrowwallet.sparrow.control.*;
|
||||||
import com.sparrowwallet.sparrow.event.*;
|
import com.sparrowwallet.sparrow.event.*;
|
||||||
|
@ -252,8 +252,8 @@ public class HeadersController extends TransactionFormController implements Init
|
||||||
locktimeFieldset.getChildren().add(locktimeBlockField);
|
locktimeFieldset.getChildren().add(locktimeBlockField);
|
||||||
Integer block = locktimeBlock.getValue();
|
Integer block = locktimeBlock.getValue();
|
||||||
if(block != null) {
|
if(block != null) {
|
||||||
locktimeCurrentHeight.setVisible(headersForm.isEditable() && AppController.getCurrentBlockHeight() != null && block < AppController.getCurrentBlockHeight());
|
locktimeCurrentHeight.setVisible(headersForm.isEditable() && AppServices.getCurrentBlockHeight() != null && block < AppServices.getCurrentBlockHeight());
|
||||||
futureBlockWarning.setVisible(AppController.getCurrentBlockHeight() != null && block > AppController.getCurrentBlockHeight());
|
futureBlockWarning.setVisible(AppServices.getCurrentBlockHeight() != null && block > AppServices.getCurrentBlockHeight());
|
||||||
tx.setLocktime(block);
|
tx.setLocktime(block);
|
||||||
if(old_toggle != null) {
|
if(old_toggle != null) {
|
||||||
EventManager.get().post(new TransactionChangedEvent(tx));
|
EventManager.get().post(new TransactionChangedEvent(tx));
|
||||||
|
@ -303,8 +303,8 @@ public class HeadersController extends TransactionFormController implements Init
|
||||||
|
|
||||||
locktimeBlock.valueProperty().addListener((obs, oldValue, newValue) -> {
|
locktimeBlock.valueProperty().addListener((obs, oldValue, newValue) -> {
|
||||||
tx.setLocktime(newValue);
|
tx.setLocktime(newValue);
|
||||||
locktimeCurrentHeight.setVisible(headersForm.isEditable() && AppController.getCurrentBlockHeight() != null && newValue < AppController.getCurrentBlockHeight());
|
locktimeCurrentHeight.setVisible(headersForm.isEditable() && AppServices.getCurrentBlockHeight() != null && newValue < AppServices.getCurrentBlockHeight());
|
||||||
futureBlockWarning.setVisible(AppController.getCurrentBlockHeight() != null && newValue > AppController.getCurrentBlockHeight());
|
futureBlockWarning.setVisible(AppServices.getCurrentBlockHeight() != null && newValue > AppServices.getCurrentBlockHeight());
|
||||||
if(oldValue != null) {
|
if(oldValue != null) {
|
||||||
EventManager.get().post(new TransactionChangedEvent(tx));
|
EventManager.get().post(new TransactionChangedEvent(tx));
|
||||||
EventManager.get().post(new TransactionLocktimeChangedEvent(tx));
|
EventManager.get().post(new TransactionLocktimeChangedEvent(tx));
|
||||||
|
@ -360,7 +360,7 @@ public class HeadersController extends TransactionFormController implements Init
|
||||||
broadcastButton.managedProperty().bind(broadcastButton.visibleProperty());
|
broadcastButton.managedProperty().bind(broadcastButton.visibleProperty());
|
||||||
saveFinalButton.managedProperty().bind(saveFinalButton.visibleProperty());
|
saveFinalButton.managedProperty().bind(saveFinalButton.visibleProperty());
|
||||||
saveFinalButton.visibleProperty().bind(broadcastButton.visibleProperty().not());
|
saveFinalButton.visibleProperty().bind(broadcastButton.visibleProperty().not());
|
||||||
broadcastButton.visibleProperty().bind(AppController.onlineProperty());
|
broadcastButton.visibleProperty().bind(AppServices.onlineProperty());
|
||||||
|
|
||||||
BitcoinURI payjoinURI = getPayjoinURI();
|
BitcoinURI payjoinURI = getPayjoinURI();
|
||||||
boolean isPayjoinOriginalTx = payjoinURI != null && headersForm.getPsbt() != null && headersForm.getPsbt().getPsbtInputs().stream().noneMatch(PSBTInput::isFinalized);
|
boolean isPayjoinOriginalTx = payjoinURI != null && headersForm.getPsbt() != null && headersForm.getPsbt().getPsbtInputs().stream().noneMatch(PSBTInput::isFinalized);
|
||||||
|
@ -377,7 +377,7 @@ public class HeadersController extends TransactionFormController implements Init
|
||||||
broadcastButtonBox.setVisible(false);
|
broadcastButtonBox.setVisible(false);
|
||||||
|
|
||||||
if(headersForm.getBlockTransaction() != null) {
|
if(headersForm.getBlockTransaction() != null) {
|
||||||
updateBlockchainForm(headersForm.getBlockTransaction(), AppController.getCurrentBlockHeight());
|
updateBlockchainForm(headersForm.getBlockTransaction(), AppServices.getCurrentBlockHeight());
|
||||||
} else if(headersForm.getPsbt() != null) {
|
} else if(headersForm.getPsbt() != null) {
|
||||||
PSBT psbt = headersForm.getPsbt();
|
PSBT psbt = headersForm.getPsbt();
|
||||||
|
|
||||||
|
@ -558,7 +558,7 @@ public class HeadersController extends TransactionFormController implements Init
|
||||||
for(TransactionOutput txOutput : headersForm.getPsbt().getTransaction().getOutputs()) {
|
for(TransactionOutput txOutput : headersForm.getPsbt().getTransaction().getOutputs()) {
|
||||||
try {
|
try {
|
||||||
Address address = txOutput.getScript().getToAddresses()[0];
|
Address address = txOutput.getScript().getToAddresses()[0];
|
||||||
BitcoinURI bitcoinURI = AppController.getPayjoinURI(address);
|
BitcoinURI bitcoinURI = AppServices.getPayjoinURI(address);
|
||||||
if(bitcoinURI != null) {
|
if(bitcoinURI != null) {
|
||||||
return bitcoinURI;
|
return bitcoinURI;
|
||||||
}
|
}
|
||||||
|
@ -602,8 +602,8 @@ public class HeadersController extends TransactionFormController implements Init
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLocktimeToCurrentHeight(ActionEvent event) {
|
public void setLocktimeToCurrentHeight(ActionEvent event) {
|
||||||
if(AppController.getCurrentBlockHeight() != null && locktimeBlock.isEditable()) {
|
if(AppServices.getCurrentBlockHeight() != null && locktimeBlock.isEditable()) {
|
||||||
locktimeBlock.getValueFactory().setValue(AppController.getCurrentBlockHeight());
|
locktimeBlock.getValueFactory().setValue(AppServices.getCurrentBlockHeight());
|
||||||
Platform.runLater(() -> locktimeBlockType.requestFocus());
|
Platform.runLater(() -> locktimeBlockType.requestFocus());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -659,7 +659,7 @@ public class HeadersController extends TransactionFormController implements Init
|
||||||
}
|
}
|
||||||
} catch(IOException e) {
|
} catch(IOException e) {
|
||||||
log.error("Error saving PSBT", e);
|
log.error("Error saving PSBT", e);
|
||||||
AppController.showErrorDialog("Error saving PSBT", "Cannot write to " + file.getAbsolutePath());
|
AppServices.showErrorDialog("Error saving PSBT", "Cannot write to " + file.getAbsolutePath());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -700,7 +700,7 @@ public class HeadersController extends TransactionFormController implements Init
|
||||||
});
|
});
|
||||||
decryptWalletService.setOnFailed(workerStateEvent -> {
|
decryptWalletService.setOnFailed(workerStateEvent -> {
|
||||||
EventManager.get().post(new StorageEvent(file, TimedEvent.Action.END, "Failed"));
|
EventManager.get().post(new StorageEvent(file, TimedEvent.Action.END, "Failed"));
|
||||||
AppController.showErrorDialog("Incorrect Password", decryptWalletService.getException().getMessage());
|
AppServices.showErrorDialog("Incorrect Password", decryptWalletService.getException().getMessage());
|
||||||
});
|
});
|
||||||
EventManager.get().post(new StorageEvent(file, TimedEvent.Action.START, "Decrypting wallet..."));
|
EventManager.get().post(new StorageEvent(file, TimedEvent.Action.START, "Decrypting wallet..."));
|
||||||
decryptWalletService.start();
|
decryptWalletService.start();
|
||||||
|
@ -716,7 +716,7 @@ public class HeadersController extends TransactionFormController implements Init
|
||||||
updateSignedKeystores(headersForm.getSigningWallet());
|
updateSignedKeystores(headersForm.getSigningWallet());
|
||||||
} catch(Exception e) {
|
} catch(Exception e) {
|
||||||
log.warn("Failed to Sign", e);
|
log.warn("Failed to Sign", e);
|
||||||
AppController.showErrorDialog("Failed to Sign", e.getMessage());
|
AppServices.showErrorDialog("Failed to Sign", e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -726,7 +726,7 @@ public class HeadersController extends TransactionFormController implements Init
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> fingerprints = headersForm.getSigningWallet().getKeystores().stream().map(keystore -> keystore.getKeyDerivation().getMasterFingerprint()).collect(Collectors.toList());
|
List<String> fingerprints = headersForm.getSigningWallet().getKeystores().stream().map(keystore -> keystore.getKeyDerivation().getMasterFingerprint()).collect(Collectors.toList());
|
||||||
List<Device> signingDevices = AppController.getDevices().stream().filter(device -> fingerprints.contains(device.getFingerprint())).collect(Collectors.toList());
|
List<Device> signingDevices = AppServices.getDevices().stream().filter(device -> fingerprints.contains(device.getFingerprint())).collect(Collectors.toList());
|
||||||
if(signingDevices.isEmpty() && headersForm.getSigningWallet().getKeystores().stream().noneMatch(keystore -> keystore.getSource().equals(KeystoreSource.HW_USB))) {
|
if(signingDevices.isEmpty() && headersForm.getSigningWallet().getKeystores().stream().noneMatch(keystore -> keystore.getSource().equals(KeystoreSource.HW_USB))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -788,7 +788,7 @@ public class HeadersController extends TransactionFormController implements Init
|
||||||
broadcastTransactionService.setOnFailed(workerStateEvent -> {
|
broadcastTransactionService.setOnFailed(workerStateEvent -> {
|
||||||
broadcastProgressBar.setProgress(0);
|
broadcastProgressBar.setProgress(0);
|
||||||
log.error("Error broadcasting transaction", workerStateEvent.getSource().getException());
|
log.error("Error broadcasting transaction", workerStateEvent.getSource().getException());
|
||||||
AppController.showErrorDialog("Error broadcasting transaction", "The server returned an error when broadcasting the transaction. The server response is contained in sparrow.log");
|
AppServices.showErrorDialog("Error broadcasting transaction", "The server returned an error when broadcasting the transaction. The server response is contained in sparrow.log");
|
||||||
broadcastButton.setDisable(false);
|
broadcastButton.setDisable(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -816,7 +816,7 @@ public class HeadersController extends TransactionFormController implements Init
|
||||||
}
|
}
|
||||||
} catch(IOException e) {
|
} catch(IOException e) {
|
||||||
log.error("Error saving transaction", e);
|
log.error("Error saving transaction", e);
|
||||||
AppController.showErrorDialog("Error saving transaction", "Cannot write to " + file.getAbsolutePath());
|
AppServices.showErrorDialog("Error saving transaction", "Cannot write to " + file.getAbsolutePath());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -832,7 +832,7 @@ public class HeadersController extends TransactionFormController implements Init
|
||||||
PSBT proposalPsbt = payjoin.requestPayjoinPSBT(true);
|
PSBT proposalPsbt = payjoin.requestPayjoinPSBT(true);
|
||||||
EventManager.get().post(new ViewPSBTEvent(headersForm.getName() + " Payjoin", proposalPsbt));
|
EventManager.get().post(new ViewPSBTEvent(headersForm.getName() + " Payjoin", proposalPsbt));
|
||||||
} catch(PayjoinReceiverException e) {
|
} catch(PayjoinReceiverException e) {
|
||||||
AppController.showErrorDialog("Invalid Payjoin Transaction", e.getMessage());
|
AppServices.showErrorDialog("Invalid Payjoin Transaction", e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -844,8 +844,8 @@ public class HeadersController extends TransactionFormController implements Init
|
||||||
blockTransaction = headersForm.getSigningWallet().getTransactions().get(txId);
|
blockTransaction = headersForm.getSigningWallet().getTransactions().get(txId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(blockTransaction != null && AppController.getCurrentBlockHeight() != null) {
|
if(blockTransaction != null && AppServices.getCurrentBlockHeight() != null) {
|
||||||
updateBlockchainForm(blockTransaction, AppController.getCurrentBlockHeight());
|
updateBlockchainForm(blockTransaction, AppServices.getCurrentBlockHeight());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -867,7 +867,7 @@ public class HeadersController extends TransactionFormController implements Init
|
||||||
public void blockTransactionFetched(BlockTransactionFetchedEvent event) {
|
public void blockTransactionFetched(BlockTransactionFetchedEvent event) {
|
||||||
if(event.getTxId().equals(headersForm.getTransaction().getTxId())) {
|
if(event.getTxId().equals(headersForm.getTransaction().getTxId())) {
|
||||||
if(event.getBlockTransaction() != null && (!Sha256Hash.ZERO_HASH.equals(event.getBlockTransaction().getBlockHash()) || headersForm.getBlockTransaction() == null)) {
|
if(event.getBlockTransaction() != null && (!Sha256Hash.ZERO_HASH.equals(event.getBlockTransaction().getBlockHash()) || headersForm.getBlockTransaction() == null)) {
|
||||||
updateBlockchainForm(event.getBlockTransaction(), AppController.getCurrentBlockHeight());
|
updateBlockchainForm(event.getBlockTransaction(), AppServices.getCurrentBlockHeight());
|
||||||
}
|
}
|
||||||
|
|
||||||
Long feeAmt = calculateFee(event.getInputTransactions());
|
Long feeAmt = calculateFee(event.getInputTransactions());
|
||||||
|
@ -1021,7 +1021,7 @@ public class HeadersController extends TransactionFormController implements Init
|
||||||
BlockTransaction blockTransaction = transactionMap.get(txid);
|
BlockTransaction blockTransaction = transactionMap.get(txid);
|
||||||
if(blockTransaction != null) {
|
if(blockTransaction != null) {
|
||||||
headersForm.setBlockTransaction(blockTransaction);
|
headersForm.setBlockTransaction(blockTransaction);
|
||||||
updateBlockchainForm(blockTransaction, AppController.getCurrentBlockHeight());
|
updateBlockchainForm(blockTransaction, AppServices.getCurrentBlockHeight());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
transactionReferenceService.setOnFailed(failEvent -> {
|
transactionReferenceService.setOnFailed(failEvent -> {
|
||||||
|
@ -1064,7 +1064,7 @@ public class HeadersController extends TransactionFormController implements Init
|
||||||
updateBlockchainForm(headersForm.getBlockTransaction(), event.getHeight());
|
updateBlockchainForm(headersForm.getBlockTransaction(), event.getHeight());
|
||||||
}
|
}
|
||||||
if(futureBlockWarning.isVisible()) {
|
if(futureBlockWarning.isVisible()) {
|
||||||
futureBlockWarning.setVisible(AppController.getCurrentBlockHeight() != null && locktimeBlock.getValue() > event.getHeight());
|
futureBlockWarning.setVisible(AppServices.getCurrentBlockHeight() != null && locktimeBlock.getValue() > event.getHeight());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ import com.sparrowwallet.drongo.psbt.PSBT;
|
||||||
import com.sparrowwallet.drongo.psbt.PSBTInput;
|
import com.sparrowwallet.drongo.psbt.PSBTInput;
|
||||||
import com.sparrowwallet.drongo.psbt.PSBTOutput;
|
import com.sparrowwallet.drongo.psbt.PSBTOutput;
|
||||||
import com.sparrowwallet.drongo.wallet.BlockTransaction;
|
import com.sparrowwallet.drongo.wallet.BlockTransaction;
|
||||||
import com.sparrowwallet.sparrow.AppController;
|
import com.sparrowwallet.sparrow.AppServices;
|
||||||
import com.sparrowwallet.sparrow.EventManager;
|
import com.sparrowwallet.sparrow.EventManager;
|
||||||
import com.sparrowwallet.sparrow.TransactionTabData;
|
import com.sparrowwallet.sparrow.TransactionTabData;
|
||||||
import com.sparrowwallet.sparrow.control.TransactionDiagram;
|
import com.sparrowwallet.sparrow.control.TransactionDiagram;
|
||||||
|
@ -326,7 +326,7 @@ public class TransactionController implements Initializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fetchThisAndInputBlockTransactions(int indexStart, int indexEnd) {
|
private void fetchThisAndInputBlockTransactions(int indexStart, int indexEnd) {
|
||||||
if(AppController.isOnline() && indexStart < getTransaction().getInputs().size()) {
|
if(AppServices.isOnline() && indexStart < getTransaction().getInputs().size()) {
|
||||||
Set<Sha256Hash> references = new HashSet<>();
|
Set<Sha256Hash> references = new HashSet<>();
|
||||||
if(getPSBT() == null) {
|
if(getPSBT() == null) {
|
||||||
references.add(getTransaction().getTxId());
|
references.add(getTransaction().getTxId());
|
||||||
|
@ -378,7 +378,7 @@ public class TransactionController implements Initializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fetchOutputBlockTransactions(int indexStart, int indexEnd) {
|
private void fetchOutputBlockTransactions(int indexStart, int indexEnd) {
|
||||||
if(AppController.isOnline() && getPSBT() == null && indexStart < getTransaction().getOutputs().size()) {
|
if(AppServices.isOnline() && getPSBT() == null && indexStart < getTransaction().getOutputs().size()) {
|
||||||
int maxIndex = Math.min(getTransaction().getOutputs().size(), indexEnd);
|
int maxIndex = Math.min(getTransaction().getOutputs().size(), indexEnd);
|
||||||
ElectrumServer.TransactionOutputsReferenceService transactionOutputsReferenceService = new ElectrumServer.TransactionOutputsReferenceService(getTransaction(), indexStart, maxIndex);
|
ElectrumServer.TransactionOutputsReferenceService transactionOutputsReferenceService = new ElectrumServer.TransactionOutputsReferenceService(getTransaction(), indexStart, maxIndex);
|
||||||
transactionOutputsReferenceService.setOnSucceeded(successEvent -> {
|
transactionOutputsReferenceService.setOnSucceeded(successEvent -> {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package com.sparrowwallet.sparrow.wallet;
|
package com.sparrowwallet.sparrow.wallet;
|
||||||
|
|
||||||
import com.sparrowwallet.drongo.wallet.Wallet;
|
import com.sparrowwallet.drongo.wallet.Wallet;
|
||||||
import com.sparrowwallet.sparrow.AppController;
|
import com.sparrowwallet.sparrow.AppServices;
|
||||||
import javafx.fxml.FXMLLoader;
|
import javafx.fxml.FXMLLoader;
|
||||||
import javafx.scene.control.ButtonBar;
|
import javafx.scene.control.ButtonBar;
|
||||||
import javafx.scene.control.ButtonType;
|
import javafx.scene.control.ButtonType;
|
||||||
|
@ -14,10 +14,10 @@ import java.io.IOException;
|
||||||
public class AdvancedDialog extends Dialog<Void> {
|
public class AdvancedDialog extends Dialog<Void> {
|
||||||
public AdvancedDialog(Wallet wallet) {
|
public AdvancedDialog(Wallet wallet) {
|
||||||
final DialogPane dialogPane = getDialogPane();
|
final DialogPane dialogPane = getDialogPane();
|
||||||
AppController.setStageIcon(dialogPane.getScene().getWindow());
|
AppServices.setStageIcon(dialogPane.getScene().getWindow());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
FXMLLoader advancedLoader = new FXMLLoader(AppController.class.getResource("wallet/advanced.fxml"));
|
FXMLLoader advancedLoader = new FXMLLoader(AppServices.class.getResource("wallet/advanced.fxml"));
|
||||||
dialogPane.setContent(Borders.wrap(advancedLoader.load()).emptyBorder().buildAll());
|
dialogPane.setContent(Borders.wrap(advancedLoader.load()).emptyBorder().buildAll());
|
||||||
AdvancedController settingsAdvancedController = advancedLoader.getController();
|
AdvancedController settingsAdvancedController = advancedLoader.getController();
|
||||||
settingsAdvancedController.initializeView(wallet);
|
settingsAdvancedController.initializeView(wallet);
|
||||||
|
|
|
@ -5,7 +5,7 @@ import com.sparrowwallet.drongo.*;
|
||||||
import com.sparrowwallet.drongo.wallet.Keystore;
|
import com.sparrowwallet.drongo.wallet.Keystore;
|
||||||
import com.sparrowwallet.drongo.wallet.KeystoreSource;
|
import com.sparrowwallet.drongo.wallet.KeystoreSource;
|
||||||
import com.sparrowwallet.drongo.wallet.Wallet;
|
import com.sparrowwallet.drongo.wallet.Wallet;
|
||||||
import com.sparrowwallet.sparrow.AppController;
|
import com.sparrowwallet.sparrow.AppServices;
|
||||||
import com.sparrowwallet.sparrow.EventManager;
|
import com.sparrowwallet.sparrow.EventManager;
|
||||||
import com.sparrowwallet.sparrow.control.QRDisplayDialog;
|
import com.sparrowwallet.sparrow.control.QRDisplayDialog;
|
||||||
import com.sparrowwallet.sparrow.control.QRScanDialog;
|
import com.sparrowwallet.sparrow.control.QRScanDialog;
|
||||||
|
@ -340,7 +340,7 @@ public class KeystoreController extends WalletFormController implements Initiali
|
||||||
});
|
});
|
||||||
decryptWalletService.setOnFailed(workerStateEvent -> {
|
decryptWalletService.setOnFailed(workerStateEvent -> {
|
||||||
EventManager.get().post(new StorageEvent(getWalletForm().getWalletFile(), TimedEvent.Action.END, "Failed"));
|
EventManager.get().post(new StorageEvent(getWalletForm().getWalletFile(), TimedEvent.Action.END, "Failed"));
|
||||||
AppController.showErrorDialog("Incorrect Password", decryptWalletService.getException().getMessage());
|
AppServices.showErrorDialog("Incorrect Password", decryptWalletService.getException().getMessage());
|
||||||
});
|
});
|
||||||
EventManager.get().post(new StorageEvent(getWalletForm().getWalletFile(), TimedEvent.Action.START, "Decrypting wallet..."));
|
EventManager.get().post(new StorageEvent(getWalletForm().getWalletFile(), TimedEvent.Action.START, "Decrypting wallet..."));
|
||||||
decryptWalletService.start();
|
decryptWalletService.start();
|
||||||
|
@ -364,9 +364,9 @@ public class KeystoreController extends WalletFormController implements Initiali
|
||||||
xpub.setText(result.extendedKey.getExtendedKey());
|
xpub.setText(result.extendedKey.getExtendedKey());
|
||||||
} else if(result.exception != null) {
|
} else if(result.exception != null) {
|
||||||
log.error("Error scanning QR", result.exception);
|
log.error("Error scanning QR", result.exception);
|
||||||
AppController.showErrorDialog("Error scanning QR", result.exception.getMessage());
|
AppServices.showErrorDialog("Error scanning QR", result.exception.getMessage());
|
||||||
} else {
|
} else {
|
||||||
AppController.showErrorDialog("Invalid QR Code", "QR Code did not contain a valid " + Network.get().getXpubHeader().getDisplayName());
|
AppServices.showErrorDialog("Invalid QR Code", "QR Code did not contain a valid " + Network.get().getXpubHeader().getDisplayName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ import com.sparrowwallet.drongo.uri.BitcoinURI;
|
||||||
import com.sparrowwallet.drongo.wallet.MaxUtxoSelector;
|
import com.sparrowwallet.drongo.wallet.MaxUtxoSelector;
|
||||||
import com.sparrowwallet.drongo.wallet.Payment;
|
import com.sparrowwallet.drongo.wallet.Payment;
|
||||||
import com.sparrowwallet.drongo.wallet.UtxoSelector;
|
import com.sparrowwallet.drongo.wallet.UtxoSelector;
|
||||||
import com.sparrowwallet.sparrow.AppController;
|
import com.sparrowwallet.sparrow.AppServices;
|
||||||
import com.sparrowwallet.sparrow.CurrencyRate;
|
import com.sparrowwallet.sparrow.CurrencyRate;
|
||||||
import com.sparrowwallet.sparrow.EventManager;
|
import com.sparrowwallet.sparrow.EventManager;
|
||||||
import com.sparrowwallet.sparrow.control.CoinTextFormatter;
|
import com.sparrowwallet.sparrow.control.CoinTextFormatter;
|
||||||
|
@ -74,7 +74,7 @@ public class PaymentController extends WalletFormController implements Initializ
|
||||||
|
|
||||||
Long recipientValueSats = getRecipientValueSats();
|
Long recipientValueSats = getRecipientValueSats();
|
||||||
if(recipientValueSats != null) {
|
if(recipientValueSats != null) {
|
||||||
setFiatAmount(AppController.getFiatCurrencyExchangeRate(), recipientValueSats);
|
setFiatAmount(AppServices.getFiatCurrencyExchangeRate(), recipientValueSats);
|
||||||
} else {
|
} else {
|
||||||
fiatAmount.setText("");
|
fiatAmount.setText("");
|
||||||
}
|
}
|
||||||
|
@ -260,7 +260,7 @@ public class PaymentController extends WalletFormController implements Initializ
|
||||||
label.setText(payment.getLabel());
|
label.setText(payment.getLabel());
|
||||||
}
|
}
|
||||||
setRecipientValueSats(payment.getAmount());
|
setRecipientValueSats(payment.getAmount());
|
||||||
setFiatAmount(AppController.getFiatCurrencyExchangeRate(), payment.getAmount());
|
setFiatAmount(AppServices.getFiatCurrencyExchangeRate(), payment.getAmount());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -320,7 +320,7 @@ public class PaymentController extends WalletFormController implements Initializ
|
||||||
setRecipientValueSats(bitcoinURI.getAmount());
|
setRecipientValueSats(bitcoinURI.getAmount());
|
||||||
}
|
}
|
||||||
if(bitcoinURI.getPayjoinUrl() != null) {
|
if(bitcoinURI.getPayjoinUrl() != null) {
|
||||||
AppController.addPayjoinURI(bitcoinURI);
|
AppServices.addPayjoinURI(bitcoinURI);
|
||||||
}
|
}
|
||||||
sendController.updateTransaction();
|
sendController.updateTransaction();
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ import com.sparrowwallet.drongo.wallet.BlockTransactionHashIndex;
|
||||||
import com.sparrowwallet.drongo.wallet.Keystore;
|
import com.sparrowwallet.drongo.wallet.Keystore;
|
||||||
import com.sparrowwallet.drongo.wallet.KeystoreSource;
|
import com.sparrowwallet.drongo.wallet.KeystoreSource;
|
||||||
import com.sparrowwallet.drongo.wallet.Wallet;
|
import com.sparrowwallet.drongo.wallet.Wallet;
|
||||||
import com.sparrowwallet.sparrow.AppController;
|
import com.sparrowwallet.sparrow.AppServices;
|
||||||
import com.sparrowwallet.sparrow.EventManager;
|
import com.sparrowwallet.sparrow.EventManager;
|
||||||
import com.sparrowwallet.sparrow.control.*;
|
import com.sparrowwallet.sparrow.control.*;
|
||||||
import com.sparrowwallet.sparrow.event.ReceiveToEvent;
|
import com.sparrowwallet.sparrow.event.ReceiveToEvent;
|
||||||
|
@ -116,7 +116,7 @@ public class ReceiveController extends WalletFormController implements Initializ
|
||||||
outputDescriptor.clear();
|
outputDescriptor.clear();
|
||||||
outputDescriptor.append(nodeEntry.getOutputDescriptor(), "descriptor-text");
|
outputDescriptor.append(nodeEntry.getOutputDescriptor(), "descriptor-text");
|
||||||
|
|
||||||
updateDisplayAddress(AppController.getDevices());
|
updateDisplayAddress(AppServices.getDevices());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateDerivationPath(NodeEntry nodeEntry) {
|
private void updateDerivationPath(NodeEntry nodeEntry) {
|
||||||
|
@ -138,7 +138,7 @@ public class ReceiveController extends WalletFormController implements Initializ
|
||||||
|
|
||||||
private void updateLastUsed() {
|
private void updateLastUsed() {
|
||||||
Set<BlockTransactionHashIndex> currentOutputs = currentEntry.getNode().getTransactionOutputs();
|
Set<BlockTransactionHashIndex> currentOutputs = currentEntry.getNode().getTransactionOutputs();
|
||||||
if(AppController.isOnline() && currentOutputs.isEmpty()) {
|
if(AppServices.isOnline() && currentOutputs.isEmpty()) {
|
||||||
lastUsed.setText("Never");
|
lastUsed.setText("Never");
|
||||||
lastUsed.setGraphic(getUnusedGlyph());
|
lastUsed.setGraphic(getUnusedGlyph());
|
||||||
} else if(!currentOutputs.isEmpty()) {
|
} else if(!currentOutputs.isEmpty()) {
|
||||||
|
|
|
@ -6,7 +6,7 @@ import com.sparrowwallet.drongo.address.InvalidAddressException;
|
||||||
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.*;
|
import com.sparrowwallet.drongo.wallet.*;
|
||||||
import com.sparrowwallet.sparrow.AppController;
|
import com.sparrowwallet.sparrow.AppServices;
|
||||||
import com.sparrowwallet.sparrow.CurrencyRate;
|
import com.sparrowwallet.sparrow.CurrencyRate;
|
||||||
import com.sparrowwallet.sparrow.EventManager;
|
import com.sparrowwallet.sparrow.EventManager;
|
||||||
import com.sparrowwallet.sparrow.control.*;
|
import com.sparrowwallet.sparrow.control.*;
|
||||||
|
@ -128,7 +128,7 @@ public class SendController extends WalletFormController implements Initializabl
|
||||||
if(newValue.isEmpty()) {
|
if(newValue.isEmpty()) {
|
||||||
fiatFeeAmount.setText("");
|
fiatFeeAmount.setText("");
|
||||||
} else {
|
} else {
|
||||||
setFiatFeeAmount(AppController.getFiatCurrencyExchangeRate(), getFeeValueSats());
|
setFiatFeeAmount(AppServices.getFiatCurrencyExchangeRate(), getFeeValueSats());
|
||||||
}
|
}
|
||||||
|
|
||||||
setTargetBlocks(getTargetBlocks());
|
setTargetBlocks(getTargetBlocks());
|
||||||
|
@ -390,7 +390,7 @@ public class SendController extends WalletFormController implements Initializabl
|
||||||
Tab tab = new Tab(Integer.toString(highestTabNo.isPresent() ? highestTabNo.getAsInt() + 1 : 1));
|
Tab tab = new Tab(Integer.toString(highestTabNo.isPresent() ? highestTabNo.getAsInt() + 1 : 1));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
FXMLLoader paymentLoader = new FXMLLoader(AppController.class.getResource("wallet/payment.fxml"));
|
FXMLLoader paymentLoader = new FXMLLoader(AppServices.class.getResource("wallet/payment.fxml"));
|
||||||
tab.setContent(paymentLoader.load());
|
tab.setContent(paymentLoader.load());
|
||||||
PaymentController controller = paymentLoader.getController();
|
PaymentController controller = paymentLoader.getController();
|
||||||
controller.setSendController(this);
|
controller.setSendController(this);
|
||||||
|
@ -451,7 +451,7 @@ public class SendController extends WalletFormController implements Initializabl
|
||||||
if(!userFeeSet.get() || (getFeeValueSats() != null && getFeeValueSats() > 0)) {
|
if(!userFeeSet.get() || (getFeeValueSats() != null && getFeeValueSats() > 0)) {
|
||||||
Wallet wallet = getWalletForm().getWallet();
|
Wallet wallet = getWalletForm().getWallet();
|
||||||
Long userFee = userFeeSet.get() ? getFeeValueSats() : null;
|
Long userFee = userFeeSet.get() ? getFeeValueSats() : null;
|
||||||
Integer currentBlockHeight = AppController.getCurrentBlockHeight();
|
Integer currentBlockHeight = AppServices.getCurrentBlockHeight();
|
||||||
boolean groupByAddress = Config.get().isGroupByAddress();
|
boolean groupByAddress = Config.get().isGroupByAddress();
|
||||||
boolean includeMempoolChange = Config.get().isIncludeMempoolChange();
|
boolean includeMempoolChange = Config.get().isIncludeMempoolChange();
|
||||||
boolean includeMempoolInputs = includeMempoolInputsProperty.get();
|
boolean includeMempoolInputs = includeMempoolInputsProperty.get();
|
||||||
|
@ -532,7 +532,7 @@ public class SendController extends WalletFormController implements Initializabl
|
||||||
df.setMaximumFractionDigits(8);
|
df.setMaximumFractionDigits(8);
|
||||||
fee.setText(df.format(feeAmountUnit.getValue().getValue(feeValue)));
|
fee.setText(df.format(feeAmountUnit.getValue().getValue(feeValue)));
|
||||||
fee.textProperty().addListener(feeListener);
|
fee.textProperty().addListener(feeListener);
|
||||||
setFiatFeeAmount(AppController.getFiatCurrencyExchangeRate(), feeValue);
|
setFiatFeeAmount(AppServices.getFiatCurrencyExchangeRate(), feeValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Integer getTargetBlocks() {
|
private Integer getTargetBlocks() {
|
||||||
|
@ -565,7 +565,7 @@ public class SendController extends WalletFormController implements Initializabl
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<Integer, Double> getTargetBlocksFeeRates() {
|
private Map<Integer, Double> getTargetBlocksFeeRates() {
|
||||||
Map<Integer, Double> retrievedFeeRates = AppController.getTargetBlockFeeRates();
|
Map<Integer, Double> retrievedFeeRates = AppServices.getTargetBlockFeeRates();
|
||||||
if(retrievedFeeRates == null) {
|
if(retrievedFeeRates == null) {
|
||||||
retrievedFeeRates = TARGET_BLOCKS_RANGE.stream().collect(Collectors.toMap(java.util.function.Function.identity(), v -> FALLBACK_FEE_RATE,
|
retrievedFeeRates = TARGET_BLOCKS_RANGE.stream().collect(Collectors.toMap(java.util.function.Function.identity(), v -> FALLBACK_FEE_RATE,
|
||||||
(u, v) -> { throw new IllegalStateException("Duplicate target blocks"); },
|
(u, v) -> { throw new IllegalStateException("Duplicate target blocks"); },
|
||||||
|
@ -600,11 +600,11 @@ public class SendController extends WalletFormController implements Initializabl
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<Date, Set<MempoolRateSize>> getMempoolHistogram() {
|
private Map<Date, Set<MempoolRateSize>> getMempoolHistogram() {
|
||||||
return AppController.getMempoolHistogram();
|
return AppServices.getMempoolHistogram();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isInsufficientFeeRate() {
|
public boolean isInsufficientFeeRate() {
|
||||||
return walletTransactionProperty.get() != null && walletTransactionProperty.get().getFeeRate() < AppController.getMinimumRelayFeeRate();
|
return walletTransactionProperty.get() != null && walletTransactionProperty.get().getFeeRate() < AppServices.getMinimumRelayFeeRate();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setFeeRate(Double feeRateAmt) {
|
private void setFeeRate(Double feeRateAmt) {
|
||||||
|
|
|
@ -11,7 +11,7 @@ import com.sparrowwallet.drongo.wallet.Keystore;
|
||||||
import com.sparrowwallet.drongo.wallet.KeystoreSource;
|
import com.sparrowwallet.drongo.wallet.KeystoreSource;
|
||||||
import com.sparrowwallet.drongo.wallet.Wallet;
|
import com.sparrowwallet.drongo.wallet.Wallet;
|
||||||
import com.sparrowwallet.drongo.wallet.WalletModel;
|
import com.sparrowwallet.drongo.wallet.WalletModel;
|
||||||
import com.sparrowwallet.sparrow.AppController;
|
import com.sparrowwallet.sparrow.AppServices;
|
||||||
import com.sparrowwallet.sparrow.EventManager;
|
import com.sparrowwallet.sparrow.EventManager;
|
||||||
import com.sparrowwallet.sparrow.control.*;
|
import com.sparrowwallet.sparrow.control.*;
|
||||||
import com.sparrowwallet.sparrow.event.RequestOpenWalletsEvent;
|
import com.sparrowwallet.sparrow.event.RequestOpenWalletsEvent;
|
||||||
|
@ -223,7 +223,7 @@ public class SettingsController extends WalletFormController implements Initiali
|
||||||
tab.setClosable(false);
|
tab.setClosable(false);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
FXMLLoader keystoreLoader = new FXMLLoader(AppController.class.getResource("wallet/keystore.fxml"));
|
FXMLLoader keystoreLoader = new FXMLLoader(AppServices.class.getResource("wallet/keystore.fxml"));
|
||||||
tab.setContent(keystoreLoader.load());
|
tab.setContent(keystoreLoader.load());
|
||||||
KeystoreController controller = keystoreLoader.getController();
|
KeystoreController controller = keystoreLoader.getController();
|
||||||
controller.setKeystore(getWalletForm(), keystore);
|
controller.setKeystore(getWalletForm(), keystore);
|
||||||
|
@ -258,7 +258,7 @@ public class SettingsController extends WalletFormController implements Initiali
|
||||||
} else if(result.payload != null && !result.payload.isEmpty()) {
|
} else if(result.payload != null && !result.payload.isEmpty()) {
|
||||||
setDescriptorText(result.payload);
|
setDescriptorText(result.payload);
|
||||||
} else if(result.exception != null) {
|
} else if(result.exception != null) {
|
||||||
AppController.showErrorDialog("Error scanning QR", result.exception.getMessage());
|
AppServices.showErrorDialog("Error scanning QR", result.exception.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -291,7 +291,7 @@ public class SettingsController extends WalletFormController implements Initiali
|
||||||
|
|
||||||
EventManager.get().post(new SettingsChangedEvent(editedWallet, SettingsChangedEvent.Type.POLICY));
|
EventManager.get().post(new SettingsChangedEvent(editedWallet, SettingsChangedEvent.Type.POLICY));
|
||||||
} catch(Exception e) {
|
} catch(Exception e) {
|
||||||
AppController.showErrorDialog("Invalid output descriptor", e.getMessage());
|
AppServices.showErrorDialog("Invalid output descriptor", e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -353,7 +353,7 @@ public class SettingsController extends WalletFormController implements Initiali
|
||||||
walletForm.saveBackup();
|
walletForm.saveBackup();
|
||||||
} catch(IOException e) {
|
} catch(IOException e) {
|
||||||
log.error("Error saving wallet backup", e);
|
log.error("Error saving wallet backup", e);
|
||||||
AppController.showErrorDialog("Error saving wallet backup", e.getMessage());
|
AppServices.showErrorDialog("Error saving wallet backup", e.getMessage());
|
||||||
revert.setDisable(false);
|
revert.setDisable(false);
|
||||||
apply.setDisable(false);
|
apply.setDisable(false);
|
||||||
return;
|
return;
|
||||||
|
@ -369,7 +369,7 @@ public class SettingsController extends WalletFormController implements Initiali
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
log.error("Error saving wallet", e);
|
log.error("Error saving wallet", e);
|
||||||
AppController.showErrorDialog("Error saving wallet", e.getMessage());
|
AppServices.showErrorDialog("Error saving wallet", e.getMessage());
|
||||||
revert.setDisable(false);
|
revert.setDisable(false);
|
||||||
apply.setDisable(false);
|
apply.setDisable(false);
|
||||||
}
|
}
|
||||||
|
@ -384,7 +384,7 @@ public class SettingsController extends WalletFormController implements Initiali
|
||||||
ECKey encryptionPubKey = ECKey.fromPublicOnly(encryptionFullKey);
|
ECKey encryptionPubKey = ECKey.fromPublicOnly(encryptionFullKey);
|
||||||
|
|
||||||
if(existingPubKey != null && !Storage.NO_PASSWORD_KEY.equals(existingPubKey) && !existingPubKey.equals(encryptionPubKey)) {
|
if(existingPubKey != null && !Storage.NO_PASSWORD_KEY.equals(existingPubKey) && !existingPubKey.equals(encryptionPubKey)) {
|
||||||
AppController.showErrorDialog("Incorrect Password", "The password was incorrect.");
|
AppServices.showErrorDialog("Incorrect Password", "The password was incorrect.");
|
||||||
revert.setDisable(false);
|
revert.setDisable(false);
|
||||||
apply.setDisable(false);
|
apply.setDisable(false);
|
||||||
return;
|
return;
|
||||||
|
@ -406,7 +406,7 @@ public class SettingsController extends WalletFormController implements Initiali
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("Error saving wallet", e);
|
log.error("Error saving wallet", e);
|
||||||
AppController.showErrorDialog("Error saving wallet", e.getMessage());
|
AppServices.showErrorDialog("Error saving wallet", e.getMessage());
|
||||||
revert.setDisable(false);
|
revert.setDisable(false);
|
||||||
apply.setDisable(false);
|
apply.setDisable(false);
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -418,7 +418,7 @@ public class SettingsController extends WalletFormController implements Initiali
|
||||||
});
|
});
|
||||||
keyDerivationService.setOnFailed(workerStateEvent -> {
|
keyDerivationService.setOnFailed(workerStateEvent -> {
|
||||||
EventManager.get().post(new StorageEvent(walletForm.getWalletFile(), TimedEvent.Action.END, "Failed"));
|
EventManager.get().post(new StorageEvent(walletForm.getWalletFile(), TimedEvent.Action.END, "Failed"));
|
||||||
AppController.showErrorDialog("Error saving wallet", keyDerivationService.getException().getMessage());
|
AppServices.showErrorDialog("Error saving wallet", keyDerivationService.getException().getMessage());
|
||||||
revert.setDisable(false);
|
revert.setDisable(false);
|
||||||
apply.setDisable(false);
|
apply.setDisable(false);
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package com.sparrowwallet.sparrow.wallet;
|
package com.sparrowwallet.sparrow.wallet;
|
||||||
|
|
||||||
import com.google.common.eventbus.Subscribe;
|
import com.google.common.eventbus.Subscribe;
|
||||||
import com.sparrowwallet.sparrow.AppController;
|
import com.sparrowwallet.sparrow.AppServices;
|
||||||
import com.sparrowwallet.sparrow.CurrencyRate;
|
import com.sparrowwallet.sparrow.CurrencyRate;
|
||||||
import com.sparrowwallet.sparrow.EventManager;
|
import com.sparrowwallet.sparrow.EventManager;
|
||||||
import com.sparrowwallet.sparrow.control.BalanceChart;
|
import com.sparrowwallet.sparrow.control.BalanceChart;
|
||||||
|
@ -47,7 +47,7 @@ public class TransactionsController extends WalletFormController implements Init
|
||||||
transactionsTable.initialize(walletTransactionsEntry);
|
transactionsTable.initialize(walletTransactionsEntry);
|
||||||
|
|
||||||
balance.valueProperty().addListener((observable, oldValue, newValue) -> {
|
balance.valueProperty().addListener((observable, oldValue, newValue) -> {
|
||||||
setFiatBalance(AppController.getFiatCurrencyExchangeRate(), newValue.longValue());
|
setFiatBalance(AppServices.getFiatCurrencyExchangeRate(), newValue.longValue());
|
||||||
});
|
});
|
||||||
balance.setValue(walletTransactionsEntry.getBalance());
|
balance.setValue(walletTransactionsEntry.getBalance());
|
||||||
mempoolBalance.setValue(walletTransactionsEntry.getMempoolBalance());
|
mempoolBalance.setValue(walletTransactionsEntry.getMempoolBalance());
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package com.sparrowwallet.sparrow.wallet;
|
package com.sparrowwallet.sparrow.wallet;
|
||||||
|
|
||||||
import com.google.common.eventbus.Subscribe;
|
import com.google.common.eventbus.Subscribe;
|
||||||
import com.sparrowwallet.sparrow.AppController;
|
import com.sparrowwallet.sparrow.AppServices;
|
||||||
import com.sparrowwallet.sparrow.EventManager;
|
import com.sparrowwallet.sparrow.EventManager;
|
||||||
import com.sparrowwallet.sparrow.event.ReceiveActionEvent;
|
import com.sparrowwallet.sparrow.event.ReceiveActionEvent;
|
||||||
import com.sparrowwallet.sparrow.event.SendActionEvent;
|
import com.sparrowwallet.sparrow.event.SendActionEvent;
|
||||||
|
@ -57,7 +57,7 @@ public class WalletController extends WalletFormController implements Initializa
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if(!existing) {
|
if(!existing) {
|
||||||
FXMLLoader functionLoader = new FXMLLoader(AppController.class.getResource("wallet/" + function.toString().toLowerCase() + ".fxml"));
|
FXMLLoader functionLoader = new FXMLLoader(AppServices.class.getResource("wallet/" + function.toString().toLowerCase() + ".fxml"));
|
||||||
Node walletFunction = functionLoader.load();
|
Node walletFunction = functionLoader.load();
|
||||||
walletFunction.setUserData(function);
|
walletFunction.setUserData(function);
|
||||||
WalletFormController controller = functionLoader.getController();
|
WalletFormController controller = functionLoader.getController();
|
||||||
|
|
|
@ -4,7 +4,7 @@ import com.google.common.eventbus.Subscribe;
|
||||||
import com.sparrowwallet.drongo.KeyPurpose;
|
import com.sparrowwallet.drongo.KeyPurpose;
|
||||||
import com.sparrowwallet.drongo.wallet.Wallet;
|
import com.sparrowwallet.drongo.wallet.Wallet;
|
||||||
import com.sparrowwallet.drongo.wallet.WalletNode;
|
import com.sparrowwallet.drongo.wallet.WalletNode;
|
||||||
import com.sparrowwallet.sparrow.AppController;
|
import com.sparrowwallet.sparrow.AppServices;
|
||||||
import com.sparrowwallet.sparrow.EventManager;
|
import com.sparrowwallet.sparrow.EventManager;
|
||||||
import com.sparrowwallet.sparrow.WalletTabData;
|
import com.sparrowwallet.sparrow.WalletTabData;
|
||||||
import com.sparrowwallet.sparrow.event.*;
|
import com.sparrowwallet.sparrow.event.*;
|
||||||
|
@ -32,7 +32,7 @@ public class WalletForm {
|
||||||
public WalletForm(Storage storage, Wallet currentWallet) {
|
public WalletForm(Storage storage, Wallet currentWallet) {
|
||||||
this.storage = storage;
|
this.storage = storage;
|
||||||
this.wallet = currentWallet;
|
this.wallet = currentWallet;
|
||||||
refreshHistory(AppController.getCurrentBlockHeight());
|
refreshHistory(AppServices.getCurrentBlockHeight());
|
||||||
}
|
}
|
||||||
|
|
||||||
public Wallet getWallet() {
|
public Wallet getWallet() {
|
||||||
|
@ -62,7 +62,7 @@ public class WalletForm {
|
||||||
public void saveAndRefresh() throws IOException {
|
public void saveAndRefresh() throws IOException {
|
||||||
wallet.clearHistory();
|
wallet.clearHistory();
|
||||||
save();
|
save();
|
||||||
refreshHistory(AppController.getCurrentBlockHeight());
|
refreshHistory(AppServices.getCurrentBlockHeight());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void saveBackup() throws IOException {
|
public void saveBackup() throws IOException {
|
||||||
|
@ -75,7 +75,7 @@ public class WalletForm {
|
||||||
|
|
||||||
public void refreshHistory(Integer blockHeight, WalletNode node) {
|
public void refreshHistory(Integer blockHeight, WalletNode node) {
|
||||||
Wallet previousWallet = wallet.copy();
|
Wallet previousWallet = wallet.copy();
|
||||||
if(wallet.isValid() && AppController.isOnline()) {
|
if(wallet.isValid() && AppServices.isOnline()) {
|
||||||
log.debug(node == null ? "Refreshing full wallet history" : "Requesting node wallet history for " + node.getDerivationPath());
|
log.debug(node == null ? "Refreshing full wallet history" : "Requesting node wallet history for " + node.getDerivationPath());
|
||||||
ElectrumServer.TransactionHistoryService historyService = new ElectrumServer.TransactionHistoryService(wallet, getWalletTransactionNodes(node));
|
ElectrumServer.TransactionHistoryService historyService = new ElectrumServer.TransactionHistoryService(wallet, getWalletTransactionNodes(node));
|
||||||
historyService.setOnSucceeded(workerStateEvent -> {
|
historyService.setOnSucceeded(workerStateEvent -> {
|
||||||
|
@ -226,7 +226,7 @@ public class WalletForm {
|
||||||
walletUtxosEntry = null;
|
walletUtxosEntry = null;
|
||||||
accountEntries.clear();
|
accountEntries.clear();
|
||||||
EventManager.get().post(new WalletNodesChangedEvent(wallet));
|
EventManager.get().post(new WalletNodesChangedEvent(wallet));
|
||||||
refreshHistory(AppController.getCurrentBlockHeight());
|
refreshHistory(AppServices.getCurrentBlockHeight());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,7 +249,7 @@ public class WalletForm {
|
||||||
WalletNode walletNode = event.getWalletNode(wallet);
|
WalletNode walletNode = event.getWalletNode(wallet);
|
||||||
if(walletNode != null) {
|
if(walletNode != null) {
|
||||||
log.debug(wallet.getName() + " history event for node " + walletNode);
|
log.debug(wallet.getName() + " history event for node " + walletNode);
|
||||||
refreshHistory(AppController.getCurrentBlockHeight(), walletNode);
|
refreshHistory(AppServices.getCurrentBlockHeight(), walletNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue