mirror of
https://github.com/sparrowwallet/sparrow.git
synced 2024-12-23 20:36:44 +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.SecureString;
|
||||
import com.sparrowwallet.drongo.Utils;
|
||||
import com.sparrowwallet.drongo.address.Address;
|
||||
import com.sparrowwallet.drongo.crypto.ECKey;
|
||||
import com.sparrowwallet.drongo.crypto.EncryptionType;
|
||||
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.PSBTInput;
|
||||
import com.sparrowwallet.drongo.psbt.PSBTParseException;
|
||||
import com.sparrowwallet.drongo.uri.BitcoinURI;
|
||||
import com.sparrowwallet.drongo.wallet.*;
|
||||
import com.sparrowwallet.sparrow.control.*;
|
||||
import com.sparrowwallet.sparrow.event.*;
|
||||
import com.sparrowwallet.sparrow.io.*;
|
||||
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.transaction.TransactionController;
|
||||
import com.sparrowwallet.sparrow.transaction.TransactionData;
|
||||
|
@ -37,10 +32,7 @@ import com.sparrowwallet.sparrow.wallet.WalletForm;
|
|||
import de.codecentric.centerdevice.MenuToolkit;
|
||||
import javafx.animation.*;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.collections.ListChangeListener;
|
||||
import javafx.concurrent.Worker;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
|
@ -55,7 +47,6 @@ import javafx.scene.image.ImageView;
|
|||
import javafx.scene.input.Dragboard;
|
||||
import javafx.scene.input.TransferMode;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import javafx.scene.text.Font;
|
||||
import javafx.stage.FileChooser;
|
||||
import javafx.stage.Stage;
|
||||
import javafx.stage.StageStyle;
|
||||
|
@ -70,27 +61,17 @@ import java.io.*;
|
|||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.text.ParseException;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.sparrowwallet.sparrow.AppServices.*;
|
||||
|
||||
public class AppController implements Initializable {
|
||||
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";
|
||||
|
||||
private MainApp application;
|
||||
|
||||
@FXML
|
||||
private MenuItem saveTransaction;
|
||||
|
||||
|
@ -127,35 +108,8 @@ public class AppController implements Initializable {
|
|||
@FXML
|
||||
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 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
|
||||
public void initialize(URL location, ResourceBundle resources) {
|
||||
EventManager.get().register(this);
|
||||
|
@ -258,152 +212,12 @@ public class AppController implements Initializable {
|
|||
showTxHex.setSelected(Config.get().isShowTransactionHex());
|
||||
exportWallet.setDisable(true);
|
||||
|
||||
serverToggle.selectedProperty().addListener((observable, oldValue, newValue) -> {
|
||||
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().bindBidirectional(serverToggle.selectedProperty());
|
||||
onlineProperty().addListener((observable, oldValue, newValue) -> {
|
||||
Platform.runLater(this::setServerToggleTooltip);
|
||||
Platform.runLater(() -> setServerToggleTooltip(getCurrentBlockHeight()));
|
||||
});
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
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;
|
||||
openTransactionIdItem.disableProperty().bind(onlineProperty().not());
|
||||
}
|
||||
|
||||
private void setOsxApplicationMenu() {
|
||||
|
@ -577,7 +391,7 @@ public class AppController implements Initializable {
|
|||
log.error("Error scanning QR", result.exception);
|
||||
showErrorDialog("Error scanning QR", result.exception.getMessage());
|
||||
} 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) {
|
||||
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() {
|
||||
Map<Wallet, Storage> openWallets = new LinkedHashMap<>();
|
||||
|
||||
|
@ -704,28 +460,6 @@ public class AppController implements Initializable {
|
|||
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) {
|
||||
for(Tab tab : tabs.getTabs()) {
|
||||
|
@ -745,7 +479,7 @@ public class AppController implements Initializable {
|
|||
|
||||
public void quit(ActionEvent event) {
|
||||
try {
|
||||
application.stop();
|
||||
AppServices.get().getApplication().stop();
|
||||
} catch (Exception 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);
|
||||
}
|
||||
|
||||
private void setServerToggleTooltip() {
|
||||
serverToggle.setTooltip(new Tooltip(isOnline() ? "Connected to " + Config.get().getElectrumServer() + (getCurrentBlockHeight() != null ? " at height " + getCurrentBlockHeight() : "") : "Disconnected"));
|
||||
private void setServerToggleTooltip(Integer currentBlockHeight) {
|
||||
serverToggle.setTooltip(new Tooltip(AppServices.isOnline() ? "Connected to " + Config.get().getElectrumServer() + (currentBlockHeight != null ? " at height " + currentBlockHeight : "") : "Disconnected"));
|
||||
}
|
||||
|
||||
public void newWallet(ActionEvent event) {
|
||||
|
@ -1266,6 +1000,7 @@ public class AppController implements Initializable {
|
|||
|
||||
@Subscribe
|
||||
public void tabSelected(TabSelectedEvent event) {
|
||||
//TODO: Handle multiple windows
|
||||
String tabName = event.getTabName();
|
||||
if(tabs.getScene() != null) {
|
||||
Stage tabStage = (Stage)tabs.getScene().getWindow();
|
||||
|
@ -1304,11 +1039,13 @@ public class AppController implements Initializable {
|
|||
|
||||
@Subscribe
|
||||
public void walletSettingsChanged(WalletSettingsChangedEvent event) {
|
||||
//TODO: Handle multiple windows
|
||||
exportWallet.setDisable(!event.getWallet().isValid());
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void newWalletTransactions(NewWalletTransactionsEvent event) {
|
||||
//TODO: Handle multiple windows
|
||||
if(Config.get().isNotifyNewTransactions()) {
|
||||
String text;
|
||||
if(event.getBlockTransactions().size() == 1) {
|
||||
|
@ -1380,7 +1117,7 @@ public class AppController implements Initializable {
|
|||
public void versionUpdated(VersionUpdatedEvent event) {
|
||||
Hyperlink versionUpdateLabel = new Hyperlink("Sparrow " + event.getVersion() + " available");
|
||||
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) {
|
||||
|
@ -1417,8 +1154,6 @@ public class AppController implements Initializable {
|
|||
|
||||
@Subscribe
|
||||
public void usbDevicesFound(UsbDeviceEvent event) {
|
||||
devices = Collections.unmodifiableList(event.getDevices());
|
||||
|
||||
UsbStatusButton usbStatus = null;
|
||||
for(Node node : statusBar.getRightItems()) {
|
||||
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
|
||||
public void newBlock(NewBlockEvent event) {
|
||||
currentBlockHeight = 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());
|
||||
setServerToggleTooltip(event.getHeight());
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void viewTransaction(ViewTransactionEvent event) {
|
||||
//TODO: Handle multiple windows
|
||||
Tab tab = addTransactionTab(event.getBlockTransaction(), event.getInitialView(), event.getInitialIndex());
|
||||
tabs.getSelectionModel().select(tab);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void viewPSBT(ViewPSBTEvent event) {
|
||||
//TODO: Handle multiple windows
|
||||
Tab tab = addTransactionTab(event.getLabel(), event.getPsbt());
|
||||
tabs.getSelectionModel().select(tab);
|
||||
}
|
||||
|
@ -1492,102 +1202,27 @@ public class AppController implements Initializable {
|
|||
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
|
||||
public void requestOpenWallets(RequestOpenWalletsEvent event) {
|
||||
//TODO: Handle multiple windows
|
||||
EventManager.get().post(new OpenWalletsEvent(getOpenWallets()));
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void requestWalletOpen(RequestWalletOpenEvent event) {
|
||||
//TODO: Handle multiple windows
|
||||
openWallet(null);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void requestTransactionOpen(RequestTransactionOpenEvent event) {
|
||||
//TODO: Handle multiple windows
|
||||
openTransactionFromFile(null);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void requestQRScan(RequestQRScanEvent event) {
|
||||
//TODO: Handle multiple windows
|
||||
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 FontAwesome5Brands());
|
||||
Font.loadFont(AppController.class.getResourceAsStream("/font/RobotoMono-Regular.ttf"), 13);
|
||||
Font.loadFont(AppServices.class.getResourceAsStream("/font/RobotoMono-Regular.ttf"), 13);
|
||||
|
||||
boolean createNewWallet = false;
|
||||
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"));
|
||||
Parent root = transactionLoader.load();
|
||||
AppController appController = transactionLoader.getController();
|
||||
appController.setApplication(this);
|
||||
|
||||
Scene scene = new Scene(root);
|
||||
scene.getStylesheets().add(getClass().getResource("app.css").toExternalForm());
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package com.sparrowwallet.sparrow.control;
|
||||
|
||||
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.event.ReceiveActionEvent;
|
||||
import com.sparrowwallet.sparrow.event.ReceiveToEvent;
|
||||
|
@ -33,7 +33,7 @@ public class AddressTreeTable extends CoinTreeTable {
|
|||
getColumns().add(addressCol);
|
||||
|
||||
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");
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package com.sparrowwallet.sparrow.control;
|
||||
|
||||
import com.sparrowwallet.sparrow.AppController;
|
||||
import com.sparrowwallet.sparrow.AppServices;
|
||||
import com.sparrowwallet.sparrow.EventManager;
|
||||
import com.sparrowwallet.sparrow.event.UsbDeviceEvent;
|
||||
import com.sparrowwallet.sparrow.glyphfont.FontAwesome5Brands;
|
||||
|
@ -33,8 +33,8 @@ public abstract class DeviceDialog<R> extends Dialog<R> {
|
|||
this.operationFingerprints = operationFingerprints;
|
||||
|
||||
final DialogPane dialogPane = getDialogPane();
|
||||
dialogPane.getStylesheets().add(AppController.class.getResource("general.css").toExternalForm());
|
||||
AppController.setStageIcon(dialogPane.getScene().getWindow());
|
||||
dialogPane.getStylesheets().add(AppServices.class.getResource("general.css").toExternalForm());
|
||||
AppServices.setStageIcon(dialogPane.getScene().getWindow());
|
||||
|
||||
StackPane stackPane = new StackPane();
|
||||
dialogPane.setContent(stackPane);
|
||||
|
@ -67,7 +67,7 @@ public abstract class DeviceDialog<R> extends Dialog<R> {
|
|||
|
||||
stackPane.getChildren().addAll(anchorPane, scanBox);
|
||||
|
||||
List<Device> devices = AppController.getDevices();
|
||||
List<Device> devices = AppServices.getDevices();
|
||||
if(devices == null || devices.isEmpty()) {
|
||||
scanBox.setVisible(true);
|
||||
} else {
|
||||
|
|
|
@ -5,7 +5,7 @@ import com.sparrowwallet.drongo.address.Address;
|
|||
import com.sparrowwallet.drongo.protocol.Transaction;
|
||||
import com.sparrowwallet.drongo.protocol.TransactionOutput;
|
||||
import com.sparrowwallet.drongo.wallet.*;
|
||||
import com.sparrowwallet.sparrow.AppController;
|
||||
import com.sparrowwallet.sparrow.AppServices;
|
||||
import com.sparrowwallet.sparrow.EventManager;
|
||||
import com.sparrowwallet.sparrow.event.*;
|
||||
import com.sparrowwallet.sparrow.glyphfont.FontAwesome5;
|
||||
|
@ -202,11 +202,11 @@ class EntryCell extends TreeTableCell<Entry, Entry> {
|
|||
}
|
||||
|
||||
private static Double getMaxFeeRate() {
|
||||
if(AppController.getTargetBlockFeeRates().isEmpty()) {
|
||||
if(AppServices.getTargetBlockFeeRates().isEmpty()) {
|
||||
return 100.0;
|
||||
}
|
||||
|
||||
return AppController.getTargetBlockFeeRates().values().iterator().next();
|
||||
return AppServices.getTargetBlockFeeRates().values().iterator().next();
|
||||
}
|
||||
|
||||
private static void sendSelectedUtxos(TreeTableView<Entry> treeTableView, HashIndexEntry hashIndexEntry) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package com.sparrowwallet.sparrow.control;
|
||||
|
||||
import com.sparrowwallet.sparrow.AppController;
|
||||
import com.sparrowwallet.sparrow.AppServices;
|
||||
|
||||
public class IdLabel extends CopyableLabel {
|
||||
public IdLabel() {
|
||||
|
@ -9,6 +9,6 @@ public class IdLabel extends CopyableLabel {
|
|||
|
||||
public IdLabel(String text) {
|
||||
super(text);
|
||||
setFont(AppController.getMonospaceFont());
|
||||
setFont(AppServices.getMonospaceFont());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package com.sparrowwallet.sparrow.control;
|
||||
|
||||
import com.sparrowwallet.drongo.wallet.Keystore;
|
||||
import com.sparrowwallet.sparrow.AppController;
|
||||
import com.sparrowwallet.sparrow.AppServices;
|
||||
import com.sparrowwallet.sparrow.glyphfont.FontAwesome5;
|
||||
import javafx.application.Platform;
|
||||
import javafx.scene.control.ButtonType;
|
||||
|
@ -25,8 +25,8 @@ public class KeystorePassphraseDialog extends Dialog<String> {
|
|||
final DialogPane dialogPane = getDialogPane();
|
||||
setTitle("Keystore Passphrase" + (walletName != null ? " - " + walletName : ""));
|
||||
dialogPane.setHeaderText("Please enter the passphrase for keystore: \n" + keystore.getLabel());
|
||||
dialogPane.getStylesheets().add(AppController.class.getResource("general.css").toExternalForm());
|
||||
AppController.setStageIcon(dialogPane.getScene().getWindow());
|
||||
dialogPane.getStylesheets().add(AppServices.class.getResource("general.css").toExternalForm());
|
||||
AppServices.setStageIcon(dialogPane.getScene().getWindow());
|
||||
dialogPane.getButtonTypes().addAll(ButtonType.CANCEL, ButtonType.OK);
|
||||
dialogPane.setPrefWidth(380);
|
||||
dialogPane.setPrefHeight(200);
|
||||
|
|
|
@ -12,7 +12,7 @@ import com.sparrowwallet.drongo.wallet.Keystore;
|
|||
import com.sparrowwallet.drongo.wallet.KeystoreSource;
|
||||
import com.sparrowwallet.drongo.wallet.Wallet;
|
||||
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.event.OpenWalletsEvent;
|
||||
import com.sparrowwallet.sparrow.event.RequestOpenWalletsEvent;
|
||||
|
@ -37,8 +37,6 @@ import java.security.SignatureException;
|
|||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import static com.sparrowwallet.sparrow.AppController.setStageIcon;
|
||||
|
||||
public class MessageSignDialog extends Dialog<ButtonBar.ButtonData> {
|
||||
private static final Logger log = LoggerFactory.getLogger(MessageSignDialog.class);
|
||||
|
||||
|
@ -84,8 +82,8 @@ public class MessageSignDialog extends Dialog<ButtonBar.ButtonData> {
|
|||
this.walletNode = walletNode;
|
||||
|
||||
final DialogPane dialogPane = getDialogPane();
|
||||
dialogPane.getStylesheets().add(AppController.class.getResource("general.css").toExternalForm());
|
||||
AppController.setStageIcon(dialogPane.getScene().getWindow());
|
||||
dialogPane.getStylesheets().add(AppServices.class.getResource("general.css").toExternalForm());
|
||||
AppServices.setStageIcon(dialogPane.getScene().getWindow());
|
||||
dialogPane.setHeaderText(wallet == null ? "Verify Message" : "Sign/Verify Message");
|
||||
|
||||
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() {
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -234,7 +232,7 @@ public class MessageSignDialog extends Dialog<ButtonBar.ButtonData> {
|
|||
signature.appendText(signatureText);
|
||||
} catch(Exception 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) {
|
||||
Alert alert = new Alert(Alert.AlertType.INFORMATION);
|
||||
setStageIcon(alert.getDialogPane().getScene().getWindow());
|
||||
AppServices.setStageIcon(alert.getDialogPane().getScene().getWindow());
|
||||
alert.setTitle("Verification Succeeded");
|
||||
alert.setHeaderText("Verification Succeeded");
|
||||
alert.setContentText("The signature verified against the message.");
|
||||
alert.showAndWait();
|
||||
} 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) {
|
||||
AppController.showErrorDialog("Could not verify message", e.getMessage());
|
||||
AppServices.showErrorDialog("Could not verify message", e.getMessage());
|
||||
} catch(Exception 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 -> {
|
||||
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..."));
|
||||
decryptWalletService.start();
|
||||
|
|
|
@ -7,7 +7,7 @@ import com.google.zxing.common.BitMatrix;
|
|||
import com.google.zxing.qrcode.QRCodeWriter;
|
||||
import com.sparrowwallet.hummingbird.LegacyUREncoder;
|
||||
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.io.ImportException;
|
||||
import com.sparrowwallet.hummingbird.UR;
|
||||
|
@ -63,7 +63,7 @@ public class QRDisplayDialog extends Dialog<UR> {
|
|||
|
||||
final DialogPane dialogPane = new QRDisplayDialogPane();
|
||||
setDialogPane(dialogPane);
|
||||
AppController.setStageIcon(dialogPane.getScene().getWindow());
|
||||
AppServices.setStageIcon(dialogPane.getScene().getWindow());
|
||||
|
||||
StackPane stackPane = new StackPane();
|
||||
qrImageView = new ImageView();
|
||||
|
@ -102,7 +102,7 @@ public class QRDisplayDialog extends Dialog<UR> {
|
|||
this.encoder = null;
|
||||
|
||||
final DialogPane dialogPane = getDialogPane();
|
||||
AppController.setStageIcon(dialogPane.getScene().getWindow());
|
||||
AppServices.setStageIcon(dialogPane.getScene().getWindow());
|
||||
|
||||
StackPane stackPane = new StackPane();
|
||||
qrImageView = new ImageView();
|
||||
|
|
|
@ -19,10 +19,10 @@ import com.sparrowwallet.drongo.wallet.Keystore;
|
|||
import com.sparrowwallet.drongo.wallet.Wallet;
|
||||
import com.sparrowwallet.hummingbird.LegacyURDecoder;
|
||||
import com.sparrowwallet.hummingbird.registry.*;
|
||||
import com.sparrowwallet.sparrow.AppController;
|
||||
import com.sparrowwallet.hummingbird.ResultType;
|
||||
import com.sparrowwallet.hummingbird.UR;
|
||||
import com.sparrowwallet.hummingbird.URDecoder;
|
||||
import com.sparrowwallet.sparrow.AppServices;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
|
@ -66,7 +66,7 @@ public class QRScanDialog extends Dialog<QRScanDialog.Result> {
|
|||
WebcamView webcamView = new WebcamView(webcamService);
|
||||
|
||||
final DialogPane dialogPane = getDialogPane();
|
||||
AppController.setStageIcon(dialogPane.getScene().getWindow());
|
||||
AppServices.setStageIcon(dialogPane.getScene().getWindow());
|
||||
|
||||
StackPane stackPane = new StackPane();
|
||||
stackPane.getChildren().add(webcamView.getView());
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package com.sparrowwallet.sparrow.control;
|
||||
|
||||
import com.sparrowwallet.drongo.wallet.Keystore;
|
||||
import com.sparrowwallet.sparrow.AppController;
|
||||
import com.sparrowwallet.sparrow.AppServices;
|
||||
import javafx.application.Platform;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
|
@ -10,8 +10,8 @@ import javafx.scene.layout.StackPane;
|
|||
public class SeedDisplayDialog extends Dialog<Void> {
|
||||
public SeedDisplayDialog(Keystore decryptedKeystore) {
|
||||
final DialogPane dialogPane = getDialogPane();
|
||||
dialogPane.getStylesheets().add(AppController.class.getResource("general.css").toExternalForm());
|
||||
AppController.setStageIcon(dialogPane.getScene().getWindow());
|
||||
dialogPane.getStylesheets().add(AppServices.class.getResource("general.css").toExternalForm());
|
||||
AppServices.setStageIcon(dialogPane.getScene().getWindow());
|
||||
|
||||
int lines = decryptedKeystore.getSeed().getMnemonicCode().size() / 3;
|
||||
int height = lines * 40;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package com.sparrowwallet.sparrow.control;
|
||||
|
||||
import com.sparrowwallet.sparrow.AppController;
|
||||
import com.sparrowwallet.sparrow.AppServices;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.NamedArg;
|
||||
import javafx.scene.control.*;
|
||||
|
@ -29,8 +29,8 @@ public class TextAreaDialog extends Dialog<String> {
|
|||
this.defaultValue = defaultValue;
|
||||
|
||||
dialogPane.setContent(hbox);
|
||||
dialogPane.getStylesheets().add(AppController.class.getResource("general.css").toExternalForm());
|
||||
AppController.setStageIcon(dialogPane.getScene().getWindow());
|
||||
dialogPane.getStylesheets().add(AppServices.class.getResource("general.css").toExternalForm());
|
||||
AppServices.setStageIcon(dialogPane.getScene().getWindow());
|
||||
|
||||
dialogPane.getStyleClass().add("text-input-dialog");
|
||||
dialogPane.getButtonTypes().addAll(ButtonType.OK, ButtonType.CANCEL);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package com.sparrowwallet.sparrow.control;
|
||||
|
||||
import com.sparrowwallet.sparrow.AppController;
|
||||
import com.sparrowwallet.sparrow.AppServices;
|
||||
import javafx.application.Platform;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.geometry.Pos;
|
||||
|
@ -21,7 +21,7 @@ public class TitledDescriptionPane extends TitledPane {
|
|||
protected HBox buttonBox;
|
||||
|
||||
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");
|
||||
|
||||
setPadding(Insets.EMPTY);
|
||||
|
|
|
@ -7,7 +7,7 @@ import com.sparrowwallet.drongo.wallet.BlockTransactionHashIndex;
|
|||
import com.sparrowwallet.drongo.wallet.Payment;
|
||||
import com.sparrowwallet.drongo.wallet.WalletNode;
|
||||
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.event.ExcludeUtxoEvent;
|
||||
import com.sparrowwallet.sparrow.glyphfont.FontAwesome5;
|
||||
|
@ -103,7 +103,7 @@ public class TransactionDiagram extends GridPane {
|
|||
for(Payment payment : walletTx.getPayments()) {
|
||||
try {
|
||||
Address address = payment.getAddress();
|
||||
BitcoinURI bitcoinURI = AppController.getPayjoinURI(address);
|
||||
BitcoinURI bitcoinURI = AppServices.getPayjoinURI(address);
|
||||
if(bitcoinURI != null) {
|
||||
return bitcoinURI;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ package com.sparrowwallet.sparrow.control;
|
|||
|
||||
import com.sparrowwallet.drongo.Utils;
|
||||
import com.sparrowwallet.drongo.protocol.Sha256Hash;
|
||||
import com.sparrowwallet.sparrow.AppController;
|
||||
import com.sparrowwallet.sparrow.AppServices;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.binding.BooleanBinding;
|
||||
|
@ -23,13 +23,13 @@ public class TransactionIdDialog extends Dialog<Sha256Hash> {
|
|||
|
||||
public TransactionIdDialog() {
|
||||
this.txid = (CustomTextField) TextFields.createClearableTextField();
|
||||
txid.setFont(AppController.getMonospaceFont());
|
||||
txid.setFont(AppServices.getMonospaceFont());
|
||||
final DialogPane dialogPane = getDialogPane();
|
||||
AppController.setStageIcon(dialogPane.getScene().getWindow());
|
||||
AppServices.setStageIcon(dialogPane.getScene().getWindow());
|
||||
|
||||
setTitle("Load Transaction");
|
||||
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.setPrefWidth(550);
|
||||
dialogPane.setPrefHeight(200);
|
||||
|
|
|
@ -3,7 +3,7 @@ package com.sparrowwallet.sparrow.control;
|
|||
import com.google.common.eventbus.Subscribe;
|
||||
import com.sparrowwallet.drongo.policy.PolicyType;
|
||||
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.event.WalletExportEvent;
|
||||
import com.sparrowwallet.sparrow.io.*;
|
||||
|
@ -23,7 +23,7 @@ public class WalletExportDialog extends Dialog<Wallet> {
|
|||
});
|
||||
|
||||
final DialogPane dialogPane = getDialogPane();
|
||||
AppController.setStageIcon(dialogPane.getScene().getWindow());
|
||||
AppServices.setStageIcon(dialogPane.getScene().getWindow());
|
||||
|
||||
StackPane stackPane = new StackPane();
|
||||
dialogPane.setContent(stackPane);
|
||||
|
|
|
@ -2,7 +2,7 @@ package com.sparrowwallet.sparrow.control;
|
|||
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
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.event.WalletImportEvent;
|
||||
import com.sparrowwallet.sparrow.io.*;
|
||||
|
@ -22,7 +22,7 @@ public class WalletImportDialog extends Dialog<Wallet> {
|
|||
});
|
||||
|
||||
final DialogPane dialogPane = getDialogPane();
|
||||
AppController.setStageIcon(dialogPane.getScene().getWindow());
|
||||
AppServices.setStageIcon(dialogPane.getScene().getWindow());
|
||||
|
||||
StackPane stackPane = new StackPane();
|
||||
dialogPane.setContent(stackPane);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
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.io.Storage;
|
||||
import javafx.application.Platform;
|
||||
|
@ -22,11 +22,11 @@ public class WalletNameDialog extends Dialog<String> {
|
|||
public WalletNameDialog() {
|
||||
this.name = (CustomTextField)TextFields.createClearableTextField();
|
||||
final DialogPane dialogPane = getDialogPane();
|
||||
AppController.setStageIcon(dialogPane.getScene().getWindow());
|
||||
AppServices.setStageIcon(dialogPane.getScene().getWindow());
|
||||
|
||||
setTitle("Wallet Name");
|
||||
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.setPrefWidth(380);
|
||||
dialogPane.setPrefHeight(200);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package com.sparrowwallet.sparrow.control;
|
||||
|
||||
import com.sparrowwallet.drongo.SecureString;
|
||||
import com.sparrowwallet.sparrow.AppController;
|
||||
import com.sparrowwallet.sparrow.AppServices;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.binding.BooleanBinding;
|
||||
|
@ -37,8 +37,8 @@ public class WalletPasswordDialog extends Dialog<SecureString> {
|
|||
final DialogPane dialogPane = getDialogPane();
|
||||
setTitle("Wallet Password" + (walletName != null ? " - " + walletName : ""));
|
||||
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());
|
||||
AppController.setStageIcon(dialogPane.getScene().getWindow());
|
||||
dialogPane.getStylesheets().add(AppServices.class.getResource("general.css").toExternalForm());
|
||||
AppServices.setStageIcon(dialogPane.getScene().getWindow());
|
||||
dialogPane.getButtonTypes().addAll(ButtonType.CANCEL);
|
||||
dialogPane.setPrefWidth(380);
|
||||
dialogPane.setPrefHeight(260);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package com.sparrowwallet.sparrow.control;
|
||||
|
||||
import com.sparrowwallet.sparrow.AppController;
|
||||
import com.sparrowwallet.sparrow.AppServices;
|
||||
import com.sparrowwallet.sparrow.Mode;
|
||||
import javafx.application.HostServices;
|
||||
import javafx.geometry.Insets;
|
||||
|
@ -27,8 +27,8 @@ public class WelcomeDialog extends Dialog<Mode> {
|
|||
|
||||
setTitle("Welcome to Sparrow");
|
||||
dialogPane.setHeaderText("Welcome to Sparrow!");
|
||||
dialogPane.getStylesheets().add(AppController.class.getResource("general.css").toExternalForm());
|
||||
AppController.setStageIcon(dialogPane.getScene().getWindow());
|
||||
dialogPane.getStylesheets().add(AppServices.class.getResource("general.css").toExternalForm());
|
||||
AppServices.setStageIcon(dialogPane.getScene().getWindow());
|
||||
dialogPane.setPrefWidth(600);
|
||||
dialogPane.setPrefHeight(480);
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ package com.sparrowwallet.sparrow.keystoreimport;
|
|||
|
||||
import com.sparrowwallet.drongo.wallet.KeystoreSource;
|
||||
import com.sparrowwallet.drongo.wallet.Wallet;
|
||||
import com.sparrowwallet.sparrow.AppController;
|
||||
import com.sparrowwallet.sparrow.AppServices;
|
||||
import com.sparrowwallet.sparrow.io.Device;
|
||||
import javafx.application.Platform;
|
||||
import javafx.fxml.FXML;
|
||||
|
@ -84,7 +84,7 @@ public class KeystoreImportController implements Initializable {
|
|||
importPane.getChildren().removeAll(importPane.getChildren());
|
||||
|
||||
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();
|
||||
KeystoreImportDetailController controller = importLoader.getController();
|
||||
controller.setMasterController(this);
|
||||
|
|
|
@ -7,7 +7,7 @@ import com.sparrowwallet.drongo.wallet.Keystore;
|
|||
import com.sparrowwallet.drongo.wallet.KeystoreSource;
|
||||
import com.sparrowwallet.drongo.wallet.Wallet;
|
||||
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.event.KeystoreImportEvent;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
|
@ -32,10 +32,10 @@ public class KeystoreImportDialog extends Dialog<Keystore> {
|
|||
});
|
||||
|
||||
final DialogPane dialogPane = getDialogPane();
|
||||
AppController.setStageIcon(dialogPane.getScene().getWindow());
|
||||
AppServices.setStageIcon(dialogPane.getScene().getWindow());
|
||||
|
||||
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());
|
||||
keystoreImportController = ksiLoader.getController();
|
||||
keystoreImportController.initializeView(wallet);
|
||||
|
|
|
@ -7,7 +7,7 @@ import com.sparrowwallet.drongo.Utils;
|
|||
import com.sparrowwallet.drongo.protocol.Sha256Hash;
|
||||
import com.sparrowwallet.drongo.protocol.Transaction;
|
||||
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.event.WalletHistoryStatusEvent;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -209,7 +209,7 @@ public class SimpleElectrumServerRpc implements ElectrumServerRpc {
|
|||
VerboseTransaction verboseTransaction = new VerboseTransaction();
|
||||
verboseTransaction.txid = id;
|
||||
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();
|
||||
result.put(txid, verboseTransaction);
|
||||
} catch(Exception ex) {
|
||||
|
|
|
@ -5,7 +5,7 @@ import com.sparrowwallet.drongo.Utils;
|
|||
import com.sparrowwallet.drongo.protocol.Sha256Hash;
|
||||
import com.sparrowwallet.drongo.protocol.Transaction;
|
||||
import com.sparrowwallet.drongo.wallet.BlockTransaction;
|
||||
import com.sparrowwallet.sparrow.AppController;
|
||||
import com.sparrowwallet.sparrow.AppServices;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
|
@ -26,7 +26,7 @@ class VerboseTransaction {
|
|||
return 0;
|
||||
}
|
||||
|
||||
Integer currentHeight = AppController.getCurrentBlockHeight();
|
||||
Integer currentHeight = AppServices.getCurrentBlockHeight();
|
||||
if(currentHeight != null) {
|
||||
return currentHeight - confirmations + 1;
|
||||
}
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
package com.sparrowwallet.sparrow.preferences;
|
||||
|
||||
import com.sparrowwallet.drongo.wallet.KeystoreSource;
|
||||
import com.sparrowwallet.drongo.wallet.Wallet;
|
||||
import com.sparrowwallet.sparrow.AppController;
|
||||
import com.sparrowwallet.sparrow.AppServices;
|
||||
import com.sparrowwallet.sparrow.io.Config;
|
||||
import com.sparrowwallet.sparrow.keystoreimport.KeystoreImportDetailController;
|
||||
import javafx.application.Platform;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
|
@ -63,7 +60,7 @@ public class PreferencesController implements Initializable {
|
|||
preferencesPane.getChildren().removeAll(preferencesPane.getChildren());
|
||||
|
||||
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();
|
||||
PreferencesDetailController controller = preferencesDetailLoader.getController();
|
||||
controller.setMasterController(this);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package com.sparrowwallet.sparrow.preferences;
|
||||
|
||||
import com.sparrowwallet.sparrow.AppController;
|
||||
import com.sparrowwallet.sparrow.AppServices;
|
||||
import com.sparrowwallet.sparrow.EventManager;
|
||||
import com.sparrowwallet.sparrow.event.RequestConnectEvent;
|
||||
import com.sparrowwallet.sparrow.io.Config;
|
||||
|
@ -27,10 +27,10 @@ public class PreferencesDialog extends Dialog<Boolean> {
|
|||
|
||||
public PreferencesDialog(PreferenceGroup initialGroup, boolean initialSetup) {
|
||||
final DialogPane dialogPane = getDialogPane();
|
||||
AppController.setStageIcon(dialogPane.getScene().getWindow());
|
||||
AppServices.setStageIcon(dialogPane.getScene().getWindow());
|
||||
|
||||
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());
|
||||
PreferencesController preferencesController = preferencesLoader.getController();
|
||||
preferencesController.initializeView(Config.get());
|
||||
|
|
|
@ -11,7 +11,7 @@ import com.sparrowwallet.drongo.uri.BitcoinURI;
|
|||
import com.sparrowwallet.drongo.wallet.*;
|
||||
import com.sparrowwallet.hummingbird.UR;
|
||||
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.control.*;
|
||||
import com.sparrowwallet.sparrow.event.*;
|
||||
|
@ -252,8 +252,8 @@ public class HeadersController extends TransactionFormController implements Init
|
|||
locktimeFieldset.getChildren().add(locktimeBlockField);
|
||||
Integer block = locktimeBlock.getValue();
|
||||
if(block != null) {
|
||||
locktimeCurrentHeight.setVisible(headersForm.isEditable() && AppController.getCurrentBlockHeight() != null && block < AppController.getCurrentBlockHeight());
|
||||
futureBlockWarning.setVisible(AppController.getCurrentBlockHeight() != null && block > AppController.getCurrentBlockHeight());
|
||||
locktimeCurrentHeight.setVisible(headersForm.isEditable() && AppServices.getCurrentBlockHeight() != null && block < AppServices.getCurrentBlockHeight());
|
||||
futureBlockWarning.setVisible(AppServices.getCurrentBlockHeight() != null && block > AppServices.getCurrentBlockHeight());
|
||||
tx.setLocktime(block);
|
||||
if(old_toggle != null) {
|
||||
EventManager.get().post(new TransactionChangedEvent(tx));
|
||||
|
@ -303,8 +303,8 @@ public class HeadersController extends TransactionFormController implements Init
|
|||
|
||||
locktimeBlock.valueProperty().addListener((obs, oldValue, newValue) -> {
|
||||
tx.setLocktime(newValue);
|
||||
locktimeCurrentHeight.setVisible(headersForm.isEditable() && AppController.getCurrentBlockHeight() != null && newValue < AppController.getCurrentBlockHeight());
|
||||
futureBlockWarning.setVisible(AppController.getCurrentBlockHeight() != null && newValue > AppController.getCurrentBlockHeight());
|
||||
locktimeCurrentHeight.setVisible(headersForm.isEditable() && AppServices.getCurrentBlockHeight() != null && newValue < AppServices.getCurrentBlockHeight());
|
||||
futureBlockWarning.setVisible(AppServices.getCurrentBlockHeight() != null && newValue > AppServices.getCurrentBlockHeight());
|
||||
if(oldValue != null) {
|
||||
EventManager.get().post(new TransactionChangedEvent(tx));
|
||||
EventManager.get().post(new TransactionLocktimeChangedEvent(tx));
|
||||
|
@ -360,7 +360,7 @@ public class HeadersController extends TransactionFormController implements Init
|
|||
broadcastButton.managedProperty().bind(broadcastButton.visibleProperty());
|
||||
saveFinalButton.managedProperty().bind(saveFinalButton.visibleProperty());
|
||||
saveFinalButton.visibleProperty().bind(broadcastButton.visibleProperty().not());
|
||||
broadcastButton.visibleProperty().bind(AppController.onlineProperty());
|
||||
broadcastButton.visibleProperty().bind(AppServices.onlineProperty());
|
||||
|
||||
BitcoinURI payjoinURI = getPayjoinURI();
|
||||
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);
|
||||
|
||||
if(headersForm.getBlockTransaction() != null) {
|
||||
updateBlockchainForm(headersForm.getBlockTransaction(), AppController.getCurrentBlockHeight());
|
||||
updateBlockchainForm(headersForm.getBlockTransaction(), AppServices.getCurrentBlockHeight());
|
||||
} else if(headersForm.getPsbt() != null) {
|
||||
PSBT psbt = headersForm.getPsbt();
|
||||
|
||||
|
@ -558,7 +558,7 @@ public class HeadersController extends TransactionFormController implements Init
|
|||
for(TransactionOutput txOutput : headersForm.getPsbt().getTransaction().getOutputs()) {
|
||||
try {
|
||||
Address address = txOutput.getScript().getToAddresses()[0];
|
||||
BitcoinURI bitcoinURI = AppController.getPayjoinURI(address);
|
||||
BitcoinURI bitcoinURI = AppServices.getPayjoinURI(address);
|
||||
if(bitcoinURI != null) {
|
||||
return bitcoinURI;
|
||||
}
|
||||
|
@ -602,8 +602,8 @@ public class HeadersController extends TransactionFormController implements Init
|
|||
}
|
||||
|
||||
public void setLocktimeToCurrentHeight(ActionEvent event) {
|
||||
if(AppController.getCurrentBlockHeight() != null && locktimeBlock.isEditable()) {
|
||||
locktimeBlock.getValueFactory().setValue(AppController.getCurrentBlockHeight());
|
||||
if(AppServices.getCurrentBlockHeight() != null && locktimeBlock.isEditable()) {
|
||||
locktimeBlock.getValueFactory().setValue(AppServices.getCurrentBlockHeight());
|
||||
Platform.runLater(() -> locktimeBlockType.requestFocus());
|
||||
}
|
||||
}
|
||||
|
@ -659,7 +659,7 @@ public class HeadersController extends TransactionFormController implements Init
|
|||
}
|
||||
} catch(IOException 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 -> {
|
||||
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..."));
|
||||
decryptWalletService.start();
|
||||
|
@ -716,7 +716,7 @@ public class HeadersController extends TransactionFormController implements Init
|
|||
updateSignedKeystores(headersForm.getSigningWallet());
|
||||
} catch(Exception 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<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))) {
|
||||
return;
|
||||
}
|
||||
|
@ -788,7 +788,7 @@ public class HeadersController extends TransactionFormController implements Init
|
|||
broadcastTransactionService.setOnFailed(workerStateEvent -> {
|
||||
broadcastProgressBar.setProgress(0);
|
||||
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);
|
||||
});
|
||||
|
||||
|
@ -816,7 +816,7 @@ public class HeadersController extends TransactionFormController implements Init
|
|||
}
|
||||
} catch(IOException 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);
|
||||
EventManager.get().post(new ViewPSBTEvent(headersForm.getName() + " Payjoin", proposalPsbt));
|
||||
} 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);
|
||||
}
|
||||
|
||||
if(blockTransaction != null && AppController.getCurrentBlockHeight() != null) {
|
||||
updateBlockchainForm(blockTransaction, AppController.getCurrentBlockHeight());
|
||||
if(blockTransaction != null && AppServices.getCurrentBlockHeight() != null) {
|
||||
updateBlockchainForm(blockTransaction, AppServices.getCurrentBlockHeight());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -867,7 +867,7 @@ public class HeadersController extends TransactionFormController implements Init
|
|||
public void blockTransactionFetched(BlockTransactionFetchedEvent event) {
|
||||
if(event.getTxId().equals(headersForm.getTransaction().getTxId())) {
|
||||
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());
|
||||
|
@ -1021,7 +1021,7 @@ public class HeadersController extends TransactionFormController implements Init
|
|||
BlockTransaction blockTransaction = transactionMap.get(txid);
|
||||
if(blockTransaction != null) {
|
||||
headersForm.setBlockTransaction(blockTransaction);
|
||||
updateBlockchainForm(blockTransaction, AppController.getCurrentBlockHeight());
|
||||
updateBlockchainForm(blockTransaction, AppServices.getCurrentBlockHeight());
|
||||
}
|
||||
});
|
||||
transactionReferenceService.setOnFailed(failEvent -> {
|
||||
|
@ -1064,7 +1064,7 @@ public class HeadersController extends TransactionFormController implements Init
|
|||
updateBlockchainForm(headersForm.getBlockTransaction(), event.getHeight());
|
||||
}
|
||||
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.PSBTOutput;
|
||||
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.TransactionTabData;
|
||||
import com.sparrowwallet.sparrow.control.TransactionDiagram;
|
||||
|
@ -326,7 +326,7 @@ public class TransactionController implements Initializable {
|
|||
}
|
||||
|
||||
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<>();
|
||||
if(getPSBT() == null) {
|
||||
references.add(getTransaction().getTxId());
|
||||
|
@ -378,7 +378,7 @@ public class TransactionController implements Initializable {
|
|||
}
|
||||
|
||||
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);
|
||||
ElectrumServer.TransactionOutputsReferenceService transactionOutputsReferenceService = new ElectrumServer.TransactionOutputsReferenceService(getTransaction(), indexStart, maxIndex);
|
||||
transactionOutputsReferenceService.setOnSucceeded(successEvent -> {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package com.sparrowwallet.sparrow.wallet;
|
||||
|
||||
import com.sparrowwallet.drongo.wallet.Wallet;
|
||||
import com.sparrowwallet.sparrow.AppController;
|
||||
import com.sparrowwallet.sparrow.AppServices;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.control.ButtonBar;
|
||||
import javafx.scene.control.ButtonType;
|
||||
|
@ -14,10 +14,10 @@ import java.io.IOException;
|
|||
public class AdvancedDialog extends Dialog<Void> {
|
||||
public AdvancedDialog(Wallet wallet) {
|
||||
final DialogPane dialogPane = getDialogPane();
|
||||
AppController.setStageIcon(dialogPane.getScene().getWindow());
|
||||
AppServices.setStageIcon(dialogPane.getScene().getWindow());
|
||||
|
||||
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());
|
||||
AdvancedController settingsAdvancedController = advancedLoader.getController();
|
||||
settingsAdvancedController.initializeView(wallet);
|
||||
|
|
|
@ -5,7 +5,7 @@ import com.sparrowwallet.drongo.*;
|
|||
import com.sparrowwallet.drongo.wallet.Keystore;
|
||||
import com.sparrowwallet.drongo.wallet.KeystoreSource;
|
||||
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.control.QRDisplayDialog;
|
||||
import com.sparrowwallet.sparrow.control.QRScanDialog;
|
||||
|
@ -340,7 +340,7 @@ public class KeystoreController extends WalletFormController implements Initiali
|
|||
});
|
||||
decryptWalletService.setOnFailed(workerStateEvent -> {
|
||||
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..."));
|
||||
decryptWalletService.start();
|
||||
|
@ -364,9 +364,9 @@ public class KeystoreController extends WalletFormController implements Initiali
|
|||
xpub.setText(result.extendedKey.getExtendedKey());
|
||||
} else if(result.exception != null) {
|
||||
log.error("Error scanning QR", result.exception);
|
||||
AppController.showErrorDialog("Error scanning QR", result.exception.getMessage());
|
||||
AppServices.showErrorDialog("Error scanning QR", result.exception.getMessage());
|
||||
} 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.Payment;
|
||||
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.EventManager;
|
||||
import com.sparrowwallet.sparrow.control.CoinTextFormatter;
|
||||
|
@ -74,7 +74,7 @@ public class PaymentController extends WalletFormController implements Initializ
|
|||
|
||||
Long recipientValueSats = getRecipientValueSats();
|
||||
if(recipientValueSats != null) {
|
||||
setFiatAmount(AppController.getFiatCurrencyExchangeRate(), recipientValueSats);
|
||||
setFiatAmount(AppServices.getFiatCurrencyExchangeRate(), recipientValueSats);
|
||||
} else {
|
||||
fiatAmount.setText("");
|
||||
}
|
||||
|
@ -260,7 +260,7 @@ public class PaymentController extends WalletFormController implements Initializ
|
|||
label.setText(payment.getLabel());
|
||||
}
|
||||
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());
|
||||
}
|
||||
if(bitcoinURI.getPayjoinUrl() != null) {
|
||||
AppController.addPayjoinURI(bitcoinURI);
|
||||
AppServices.addPayjoinURI(bitcoinURI);
|
||||
}
|
||||
sendController.updateTransaction();
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ import com.sparrowwallet.drongo.wallet.BlockTransactionHashIndex;
|
|||
import com.sparrowwallet.drongo.wallet.Keystore;
|
||||
import com.sparrowwallet.drongo.wallet.KeystoreSource;
|
||||
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.control.*;
|
||||
import com.sparrowwallet.sparrow.event.ReceiveToEvent;
|
||||
|
@ -116,7 +116,7 @@ public class ReceiveController extends WalletFormController implements Initializ
|
|||
outputDescriptor.clear();
|
||||
outputDescriptor.append(nodeEntry.getOutputDescriptor(), "descriptor-text");
|
||||
|
||||
updateDisplayAddress(AppController.getDevices());
|
||||
updateDisplayAddress(AppServices.getDevices());
|
||||
}
|
||||
|
||||
private void updateDerivationPath(NodeEntry nodeEntry) {
|
||||
|
@ -138,7 +138,7 @@ public class ReceiveController extends WalletFormController implements Initializ
|
|||
|
||||
private void updateLastUsed() {
|
||||
Set<BlockTransactionHashIndex> currentOutputs = currentEntry.getNode().getTransactionOutputs();
|
||||
if(AppController.isOnline() && currentOutputs.isEmpty()) {
|
||||
if(AppServices.isOnline() && currentOutputs.isEmpty()) {
|
||||
lastUsed.setText("Never");
|
||||
lastUsed.setGraphic(getUnusedGlyph());
|
||||
} else if(!currentOutputs.isEmpty()) {
|
||||
|
|
|
@ -6,7 +6,7 @@ import com.sparrowwallet.drongo.address.InvalidAddressException;
|
|||
import com.sparrowwallet.drongo.protocol.Transaction;
|
||||
import com.sparrowwallet.drongo.psbt.PSBT;
|
||||
import com.sparrowwallet.drongo.wallet.*;
|
||||
import com.sparrowwallet.sparrow.AppController;
|
||||
import com.sparrowwallet.sparrow.AppServices;
|
||||
import com.sparrowwallet.sparrow.CurrencyRate;
|
||||
import com.sparrowwallet.sparrow.EventManager;
|
||||
import com.sparrowwallet.sparrow.control.*;
|
||||
|
@ -128,7 +128,7 @@ public class SendController extends WalletFormController implements Initializabl
|
|||
if(newValue.isEmpty()) {
|
||||
fiatFeeAmount.setText("");
|
||||
} else {
|
||||
setFiatFeeAmount(AppController.getFiatCurrencyExchangeRate(), getFeeValueSats());
|
||||
setFiatFeeAmount(AppServices.getFiatCurrencyExchangeRate(), getFeeValueSats());
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
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());
|
||||
PaymentController controller = paymentLoader.getController();
|
||||
controller.setSendController(this);
|
||||
|
@ -451,7 +451,7 @@ public class SendController extends WalletFormController implements Initializabl
|
|||
if(!userFeeSet.get() || (getFeeValueSats() != null && getFeeValueSats() > 0)) {
|
||||
Wallet wallet = getWalletForm().getWallet();
|
||||
Long userFee = userFeeSet.get() ? getFeeValueSats() : null;
|
||||
Integer currentBlockHeight = AppController.getCurrentBlockHeight();
|
||||
Integer currentBlockHeight = AppServices.getCurrentBlockHeight();
|
||||
boolean groupByAddress = Config.get().isGroupByAddress();
|
||||
boolean includeMempoolChange = Config.get().isIncludeMempoolChange();
|
||||
boolean includeMempoolInputs = includeMempoolInputsProperty.get();
|
||||
|
@ -532,7 +532,7 @@ public class SendController extends WalletFormController implements Initializabl
|
|||
df.setMaximumFractionDigits(8);
|
||||
fee.setText(df.format(feeAmountUnit.getValue().getValue(feeValue)));
|
||||
fee.textProperty().addListener(feeListener);
|
||||
setFiatFeeAmount(AppController.getFiatCurrencyExchangeRate(), feeValue);
|
||||
setFiatFeeAmount(AppServices.getFiatCurrencyExchangeRate(), feeValue);
|
||||
}
|
||||
|
||||
private Integer getTargetBlocks() {
|
||||
|
@ -565,7 +565,7 @@ public class SendController extends WalletFormController implements Initializabl
|
|||
}
|
||||
|
||||
private Map<Integer, Double> getTargetBlocksFeeRates() {
|
||||
Map<Integer, Double> retrievedFeeRates = AppController.getTargetBlockFeeRates();
|
||||
Map<Integer, Double> retrievedFeeRates = AppServices.getTargetBlockFeeRates();
|
||||
if(retrievedFeeRates == null) {
|
||||
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"); },
|
||||
|
@ -600,11 +600,11 @@ public class SendController extends WalletFormController implements Initializabl
|
|||
}
|
||||
|
||||
private Map<Date, Set<MempoolRateSize>> getMempoolHistogram() {
|
||||
return AppController.getMempoolHistogram();
|
||||
return AppServices.getMempoolHistogram();
|
||||
}
|
||||
|
||||
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) {
|
||||
|
|
|
@ -11,7 +11,7 @@ import com.sparrowwallet.drongo.wallet.Keystore;
|
|||
import com.sparrowwallet.drongo.wallet.KeystoreSource;
|
||||
import com.sparrowwallet.drongo.wallet.Wallet;
|
||||
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.control.*;
|
||||
import com.sparrowwallet.sparrow.event.RequestOpenWalletsEvent;
|
||||
|
@ -223,7 +223,7 @@ public class SettingsController extends WalletFormController implements Initiali
|
|||
tab.setClosable(false);
|
||||
|
||||
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());
|
||||
KeystoreController controller = keystoreLoader.getController();
|
||||
controller.setKeystore(getWalletForm(), keystore);
|
||||
|
@ -258,7 +258,7 @@ public class SettingsController extends WalletFormController implements Initiali
|
|||
} else if(result.payload != null && !result.payload.isEmpty()) {
|
||||
setDescriptorText(result.payload);
|
||||
} 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));
|
||||
} 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();
|
||||
} catch(IOException 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);
|
||||
apply.setDisable(false);
|
||||
return;
|
||||
|
@ -369,7 +369,7 @@ public class SettingsController extends WalletFormController implements Initiali
|
|||
}
|
||||
} catch (IOException e) {
|
||||
log.error("Error saving wallet", e);
|
||||
AppController.showErrorDialog("Error saving wallet", e.getMessage());
|
||||
AppServices.showErrorDialog("Error saving wallet", e.getMessage());
|
||||
revert.setDisable(false);
|
||||
apply.setDisable(false);
|
||||
}
|
||||
|
@ -384,7 +384,7 @@ public class SettingsController extends WalletFormController implements Initiali
|
|||
ECKey encryptionPubKey = ECKey.fromPublicOnly(encryptionFullKey);
|
||||
|
||||
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);
|
||||
apply.setDisable(false);
|
||||
return;
|
||||
|
@ -406,7 +406,7 @@ public class SettingsController extends WalletFormController implements Initiali
|
|||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Error saving wallet", e);
|
||||
AppController.showErrorDialog("Error saving wallet", e.getMessage());
|
||||
AppServices.showErrorDialog("Error saving wallet", e.getMessage());
|
||||
revert.setDisable(false);
|
||||
apply.setDisable(false);
|
||||
} finally {
|
||||
|
@ -418,7 +418,7 @@ public class SettingsController extends WalletFormController implements Initiali
|
|||
});
|
||||
keyDerivationService.setOnFailed(workerStateEvent -> {
|
||||
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);
|
||||
apply.setDisable(false);
|
||||
});
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package com.sparrowwallet.sparrow.wallet;
|
||||
|
||||
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.EventManager;
|
||||
import com.sparrowwallet.sparrow.control.BalanceChart;
|
||||
|
@ -47,7 +47,7 @@ public class TransactionsController extends WalletFormController implements Init
|
|||
transactionsTable.initialize(walletTransactionsEntry);
|
||||
|
||||
balance.valueProperty().addListener((observable, oldValue, newValue) -> {
|
||||
setFiatBalance(AppController.getFiatCurrencyExchangeRate(), newValue.longValue());
|
||||
setFiatBalance(AppServices.getFiatCurrencyExchangeRate(), newValue.longValue());
|
||||
});
|
||||
balance.setValue(walletTransactionsEntry.getBalance());
|
||||
mempoolBalance.setValue(walletTransactionsEntry.getMempoolBalance());
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package com.sparrowwallet.sparrow.wallet;
|
||||
|
||||
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.event.ReceiveActionEvent;
|
||||
import com.sparrowwallet.sparrow.event.SendActionEvent;
|
||||
|
@ -57,7 +57,7 @@ public class WalletController extends WalletFormController implements Initializa
|
|||
|
||||
try {
|
||||
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();
|
||||
walletFunction.setUserData(function);
|
||||
WalletFormController controller = functionLoader.getController();
|
||||
|
|
|
@ -4,7 +4,7 @@ import com.google.common.eventbus.Subscribe;
|
|||
import com.sparrowwallet.drongo.KeyPurpose;
|
||||
import com.sparrowwallet.drongo.wallet.Wallet;
|
||||
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.WalletTabData;
|
||||
import com.sparrowwallet.sparrow.event.*;
|
||||
|
@ -32,7 +32,7 @@ public class WalletForm {
|
|||
public WalletForm(Storage storage, Wallet currentWallet) {
|
||||
this.storage = storage;
|
||||
this.wallet = currentWallet;
|
||||
refreshHistory(AppController.getCurrentBlockHeight());
|
||||
refreshHistory(AppServices.getCurrentBlockHeight());
|
||||
}
|
||||
|
||||
public Wallet getWallet() {
|
||||
|
@ -62,7 +62,7 @@ public class WalletForm {
|
|||
public void saveAndRefresh() throws IOException {
|
||||
wallet.clearHistory();
|
||||
save();
|
||||
refreshHistory(AppController.getCurrentBlockHeight());
|
||||
refreshHistory(AppServices.getCurrentBlockHeight());
|
||||
}
|
||||
|
||||
public void saveBackup() throws IOException {
|
||||
|
@ -75,7 +75,7 @@ public class WalletForm {
|
|||
|
||||
public void refreshHistory(Integer blockHeight, WalletNode node) {
|
||||
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());
|
||||
ElectrumServer.TransactionHistoryService historyService = new ElectrumServer.TransactionHistoryService(wallet, getWalletTransactionNodes(node));
|
||||
historyService.setOnSucceeded(workerStateEvent -> {
|
||||
|
@ -226,7 +226,7 @@ public class WalletForm {
|
|||
walletUtxosEntry = null;
|
||||
accountEntries.clear();
|
||||
EventManager.get().post(new WalletNodesChangedEvent(wallet));
|
||||
refreshHistory(AppController.getCurrentBlockHeight());
|
||||
refreshHistory(AppServices.getCurrentBlockHeight());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -249,7 +249,7 @@ public class WalletForm {
|
|||
WalletNode walletNode = event.getWalletNode(wallet);
|
||||
if(walletNode != null) {
|
||||
log.debug(wallet.getName() + " history event for node " + walletNode);
|
||||
refreshHistory(AppController.getCurrentBlockHeight(), walletNode);
|
||||
refreshHistory(AppServices.getCurrentBlockHeight(), walletNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue