use of org.bitcoinj.core.Wallet in project bitsquare by bitsquare.
the class MainViewModel method start.
///////////////////////////////////////////////////////////////////////////////////////////
// API
///////////////////////////////////////////////////////////////////////////////////////////
public void start() {
// TODO need more though how to improve privacy without annoying first time users.
/* String key = "showAddBitcoinNodesWindowKey";
if (preferences.showAgain(key))
addBitcoinNodesWindow.dontShowAgainId(key, preferences)
.onClose(() -> {
preferences.dontShowAgain(key, true);
initializeAllServices();
})
.onAction(() -> {
preferences.dontShowAgain(key, true);
initializeAllServices();
})
.show();
else
initializeAllServices();
}
private void initializeAllServices() {*/
Log.traceCall();
UserThread.runAfter(tacWindow::showIfNeeded, 2);
ChangeListener<Boolean> walletInitializedListener = (observable, oldValue, newValue) -> {
if (newValue && !p2pNetWorkReady.get())
showStartupTimeoutPopup();
};
Timer startupTimeout = UserThread.runAfter(() -> {
log.warn("startupTimeout called");
Wallet wallet = walletService.getWallet();
if (wallet != null && wallet.isEncrypted())
walletInitialized.addListener(walletInitializedListener);
else
showStartupTimeoutPopup();
}, 4, TimeUnit.MINUTES);
p2pNetWorkReady = initP2PNetwork();
initBitcoinWallet();
// need to store it to not get garbage collected
allServicesDone = EasyBind.combine(walletInitialized, p2pNetWorkReady, (a, b) -> a && b);
allServicesDone.subscribe((observable, oldValue, newValue) -> {
if (newValue) {
startupTimeout.stop();
walletInitialized.removeListener(walletInitializedListener);
onAllServicesInitialized();
if (startupTimeoutPopup != null)
startupTimeoutPopup.hide();
}
});
}
use of org.bitcoinj.core.Wallet in project bitsquare by bitsquare.
the class MainViewModel method initWalletService.
private void initWalletService() {
Log.traceCall();
ObjectProperty<Throwable> walletServiceException = new SimpleObjectProperty<>();
btcInfoBinding = EasyBind.combine(walletService.downloadPercentageProperty(), walletService.numPeersProperty(), walletServiceException, (downloadPercentage, numPeers, exception) -> {
String result = "";
if (exception == null) {
double percentage = (double) downloadPercentage;
int peers = (int) numPeers;
String numPeersString = "Bitcoin network peers: " + peers;
btcSyncProgress.set(percentage);
if (percentage == 1) {
result = numPeersString + " / synchronized with " + btcNetworkAsString;
btcSplashSyncIconId.set("image-connection-synced");
} else if (percentage > 0.0) {
result = numPeersString + " / synchronizing with " + btcNetworkAsString + ": " + formatter.formatToPercentWithSymbol(percentage);
} else {
result = numPeersString + " / connecting to " + btcNetworkAsString;
}
} else {
result = "Bitcoin network peers: " + numBtcPeers + " / connecting to " + btcNetworkAsString + " failed";
if (exception instanceof TimeoutException) {
walletServiceErrorMsg.set("Connecting to the bitcoin network failed because of a timeout.");
} else if (exception.getCause() instanceof BlockStoreException) {
log.error(exception.getMessage());
// Ugly, but no other way to cover that specific case
if (exception.getMessage().equals("Store file is already locked by another process"))
new Popup().warning("Bitsquare is already running. You cannot run two instances of Bitsquare.").closeButtonText("Shut down").onClose(BitsquareApp.shutDownHandler::run).show();
else
new Popup().error("Cannot open wallet because of an exception:\n" + exception.getMessage()).show();
} else if (exception.getMessage() != null) {
walletServiceErrorMsg.set("Connection to the bitcoin network failed because of an error:" + exception.getMessage());
} else {
walletServiceErrorMsg.set("Connection to the bitcoin network failed because of an error:" + exception.toString());
}
}
return result;
});
btcInfoBinding.subscribe((observable, oldValue, newValue) -> {
btcInfo.set(newValue);
});
walletService.initialize(null, () -> {
numBtcPeers = walletService.numPeersProperty().get();
if (walletService.getWallet().isEncrypted()) {
if (p2pNetWorkReady.get())
splashP2PNetworkAnimationVisible.set(false);
walletPasswordWindow.onAesKey(aesKey -> {
walletService.setAesKey(aesKey);
tradeWalletService.setAesKey(aesKey);
walletInitialized.set(true);
}).hideCloseButton().show();
} else {
walletInitialized.set(true);
}
}, walletServiceException::set);
}
use of org.bitcoinj.core.Wallet in project bitsquare by bitsquare.
the class MainViewModel method onAllServicesInitialized.
private void onAllServicesInitialized() {
Log.traceCall();
clock.start();
// disputeManager
disputeManager.onAllServicesInitialized();
disputeManager.getDisputesAsObservableList().addListener((ListChangeListener<Dispute>) change -> {
change.next();
onDisputesChangeListener(change.getAddedSubList(), change.getRemoved());
});
onDisputesChangeListener(disputeManager.getDisputesAsObservableList(), null);
// tradeManager
tradeManager.onAllServicesInitialized();
tradeManager.getTrades().addListener((ListChangeListener<Trade>) c -> updateBalance());
tradeManager.getTrades().addListener((ListChangeListener<Trade>) change -> onTradesChanged());
onTradesChanged();
// We handle the trade period here as we display a global popup if we reached dispute time
tradesAndUIReady = EasyBind.combine(isSplashScreenRemoved, tradeManager.pendingTradesInitializedProperty(), (a, b) -> a && b);
tradesAndUIReady.subscribe((observable, oldValue, newValue) -> {
if (newValue)
applyTradePeriodState();
});
// walletService
walletService.addBalanceListener(new BalanceListener() {
@Override
public void onBalanceChanged(Coin balance, Transaction tx) {
updateBalance();
}
});
openOfferManager.getOpenOffers().addListener((ListChangeListener<OpenOffer>) c -> updateBalance());
tradeManager.getTrades().addListener((ListChangeListener<Trade>) c -> updateBalance());
openOfferManager.onAllServicesInitialized();
arbitratorManager.onAllServicesInitialized();
alertManager.alertMessageProperty().addListener((observable, oldValue, newValue) -> displayAlertIfPresent(newValue));
privateNotificationManager.privateNotificationProperty().addListener((observable, oldValue, newValue) -> displayPrivateNotification(newValue));
displayAlertIfPresent(alertManager.alertMessageProperty().get());
p2PService.onAllServicesInitialized();
setupBtcNumPeersWatcher();
setupP2PNumPeersWatcher();
updateBalance();
if (DevFlags.DEV_MODE) {
preferences.setShowOwnOffersInOfferBook(true);
if (user.getPaymentAccounts().isEmpty())
setupDevDummyPaymentAccounts();
}
setupMarketPriceFeed();
swapPendingOfferFundingEntries();
fillPriceFeedComboBoxItems();
showAppScreen.set(true);
// We want to test if the client is compiled with the correct crypto provider (BountyCastle)
// and if the unlimited Strength for cryptographic keys is set.
// If users compile themselves they might miss that step and then would get an exception in the trade.
// To avoid that we add here at startup a sample encryption and signing to see if it don't causes an exception.
// See: https://github.com/bitsquare/bitsquare/blob/master/doc/build.md#7-enable-unlimited-strength-for-cryptographic-keys
Thread checkCryptoThread = new Thread() {
@Override
public void run() {
try {
Thread.currentThread().setName("checkCryptoThread");
log.trace("Run crypto test");
// just use any simple dummy msg
io.bitsquare.p2p.peers.keepalive.messages.Ping payload = new Ping(1, 1);
SealedAndSigned sealedAndSigned = Encryption.encryptHybridWithSignature(payload, keyRing.getSignatureKeyPair(), keyRing.getPubKeyRing().getEncryptionPubKey());
DecryptedDataTuple tuple = Encryption.decryptHybridWithSignature(sealedAndSigned, keyRing.getEncryptionKeyPair().getPrivate());
if (tuple.payload instanceof Ping && ((Ping) tuple.payload).nonce == payload.nonce && ((Ping) tuple.payload).lastRoundTripTime == payload.lastRoundTripTime)
log.debug("Crypto test succeeded");
else
throw new CryptoException("Payload not correct after decryption");
} catch (CryptoException e) {
e.printStackTrace();
String msg = "Seems that you use a self compiled binary and have not following the build " + "instructions in https://github.com/bitsquare/bitsquare/blob/master/doc/build.md#7-enable-unlimited-strength-for-cryptographic-keys.\n\n" + "If that is not the case and you use the official Bitsquare binary, " + "please file a bug report to the Github page.\n" + "Error=" + e.getMessage();
log.error(msg);
UserThread.execute(() -> new Popup<>().warning(msg).actionButtonText("Shut down").onAction(BitsquareApp.shutDownHandler::run).closeButtonText("Report bug at Github issues").onClose(() -> GUIUtil.openWebPage("https://github.com/bitsquare/bitsquare/issues")).show());
}
}
};
checkCryptoThread.start();
if (Security.getProvider("BC") == null) {
new Popup<>().warning("There is a problem with the crypto libraries. BountyCastle is not available.").actionButtonText("Shut down").onAction(BitsquareApp.shutDownHandler::run).closeButtonText("Report bug at Github issues").onClose(() -> GUIUtil.openWebPage("https://github.com/bitsquare/bitsquare/issues")).show();
}
String remindPasswordAndBackupKey = "remindPasswordAndBackup";
user.getPaymentAccountsAsObservable().addListener((SetChangeListener<PaymentAccount>) change -> {
if (!walletService.getWallet().isEncrypted() && preferences.showAgain(remindPasswordAndBackupKey) && change.wasAdded()) {
new Popup<>().headLine("Important security recommendation").information("We would like to remind you to consider using password protection for your wallet if you have not already enabled that.\n\n" + "It is also highly recommended to write down the wallet seed words. Those seed words are like a master password for recovering your Bitcoin wallet.\n" + "At the \"Wallet Seed\" section you find more information.\n\n" + "Additionally you can backup the complete application data folder at the \"Backup\" section.\n" + "Please note, that this backup is not encrypted!").dontShowAgainId(remindPasswordAndBackupKey, preferences).show();
}
});
checkIfOpenOffersMatchTradeProtocolVersion();
}
use of org.bitcoinj.core.Wallet in project bitsquare by bitsquare.
the class PasswordView method initialize.
@Override
public void initialize() {
headline = addTitledGroupBg(root, gridRow, 2, "");
passwordField = addLabelPasswordTextField(root, gridRow, "Enter password:", Layout.FIRST_ROW_DISTANCE).second;
passwordField.setValidator(passwordValidator);
passwordFieldChangeListener = (observable, oldValue, newValue) -> validatePasswords();
Tuple2<Label, PasswordTextField> tuple2 = addLabelPasswordTextField(root, ++gridRow, "Repeat password:");
repeatedPasswordLabel = tuple2.first;
repeatedPasswordField = tuple2.second;
repeatedPasswordField.setValidator(passwordValidator);
repeatedPasswordFieldChangeListener = (observable, oldValue, newValue) -> validatePasswords();
Tuple3<Button, BusyAnimation, Label> tuple = addButtonBusyAnimationLabel(root, ++gridRow, "", 15);
pwButton = tuple.first;
BusyAnimation busyAnimation = tuple.second;
Label deriveStatusLabel = tuple.third;
pwButton.setDisable(true);
setText();
pwButton.setOnAction(e -> {
String password = passwordField.getText();
checkArgument(password.length() < 50, "Password must be less then 50 characters.");
pwButton.setDisable(true);
deriveStatusLabel.setText("Derive key from password");
busyAnimation.play();
KeyCrypterScrypt keyCrypterScrypt;
Wallet wallet = walletService.getWallet();
if (wallet.isEncrypted())
keyCrypterScrypt = (KeyCrypterScrypt) wallet.getKeyCrypter();
else
keyCrypterScrypt = ScryptUtil.getKeyCrypterScrypt();
ScryptUtil.deriveKeyWithScrypt(keyCrypterScrypt, password, aesKey -> {
deriveStatusLabel.setText("");
busyAnimation.stop();
if (wallet.isEncrypted()) {
if (wallet.checkAESKey(aesKey)) {
walletService.decryptWallet(aesKey);
tradeWalletService.setAesKey(null);
new Popup().feedback("Wallet successfully decrypted and password protection removed.").show();
passwordField.setText("");
repeatedPasswordField.setText("");
walletService.backupWallet();
} else {
pwButton.setDisable(false);
new Popup().warning("You entered the wrong password.\n\n" + "Please try entering your password again, carefully checking for typos or spelling errors.").show();
}
} else {
walletService.encryptWallet(keyCrypterScrypt, aesKey);
tradeWalletService.setAesKey(aesKey);
new Popup().feedback("Wallet successfully encrypted and password protection enabled.").show();
passwordField.setText("");
repeatedPasswordField.setText("");
walletService.clearBackup();
walletService.backupWallet();
}
setText();
});
});
addTitledGroupBg(root, ++gridRow, 1, "Information", Layout.GROUP_DISTANCE);
addMultilineLabel(root, gridRow, "With password protection you need to enter your password when" + " withdrawing bitcoin out of your wallet or " + "if you want to view or restore a wallet from seed words as well as at application startup.", Layout.FIRST_ROW_AND_GROUP_DISTANCE);
}
use of org.bitcoinj.core.Wallet in project bitsquare by bitsquare.
the class WalletPasswordWindow method addButtons.
private void addButtons() {
BusyAnimation busyAnimation = new BusyAnimation(false);
Label deriveStatusLabel = new Label();
unlockButton = new Button("Unlock");
unlockButton.setDefaultButton(true);
unlockButton.setDisable(true);
unlockButton.setOnAction(e -> {
String password = passwordTextField.getText();
checkArgument(password.length() < 50, "Password must be less then 50 characters.");
Wallet wallet = walletService.getWallet();
KeyCrypterScrypt keyCrypterScrypt = (KeyCrypterScrypt) wallet.getKeyCrypter();
if (keyCrypterScrypt != null) {
busyAnimation.play();
deriveStatusLabel.setText("Derive key from password");
ScryptUtil.deriveKeyWithScrypt(keyCrypterScrypt, password, aesKey -> {
if (wallet.checkAESKey(aesKey)) {
if (aesKeyHandler != null)
aesKeyHandler.onAesKey(aesKey);
hide();
} else {
busyAnimation.stop();
deriveStatusLabel.setText("");
UserThread.runAfter(() -> new Popup().warning("You entered the wrong password.\n\n" + "Please try entering your password again, carefully checking for typos or spelling errors.").onClose(this::blurAgain).show(), Transitions.DEFAULT_DURATION, TimeUnit.MILLISECONDS);
}
});
} else {
log.error("wallet.getKeyCrypter() is null, that must not happen.");
}
});
forgotPasswordButton = new Button("Forgot password?");
forgotPasswordButton.setOnAction(e -> {
forgotPasswordButton.setDisable(true);
unlockButton.setDefaultButton(false);
showRestoreScreen();
});
Button cancelButton = new Button("Cancel");
cancelButton.setOnAction(event -> {
hide();
closeHandlerOptional.ifPresent(closeHandler -> closeHandler.run());
});
HBox hBox = new HBox();
hBox.setMinWidth(560);
hBox.setSpacing(10);
GridPane.setRowIndex(hBox, ++rowIndex);
GridPane.setColumnIndex(hBox, 1);
hBox.setAlignment(Pos.CENTER_LEFT);
if (hideCloseButton)
hBox.getChildren().addAll(unlockButton, forgotPasswordButton, busyAnimation, deriveStatusLabel);
else
hBox.getChildren().addAll(unlockButton, cancelButton);
gridPane.getChildren().add(hBox);
ColumnConstraints columnConstraints1 = new ColumnConstraints();
columnConstraints1.setHalignment(HPos.RIGHT);
columnConstraints1.setHgrow(Priority.SOMETIMES);
ColumnConstraints columnConstraints2 = new ColumnConstraints();
columnConstraints2.setHgrow(Priority.ALWAYS);
gridPane.getColumnConstraints().addAll(columnConstraints1, columnConstraints2);
}
Aggregations