mirror of
https://github.com/bisq-network/bisq.git
synced 2025-02-25 07:27:18 +01:00
Move password check at startup before init rest of app. cleanup, wording improvements
This commit is contained in:
parent
cc46a81644
commit
5af70848a7
16 changed files with 142 additions and 114 deletions
|
@ -383,11 +383,6 @@ public class WalletService {
|
||||||
return ImmutableList.copyOf(addressEntryList);
|
return ImmutableList.copyOf(addressEntryList);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void swapTradeToSavings(String offerId) {
|
|
||||||
getOrCreateAddressEntry(offerId, AddressEntry.Context.OFFER_FUNDING);
|
|
||||||
addressEntryList.swapTradeToSavings(offerId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void swapTradeEntryToAvailableEntry(String offerId, AddressEntry.Context context) {
|
public void swapTradeEntryToAvailableEntry(String offerId, AddressEntry.Context context) {
|
||||||
Optional<AddressEntry> addressEntryOptional = getAddressEntryListAsImmutableList().stream()
|
Optional<AddressEntry> addressEntryOptional = getAddressEntryListAsImmutableList().stream()
|
||||||
.filter(e -> offerId.equals(e.getOfferId()))
|
.filter(e -> offerId.equals(e.getOfferId()))
|
||||||
|
|
|
@ -58,9 +58,9 @@ public final class Offer implements StoragePayload, RequiresOwnerIsOnlinePayload
|
||||||
@JsonExclude
|
@JsonExclude
|
||||||
private static final Logger log = LoggerFactory.getLogger(Offer.class);
|
private static final Logger log = LoggerFactory.getLogger(Offer.class);
|
||||||
public static final long TTL = TimeUnit.SECONDS.toMillis(4 * 60);
|
public static final long TTL = TimeUnit.SECONDS.toMillis(4 * 60);
|
||||||
public final static String TAC_OFFERER = "With placing that offer I accept to trade " +
|
public final static String TAC_OFFERER = "With placing that offer I agree to trade " +
|
||||||
"with anyone who fulfills the conditions as defined above.";
|
"with any trader who fulfills the conditions as defined above.";
|
||||||
public static final String TAC_TAKER = "With taking that offer I commit to the trade conditions as defined above.";
|
public static final String TAC_TAKER = "With taking that offer I agree to the trade conditions as defined above.";
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -76,7 +76,7 @@ import static io.bitsquare.app.BitsquareEnvironment.APP_NAME_KEY;
|
||||||
public class BitsquareApp extends Application {
|
public class BitsquareApp extends Application {
|
||||||
private static final Logger log = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(BitsquareApp.class);
|
private static final Logger log = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(BitsquareApp.class);
|
||||||
|
|
||||||
public static final boolean DEV_MODE = true;
|
public static final boolean DEV_MODE = false;
|
||||||
public static final boolean IS_RELEASE_VERSION = !DEV_MODE && true;
|
public static final boolean IS_RELEASE_VERSION = !DEV_MODE && true;
|
||||||
|
|
||||||
private static Environment env;
|
private static Environment env;
|
||||||
|
|
|
@ -409,6 +409,26 @@ public class MainViewModel implements ViewModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onAllServicesInitialized() {
|
private void onAllServicesInitialized() {
|
||||||
|
// In case we have any offers open or a pending trade we need to unlock our trading wallet so a trade can be executed automatically
|
||||||
|
// Otherwise we delay the password request to create offer, or take offer.
|
||||||
|
// When the password is set it will be stored to the tradeWalletService as well, so its only needed after a restart.
|
||||||
|
if (walletService.getWallet().isEncrypted() &&
|
||||||
|
(openOfferManager.getOpenOffers().size() > 0
|
||||||
|
|| tradeManager.getTrades().size() > 0
|
||||||
|
|| disputeManager.getDisputesAsObservableList().size() > 0)) {
|
||||||
|
walletPasswordWindow
|
||||||
|
.onAesKey(aesKey -> {
|
||||||
|
tradeWalletService.setAesKey(aesKey);
|
||||||
|
onAllServicesInitializedAndUnlocked();
|
||||||
|
})
|
||||||
|
.hideCloseButton()
|
||||||
|
.show();
|
||||||
|
} else {
|
||||||
|
onAllServicesInitializedAndUnlocked();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onAllServicesInitializedAndUnlocked() {
|
||||||
Log.traceCall();
|
Log.traceCall();
|
||||||
|
|
||||||
clock.start();
|
clock.start();
|
||||||
|
@ -435,15 +455,6 @@ public class MainViewModel implements ViewModel {
|
||||||
});
|
});
|
||||||
|
|
||||||
// walletService
|
// walletService
|
||||||
// In case we have any offers open or a pending trade we need to unlock our trading wallet so a trade can be executed automatically
|
|
||||||
// Otherwise we delay the password request to create offer, or take offer.
|
|
||||||
// When the password is set it will be stored to the tradeWalletService as well, so its only needed after a restart.
|
|
||||||
if (walletService.getWallet().isEncrypted() &&
|
|
||||||
(openOfferManager.getOpenOffers().size() > 0
|
|
||||||
|| tradeManager.getTrades().size() > 0
|
|
||||||
|| disputeManager.getDisputesAsObservableList().size() > 0)) {
|
|
||||||
walletPasswordWindow.onAesKey(aesKey -> tradeWalletService.setAesKey(aesKey)).show();
|
|
||||||
}
|
|
||||||
walletService.addBalanceListener(new BalanceListener() {
|
walletService.addBalanceListener(new BalanceListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onBalanceChanged(Coin balance, Transaction tx) {
|
public void onBalanceChanged(Coin balance, Transaction tx) {
|
||||||
|
@ -463,6 +474,7 @@ public class MainViewModel implements ViewModel {
|
||||||
updateBalance();
|
updateBalance();
|
||||||
setupDevDummyPaymentAccount();
|
setupDevDummyPaymentAccount();
|
||||||
setupMarketPriceFeed();
|
setupMarketPriceFeed();
|
||||||
|
swapPendingOfferFundingEntries();
|
||||||
|
|
||||||
showAppScreen.set(true);
|
showAppScreen.set(true);
|
||||||
|
|
||||||
|
@ -677,6 +689,12 @@ public class MainViewModel implements ViewModel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void swapPendingOfferFundingEntries() {
|
||||||
|
tradeManager.getAddressEntriesForAvailableBalanceStream()
|
||||||
|
.filter(addressEntry -> addressEntry.getOfferId() != null)
|
||||||
|
.forEach(addressEntry -> walletService.swapTradeEntryToAvailableEntry(addressEntry.getOfferId(), AddressEntry.Context.OFFER_FUNDING));
|
||||||
|
}
|
||||||
|
|
||||||
private void updateBalance() {
|
private void updateBalance() {
|
||||||
updateAvailableBalance();
|
updateAvailableBalance();
|
||||||
updateReservedBalance();
|
updateReservedBalance();
|
||||||
|
|
|
@ -147,7 +147,7 @@ public class PasswordView extends ActivatableView<GridPane, Void> {
|
||||||
" withdrawing bitcoin out of your wallet or " +
|
" withdrawing bitcoin out of your wallet or " +
|
||||||
"if you want to view or restore a wallet from seed words.\n" +
|
"if you want to view or restore a wallet from seed words.\n" +
|
||||||
"For the transactions used in the trade process we don't support password protection as that would make automatic offer " +
|
"For the transactions used in the trade process we don't support password protection as that would make automatic offer " +
|
||||||
"execution impossible.",
|
"execution impossible, but you need to provide the password at application startup if you have open offer, trades or disputes.",
|
||||||
Layout.FIRST_ROW_AND_GROUP_DISTANCE);
|
Layout.FIRST_ROW_AND_GROUP_DISTANCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -91,6 +91,7 @@ public class SeedWordsView extends ActivatableView<GridPane, Void> {
|
||||||
addTitledGroupBg(root, gridRow, 2, "Backup your wallet seed words");
|
addTitledGroupBg(root, gridRow, 2, "Backup your wallet seed words");
|
||||||
displaySeedWordsTextArea = addLabelTextArea(root, gridRow, "Wallet seed words:", "", Layout.FIRST_ROW_DISTANCE).second;
|
displaySeedWordsTextArea = addLabelTextArea(root, gridRow, "Wallet seed words:", "", Layout.FIRST_ROW_DISTANCE).second;
|
||||||
displaySeedWordsTextArea.setPrefHeight(60);
|
displaySeedWordsTextArea.setPrefHeight(60);
|
||||||
|
displaySeedWordsTextArea.setEditable(false);
|
||||||
datePicker = addLabelDatePicker(root, ++gridRow, "Creation Date:").second;
|
datePicker = addLabelDatePicker(root, ++gridRow, "Creation Date:").second;
|
||||||
datePicker.setMouseTransparent(true);
|
datePicker.setMouseTransparent(true);
|
||||||
|
|
||||||
|
|
|
@ -240,19 +240,7 @@ public class LockedView extends ActivatableView<VBox, Void> {
|
||||||
if (item != null && !empty) {
|
if (item != null && !empty) {
|
||||||
Optional<Tradable> tradableOptional = getTradable(item);
|
Optional<Tradable> tradableOptional = getTradable(item);
|
||||||
if (tradableOptional.isPresent()) {
|
if (tradableOptional.isPresent()) {
|
||||||
AddressEntry addressEntry = item.getAddressEntry();
|
field = new HyperlinkWithIcon("Locked in MultiSig for trade with ID: " + item.getAddressEntry().getShortOfferId(),
|
||||||
String details;
|
|
||||||
if (addressEntry.isTrade()) {
|
|
||||||
details = "Trade ID: " + addressEntry.getShortOfferId();
|
|
||||||
} else if (addressEntry.isOpenOffer()) {
|
|
||||||
details = "Offer ID: " + addressEntry.getShortOfferId();
|
|
||||||
} else if (addressEntry.getContext() == AddressEntry.Context.ARBITRATOR) {
|
|
||||||
details = "Arbitration fee";
|
|
||||||
} else {
|
|
||||||
details = "-";
|
|
||||||
}
|
|
||||||
|
|
||||||
field = new HyperlinkWithIcon("Locked in trade with ID: " + details + " (MultiSig)",
|
|
||||||
AwesomeIcon.INFO_SIGN);
|
AwesomeIcon.INFO_SIGN);
|
||||||
field.setOnAction(event -> openDetailPopup(item));
|
field.setOnAction(event -> openDetailPopup(item));
|
||||||
field.setTooltip(new Tooltip("Open popup for details"));
|
field.setTooltip(new Tooltip("Open popup for details"));
|
||||||
|
|
|
@ -240,19 +240,7 @@ public class ReservedView extends ActivatableView<VBox, Void> {
|
||||||
if (item != null && !empty) {
|
if (item != null && !empty) {
|
||||||
Optional<Tradable> tradableOptional = getTradable(item);
|
Optional<Tradable> tradableOptional = getTradable(item);
|
||||||
if (tradableOptional.isPresent()) {
|
if (tradableOptional.isPresent()) {
|
||||||
AddressEntry addressEntry = item.getAddressEntry();
|
field = new HyperlinkWithIcon("Reserved in local wallet for offer with ID: " + item.getAddressEntry().getShortOfferId(),
|
||||||
String details;
|
|
||||||
if (addressEntry.isTrade()) {
|
|
||||||
details = "Trade ID: " + addressEntry.getShortOfferId();
|
|
||||||
} else if (addressEntry.isOpenOffer()) {
|
|
||||||
details = "Offer ID: " + addressEntry.getShortOfferId();
|
|
||||||
} else if (addressEntry.getContext() == AddressEntry.Context.ARBITRATOR) {
|
|
||||||
details = "Arbitration fee";
|
|
||||||
} else {
|
|
||||||
details = "-";
|
|
||||||
}
|
|
||||||
|
|
||||||
field = new HyperlinkWithIcon("Reserved in offer with ID: " + details + " (local wallet)",
|
|
||||||
AwesomeIcon.INFO_SIGN);
|
AwesomeIcon.INFO_SIGN);
|
||||||
field.setOnAction(event -> openDetailPopup(item));
|
field.setOnAction(event -> openDetailPopup(item));
|
||||||
field.setTooltip(new Tooltip("Open popup for details"));
|
field.setTooltip(new Tooltip("Open popup for details"));
|
||||||
|
|
|
@ -290,17 +290,28 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
|
||||||
.show();
|
.show();
|
||||||
|
|
||||||
key = "createOfferFundWalletInfo";
|
key = "createOfferFundWalletInfo";
|
||||||
String tradeAmountText = model.isSellOffer() ? "the trade amount, " : "";
|
String tradeAmountText = model.isSellOffer() ? "- Trade amount: " + model.tradeAmount.get() + "\n" : "";
|
||||||
new Popup().headLine("Fund your trading wallet").instruction("You need to pay in " +
|
|
||||||
model.totalToPay.get() + " to your local Bitsquare trading wallet.\n" +
|
new Popup().headLine("Fund your offer").instruction("You need to deposit " +
|
||||||
"The amount is the sum of " + tradeAmountText + "the security deposit, the trading fee and " +
|
model.totalToPay.get() + " to this offer.\n\n" +
|
||||||
"the bitcoin mining fee.\n\n" +
|
|
||||||
"You can choose between 2 options:\n" +
|
"Those funds are reserved in your local wallet and will get locked into the Multisig " +
|
||||||
"Either you transfer from your Bitsquare wallet the funds or if you prefer better privacy by " +
|
"deposit address once someone takes your offer.\n\n" +
|
||||||
"separating all trade transactions you can send from your external Bitcoin wallet the exact amount to the address: " +
|
|
||||||
model.getAddressAsString() + "\n" +
|
"The amount is the sum of:\n" +
|
||||||
"(you can copy the address in the screen below after closing that popup)\n\n" +
|
tradeAmountText +
|
||||||
"You can see the status of your incoming payment and all the details in the screen below.")
|
"- Security deposit: " + model.getSecurityDeposit() + "\n" +
|
||||||
|
"- Trading fee: " + model.getOfferFee() + "\n" +
|
||||||
|
"- Bitcoin mining fee: " + model.getNetworkFee() + "\n\n" +
|
||||||
|
|
||||||
|
"For funding you can choose between 2 options:\n" +
|
||||||
|
"- Transfer fund from your Bitsquare wallet OR\n" +
|
||||||
|
"- Transfer fund from any external wallet\n\n" +
|
||||||
|
|
||||||
|
"If you prefer a higher level of privacy you should use for each trade a distinct funding transaction using the external wallet option.\n" +
|
||||||
|
"If you prefer convenience using the Bitsquare wallet for several trades might be your preferred option.\n\n" +
|
||||||
|
|
||||||
|
"You can see all the details for funding when you close that popup.")
|
||||||
.dontShowAgainId(key, preferences)
|
.dontShowAgainId(key, preferences)
|
||||||
.show();
|
.show();
|
||||||
}
|
}
|
||||||
|
|
|
@ -302,18 +302,24 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
||||||
.show();
|
.show();
|
||||||
|
|
||||||
key = "takeOfferFundWalletInfo";
|
key = "takeOfferFundWalletInfo";
|
||||||
String tradeAmountText = model.isSeller() ? "the trade amount, " : "";
|
String tradeAmountText = model.isSeller() ? "- Trade amount: " + model.getAmount() + "\n" : "";
|
||||||
new Popup().headLine("Fund your trading wallet")
|
new Popup().headLine("Fund your trade").instruction("You need to deposit " +
|
||||||
.instruction("You need to pay in " +
|
model.totalToPay.get() + " for taking this offer.\n\n" +
|
||||||
model.totalToPay.get() + " to your local Bitsquare trading wallet.\n" +
|
|
||||||
"The amount is the sum of " + tradeAmountText + "the security deposit, the trading fee and " +
|
"The amount is the sum of:\n" +
|
||||||
"the bitcoin mining fee.\n\n" +
|
tradeAmountText +
|
||||||
"You can choose between 2 options:\n" +
|
"- Security deposit: " + model.getSecurityDeposit() + "\n" +
|
||||||
"Either you transfer from your Bitsquare wallet the funds or if you prefer better privacy by " +
|
"- Trading fee: " + model.getTakerFee() + "\n" +
|
||||||
"separating all trade transactions you can send from your external Bitcoin wallet the exact amount to the address: " +
|
"- Bitcoin mining fee: " + model.getNetworkFee() + "\n\n" +
|
||||||
model.dataModel.getAddressEntry().getAddressString() + "\n" +
|
|
||||||
"(you can copy the address in the screen below after closing that popup)\n\n" +
|
"For funding you can choose between 2 options:\n" +
|
||||||
"You can see the status of your incoming payment and all the details in the screen below.")
|
"- Transfer fund from your Bitsquare wallet OR\n" +
|
||||||
|
"- Transfer fund from any external wallet\n\n" +
|
||||||
|
|
||||||
|
"If you prefer a higher level of privacy you should use for each trade a distinct funding transaction using the external wallet option.\n" +
|
||||||
|
"If you prefer convenience using the Bitsquare wallet for several trades might be your preferred option.\n\n" +
|
||||||
|
|
||||||
|
"You can see all the details for funding when you close that popup.")
|
||||||
.dontShowAgainId(key, preferences)
|
.dontShowAgainId(key, preferences)
|
||||||
.show();
|
.show();
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,6 +57,7 @@ import static io.bitsquare.gui.util.FormBuilder.addCheckBox;
|
||||||
public abstract class Overlay<T extends Overlay> {
|
public abstract class Overlay<T extends Overlay> {
|
||||||
protected final Logger log = LoggerFactory.getLogger(this.getClass());
|
protected final Logger log = LoggerFactory.getLogger(this.getClass());
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Enum
|
// Enum
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -128,6 +129,7 @@ public abstract class Overlay<T extends Overlay> {
|
||||||
protected Timer centerTime;
|
protected Timer centerTime;
|
||||||
protected double buttonDistance = 20;
|
protected double buttonDistance = 20;
|
||||||
protected Type type = Type.Undefined;
|
protected Type type = Type.Undefined;
|
||||||
|
protected boolean hideCloseButton;
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -334,6 +336,11 @@ public abstract class Overlay<T extends Overlay> {
|
||||||
return (T) this;
|
return (T) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public T hideCloseButton() {
|
||||||
|
this.hideCloseButton = true;
|
||||||
|
return (T) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Protected
|
// Protected
|
||||||
|
@ -715,7 +722,7 @@ public abstract class Overlay<T extends Overlay> {
|
||||||
GridPane.setColumnSpan(hBox, 2);
|
GridPane.setColumnSpan(hBox, 2);
|
||||||
GridPane.setMargin(hBox, new Insets(buttonDistance, 0, 0, 0));
|
GridPane.setMargin(hBox, new Insets(buttonDistance, 0, 0, 0));
|
||||||
gridPane.getChildren().add(hBox);
|
gridPane.getChildren().add(hBox);
|
||||||
} else {
|
} else if (!hideCloseButton) {
|
||||||
closeButton.setDefaultButton(true);
|
closeButton.setDefaultButton(true);
|
||||||
GridPane.setHalignment(closeButton, HPos.RIGHT);
|
GridPane.setHalignment(closeButton, HPos.RIGHT);
|
||||||
if (!showReportErrorButtons)
|
if (!showReportErrorButtons)
|
||||||
|
|
|
@ -84,7 +84,7 @@ public class OfferDetailsWindow extends Overlay<OfferDetailsWindow> {
|
||||||
this.tradeAmount = tradeAmount;
|
this.tradeAmount = tradeAmount;
|
||||||
|
|
||||||
rowIndex = -1;
|
rowIndex = -1;
|
||||||
width = 850;
|
width = 900;
|
||||||
createGridPane();
|
createGridPane();
|
||||||
addContent();
|
addContent();
|
||||||
display();
|
display();
|
||||||
|
@ -93,7 +93,7 @@ public class OfferDetailsWindow extends Overlay<OfferDetailsWindow> {
|
||||||
public void show(Offer offer) {
|
public void show(Offer offer) {
|
||||||
this.offer = offer;
|
this.offer = offer;
|
||||||
rowIndex = -1;
|
rowIndex = -1;
|
||||||
width = 850;
|
width = 900;
|
||||||
createGridPane();
|
createGridPane();
|
||||||
addContent();
|
addContent();
|
||||||
display();
|
display();
|
||||||
|
@ -222,7 +222,7 @@ public class OfferDetailsWindow extends Overlay<OfferDetailsWindow> {
|
||||||
|
|
||||||
if (placeOfferHandlerOptional.isPresent()) {
|
if (placeOfferHandlerOptional.isPresent()) {
|
||||||
addTitledGroupBg(gridPane, ++rowIndex, 1, "Commitment", Layout.GROUP_DISTANCE);
|
addTitledGroupBg(gridPane, ++rowIndex, 1, "Commitment", Layout.GROUP_DISTANCE);
|
||||||
addLabelTextField(gridPane, rowIndex, "Please note:", Offer.TAC_OFFERER, Layout.FIRST_ROW_AND_GROUP_DISTANCE);
|
addLabelTextField(gridPane, rowIndex, "I agree:", Offer.TAC_OFFERER, Layout.FIRST_ROW_AND_GROUP_DISTANCE);
|
||||||
|
|
||||||
addConfirmAndCancelButtons(true);
|
addConfirmAndCancelButtons(true);
|
||||||
} else if (takeOfferHandlerOptional.isPresent()) {
|
} else if (takeOfferHandlerOptional.isPresent()) {
|
||||||
|
|
|
@ -92,7 +92,6 @@ public class WalletPasswordWindow extends Overlay<WalletPasswordWindow> {
|
||||||
display();
|
display();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public WalletPasswordWindow onAesKey(AesKeyHandler aesKeyHandler) {
|
public WalletPasswordWindow onAesKey(AesKeyHandler aesKeyHandler) {
|
||||||
this.aesKeyHandler = aesKeyHandler;
|
this.aesKeyHandler = aesKeyHandler;
|
||||||
return this;
|
return this;
|
||||||
|
@ -137,7 +136,10 @@ public class WalletPasswordWindow extends Overlay<WalletPasswordWindow> {
|
||||||
hBox.setSpacing(10);
|
hBox.setSpacing(10);
|
||||||
GridPane.setRowIndex(hBox, ++rowIndex);
|
GridPane.setRowIndex(hBox, ++rowIndex);
|
||||||
GridPane.setColumnIndex(hBox, 1);
|
GridPane.setColumnIndex(hBox, 1);
|
||||||
hBox.getChildren().addAll(unlockButton, cancelButton);
|
if (hideCloseButton)
|
||||||
|
hBox.getChildren().add(unlockButton);
|
||||||
|
else
|
||||||
|
hBox.getChildren().addAll(unlockButton, cancelButton);
|
||||||
gridPane.getChildren().add(hBox);
|
gridPane.getChildren().add(hBox);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -71,7 +71,7 @@ public class PendingTradesDataModel extends ActivatableDataModel {
|
||||||
private final KeyRing keyRing;
|
private final KeyRing keyRing;
|
||||||
public final DisputeManager disputeManager;
|
public final DisputeManager disputeManager;
|
||||||
public final Navigation navigation;
|
public final Navigation navigation;
|
||||||
private final WalletPasswordWindow walletPasswordWindow;
|
public final WalletPasswordWindow walletPasswordWindow;
|
||||||
private final NotificationCenter notificationCenter;
|
private final NotificationCenter notificationCenter;
|
||||||
|
|
||||||
final ObservableList<PendingTradesListItem> list = FXCollections.observableArrayList();
|
final ObservableList<PendingTradesListItem> list = FXCollections.observableArrayList();
|
||||||
|
@ -147,12 +147,26 @@ public class PendingTradesDataModel extends ActivatableDataModel {
|
||||||
((SellerTrade) getTrade()).onFiatPaymentReceived(resultHandler, errorMessageHandler);
|
((SellerTrade) getTrade()).onFiatPaymentReceived(resultHandler, errorMessageHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onWithdrawRequest(String toAddress, Coin receiverAmount, ResultHandler resultHandler, FaultHandler faultHandler) {
|
public void onWithdrawRequest(String toAddress, Coin receiverAmount, KeyParameter aesKey, ResultHandler resultHandler, FaultHandler faultHandler) {
|
||||||
checkNotNull(getTrade(), "trade must not be null");
|
checkNotNull(getTrade(), "trade must not be null");
|
||||||
if (walletService.getWallet().isEncrypted()) {
|
|
||||||
walletPasswordWindow.onAesKey(aesKey -> doWithdrawRequest(toAddress, receiverAmount, aesKey, resultHandler, faultHandler)).show();
|
if (toAddress != null && toAddress.length() > 0) {
|
||||||
} else
|
tradeManager.onWithdrawRequest(
|
||||||
doWithdrawRequest(toAddress, receiverAmount, null, resultHandler, faultHandler);
|
toAddress,
|
||||||
|
receiverAmount,
|
||||||
|
aesKey,
|
||||||
|
getTrade(),
|
||||||
|
() -> {
|
||||||
|
resultHandler.handleResult();
|
||||||
|
selectBestItem();
|
||||||
|
},
|
||||||
|
(errorMessage, throwable) -> {
|
||||||
|
log.error(errorMessage);
|
||||||
|
faultHandler.handleFault(errorMessage, throwable);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
faultHandler.handleFault("No receiver address defined", null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onOpenDispute() {
|
public void onOpenDispute() {
|
||||||
|
@ -279,26 +293,6 @@ public class PendingTradesDataModel extends ActivatableDataModel {
|
||||||
selectedItemProperty.set(item);
|
selectedItemProperty.set(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doWithdrawRequest(String toAddress, Coin receiverAmount, KeyParameter aesKey, ResultHandler resultHandler, FaultHandler faultHandler) {
|
|
||||||
if (toAddress != null && toAddress.length() > 0) {
|
|
||||||
tradeManager.onWithdrawRequest(
|
|
||||||
toAddress,
|
|
||||||
receiverAmount,
|
|
||||||
aesKey,
|
|
||||||
getTrade(),
|
|
||||||
() -> {
|
|
||||||
resultHandler.handleResult();
|
|
||||||
selectBestItem();
|
|
||||||
},
|
|
||||||
(errorMessage, throwable) -> {
|
|
||||||
log.error(errorMessage);
|
|
||||||
faultHandler.handleFault(errorMessage, throwable);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
faultHandler.handleFault("No receiver address defined", null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void tryOpenDispute(boolean isSupportTicket) {
|
private void tryOpenDispute(boolean isSupportTicket) {
|
||||||
if (getTrade() != null) {
|
if (getTrade() != null) {
|
||||||
Transaction depositTx = getTrade().getDepositTx();
|
Transaction depositTx = getTrade().getDepositTx();
|
||||||
|
|
|
@ -23,6 +23,8 @@ import io.bitsquare.btc.AddressEntry;
|
||||||
import io.bitsquare.btc.AddressEntryException;
|
import io.bitsquare.btc.AddressEntryException;
|
||||||
import io.bitsquare.btc.Restrictions;
|
import io.bitsquare.btc.Restrictions;
|
||||||
import io.bitsquare.btc.WalletService;
|
import io.bitsquare.btc.WalletService;
|
||||||
|
import io.bitsquare.common.handlers.FaultHandler;
|
||||||
|
import io.bitsquare.common.handlers.ResultHandler;
|
||||||
import io.bitsquare.common.util.Tuple2;
|
import io.bitsquare.common.util.Tuple2;
|
||||||
import io.bitsquare.gui.components.InputTextField;
|
import io.bitsquare.gui.components.InputTextField;
|
||||||
import io.bitsquare.gui.main.MainView;
|
import io.bitsquare.gui.main.MainView;
|
||||||
|
@ -43,6 +45,7 @@ import javafx.scene.layout.GridPane;
|
||||||
import javafx.scene.layout.HBox;
|
import javafx.scene.layout.HBox;
|
||||||
import org.bitcoinj.core.AddressFormatException;
|
import org.bitcoinj.core.AddressFormatException;
|
||||||
import org.bitcoinj.core.Coin;
|
import org.bitcoinj.core.Coin;
|
||||||
|
import org.spongycastle.crypto.params.KeyParameter;
|
||||||
|
|
||||||
import static io.bitsquare.gui.util.FormBuilder.*;
|
import static io.bitsquare.gui.util.FormBuilder.*;
|
||||||
|
|
||||||
|
@ -150,7 +153,7 @@ public class BuyerStep5View extends TradeStepView {
|
||||||
if (!BitsquareApp.DEV_MODE && preferences.showAgain(key)) {
|
if (!BitsquareApp.DEV_MODE && preferences.showAgain(key)) {
|
||||||
preferences.dontShowAgain(key, true);
|
preferences.dontShowAgain(key, true);
|
||||||
new Notification().headLine("Trade completed")
|
new Notification().headLine("Trade completed")
|
||||||
.notification("You can withdraw your funds now to your external Bitcoin wallet.")
|
.notification("You can withdraw your funds now to your external Bitcoin wallet or transfer it to the Bitsquare wallet.")
|
||||||
.autoClose()
|
.autoClose()
|
||||||
.show();
|
.show();
|
||||||
}
|
}
|
||||||
|
@ -222,18 +225,33 @@ public class BuyerStep5View extends TradeStepView {
|
||||||
private void doWithdrawal(Coin receiverAmount) {
|
private void doWithdrawal(Coin receiverAmount) {
|
||||||
useSavingsWalletButton.setDisable(true);
|
useSavingsWalletButton.setDisable(true);
|
||||||
withdrawToExternalWalletButton.setDisable(true);
|
withdrawToExternalWalletButton.setDisable(true);
|
||||||
|
String toAddress = withdrawAddressTextField.getText();
|
||||||
|
ResultHandler resultHandler = this::handleTradeCompleted;
|
||||||
|
FaultHandler faultHandler = (errorMessage, throwable) -> {
|
||||||
|
useSavingsWalletButton.setDisable(false);
|
||||||
|
withdrawToExternalWalletButton.setDisable(false);
|
||||||
|
if (throwable != null && throwable.getMessage() != null)
|
||||||
|
new Popup().error(errorMessage + "\n\n" + throwable.getMessage()).show();
|
||||||
|
else
|
||||||
|
new Popup().error(errorMessage).show();
|
||||||
|
};
|
||||||
|
if (model.dataModel.walletService.getWallet().isEncrypted()) {
|
||||||
|
model.dataModel.walletPasswordWindow.onAesKey(aesKey -> doWithdrawRequest(toAddress, receiverAmount, aesKey, resultHandler, faultHandler))
|
||||||
|
.onClose(() -> {
|
||||||
|
useSavingsWalletButton.setDisable(false);
|
||||||
|
withdrawToExternalWalletButton.setDisable(false);
|
||||||
|
})
|
||||||
|
.show();
|
||||||
|
} else
|
||||||
|
doWithdrawRequest(toAddress, receiverAmount, null, resultHandler, faultHandler);
|
||||||
|
}
|
||||||
|
|
||||||
model.dataModel.onWithdrawRequest(withdrawAddressTextField.getText(),
|
private void doWithdrawRequest(String toAddress, Coin receiverAmount, KeyParameter aesKey, ResultHandler resultHandler, FaultHandler faultHandler) {
|
||||||
|
model.dataModel.onWithdrawRequest(toAddress,
|
||||||
receiverAmount,
|
receiverAmount,
|
||||||
this::handleTradeCompleted,
|
aesKey,
|
||||||
(errorMessage, throwable) -> {
|
resultHandler,
|
||||||
useSavingsWalletButton.setDisable(false);
|
faultHandler);
|
||||||
withdrawToExternalWalletButton.setDisable(false);
|
|
||||||
if (throwable != null && throwable.getMessage() != null)
|
|
||||||
new Popup().error(errorMessage + "\n\n" + throwable.getMessage()).show();
|
|
||||||
else
|
|
||||||
new Popup().error(errorMessage).show();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleTradeCompleted() {
|
private void handleTradeCompleted() {
|
||||||
|
|
|
@ -49,7 +49,7 @@ createOffer.amountPriceBox.error.message=An error occurred when placing the offe
|
||||||
createOffer.validation.amountSmallerThanMinAmount=Amount cannot be smaller than minimum amount.
|
createOffer.validation.amountSmallerThanMinAmount=Amount cannot be smaller than minimum amount.
|
||||||
createOffer.validation.minAmountLargerThanAmount=Minimum amount cannot be larger than amount.
|
createOffer.validation.minAmountLargerThanAmount=Minimum amount cannot be larger than amount.
|
||||||
|
|
||||||
createOffer.fundsBox.title=Fund your trade wallet
|
createOffer.fundsBox.title=Fund your offer
|
||||||
createOffer.fundsBox.totalsNeeded=Funds needed:
|
createOffer.fundsBox.totalsNeeded=Funds needed:
|
||||||
createOffer.fundsBox.totalsNeeded.prompt=Will be calculated from the bitcoin amount entered above
|
createOffer.fundsBox.totalsNeeded.prompt=Will be calculated from the bitcoin amount entered above
|
||||||
createOffer.fundsBox.address=Trade wallet address:
|
createOffer.fundsBox.address=Trade wallet address:
|
||||||
|
@ -103,7 +103,7 @@ takeOffer.validation.amountSmallerThanMinAmount=Amount cannot be smaller than mi
|
||||||
takeOffer.validation.amountLargerThanOfferAmount=Input amount cannot be higher than the amount defined in the offer.
|
takeOffer.validation.amountLargerThanOfferAmount=Input amount cannot be higher than the amount defined in the offer.
|
||||||
takeOffer.validation.amountLargerThanOfferAmountMinusFee=That input amount would create a dust change for the seller.
|
takeOffer.validation.amountLargerThanOfferAmountMinusFee=That input amount would create a dust change for the seller.
|
||||||
|
|
||||||
takeOffer.fundsBox.title=Fund your trade wallet
|
takeOffer.fundsBox.title=Fund your trade
|
||||||
takeOffer.fundsBox.isOfferAvailable=Check if offer is available...
|
takeOffer.fundsBox.isOfferAvailable=Check if offer is available...
|
||||||
takeOffer.fundsBox.totalsNeeded=Funds needed:
|
takeOffer.fundsBox.totalsNeeded=Funds needed:
|
||||||
takeOffer.fundsBox.totalsNeeded.prompt=Will be calculated from the bitcoin amount entered above
|
takeOffer.fundsBox.totalsNeeded.prompt=Will be calculated from the bitcoin amount entered above
|
||||||
|
|
Loading…
Add table
Reference in a new issue