mirror of
https://github.com/bisq-network/bisq.git
synced 2025-02-24 15:10:44 +01:00
Savings wallet (WIP)
This commit is contained in:
parent
f07aa9ba6a
commit
091eae4965
19 changed files with 288 additions and 169 deletions
|
@ -36,12 +36,12 @@ public class FeePolicy {
|
|||
// disputed payout tx: 408 bytes
|
||||
|
||||
// We set a fixed fee to make the needed amounts in the trade predictable.
|
||||
// We use 0.0003 BTC (0.12 EUR @ 400 EUR/BTC) which is for our tx sizes about 75-150 satoshi/byte
|
||||
// We use 0.0002 BTC (0.08 EUR @ 400 EUR/BTC) which is for our tx sizes about 50-90 satoshi/byte
|
||||
// We cannot make that user defined as it need to be the same for both users, so we can only change that in
|
||||
// software updates
|
||||
// TODO before Beta we should get a good future proof guess as a change causes incompatible versions
|
||||
public static Coin getFixedTxFeeForTrades() {
|
||||
return Coin.valueOf(30_000);
|
||||
return Coin.valueOf(20_000);
|
||||
}
|
||||
|
||||
// For non trade transactions (withdrawal) we use the default fee calculation
|
||||
|
@ -50,7 +50,7 @@ public class FeePolicy {
|
|||
// The BitcoinJ fee calculation use kb so a tx size < 1kb will still pay the fee for a kb tx.
|
||||
// Our payout tx has about 370 bytes so we get a fee/kb value of about 90 satoshi/byte making it high priority
|
||||
// Other payout transactions (E.g. arbitrators many collected transactions) will go with 30 satoshi/byte if > 1kb
|
||||
private static Coin FEE_PER_KB = Coin.valueOf(30_000); // 0.0003 BTC about 0.12 EUR @ 400 EUR/BTC
|
||||
private static Coin FEE_PER_KB = Coin.valueOf(20_000); // 0.0002 BTC about 0.08 EUR @ 400 EUR/BTC
|
||||
|
||||
public static void setFeePerKb(Coin feePerKb) {
|
||||
FEE_PER_KB = feePerKb;
|
||||
|
@ -84,8 +84,8 @@ public class FeePolicy {
|
|||
|
||||
|
||||
// TODO will be increased once we get higher limits
|
||||
// 0.01 BTC; about 0.4 EUR @ 400 EUR/BTC
|
||||
// 0.02 BTC; about 8 EUR @ 400 EUR/BTC
|
||||
public static Coin getSecurityDeposit() {
|
||||
return Coin.valueOf(1_000_000);
|
||||
return Coin.valueOf(2_000_000);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -333,6 +333,12 @@ public class WalletService {
|
|||
.findAny();
|
||||
}
|
||||
|
||||
public List<AddressEntry> getTradeAddressEntryList() {
|
||||
return getAddressEntryList().stream()
|
||||
.filter(e -> e.getContext().equals(AddressEntry.Context.TRADE))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SavingsAddressEntry
|
||||
|
@ -493,6 +499,10 @@ public class WalletService {
|
|||
return wallet != null ? getBalance(wallet.calculateAllSpendCandidates(), address) : Coin.ZERO;
|
||||
}
|
||||
|
||||
public Coin getBalanceForAddressEntryWithTradeId(String tradeId) {
|
||||
return getBalanceForAddress(getTradeAddressEntry(tradeId).getAddress());
|
||||
}
|
||||
|
||||
private Coin getBalance(List<TransactionOutput> transactionOutputs, Address address) {
|
||||
Coin balance = Coin.ZERO;
|
||||
for (TransactionOutput transactionOutput : transactionOutputs) {
|
||||
|
@ -539,7 +549,8 @@ public class WalletService {
|
|||
Coin fee;
|
||||
try {
|
||||
wallet.completeTx(getSendRequest(fromAddress, toAddress, amount, aesKey));
|
||||
fee = Coin.ZERO;
|
||||
// We use the min fee for now as the mix of savingswallet/trade wallet has some nasty edge cases...
|
||||
fee = FeePolicy.getFixedTxFeeForTrades();
|
||||
} catch (InsufficientMoneyException e) {
|
||||
log.info("The amount to be transferred is not enough to pay the transaction fees of {}. " +
|
||||
"We subtract that fee from the receivers amount to make the transaction possible.");
|
||||
|
@ -556,7 +567,8 @@ public class WalletService {
|
|||
Coin fee;
|
||||
try {
|
||||
wallet.completeTx(getSendRequestForMultipleAddresses(fromAddresses, toAddress, amount, null, aesKey));
|
||||
fee = Coin.ZERO;
|
||||
// We use the min fee for now as the mix of savingswallet/trade wallet has some nasty edge cases...
|
||||
fee = FeePolicy.getFixedTxFeeForTrades();
|
||||
} catch (InsufficientMoneyException e) {
|
||||
log.info("The amount to be transferred is not enough to pay the transaction fees of {}. " +
|
||||
"We subtract that fee from the receivers amount to make the transaction possible.");
|
||||
|
|
|
@ -67,18 +67,18 @@ public final class PaymentMethod implements Persistable, Comparable {
|
|||
public static PaymentMethod BLOCK_CHAINS;
|
||||
|
||||
public static final List<PaymentMethod> ALL_VALUES = new ArrayList<>(Arrays.asList(
|
||||
OK_PAY = new PaymentMethod(OK_PAY_ID, 0, DAY, Coin.parseCoin("0.4")), // tx instant so min. wait time
|
||||
PERFECT_MONEY = new PaymentMethod(PERFECT_MONEY_ID, 0, DAY, Coin.parseCoin("0.4")),
|
||||
SEPA = new PaymentMethod(SEPA_ID, 0, 8 * DAY, Coin.parseCoin("0.3")), // sepa takes 1-3 business days. We use 8 days to include safety for holidays
|
||||
NATIONAL_BANK = new PaymentMethod(NATIONAL_BANK_ID, 0, 4 * DAY, Coin.parseCoin("0.3")),
|
||||
SAME_BANK = new PaymentMethod(SAME_BANK_ID, 0, 2 * DAY, Coin.parseCoin("0.3")),
|
||||
SPECIFIC_BANKS = new PaymentMethod(SPECIFIC_BANKS_ID, 0, 4 * DAY, Coin.parseCoin("0.3")),
|
||||
SWISH = new PaymentMethod(SWISH_ID, 0, DAY, Coin.parseCoin("0.4")),
|
||||
ALI_PAY = new PaymentMethod(ALI_PAY_ID, 0, DAY, Coin.parseCoin("0.4")),
|
||||
OK_PAY = new PaymentMethod(OK_PAY_ID, 0, DAY, Coin.parseCoin("1")), // tx instant so min. wait time
|
||||
SEPA = new PaymentMethod(SEPA_ID, 0, 8 * DAY, Coin.parseCoin("0.5")), // sepa takes 1-3 business days. We use 8 days to include safety for holidays
|
||||
NATIONAL_BANK = new PaymentMethod(NATIONAL_BANK_ID, 0, 4 * DAY, Coin.parseCoin("0.5")),
|
||||
SAME_BANK = new PaymentMethod(SAME_BANK_ID, 0, 2 * DAY, Coin.parseCoin("0.5")),
|
||||
SPECIFIC_BANKS = new PaymentMethod(SPECIFIC_BANKS_ID, 0, 4 * DAY, Coin.parseCoin("0.5")),
|
||||
PERFECT_MONEY = new PaymentMethod(PERFECT_MONEY_ID, 0, DAY, Coin.parseCoin("0.75")),
|
||||
SWISH = new PaymentMethod(SWISH_ID, 0, DAY, Coin.parseCoin("0.75")),
|
||||
ALI_PAY = new PaymentMethod(ALI_PAY_ID, 0, DAY, Coin.parseCoin("0.75")),
|
||||
/* FED_WIRE = new PaymentMethod(FED_WIRE_ID, 0, DAY, Coin.parseCoin("0.1")),*/
|
||||
/* TRANSFER_WISE = new PaymentMethod(TRANSFER_WISE_ID, 0, DAY, Coin.parseCoin("0.1")),*/
|
||||
/* US_POSTAL_MONEY_ORDER = new PaymentMethod(US_POSTAL_MONEY_ORDER_ID, 0, DAY, Coin.parseCoin("0.1")),*/
|
||||
BLOCK_CHAINS = new PaymentMethod(BLOCK_CHAINS_ID, 0, DAY, Coin.parseCoin("0.5"))
|
||||
BLOCK_CHAINS = new PaymentMethod(BLOCK_CHAINS_ID, 0, DAY, Coin.parseCoin("1"))
|
||||
));
|
||||
|
||||
|
||||
|
|
|
@ -1,36 +0,0 @@
|
|||
package io.bitsquare.trade;
|
||||
|
||||
import io.bitsquare.btc.AddressEntry;
|
||||
import io.bitsquare.btc.WalletService;
|
||||
import io.bitsquare.trade.offer.OpenOfferManager;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class TradableCollections {
|
||||
private static final Logger log = LoggerFactory.getLogger(TradableCollections.class);
|
||||
|
||||
public static List<AddressEntry> getAddressEntriesForAvailableBalance(OpenOfferManager openOfferManager, TradeManager tradeManager, WalletService walletService) {
|
||||
Set<String> reservedTrades = getNotCompletedTradableItems(openOfferManager, tradeManager).stream()
|
||||
.map(tradable -> tradable.getOffer().getId())
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
List<AddressEntry> list = new ArrayList<>();
|
||||
list.addAll(walletService.getAddressEntryList().stream()
|
||||
.filter(e -> walletService.getBalanceForAddress(e.getAddress()).isPositive())
|
||||
.filter(e -> !reservedTrades.contains(e.getOfferId()))
|
||||
.collect(Collectors.toList()));
|
||||
return list;
|
||||
}
|
||||
|
||||
public static Set<Tradable> getNotCompletedTradableItems(OpenOfferManager openOfferManager, TradeManager tradeManager) {
|
||||
return Stream.concat(openOfferManager.getOpenOffers().stream(), tradeManager.getTrades().stream())
|
||||
.filter(tradable -> !(tradable instanceof Trade) || ((Trade) tradable).getState().getPhase() != Trade.Phase.PAYOUT_PAID)
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
}
|
110
core/src/main/java/io/bitsquare/trade/TradableHelper.java
Normal file
110
core/src/main/java/io/bitsquare/trade/TradableHelper.java
Normal file
|
@ -0,0 +1,110 @@
|
|||
package io.bitsquare.trade;
|
||||
|
||||
import io.bitsquare.btc.AddressEntry;
|
||||
import io.bitsquare.btc.FeePolicy;
|
||||
import io.bitsquare.btc.WalletService;
|
||||
import io.bitsquare.trade.closed.ClosedTradableManager;
|
||||
import io.bitsquare.trade.failed.FailedTradesManager;
|
||||
import io.bitsquare.trade.offer.Offer;
|
||||
import io.bitsquare.trade.offer.OpenOffer;
|
||||
import io.bitsquare.trade.offer.OpenOfferManager;
|
||||
import org.bitcoinj.core.Coin;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class TradableHelper {
|
||||
private static final Logger log = LoggerFactory.getLogger(TradableHelper.class);
|
||||
|
||||
public static List<AddressEntry> getAddressEntriesForAvailableBalance(OpenOfferManager openOfferManager, TradeManager tradeManager, WalletService walletService) {
|
||||
Set<String> reservedTradeIds = getNotCompletedTradableItems(openOfferManager, tradeManager).stream()
|
||||
.map(tradable -> tradable.getOffer().getId())
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
return walletService.getAddressEntryList().stream()
|
||||
.filter(e -> walletService.getBalanceForAddress(e.getAddress()).isPositive())
|
||||
.filter(e -> !reservedTradeIds.contains(e.getOfferId()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public static Set<Tradable> getNotCompletedTradableItems(OpenOfferManager openOfferManager, TradeManager tradeManager) {
|
||||
return Stream.concat(openOfferManager.getOpenOffers().stream(), tradeManager.getTrades().stream())
|
||||
.filter(tradable -> !(tradable instanceof Trade) || ((Trade) tradable).getState().getPhase() != Trade.Phase.PAYOUT_PAID)
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
public static Coin getBalanceInOpenOffer(OpenOffer openOffer) {
|
||||
Offer offer = openOffer.getOffer();
|
||||
Coin balance = FeePolicy.getSecurityDeposit().add(FeePolicy.getFeePerKb());
|
||||
// For the seller we add the trade amount
|
||||
if (offer.getDirection() == Offer.Direction.SELL)
|
||||
balance = balance.add(offer.getAmount());
|
||||
|
||||
return balance;
|
||||
}
|
||||
|
||||
public static Coin getBalanceInTrade(Trade trade, WalletService walletService) {
|
||||
AddressEntry addressEntry = walletService.getTradeAddressEntry(trade.getId());
|
||||
Coin balance = FeePolicy.getSecurityDeposit().add(FeePolicy.getFeePerKb());
|
||||
// For the seller we add the trade amount
|
||||
if (trade.getContract() != null &&
|
||||
trade.getTradeAmount() != null &&
|
||||
trade.getContract().getSellerPayoutAddressString().equals(addressEntry.getAddressString()))
|
||||
balance = balance.add(trade.getTradeAmount());
|
||||
return balance;
|
||||
}
|
||||
|
||||
public static Coin getAvailableBalance(AddressEntry addressEntry, WalletService walletService,
|
||||
OpenOfferManager openOfferManager, TradeManager tradeManager,
|
||||
ClosedTradableManager closedTradableManager,
|
||||
FailedTradesManager failedTradesManager) {
|
||||
Coin balance;
|
||||
Coin totalBalance = walletService.getBalanceForAddress(addressEntry.getAddress());
|
||||
String id = addressEntry.getOfferId();
|
||||
Optional<OpenOffer> openOfferOptional = openOfferManager.getOpenOfferById(id);
|
||||
Optional<Trade> tradeOptional = tradeManager.getTradeById(id);
|
||||
Optional<Tradable> closedTradableOptional = closedTradableManager.getTradableById(id);
|
||||
Optional<Trade> failedTradesOptional = failedTradesManager.getTradeById(id);
|
||||
|
||||
if (openOfferOptional.isPresent()) {
|
||||
balance = totalBalance.subtract(TradableHelper.getBalanceInOpenOffer(openOfferOptional.get()));
|
||||
} else if (tradeOptional.isPresent()) {
|
||||
Trade trade = tradeOptional.get();
|
||||
if (trade.getState().getPhase() != Trade.Phase.PAYOUT_PAID)
|
||||
balance = totalBalance.subtract(TradableHelper.getBalanceInTrade(trade, walletService));
|
||||
else
|
||||
balance = totalBalance;
|
||||
} else if (closedTradableOptional.isPresent()) {
|
||||
Tradable tradable = closedTradableOptional.get();
|
||||
Coin balanceInTrade = Coin.ZERO;
|
||||
if (tradable instanceof OpenOffer)
|
||||
balanceInTrade = TradableHelper.getBalanceInOpenOffer((OpenOffer) tradable);
|
||||
else if (tradable instanceof Trade)
|
||||
balanceInTrade = TradableHelper.getBalanceInTrade((Trade) tradable, walletService);
|
||||
balance = totalBalance.subtract(balanceInTrade);
|
||||
} else if (failedTradesOptional.isPresent()) {
|
||||
balance = totalBalance.subtract(TradableHelper.getBalanceInTrade(failedTradesOptional.get(), walletService));
|
||||
} else {
|
||||
balance = totalBalance;
|
||||
}
|
||||
return balance;
|
||||
}
|
||||
|
||||
public static Coin getReservedBalance(Tradable tradable, WalletService walletService) {
|
||||
AddressEntry addressEntry = walletService.getTradeAddressEntry(tradable.getId());
|
||||
Coin balance = walletService.getBalanceForAddress(addressEntry.getAddress());
|
||||
if (tradable instanceof Trade) {
|
||||
Trade trade = (Trade) tradable;
|
||||
if (trade.getState().getPhase().ordinal() < Trade.Phase.PAYOUT_PAID.ordinal())
|
||||
balance = TradableHelper.getBalanceInTrade(trade, walletService);
|
||||
} else if (tradable instanceof OpenOffer) {
|
||||
balance = TradableHelper.getBalanceInOpenOffer((OpenOffer) tradable);
|
||||
}
|
||||
return balance;
|
||||
}
|
||||
}
|
|
@ -147,7 +147,7 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
|||
public void closeAllOpenOffers(@Nullable Runnable completeHandler) {
|
||||
openOffers.forEach(openOffer -> offerBookService.removeOfferAtShutDown(openOffer.getOffer()));
|
||||
if (completeHandler != null)
|
||||
UserThread.runAfter(completeHandler::run, openOffers.size() * 200 + 300, TimeUnit.MILLISECONDS);
|
||||
UserThread.runAfter(completeHandler::run, openOffers.size() * 100 + 200, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -55,9 +55,11 @@ import io.bitsquare.p2p.network.Connection;
|
|||
import io.bitsquare.p2p.network.ConnectionListener;
|
||||
import io.bitsquare.p2p.peers.keepalive.messages.Ping;
|
||||
import io.bitsquare.payment.OKPayAccount;
|
||||
import io.bitsquare.trade.TradableCollections;
|
||||
import io.bitsquare.trade.TradableHelper;
|
||||
import io.bitsquare.trade.Trade;
|
||||
import io.bitsquare.trade.TradeManager;
|
||||
import io.bitsquare.trade.closed.ClosedTradableManager;
|
||||
import io.bitsquare.trade.failed.FailedTradesManager;
|
||||
import io.bitsquare.trade.offer.OpenOffer;
|
||||
import io.bitsquare.trade.offer.OpenOfferManager;
|
||||
import io.bitsquare.user.Preferences;
|
||||
|
@ -80,6 +82,7 @@ import java.util.Optional;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class MainViewModel implements ViewModel {
|
||||
private static final Logger log = LoggerFactory.getLogger(MainViewModel.class);
|
||||
|
@ -137,6 +140,8 @@ public class MainViewModel implements ViewModel {
|
|||
|
||||
private MonadicBinding<Boolean> allServicesDone, tradesAndUIReady;
|
||||
private final PriceFeed priceFeed;
|
||||
private final ClosedTradableManager closedTradableManager;
|
||||
private final FailedTradesManager failedTradesManager;
|
||||
private final User user;
|
||||
private int numBtcPeers = 0;
|
||||
private Timer checkNumberOfBtcPeersTimer;
|
||||
|
@ -153,11 +158,14 @@ public class MainViewModel implements ViewModel {
|
|||
public MainViewModel(WalletService walletService, TradeWalletService tradeWalletService,
|
||||
PriceFeed priceFeed,
|
||||
ArbitratorManager arbitratorManager, P2PService p2PService, TradeManager tradeManager,
|
||||
OpenOfferManager openOfferManager, DisputeManager disputeManager, Preferences preferences,
|
||||
OpenOfferManager openOfferManager, ClosedTradableManager closedTradableManager,
|
||||
FailedTradesManager failedTradesManager, DisputeManager disputeManager, Preferences preferences,
|
||||
User user, AlertManager alertManager, WalletPasswordWindow walletPasswordWindow,
|
||||
NotificationCenter notificationCenter, TacWindow tacWindow, Clock clock,
|
||||
KeyRing keyRing, Navigation navigation, BSFormatter formatter) {
|
||||
this.priceFeed = priceFeed;
|
||||
this.closedTradableManager = closedTradableManager;
|
||||
this.failedTradesManager = failedTradesManager;
|
||||
this.user = user;
|
||||
this.walletService = walletService;
|
||||
this.tradeWalletService = tradeWalletService;
|
||||
|
@ -670,7 +678,7 @@ public class MainViewModel implements ViewModel {
|
|||
}
|
||||
|
||||
private void swapPendingTradeAddressEntriesToSavingsWallet() {
|
||||
TradableCollections.getAddressEntriesForAvailableBalance(openOfferManager, tradeManager, walletService).stream()
|
||||
TradableHelper.getAddressEntriesForAvailableBalance(openOfferManager, tradeManager, walletService).stream()
|
||||
.filter(addressEntry -> addressEntry.getOfferId() != null)
|
||||
.forEach(addressEntry -> walletService.swapTradeToSavings(addressEntry.getOfferId()));
|
||||
}
|
||||
|
@ -691,12 +699,36 @@ public class MainViewModel implements ViewModel {
|
|||
updateLockedBalance();
|
||||
}
|
||||
|
||||
private void updateAvailableBalance() {
|
||||
Optional<Coin> totalAvailableOptional = Stream.concat(walletService.getSavingsAddressEntryList().stream(), walletService.getTradeAddressEntryList().stream())
|
||||
.filter(addressEntry -> walletService.getBalanceForAddress(addressEntry.getAddress()).isPositive())
|
||||
.map(addressEntry -> TradableHelper.getAvailableBalance(addressEntry,
|
||||
walletService,
|
||||
openOfferManager,
|
||||
tradeManager,
|
||||
closedTradableManager,
|
||||
failedTradesManager))
|
||||
.filter(balance -> balance.isPositive())
|
||||
.reduce(Coin::add);
|
||||
|
||||
|
||||
/*Optional<Coin> totalAvailableOptional = TradableHelper.getAddressEntriesForAvailableBalance(openOfferManager, tradeManager, walletService)
|
||||
.stream()
|
||||
.map(e -> walletService.getBalanceForAddress(e.getAddress()))
|
||||
.reduce(Coin::add);*/
|
||||
if (totalAvailableOptional.isPresent())
|
||||
availableBalance.set(formatter.formatCoinWithCode(totalAvailableOptional.get()));
|
||||
else
|
||||
availableBalance.set(formatter.formatCoinWithCode(Coin.ZERO));
|
||||
}
|
||||
|
||||
private void updateReservedBalance() {
|
||||
Coin sum = Coin.valueOf(TradableCollections.getNotCompletedTradableItems(openOfferManager, tradeManager).stream()
|
||||
.map(tradable -> walletService.getTradeAddressEntry(tradable.getId()))
|
||||
.map(addressEntry -> walletService.getBalanceForAddress(addressEntry.getAddress()))
|
||||
Coin sum = Coin.valueOf(TradableHelper.getNotCompletedTradableItems(openOfferManager, tradeManager).stream()
|
||||
.filter(tradable -> tradable instanceof OpenOffer)
|
||||
.map(tradable -> TradableHelper.getReservedBalance(tradable, walletService))
|
||||
.mapToLong(Coin::getValue)
|
||||
.sum());
|
||||
|
||||
reservedBalance.set(formatter.formatCoinWithCode(sum));
|
||||
}
|
||||
|
||||
|
@ -725,17 +757,6 @@ public class MainViewModel implements ViewModel {
|
|||
lockedBalance.set(formatter.formatCoinWithCode(sum));
|
||||
}
|
||||
|
||||
private void updateAvailableBalance() {
|
||||
Optional<Coin> totalAvailableOptional = TradableCollections.getAddressEntriesForAvailableBalance(openOfferManager, tradeManager, walletService)
|
||||
.stream()
|
||||
.map(e -> walletService.getBalanceForAddress(e.getAddress())).reduce(Coin::add);
|
||||
if (totalAvailableOptional.isPresent())
|
||||
availableBalance.set(formatter.formatCoinWithCode(totalAvailableOptional.get()));
|
||||
else
|
||||
availableBalance.set(formatter.formatCoinWithCode(Coin.ZERO));
|
||||
}
|
||||
|
||||
|
||||
private void onDisputesChangeListener(List<? extends Dispute> addedList, @Nullable List<? extends Dispute> removedList) {
|
||||
if (removedList != null) {
|
||||
removedList.stream().forEach(dispute -> {
|
||||
|
|
|
@ -83,19 +83,6 @@ public class FundsView extends ActivatableViewAndModel<TabPane, Activatable> {
|
|||
navigation.navigateTo(MainView.class, FundsView.class, ReservedView.class);
|
||||
else if (root.getSelectionModel().getSelectedItem() == transactionsTab)
|
||||
navigation.navigateTo(MainView.class, FundsView.class, TransactionsView.class);
|
||||
|
||||
String key = "tradeWalletInfoAtFunds";
|
||||
/* if (!BitsquareApp.DEV_MODE)
|
||||
new Popup().backgroundInfo("Bitsquare does not use a single application wallet, but dedicated wallets for every trade.\n\n" +
|
||||
"Funding of the wallet will be done when needed, for instance when you create or take an offer.\n" +
|
||||
"Withdrawing funds can be done after a trade is completed.\n\n" +
|
||||
"Dedicated wallets help protect user privacy and prevent leaking information of previous trades to other " +
|
||||
"traders.")
|
||||
.actionButtonText("Visit FAQ web page")
|
||||
.onAction(() -> Utilities.openWebPage("https://bitsquare.io/faq"))
|
||||
.closeButtonText("I understand")
|
||||
.dontShowAgainId(key, preferences)
|
||||
.show();*/
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -132,7 +132,7 @@ public class DepositView extends ActivatableView<VBox, Void> {
|
|||
.compareTo(o2.getProgressIndicator().getProgress()));
|
||||
usageColumn.setComparator((a, b) -> (a.getNumTxOutputs() < b.getNumTxOutputs()) ? -1 : ((a.getNumTxOutputs() == b.getNumTxOutputs()) ? 0 : 1));
|
||||
tableView.getSortOrder().add(usageColumn);
|
||||
|
||||
tableView.setItems(sortedList);
|
||||
|
||||
titledGroupBg = addTitledGroupBg(gridPane, gridRow, 3, "Fund your wallet");
|
||||
|
||||
|
@ -209,7 +209,7 @@ public class DepositView extends ActivatableView<VBox, Void> {
|
|||
protected void activate() {
|
||||
tableView.getSelectionModel().selectedItemProperty().addListener(tableViewSelectionListener);
|
||||
sortedList.comparatorProperty().bind(tableView.comparatorProperty());
|
||||
tableView.setItems(sortedList);
|
||||
|
||||
updateList();
|
||||
|
||||
walletService.addBalanceListener(balanceListener);
|
||||
|
|
|
@ -18,11 +18,11 @@
|
|||
package io.bitsquare.gui.main.funds.reserved;
|
||||
|
||||
import io.bitsquare.btc.AddressEntry;
|
||||
import io.bitsquare.btc.FeePolicy;
|
||||
import io.bitsquare.btc.WalletService;
|
||||
import io.bitsquare.btc.listeners.BalanceListener;
|
||||
import io.bitsquare.gui.util.BSFormatter;
|
||||
import io.bitsquare.trade.Tradable;
|
||||
import io.bitsquare.trade.TradableHelper;
|
||||
import io.bitsquare.trade.Trade;
|
||||
import io.bitsquare.trade.offer.OpenOffer;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
|
@ -62,60 +62,50 @@ public class ReservedListItem {
|
|||
balanceListener = new BalanceListener(getAddress()) {
|
||||
@Override
|
||||
public void onBalanceChanged(Coin balance, Transaction tx) {
|
||||
updateBalance(balance);
|
||||
updateBalance();
|
||||
}
|
||||
};
|
||||
walletService.addBalanceListener(balanceListener);
|
||||
updateBalance(walletService.getBalanceForAddress(getAddress()));
|
||||
updateBalance();
|
||||
}
|
||||
|
||||
public void cleanup() {
|
||||
walletService.removeBalanceListener(balanceListener);
|
||||
}
|
||||
|
||||
private void updateBalance(Coin balance) {
|
||||
this.balance = balance;
|
||||
if (balance != null) {
|
||||
balanceLabel.setText(formatter.formatCoin(balance));
|
||||
private void updateBalance() {
|
||||
balance = TradableHelper.getReservedBalance(tradable, walletService);
|
||||
if (balance != null)
|
||||
balanceLabel.setText(formatter.formatCoin(this.balance));
|
||||
|
||||
if (tradable instanceof Trade) {
|
||||
Trade trade = (Trade) tradable;
|
||||
Trade.Phase phase = trade.getState().getPhase();
|
||||
switch (phase) {
|
||||
case PREPARATION:
|
||||
case TAKER_FEE_PAID:
|
||||
fundsInfo = "Reserved in local wallet";
|
||||
break;
|
||||
case DEPOSIT_REQUESTED:
|
||||
case DEPOSIT_PAID:
|
||||
case FIAT_SENT:
|
||||
case FIAT_RECEIVED:
|
||||
fundsInfo = "Locked in MultiSig";
|
||||
// We ignore the tx fee as it will be paid by both (once deposit, once payout)
|
||||
Coin balanceInDeposit = FeePolicy.getSecurityDeposit().add(FeePolicy.getFeePerKb());
|
||||
// For the seller we add the trade amount
|
||||
if (trade.getContract() != null &&
|
||||
trade.getTradeAmount() != null &&
|
||||
trade.getContract().getSellerPayoutAddressString().equals(addressString))
|
||||
balanceInDeposit = balanceInDeposit.add(trade.getTradeAmount());
|
||||
|
||||
balanceLabel.setText(formatter.formatCoin(balanceInDeposit));
|
||||
break;
|
||||
case PAYOUT_PAID:
|
||||
fundsInfo = "Received in local wallet";
|
||||
break;
|
||||
case WITHDRAWN:
|
||||
log.error("Invalid state at updateBalance (WITHDRAWN)");
|
||||
break;
|
||||
case DISPUTE:
|
||||
log.error("Invalid state at updateBalance (DISPUTE)");
|
||||
break;
|
||||
default:
|
||||
log.warn("Not supported tradePhase: " + phase);
|
||||
}
|
||||
} else if (tradable instanceof OpenOffer) {
|
||||
fundsInfo = "Reserved in local wallet";
|
||||
if (tradable instanceof Trade) {
|
||||
Trade trade = (Trade) tradable;
|
||||
Trade.Phase phase = trade.getState().getPhase();
|
||||
switch (phase) {
|
||||
case PREPARATION:
|
||||
case TAKER_FEE_PAID:
|
||||
fundsInfo = "Reserved in local wallet";
|
||||
break;
|
||||
case DEPOSIT_REQUESTED:
|
||||
case DEPOSIT_PAID:
|
||||
case FIAT_SENT:
|
||||
case FIAT_RECEIVED:
|
||||
fundsInfo = "Locked in MultiSig";
|
||||
break;
|
||||
case PAYOUT_PAID:
|
||||
fundsInfo = "Received in local wallet";
|
||||
break;
|
||||
case WITHDRAWN:
|
||||
log.error("Invalid state at updateBalance (WITHDRAWN)");
|
||||
break;
|
||||
case DISPUTE:
|
||||
log.error("Invalid state at updateBalance (DISPUTE)");
|
||||
break;
|
||||
default:
|
||||
log.warn("Not supported tradePhase: " + phase);
|
||||
}
|
||||
} else if (tradable instanceof OpenOffer) {
|
||||
fundsInfo = "Reserved in local wallet";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ import io.bitsquare.gui.main.overlays.windows.OfferDetailsWindow;
|
|||
import io.bitsquare.gui.main.overlays.windows.TradeDetailsWindow;
|
||||
import io.bitsquare.gui.util.BSFormatter;
|
||||
import io.bitsquare.trade.Tradable;
|
||||
import io.bitsquare.trade.TradableCollections;
|
||||
import io.bitsquare.trade.TradableHelper;
|
||||
import io.bitsquare.trade.Trade;
|
||||
import io.bitsquare.trade.TradeManager;
|
||||
import io.bitsquare.trade.offer.OpenOffer;
|
||||
|
@ -38,6 +38,7 @@ import io.bitsquare.trade.offer.OpenOfferManager;
|
|||
import io.bitsquare.user.Preferences;
|
||||
import javafx.beans.property.ReadOnlyObjectWrapper;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ListChangeListener;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.collections.transformation.SortedList;
|
||||
import javafx.fxml.FXML;
|
||||
|
@ -68,6 +69,8 @@ public class ReservedView extends ActivatableView<VBox, Void> {
|
|||
private final ObservableList<ReservedListItem> observableList = FXCollections.observableArrayList();
|
||||
private final SortedList<ReservedListItem> sortedList = new SortedList<>(observableList);
|
||||
private BalanceListener balanceListener;
|
||||
private ListChangeListener<OpenOffer> openOfferListChangeListener;
|
||||
private ListChangeListener<Trade> tradeListChangeListener;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -86,7 +89,6 @@ public class ReservedView extends ActivatableView<VBox, Void> {
|
|||
this.tradeDetailsWindow = tradeDetailsWindow;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
|
||||
|
@ -100,7 +102,12 @@ public class ReservedView extends ActivatableView<VBox, Void> {
|
|||
addressColumn.setComparator((o1, o2) -> o1.getAddressString().compareTo(o2.getAddressString()));
|
||||
detailsColumn.setComparator((o1, o2) -> o1.getTradable().getId().compareTo(o2.getTradable().getId()));
|
||||
balanceColumn.setComparator((o1, o2) -> o1.getBalance().compareTo(o2.getBalance()));
|
||||
dateColumn.setComparator((o1, o2) -> getTradable(o2).get().getDate().compareTo(getTradable(o1).get().getDate()));
|
||||
dateColumn.setComparator((o1, o2) -> {
|
||||
if (getTradable(o1).isPresent() && getTradable(o2).isPresent())
|
||||
return getTradable(o2).get().getDate().compareTo(getTradable(o1).get().getDate());
|
||||
else
|
||||
return 0;
|
||||
});
|
||||
tableView.getSortOrder().add(dateColumn);
|
||||
dateColumn.setSortType(TableColumn.SortType.DESCENDING);
|
||||
|
||||
|
@ -110,10 +117,14 @@ public class ReservedView extends ActivatableView<VBox, Void> {
|
|||
updateList();
|
||||
}
|
||||
};
|
||||
openOfferListChangeListener = c -> updateList();
|
||||
tradeListChangeListener = c -> updateList();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void activate() {
|
||||
openOfferManager.getOpenOffers().addListener(openOfferListChangeListener);
|
||||
tradeManager.getTrades().addListener(tradeListChangeListener);
|
||||
sortedList.comparatorProperty().bind(tableView.comparatorProperty());
|
||||
tableView.setItems(sortedList);
|
||||
updateList();
|
||||
|
@ -123,6 +134,8 @@ public class ReservedView extends ActivatableView<VBox, Void> {
|
|||
|
||||
@Override
|
||||
protected void deactivate() {
|
||||
openOfferManager.getOpenOffers().removeListener(openOfferListChangeListener);
|
||||
tradeManager.getTrades().removeListener(tradeListChangeListener);
|
||||
sortedList.comparatorProperty().unbind();
|
||||
observableList.forEach(ReservedListItem::cleanup);
|
||||
walletService.removeBalanceListener(balanceListener);
|
||||
|
@ -135,9 +148,7 @@ public class ReservedView extends ActivatableView<VBox, Void> {
|
|||
|
||||
private void updateList() {
|
||||
observableList.forEach(ReservedListItem::cleanup);
|
||||
|
||||
|
||||
observableList.setAll(TradableCollections.getNotCompletedTradableItems(openOfferManager, tradeManager).stream()
|
||||
observableList.setAll(TradableHelper.getNotCompletedTradableItems(openOfferManager, tradeManager).stream()
|
||||
.map(tradable -> new ReservedListItem(tradable, walletService.getTradeAddressEntry(tradable.getOffer().getId()), walletService, formatter))
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
|
|
|
@ -21,6 +21,11 @@ import io.bitsquare.btc.AddressEntry;
|
|||
import io.bitsquare.btc.WalletService;
|
||||
import io.bitsquare.btc.listeners.BalanceListener;
|
||||
import io.bitsquare.gui.util.BSFormatter;
|
||||
import io.bitsquare.trade.TradableHelper;
|
||||
import io.bitsquare.trade.TradeManager;
|
||||
import io.bitsquare.trade.closed.ClosedTradableManager;
|
||||
import io.bitsquare.trade.failed.FailedTradesManager;
|
||||
import io.bitsquare.trade.offer.OpenOfferManager;
|
||||
import javafx.scene.control.Label;
|
||||
import org.bitcoinj.core.Address;
|
||||
import org.bitcoinj.core.Coin;
|
||||
|
@ -31,13 +36,25 @@ public class WithdrawalListItem {
|
|||
private final Label balanceLabel;
|
||||
private final AddressEntry addressEntry;
|
||||
private final WalletService walletService;
|
||||
private final OpenOfferManager openOfferManager;
|
||||
private final TradeManager tradeManager;
|
||||
private final ClosedTradableManager closedTradableManager;
|
||||
private final FailedTradesManager failedTradesManager;
|
||||
private final BSFormatter formatter;
|
||||
private Coin balance;
|
||||
private final String addressString;
|
||||
|
||||
public WithdrawalListItem(AddressEntry addressEntry, WalletService walletService, BSFormatter formatter) {
|
||||
public WithdrawalListItem(AddressEntry addressEntry, WalletService walletService,
|
||||
OpenOfferManager openOfferManager, TradeManager tradeManager,
|
||||
ClosedTradableManager closedTradableManager,
|
||||
FailedTradesManager failedTradesManager,
|
||||
BSFormatter formatter) {
|
||||
this.addressEntry = addressEntry;
|
||||
this.walletService = walletService;
|
||||
this.openOfferManager = openOfferManager;
|
||||
this.tradeManager = tradeManager;
|
||||
this.closedTradableManager = closedTradableManager;
|
||||
this.failedTradesManager = failedTradesManager;
|
||||
this.formatter = formatter;
|
||||
addressString = addressEntry.getAddressString();
|
||||
|
||||
|
@ -46,23 +63,28 @@ public class WithdrawalListItem {
|
|||
balanceListener = new BalanceListener(getAddress()) {
|
||||
@Override
|
||||
public void onBalanceChanged(Coin balance, Transaction tx) {
|
||||
updateBalance(balance);
|
||||
updateBalance();
|
||||
}
|
||||
};
|
||||
walletService.addBalanceListener(balanceListener);
|
||||
|
||||
updateBalance(walletService.getBalanceForAddress(getAddress()));
|
||||
updateBalance();
|
||||
}
|
||||
|
||||
public void cleanup() {
|
||||
walletService.removeBalanceListener(balanceListener);
|
||||
}
|
||||
|
||||
private void updateBalance(Coin balance) {
|
||||
this.balance = balance;
|
||||
if (balance != null) {
|
||||
balanceLabel.setText(formatter.formatCoin(balance));
|
||||
}
|
||||
private void updateBalance() {
|
||||
balance = TradableHelper.getAvailableBalance(addressEntry,
|
||||
walletService,
|
||||
openOfferManager,
|
||||
tradeManager,
|
||||
closedTradableManager,
|
||||
failedTradesManager);
|
||||
|
||||
if (balance != null)
|
||||
balanceLabel.setText(formatter.formatCoin(this.balance));
|
||||
}
|
||||
|
||||
public final String getLabel() {
|
||||
|
|
|
@ -34,7 +34,6 @@ import io.bitsquare.gui.main.overlays.windows.WalletPasswordWindow;
|
|||
import io.bitsquare.gui.util.BSFormatter;
|
||||
import io.bitsquare.gui.util.validation.BtcAddressValidator;
|
||||
import io.bitsquare.trade.Tradable;
|
||||
import io.bitsquare.trade.TradableCollections;
|
||||
import io.bitsquare.trade.Trade;
|
||||
import io.bitsquare.trade.TradeManager;
|
||||
import io.bitsquare.trade.closed.ClosedTradableManager;
|
||||
|
@ -61,6 +60,7 @@ import org.spongycastle.crypto.params.KeyParameter;
|
|||
import javax.inject.Inject;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@FxmlView
|
||||
public class WithdrawalView extends ActivatableView<VBox, Void> {
|
||||
|
@ -197,7 +197,7 @@ public class WithdrawalView extends ActivatableView<VBox, Void> {
|
|||
withdrawToTextField.getText(), senderAmount, null);
|
||||
Coin receiverAmount = senderAmount.subtract(requiredFee);
|
||||
if (BitsquareApp.DEV_MODE) {
|
||||
doWithdraw(receiverAmount, callback);
|
||||
doWithdraw(senderAmount, callback);
|
||||
} else {
|
||||
new Popup().headLine("Confirm withdrawal request")
|
||||
.confirmation("Sending: " + formatter.formatCoinWithCode(senderAmount) + "\n" +
|
||||
|
@ -283,8 +283,11 @@ public class WithdrawalView extends ActivatableView<VBox, Void> {
|
|||
|
||||
private void updateList() {
|
||||
observableList.forEach(WithdrawalListItem::cleanup);
|
||||
observableList.setAll(TradableCollections.getAddressEntriesForAvailableBalance(openOfferManager, tradeManager, walletService).stream()
|
||||
.map(addressEntry -> new WithdrawalListItem(addressEntry, walletService, formatter))
|
||||
observableList.setAll(Stream.concat(walletService.getSavingsAddressEntryList().stream(), walletService.getTradeAddressEntryList().stream())
|
||||
.filter(addressEntry -> walletService.getBalanceForAddress(addressEntry.getAddress()).isPositive())
|
||||
.map(addressEntry -> new WithdrawalListItem(addressEntry, walletService, openOfferManager, tradeManager,
|
||||
closedTradableManager, failedTradesManager, formatter))
|
||||
.filter(item -> item.getBalance().isPositive())
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
|
|
|
@ -318,9 +318,11 @@ class CreateOfferDataModel extends ActivatableDataModel {
|
|||
}
|
||||
}
|
||||
|
||||
void useSavingsWalletForFunding() {
|
||||
useSavingsWallet = true;
|
||||
void fundFromSavingsWallet() {
|
||||
this.useSavingsWallet = true;
|
||||
updateBalance();
|
||||
if (!isWalletFunded.get())
|
||||
this.useSavingsWallet = false;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -20,7 +20,6 @@ package io.bitsquare.gui.main.offer.createoffer;
|
|||
import de.jensd.fx.fontawesome.AwesomeDude;
|
||||
import de.jensd.fx.fontawesome.AwesomeIcon;
|
||||
import io.bitsquare.app.BitsquareApp;
|
||||
import io.bitsquare.btc.FeePolicy;
|
||||
import io.bitsquare.common.UserThread;
|
||||
import io.bitsquare.common.util.Tuple2;
|
||||
import io.bitsquare.common.util.Tuple3;
|
||||
|
@ -296,13 +295,11 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
|
|||
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 bitcoin mining fee.\n\n" +
|
||||
"Please send from your external Bitcoin wallet the exact amount to the address: " +
|
||||
"You can choose between 2 options:\n" +
|
||||
"Either you transfer from your Bitsquare wallet the funds or if you prefer better privacy by " +
|
||||
"separating all trade transactions you can send from your external Bitcoin wallet the exact amount to the address: " +
|
||||
model.getAddressAsString() + "\n" +
|
||||
"(you can copy the address in the screen below after closing that popup)\n\n" +
|
||||
"Make sure you use a sufficiently high mining fee of at least " +
|
||||
model.formatter.formatCoinWithCode(FeePolicy.getMinRequiredFeeForFundingTx()) +
|
||||
" to avoid problems that your transaction does not get confirmed in the blockchain.\n" +
|
||||
"Transactions with a lower fee will not be accepted.\n\n" +
|
||||
"You can see the status of your incoming payment and all the details in the screen below.")
|
||||
.dontShowAgainId(key, preferences)
|
||||
.show();
|
||||
|
@ -804,7 +801,7 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
|
|||
fundFromSavingsWalletButton = new Button("Transfer funds from Bitsquare wallet");
|
||||
fundFromSavingsWalletButton.setDefaultButton(true);
|
||||
fundFromSavingsWalletButton.setDefaultButton(false);
|
||||
fundFromSavingsWalletButton.setOnAction(e -> model.useSavingsWalletForFunding());
|
||||
fundFromSavingsWalletButton.setOnAction(e -> model.fundFromSavingsWallet());
|
||||
Label label = new Label("OR");
|
||||
label.setPadding(new Insets(5, 0, 0, 0));
|
||||
fundFromExternalWalletButton = new Button("Pay in funds from external wallet");
|
||||
|
|
|
@ -375,8 +375,8 @@ class CreateOfferViewModel extends ActivatableWithDataModel<CreateOfferDataModel
|
|||
updateSpinnerInfo();
|
||||
}
|
||||
|
||||
boolean useSavingsWalletForFunding() {
|
||||
dataModel.useSavingsWalletForFunding();
|
||||
boolean fundFromSavingsWallet() {
|
||||
dataModel.fundFromSavingsWallet();
|
||||
if (dataModel.isWalletFunded.get()) {
|
||||
updateButtonDisableState();
|
||||
return true;
|
||||
|
|
|
@ -252,9 +252,11 @@ class TakeOfferDataModel extends ActivatableDataModel {
|
|||
this.paymentAccount = paymentAccount;
|
||||
}
|
||||
|
||||
void useSavingsWalletForFunding() {
|
||||
void fundFromSavingsWallet() {
|
||||
useSavingsWallet = true;
|
||||
updateBalance();
|
||||
if (!isWalletFunded.get())
|
||||
this.useSavingsWallet = false;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -20,7 +20,6 @@ package io.bitsquare.gui.main.offer.takeoffer;
|
|||
import de.jensd.fx.fontawesome.AwesomeDude;
|
||||
import de.jensd.fx.fontawesome.AwesomeIcon;
|
||||
import io.bitsquare.app.BitsquareApp;
|
||||
import io.bitsquare.btc.FeePolicy;
|
||||
import io.bitsquare.common.UserThread;
|
||||
import io.bitsquare.common.util.Tuple2;
|
||||
import io.bitsquare.common.util.Tuple3;
|
||||
|
@ -309,12 +308,11 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
|||
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 bitcoin mining fee.\n\n" +
|
||||
"Please send from your external Bitcoin wallet the exact amount to the address: " +
|
||||
model.dataModel.getAddressEntry().getAddressString() + "\n(you can copy the address in the screen below after closing that popup)\n\n" +
|
||||
"Make sure you use a sufficiently high mining fee of at least " +
|
||||
model.formatter.formatCoinWithCode(FeePolicy.getMinRequiredFeeForFundingTx()) +
|
||||
" to avoid problems that your transaction does not get confirmed in the blockchain.\n" +
|
||||
"Transactions with a lower fee will not be accepted.\n\n" +
|
||||
"You can choose between 2 options:\n" +
|
||||
"Either you transfer from your Bitsquare wallet the funds or if you prefer better privacy by " +
|
||||
"separating all trade transactions you can send from your external Bitcoin wallet the exact amount to the address: " +
|
||||
model.dataModel.getAddressEntry().getAddressString() + "\n" +
|
||||
"(you can copy the address in the screen below after closing that popup)\n\n" +
|
||||
"You can see the status of your incoming payment and all the details in the screen below.")
|
||||
.dontShowAgainId(key, preferences)
|
||||
.show();
|
||||
|
@ -726,7 +724,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
|||
fundFromSavingsWalletButton = new Button("Transfer funds from Bitsquare wallet");
|
||||
fundFromSavingsWalletButton.setDefaultButton(true);
|
||||
fundFromSavingsWalletButton.setDefaultButton(false);
|
||||
fundFromSavingsWalletButton.setOnAction(e -> model.useSavingsWalletForFunding());
|
||||
fundFromSavingsWalletButton.setOnAction(e -> model.fundFromSavingsWallet());
|
||||
Label label = new Label("OR");
|
||||
label.setPadding(new Insets(5, 0, 0, 0));
|
||||
fundFromExternalWalletButton = new Button("Pay in funds from external wallet");
|
||||
|
|
|
@ -207,8 +207,8 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
|
|||
updateSpinnerInfo();
|
||||
}
|
||||
|
||||
boolean useSavingsWalletForFunding() {
|
||||
dataModel.useSavingsWalletForFunding();
|
||||
boolean fundFromSavingsWallet() {
|
||||
dataModel.fundFromSavingsWallet();
|
||||
if (dataModel.isWalletFunded.get()) {
|
||||
updateButtonDisableState();
|
||||
return true;
|
||||
|
|
Loading…
Add table
Reference in a new issue