mirror of
https://github.com/sparrowwallet/sparrow.git
synced 2024-12-24 12:46:45 +00:00
usb status, key progress timing
This commit is contained in:
parent
2acc922b06
commit
fdd8327464
13 changed files with 207 additions and 62 deletions
BIN
.DS_Store
vendored
BIN
.DS_Store
vendored
Binary file not shown.
2
drongo
2
drongo
|
@ -1 +1 @@
|
|||
Subproject commit 06de1d7e1458cb00cc242025c5e0d536633083a0
|
||||
Subproject commit 785040898babf4b198985531f61af7ce48178b17
|
|
@ -12,13 +12,12 @@ import com.sparrowwallet.drongo.protocol.Transaction;
|
|||
import com.sparrowwallet.drongo.psbt.PSBT;
|
||||
import com.sparrowwallet.drongo.psbt.PSBTParseException;
|
||||
import com.sparrowwallet.drongo.wallet.Keystore;
|
||||
import com.sparrowwallet.drongo.wallet.KeystoreSource;
|
||||
import com.sparrowwallet.drongo.wallet.MnemonicException;
|
||||
import com.sparrowwallet.drongo.wallet.Wallet;
|
||||
import com.sparrowwallet.sparrow.control.*;
|
||||
import com.sparrowwallet.sparrow.event.*;
|
||||
import com.sparrowwallet.sparrow.io.FileType;
|
||||
import com.sparrowwallet.sparrow.io.IOUtils;
|
||||
import com.sparrowwallet.sparrow.io.Storage;
|
||||
import com.sparrowwallet.sparrow.io.*;
|
||||
import com.sparrowwallet.sparrow.transaction.TransactionController;
|
||||
import com.sparrowwallet.sparrow.wallet.WalletController;
|
||||
import com.sparrowwallet.sparrow.wallet.WalletForm;
|
||||
|
@ -30,6 +29,7 @@ import javafx.event.ActionEvent;
|
|||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.input.Dragboard;
|
||||
import javafx.scene.input.TransferMode;
|
||||
|
@ -263,7 +263,7 @@ public class AppController implements Initializable {
|
|||
SecureString password = optionalPassword.get();
|
||||
Storage.LoadWalletService loadWalletService = new Storage.LoadWalletService(storage, password);
|
||||
loadWalletService.setOnSucceeded(workerStateEvent -> {
|
||||
EventManager.get().post(new TimedWorkerEvent("Done"));
|
||||
EventManager.get().post(new StorageEvent(storage.getWalletFile(), TimedEvent.Action.END, "Done"));
|
||||
Storage.WalletAndKey walletAndKey = loadWalletService.getValue();
|
||||
try {
|
||||
restorePublicKeysFromSeed(walletAndKey.wallet, walletAndKey.key);
|
||||
|
@ -276,7 +276,7 @@ public class AppController implements Initializable {
|
|||
}
|
||||
});
|
||||
loadWalletService.setOnFailed(workerStateEvent -> {
|
||||
EventManager.get().post(new TimedWorkerEvent("Failed"));
|
||||
EventManager.get().post(new StorageEvent(storage.getWalletFile(), TimedEvent.Action.END, "Failed"));
|
||||
Throwable exception = loadWalletService.getException();
|
||||
if(exception instanceof InvalidPasswordException) {
|
||||
showErrorDialog("Invalid Password", "The wallet password was invalid.");
|
||||
|
@ -284,8 +284,8 @@ public class AppController implements Initializable {
|
|||
showErrorDialog("Error Opening Wallet", exception.getMessage());
|
||||
}
|
||||
});
|
||||
EventManager.get().post(new StorageEvent(storage.getWalletFile(), TimedEvent.Action.START, "Decrypting wallet..."));
|
||||
loadWalletService.start();
|
||||
EventManager.get().post(new TimedWorkerEvent("Decrypting wallet...", 1000));
|
||||
} else {
|
||||
throw new IOException("Unsupported file type");
|
||||
}
|
||||
|
@ -379,6 +379,15 @@ public class AppController implements Initializable {
|
|||
WalletForm walletForm = new WalletForm(storage, wallet);
|
||||
controller.setWalletForm(walletForm);
|
||||
|
||||
if(!storage.getWalletFile().exists() || wallet.containsSource(KeystoreSource.HW_USB)) {
|
||||
Hwi.EnumerateService enumerateService = new Hwi.EnumerateService(null);
|
||||
enumerateService.setOnSucceeded(workerStateEvent -> {
|
||||
List<Device> devices = enumerateService.getValue();
|
||||
EventManager.get().post(new UsbDeviceEvent(devices));
|
||||
});
|
||||
enumerateService.start();
|
||||
}
|
||||
|
||||
tabs.getTabs().add(tab);
|
||||
return tab;
|
||||
} catch(IOException e) {
|
||||
|
@ -501,17 +510,17 @@ public class AppController implements Initializable {
|
|||
}
|
||||
|
||||
@Subscribe
|
||||
public void timedWorker(TimedWorkerEvent event) {
|
||||
if(statusTimeline != null && statusTimeline.getStatus() == Animation.Status.RUNNING) {
|
||||
public void timedWorker(TimedEvent event) {
|
||||
if(event.getTimeMills() == 0) {
|
||||
if(statusTimeline != null && statusTimeline.getStatus() == Animation.Status.RUNNING) {
|
||||
statusTimeline.stop();
|
||||
}
|
||||
statusBar.setText("");
|
||||
statusBar.setProgress(0);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
statusBar.setProgress(event.getTimeMills());
|
||||
} else if(event.getTimeMills() < 0) {
|
||||
statusBar.setText(event.getStatus());
|
||||
statusBar.setProgress(event.getTimeMills());
|
||||
} else {
|
||||
statusBar.setText(event.getStatus());
|
||||
statusTimeline = new Timeline(
|
||||
new KeyFrame(Duration.ZERO, new KeyValue(statusBar.progressProperty(), 0)),
|
||||
|
@ -524,3 +533,22 @@ public class AppController implements Initializable {
|
|||
statusTimeline.play();
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void usbDevicesFound(UsbDeviceEvent event) {
|
||||
if(event.getDevices().isEmpty()) {
|
||||
Node usbStatus = null;
|
||||
for(Node node : statusBar.getRightItems()) {
|
||||
if(node instanceof UsbStatusButton) {
|
||||
usbStatus = node;
|
||||
}
|
||||
}
|
||||
if(usbStatus != null) {
|
||||
statusBar.getRightItems().removeAll(usbStatus);
|
||||
}
|
||||
} else {
|
||||
UsbStatusButton usbStatusButton = new UsbStatusButton(event.getDevices());
|
||||
statusBar.getRightItems().add(usbStatusButton);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,9 @@ import javafx.scene.image.Image;
|
|||
import javafx.stage.Stage;
|
||||
import org.controlsfx.glyphfont.GlyphFontRegistry;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
public class MainApp extends Application {
|
||||
|
||||
@Override
|
||||
|
@ -43,6 +46,9 @@ public class MainApp extends Application {
|
|||
// KeystoreImportDialog dlg = new KeystoreImportDialog(wallet);
|
||||
// dlg.showAndWait();
|
||||
|
||||
Path path = Paths.get("").toAbsolutePath();
|
||||
System.out.println(path.toFile().getAbsolutePath());
|
||||
|
||||
stage.show();
|
||||
}
|
||||
|
||||
|
|
|
@ -300,7 +300,7 @@ public class DevicePane extends TitledDescriptionPane {
|
|||
String xpub = getXpubService.getValue();
|
||||
|
||||
Keystore keystore = new Keystore();
|
||||
keystore.setLabel(device.getModel().toDisplayString() + " " + device.getFingerprint().toUpperCase());
|
||||
keystore.setLabel(device.getModel().toDisplayString());
|
||||
keystore.setSource(KeystoreSource.HW_USB);
|
||||
keystore.setWalletModel(device.getModel());
|
||||
keystore.setKeyDerivation(new KeyDerivation(device.getFingerprint(), derivationPath));
|
||||
|
|
|
@ -3,7 +3,8 @@ package com.sparrowwallet.sparrow.control;
|
|||
import com.sparrowwallet.drongo.SecureString;
|
||||
import com.sparrowwallet.drongo.wallet.Wallet;
|
||||
import com.sparrowwallet.sparrow.EventManager;
|
||||
import com.sparrowwallet.sparrow.event.TimedWorkerEvent;
|
||||
import com.sparrowwallet.sparrow.event.StorageEvent;
|
||||
import com.sparrowwallet.sparrow.event.TimedEvent;
|
||||
import com.sparrowwallet.sparrow.event.WalletExportEvent;
|
||||
import com.sparrowwallet.sparrow.io.Storage;
|
||||
import com.sparrowwallet.sparrow.io.WalletExport;
|
||||
|
@ -59,7 +60,7 @@ public class FileWalletExportPane extends TitledDescriptionPane {
|
|||
if(password.isPresent()) {
|
||||
Storage.DecryptWalletService decryptWalletService = new Storage.DecryptWalletService(copy, password.get());
|
||||
decryptWalletService.setOnSucceeded(workerStateEvent -> {
|
||||
EventManager.get().post(new TimedWorkerEvent("Done"));
|
||||
EventManager.get().post(new StorageEvent(file, TimedEvent.Action.END, "Done"));
|
||||
Wallet decryptedWallet = decryptWalletService.getValue();
|
||||
try {
|
||||
OutputStream outputStream = new FileOutputStream(file);
|
||||
|
@ -76,11 +77,11 @@ public class FileWalletExportPane extends TitledDescriptionPane {
|
|||
}
|
||||
});
|
||||
decryptWalletService.setOnFailed(workerStateEvent -> {
|
||||
EventManager.get().post(new TimedWorkerEvent("Failed"));
|
||||
EventManager.get().post(new StorageEvent(file, TimedEvent.Action.END, "Failed"));
|
||||
setError("Export Error", decryptWalletService.getException().getMessage());
|
||||
});
|
||||
EventManager.get().post(new StorageEvent(file, TimedEvent.Action.START, "Decrypting wallet..."));
|
||||
decryptWalletService.start();
|
||||
EventManager.get().post(new TimedWorkerEvent("Decrypting wallet...", 1000));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
package com.sparrowwallet.sparrow.control;
|
||||
|
||||
import com.sparrowwallet.sparrow.glyphfont.FontAwesome5Brands;
|
||||
import com.sparrowwallet.sparrow.io.Device;
|
||||
import javafx.geometry.Side;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.*;
|
||||
import org.controlsfx.glyphfont.Glyph;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class UsbStatusButton extends MenuButton {
|
||||
private final List<Device> devices;
|
||||
|
||||
public UsbStatusButton(List<Device> devices) {
|
||||
super("");
|
||||
setGraphic(getIcon());
|
||||
this.devices = devices;
|
||||
|
||||
this.setPopupSide(Side.TOP);
|
||||
|
||||
for(Device device : devices) {
|
||||
MenuItem deviceItem = new MenuItem(device.getModel().toDisplayString());
|
||||
getItems().add(deviceItem);
|
||||
}
|
||||
}
|
||||
|
||||
private Node getIcon() {
|
||||
Glyph usb = new Glyph(FontAwesome5Brands.FONT_NAME, FontAwesome5Brands.Glyph.USB);
|
||||
usb.setFontSize(10);
|
||||
return usb;
|
||||
}
|
||||
|
||||
private class UsbStatusContextMenu extends ContextMenu {
|
||||
public UsbStatusContextMenu() {
|
||||
for(Device device : devices) {
|
||||
MenuItem deviceItem = new MenuItem(device.getModel().toDisplayString());
|
||||
getItems().add(deviceItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package com.sparrowwallet.sparrow.event;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class StorageEvent extends TimedEvent {
|
||||
private static boolean firstRunDone = false;
|
||||
private static int keyDerivationPeriod = -1;
|
||||
private static final Map<File, Long> eventTime = new HashMap<>();
|
||||
|
||||
public StorageEvent(File file, Action action, String status) {
|
||||
super(action, status);
|
||||
|
||||
if(action == Action.START) {
|
||||
eventTime.put(file, System.currentTimeMillis());
|
||||
timeMills = keyDerivationPeriod;
|
||||
} else if(action == Action.END) {
|
||||
long start = eventTime.get(file);
|
||||
if(firstRunDone) {
|
||||
keyDerivationPeriod = (int)(System.currentTimeMillis() - start);
|
||||
}
|
||||
firstRunDone = true;
|
||||
System.out.println(keyDerivationPeriod);
|
||||
timeMills = 0;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package com.sparrowwallet.sparrow.event;
|
||||
|
||||
public class TimedEvent {
|
||||
private final Action action;
|
||||
private final String status;
|
||||
protected int timeMills;
|
||||
|
||||
public TimedEvent(Action action, String status) {
|
||||
this.action = action;
|
||||
this.status = status;
|
||||
this.timeMills = 0;
|
||||
}
|
||||
|
||||
public TimedEvent(Action action, String status, int timeMills) {
|
||||
this.action = action;
|
||||
this.status = status;
|
||||
this.timeMills = timeMills;
|
||||
}
|
||||
|
||||
public Action getAction() {
|
||||
return action;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public int getTimeMills() {
|
||||
return timeMills;
|
||||
}
|
||||
|
||||
public enum Action {
|
||||
START, END;
|
||||
}
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
package com.sparrowwallet.sparrow.event;
|
||||
|
||||
public class TimedWorkerEvent {
|
||||
private final String status;
|
||||
private final int timeMills;
|
||||
|
||||
public TimedWorkerEvent(String status) {
|
||||
this.status = status;
|
||||
this.timeMills = 0;
|
||||
}
|
||||
|
||||
public TimedWorkerEvent(String status, int timeMills) {
|
||||
this.status = status;
|
||||
this.timeMills = timeMills;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public int getTimeMills() {
|
||||
return timeMills;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package com.sparrowwallet.sparrow.event;
|
||||
|
||||
import com.sparrowwallet.sparrow.io.Device;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class UsbDeviceEvent {
|
||||
private List<Device> devices;
|
||||
|
||||
public UsbDeviceEvent(List<Device> devices) {
|
||||
this.devices = devices;
|
||||
}
|
||||
|
||||
public List<Device> getDevices() {
|
||||
return devices;
|
||||
}
|
||||
}
|
|
@ -15,7 +15,8 @@ import com.sparrowwallet.sparrow.EventManager;
|
|||
import com.sparrowwallet.sparrow.control.CopyableLabel;
|
||||
import com.sparrowwallet.sparrow.control.WalletPasswordDialog;
|
||||
import com.sparrowwallet.sparrow.event.SettingsChangedEvent;
|
||||
import com.sparrowwallet.sparrow.event.TimedWorkerEvent;
|
||||
import com.sparrowwallet.sparrow.event.StorageEvent;
|
||||
import com.sparrowwallet.sparrow.event.TimedEvent;
|
||||
import com.sparrowwallet.sparrow.event.WalletChangedEvent;
|
||||
import com.sparrowwallet.sparrow.io.Storage;
|
||||
import javafx.beans.property.SimpleIntegerProperty;
|
||||
|
@ -276,7 +277,7 @@ public class SettingsController extends WalletFormController implements Initiali
|
|||
} else {
|
||||
Storage.KeyDerivationService keyDerivationService = new Storage.KeyDerivationService(walletForm.getStorage(), password.get());
|
||||
keyDerivationService.setOnSucceeded(workerStateEvent -> {
|
||||
EventManager.get().post(new TimedWorkerEvent("Done"));
|
||||
EventManager.get().post(new StorageEvent(walletForm.getWalletFile(), TimedEvent.Action.END, "Done"));
|
||||
ECKey encryptionFullKey = keyDerivationService.getValue();
|
||||
Key key = null;
|
||||
|
||||
|
@ -308,13 +309,13 @@ public class SettingsController extends WalletFormController implements Initiali
|
|||
}
|
||||
});
|
||||
keyDerivationService.setOnFailed(workerStateEvent -> {
|
||||
EventManager.get().post(new TimedWorkerEvent("Failed"));
|
||||
EventManager.get().post(new StorageEvent(walletForm.getWalletFile(), TimedEvent.Action.END, "Failed"));
|
||||
AppController.showErrorDialog("Error saving wallet", keyDerivationService.getException().getMessage());
|
||||
revert.setDisable(false);
|
||||
apply.setDisable(false);
|
||||
});
|
||||
EventManager.get().post(new StorageEvent(walletForm.getWalletFile(), TimedEvent.Action.START, "Encrypting wallet..."));
|
||||
keyDerivationService.start();
|
||||
EventManager.get().post(new TimedWorkerEvent("Encrypting wallet...", 1000));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
package com.sparrowwallet.sparrow.wallet;
|
||||
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
import com.sparrowwallet.sparrow.AppController;
|
||||
import com.sparrowwallet.sparrow.EventManager;
|
||||
import com.sparrowwallet.sparrow.event.WalletChangedEvent;
|
||||
import javafx.application.Platform;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
|
@ -65,13 +67,17 @@ public class WalletController extends WalletFormController implements Initializa
|
|||
}
|
||||
});
|
||||
|
||||
if(!walletForm.getWallet().isValid()) {
|
||||
configure(walletForm.getWallet().isValid());
|
||||
}
|
||||
|
||||
public void configure(boolean isWalletValid) {
|
||||
for(Toggle toggle : walletMenu.getToggles()) {
|
||||
if(toggle.getUserData().equals(Function.SETTINGS)) {
|
||||
if(!isWalletValid) {
|
||||
toggle.setSelected(true);
|
||||
} else {
|
||||
((ToggleButton)toggle).setDisable(true);
|
||||
}
|
||||
} else {
|
||||
((ToggleButton)toggle).setDisable(!isWalletValid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -85,4 +91,9 @@ public class WalletController extends WalletFormController implements Initializa
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void walletChanged(WalletChangedEvent event) {
|
||||
configure(walletForm.getWallet().isValid());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue