diff --git a/gui/src/main/java/io/bisq/gui/main/account/content/seedwords/SeedWordsView.java b/gui/src/main/java/io/bisq/gui/main/account/content/seedwords/SeedWordsView.java index 4629c37cc6..17b663e4e1 100644 --- a/gui/src/main/java/io/bisq/gui/main/account/content/seedwords/SeedWordsView.java +++ b/gui/src/main/java/io/bisq/gui/main/account/content/seedwords/SeedWordsView.java @@ -19,8 +19,8 @@ package io.bisq.gui.main.account.content.seedwords; import com.google.common.base.Joiner; import com.google.common.base.Splitter; -import io.bisq.common.UserThread; import io.bisq.common.locale.Res; +import io.bisq.common.storage.Storage; import io.bisq.core.btc.wallet.BtcWalletService; import io.bisq.core.btc.wallet.WalletsManager; import io.bisq.core.user.DontShowAgainLookup; @@ -28,6 +28,7 @@ import io.bisq.gui.common.view.ActivatableView; import io.bisq.gui.common.view.FxmlView; import io.bisq.gui.main.overlays.popups.Popup; import io.bisq.gui.main.overlays.windows.WalletPasswordWindow; +import io.bisq.gui.util.GUIUtil; import io.bisq.gui.util.Layout; import javafx.beans.property.BooleanProperty; import javafx.beans.property.SimpleBooleanProperty; @@ -41,6 +42,8 @@ import org.bitcoinj.crypto.MnemonicException; import org.bitcoinj.wallet.DeterministicSeed; import javax.inject.Inject; +import javax.inject.Named; +import java.io.File; import java.io.IOException; import java.time.Instant; import java.time.LocalDate; @@ -56,6 +59,7 @@ public class SeedWordsView extends ActivatableView { private final WalletsManager walletsManager; private final BtcWalletService btcWalletService; private final WalletPasswordWindow walletPasswordWindow; + private final File storageDir; private Button restoreButton; private TextArea displaySeedWordsTextArea, seedWordsTextArea; @@ -75,10 +79,14 @@ public class SeedWordsView extends ActivatableView { /////////////////////////////////////////////////////////////////////////////////////////// @Inject - private SeedWordsView(WalletsManager walletsManager, BtcWalletService btcWalletService, WalletPasswordWindow walletPasswordWindow) { + private SeedWordsView(WalletsManager walletsManager, + BtcWalletService btcWalletService, + WalletPasswordWindow walletPasswordWindow, + @Named(Storage.STORAGE_DIR) File storageDir) { this.walletsManager = walletsManager; this.btcWalletService = btcWalletService; this.walletPasswordWindow = walletPasswordWindow; + this.storageDir = storageDir; } @Override @@ -230,19 +238,6 @@ public class SeedWordsView extends ActivatableView { //TODO Is ZoneOffset correct? long date = value != null ? value.atStartOfDay().toEpochSecond(ZoneOffset.UTC) : 0; DeterministicSeed seed = new DeterministicSeed(Splitter.on(" ").splitToList(seedWordsTextArea.getText()), null, "", date); - walletsManager.restoreSeedWords( - seed, - () -> UserThread.execute(() -> { - log.info("Wallets restored with seed words"); - new Popup<>().feedback(Res.get("seed.restore.success")) - .useShutDownButton() - .show(); - }), - throwable -> UserThread.execute(() -> { - log.error(throwable.getMessage()); - new Popup<>().error(Res.get("seed.restore.error", Res.get("shared.errorMessageInline", - throwable.getMessage()))) - .show(); - })); + GUIUtil.restoreSeedWords(seed, walletsManager, storageDir); } } diff --git a/gui/src/main/java/io/bisq/gui/main/overlays/windows/WalletPasswordWindow.java b/gui/src/main/java/io/bisq/gui/main/overlays/windows/WalletPasswordWindow.java index 5de86004f4..077454e0e3 100644 --- a/gui/src/main/java/io/bisq/gui/main/overlays/windows/WalletPasswordWindow.java +++ b/gui/src/main/java/io/bisq/gui/main/overlays/windows/WalletPasswordWindow.java @@ -20,6 +20,7 @@ package io.bisq.gui.main.overlays.windows; import com.google.common.base.Splitter; import io.bisq.common.UserThread; import io.bisq.common.locale.Res; +import io.bisq.common.storage.Storage; import io.bisq.common.util.Tuple2; import io.bisq.core.btc.wallet.WalletsManager; import io.bisq.core.crypto.ScryptUtil; @@ -27,6 +28,7 @@ import io.bisq.gui.components.BusyAnimation; import io.bisq.gui.components.PasswordTextField; import io.bisq.gui.main.overlays.Overlay; import io.bisq.gui.main.overlays.popups.Popup; +import io.bisq.gui.util.GUIUtil; import io.bisq.gui.util.Transitions; import io.bisq.gui.util.validation.PasswordValidator; import javafx.beans.property.BooleanProperty; @@ -43,15 +45,16 @@ import javafx.scene.layout.ColumnConstraints; import javafx.scene.layout.GridPane; import javafx.scene.layout.HBox; import javafx.scene.layout.Priority; +import lombok.extern.slf4j.Slf4j; import org.bitcoinj.crypto.KeyCrypterScrypt; import org.bitcoinj.crypto.MnemonicCode; import org.bitcoinj.crypto.MnemonicException; import org.bitcoinj.wallet.DeterministicSeed; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.spongycastle.crypto.params.KeyParameter; import javax.inject.Inject; +import javax.inject.Named; +import java.io.File; import java.io.IOException; import java.time.Instant; import java.time.LocalDate; @@ -63,8 +66,10 @@ import static com.google.common.base.Preconditions.checkArgument; import static io.bisq.gui.util.FormBuilder.*; import static javafx.beans.binding.Bindings.createBooleanBinding; +@Slf4j public class WalletPasswordWindow extends Overlay { - private static final Logger log = LoggerFactory.getLogger(WalletPasswordWindow.class); + private final WalletsManager walletsManager; + private final File storageDir; private Button unlockButton; private AesKeyHandler aesKeyHandler; private PasswordTextField passwordTextField; @@ -78,7 +83,6 @@ public class WalletPasswordWindow extends Overlay { private ChangeListener wordsTextAreaChangeListener; private ChangeListener seedWordsValidChangeListener; private LocalDate walletCreationDate; - private final WalletsManager walletsManager; /////////////////////////////////////////////////////////////////////////////////////////// @@ -90,8 +94,10 @@ public class WalletPasswordWindow extends Overlay { } @Inject - private WalletPasswordWindow(WalletsManager walletsManager) { + private WalletPasswordWindow(WalletsManager walletsManager, + @Named(Storage.STORAGE_DIR) File storageDir) { this.walletsManager = walletsManager; + this.storageDir = storageDir; type = Type.Attention; width = 800; } @@ -278,7 +284,7 @@ public class WalletPasswordWindow extends Overlay { // wallet creation date is not encrypted walletCreationDate = Instant.ofEpochSecond(walletsManager.getChainSeedCreationTimeSeconds()).atZone(ZoneId.systemDefault()).toLocalDate(); - log.info("walletCreationDate "+walletCreationDate); + log.info("walletCreationDate " + walletCreationDate); datePicker.setValue(walletCreationDate); restoreButton.disableProperty().bind(createBooleanBinding(() -> !seedWordsValid.get() || !seedWordsEdited.get(), seedWordsValid, seedWordsEdited)); @@ -344,19 +350,6 @@ public class WalletPasswordWindow extends Overlay { //TODO Is ZoneOffset correct? long date = value != null ? value.atStartOfDay().toEpochSecond(ZoneOffset.UTC) : 0; DeterministicSeed seed = new DeterministicSeed(Splitter.on(" ").splitToList(seedWordsTextArea.getText()), null, "", date); - walletsManager.restoreSeedWords( - seed, - () -> UserThread.execute(() -> { - log.info("Wallet restored with seed words"); - new Popup<>().feedback(Res.get("seed.restore.success")) - .useShutDownButton() - .show(); - }), - throwable -> UserThread.execute(() -> { - log.error(throwable.getMessage()); - new Popup<>().error(Res.get("seed.restore.error", - Res.get("shared.errorMessageInline", throwable.getMessage()))) - .show(); - })); + GUIUtil.restoreSeedWords(seed, walletsManager, storageDir); } } diff --git a/gui/src/main/java/io/bisq/gui/util/GUIUtil.java b/gui/src/main/java/io/bisq/gui/util/GUIUtil.java index ea38ee363e..546729ea5d 100644 --- a/gui/src/main/java/io/bisq/gui/util/GUIUtil.java +++ b/gui/src/main/java/io/bisq/gui/util/GUIUtil.java @@ -29,9 +29,11 @@ import io.bisq.common.locale.Res; import io.bisq.common.locale.TradeCurrency; import io.bisq.common.proto.persistable.PersistableList; import io.bisq.common.proto.persistable.PersistenceProtoResolver; +import io.bisq.common.storage.FileUtil; import io.bisq.common.storage.Storage; import io.bisq.common.util.Utilities; import io.bisq.core.app.BisqEnvironment; +import io.bisq.core.btc.wallet.WalletsManager; import io.bisq.core.btc.wallet.WalletsSetup; import io.bisq.core.payment.PaymentAccount; import io.bisq.core.payment.PaymentAccountList; @@ -59,6 +61,7 @@ import org.bitcoinj.core.Address; import org.bitcoinj.core.Coin; import org.bitcoinj.core.TransactionConfidence; import org.bitcoinj.uri.BitcoinURI; +import org.bitcoinj.wallet.DeterministicSeed; import javax.annotation.Nullable; import java.io.File; @@ -443,4 +446,25 @@ public class GUIUtil { else if (!walletsSetup.isDownloadComplete()) new Popup<>().information(Res.get("popup.warning.downloadNotComplete")).show(); } + + public static void restoreSeedWords(DeterministicSeed seed, WalletsManager walletsManager, File storageDir) { + try { + FileUtil.renameFile(new File(storageDir, "AddressEntryList"), new File(storageDir, "AddressEntryList_wallet_restore_" + System.currentTimeMillis())); + } catch (Throwable t) { + new Popup<>().error(Res.get("error.deleteAddressEntryListFailed", t)).show(); + } + walletsManager.restoreSeedWords( + seed, + () -> UserThread.execute(() -> { + log.info("Wallets restored with seed words"); + new Popup<>().feedback(Res.get("seed.restore.success")) + .useShutDownButton() + .show(); + }), + throwable -> UserThread.execute(() -> { + log.error(throwable.toString()); + new Popup<>().error(Res.get("seed.restore.error", Res.get("shared.errorMessageInline", throwable))) + .show(); + })); + } }